Merge branch 'master' into NetHack-3.7

This commit is contained in:
nhmall
2019-07-14 09:57:32 -04:00
18 changed files with 517 additions and 40 deletions

View File

@@ -470,6 +470,17 @@ struct early_opt {
boolean valallowed; boolean valallowed;
}; };
struct ptr_array {
size_t length;
size_t max_length;
void ** elements;
};
typedef struct ptr_array ptr_array_t;
/* logging verbosity levels */
#define LOG_MINIMAL 0
#define LOG_VERBOSE 1
/* special key functions */ /* special key functions */
enum nh_keyfunc { enum nh_keyfunc {
NHKF_ESC = 0, NHKF_ESC = 0,

View File

@@ -28,6 +28,13 @@ E void FDECL(welcome, (BOOLEAN_P));
E time_t NDECL(get_realtime); E time_t NDECL(get_realtime);
E int FDECL(argcheck, (int, char **, enum earlyarg)); E int FDECL(argcheck, (int, char **, enum earlyarg));
E void NDECL(early_init); E void NDECL(early_init);
E void NDECL(fuzzer_start);
E void NDECL(fuzzer_stop);
E void NDECL(fuzzer_toggle);
E void VDECL(fuzzer_log, (int, const char *, ...)) PRINTF_F(2, 3);
E void NDECL(fuzzer_check);
E void NDECL(fuzzer_auto_start);
E boolean FDECL(fuzzer_msg_history, (const char *));
/* ### apply.c ### */ /* ### apply.c ### */
@@ -951,6 +958,7 @@ E boolean
FDECL(fuzzymatch, (const char *, const char *, const char *, BOOLEAN_P)); FDECL(fuzzymatch, (const char *, const char *, const char *, BOOLEAN_P));
E void FDECL(init_random, (int FDECL((*fn), (int)))); E void FDECL(init_random, (int FDECL((*fn), (int))));
E void FDECL(reseed_random, (int FDECL((*fn), (int)))); E void FDECL(reseed_random, (int FDECL((*fn), (int))));
E void FDECL(set_random, (unsigned long, int FDECL((*fn), (int))));
E time_t NDECL(getnow); E time_t NDECL(getnow);
E int NDECL(getyear); E int NDECL(getyear);
#if 0 #if 0
@@ -969,6 +977,8 @@ E void FDECL(strbuf_append, (strbuf_t *, const char *));
E void FDECL(strbuf_reserve, (strbuf_t *, int)); E void FDECL(strbuf_reserve, (strbuf_t *, int));
E void FDECL(strbuf_empty, (strbuf_t *)); E void FDECL(strbuf_empty, (strbuf_t *));
E void FDECL(strbuf_nl_to_crlf, (strbuf_t *)); E void FDECL(strbuf_nl_to_crlf, (strbuf_t *));
E struct ptr_array * FDECL(ptr_array_new, (size_t length));
E void FDECL(ptr_array_free, (struct ptr_array *));
/* ### invent.c ### */ /* ### invent.c ### */
@@ -2157,6 +2167,7 @@ E int FDECL(rnd, (int));
E int FDECL(d, (int, int)); E int FDECL(d, (int, int));
E int FDECL(rne, (int)); E int FDECL(rne, (int));
E int FDECL(rnz, (int)); E int FDECL(rnz, (int));
E unsigned long NDECL(rul);
/* ### role.c ### */ /* ### role.c ### */

View File

@@ -433,6 +433,10 @@ struct instance_flags {
chosen_windowport[], but do not switch to chosen_windowport[], but do not switch to
it in the midst of options processing */ it in the midst of options processing */
boolean obsolete; /* obsolete options can point at this, it isn't used */ boolean obsolete; /* obsolete options can point at this, it isn't used */
boolean fuzzer_auto_start; /* start fuzzer automatically */
int fuzzer_stop_and_save; /* move when fuzzer stops and saves game */
boolean fuzzer_saving; /* fuzzer is saving game */
int verbose_logging_start; /* move when verbose fuzzer logging starts */
}; };
/* /*

View File

@@ -4,7 +4,7 @@
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
/* various code that was replicated in *main.c */ /* various code that was replicated in *main.c */
#define NEED_VARARGS
#include "hack.h" #include "hack.h"
#include <ctype.h> #include <ctype.h>
@@ -441,6 +441,8 @@ boolean resuming;
#ifdef MAIL #ifdef MAIL
ckmailstatus(); ckmailstatus();
#endif #endif
fuzzer_check();
rhack((char *) 0); rhack((char *) 0);
} }
if (u.utotype) /* change dungeon level */ if (u.utotype) /* change dungeon level */
@@ -588,6 +590,8 @@ newgame()
{ {
int i; int i;
fuzzer_auto_start();
#ifdef MFLOPPY #ifdef MFLOPPY
gameDiskPrompt(); gameDiskPrompt();
#endif #endif
@@ -927,4 +931,131 @@ const char *opts;
#endif #endif
return; return;
} }
static FILE * g_fuzzer_log_file = NULL;
static int g_fuzzer_log_level = LOG_MINIMAL;
/* fuzzer_start() starts the fuzzer opening the fuzzer log file */
void
fuzzer_start()
{
if (!iflags.debug_fuzzer) {
const char * fq_replay;
iflags.debug_fuzzer = TRUE;
iflags.fuzzer_auto_start = FALSE;
nhassert(g_fuzzer_log_file == NULL);
fq_replay = fqname("fuzzer.log", SAVEPREFIX, 0);
g_fuzzer_log_file = fopen(fq_replay, "w");
}
}
/* fuzzer_stop() stops the fuzzer and close the fuzzer log file */
void
fuzzer_stop()
{
if (iflags.debug_fuzzer) {
if(g_fuzzer_log_file != NULL) {
fclose(g_fuzzer_log_file);
g_fuzzer_log_file = NULL;
}
}
}
/* fuzzer_toggle() toggles fuzzer state */
void
fuzzer_toggle()
{
if (iflags.debug_fuzzer)
fuzzer_stop();
else
fuzzer_start();
}
/* fuzzer_log() is used to place messages in the file 'fuzzer.log'. This
* log is the primary tool for monitoring fuzzer activity and tracking down
* issues that the fuzzer is able to reproduce.
*/
void
fuzzer_log
VA_DECL2(int, level, const char *, str)
{
VA_START(str);
VA_INIT(str, char *);
if (!g_fuzzer_log_file)
return;
if (iflags.verbose_logging_start != 0 && g.moves >= iflags.verbose_logging_start)
g_fuzzer_log_level = LOG_VERBOSE;
if (level <= g_fuzzer_log_level)
Vfprintf(g_fuzzer_log_file, str, VA_ARGS);
VA_END();
}
/* fuzzer_check() is called prior to rhack(0) to allow the fuzzer to
* check if it should stop and to allow it to reseed the game.
*/
void
fuzzer_check()
{
if (iflags.debug_fuzzer)
{
if (g.moves >= iflags.fuzzer_stop_and_save) {
iflags.fuzzer_saving = TRUE;
dosave0();
exit_nhwindows("Goodbye from the fuzzer...");
fuzzer_stop();
nh_terminate(EXIT_SUCCESS);
}
unsigned long seed = rul();
set_random(seed, rn2);
fuzzer_log(LOG_MINIMAL, "SEED:%ld:%lu\n", g.moves, seed);
}
}
/* fuzzer_auto_start is called when creating a new game to allow
* the fuzzer to start itself.
*/
void
fuzzer_auto_start()
{
if (iflags.fuzzer_auto_start) {
nhassert(!iflags.debug_fuzzer);
fuzzer_start();
unsigned long seed = rul();
set_random(seed, rn2);
fuzzer_log(LOG_MINIMAL, "START:%ld:%lu\n", g.moves, seed);
}
}
/* fuzzer_msg_history is called during save file recovery to allow
* the fuzzer to snoop the messages being recovered. The fuzzer
* saves a seed as a message in save files and this is the mechanism
* used to recover that seed if the fuzzer is being auto started.
*/
boolean
fuzzer_msg_history(msg)
const char * msg;
{
long saved_moves;
unsigned long saved_seed;
if (sscanf(msg, "SEED:%ld:%lu", &saved_moves, &saved_seed) == 2) {
nhassert(saved_moves == g.moves);
if (iflags.fuzzer_auto_start) {
fuzzer_start();
set_random(saved_seed, rn2);
fuzzer_log(LOG_MINIMAL, "START:%ld:%lu\n", g.moves, saved_seed);
}
return TRUE;
}
return FALSE;
}
/*allmain.c*/ /*allmain.c*/

