X-Git-Url: https://jxself.org/git/?p=open-adventure.git;a=blobdiff_plain;f=misc.c;h=2b6a58b212a7561eab784dad1a151566319cab4f;hp=a38c54657f42dd1fadffed8a561b28dbb10c9f28;hb=1c4fcaf43edea3d1a29fe6f4949f6397c314c67e;hpb=f03bde268ebb52455d4ca728ce043e2bddedae22 diff --git a/misc.c b/misc.c index a38c546..2b6a58b 100644 --- a/misc.c +++ b/misc.c @@ -10,19 +10,7 @@ #include "advent.h" #include "dungeon.h" -char* xstrdup(const char* s) -{ - char* ptr = strdup(s); - if (ptr == NULL) { - // LCOV_EXCL_START - // exclude from coverage analysis because we can't simulate an out of memory error in testing - fprintf(stderr, "Out of memory!\n"); - exit(EXIT_FAILURE); - } - return (ptr); -} - -void* xmalloc(size_t size) +static void* xmalloc(size_t size) { void* ptr = malloc(size); if (ptr == NULL) { @@ -68,7 +56,7 @@ void packed_to_token(long packed, char token[TOKLEN+1]) } } -long token_to_packed(const char token[TOKLEN+1]) +long token_to_packed(const char token[]) { const char ascii_to_advent[] = { 63, 63, 63, 63, 63, 63, 63, 63, @@ -92,9 +80,11 @@ long token_to_packed(const char token[TOKLEN+1]) }; size_t t_len = strlen(token); + if (t_len > TOKLEN) + t_len = TOKLEN; long packed = 0; for (size_t i = 0; i < t_len; ++i) { - char mapped = ascii_to_advent[(int) token[i]]; + char mapped = ascii_to_advent[(int) toupper(token[i])]; packed |= (mapped << (6 * i)); } return (packed); @@ -107,29 +97,9 @@ void tokenize(char* raw, struct command_t *cmd) /* 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] = { - {"\0\0\0\0\0"}, - {"\0\0\0\0\0"}, - {"\0\0\0\0\0"}, - {"\0\0\0\0\0"}, - }; - - // break the words into up to 4 5-char substrings - sscanf(cmd->raw1, "%5s%5s", chunk_data[0], chunk_data[1]); - if (word_count == 2) - sscanf(cmd->raw2, "%5s%5s", chunk_data[2], chunk_data[3]); - - // uppercase all the substrings - for (int i = 0; i < 4; ++i) - for (unsigned int j = 0; j < strlen(chunk_data[i]); ++j) - chunk_data[i][j] = (char) toupper(chunk_data[i][j]); - // pack the substrings - 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]); + cmd->wd1 = token_to_packed(cmd->raw1); + cmd->wd2 = token_to_packed(cmd->raw2); } /* Hide the fact that wods are corrently packed longs */ @@ -149,7 +119,7 @@ void wordclear(token_t *v) *v = 0; } -/* I/O routines (speak, pspeak, rspeak, get_input, yes) */ +/* I/O routines (speak, pspeak, rspeak, sspeak, get_input, yes) */ void vspeak(const char* msg, bool blank, va_list ap) { @@ -220,20 +190,6 @@ void vspeak(const char* msg, bool blank, va_list ap) size -= len; } - // All-lowercase specifier. - if (msg[i] == 'L' || - msg[i] == 'C') { - packed_to_token(arg, renderp); /* unpack directly to destination */ - int len = strlen(renderp); - for (int j = 0; j < len; ++j) { - renderp[j] = tolower(renderp[j]); - } - if (msg[i] == 'C') // First char uppercase, rest lowercase. - renderp[0] = toupper(renderp[0]); - renderp += len; - size -= len; - } - previous_arg = arg; } } @@ -253,6 +209,16 @@ void speak(const char* msg, ...) va_end(ap); } +void sspeak(const long msg, ...) +{ + va_list ap; + va_start(ap, msg); + fputc('\n', stdout); + vprintf(arbitrary_messages[msg], ap); + fputc('\n', stdout); + va_end(ap); +} + void pspeak(vocab_t msg, enum speaktype mode, int skip, bool blank, ...) /* Find the skip+1st message from msg and print it. Modes are: * feel = for inventory, what you can touch @@ -301,19 +267,24 @@ void echo_input(FILE* destination, const char* input_prompt, const char* input) free(prompt_and_input); } -int word_count(char* s) +int word_count(char* str) { - char* copy = xstrdup(s); char delims[] = " \t"; int count = 0; - char* word; + int inblanks = true; + + for (char *s = str; *s; s++) + if (inblanks) { + if (strchr(delims, *s) == 0) { + ++count; + inblanks = false; + } + } else { + if (strchr(delims, *s) != 0) { + inblanks = true; + } + } - word = strtok(copy, delims); - while (word != NULL) { - word = strtok(NULL, delims); - ++count; - } - free(copy); return (count); }