From 140bb9cc851e8051d89591d9ad5f5f72a2841eb9 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 10 Dec 2018 17:34:18 -0800 Subject: [PATCH] fix 'a X' The fruit name fix a couple of days ago revealed that an() didn't pick the right article for single letters. If you set named fruit to "X" and wished for "fruit", you'd have 'k - a X' added to inventory. This changes an() and also doname() which bypasses an(). --- src/objnam.c | 93 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/src/objnam.c b/src/objnam.c index 05aade695..ce828c355 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1543745355 2018/12/02 10:09:15 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.227 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1544492043 2018/12/11 01:34:03 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.229 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -19,6 +19,7 @@ STATIC_DCL void FDECL(releaseobuf, (char *)); STATIC_DCL char *FDECL(minimal_xname, (struct obj *)); STATIC_DCL void FDECL(add_erosion_words, (struct obj *, char *)); STATIC_DCL char *FDECL(doname_base, (struct obj *obj, unsigned)); +STATIC_DCL char *FDECL(just_an, (char *str, const char *)); STATIC_DCL boolean FDECL(singplur_lookup, (char *, char *, BOOLEAN_P, const char *const *)); STATIC_DCL char *FDECL(singplur_compound, (char *)); @@ -476,11 +477,12 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ Strcat(buf, un); } else Strcat(buf, dn); - /* If we use an() here we'd have to remember never to use */ - /* it whenever calling doname() or xname(). */ + if (typ == FIGURINE && omndx != NON_PM) { - Sprintf(eos(buf), " of a%s %s", - index(vowels, *mons[omndx].mname) ? "n" : "", + char anbuf[10]; /* [4] would be enough: 'a','n',' ','\0' */ + + Sprintf(eos(buf), " of %s%s", + just_an(anbuf, mons[omndx].mname), mons[omndx].mname); } else if (is_wet_towel(obj)) { if (wizard) @@ -506,9 +508,9 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ break; } - if (nn) + if (nn) { Strcat(buf, actualn); - else if (un) { + } else if (un) { if (is_boots(obj)) Strcat(buf, "boots"); else if (is_gloves(obj)) @@ -567,7 +569,9 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ Strcpy(buf, actualn); break; case ROCK_CLASS: - if (typ == STATUE && omndx != NON_PM) + if (typ == STATUE && omndx != NON_PM) { + char anbuf[10]; + Sprintf(buf, "%s%s of %s%s", (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC)) ? "historic " @@ -577,11 +581,9 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ ? "" : the_unique_pm(&mons[omndx]) ? "the " - : index(vowels, *mons[omndx].mname) - ? "an " - : "a ", + : just_an(anbuf, mons[omndx].mname), mons[omndx].mname); - else + } else Strcpy(buf, actualn); break; case BALL_CLASS: @@ -1213,14 +1215,13 @@ unsigned doname_flags; if (price > 0) Sprintf(eos(bp), " (%ld %s)", price, currency(price)); } - if (!strncmp(prefix, "a ", 2) - && index(vowels, *(prefix + 2) ? *(prefix + 2) : *bp) - && (*(prefix + 2) - || (strncmp(bp, "uranium", 7) && strncmp(bp, "unicorn", 7) - && strncmp(bp, "eucalyptus", 10)))) { - Strcpy(tmpbuf, prefix); - Strcpy(prefix, "an "); - Strcpy(prefix + 3, tmpbuf + 2); + if (!strncmp(prefix, "a ", 2)) { + /* save current prefix, without "a "; might be empty */ + Strcpy(tmpbuf, prefix + 2); + /* set prefix[] to "", "a ", or "an " */ + (void) just_an(prefix, *tmpbuf ? tmpbuf : bp); + /* apprend remainder of original prefix */ + Strcat(prefix, tmpbuf); } /* show weight for items (debug tourist info) @@ -1590,26 +1591,46 @@ char *FDECL((*func), (OBJ_P)); return nam; } +/* pick "", "a ", or "an " as article for 'str'; used by an() and doname() */ +STATIC_OVL char * +just_an(outbuf, str) +char *outbuf; +const char *str; +{ + char c0; + + *outbuf = '\0'; + c0 = lowc(*str); + if (!str[1]) { + /* single letter; might be used for named fruit */ + Strcpy(outbuf, index("aefhilmnosx", c0) ? "an " : "a "); + } else if (!strncmpi(str, "the ", 4) || !strcmpi(str, "molten lava") + || !strcmpi(str, "iron bars") || !strcmpi(str, "ice")) { + ; /* no article */ + } else { + if ((index(vowels, c0) && strncmpi(str, "one-", 4) + && strncmpi(str, "eucalyptus", 10) && strncmpi(str, "unicorn", 7) + && strncmpi(str, "uranium", 7) && strncmpi(str, "useful", 6)) + || (index("x", c0) && !index(vowels, lowc(str[1])))) + Strcpy(outbuf, "an "); + else + Strcpy(outbuf, "a "); + } + return outbuf; +} + char * an(str) -register const char *str; +const char *str; { char *buf = nextobuf(); - buf[0] = '\0'; - - if (strncmpi(str, "the ", 4) && strcmp(str, "molten lava") - && strcmp(str, "iron bars") && strcmp(str, "ice")) { - if (index(vowels, *str) && strncmp(str, "one-", 4) - && strncmp(str, "useful", 6) && strncmp(str, "unicorn", 7) - && strncmp(str, "uranium", 7) && strncmp(str, "eucalyptus", 10)) - Strcpy(buf, "an "); - else - Strcpy(buf, "a "); + if (!str || !*str) { + impossible("Alphabet soup: 'an(%s)'.", str ? "\"\"" : ""); + return strcpy(buf, "an []"); } - - Strcat(buf, str); - return buf; + just_an(buf, str); + return strcat(buf, str); } char * @@ -1633,6 +1654,10 @@ const char *str; char *buf = nextobuf(); boolean insert_the = FALSE; + if (!str || !*str) { + impossible("Alphabet soup: 'the(%s)'.", str ? "\"\"" : ""); + return strcpy(buf, "the []"); + } if (!strncmpi(str, "the ", 4)) { buf[0] = lowc(*str); Strcpy(&buf[1], str + 1); -- 2.40.0