View File

@@ -2516,7 +2516,8 @@ recalc_mapseen()
struct cemetery *bp, **bonesaddr; struct cemetery *bp, **bonesaddr;
struct trap *t; struct trap *t;
unsigned i, ridx; unsigned i, ridx;
int x, y, ltyp, count, atmp; int x, y, ltyp, count;
unsigned int atmp;
/* Should not happen in general, but possible if in the process /* Should not happen in general, but possible if in the process
* of being booted from the quest. The mapseen object gets * of being booted from the quest. The mapseen object gets

View File

@@ -854,7 +854,7 @@ STATIC_DCL struct tm *NDECL(getlt);
/* Sets the seed for the random number generator */ /* Sets the seed for the random number generator */
#ifdef USE_ISAAC64 #ifdef USE_ISAAC64
static void void
set_random(seed, fn) set_random(seed, fn)
unsigned long seed; unsigned long seed;
int FDECL((*fn), (int)); int FDECL((*fn), (int));
@@ -865,7 +865,7 @@ int FDECL((*fn), (int));
#else /* USE_ISAAC64 */ #else /* USE_ISAAC64 */
/*ARGSUSED*/ /*ARGSUSED*/
static void void
set_random(seed, fn) set_random(seed, fn)
unsigned long seed; unsigned long seed;
int FDECL((*fn), (int)) UNUSED; int FDECL((*fn), (int)) UNUSED;
@@ -917,7 +917,7 @@ int FDECL((*fn), (int));
{ {
/* only reseed if we are certain that the seed generation is unguessable /* only reseed if we are certain that the seed generation is unguessable
* by the players. */ * by the players. */
if (has_strong_rngseed) if (has_strong_rngseed && !iflags.debug_fuzzer)
init_random(fn); init_random(fn);
} }
@@ -1108,6 +1108,9 @@ phase_of_the_moon() /* 0-7, with 0: new, 4: full */
register struct tm *lt = getlt(); register struct tm *lt = getlt();
register int epact, diy, goldn; register int epact, diy, goldn;
if(iflags.debug_fuzzer)
return rn2(8);
diy = lt->tm_yday; diy = lt->tm_yday;
goldn = (lt->tm_year % 19) + 1; goldn = (lt->tm_year % 19) + 1;
epact = (11 * goldn + 18) % 30; epact = (11 * goldn + 18) % 30;
@@ -1122,6 +1125,9 @@ friday_13th()
{ {
register struct tm *lt = getlt(); register struct tm *lt = getlt();
if(iflags.debug_fuzzer)
return rn2(30);
/* tm_wday (day of week; 0==Sunday) == 5 => Friday */ /* tm_wday (day of week; 0==Sunday) == 5 => Friday */
return (boolean) (lt->tm_wday == 5 && lt->tm_mday == 13); return (boolean) (lt->tm_wday == 5 && lt->tm_mday == 13);
} }
@@ -1223,4 +1229,38 @@ strbuf_t *strbuf;
} }
} }
ptr_array_t *
ptr_array_new(max_length)
size_t max_length;
{
size_t esize = max_length * sizeof(void *);
ptr_array_t * a = (ptr_array_t *) malloc(sizeof(ptr_array_t) + esize);
a->elements = (void **)(a + 1);
a->length = 0;
a->max_length = max_length;
memset(a->elements, 0, esize);
return a;
}
void
ptr_array_free(a)
ptr_array_t * a;
{
size_t i;
nhassert(a->length <= a->max_length);
for(i = 0; i < a->length; i++)
if(a->elements[i])
free(a->elements[i]);
for (i = a->length; i < a->max_length; i++) {
nhassert(a->elements[i] == NULL);
if(a->elements[i])
free(a->elements[i]);
}
free(a);
}
/*hacklib.c*/ /*hacklib.c*/

