From 5dd6c05322c9ce435f417bc070b73071b78e5fcc Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 23 Feb 2018 13:07:49 -0800 Subject: [PATCH] switch docall() to safe_qbuf() Simplify docall() for object types. Adds some different complexity to a new routine so the overall simplification is rather minimal, but we already have a routine to construct prompt buffers involving formatted object names without allowing overflow, so use it. tty getlin() limits the input to COLNO characters, so 80 by default. To get potential QBUFSZ overflow, I had to increase COLNO in global.h and rebuild from scratch. A value greater than 127 triggers a lot of warnings. I didn't try 127. 126 gets one warning, involving use of FARAWAY (defined as COLNO+2) in dogmove.c. We should change things to limit object names to much less than 80, but this doesn't attempt to implement that. --- src/do_name.c | 60 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/do_name.c b/src/do_name.c index 7aceca6e1..ae57474f9 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_name.c $NHDT-Date: 1519281849 2018/02/22 06:44:09 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 3.6 do_name.c $NHDT-Date: 1519420054 2018/02/23 21:07:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.128 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -14,6 +14,7 @@ STATIC_DCL void FDECL(auto_describe, (int, int)); STATIC_DCL void NDECL(do_mname); STATIC_DCL boolean FDECL(alreadynamed, (struct monst *, char *, char *)); STATIC_DCL void FDECL(do_oname, (struct obj *)); +STATIC_PTR char *FDECL(docall_xname, (struct obj *)); STATIC_DCL void NDECL(namefloorobj); STATIC_DCL char *FDECL(bogusmon, (char *,char *)); @@ -1405,33 +1406,56 @@ docallcmd() return 0; } +/* for use by safe_qbuf() */ +STATIC_PTR char * +docall_xname(obj) +struct obj *obj; +{ + struct obj otemp; + + otemp = *obj; + otemp.oextra = (struct oextra *) 0; + otemp.quan = 1L; + /* in case water is already known, convert "[un]holy water" to "water" */ + otemp.blessed = otemp.cursed = 0; + /* remove attributes that are doname() caliber but get formatted + by xname(); most of these fixups aren't really needed because the + relevant type of object isn't callable so won't reach this far */ + if (otemp.oclass == WEAPON_CLASS) + otemp.opoisoned = 0; /* not poisoned */ + else if (otemp.oclass == POTION_CLASS) + otemp.odiluted = 0; /* not diluted */ + else if (otemp.otyp == TOWEL || otemp.otyp == STATUE) + otemp.spe = 0; /* not wet or historic */ + else if (otemp.otyp == TIN) + otemp.known = 0; /* suppress tin type (homemade, &c) and mon type */ + else if (otemp.otyp == FIGURINE) + otemp.corpsenm = NON_PM; /* suppress mon type */ + else if (otemp.otyp == HEAVY_IRON_BALL) + otemp.owt = objects[HEAVY_IRON_BALL].oc_weight; /* not "very heavy" */ + else if (otemp.oclass == FOOD_CLASS && otemp.globby) + otemp.owt = 120; /* 6*20, neither a small glob nor a large one */ + + return an(xname(&otemp)); +} + void docall(obj) -register struct obj *obj; +struct obj *obj; { char buf[BUFSZ], qbuf[QBUFSZ]; - struct obj otemp; - register char **str1; + char **str1; if (!obj->dknown) return; /* probably blind */ - otemp = *obj; - otemp.quan = 1L; - otemp.oextra = (struct oextra *) 0; - if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink) { + if (obj->oclass == POTION_CLASS && obj->fromsink) /* kludge, meaning it's sink water */ Sprintf(qbuf, "Call a stream of %s fluid:", - OBJ_DESCR(objects[otemp.otyp])); - } else { - char tmpbuf[BUFSZ], *tmpname = an(xname(&otemp)); - - if (strlen(tmpname) < (BUFSZ - 1)) { - Strcpy(tmpbuf, tmpname); - tmpbuf[QBUFSZ - 7] = '\0'; /* need room for "Call :"*/ - Sprintf(qbuf, "Call %s:", tmpbuf); - } - } + OBJ_DESCR(objects[obj->otyp])); + else + (void) safe_qbuf(qbuf, "Call ", ":", obj, + docall_xname, simpleonames, "thing"); getlin(qbuf, buf); if (!*buf || *buf == '\033') return;