optimize pline("%s",string)
pline() already skips sprintf/vsnprintf if the format doesn't contain any percent signs. Do the same if the entire format is "%s". Also, if ESC is used to suppress messages for the rest of the current move, the text for any impossible warnings issued during that time would be suppressed too so not be seen.
This commit is contained in:
@@ -1149,6 +1149,8 @@ prevent hug attacks and touch or engulf attacks for wrap, stick-to, and
|
|||||||
wand of speed gives temporary speed, potion gives intrinsic
|
wand of speed gives temporary speed, potion gives intrinsic
|
||||||
some monsters (riders, shopkeepers, priests, quest leader) can break boulders
|
some monsters (riders, shopkeepers, priests, quest leader) can break boulders
|
||||||
corpse-eating monsters will go out of their way to eat corpses on the floor
|
corpse-eating monsters will go out of their way to eat corpses on the floor
|
||||||
|
warnings via impossible() would be unseen if message suppression via ESC at
|
||||||
|
--More-- prompt was in effect
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||||
|
|||||||
+28
-17
@@ -99,7 +99,6 @@ vpline(const char *line, va_list the_args)
|
|||||||
char pbuf[BIGBUFSZ]; /* will get chopped down to BUFSZ-1 if longer */
|
char pbuf[BIGBUFSZ]; /* will get chopped down to BUFSZ-1 if longer */
|
||||||
int ln;
|
int ln;
|
||||||
int msgtyp;
|
int msgtyp;
|
||||||
int vlen = 0;
|
|
||||||
boolean no_repeat;
|
boolean no_repeat;
|
||||||
|
|
||||||
if (!line || !*line)
|
if (!line || !*line)
|
||||||
@@ -111,24 +110,33 @@ vpline(const char *line, va_list the_args)
|
|||||||
if (gp.program_state.wizkit_wishing)
|
if (gp.program_state.wizkit_wishing)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (strchr(line, '%')) {
|
if (!strchr(line, '%')) {
|
||||||
vlen = vsnprintf(pbuf, sizeof(pbuf), line, the_args);
|
/* format does not specify any substitutions; use it as-is */
|
||||||
#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) && defined(DEBUG)
|
ln = (int) strlen(line);
|
||||||
if (vlen >= (int) sizeof pbuf)
|
} else if (line[0] == '%' && line[1] == 's' && !line[2]) {
|
||||||
panic("%s: truncation of buffer at %zu of %d bytes",
|
/* "%s" => single string; skip format and use its first argument;
|
||||||
"pline", sizeof pbuf, vlen);
|
unlike with the format, it is irrelevant whether the argument
|
||||||
#else
|
contains any percent signs */
|
||||||
nhUse(vlen);
|
line = va_arg(the_args, const char *); /*VA_NEXT(line,const char *);*/
|
||||||
#endif
|
ln = (int) strlen(line);
|
||||||
|
} else {
|
||||||
|
/* perform printf() formatting */
|
||||||
|
ln = vsnprintf(pbuf, sizeof pbuf, line, the_args);
|
||||||
line = pbuf;
|
line = pbuf;
|
||||||
|
/* note: 'ln' is number of characters attempted, not necessarily
|
||||||
|
strlen(line); that matters for the overflow check; if we avoid
|
||||||
|
the extremely-too-long panic then 'ln' will be actual length */
|
||||||
}
|
}
|
||||||
if ((ln = (int) strlen(line)) > BUFSZ - 1) {
|
if (ln > (int) sizeof pbuf - 1) /* extremely too long */
|
||||||
if (line != pbuf) /* no '%' was present */
|
panic("pline attempting to print %d characters!", ln);
|
||||||
(void) strncpy(pbuf, line, BUFSZ - 1); /* caveat: unterminated */
|
|
||||||
/* truncate, preserving the final 3 characters:
|
if (ln > BUFSZ - 1) {
|
||||||
"___ extremely long text" -> "___ extremely l...ext"
|
/* too long but modestly so; allow but truncate, preserving final
|
||||||
|
3 chars: "___ extremely long text" -> "___ extremely l...ext"
|
||||||
(this may be suboptimal if overflow is less than 3) */
|
(this may be suboptimal if overflow is less than 3) */
|
||||||
memcpy(pbuf + BUFSZ - 1 - 6, "...", 3);
|
if (line != pbuf) /* no '%' was present or format was just "%s" */
|
||||||
|
(void) strncpy(pbuf, line, BUFSZ - 1); /* caveat: unterminated */
|
||||||
|
pbuf[BUFSZ - 1 - 6] = pbuf[BUFSZ - 1 - 5] = pbuf[BUFSZ - 1 - 4] = '.';
|
||||||
/* avoid strncpy; buffers could overlap if excess is small */
|
/* avoid strncpy; buffers could overlap if excess is small */
|
||||||
pbuf[BUFSZ - 1 - 3] = line[ln - 3];
|
pbuf[BUFSZ - 1 - 3] = line[ln - 3];
|
||||||
pbuf[BUFSZ - 1 - 2] = line[ln - 2];
|
pbuf[BUFSZ - 1 - 2] = line[ln - 2];
|
||||||
@@ -503,13 +511,16 @@ impossible(const char *s, ...)
|
|||||||
panic("impossible called impossible");
|
panic("impossible called impossible");
|
||||||
|
|
||||||
gp.program_state.in_impossible = 1;
|
gp.program_state.in_impossible = 1;
|
||||||
(void) vsnprintf(pbuf, sizeof(pbuf), s, the_args);
|
(void) vsnprintf(pbuf, sizeof pbuf, s, the_args);
|
||||||
va_end(the_args);
|
va_end(the_args);
|
||||||
pbuf[BUFSZ - 1] = '\0'; /* sanity */
|
pbuf[BUFSZ - 1] = '\0'; /* sanity */
|
||||||
paniclog("impossible", pbuf);
|
paniclog("impossible", pbuf);
|
||||||
if (iflags.debug_fuzzer)
|
if (iflags.debug_fuzzer)
|
||||||
panic("%s", pbuf);
|
panic("%s", pbuf);
|
||||||
|
|
||||||
|
gp.pline_flags = URGENT_MESSAGE;
|
||||||
pline("%s", pbuf);
|
pline("%s", pbuf);
|
||||||
|
gp.pline_flags = 0;
|
||||||
/* reuse pbuf[] */
|
/* reuse pbuf[] */
|
||||||
Strcpy(pbuf, "Program in disorder!");
|
Strcpy(pbuf, "Program in disorder!");
|
||||||
if (gp.program_state.something_worth_saving)
|
if (gp.program_state.something_worth_saving)
|
||||||
|
|||||||
Reference in New Issue
Block a user