View File

@@ -1509,6 +1509,8 @@ NHFILE *nhfp;
if (nhfp->fieldlevel) if (nhfp->fieldlevel)
sfi_str(nhfp, msg, "msghistory", "msg", msgsize); sfi_str(nhfp, msg, "msghistory", "msg", msgsize);
msg[msgsize] = '\0'; msg[msgsize] = '\0';
if(fuzzer_msg_history(msg))
continue;
putmsghistory(msg, TRUE); putmsghistory(msg, TRUE);
++msgcount; ++msgcount;
} }

View File

@@ -56,10 +56,21 @@ int FDECL((*fn), (int));
(int) sizeof seed); (int) sizeof seed);
} }
unsigned long
rul()
{
unsigned long value;
value = (unsigned long) isaac64_next_uint64(&rnglist[CORE].rng_state);
fuzzer_log(LOG_VERBOSE, "RANDOM:%llu\n", value);
return value;
}
static int static int
RND(int x) RND(int x)
{ {
return (isaac64_next_uint64(&rnglist[CORE].rng_state) % x); return (rul() % x);
} }
/* 0 <= rn2(x) < x, but on a different sequence from the "main" rn2; /* 0 <= rn2(x) < x, but on a different sequence from the "main" rn2;
@@ -69,6 +80,8 @@ int
rn2_on_display_rng(x) rn2_on_display_rng(x)
register int x; register int x;
{ {
if (iflags.debug_fuzzer)
return rn2(x);
return (isaac64_next_uint64(&rnglist[DISP].rng_state) % x); return (isaac64_next_uint64(&rnglist[DISP].rng_state) % x);
} }
@@ -94,6 +107,20 @@ register int x;
seed *= 2739110765; seed *= 2739110765;
return (int)((seed >> 16) % (unsigned)x); return (int)((seed >> 16) % (unsigned)x);
} }
unsigned long
rul()
{
#if defined(LINT) && defined(UNIX)
return (unsigned long) rand();
#else /* LINT */
#if defined(UNIX) || defined(RANDOM)
return (unsigned long) Rand();
#else
return (unsigned long) (Rand() >> 3);
#endif /* defined(UNIX) || defined(RANDOM) */
#endif /* LINT */
}
#endif /* USE_ISAAC64 */ #endif /* USE_ISAAC64 */
/* 0 <= rn2(x) < x */ /* 0 <= rn2(x) < x */

