makeplural & makesingular overhaul (trunk only)

I stumbled across a copy of an old newsgroup bug report which
complained that wishing for "Gauntlets of Power" didn't work.  I thought
that this was something which had already been fixed, but when I tried it
out, I discovered that you still couldn't wish for that.  It was failing
because case-sensitive makesinglar() didn't recognize that "Gauntlets"
needs special handling.  After the unwanted transformation, the case-
insensitive object matching would fail to find "gauntlet of power".

     Removing case-sensitivity for special cases like "boots" and "gloves"
would have fixed that, but this patch goes further and removes case-
sensitivity entirely for both makesingular and makeplural.  Words which
get their endings modified work when the input is upper or mixed case.
Any modified letters retain the case of the original, so the reason for
case-sensitivity--user specified fruits that aren't lower case--is covered.

     Some makeplural fixes:  the plural for dingo is dingoes (dictionary
says "-es", not "-s") and for roshi is roshi (just guessing here; most of
the Japanese names use same spelling for singular and plural, but we were
producing roshis).  Several words which makesingular leaves in plural form
(boots, gloves, &c) are now recognized by makeplural (avoiding gloveses).

     It also fixes a bunch of incorrect singularizations of plural monster
names:  foxes, *wolves, lynxes, fungi/humunculi/succubi, mumakil, wumpuses,
baluchitheria, Aleaxes, *elves, erinyes, djinn, priestesses, & valkyries.
Some non-monsters that makeplural handles correctly were also not being
singularized right:  feet, hooves, lice/mice, algae, children, nemeses.
This commit is contained in:
nethack.rankin
2007-05-01 03:59:32 +00:00
parent 6aff1bfad1
commit 894e7f0267
4 changed files with 301 additions and 169 deletions

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)hacklib.c 3.5 2007/03/05 */
/* SCCS Id: @(#)hacklib.c 3.5 2007/04/30 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* Copyright (c) Robert Patrick Rankin, 1991 */
/* NetHack may be freely redistributed. See license for details. */
@@ -20,6 +20,7 @@ NetHack, except that rounddiv may call panic().
char * eos (char *)
char * strkitten (char *,char)
void copynchars (char *,const char *,int)
void Strcasecpy (char *,const char *)
char * s_suffix (const char *)
char * xcrypt (const char *, char *)
boolean onlyspace (const char *)
@@ -156,6 +157,47 @@ copynchars(dst, src, n) /* truncating string copy */
*dst = '\0';
}
/* this assumes ASCII; someday we'll have to switch over to <ctype.h> */
#define nh_islower(c) ((c) >= 'a' && (c) <= 'z')
#define nh_isupper(c) ((c) >= 'A' && (c) <= 'Z')
#define nh_tolower(c) lowc(c)
#define nh_toupper(c) highc(c)
/* for case-insensitive editions of makeplural() and makesingular();
src might be shorter, same length, or longer than dst */
void
Strcasecpy(dst, src) /* overwrite string, preserving old chars' case */
char *dst;
const char *src;
{
int ic, oc, dst_exhausted = 0;
/* while dst has characters, replace each one with corresponding
character from src, converting case in the process if they differ;
once dst runs out, propagate the case of its last character to any
remaining src; if dst starts empty, it must be a pointer to the
tail of some other string because we examine the char at dst[-1] */
while ((ic = (int)(unsigned char)*src++) != '\0') {
if (!dst_exhausted && !*dst) dst_exhausted = 1;
/* fetch old character */
oc = (int)(unsigned char)*(dst - dst_exhausted);
/* possibly convert new character */
if (nh_islower(oc)) { /* the usual case... */
if (nh_isupper(ic)) ic = nh_tolower(ic);
} else if (nh_isupper(oc)) {
if (nh_islower(ic)) ic = nh_toupper(ic);
}
/* store new character */
*dst++ = (char)ic;
}
*dst = '\0';
}
#undef nh_islower
#undef nh_isupper
#undef nh_tolower
#undef nh_toupper
char *
s_suffix(s) /* return a name converted to possessive */
const char *s;