static zword smart_tokeniser(zword dictionarytable, const char *text, unsigned length, BOOL is_begin) { zword word_num = 0; unsigned tlength = (length < 12) ? length : 12; char tbuffer[13]; /* Letter replacements are tried in this order - */ const char fixmeletters[] = "abcdefghijklmnopqrstuvwxyz"; /* char fixmeletters[] = "etaonrishdlfcmugpywbvkxjqz"; */ word_num = find_word(dictionarytable, text, length); /* Some game files don't contain abbreviations for common commands */ if(!word_num && do_expand && length == 1 && is_begin) { const char * const abbrevs[26] = { "a", "b", "close", "down", "east", "f", "again", "h", "inventory", "j", "attack", "look", "m", "north", "oops", "open", "quit", "drop", "south", "take", "up", "v", "west", "examine", "yes", "wait" }; if('a' <= text[0] && text[0] <= 'z') { strcpy(tbuffer, abbrevs[text[0] - 'a']); tlength = strlen(tbuffer); word_num = find_word(dictionarytable, tbuffer, tlength); } } /* Check for various typing errors */ /* Don't attempt typo correction in very short words */ if(do_spell_correct && length >= 3) { if(!word_num) { /* Check for transposes */ /* To fix, try all possible transposes */ unsigned position; for(position = 1; position < tlength; position++) { unsigned s; for(s = 0; s < tlength; s++) tbuffer[s] = text[s]; tbuffer[position - 1] = text[position]; tbuffer[position] = text[position - 1]; word_num = find_word(dictionarytable, tbuffer, tlength); if(word_num) break; } } if(!word_num) { /* Check for deletions */ /* To fix, try all possible insertions */ unsigned position; for(position = 0; position <= tlength; position++) { unsigned s; for(s = 0; s < position; s++) /* letters before the insertion */ tbuffer[s] = text[s]; for(s = position; s < tlength; s++) /* after the insertion */ tbuffer[s + 1] = text[s]; /* try each letter */ for(s = 0; s < sizeof(fixmeletters); s++) { tbuffer[position] = fixmeletters[s]; word_num = find_word(dictionarytable, tbuffer, tlength + 1); if(word_num) break; } if(word_num) { tlength++; break; } } } if(!word_num) { /* Check for insertions */ /* To fix, try all possible deletions */ unsigned position; for(position = 0; position < tlength; position++) { unsigned s; for(s = 0; s < position; s++) /* letters before the deletion */ tbuffer[s] = text[s]; for(s = position + 1; s < tlength; s++) /* after the deletion */ tbuffer[s - 1] = text[s]; word_num = find_word(dictionarytable, tbuffer, tlength - 1); if(word_num) { tlength--; break; } } } if(!word_num) { /* Check for substitutions */ /* To fix, try all possible substitutions */ unsigned position; for(position = 0; position < tlength; position++) { unsigned s; for(s = 0; s < tlength; s++) tbuffer[s] = text[s]; /* try each letter */ for(s = 0; s < sizeof(fixmeletters); s++) { tbuffer[position] = fixmeletters[s]; word_num = find_word(dictionarytable, tbuffer, tlength); if(word_num) break; } if(word_num) break; } } } /* Report any corrections made */ if(word_num) { struct Typocorrection *p; char original[13], changedto[13]; n_strncpy(original, text, 13); n_strncpy(changedto, tbuffer, 13); if(length < 13) original[length] = 0; if(tlength < 13) changedto[tlength] = 0; LEsearch(recent_corrections, p, ((n_strncmp(p->original, original, 13) == 0) && (n_strncmp(p->changedto, changedto, 13) == 0))); /* Only print a correction if it hasn't yet been reported this turn */ if(!p) { struct Typocorrection newcorrection; n_strncpy(newcorrection.original, original, 13); n_strncpy(newcorrection.changedto, changedto, 13); LEadd(recent_corrections, newcorrection); set_glk_stream_current(); if(allow_output) { glk_put_char('['); w_glk_put_buffer(text, length); w_glk_put_string(" -> "); w_glk_put_buffer(tbuffer, tlength); glk_put_char(']'); glk_put_char(10); } } } return word_num; }
static BOOL parse_commands(int argc, char **argv) { int i; unsigned n; for(i = 1; i < argc; i++) { BOOL flag = TRUE; const char *p = argv[i]; if(p[0] == '-') { BOOL found = FALSE; while(*p == '-') p++; if(n_strncmp(p, "no-", 3) == 0) { flag = FALSE; p+=3; } if(n_strcasecmp(p, "help") == 0) { show_help(); exit(0); } if(n_strcasecmp(p, "version") == 0) { printf("nitfol version %d.%d\n", NITFOL_MAJOR, NITFOL_MINOR); exit(0); } for(n = 0; n < sizeof(options) / sizeof(*options); n++) { if((n_strlen(p) == 1 && *p == options[n].shortname) || n_strcmp(options[n].longname, p) == 0) { found = TRUE; switch(options[n].type) { case option_flag: options[n].int_func(flag); break; case option_file: i++; options[n].str_func(startup_open(argv[i])); break; case option_wfile: i++; options[n].str_func(startup_wopen(argv[i])); break; case option_number: i++; options[n].int_func(n_strtol(argv[i], NULL, 0)); break; case option_string: i++; options[n].string_func(argv[i]); break; } } } if(!found) return FALSE; } else { strid_t s = startup_open(argv[i]); if(!s) return FALSE; if(!game_use_file(s)) return FALSE; } } return TRUE; }