View File

@@ -132,7 +132,7 @@ dosave0()
return 0; return 0;
#endif #endif
HUP if (iflags.window_inited) { HUP if (!iflags.debug_fuzzer && iflags.window_inited) {
nh_uncompress(fq_save); nh_uncompress(fq_save);
nhfp = open_savefile(); nhfp = open_savefile();
if (nhfp) { if (nhfp) {
@@ -1225,6 +1225,25 @@ NHFILE *nhfp;
} }
++msgcount; ++msgcount;
} }
/* If the fuzzer is stopping and saving, save a seed as a message.
In 3.7, we will modify the save file format and save the seed
directly in the saved game state. */
if (iflags.fuzzer_saving) {
char message[BUFSIZ];
unsigned long seed = rul();
sprintf(message, "SEED:%ld:%lu", g.moves, seed);
fuzzer_log(LOG_MINIMAL, "STOP:%ld:%lu\n", g.moves, seed);
msglen = strlen(message);
if (nhfp->structlevel) {
bwrite(nhfp->fd, (genericptr_t) &msglen, sizeof msglen);
bwrite(nhfp->fd, (genericptr_t) message, msglen);
}
if (nhfp->fieldlevel) {
sfo_int(nhfp, &msglen, "msghistory", "msghistory_length", 1);
sfo_str(nhfp, message, "msghistory", "msg", msglen);
}
}
if (nhfp->structlevel) if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) &minusone, sizeof (int)); bwrite(nhfp->fd, (genericptr_t) &minusone, sizeof (int));
if (nhfp->fieldlevel) if (nhfp->fieldlevel)

View File

