diff --git a/include/extern.h b/include/extern.h index 7b10a786b..8a88f5abc 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1021,6 +1021,7 @@ extern char *tabexpand(char *); extern char *visctrl(char); extern char *strsubst(char *, const char *, const char *); extern int strNsubst(char *, const char *, const char *, int); +extern const char *findword(const char *, const char *, int, boolean); extern const char *ordin(int); extern char *sitoa(int); extern int sgn(int); diff --git a/src/hacklib.c b/src/hacklib.c index 38fd5a9c2..48dca9344 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -41,6 +41,7 @@ char * visctrl (char) char * strsubst (char *, const char *, const char *) int strNsubst (char *,const char *,const char *,int) + const char * findword (const char *,const char *,int,boolean) const char * ordin (int) char * sitoa (int) int sgn (int) @@ -615,6 +616,30 @@ strNsubst( return rcount; } +/* search for a word in a space-separated list; returns non-Null if found */ +const char * +findword( + const char *list, /* string of space-separated words */ + const char *word, /* word to try to find */ + int wordlen, /* so that it isn't required to be \0 terminated */ + boolean ignorecase) /* T: case-blind, F: case-sensitive */ +{ + const char *p = list; + + while (p) { + while (*p == ' ') + ++p; + if (!*p) + break; + if ((ignorecase ? !strncmpi(p, word, wordlen) + : !strncmp(p, word, wordlen)) + && (p[wordlen] == '\0' || p[wordlen] == ' ')) + return p; + p = strchr(p + 1, ' '); + } + return (const char *) 0; +} + /* return the ordinal suffix of a number */ const char * ordin(int n) /* note: should be non-negative */ diff --git a/src/role.c b/src/role.c index 6496c3ec8..e1d6a183e 100644 --- a/src/role.c +++ b/src/role.c @@ -819,6 +819,9 @@ str2race(const char *str) /* Does it match the noun? */ if (!strncmpi(str, races[i].noun, len)) return i; + /* check adjective too */ + if (races[i].adj && !strncmpi(str, races[i].adj, len)) + return i; /* Or the filecode? */ if (!strcmpi(str, races[i].filecode)) return i; @@ -1603,20 +1606,25 @@ plnamesuffix(void) /* some generic user names will be ignored in favor of prompting */ if (sysopt.genericusers) { if (*sysopt.genericusers == '*') { - *gp.plname = '\0'; + gp.plname[0] = '\0'; } else { - i = (int) strlen(gp.plname); - if ((sptr = strstri(sysopt.genericusers, gp.plname)) != 0 - && (sptr == sysopt.genericusers || sptr[-1] == ' ') - && (sptr[i] == ' ' || sptr[i] == '\0')) - *gp.plname = '\0'; /* call askname() */ + /* need to ignore appended '-role-race-gender-alignment'; + 'plnamelen' is non-zero when dealing with plname[] value that + contains a username with dash(es) in it and is usually 0 */ + i = ((eptr = strchr(gp.plname + gp.plnamelen, '-')) != 0) + ? (int) (eptr - gp.plname) + : Strlen(gp.plname); + /* look for plname[] in the 'genericusers' space-separated list */ + if (findword(sysopt.genericusers, gp.plname, i, FALSE)) + /* it's generic; remove it so that askname() will be called */ + gp.plname[0] = '\0'; } - if (!*gp.plname) + if (!gp.plname[0]) gp.plnamelen = 0; } do { - if (!*gp.plname) { + if (!gp.plname[0]) { askname(); /* fill gp.plname[] if necessary, or set defer_plname */ gp.plnamelen = 0; /* plname[] might have -role-race-&c attached */ } @@ -1641,7 +1649,7 @@ plnamesuffix(void) else if ((i = str2align(sptr)) != ROLE_NONE) flags.initalign = i; } - } while (!*gp.plname && !iflags.defer_plname); + } while (!gp.plname[0] && !iflags.defer_plname); /* commas in the gp.plname confuse the record file, convert to spaces */ (void) strNsubst(gp.plname, ",", " ", 0);