From 81d73ce417dda6a98e2e918e06922e68b67c53f7 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 18 Dec 2018 19:11:36 -0800 Subject: [PATCH 1/3] disable gcc's __attribute__((warn_unused_result)) Casting to (void) to discard a function return value doesn't satisfy gcc's -Wunused-result (which we aren't enabling but is apparently being activated for particular functions by glibc header files). Turn it into a no-op to suppress three dozen warnings from Travis builds. --- include/tradstdc.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/tradstdc.h b/include/tradstdc.h index d1b1f250c..e6a8f3e8f 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -405,6 +405,10 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ #if __GNUC__ >= 3 #define UNUSED __attribute__((unused)) #define NORETURN __attribute__((noreturn)) +/* disable gcc's __attribute__((__warn_unused_result__)) since explicitly + discarding the result by casting to (void) is not accepted as a 'use' */ +#define __warn_unused_result__ /*empty*/ +#define warn_unused_result /*empty*/ #endif #endif From b32c93cacdc68997882f295bbf5ea2c5a9a7faec Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 19 Dec 2018 03:06:40 -0800 Subject: [PATCH 2/3] fix #H2636 - vault guard "fakecorr overflow" panic Another 6.5 year old report. This one from Steven Melenchuk told how to reproduce C343-23 which is still open on our 'known bugs' page. (I've no idea whether the original bug report came through the contact page, and if so, what its assigned number was.) I didn't try to solve this one, I just confirmed that it could be reproduced and took the fix from grunthack at github. He didn't menion a fix at the time but implemented one before abandoing his variant. (Others kept it going afterwards; fix was during his time.) The overflow occurred when the guard couldn't figure out where to move to next and just repeatedly 'moved' to his current location until the maximum number of fake corridor spots was used up. The fix detects not knowing where to go next and explicitly choosing a new destination. Original problem could be reproduced by teleporting into the vault, digging out a wall and two spaces of stone in a straight line, then going back into the vault to wait for a guard. When he shows up: answer, drop gold, follow. If the guard's path walks through both dug spaces, he will stop waiting for the hero. But hero is in between the guard and the gap in the vault wall and can't advance; guard has reached a persistent corridor so doesn't know where to go next. Have hero wait for 125-ish more turns and then game panicks. The code was 3.4.3 vintage so needed thorough reformatting, but not any actual changes (unless I've overlooked something). --- doc/fixes36.2 | 3 ++ src/vault.c | 126 ++++++++++++++++++++++++++++---------------------- 2 files changed, 73 insertions(+), 56 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index f499a6351..d7348a2ee 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -286,6 +286,9 @@ while levitating inside a shop, throwing an unpaid item and having recoil move the shopkeeper and summon kops diluted potion of oil is less effective when filling lamps (adds less fuel) or burning (lasts less long) or exploding (inflicts less damage) +apply fix from grunthack to prevent panic "fakecorr overflow" when vault guard + couldn't figure out how to lead the hero from vault to civilization; + fixes longstanding bug C343-23 Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/src/vault.c b/src/vault.c index 0e811d117..c23f55595 100644 --- a/src/vault.c +++ b/src/vault.c @@ -1,17 +1,17 @@ -/* NetHack 3.6 vault.c $NHDT-Date: 1544608469 2018/12/12 09:54:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.57 $ */ +/* NetHack 3.6 vault.c $NHDT-Date: 1545217597 2018/12/19 11:06:37 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.58 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" -STATIC_DCL struct monst *NDECL(findgd); - STATIC_DCL boolean FDECL(clear_fcorr, (struct monst *, BOOLEAN_P)); STATIC_DCL void FDECL(blackout, (int, int)); STATIC_DCL void FDECL(restfakecorr, (struct monst *)); STATIC_DCL void FDECL(parkguard, (struct monst *)); STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *, int, int)); +STATIC_DCL struct monst *NDECL(findgd); +STATIC_DCL boolean FDECL(find_guard_dest, (struct monst *, xchar *, xchar *)); STATIC_DCL void FDECL(move_gold, (struct obj *, int)); STATIC_DCL void FDECL(wallify_vault, (struct monst *)); STATIC_DCL void FDECL(gd_mv_monaway, (struct monst *, int, int)); @@ -232,6 +232,44 @@ char *array; return '\0'; } +STATIC_OVL boolean +find_guard_dest(guard, rx, ry) +struct monst *guard; +xchar *rx, *ry; +{ + register int x, y, dd, lx = 0, ly = 0; + + for (dd = 2; (dd < ROWNO || dd < COLNO); dd++) { + for (y = u.uy - dd; y <= u.uy + dd; ly = y, y++) { + if (y < 0 || y > ROWNO - 1) + continue; + for (x = u.ux - dd; x <= u.ux + dd; lx = x, x++) { + if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd) + x = u.ux + dd; + if (x < 1 || x > COLNO - 1) + continue; + if (guard && ((x == guard->mx && y == guard->my) + || (guard->isgd && in_fcorridor(guard, x, y)))) + continue; + if (levl[x][y].typ == CORR) { + lx = (x < u.ux) ? x + 1 : (x > u.ux) ? x - 1 : x; + ly = (y < u.uy) ? y + 1 : (y > u.uy) ? y - 1 : y; + if (levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR) + goto incr_radius; + *rx = x; + *ry = y; + return TRUE; + } + } + } + incr_radius: + ; + } + impossible("Not a single corridor on this level?"); + tele(); + return FALSE; +} + void invault() { @@ -252,49 +290,14 @@ invault() if (++u.uinvault % VAULT_GUARD_TIME == 0 && !guard) { /* if time ok and no guard now. */ char buf[BUFSZ]; - register int x, y, dd, gx, gy; - int lx = 0, ly = 0; + register int x, y, gx, gy; + xchar rx, ry; long umoney; /* first find the goal for the guard */ - for (dd = 2; (dd < ROWNO || dd < COLNO); dd++) { - for (y = u.uy - dd; y <= u.uy + dd; ly = y, y++) { - if (y < 0 || y > ROWNO - 1) - continue; - for (x = u.ux - dd; x <= u.ux + dd; lx = x, x++) { - if (y != u.uy - dd && y != u.uy + dd && x != u.ux - dd) - x = u.ux + dd; - if (x < 1 || x > COLNO - 1) - continue; - if (levl[x][y].typ == CORR) { - if (x < u.ux) - lx = x + 1; - else if (x > u.ux) - lx = x - 1; - else - lx = x; - if (y < u.uy) - ly = y + 1; - else if (y > u.uy) - ly = y - 1; - else - ly = y; - if (levl[lx][ly].typ != STONE - && levl[lx][ly].typ != CORR) - goto incr_radius; - goto fnd; - } - } - } - incr_radius: - ; - } - impossible("Not a single corridor on this level??"); - tele(); - return; - fnd: - gx = x; - gy = y; + if (!find_guard_dest((struct monst *)0, &rx, &ry)) + return; + gx = rx, gy = ry; /* next find a good place for a door in the wall */ x = u.ux; @@ -621,7 +624,7 @@ gd_move(grd) register struct monst *grd; { int x, y, nx, ny, m, n; - int dx, dy, gx, gy, fci; + int dx, dy, gx = 0, gy = 0, fci; uchar typ; struct rm *crm; struct fakecorridor *fcp; @@ -705,7 +708,7 @@ register struct monst *grd; levl[m][n].typ = egrd->fakecorr[0].ftyp; newsym(m, n); grd->mpeaceful = 0; - letknow: + letknow: if (!cansee(grd->mx, grd->my) || !mon_visible(grd)) You_hear("%s.", m_carrying(grd, TIN_WHISTLE) @@ -848,10 +851,10 @@ register struct monst *grd; goto proceed; } } - nextnxy: + nextnxy: ; } -nextpos: + nextpos: nx = x; ny = y; gx = egrd->gdx; @@ -892,19 +895,30 @@ nextpos: break; } crm->typ = CORR; -proceed: + proceed: newspot = TRUE; unblock_point(nx, ny); /* doesn't block light */ if (cansee(nx, ny)) newsym(nx, ny); - fcp = &(egrd->fakecorr[egrd->fcend]); - if (egrd->fcend++ == FCSIZ) - panic("fakecorr overflow"); - fcp->fx = nx; - fcp->fy = ny; - fcp->ftyp = typ; -newpos: + if ((nx != gx || ny != gy) || (grd->mx != gx || grd->my != gy)) { + fcp = &(egrd->fakecorr[egrd->fcend]); + if (egrd->fcend++ == FCSIZ) + panic("fakecorr overflow"); + fcp->fx = nx; + fcp->fy = ny; + fcp->ftyp = typ; + } else if (!egrd->gddone) { + /* We're stuck, so try to find a new destination. */ + if (!find_guard_dest(grd, &egrd->gdx, &egrd->gdy) + || (egrd->gdx == gx && egrd->gdy == gy)) { + pline("%s, confused, disappears.", Monnam(grd)); + disappear_msg_seen = TRUE; + goto cleanup; + } else + goto nextpos; + } + newpos: gd_mv_monaway(grd, nx, ny); if (egrd->gddone) { /* The following is a kludge. We need to keep */ @@ -916,7 +930,7 @@ newpos: /* to avoid a check at the top of this function. */ /* At the end of the process, the guard is killed */ /* in restfakecorr(). */ - cleanup: + cleanup: x = grd->mx, y = grd->my; see_guard = canspotmon(grd); parkguard(grd); /* move to <0,0> */ From a2296d043fa57d94dec833ed0d224b83bbdc79aa Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 19 Dec 2018 06:43:00 -0500 Subject: [PATCH 3/3] eliminate sys/share/pcsys.c from Windows build Windows build was actually only using a single function in there, so just add a similar function to sys/winnt/winnt.c and eliminate the need for including sys/share/pcsys.c in the build. --- sys/share/pcsys.c | 26 +++----------------------- sys/winnt/Makefile.msc | 7 +++---- sys/winnt/winnt.c | 20 ++++++++++++++++++++ win/win32/vs2017/NetHack.vcxproj | 1 - win/win32/vs2017/NetHackW.vcxproj | 1 - 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index 8a99b181e..14d0e4591 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -3,7 +3,7 @@ /* NetHack may be freely redistributed. See license for details. */ /* - * System related functions for MSDOS, OS/2, TOS, and Windows NT + * System related functions for MSDOS, OS/2, TOS */ #define NEED_VARARGS @@ -28,7 +28,7 @@ #define filesize filesize_nh #endif -#if defined(MICRO) || defined(WIN32) || defined(OS2) +#if defined(MICRO) || defined(OS2) void FDECL(nethack_exit, (int)); #else #define nethack_exit exit @@ -51,11 +51,7 @@ STATIC_DCL boolean NDECL(comspec_exists); #endif #endif -#ifdef WIN32 -extern int GUILaunched; /* from nttty.c */ -#endif - -#if defined(MICRO) || defined(WIN32) +#if defined(MICRO) void flushout() @@ -391,7 +387,6 @@ char *name; return; } -#ifndef WIN32 void getreturn(str) const char *str; @@ -420,7 +415,6 @@ VA_DECL(const char *, fmt) VA_END(); return; } -#endif /* * Follow the PATH, trying to fopen the file. @@ -507,10 +501,8 @@ msexit() flushout(); #ifndef TOS -#ifndef WIN32 enable_ctrlP(); /* in case this wasn't done */ #endif -#endif #ifdef MFLOPPY if (ramdisk) copybones(TOPERM); @@ -526,18 +518,6 @@ msexit() if (colors_changed) restore_colors(); #endif -#endif -#ifdef WIN32 - /* Only if we started from the GUI, not the command prompt, - * we need to get one last return, so the score board does - * not vanish instantly after being created. - * GUILaunched is defined and set in nttty.c. - */ - synch_cursor(); - if (GUILaunched) - getreturn("to end"); - synch_cursor(); - getreturn_enabled = TRUE; #endif wait_synch(); return; diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 19f406a52..292c8b663 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -233,7 +233,7 @@ VOBJ24 = $(O)track.o $(O)trap.o $(O)u_init.o $(O)uhitm.o VOBJ25 = $(O)vault.o $(O)vis_tab.o $(O)vision.o $(O)weapon.o VOBJ26 = $(O)were.o $(O)wield.o $(O)windows.o $(O)wizard.o VOBJ27 = $(O)worm.o $(O)worn.o $(O)write.o $(O)zap.o -VOBJ28 = $(O)win10.o $(O)safeproc.o $(O)windmain.o +VOBJ28 = DLBOBJ = $(O)dlb.o @@ -248,7 +248,8 @@ CURSESOBJ= $(O)cursdial.o $(O)cursinit.o $(O)cursinvt.o $(O)cursmain.o \ $(O)cursmesg.o $(O)cursmisc.o $(O)cursstat.o $(O)curswins.o !ENDIF -SOBJ = $(O)winnt.o $(O)pcsys.o $(SOUND) $(O)nhlan.o +SOBJ = $(O)windmain.o $(O)winnt.o $(O)win10.o \ + $(O)safeproc.o $(O)nhlan.o $(SOUND) OBJS = $(VOBJ01) $(VOBJ02) $(VOBJ03) $(VOBJ04) $(VOBJ05) \ $(VOBJ06) $(VOBJ07) $(VOBJ08) $(VOBJ09) $(VOBJ10) \ @@ -1511,8 +1512,6 @@ $(O)\curswins.c: $(WCURSES)\curswins.c $(WCURSES)\curswins.h $(INCL)\wincurs.h $(O)tos.o: ..\sys\atari\tos.c $(HACK_H) $(INCL)\tcap.h @$(CC) $(cflagsBuild) -Fo$@ ..\sys\atari\tos.c -$(O)pcsys.o: ..\sys\share\pcsys.c $(HACK_H) - @$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pcsys.c $(O)pctty.o: ..\sys\share\pctty.c $(HACK_H) @$(CC) $(cflagsBuild) -Fo$@ ..\sys\share\pctty.c $(O)random.o: ..\sys\share\random.c $(HACK_H) diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index c75e53c47..035ea7457 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -660,6 +660,26 @@ const char *window_opt; } return 0; } + +/* + * Add a backslash to any name not ending in /, \ or : There must + * be room for the \ + */ +void +append_slash(name) +char *name; +{ + char *ptr; + + if (!*name) + return; + ptr = name + (strlen(name) - 1); + if (*ptr != '\\' && *ptr != '/' && *ptr != ':') { + *++ptr = '\\'; + *++ptr = '\0'; + } + return; +} #endif /* WIN32 */ /*winnt.c*/ diff --git a/win/win32/vs2017/NetHack.vcxproj b/win/win32/vs2017/NetHack.vcxproj index d5feb73b7..ee086fcc5 100644 --- a/win/win32/vs2017/NetHack.vcxproj +++ b/win/win32/vs2017/NetHack.vcxproj @@ -151,7 +151,6 @@ - diff --git a/win/win32/vs2017/NetHackW.vcxproj b/win/win32/vs2017/NetHackW.vcxproj index 79a25df44..93c2e447b 100644 --- a/win/win32/vs2017/NetHackW.vcxproj +++ b/win/win32/vs2017/NetHackW.vcxproj @@ -146,7 +146,6 @@ -