Refactor tokenization to save raw tokens and use static buffer space...
authorEric S. Raymond <esr@thyrsus.com>
Mon, 3 Jul 2017 12:53:10 +0000 (08:53 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Mon, 3 Jul 2017 12:53:10 +0000 (08:53 -0400)
...rather than dynamic storage.

As a side effect, this seems to have fixed a very ninor bug in the processing
of the bare word 'nothing'.  But I don't know where the bug was.  Not happy.

advent.h
main.c
misc.c
tests/woodshint.chk

index 085244067441c5de988a35ef3c3d57df88142b8b..8ef2f5b59c950b0471e3159f675d73b392324ae2 100644 (file)
--- a/advent.h
+++ b/advent.h
@@ -183,6 +183,7 @@ struct command_t {
     vocab_t obj;
     token_t wd1, wd1x;
     token_t wd2, wd2x;
+    char raw1[BUFSIZ], raw2[BUFSIZ];
 };
 
 extern struct game_t game;
@@ -192,7 +193,7 @@ extern char* xstrdup(const char* s);
 extern void* xmalloc(size_t size);
 extern void packed_to_token(long, char token[]);
 extern long token_to_packed(const char token[TOKLEN+1]);
-extern void tokenize(char*, long tokens[4]);
+extern void tokenize(char*, struct command_t *);
 extern void vspeak(const char*, bool, va_list);
 extern bool wordeq(token_t, token_t);
 extern bool wordempty(token_t);
diff --git a/main.c b/main.c
index 3b48af3cf596e6700ff358a7859e141cce7f3b3c..c2c4daa79a5029c26dfe06705b1cba99403d17a8 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1054,12 +1054,7 @@ L2600:
         strncpy(inputbuf, input, LINESIZE - 1);
         free(input);
 
-        long tokens[4];
-        tokenize(inputbuf, tokens);
-        command.wd1 = tokens[0];
-        command.wd1x = tokens[1];
-        command.wd2 = tokens[2];
-        command.wd2x = tokens[3];
+        tokenize(inputbuf, &command);
 
         /*  Every input, check "game.foobar" flag.  If zero, nothing's
          *  going on.  If pos, make neg.  If neg, he skipped a word,
diff --git a/misc.c b/misc.c
index 6f80c9d861a89bb7c8c73b9ff963ba45b1bea245..a38c54657f42dd1fadffed8a561b28dbb10c9f28 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -100,17 +100,12 @@ long token_to_packed(const char token[TOKLEN+1])
     return (packed);
 }
 
-void tokenize(char* raw, long tokens[4])
+void tokenize(char* raw, struct command_t *cmd)
 {
-    // set each token to 0
-    for (int i = 0; i < 4; ++i)
-        tokens[i] = 0;
+    memset(cmd, '\0', sizeof(struct command_t));
 
-    // grab the first two words
-    char* words[2];
-    words[0] = (char*) xmalloc(strlen(raw) + 1);
-    words[1] = (char*) xmalloc(strlen(raw) + 1);
-    int word_count = sscanf(raw, "%s%s", words[0], words[1]);
+    /* FIXME: put a bound prefix on the %s to prevent buffer overflow */
+    int word_count = sscanf(raw, "%s%s", cmd->raw1, cmd->raw2);
 
     // make space for substrings and zero it out
     char chunk_data[][TOKLEN+1] = {
@@ -121,11 +116,9 @@ void tokenize(char* raw, long tokens[4])
     };
 
     // break the words into up to 4 5-char substrings
-    sscanf(words[0], "%5s%5s", chunk_data[0], chunk_data[1]);
+    sscanf(cmd->raw1, "%5s%5s", chunk_data[0], chunk_data[1]);
     if (word_count == 2)
-        sscanf(words[1], "%5s%5s", chunk_data[2], chunk_data[3]);
-    free(words[0]);
-    free(words[1]);
+        sscanf(cmd->raw2, "%5s%5s", chunk_data[2], chunk_data[3]);
 
     // uppercase all the substrings
     for (int i = 0; i < 4; ++i)
@@ -133,8 +126,10 @@ void tokenize(char* raw, long tokens[4])
             chunk_data[i][j] = (char) toupper(chunk_data[i][j]);
 
     // pack the substrings
-    for (int i = 0; i < 4; ++i)
-        tokens[i] = token_to_packed(chunk_data[i]);
+    cmd->wd1  = token_to_packed(chunk_data[0]);
+    cmd->wd1x = token_to_packed(chunk_data[1]);
+    cmd->wd2  = token_to_packed(chunk_data[2]);
+    cmd->wd2x = token_to_packed(chunk_data[3]);
 }
 
 /* Hide the fact that wods are corrently packed longs */
index 51aed46a351ab43fec471064d37a1aaff46e69ed..23263f0d90c04f124ec85160c528fa4f793362d5 100644 (file)
@@ -122,7 +122,7 @@ Say what?
 
 > nothing
 
-Okay, "NOTHI".
+OK
 
 > wave