From 5c8b36e95a56324b63c308321cefdb8b66a529ed Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 19 Nov 2023 17:36:25 -0500 Subject: [PATCH] Revert "don't build in support for obsolete makedefs options" This reverts commit 13f49bdd92e9f2e6c07ef62d1712baad5746a343. --- sys/unix/Makefile.src | 6 +- sys/unix/Makefile.top | 19 +- sys/unix/Makefile.utl | 7 +- sys/windows/Makefile.mingw32 | 8 +- util/makedefs.c | 917 ++++++++++++++++------------------- 5 files changed, 451 insertions(+), 506 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index beabb2693..3615da20c 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -746,9 +746,9 @@ $(TARGETPFX)date.o: date.c $(HACK_H) $(HACKCSRC) $(HOBJ) # Do NOT include ../dat/gitinfo.txt as either a prerequisite or target. # 'makedefs -v' processes it when present and ignores it if not. # -#../include/date.h: ../util/makedefs $(VERSOURCES) $(HACK_H) -# -$(SHELL) ../sys/unix/gitinfo.sh $(GITINFO) #before 'makedefs -v' -# ../util/makedefs -v +../include/date.h: ../util/makedefs $(VERSOURCES) $(HACK_H) + -$(SHELL) ../sys/unix/gitinfo.sh $(GITINFO) #before 'makedefs -v' + ../util/makedefs -v lint: # lint cannot have -p here because (i) capitals are meaningful: diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index c3395a14d..c2e52e250 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -67,7 +67,7 @@ DIRPERM = 0755 # Qt without X11; assumes GRAPHIC_TOMBSTONE: # VARDATND = nhtiles.bmp pet_mark.xbm pilemark.xbm rip.xpm -VARDATD = bogusmon data engrave epitaph oracles quest.lua rumors +VARDATD = bogusmon data engrave epitaph oracles options quest.lua rumors VARDAT = $(VARDATD) $(VARDATND) # Some versions of make use the SHELL environment variable as the @@ -245,9 +245,8 @@ GEM_RSC.RSC: title.img: ( cd dat ; $(MAKE) title.img ) -check-dlb: - @true -# @if egrep -s librarian options; then $(MAKE) dlb ; else true ; fi +check-dlb: options + @if egrep -s librarian dat/options ; then $(MAKE) dlb ; else true ; fi dlb: ( cd util ; $(MAKE) dlb ) @@ -265,12 +264,12 @@ recover: $(GAME) ( cd util ; $(MAKE) recover ) dofiles: -# target=`sed -n \ -# -e '/librarian/{' \ -# -e 's/.*/dlb/p' \ -# -e 'q' \ -# -e '}' \ -# -e '$$s/.*/nodlb/p' < dat/options` ; \ + target=`sed -n \ + -e '/librarian/{' \ + -e 's/.*/dlb/p' \ + -e 'q' \ + -e '}' \ + -e '$$s/.*/nodlb/p' < dat/options` ; \ $(MAKE) dofiles-$${target-nodlb} cp src/$(GAME) $(INSTDIR) cp util/recover $(INSTDIR) diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index bd3f71fcd..c51e1991a 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -194,11 +194,6 @@ ODATE = $(OBJDIR)/date.o # object files for makedefs MAKEOBJS = makedefs.o $(OMONOBJ) $(ODATE) $(OALLOC) -# To include old makedefs options support, define -# OLD_MAKEDEFS_OPTIONS -#OLD_MAKEDEFS_OPTIONS = -DOLD_MAKEDEFS_OPTIONS -OLD_MAKEDEFS_OPTIONS = - # object files for recovery utility RECOVOBJS = $(TARGETPFX)recover.o @@ -236,7 +231,7 @@ makedefs.o: makedefs.c ../src/mdlib.c $(CONFIG_H) \ ../include/monst.h ../include/monsters.h ../include/objects.h \ ../include/you.h ../include/context.h ../include/flag.h \ ../include/dlb.h ../include/patchlevel.h mdgrep.h - $(CC) $(CFLAGS) $(CSTD) $(OLD_MAKEDEFS_OPTIONS) -c makedefs.c -o $@ + $(CC) $(CFLAGS) $(CSTD) -c makedefs.c -o $@ # Don't require perl to build; that is why mdgrep.h is spelled wrong below. mdgreph: mdgrep.pl diff --git a/sys/windows/Makefile.mingw32 b/sys/windows/Makefile.mingw32 index 8b1cd20e1..3a8af24a1 100644 --- a/sys/windows/Makefile.mingw32 +++ b/sys/windows/Makefile.mingw32 @@ -701,7 +701,7 @@ CLEAN_FILE += $(UTARGETS) $(UOBJS) #========================================== ODLB = $(O)dlb DLBOBJS = $(addprefix $(ODLB)/, alloc.o dlb.o dlb_main.o panic.o) -DAT_CLEAN = $(addprefix $(DAT)/, data oracles porthelp rumors engrave epitaph bogusmon) +DAT_CLEAN = $(addprefix $(DAT)/, data oracles options porthelp rumors engrave epitaph bogusmon) DAT_NOCLEAN = $(addprefix $(DAT)/, help hh cmdhelp keyhelp history opthelp optmenu \ wizhelp license engrave epitaph bogusmon tribute) DLBLST = $(DAT)/dlb.lst @@ -728,6 +728,9 @@ $(DAT)/data: $(U)makedefs.exe $(DAT)/data.base $(DAT)/oracles: $(U)makedefs.exe $(DAT)/oracles.txt $< -h +$(DAT)/options $(INCL)/date.h: $(U)makedefs.exe + $< -v + $(DAT)/porthelp: $(MSWSYS)/porthelp cp $< $@ @@ -744,6 +747,9 @@ $(DAT)/bogusmon: $(U)makedefs.exe $(DAT)/bogusmon.txt $(DAT)/engrave.txt $(DAT)/ $(DLBLST): $(LUAFILES) | $(DAT_CLEAN) $(DAT_NOCLEAN) echo data > $(DLBLST) echo oracles >> $(DLBLST) + echo options >> $(DLBLST) + if [ -f $(DAT)/ttyoptions ] ; then echo ttyoptions >> $(DLBLST) ; fi + if [ -f $(DAT)/guioptions ] ; then echo guioptions >> $(DLBLST) ; fi echo porthelp >> $(DLBLST) echo rumors >> $(DLBLST) echo help >> $(DLBLST) diff --git a/util/makedefs.c b/util/makedefs.c index 7c046491f..5cd92c1f3 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -47,79 +47,65 @@ #endif /* names of files to be generated */ -#define ORACLE_FILE "oracles" -#define DATA_FILE "data" -#define RUMOR_FILE "rumors" - -/* These are affiliated with outdated options - but we define them for us in messages */ #define DATE_FILE "date.h" #define MONST_FILE "pm.h" #define ONAME_FILE "onames.h" #ifndef OPTIONS_FILE #define OPTIONS_FILE "options" #endif +#define ORACLE_FILE "oracles" +#define DATA_FILE "data" +#define RUMOR_FILE "rumors" #define DGN_I_FILE "dungeon.def" #define DGN_O_FILE "dungeon.pdf" +#if 0 #define QTXT_I_FILE "quest.txt" #define QTXT_O_FILE "quest.dat" +#endif #define GITINFO_FILE "gitinfo.txt" - /* locations for those files */ #ifdef AMIGA #define FILE_PREFIX +#define INCLUDE_TEMPLATE "NH:include/t.%s" #define SOURCE_TEMPLATE "NH:src/%s" +#define DGN_TEMPLATE "NH:dat/%s" /* where dungeon.pdf file goes */ #define DATA_TEMPLATE "NH:slib/%s" #define DATA_IN_TEMPLATE "NH:dat/%s" -#if defined(OLD_MAKEDEFS_OPTIONS) -#define INCLUDE_TEMPLATE "NH:include/t.%s" -#define DGN_TEMPLATE "NH:dat/%s" /* where dungeon.pdf file goes */ -#endif /* OLD_MAKEDEFS_OPTIONS */ #else /* not AMIGA */ #if defined(MAC) && !defined(__MACH__) /* MacOS 9 or earlier */ +#define INCLUDE_TEMPLATE ":include:%s" #define SOURCE_TEMPLATE ":src:%s" +#define DGN_TEMPLATE ":dat:%s" /* where dungeon.pdf file goes */ #if __SC__ || __MRC__ #define DATA_TEMPLATE ":Dungeon:%s" #else #define DATA_TEMPLATE ":lib:%s" #endif /* __SC__ || __MRC__ */ #define DATA_IN_TEMPLATE ":dat:%s" -#if defined(OLD_MAKEDEFS_OPTIONS) -#define INCLUDE_TEMPLATE ":include:%s" -#define DGN_TEMPLATE ":dat:%s" /* where dungeon.pdf file goes */ -#endif /* OLD_MAKEDEFS_OPTIONS */ #else /* neither AMIGA nor MAC */ #ifdef OS2 +#define INCLUDE_TEMPLATE "..\\include\\%s" #define SOURCE_TEMPLATE "..\\src\\%s" +#define DGN_TEMPLATE "..\\dat\\%s" /* where dungeon.pdf file goes */ #define DATA_TEMPLATE "..\\dat\\%s" #define DATA_IN_TEMPLATE "..\\dat\\%s" -#if defined(OLD_MAKEDEFS_OPTIONS) -#define INCLUDE_TEMPLATE "..\\include\\%s" -#define DGN_TEMPLATE "..\\dat\\%s" /* where dungeon.pdf file goes */ -#endif /* OLD_MAKEDEFS_OPTIONS */ #else /* not AMIGA, MAC, or OS2 */ +#define INCLUDE_TEMPLATE "../include/%s" #define SOURCE_TEMPLATE "../src/%s" +#define DGN_TEMPLATE "../dat/%s" /* where dungeon.pdf file goes */ #define DATA_TEMPLATE "../dat/%s" #define DATA_IN_TEMPLATE "../dat/%s" -#if defined(OLD_MAKEDEFS_OPTIONS) -#define INCLUDE_TEMPLATE "../include/%s" -#define DGN_TEMPLATE "../dat/%s" /* where dungeon.pdf file goes */ -#endif /* OLD_MAKEDEFS_OPTIONS */ #endif /* else !OS2 */ #endif /* else !MAC */ #endif /* else !AMIGA */ static const char *Dont_Edit_Data = - "#\tThis data file is generated by 'makedefs'. Do not edit. \n"; - -#if defined(OLD_MAKEDEFS_OPTIONS) -static const char + "#\tThis data file is generated by 'makedefs'. Do not edit. \n", *Reference_file = "/* This file is generated by 'makedefs' for reference purposes only. */\n" "/* It is no longer used in the NetHack build. */\n"; -#endif /* OLD_MAKEDEFS_OPTIONS */ static struct version_info version; @@ -140,23 +126,17 @@ int main(void); #else int main(int, char **); #endif - void do_makedefs(char *); +void do_objs(void); void do_data(void); -void do_rumors(void); -void do_oracles(void); - -#if defined(OLD_MAKEDEFS_OPTIONS) -void do_date(void); void do_dungeon(void); void do_options(void); void do_monstr(void); -void do_objs(void); void do_permonst(void); void do_questtxt(void); -#else -static const char *oldfunctionality(char); -#endif /* OLD_MAKEDEFS_OPTIONS */ +void do_rumors(void); +void do_oracles(void); +void do_date(void); extern void monst_globals_init(void); /* monst.c */ extern void objects_globals_init(void); /* objects.c */ @@ -172,19 +152,18 @@ static void do_rnd_access_file(const char *, const char *, unsigned); static boolean d_filter(char *); static boolean h_filter(char *); static void opt_out_words(char *, int *); -static char *fgetline(FILE*); -#if defined(OLD_MAKEDEFS_OPTIONS) +static char *fgetline(FILE*); static char *tmpdup(const char *); static char *macronamelimit(char *, int); static void windowing_sanity(void); static boolean get_gitinfo(char *, char *); -static boolean use_enum = TRUE; -#endif /* input, output, tmp */ static FILE *ifp, *ofp, *tfp; +static boolean use_enum = TRUE; + #if defined(__BORLANDC__) && !defined(_WIN32) extern unsigned _stklen = STKSIZ; #endif @@ -205,6 +184,9 @@ ATTRNORETURN static void makedefs_exit(int) NORETURN; ATTRNORETURN static void makedefs_exit(int how) { +#if 0 /* makedefs doesn't need to do this */ + release_runtime_info(); /* dynamic data from mdlib.c and date.c */ +#endif exit(how); /*NOTREACHED*/ } @@ -300,13 +282,30 @@ do_makedefs(char *options) Fprintf(stderr, "makedefs -%c\n", *options); switch (*options) { + case 'o': + case 'O': + do_objs(); + break; case 'd': case 'D': do_data(); break; - case 'h': - case 'H': - do_oracles(); + case 'e': + case 'E': + do_dungeon(); + break; + case 'v': + case 'V': + do_date(); + do_options(); + break; + case 'p': + case 'P': + do_permonst(); + break; + case 'q': + case 'Q': + do_questtxt(); break; case 'r': case 'R': @@ -333,39 +332,11 @@ do_makedefs(char *options) /* default bogusmon: iconic monster that isn't in nethack */ "grue", MD_PAD_BOGONS); break; -#if defined(OLD_MAKEDEFS_OPTIONS) - case 'o': - case 'O': - do_objs(); + case 'h': + case 'H': + do_oracles(); break; - case 'e': - case 'E': - do_dungeon(); - break; - case 'v': - case 'V': - do_date(); - do_options(); - break; - case 'p': - case 'P': - do_permonst(); - break; - case 'q': - case 'Q': - do_questtxt(); - break; -#else - case 'o': case 'O': case 'e': case 'E': case 'v': case 'V': - case 'p': case 'P': case 'q': case 'Q': - Fprintf(stderr, "Old makedefs option.\n" - "Rebuild makedefs with '-DOLD_MAKEDEFS_OPTIONS'" - " for '%c' (%s) support.\n", - *options, oldfunctionality(*options)); - (void) fflush(stderr); - /*NOTREACHED*/ - break; -#endif /* OLD_MAKEDEFS_OPTIONS */ + default: Fprintf(stderr, "Unknown option '%c'.\n", *options); (void) fflush(stderr); @@ -379,31 +350,6 @@ do_makedefs(char *options) return; } -#if !defined(OLD_MAKEDEFS_OPTIONS) -static const char * -oldfunctionality(char sought) -{ - static struct ofn_s { - char lcoflet; - char ucoflet; - const char *ofnam; - } ofn[] = { - { 'e', 'E', DGN_O_FILE }, - { 'o', 'O', ONAME_FILE }, - { 'p', 'P', MONST_FILE }, - { 'q', 'Q', QTXT_O_FILE }, - { 'v', 'V', DATE_FILE " & " OPTIONS_FILE }, - }; - int i; - - for (i = 0; i < SIZE(ofn); ++i) { - if (sought == ofn[i].lcoflet || sought == ofn[i].ucoflet) - return ofn[i].ofnam; - } - return "unknown"; -} -#endif /* !OLD_MAKEDEFS_OPTIONS */ - static char namebuf[1000]; DISABLE_WARNING_FORMAT_NONLITERAL @@ -1218,390 +1164,7 @@ do_rumors(void) } RESTORE_WARNING_FORMAT_NONLITERAL -void -do_data(void) -{ - char infile[60], tempfile[60]; - boolean ok; - long txt_offset; - int entry_cnt, line_cnt; - char *line; - Sprintf(tempfile, DATA_TEMPLATE, "database.tmp"); - filename[0] = '\0'; -#ifdef FILE_PREFIX - Strcat(filename, file_prefix); -#endif - Sprintf(eos(filename), DATA_TEMPLATE, DATA_FILE); - Sprintf(infile, DATA_IN_TEMPLATE, DATA_FILE); -#ifdef SHORT_FILENAMES - Strcat(infile, ".bas"); -#else - Strcat(infile, ".base"); -#endif - if (!(ifp = fopen(infile, RDTMODE))) { /* data.base */ - perror(infile); - makedefs_exit(EXIT_FAILURE); - /*NOTREACHED*/ - } - if (!(ofp = fopen(filename, WRTMODE))) { /* data */ - perror(filename); - Fclose(ifp); - makedefs_exit(EXIT_FAILURE); - /*NOTREACHED*/ - } - if (!(tfp = fopen(tempfile, WRTMODE))) { /* database.tmp */ - perror(tempfile); - Fclose(ifp); - Fclose(ofp); - Unlink(filename); - makedefs_exit(EXIT_FAILURE); - /*NOTREACHED*/ - } - - /* output a dummy header record; we'll rewind and overwrite it later */ - Fprintf(ofp, "%s%08lx\n", Dont_Edit_Data, 0L); - - entry_cnt = line_cnt = 0; - /* read through the input file and split it into two sections */ - while ((line = fgetline(ifp)) != 0) { - if (d_filter(line)) { - free((genericptr_t) line); - continue; - } - if (*line > ' ') { /* got an entry name */ - /* first finish previous entry */ - if (line_cnt) - Fprintf(ofp, "%d\n", line_cnt), line_cnt = 0; - /* output the entry name */ - (void) fputs(line, ofp); - entry_cnt++; /* update number of entries */ - } else if (entry_cnt) { /* got some descriptive text */ - /* update previous entry with current text offset */ - if (!line_cnt) - Fprintf(ofp, "%ld,", ftell(tfp)); - /* save the text line in the scratch file */ - (void) fputs(line, tfp); - line_cnt++; /* update line counter */ - } - free((genericptr_t) line); - } - /* output an end marker and then record the current position */ - if (line_cnt) - Fprintf(ofp, "%d\n", line_cnt); - Fprintf(ofp, ".\n%ld,%d\n", ftell(tfp), 0); - txt_offset = ftell(ofp); - Fclose(ifp); /* all done with original input file */ - - /* reprocess the scratch file; 1st format an error msg, just in case */ - line = malloc(BUFSZ + MAXFNAMELEN); - Sprintf(line, "rewind of \"%s\"", tempfile); - if (rewind(tfp) != 0) - goto dead_data; - free((genericptr_t) line); - /* copy all lines of text from the scratch file into the output file */ - while ((line = fgetline(tfp)) != 0) { - (void) fputs(line, ofp); - free((genericptr_t) line); - } - - /* finished with scratch file */ - Fclose(tfp); - Unlink(tempfile); /* remove it */ - - /* update the first record of the output file; prepare error msg 1st */ - line = (char *) alloc(BUFSZ + MAXFNAMELEN); - Sprintf(line, "rewind of \"%s\"", filename); - ok = (rewind(ofp) == 0); - if (ok) { - Sprintf(line, "header rewrite of \"%s\"", filename); - ok = (fprintf(ofp, "%s%08lx\n", Dont_Edit_Data, - (unsigned long) txt_offset) >= 0); - } - if (!ok) { - dead_data: - perror(line); /* report the problem */ - free((genericptr_t) line); - /* close and kill the aborted output file, then give up */ - Fclose(ofp); - Unlink(filename); - makedefs_exit(EXIT_FAILURE); - /*NOTREACHED*/ - } - free((genericptr_t) line); - - /* all done */ - Fclose(ofp); - - return; -} - -/* routine to decide whether to discard something from oracles.txt */ -static boolean -h_filter(char *line) -{ - static boolean skip = FALSE; - char *tag; - - SpinCursor(3); - - if (*line == '#') - return TRUE; /* ignore comment lines */ - - tag = (char *) alloc((unsigned) strlen(line)); /* don't need +1 here */ - if (sscanf(line, "----- %s", tag) == 1) { - skip = FALSE; - } else if (skip && !strncmp(line, "-----", 5)) - skip = FALSE; - free((genericptr_t) tag); - return skip; -} - -/* routine to decide whether to discard something from data.base */ -static boolean -d_filter(char *line) -{ - if (*line == '#') - return TRUE; /* ignore comment lines */ - return FALSE; -} - -static const char *special_oracle[] = { - "\"...it is rather disconcerting to be confronted with the", - "following theorem from [Baker, Gill, and Solovay, 1975].", - "", - "Theorem 7.18 There exist recursive languages A and B such that", - " (1) P(A) == NP(A), and", - " (2) P(B) != NP(B)", - "", - "This provides impressive evidence that the techniques that are", - ("currently available will not suffice for proving that P != NP or" - " "), - "that P == NP.\" [Garey and Johnson, p. 185.]" -}; - -/* - The oracle file consists of a "do not edit" comment, a decimal count N - and set of N+1 hexadecimal fseek offsets, followed by N multiple-line - records, separated by "---" lines. The first oracle is a special case. - The input data contains just those multi-line records, separated by - "-----" lines. - */ - -void -do_oracles(void) -{ - char infile[60], tempfile[60]; - boolean in_oracle, ok; - long fpos; - unsigned long txt_offset, offset; - int oracle_cnt; - register int i; - char *line; - - Sprintf(tempfile, DATA_TEMPLATE, "oracles.tmp"); - filename[0] = '\0'; -#ifdef FILE_PREFIX - Strcat(filename, file_prefix); -#endif - Sprintf(eos(filename), DATA_TEMPLATE, ORACLE_FILE); - Sprintf(infile, DATA_IN_TEMPLATE, ORACLE_FILE); - Strcat(infile, ".txt"); - if (!(ifp = fopen(infile, RDTMODE))) { - perror(infile); - makedefs_exit(EXIT_FAILURE); - /*NOTREACHED*/ - } - if (!(ofp = fopen(filename, WRTMODE))) { - perror(filename); - Fclose(ifp); - makedefs_exit(EXIT_FAILURE); - /*NOTREACHED*/ - } - if (!(tfp = fopen(tempfile, WRTMODE))) { /* oracles.tmp */ - perror(tempfile); - Fclose(ifp); - Fclose(ofp); - Unlink(filename); - makedefs_exit(EXIT_FAILURE); - /*NOTREACHED*/ - } - - /* output a dummy header record; we'll rewind and overwrite it later */ - Fprintf(ofp, "%s%5d\n", Dont_Edit_Data, 0); - - /* handle special oracle; it must come first */ - (void) fputs("---\n", tfp); - offset = (unsigned long) ftell(tfp); - Fprintf(ofp, "%05lx\n", offset); /* start pos of special oracle */ - for (i = 0; i < SIZE(special_oracle); i++) { - (void) fputs(xcrypt(special_oracle[i]), tfp); - (void) fputc('\n', tfp); - } - SpinCursor(3); - - oracle_cnt = 1; - (void) fputs("---\n", tfp); - offset = (unsigned long) ftell(tfp); - Fprintf(ofp, "%05lx\n", offset); /* start pos of first oracle */ - in_oracle = FALSE; - - while ((line = fgetline(ifp)) != 0) { - SpinCursor(3); - - if (h_filter(line)) { - free((genericptr_t) line); - continue; - } - if (!strncmp(line, "-----", 5)) { - if (!in_oracle) { - free((genericptr_t) line); - continue; - } - in_oracle = FALSE; - oracle_cnt++; - (void) fputs("---\n", tfp); - offset = (unsigned long) ftell(tfp); - Fprintf(ofp, "%05lx\n", offset); /* start pos of this oracle */ - } else { - in_oracle = TRUE; - (void) fputs(xcrypt(line), tfp); - } - free((genericptr_t) line); - } - - if (in_oracle) { /* need to terminate last oracle */ - oracle_cnt++; - (void) fputs("---\n", tfp); - offset = (unsigned long) ftell(tfp); - Fprintf(ofp, "%05lx\n", offset); /* eof position */ - } - - /* record the current position */ - txt_offset = (unsigned long) ftell(ofp); - Fclose(ifp); /* all done with original input file */ - - /* reprocess the scratch file; 1st format an error msg, just in case */ - line = (char *) alloc(BUFSZ + MAXFNAMELEN); - Sprintf(line, "rewind of \"%s\"", tempfile); - if (rewind(tfp) != 0) - goto dead_data; - free((genericptr_t) line); - /* copy all lines of text from the scratch file into the output file */ - while ((line = fgetline(tfp)) != 0) { - (void) fputs(line, ofp); - free((genericptr_t) line); - } - - /* finished with scratch file */ - Fclose(tfp); - Unlink(tempfile); /* remove it */ - - /* update the first record of the output file; prepare error msg 1st */ - line = (char *) alloc(BUFSZ + MAXFNAMELEN); - Sprintf(line, "rewind of \"%s\"", filename); - ok = (rewind(ofp) == 0); - if (ok) { - Sprintf(line, "header rewrite of \"%s\"", filename); - ok = (fprintf(ofp, "%s%5d\n", Dont_Edit_Data, oracle_cnt) >= 0); - } - if (ok) { - Sprintf(line, "data rewrite of \"%s\"", filename); - for (i = 0; i <= oracle_cnt; i++) { -#ifndef VMS /* alpha/vms v1.0; this fflush seems to confuse ftell */ - if (!(ok = (fflush(ofp) == 0))) - break; -#endif - if (!(ok = (fpos = ftell(ofp)) >= 0)) - break; - if (!(ok = (fseek(ofp, fpos, SEEK_SET) >= 0))) - break; - if (!(ok = (fscanf(ofp, "%5lx", &offset) == 1))) - break; -#ifdef MAC -#ifdef __MWERKS__ - /* - MetroWerks CodeWarrior Pro 1's (AKA CW12) version of MSL - (ANSI C Libraries) needs this rewind or else the fprintf - stops working. This may also be true for CW11, but has - never been checked. - */ - rewind(ofp); -#endif -#endif - if (!(ok = (fseek(ofp, fpos, SEEK_SET) >= 0))) - break; - offset += txt_offset; - if (!(ok = (fprintf(ofp, "%05lx\n", offset) >= 0))) - break; - } - } - if (!ok) { - dead_data: - perror(line); /* report the problem */ - free((genericptr_t) line); - /* close and kill the aborted output file, then give up */ - Fclose(ofp); - Unlink(filename); - makedefs_exit(EXIT_FAILURE); - /*NOTREACHED*/ - } - free((genericptr_t) line); - - /* all done */ - Fclose(ofp); - - return; -} - -/* Read one line from input, up to and including the next newline - * character. Returns a pointer to the heap-allocated string, or a - * null pointer if no characters were read. - * 3.7: redone to use nethack's alloc() rather than libc's malloc() - * and realloc(). - */ -static char * -fgetline(FILE *fd) -{ - static const int inc = (BUFSZ / 2) + 16; /* fgets() wants signed int */ - unsigned len = (unsigned) inc, newlen; /* alloc() wants unsigned int */ - char *c = (char *) alloc(len), *cprime, *ret; - - *c = '\0'; - for (;;) { - ret = fgets(c + len - inc, inc, fd); - if (!ret) { - /* don't just assume ret==Null indicates an error; last line - might lack terminating newline; if previous fgets() read it, - instead of returning we would have expanded the buffer and - tried for more, then got Null due to end of file having - already been reached */ - if (feof(fd) && *c && strlen(c) < len) { - Strcat(c, "\n"); /* append missing newline */ - } else { - free((genericptr_t) c), c = NULL; - } - break; /* either with or without added newline, we're done */ - } else if (strchr(c, '\n')) { - /* normal case: we have a full line */ - break; - } - /* didn't fit in c[0..len-1]; expand buffer and read some more - [this was much simpler (and possibly slightly more efficient) - with realloc() but less safe because return values from malloc() - and realloc() were not being checked for Null, and efficiency is - a red herring because growing the buffer will be extremely rare] */ - newlen = len + (unsigned) inc; - cprime = (char *) alloc(newlen); - (void) memcpy(cprime, c, len); - free((genericptr_t) c); - c = cprime; - len = newlen; - } - return c; -} - -#if defined(OLD_MAKEDEFS_OPTIONS) void do_date(void) { @@ -1929,6 +1492,15 @@ windowing_sanity(void) return; } +/* routine to decide whether to discard something from data.base */ +static boolean +d_filter(char *line) +{ + if (*line == '#') + return TRUE; /* ignore comment lines */ + return FALSE; +} + /* * New format (v3.1) of 'data' file which allows much faster lookups [pr] @@ -1951,6 +1523,333 @@ text-b/text-c at fseek(0x01234567L + 456L) * */ +void +do_data(void) +{ + char infile[60], tempfile[60]; + boolean ok; + long txt_offset; + int entry_cnt, line_cnt; + char *line; + + Sprintf(tempfile, DATA_TEMPLATE, "database.tmp"); + filename[0] = '\0'; +#ifdef FILE_PREFIX + Strcat(filename, file_prefix); +#endif + Sprintf(eos(filename), DATA_TEMPLATE, DATA_FILE); + Sprintf(infile, DATA_IN_TEMPLATE, DATA_FILE); +#ifdef SHORT_FILENAMES + Strcat(infile, ".bas"); +#else + Strcat(infile, ".base"); +#endif + if (!(ifp = fopen(infile, RDTMODE))) { /* data.base */ + perror(infile); + makedefs_exit(EXIT_FAILURE); + /*NOTREACHED*/ + } + if (!(ofp = fopen(filename, WRTMODE))) { /* data */ + perror(filename); + Fclose(ifp); + makedefs_exit(EXIT_FAILURE); + /*NOTREACHED*/ + } + if (!(tfp = fopen(tempfile, WRTMODE))) { /* database.tmp */ + perror(tempfile); + Fclose(ifp); + Fclose(ofp); + Unlink(filename); + makedefs_exit(EXIT_FAILURE); + /*NOTREACHED*/ + } + + /* output a dummy header record; we'll rewind and overwrite it later */ + Fprintf(ofp, "%s%08lx\n", Dont_Edit_Data, 0L); + + entry_cnt = line_cnt = 0; + /* read through the input file and split it into two sections */ + while ((line = fgetline(ifp)) != 0) { + if (d_filter(line)) { + free((genericptr_t) line); + continue; + } + if (*line > ' ') { /* got an entry name */ + /* first finish previous entry */ + if (line_cnt) + Fprintf(ofp, "%d\n", line_cnt), line_cnt = 0; + /* output the entry name */ + (void) fputs(line, ofp); + entry_cnt++; /* update number of entries */ + } else if (entry_cnt) { /* got some descriptive text */ + /* update previous entry with current text offset */ + if (!line_cnt) + Fprintf(ofp, "%ld,", ftell(tfp)); + /* save the text line in the scratch file */ + (void) fputs(line, tfp); + line_cnt++; /* update line counter */ + } + free((genericptr_t) line); + } + /* output an end marker and then record the current position */ + if (line_cnt) + Fprintf(ofp, "%d\n", line_cnt); + Fprintf(ofp, ".\n%ld,%d\n", ftell(tfp), 0); + txt_offset = ftell(ofp); + Fclose(ifp); /* all done with original input file */ + + /* reprocess the scratch file; 1st format an error msg, just in case */ + line = malloc(BUFSZ + MAXFNAMELEN); + Sprintf(line, "rewind of \"%s\"", tempfile); + if (rewind(tfp) != 0) + goto dead_data; + free((genericptr_t) line); + /* copy all lines of text from the scratch file into the output file */ + while ((line = fgetline(tfp)) != 0) { + (void) fputs(line, ofp); + free((genericptr_t) line); + } + + /* finished with scratch file */ + Fclose(tfp); + Unlink(tempfile); /* remove it */ + + /* update the first record of the output file; prepare error msg 1st */ + line = (char *) alloc(BUFSZ + MAXFNAMELEN); + Sprintf(line, "rewind of \"%s\"", filename); + ok = (rewind(ofp) == 0); + if (ok) { + Sprintf(line, "header rewrite of \"%s\"", filename); + ok = (fprintf(ofp, "%s%08lx\n", Dont_Edit_Data, + (unsigned long) txt_offset) >= 0); + } + if (!ok) { + dead_data: + perror(line); /* report the problem */ + free((genericptr_t) line); + /* close and kill the aborted output file, then give up */ + Fclose(ofp); + Unlink(filename); + makedefs_exit(EXIT_FAILURE); + /*NOTREACHED*/ + } + free((genericptr_t) line); + + /* all done */ + Fclose(ofp); + + return; +} + +/* routine to decide whether to discard something from oracles.txt */ +static boolean +h_filter(char *line) +{ + static boolean skip = FALSE; + char *tag; + + SpinCursor(3); + + if (*line == '#') + return TRUE; /* ignore comment lines */ + + tag = (char *) alloc((unsigned) strlen(line)); /* don't need +1 here */ + if (sscanf(line, "----- %s", tag) == 1) { + skip = FALSE; + } else if (skip && !strncmp(line, "-----", 5)) + skip = FALSE; + free((genericptr_t) tag); + return skip; +} + +static const char *special_oracle[] = { + "\"...it is rather disconcerting to be confronted with the", + "following theorem from [Baker, Gill, and Solovay, 1975].", + "", + "Theorem 7.18 There exist recursive languages A and B such that", + " (1) P(A) == NP(A), and", + " (2) P(B) != NP(B)", + "", + "This provides impressive evidence that the techniques that are", + ("currently available will not suffice for proving that P != NP or" + " "), + "that P == NP.\" [Garey and Johnson, p. 185.]" +}; + +/* + The oracle file consists of a "do not edit" comment, a decimal count N + and set of N+1 hexadecimal fseek offsets, followed by N multiple-line + records, separated by "---" lines. The first oracle is a special case. + The input data contains just those multi-line records, separated by + "-----" lines. + */ + +void +do_oracles(void) +{ + char infile[60], tempfile[60]; + boolean in_oracle, ok; + long fpos; + unsigned long txt_offset, offset; + int oracle_cnt; + register int i; + char *line; + + Sprintf(tempfile, DATA_TEMPLATE, "oracles.tmp"); + filename[0] = '\0'; +#ifdef FILE_PREFIX + Strcat(filename, file_prefix); +#endif + Sprintf(eos(filename), DATA_TEMPLATE, ORACLE_FILE); + Sprintf(infile, DATA_IN_TEMPLATE, ORACLE_FILE); + Strcat(infile, ".txt"); + if (!(ifp = fopen(infile, RDTMODE))) { + perror(infile); + makedefs_exit(EXIT_FAILURE); + /*NOTREACHED*/ + } + if (!(ofp = fopen(filename, WRTMODE))) { + perror(filename); + Fclose(ifp); + makedefs_exit(EXIT_FAILURE); + /*NOTREACHED*/ + } + if (!(tfp = fopen(tempfile, WRTMODE))) { /* oracles.tmp */ + perror(tempfile); + Fclose(ifp); + Fclose(ofp); + Unlink(filename); + makedefs_exit(EXIT_FAILURE); + /*NOTREACHED*/ + } + + /* output a dummy header record; we'll rewind and overwrite it later */ + Fprintf(ofp, "%s%5d\n", Dont_Edit_Data, 0); + + /* handle special oracle; it must come first */ + (void) fputs("---\n", tfp); + offset = (unsigned long) ftell(tfp); + Fprintf(ofp, "%05lx\n", offset); /* start pos of special oracle */ + for (i = 0; i < SIZE(special_oracle); i++) { + (void) fputs(xcrypt(special_oracle[i]), tfp); + (void) fputc('\n', tfp); + } + SpinCursor(3); + + oracle_cnt = 1; + (void) fputs("---\n", tfp); + offset = (unsigned long) ftell(tfp); + Fprintf(ofp, "%05lx\n", offset); /* start pos of first oracle */ + in_oracle = FALSE; + + while ((line = fgetline(ifp)) != 0) { + SpinCursor(3); + + if (h_filter(line)) { + free((genericptr_t) line); + continue; + } + if (!strncmp(line, "-----", 5)) { + if (!in_oracle) { + free((genericptr_t) line); + continue; + } + in_oracle = FALSE; + oracle_cnt++; + (void) fputs("---\n", tfp); + offset = (unsigned long) ftell(tfp); + Fprintf(ofp, "%05lx\n", offset); /* start pos of this oracle */ + } else { + in_oracle = TRUE; + (void) fputs(xcrypt(line), tfp); + } + free((genericptr_t) line); + } + + if (in_oracle) { /* need to terminate last oracle */ + oracle_cnt++; + (void) fputs("---\n", tfp); + offset = (unsigned long) ftell(tfp); + Fprintf(ofp, "%05lx\n", offset); /* eof position */ + } + + /* record the current position */ + txt_offset = (unsigned long) ftell(ofp); + Fclose(ifp); /* all done with original input file */ + + /* reprocess the scratch file; 1st format an error msg, just in case */ + line = (char *) alloc(BUFSZ + MAXFNAMELEN); + Sprintf(line, "rewind of \"%s\"", tempfile); + if (rewind(tfp) != 0) + goto dead_data; + free((genericptr_t) line); + /* copy all lines of text from the scratch file into the output file */ + while ((line = fgetline(tfp)) != 0) { + (void) fputs(line, ofp); + free((genericptr_t) line); + } + + /* finished with scratch file */ + Fclose(tfp); + Unlink(tempfile); /* remove it */ + + /* update the first record of the output file; prepare error msg 1st */ + line = (char *) alloc(BUFSZ + MAXFNAMELEN); + Sprintf(line, "rewind of \"%s\"", filename); + ok = (rewind(ofp) == 0); + if (ok) { + Sprintf(line, "header rewrite of \"%s\"", filename); + ok = (fprintf(ofp, "%s%5d\n", Dont_Edit_Data, oracle_cnt) >= 0); + } + if (ok) { + Sprintf(line, "data rewrite of \"%s\"", filename); + for (i = 0; i <= oracle_cnt; i++) { +#ifndef VMS /* alpha/vms v1.0; this fflush seems to confuse ftell */ + if (!(ok = (fflush(ofp) == 0))) + break; +#endif + if (!(ok = (fpos = ftell(ofp)) >= 0)) + break; + if (!(ok = (fseek(ofp, fpos, SEEK_SET) >= 0))) + break; + if (!(ok = (fscanf(ofp, "%5lx", &offset) == 1))) + break; +#ifdef MAC +#ifdef __MWERKS__ + /* + MetroWerks CodeWarrior Pro 1's (AKA CW12) version of MSL + (ANSI C Libraries) needs this rewind or else the fprintf + stops working. This may also be true for CW11, but has + never been checked. + */ + rewind(ofp); +#endif +#endif + if (!(ok = (fseek(ofp, fpos, SEEK_SET) >= 0))) + break; + offset += txt_offset; + if (!(ok = (fprintf(ofp, "%05lx\n", offset) >= 0))) + break; + } + } + if (!ok) { + dead_data: + perror(line); /* report the problem */ + free((genericptr_t) line); + /* close and kill the aborted output file, then give up */ + Fclose(ofp); + Unlink(filename); + makedefs_exit(EXIT_FAILURE); + /*NOTREACHED*/ + } + free((genericptr_t) line); + + /* all done */ + Fclose(ofp); + + return; +} + void do_dungeon(void) { @@ -2255,6 +2154,53 @@ do_objs(void) return; } +/* Read one line from input, up to and including the next newline + * character. Returns a pointer to the heap-allocated string, or a + * null pointer if no characters were read. + * 3.7: redone to use nethack's alloc() rather than libc's malloc() + * and realloc(). + */ +static char * +fgetline(FILE *fd) +{ + static const int inc = (BUFSZ / 2) + 16; /* fgets() wants signed int */ + unsigned len = (unsigned) inc, newlen; /* alloc() wants unsigned int */ + char *c = (char *) alloc(len), *cprime, *ret; + + *c = '\0'; + for (;;) { + ret = fgets(c + len - inc, inc, fd); + if (!ret) { + /* don't just assume ret==Null indicates an error; last line + might lack terminating newline; if previous fgets() read it, + instead of returning we would have expanded the buffer and + tried for more, then got Null due to end of file having + already been reached */ + if (feof(fd) && *c && strlen(c) < len) { + Strcat(c, "\n"); /* append missing newline */ + } else { + free((genericptr_t) c), c = NULL; + } + break; /* either with or without added newline, we're done */ + } else if (strchr(c, '\n')) { + /* normal case: we have a full line */ + break; + } + /* didn't fit in c[0..len-1]; expand buffer and read some more + [this was much simpler (and possibly slightly more efficient) + with realloc() but less safe because return values from malloc() + and realloc() were not being checked for Null, and efficiency is + a red herring because growing the buffer will be extremely rare] */ + newlen = len + (unsigned) inc; + cprime = (char *) alloc(newlen); + (void) memcpy(cprime, c, len); + free((genericptr_t) c); + c = cprime; + len = newlen; + } + return c; +} + static char * tmpdup(const char* str) { @@ -2265,7 +2211,6 @@ tmpdup(const char* str) (void) strncpy(buf, str, 127); return buf; } -#endif /* OLD_MAKEDEFS_OPTIONS */ /* the STRICT_REF_DEF checking is way out of date... */ #ifdef STRICT_REF_DEF