@@ -3742,7 +3742,7 @@ struct opvar *mc;
{ {
int x, y; int x, y;
schar mapc; schar mapc;
xchar lit; uchar lit;
struct opvar *ret = selection_opvar((char *) 0); struct opvar *ret = selection_opvar((char *) 0);
if (!ov || !mc || !ret) if (!ov || !mc || !ret)

View File

@@ -475,8 +475,15 @@ int *x, *y, *mod;
coord cc; coord cc;
DWORD count; DWORD count;
really_move_cursor(); really_move_cursor();
if (iflags.debug_fuzzer) if (iflags.debug_fuzzer) {
return randomkey(); int poskey = randomkey();
if (poskey == 0) {
*x = rn2(console.width);
*y = rn2(console.height);
}
return poskey;
}
ch = (g.program_state.done_hup) ch = (g.program_state.done_hup)
? '\033' ? '\033'
: keyboard_handler.pCheckInput( : keyboard_handler.pCheckInput(

View File

@@ -337,7 +337,7 @@ attempt_restore:
resuming = TRUE; /* not starting new game */ resuming = TRUE; /* not starting new game */
if (discover) if (discover)
You("are in non-scoring discovery mode."); You("are in non-scoring discovery mode.");
if (discover || wizard) { if ((discover || wizard) && !iflags.fuzzer_auto_start) {
if (yn("Do you want to keep the save file?") == 'n') if (yn("Do you want to keep the save file?") == 'n')
(void) delete_savefile(); (void) delete_savefile();
else { else {
@@ -462,6 +462,23 @@ char *argv[];
case 'X': case 'X':
discover = TRUE, wizard = FALSE; discover = TRUE, wizard = FALSE;
break; break;
case 'F':
{
iflags.fuzzer_auto_start = 1;
if (argc > 1 && argv[1][0] != '-') {
argc--;
argv++;
iflags.fuzzer_stop_and_save = atoi(*argv);
if (argc > 1 && argv[1][0] != '-') {
argc--;
argv++;
iflags.verbose_logging_start = atoi(*argv);
}
}
}
break;
#ifdef NEWS #ifdef NEWS
case 'n': case 'n':
iflags.news = FALSE; iflags.news = FALSE;

View File

@@ -720,9 +720,19 @@ nt_assert_failed(expression, filepath, line)
{ {
const char * filename; const char * filename;
/* get file name from path */
filename = strrchr(filepath, '\\'); filename = strrchr(filepath, '\\');
filename = (filename == NULL ? filepath : filename + 1); filename = (filename == NULL ? filepath : filename + 1);
if (IsDebuggerPresent()) {
char message[BUFSIZ];
snprintf(message, sizeof(message),
"nhassert(%s) failed in file '%s' at line %d",
expression, filename, line);
OutputDebugStringA(message);
DebugBreak();
}
/* get file name from path */
impossible("nhassert(%s) failed in file '%s' at line %d", impossible("nhassert(%s) failed in file '%s' at line %d",
expression, filename, line); expression, filename, line);
} }

View File

@@ -259,7 +259,7 @@ register const char *bp;
&& cw->cury == 0 && cw->cury == 0
&& n0 + (int) strlen(g.toplines) + 3 < CO - 8 /* room for --More-- */ && n0 + (int) strlen(g.toplines) + 3 < CO - 8 /* room for --More-- */
&& (notdied = strncmp(bp, "You die", 7)) != 0) { && (notdied = strncmp(bp, "You die", 7)) != 0) {
nhassert((long) strlen(g.toplines) == cw->curx); /* nhassert((long) strlen(g.toplines) == cw->curx); */
Strcat(g.toplines, " "); Strcat(g.toplines, " ");
Strcat(g.toplines, bp); Strcat(g.toplines, bp);
cw->curx += 2; cw->curx += 2;
@@ -617,6 +617,66 @@ boolean purged; /* True: took history's pointers, False: just cloned them */
} }
} }
STATIC_OVL ptr_array_t *
get_message_history()
{
char *mesg;
int i;
struct WinDesc *cw;
size_t max_length;
ptr_array_t * a;
nhassert(WIN_MESSAGE != WIN_ERR);
nhassert(wins[WIN_MESSAGE] != NULL);
/* paranoia (too early or too late panic save attempt?) */
if (WIN_MESSAGE == WIN_ERR || !wins[WIN_MESSAGE])
return NULL;
cw = wins[WIN_MESSAGE];
max_length = cw->rows;
if (*g.toplines) max_length++;
a = ptr_array_new(max_length);
nhassert(cw->maxrow <= cw->rows);
for (i = 0; i < cw->rows; ++i) {
mesg = cw->data[(i + cw->maxrow) % cw->rows];
if (mesg && *mesg)
a->elements[a->length++] = strdup(mesg);
}
if (*g.toplines)
a->elements[a->length++] = strdup(g.toplines);
return a;
}
STATIC_OVL void
purge_message_history()
{
int i;
struct WinDesc *cw;
nhassert(WIN_MESSAGE != WIN_ERR);
nhassert(wins[WIN_MESSAGE] != NULL);
cw = wins[WIN_MESSAGE];
*g.toplines = '\0';
for (i = 0; i < cw->rows; ++i) {
if (cw->data[i]) {
free(cw->data[i]);
cw->data[i] = (char *) 0;
cw->datlen[i] = 0;
}
}
cw->maxcol = cw->maxrow = 0;
}
/* /*
* This is called by the core save routines. * This is called by the core save routines.
* Each time we are called, we return one string from the * Each time we are called, we return one string from the
@@ -631,21 +691,25 @@ char *
tty_getmsghistory(init) tty_getmsghistory(init)
boolean init; boolean init;
{ {
static int nxtidx; static size_t nxtidx;
char *nextmesg; static ptr_array_t * saved_messages = NULL;
char *result = 0; char *result = NULL;
if (init) { if (init) {
msghistory_snapshot(FALSE); nhassert(saved_messages == NULL);
saved_messages = get_message_history();
nxtidx = 0; nxtidx = 0;
wins[WIN_MESSAGE]->flags |= WIN_LOCKHISTORY;
} }
if (snapshot_mesgs) { if (saved_messages) {
nextmesg = snapshot_mesgs[nxtidx++]; if (nxtidx < saved_messages->length)
if (nextmesg) { result = saved_messages->elements[nxtidx++];
result = (char *) nextmesg;
} else { if (result == NULL) {
free_msghistory_snapshot(FALSE); ptr_array_free(saved_messages);
saved_messages = NULL;
wins[WIN_MESSAGE]->flags &= ~WIN_LOCKHISTORY;
} }
} }
return result; return result;
@@ -674,7 +738,10 @@ const char *msg;
boolean restoring_msghist; boolean restoring_msghist;
{ {
static boolean initd = FALSE; static boolean initd = FALSE;
int idx; static ptr_array_t * saved_messages = NULL;
size_t i;
nhassert(!(wins[WIN_MESSAGE]->flags & WIN_LOCKHISTORY));
if (restoring_msghist && !initd) { if (restoring_msghist && !initd) {
/* we're restoring history from the previous session, but new /* we're restoring history from the previous session, but new
@@ -682,7 +749,9 @@ boolean restoring_msghist;
for instance); collect current history (ie, those new messages), for instance); collect current history (ie, those new messages),
and also clear it out so that nothing will be present when the and also clear it out so that nothing will be present when the
restored ones are being put into place */ restored ones are being put into place */
msghistory_snapshot(TRUE); nhassert(saved_messages == NULL);
saved_messages = get_message_history();
purge_message_history();
initd = TRUE; initd = TRUE;
#ifdef DUMPLOG #ifdef DUMPLOG
/* this suffices; there's no need to scrub saved_pline[] pointers */ /* this suffices; there's no need to scrub saved_pline[] pointers */
@@ -704,22 +773,39 @@ boolean restoring_msghist;
#ifdef DUMPLOG #ifdef DUMPLOG
dumplogmsg(g.toplines); dumplogmsg(g.toplines);
#endif #endif
} else if (snapshot_mesgs) { return;
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();
Strcpy(g.toplines, snapshot_mesgs[idx]);
#ifdef DUMPLOG
dumplogmsg(g.toplines);
#endif
}
/* now release the snapshot */
free_msghistory_snapshot(TRUE);
initd = FALSE; /* reset */
} }
/* tty_putmsghistory() is called with msg==NULL to indidate that
* we are finished restoring the message history. If we saved
* some message history when we started, its time now to appened
* those saved messages.
*
* We don't otherwise expect to get called with msg==NULL.
*
*/
nhassert(restoring_msghist && initd);
if (initd && restoring_msghist) {
if (saved_messages) {
nhassert(ttyDisplay == NULL ||
ttyDisplay->toplin != TOPLINE_NEED_MORE);
for (i = 0; i < saved_messages->length; i++) {
const char * mesg = saved_messages->elements[i];
remember_topl();
nhassert(mesg);
Strcpy(g.toplines, mesg);
#ifdef DUMPLOG
dumplogmsg(g.toplines);
#endif
}
ptr_array_free(saved_messages);
saved_messages = NULL;
}
initd = FALSE;
}
} }
#endif /* TTY_GRAPHICS */ #endif /* TTY_GRAPHICS */

