compare user string against object name string using fuzzy matching */
| 3240 | |
| 3241 | /* compare user string against object name string using fuzzy matching */ |
| 3242 | staticfn boolean |
| 3243 | wishymatch( |
| 3244 | const char *u_str, /* from user, so might be variant spelling */ |
| 3245 | const char *o_str, /* from objects[], so is in canonical form */ |
| 3246 | boolean retry_inverted) /* optional extra "of" handling */ |
| 3247 | { |
| 3248 | static NEARDATA const char detect_SP[] = "detect ", |
| 3249 | SP_detection[] = " detection"; |
| 3250 | char *p, buf[BUFSZ]; |
| 3251 | |
| 3252 | /* ignore spaces & hyphens and upper/lower case when comparing */ |
| 3253 | if (fuzzymatch(u_str, o_str, " -", TRUE)) |
| 3254 | return TRUE; |
| 3255 | |
| 3256 | if (retry_inverted) { |
| 3257 | const char *u_of, *o_of; |
| 3258 | |
| 3259 | /* when just one of the strings is in the form "foo of bar", |
| 3260 | convert it into "bar foo" and perform another comparison */ |
| 3261 | u_of = strstri(u_str, " of "); |
| 3262 | o_of = strstri(o_str, " of "); |
| 3263 | if (u_of && !o_of) { |
| 3264 | Strcpy(buf, u_of + 4); |
| 3265 | copynchars(eos(strcat(buf, " ")), u_str, (int) (u_of - u_str)); |
| 3266 | if (fuzzymatch(buf, o_str, " -", TRUE)) |
| 3267 | return TRUE; |
| 3268 | } else if (o_of && !u_of) { |
| 3269 | Strcpy(buf, o_of + 4); |
| 3270 | copynchars(eos(strcat(buf, " ")), o_str, (int) (o_of - o_str)); |
| 3271 | if (fuzzymatch(u_str, buf, " -", TRUE)) |
| 3272 | return TRUE; |
| 3273 | } |
| 3274 | } |
| 3275 | |
| 3276 | /* [note: if something like "elven speed boots" ever gets added, these |
| 3277 | special cases should be changed to call wishymatch() recursively in |
| 3278 | order to get the "of" inversion handling] */ |
| 3279 | if (!strncmp(o_str, "dwarvish ", 9)) { |
| 3280 | if (!strncmpi(u_str, "dwarven ", 8)) |
| 3281 | return fuzzymatch(u_str + 8, o_str + 9, " -", TRUE); |
| 3282 | } else if (!strncmp(o_str, "elven ", 6)) { |
| 3283 | if (!strncmpi(u_str, "elvish ", 7)) |
| 3284 | return fuzzymatch(u_str + 7, o_str + 6, " -", TRUE); |
| 3285 | else if (!strncmpi(u_str, "elfin ", 6)) |
| 3286 | return fuzzymatch(u_str + 6, o_str + 6, " -", TRUE); |
| 3287 | } else if (strstri(o_str, "helm") && strstri(u_str, "helmet")) { |
| 3288 | copynchars(buf, u_str, (int) sizeof buf - 1); |
| 3289 | (void) strsubst(buf, "helmet", "helm"); |
| 3290 | return wishymatch(buf, o_str, TRUE); |
| 3291 | } else if (strstri(o_str, "gauntlets") && strstri(u_str, "gloves")) { |
| 3292 | /* -3: room to replace shorter "gloves" with longer "gauntlets" */ |
| 3293 | copynchars(buf, u_str, (int) sizeof buf - 1 - 3); |
| 3294 | (void) strsubst(buf, "gloves", "gauntlets"); |
| 3295 | return wishymatch(buf, o_str, TRUE); |
| 3296 | } else if (!strncmp(o_str, detect_SP, sizeof detect_SP - 1)) { |
| 3297 | /* check for "detect <foo>" vs "<foo> detection" */ |
| 3298 | if ((p = strstri(u_str, SP_detection)) != 0 |
| 3299 | && !*(p + sizeof SP_detection - 1)) { |
no test coverage detected