From: nhmall Date: Mon, 20 May 2019 05:33:33 +0000 (-0400) Subject: make it tougher for incomplete render_status() to go unnoticed X-Git-Tag: nmake-explicit-path~2^2~120 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cbb3dbb5f5a7c001082042bd4c2bfb35d15ac71c;p=nethack make it tougher for incomplete render_status() to go unnoticed Adds a sanity check that will write a paniclog message if a code change prevents completion of render_status() for each dirty (changed) field. --- diff --git a/include/wintty.h b/include/wintty.h index 1a609de2a..4863d6e10 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintty.h $NHDT-Date: 1553858470 2019/03/29 11:21:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 3.6 wintty.h $NHDT-Date: 1558330405 2019/05/20 05:33:25 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.34 $ */ /* Copyright (c) David Cohrs, 1991,1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -79,7 +79,7 @@ struct tty_status_fields { boolean valid; boolean dirty; boolean redraw; - boolean _not_used; /* was 'last_in_row' */ + boolean sanitycheck; /* was 'last_in_row' */ }; #endif diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 831e5326b..d1ab86446 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintty.c $NHDT-Date: 1557088734 2019/05/05 20:38:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.203 $ */ +/* NetHack 3.6 wintty.c $NHDT-Date: 1558330407 2019/05/20 05:33:27 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.205 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -210,6 +210,7 @@ STATIC_DCL int NDECL(condition_size); STATIC_DCL int FDECL(make_things_fit, (BOOLEAN_P)); STATIC_DCL void FDECL(shrink_enc, (int)); STATIC_DCL void FDECL(shrink_dlvl, (int)); +STATIC_DCL void NDECL(status_sanity_check); #endif /* @@ -3622,6 +3623,8 @@ char *posbar; * Goes through each of the two status row's fields and * calls tty_putstatusfield() to place them on the display. * ->tty_putstatusfield() + * At the end of the for-loop, the NOW values get copied + * to BEFORE values. * * tty_putstatusfield() * @@ -3748,6 +3751,7 @@ tty_status_init() tty_status[NOW][i].valid = FALSE; tty_status[NOW][i].dirty = FALSE; tty_status[NOW][i].redraw = FALSE; + tty_status[NOW][i].sanitycheck = FALSE; tty_status[BEFORE][i] = tty_status[NOW][i]; } tty_condition_bits = 0L; @@ -3851,8 +3855,10 @@ unsigned long *colormasks; reset_state = FORCE_RESET; /*FALLTHRU*/ case BL_FLUSH: - if (make_things_fit(reset_state) || truncation_expected) + if (make_things_fit(reset_state) || truncation_expected) { render_status(); + status_sanity_check(); + } return; case BL_CONDITION: tty_status[NOW][fldidx].idx = fldidx; @@ -3860,6 +3866,7 @@ unsigned long *colormasks; tty_colormasks = colormasks; tty_status[NOW][fldidx].valid = TRUE; tty_status[NOW][fldidx].dirty = TRUE; + tty_status[NOW][fldidx].sanitycheck = TRUE; truncation_expected = FALSE; break; case BL_GOLD: @@ -3887,6 +3894,7 @@ unsigned long *colormasks; tty_status[NOW][fldidx].lth = strlen(status_vals[fldidx]); tty_status[NOW][fldidx].valid = TRUE; tty_status[NOW][fldidx].dirty = TRUE; + tty_status[NOW][fldidx].sanitycheck = TRUE; break; } @@ -4110,6 +4118,50 @@ int sz[3]; return valid; } +STATIC_OVL void +status_sanity_check(VOID_ARGS) +{ + int i; + static boolean in_sanity_check = FALSE; + static const char *idxtext[] = { + "BL_TITLE", "BL_STR", "BL_DX", "BL_CO", "BL_IN", "BL_WI", /* 0.. 5 */ + "BL_CH","BL_ALIGN", "BL_SCORE", "BL_CAP", "BL_GOLD", /* 6.. 10 */ + "BL_ENE", "BL_ENEMAX", "BL_XP", "BL_AC", "BL_HD", /* 11.. 15 */ + "BL_TIME", "BL_HUNGER", "BL_HP", "BL_HPMAX", /* 16.. 19 */ + "BL_LEVELDESC", "BL_EXP", "BL_CONDITION" /* 20.. 22 */ + }; + + if (in_sanity_check) + return; + in_sanity_check = TRUE; + /* + * Make sure that every field made it down to the + * bottom of the render_status() for-loop. + */ + for (i = 0; i < MAXBLSTATS; ++i) { + if (tty_status[NOW][i].sanitycheck) { + char panicmsg[BUFSZ]; + + Sprintf(panicmsg, "failed on tty_status[NOW][%s].", idxtext[i]); + paniclog("status_sanity_check", panicmsg); + tty_status[NOW][i].sanitycheck = FALSE; + /* + * Attention developers: If you encounter the above + * message in paniclog, it almost certainly means that + * a recent code change has caused a failure to reach + * the bottom of render_status(), at least for the BL_ + * field identified in the impossible() message. + + * That could be because of the addition of a continue + * statement within the render_status() for-loop, or a + * premature return from render_status() before it finished + * its housekeeping chores. + */ + } + } + in_sanity_check = FALSE; +} + /* * This is what places a field on the tty display. */ @@ -4504,6 +4556,7 @@ render_status(VOID_ARGS) /* reset .redraw and .dirty now that they're rendered */ tty_status[NOW][idx].dirty = FALSE; tty_status[NOW][idx].redraw = FALSE; + tty_status[NOW][idx].sanitycheck = FALSE; /* * For comparison of current and previous: * - Copy the entire tty_status struct.