View File

@@ -0,0 +1,8 @@
set BIN_DIR=..\..\..\..\bin\Debug\Win32
set FUZZER_LOG=%BIN_DIR%\fuzzer.log
set FUZZER_DIR=%BIN_DIR%\fuzzer
if exist %BIN_DIR%\%USERNAME%* del %BIN_DIR%\%USERNAME%*
if exist %FUZZER_LOG% del %FUZZER_LOG%

View File

@@ -0,0 +1,23 @@
echo off
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
set STEP_SIZE=5000
set FINAL_MOVE=500000
set START_MOVE=5000
for /L %%i in (%START_MOVE%, %STEP_SIZE%, %FINAL_MOVE%) do (
call runtill.bat %%i
if ERRORLEVEL 1 (
echo FAILED getting running to %%i.
exit /b 1
)
)
echo SUCCESS.

View File

@@ -0,0 +1,7 @@
call clean.bat
set BIN_DIR=..\..\..\..\bin\Debug\Win32
set SAVED_GAME=%USERNAME%-wizard.NetHack-saved-game
set FUZZER_DIR=%BIN_DIR%\fuzzer
copy %FUZZER_DIR%\%SAVED_GAME% %BIN_DIR%\%SAVED_GAME%

View File

@@ -0,0 +1,73 @@
REM
REM runtill target_move
REM
echo off
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
set TARGET_MOVE=%1
if %TARGET_MOVE% == "" (
echo Usage:runtill target_move
goto :eof
)
set BIN_DIR=..\..\..\..\bin\Debug\Win32
set SAVED_GAME=%USERNAME%-wizard.NetHack-saved-game
set LOG_FILE=%BIN_DIR%\runtil.log
set FUZZER_LOG=%BIN_DIR%\fuzzer.log
set FUZZER_DIR=%BIN_DIR%\fuzzer
set BASELINE=%FUZZER_DIR%\fuzzer.log
if not exist %FUZZER_DIR% mkdir %FUZZER_DIR%
call clean.bat
if not exist %FUZZER_DIR%\%SAVED_GAME% (
%BIN_DIR%\nethack -D -F 0
copy %BIN_DIR%\%SAVED_GAME% %FUZZER_DIR%
)
call restore.bat
%BIN_DIR%\nethack -D -F %TARGET_MOVE%
move %BIN_DIR%\*.snap %BIN_DIR%\snapshots
copy %FUZZER_LOG% %BASELINE%
for /f "tokens=2,3 delims=: usebackq" %%i in (`findstr /c:START %BASELINE%`) do (
set START_SEED=%%j
set START_MOVE=%%i
)
for /f "tokens=2,3 delims=: usebackq" %%i in (`findstr /c:STOP %BASELINE%`) do (
set STOP_SEED=%%j
set STOP_MOVE=%%i
)
if !STOP_MOVE! LSS %TARGET_MOVE% (
cls
echo FAILED: Failed to reach target move. !STOP_MOVE! is not GTE %TARGET_MOVE%.
exit /b 1
)
call restore.bat
%BIN_DIR%\nethack -D -F %TARGET_MOVE%
fc %FUZZER_LOG% %BASELINE%
if ERRORLEVEL 1 (
cls
echo FAILED: Unable to reproduce same timeline
exit /b 1
)
del /q %FUZZER_DIR%\%SAVED_GAME%
copy %BIN_DIR%\%SAVED_GAME% %FUZZER_DIR%
echo !START_MOVE! to !STOP_MOVE!.
echo SUCCESS.