diff --git a/include/decl.h b/include/decl.h index fedb98663..d07cc3ef4 100644 --- a/include/decl.h +++ b/include/decl.h @@ -404,12 +404,6 @@ struct early_opt { boolean valallowed; }; -/* topline states */ -#define TOPLINE_EMPTY 0 /* empty */ -#define TOPLINE_NEED_MORE 1 /* non-empty, need --More-- */ -#define TOPLINE_NON_EMPTY 2 /* non-empty, no --More-- required */ -#define TOPLINE_SPECIAL_PROMPT 3 /* special prompt state */ - /* special key functions */ enum nh_keyfunc { NHKF_ESC = 0, diff --git a/include/extern.h b/include/extern.h index 8463293d5..8ee9b9917 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1931,6 +1931,7 @@ E void VDECL(verbalize, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(raw_printf, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(impossible, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(config_error_add, (const char *, ...)) PRINTF_F(1, 2); +E void FDECL(nhassert_failed, (const char *, int)); /* ### polyself.c ### */ diff --git a/include/global.h b/include/global.h index f493d8a3e..509ffacea 100644 --- a/include/global.h +++ b/include/global.h @@ -380,5 +380,10 @@ struct savefile_info { #define nhassert(e) ((void)0) #endif +/* Supply nhassert macro if not supplied by port */ +#ifndef nhassert +#define nhassert(expression) (void)((!!(expression)) || \ + (nhassert_failed(__FILE__, __LINE__), 0)) +#endif #endif /* GLOBAL_H */ diff --git a/include/ntconf.h b/include/ntconf.h index 033cfb5d2..84188f7a9 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -134,6 +134,8 @@ extern void NDECL(getlock); #ifndef HAS_STDINT_H #define HAS_STDINT_H /* force include of stdint.h in integer.h */ #endif +/* Turn on some additional warnings */ +#pragma warning(3:4389) #endif /* _MSC_VER */ /* The following is needed for prototypes of certain functions */ @@ -146,14 +148,6 @@ extern void NDECL(getlock); #define strncmpi(a, b, c) strnicmp(a, b, c) #endif -#ifdef _MSC_VER -/* Visual Studio defines this in their own headers, which we don't use */ -#ifndef snprintf -#define snprintf _snprintf -#pragma warning( \ - disable : 4996) /* deprecation warning suggesting snprintf_s */ -#endif -#endif #include #include @@ -274,17 +268,17 @@ extern int FDECL(set_win32_option, (const char *, const char *)); extern int FDECL(alternative_palette, (char *)); #endif -#ifdef NDEBUG -#define nhassert(expression) ((void)0) -#else -extern void FDECL(nhassert_failed, (const char * exp, const char * file, - int line)); - -#define nhassert(expression) (void)((!!(expression)) || \ - (nhassert_failed(#expression, __FILE__, __LINE__), 0)) -#endif - #define nethack_enter(argc, argv) nethack_enter_winnt() extern void FDECL(nethack_exit, (int)) NORETURN; extern boolean FDECL(file_exists, (const char *)); + +/* Override the default version of nhassert. The default version is unable + * to generate a string form of the expression due to the need to be + * compatible with compilers which do not support macro stringization (i.e. + * #x to turn x into its string form). + */ +extern void FDECL(nt_assert_failed, (const char *, const char *, int)); +#define nhassert(expression) (void)((!!(expression)) || \ + (nt_assert_failed(#expression, __FILE__, __LINE__), 0)) + #endif /* NTCONF_H */ diff --git a/include/wintty.h b/include/wintty.h index 6994fc93f..e6388ec0d 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -50,6 +50,12 @@ struct WinDesc { #define WIN_STOP 1 /* for NHW_MESSAGE; stops output */ #define WIN_LOCKHISTORY 2 /* for NHW_MESSAGE; suppress history updates */ +/* topline states */ +#define TOPLINE_EMPTY 0 /* empty */ +#define TOPLINE_NEED_MORE 1 /* non-empty, need --More-- */ +#define TOPLINE_NON_EMPTY 2 /* non-empty, no --More-- required */ +#define TOPLINE_SPECIAL_PROMPT 3 /* special prompt state */ + /* descriptor for tty-based displays -- all the per-display data */ struct DisplayDesc { short rows, cols; /* width and height of tty display */ diff --git a/src/allmain.c b/src/allmain.c index eff7eaa51..ce9f0e6c5 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -881,7 +881,7 @@ enum earlyarg e_arg; * optimization so that display output * can be debugged without buffering. */ -void +STATIC_OVL void debug_fields(opts) const char *opts; { diff --git a/src/apply.c b/src/apply.c index 1205a7499..79f259002 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1595,7 +1595,7 @@ int x,y; && is_valid_jump_pos(x, y, g.jumping_is_magic, FALSE)); } -void +STATIC_OVL void display_jump_positions(state) int state; { @@ -2848,7 +2848,7 @@ static const char cant_reach[] = "can't reach that spot from here."; /* find pos of monster in range, if only one monster */ -boolean +STATIC_OVL boolean find_poleable_mon(pos, min_range, max_range) coord *pos; int min_range, max_range; @@ -2901,7 +2901,7 @@ int x, y; && distu(x, y) <= g.polearm_range_max); } -void +STATIC_OVL void display_polearm_positions(state) int state; { diff --git a/src/botl.c b/src/botl.c index c73d3037f..79601bbbe 100644 --- a/src/botl.c +++ b/src/botl.c @@ -520,7 +520,7 @@ STATIC_VAR struct istat_s initblstats[MAXBLSTATS] = { * without STATUS_HILITES. */ -void +STATIC_OVL void bot_via_windowport() { char buf[BUFSZ]; @@ -2769,7 +2769,7 @@ status_hilite_linestr_gather() } -char * +STATIC_OVL char * status_hilite2str(hl) struct hilite_s *hl; { diff --git a/src/cmd.c b/src/cmd.c index 1aed1ea61..a78de13c8 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2567,7 +2567,7 @@ int final; } /* attributes: intrinsics and the like, other non-obvious capabilities */ -void +STATIC_OVL void attributes_enlightenment(unused_mode, final) int unused_mode UNUSED; int final; diff --git a/src/display.c b/src/display.c index 8da876c66..61c94a2d9 100644 --- a/src/display.c +++ b/src/display.c @@ -897,7 +897,7 @@ xchar x, y; } } -int +STATIC_OVL int tether_glyph(x, y) int x, y; { diff --git a/src/hack.c b/src/hack.c index 9c08be267..8bd90c8d1 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1341,7 +1341,7 @@ domove() g.domove_attempting = 0L; } -void +STATIC_OVL void domove_core() { register struct monst *mtmp; @@ -1939,7 +1939,7 @@ domove_core() } } -void +STATIC_OVL void maybe_smudge_engr(x1,y1,x2,y2) int x1, y1, x2, y2; { diff --git a/src/isaac64.c b/src/isaac64.c index 9ccb0db55..4d19335a3 100644 --- a/src/isaac64.c +++ b/src/isaac64.c @@ -19,7 +19,9 @@ #define ISAAC64_MASK ((uint64_t)0xFFFFFFFFFFFFFFFFULL) #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) +#if !defined(HAS_INLINE) #define HAS_INLINE +#endif #else # if (defined(__GNUC__) && __GNUC__ >= 2 && !defined(inline)) # define inline __inline__ diff --git a/src/makemon.c b/src/makemon.c index 4c867fc0d..726b671d3 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1033,7 +1033,7 @@ newmextra() return mextra; } -boolean +STATIC_OVL boolean makemon_rnd_goodpos(mon, gpflags, cc) struct monst *mon; unsigned gpflags; diff --git a/src/mkmaze.c b/src/mkmaze.c index 5f09d1bb3..a866ad88e 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -613,7 +613,7 @@ fixup_special() g.num_lregions = 0; } -void +STATIC_OVL void check_ransacked(s) char *s; { @@ -624,7 +624,7 @@ char *s; #define ORC_LEADER 1 static const char *orcfruit[] = { "paddle cactus", "dwarven root" }; -void +STATIC_OVL void migrate_orc(mtmp, mflags) struct monst *mtmp; unsigned long mflags; @@ -689,7 +689,7 @@ struct monst *mtmp; add_to_minv(mtmp, otmp); } } -void +STATIC_OVL void migr_booty_item(otyp, gang) int otyp; const char *gang; @@ -710,7 +710,7 @@ const char *gang; } } -void +STATIC_OVL void stolen_booty(VOID_ARGS) { char *gang, gang_name[BUFSZ]; diff --git a/src/mon.c b/src/mon.c index d6e45b722..c65972a86 100644 --- a/src/mon.c +++ b/src/mon.c @@ -43,7 +43,7 @@ const char *warnings[] = { #endif /* 0 */ -void +STATIC_OVL void sanity_check_single_mon(mtmp, chk_geno, msg) struct monst *mtmp; boolean chk_geno; @@ -2733,7 +2733,7 @@ struct monst *mtmp; return; } -void +STATIC_OVL void deal_with_overcrowding(mtmp) struct monst *mtmp; { diff --git a/src/objnam.c b/src/objnam.c index 1991e8e00..6660d42f6 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -411,7 +411,7 @@ struct obj *obj; return xname_flags(obj, CXN_NORMAL); } -char * +STATIC_OVL char * xname_flags(obj, cxn_flags) register struct obj *obj; unsigned cxn_flags; /* bitmask of CXN_xxx values */ @@ -2570,7 +2570,7 @@ const char *oldstr; return bp; } -boolean +STATIC_OVL boolean badman(basestr, to_plural) const char *basestr; boolean to_plural; /* true => makeplural, false => makesingular */ diff --git a/src/options.c b/src/options.c index 9176d0f76..b62bc7e01 100644 --- a/src/options.c +++ b/src/options.c @@ -1589,7 +1589,7 @@ int typ; return (char *) 0; } -int +STATIC_OVL int query_msgtype() { winid tmpwin; @@ -1783,7 +1783,7 @@ const char *errmsg; return retval; } -boolean +STATIC_OVL boolean add_menu_coloring_parsed(str, c, a) char *str; int c, a; diff --git a/src/pager.c b/src/pager.c index b4b693f78..c98dff5bb 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1409,7 +1409,7 @@ static const char *suptext2[] = { (char *) 0, }; -void +STATIC_OVL void do_supplemental_info(name, pm, without_asking) char *name; struct permonst *pm; @@ -1885,61 +1885,61 @@ docontact(VOID_ARGS) destroy_nhwindow(cwin); } -void +STATIC_OVL void dispfile_help(VOID_ARGS) { display_file(HELP, TRUE); } -void +STATIC_OVL void dispfile_shelp(VOID_ARGS) { display_file(SHELP, TRUE); } -void +STATIC_OVL void dispfile_optionfile(VOID_ARGS) { display_file(OPTIONFILE, TRUE); } -void +STATIC_OVL void dispfile_license(VOID_ARGS) { display_file(LICENSE, TRUE); } -void +STATIC_OVL void dispfile_debughelp(VOID_ARGS) { display_file(DEBUGHELP, TRUE); } -void +STATIC_OVL void hmenu_doextversion(VOID_ARGS) { (void) doextversion(); } -void +STATIC_OVL void hmenu_dohistory(VOID_ARGS) { (void) dohistory(); } -void +STATIC_OVL void hmenu_dowhatis(VOID_ARGS) { (void) dowhatis(); } -void +STATIC_OVL void hmenu_dowhatdoes(VOID_ARGS) { (void) dowhatdoes(); } -void +STATIC_OVL void hmenu_doextlist(VOID_ARGS) { (void) doextlist(); diff --git a/src/pickup.c b/src/pickup.c index 1af0c51e8..8ae5ca59c 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1697,7 +1697,7 @@ int x, y; return FALSE; } -int +STATIC_OVL int do_loot_cont(cobjp, cindex, ccount) struct obj **cobjp; int cindex, ccount; /* index of this container (1..N), number of them (N) */ diff --git a/src/pline.c b/src/pline.c index 6f3bfa537..99ddb17d2 100644 --- a/src/pline.c +++ b/src/pline.c @@ -572,4 +572,21 @@ VA_DECL(const char *, str) #endif } +/* nhassert_failed is called when an nhassert's condition is false */ +void +nhassert_failed(filepath, line) + const char * filepath; + int line; +{ + const char * filename; + + /* attempt to get filename from path. TODO: we really need a port provided + * function to return a filename from a path */ + filename = strrchr(filepath, '/'); + filename = (filename == NULL ? strrchr(filepath, '\\') : filename); + filename = (filename == NULL ? filepath : filename + 1); + + impossible("nhassert failed in file '%s' at line %d", filename, line); +} + /*pline.c*/ diff --git a/src/questpgr.c b/src/questpgr.c index 97e9b106d..e2cdc8314 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -569,7 +569,7 @@ int how; putmsghistory(out_line, FALSE); } -boolean +STATIC_OVL boolean skip_pager(common) boolean common; { diff --git a/src/shk.c b/src/shk.c index fdd078485..ab1672faa 100644 --- a/src/shk.c +++ b/src/shk.c @@ -2719,7 +2719,7 @@ boolean ininv, dummy, silent; } } -void +STATIC_OVL void append_honorific(buf) char *buf; { diff --git a/src/teleport.c b/src/teleport.c index d32fb0990..037be54fb 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1140,10 +1140,10 @@ struct monst *mtmp; sent out of his room (caller might resort to goodpos() if we report failure here, so this isn't full prevention) */ if (mtmp->isshk && inhishop(mtmp)) { - if (levl[x][y].roomno != ESHK(mtmp)->shoproom) + if (levl[x][y].roomno != (unsigned char) ESHK(mtmp)->shoproom) return FALSE; } else if (mtmp->ispriest && inhistemple(mtmp)) { - if (levl[x][y].roomno != EPRI(mtmp)->shroom) + if (levl[x][y].roomno != (unsigned char) EPRI(mtmp)->shroom) return FALSE; } /* current location is */ diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index e9041262d..8d513c59e 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -475,23 +475,6 @@ char *buf; } #endif /* RUNTIME_PORT_ID */ -/* nhassert_failed is called when an nhassert's condition is false */ -void nhassert_failed(const char * exp, const char * file, int line) -{ - char message[128]; - _snprintf(message, sizeof(message), - "NHASSERT(%s) in '%s' at line %d\n", exp, file, line); - - if (IsDebuggerPresent()) { - OutputDebugStringA(message); - DebugBreak(); - } - - // strip off the newline - message[strlen(message) - 1] = '\0'; - error(message); -} - void nethack_exit(code) int code; @@ -725,6 +708,23 @@ sys_random_seed(VOID_ARGS) } return ourseed; } + +/* nt_assert_failed is called when an nhassert's condition is false */ +void +nt_assert_failed(expression, filepath, line) + const char * expression; + const char * filepath; + int line; +{ + const char * filename; + + /* get file name from path */ + filename = strrchr(filepath, '\\'); + filename = (filename == NULL ? filepath : filename + 1); + impossible("nhassert(%s) failed in file '%s' at line %d", + expression, filename, line); +} + #endif /* WIN32 */ /*winnt.c*/ diff --git a/util/makedefs.c b/util/makedefs.c index fb5dce367..953fdddd1 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -938,7 +938,7 @@ unsigned long old_rumor_offset; return rumor_offset; } -void +static void do_rnd_access_file(fname) const char *fname; { @@ -1403,7 +1403,7 @@ do_date() return; } -boolean +static boolean get_gitinfo(githash, gitbranch) char *githash, *gitbranch; { diff --git a/win/tty/topl.c b/win/tty/topl.c index 7294f8bfd..334900d5e 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -139,7 +139,7 @@ const char *str; putsyms(str); cl_end(); ttyDisplay->toplin = TOPLINE_NEED_MORE; - if (ttyDisplay->cury && otoplin != 3) + if (ttyDisplay->cury && otoplin != TOPLINE_SPECIAL_PROMPT) more(); } @@ -204,12 +204,15 @@ more() { struct WinDesc *cw = wins[WIN_MESSAGE]; - /* avoid recursion -- only happens from interrupts */ - if (ttyDisplay->inmore++) - return; if (iflags.debug_fuzzer) return; + /* avoid recursion -- only happens from interrupts */ + if (ttyDisplay->inmore) + return; + + ttyDisplay->inmore++; + if (ttyDisplay->toplin) { tty_curs(BASE_WINDOW, cw->curx + 1, cw->cury); if (cw->curx >= CO - 8) @@ -256,7 +259,8 @@ register const char *bp; && cw->cury == 0 && n0 + (int) strlen(g.toplines) + 3 < CO - 8 /* room for --More-- */ && (notdied = strncmp(bp, "You die", 7)) != 0) { - Strcat(g.toplines, " "); + nhassert((long) strlen(g.toplines) == cw->curx); + Strcat(toplines, " "); Strcat(g.toplines, bp); cw->curx += 2; if (!(cw->flags & WIN_STOP)) @@ -309,6 +313,7 @@ char c; if (ttyDisplay->curx == 0 && ttyDisplay->cury > 0) tty_curs(BASE_WINDOW, CO, (int) ttyDisplay->cury - 1); backsp(); + nhassert(ttyDisplay->curx > 0); ttyDisplay->curx--; cw->curx = ttyDisplay->curx; return; @@ -686,6 +691,13 @@ boolean restoring_msghist; } if (msg) { + /* Caller is asking us to remember a top line that needed more. + Should we call more? This can happen when the player has set + iflags.force_invmenu and they attempt to shoot with nothing in + the quiver. */ + if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; + /* move most recent message to history, make this become most recent */ remember_topl(); Strcpy(g.toplines, msg); @@ -693,6 +705,9 @@ boolean restoring_msghist; dumplogmsg(g.toplines); #endif } else if (snapshot_mesgs) { + nhassert(ttyDisplay == NULL || + ttyDisplay->toplin != TOPLINE_NEED_MORE); + /* done putting arbitrary messages in; put the snapshot ones back */ for (idx = 0; snapshot_mesgs[idx]; ++idx) { remember_topl(); diff --git a/win/tty/wintty.c b/win/tty/wintty.c index e4f1649e2..fc4cb79eb 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -2319,7 +2319,7 @@ boolean blocking; /* with ttys, all windows are blocking */ more(); ttyDisplay->toplin = TOPLINE_NEED_MORE; /* more resets this */ tty_clear_nhwindow(window); - /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ + nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); } else ttyDisplay->toplin = TOPLINE_EMPTY; cw->curx = cw->cury = 0; @@ -2407,7 +2407,7 @@ winid window; case NHW_MESSAGE: if (ttyDisplay->toplin != TOPLINE_EMPTY) tty_display_nhwindow(WIN_MESSAGE, TRUE); - /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ + nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); /*FALLTHRU*/ case NHW_STATUS: case NHW_BASE: @@ -3162,7 +3162,7 @@ const char *mesg; more(); ttyDisplay->toplin = TOPLINE_NEED_MORE; /* more resets this */ tty_clear_nhwindow(WIN_MESSAGE); - /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ + nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); } /* normally means skip further messages, but in this case it means cancel the current prompt; any other messages should @@ -4130,7 +4130,7 @@ boolean force_update; * must be updated because they need to change. * This is now done at an individual field case-by-case level. */ -boolean +STATIC_OVL boolean check_fields(forcefields, sz) boolean forcefields; int sz[3];