diff --git a/util/makedefs.c b/util/makedefs.c index 313e019a7..c3acc3b14 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)makedefs.c 3.5 2006/12/09 */ +/* NetHack 3.5 makedefs.c $Date$ $Revision$ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ /* Copyright (c) Dean Luick, 1990. */ @@ -27,12 +27,12 @@ #include "patchlevel.h" #endif +#include #ifdef MAC # if defined(__SC__) || defined(__MRC__) /* MPW compilers */ # define MPWTOOL #include #include -#include # else /* MAC without MPWTOOL */ # define MACsansMPWTOOL # endif @@ -173,6 +173,7 @@ static boolean FDECL(h_filter, (char *)); static boolean FDECL(ranged_attk,(struct permonst*)); static int FDECL(mstrength,(struct permonst *)); static void NDECL(build_savebones_compat_string); +static void FDECL(do_ext_makedefs,(int , char **)); static boolean FDECL(qt_comment, (char *)); static boolean FDECL(qt_control, (char *)); @@ -222,6 +223,16 @@ main(void) else buf[len-1] = 0; /* remove return */ + if(buf[0]=='-' && buf[1]=='-'){ +#if 0 + split up buf into words + do_ext_makedefs(fakeargc, fakeargv); +#else + printf("extended makedefs not implemented for Mac OS9\n"); + exit(EXIT_FAILURE); +#endif + } + do_makedefs(buf); exit(EXIT_SUCCESS); return 0; @@ -238,6 +249,7 @@ char *argv[]; #ifdef FILE_PREFIX && (argc != 3) #endif + && !(argv[1][0]=='-' && argv[1][1]=='-') ) { Fprintf(stderr, "Bad arg count (%d).\n", argc-1); (void) fflush(stderr); @@ -250,7 +262,12 @@ char *argv[]; argc--;argv++; } #endif - do_makedefs(&argv[1][1]); + + if(argv[1][0]=='-' && argv[1][1]=='-'){ + do_ext_makedefs(argc, argv); + } else { + do_makedefs(&argv[1][1]); + } exit(EXIT_SUCCESS); /*NOTREACHED*/ return 0; @@ -258,22 +275,26 @@ char *argv[]; #endif +static void +link_sanity_check(){ + /* Note: these initializers don't do anything except guarantee that + we're linked properly. + */ + monst_init(); + objects_init(); +} + void do_makedefs(options) char *options; { boolean more_than_one; - /* Note: these initializers don't do anything except guarantee that - we're linked properly. - */ - monst_init(); - objects_init(); + link_sanity_check(); /* construct the current version number */ make_version(); - more_than_one = strlen(options) > 1; while (*options) { if (more_than_one) @@ -324,6 +345,358 @@ char *options; } +static FILE *inputfp; +static FILE *outputfp; + +#define TODO_GREP 1; +static void NDECL(do_grep); +static void NDECL(do_grep_showvars); +static int grep_trace = 0; + +static void +do_ext_makedefs(int argc, char **argv){ + int todo = 0; + + link_sanity_check(); + + argc--; argv++; /* skip program name */ + + while(argc){ + if(argv[0][0] != '-') break; + if(argv[0][1] != '-'){ + Fprintf(stderr, "Can't mix - and -- options.\n"); + exit(EXIT_FAILURE); + } +#define IS_OPTION(str) if(!strcmp(&argv[0][2], str)) +#define CONTINUE argv++, argc--; continue +#define CONSUME \ + argv++, argc--; \ + if(argc==0){Fprintf(stderr, "missing option\n"); exit(EXIT_FAILURE);} + IS_OPTION("input"){ + CONSUME; + if(!strcmp(argv[0], "-")){ + inputfp = stdin; + } else { + inputfp = fopen(argv[0], RDTMODE); + if(!inputfp){ + Fprintf(stderr, "Can't open '%s'.\n", argv[0]); + exit(EXIT_FAILURE); + } + } + CONTINUE; + } + IS_OPTION("output"){ + CONSUME; + if(!strcmp(argv[0], "-")){ + outputfp = stdout; + } else { + outputfp = fopen(argv[0], WRTMODE); + if(!outputfp){ + Fprintf(stderr, "Can't open '%s'.\n", argv[0]); + exit(EXIT_FAILURE); + } + } + CONTINUE; + } + IS_OPTION("grep"){ + if(todo){ + Fprintf(stderr, "Can't do grep and something else.\n"); + exit(EXIT_FAILURE); + } + todo = 1; + CONTINUE; + } + IS_OPTION("grep-showvars"){ + do_grep_showvars(); + exit(EXIT_SUCCESS); + } + IS_OPTION("grep-trace"){ + grep_trace = 1; + CONTINUE; + } +#ifdef notyet + IS_OPTION("grep-define"){ + } + IS_OPTION("grep-undef"){ + } + IS_OPTION("help"){ + } +#endif +#undef IS_OPTION + Fprintf(stderr, "Unknown option '%s'.\n", argv[0]); + exit(EXIT_FAILURE); + } + if(argc){ + Fprintf(stderr, "unexpected argument '%s'.\n", argv[0]); + exit(EXIT_FAILURE); + } + + switch(todo){ + default: + Fprintf(stderr, "Confused about what to do?\n"); + exit(EXIT_FAILURE); + case 0: + Fprintf(stderr, "Nothing to do?\n"); + exit(EXIT_FAILURE); + case 1: + do_grep(); break; + } +} + +/* + Filtering syntax: + Any line NOT starting with a caret is either suppressed or passed through + unchanged depending on the current conditional state. + + The default conditional state is printing on. + + Conditionals may be nested. + + makedefs will exit with a EXIT_FAILURE if any errors are detected; as many + errors as possible are detected before giving up. + + Unknown identifiers are treated as TRUE and also as an error to allow + processing to continue past the unknown identifier (note that "#undef" is + different than unknown). + + Any line starting with a caret is a control line; as in C, zero or more spaces + may be embedded in the line almost anywhere; the caret MUST be in column 1. + + Control lines: + ^^ a line starting with a (single) literal caret + ^# a comment - the line is ignored + ^?ID if defined(ID) + ^!ID if !defined(ID) + ^: else + ^. endif + +*/ +#define GREP_MAGIC '^' +#define GREP_STACK_SIZE 100 +static int grep_rewrite = 0; /* need to (possibly) rewrite lines */ +static int grep_writing = 1; /* need to copy lines to output */ +static int grep_errors = 0; +static int grep_sp = 0; +#define ST_LD(old,opp) (!!(old) | (!!(opp)<<1)) +#define ST_OLD(v) ((v) & 1) +#define ST_OPP(v) !!((v) & 2) +#define ST_ELSE 4 +static int grep_stack[GREP_STACK_SIZE] = {ST_LD(1,0)}; +static int grep_lineno = 0; + +struct grep_var { + const char *name; + int is_defined; /* 0 undef; 1 defined */ +}; +/* struct grep_var grep_vars[] in include file: */ +#include "mdgrep.h" + +static void +do_grep_showvars(){ + int x; + for(x=0;xis_defined, id); + } + return rv->is_defined; + } + + if(grep_trace){ + Fprintf(outputfp, "ID U %s\n", id); + } + Fprintf(stderr, "unknown identifier '%s' in line %d.\n", id, + grep_lineno); + grep_errors++; + return 2; /* So new features can be checked before makedefs + * is rebuilt. */ +} + +static void +grep_show_wstack(tag) + char *tag; +{ + int x; + + if(!grep_trace) return; + + Fprintf(outputfp, "%s w=%d sp=%d\t",tag,grep_writing, grep_sp); + for(x=grep_sp; x>=0 && x>grep_sp-6;x--){ + Fprintf(outputfp, "[%d]=%d ", x, grep_stack[x]); + } + Fprintf(outputfp, "\n"); +} + +static char * +do_grep_control(buf) + char *buf; +{ + int isif = 1; + char *buf0 = buf; + while(buf[0] && isspace(buf[0])) buf++; + switch(buf[0]){ + case '#': /* comment */ + break; + case '.': /* end of if level */ + if(grep_sp==0){ + Fprintf(stderr, "unmatched ^. (endif) at line %d.\n", + grep_lineno); + grep_errors++; + } else { + grep_writing = ST_OLD(grep_stack[grep_sp--]); + grep_show_wstack("pop"); + } + break; + case '!': /* if not ID */ + isif = 0; + /* FALLTHROUGH */ + case '?': /* if ID */ + if(grep_sp == GREP_STACK_SIZE-2){ + Fprintf(stderr, "stack overflow at line %d.", + grep_lineno); + exit(EXIT_FAILURE); + } + if(grep_writing){ + isif = grep_check_id(&buf[1])?isif:!isif; + grep_stack[++grep_sp] = ST_LD(grep_writing, !isif); + grep_writing = isif; + } else { + grep_stack[++grep_sp] = ST_LD(0, 0); + /* grep_writing = 0; */ + } + grep_show_wstack("push"); + break; + case ':': /* else */ + if(ST_ELSE & grep_stack[grep_sp]){ + Fprintf(stderr, +"multiple : for same conditional at line %d.\n", grep_lineno); + grep_errors++; + } + grep_writing = ST_OPP(grep_stack[grep_sp]); + grep_stack[grep_sp] |= ST_ELSE; + break; +#if defined(notyet) + case '(': /* start of expression */ +#endif + case GREP_MAGIC: /* ^^ -> ^ */ + return buf0; + default: + { + char str[10]; + if(isprint(buf[0])){ + str[0] = buf[0]; str[1] = '\0'; + } else { + sprintf(str, "0x%02x", buf[0]); + } + Fprintf(stderr, "unknown control ^%s at line %d.\n", + str, grep_lineno); + grep_errors++; + } + break; + } + return NULL; +} + +static void +do_grep_rewrite(buf) + char *buf; +{ + /* no language features use this yet */ + return; +} + +static void +do_grep(){ + char buf[16384]; /* looong, just in case */ + + if(!inputfp){ + Fprintf(stderr,"--grep requires --input\n"); + } + if(!outputfp){ + Fprintf(stderr,"--grep requires --output\n"); + } + if(!inputfp || !outputfp){ + exit(EXIT_FAILURE); + } + + while(!feof(inputfp) && !ferror(inputfp)){ + char *tmp; + char *buf1; + + if(fgets(buf, sizeof(buf), inputfp) == 0) break; + if(tmp=strchr(buf,'\n')) *tmp = '\0'; + grep_lineno++; + if(grep_trace){ + Fprintf(outputfp, "%04d %c >%s\n", + grep_lineno, + grep_writing?' ':'#', + buf + ); + } + + if(buf[0] == GREP_MAGIC){ + buf1 = do_grep_control(&buf[1]); + if(!buf1) continue; + } else { + buf1 = buf; + } + if(grep_rewrite) + do_grep_rewrite(buf1); + if(grep_writing) + Fprintf(outputfp, "%s\n", buf1); + } + if(ferror(inputfp)){ + Fprintf(stderr, "read error!\n"); + exit(EXIT_FAILURE); + } + if(ferror(outputfp)){ + Fprintf(stderr, "write error!\n"); + exit(EXIT_FAILURE); + } + fclose(inputfp); + fclose(outputfp); + if(grep_sp){ + Fprintf(stderr, "%d unterminated conditional level%s\n", + grep_sp, grep_sp==1?"":"s"); + grep_errors++; + } + if(grep_errors){ + Fprintf(stderr, "%d error%s detected.\n", grep_errors, + grep_errors==1?"":"s"); + exit(EXIT_FAILURE); + } +} + /* trivial text encryption routine which can't be broken with `tr' */ static diff --git a/util/mdgrep.h b/util/mdgrep.h new file mode 100644 index 000000000..70c08e448 --- /dev/null +++ b/util/mdgrep.h @@ -0,0 +1,267 @@ +/* + * This file generated by mdgrep.pl version 1.1. + * DO NOT EDIT! Your changes will be lost. + */ +static struct grep_var grep_vars[]={ + {"0", 0}, + {"1", 1}, +#if defined(AMIGA) + {"AMIGA", 1}, +#else + {"AMIGA", 0}, +#endif +#if defined(AMII_GRAPHICS) + {"AMII_GRAPHICS", 1}, +#else + {"AMII_GRAPHICS", 0}, +#endif +#if defined(ASCIIGRAPH) + {"ASCIIGRAPH", 1}, +#else + {"ASCIIGRAPH", 0}, +#endif +#if defined(BETA) + {"BETA", 1}, +#else + {"BETA", 0}, +#endif +#if defined(BSD_JOB_CONTROL) + {"BSD_JOB_CONTROL", 1}, +#else + {"BSD_JOB_CONTROL", 0}, +#endif +#if defined(CLIPPING) + {"CLIPPING", 1}, +#else + {"CLIPPING", 0}, +#endif +#if defined(COMPRESS) + {"COMPRESS", 1}, +#else + {"COMPRESS", 0}, +#endif +#if defined(DLB) + {"DLB", 1}, +#else + {"DLB", 0}, +#endif + {"FALSE", 0}, +#if defined(GEM_GRAPHICS) + {"GEM_GRAPHICS", 1}, +#else + {"GEM_GRAPHICS", 0}, +#endif +#if defined(GNOME_GRAPHICS) + {"GNOME_GRAPHICS", 1}, +#else + {"GNOME_GRAPHICS", 0}, +#endif +#if defined(HANGUPHANDLING) + {"HANGUPHANDLING", 1}, +#else + {"HANGUPHANDLING", 0}, +#endif +#if defined(MAC) + {"MAC", 1}, +#else + {"MAC", 0}, +#endif +#if defined(MAC_GRAPHICS) + {"MAC_GRAPHICS", 1}, +#else + {"MAC_GRAPHICS", 0}, +#endif +#if defined(MAIL) + {"MAIL", 1}, +#else + {"MAIL", 0}, +#endif +#if defined(MFLOPPY) + {"MFLOPPY", 1}, +#else + {"MFLOPPY", 0}, +#endif +#if defined(MSDOS) + {"MSDOS", 1}, +#else + {"MSDOS", 0}, +#endif +#if defined(MSWIN_GRAPHICS) + {"MSWIN_GRAPHICS", 1}, +#else + {"MSWIN_GRAPHICS", 0}, +#endif +#if defined(NOCWD_ASSUMPTIONS) + {"NOCWD_ASSUMPTIONS", 1}, +#else + {"NOCWD_ASSUMPTIONS", 0}, +#endif +#if defined(NOSAVEONHANGUP) + {"NOSAVEONHANGUP", 1}, +#else + {"NOSAVEONHANGUP", 0}, +#endif +#if defined(OS2) + {"OS2", 1}, +#else + {"OS2", 0}, +#endif +#if defined(POSIX_JOB_CONTROL) + {"POSIX_JOB_CONTROL", 1}, +#else + {"POSIX_JOB_CONTROL", 0}, +#endif +#if defined(QT_GRAPHICS) + {"QT_GRAPHICS", 1}, +#else + {"QT_GRAPHICS", 0}, +#endif +#if defined(RANDOM) + {"RANDOM", 1}, +#else + {"RANDOM", 0}, +#endif +#if defined(SAFERHANGUP) + {"SAFERHANGUP", 1}, +#else + {"SAFERHANGUP", 0}, +#endif +#if defined(SECURE) + {"SECURE", 1}, +#else + {"SECURE", 0}, +#endif +#if defined(SHELL) + {"SHELL", 1}, +#else + {"SHELL", 0}, +#endif +#if defined(SUSPEND) + {"SUSPEND", 1}, +#else + {"SUSPEND", 0}, +#endif +#if defined(TEXTCOLOR) + {"TEXTCOLOR", 1}, +#else + {"TEXTCOLOR", 0}, +#endif +#if defined(TOS) + {"TOS", 1}, +#else + {"TOS", 0}, +#endif + {"TRUE", 1}, +#if defined(TTY_GRAPHICS) + {"TTY_GRAPHICS", 1}, +#else + {"TTY_GRAPHICS", 0}, +#endif +#if defined(UNICODE_DRAWING) + {"UNICODE_DRAWING", 1}, +#else + {"UNICODE_DRAWING", 0}, +#endif +#if defined(UNICODE_PLAYERTEXT) + {"UNICODE_PLAYERTEXT", 1}, +#else + {"UNICODE_PLAYERTEXT", 0}, +#endif +#if defined(UNICODE_WIDEWINPORT) + {"UNICODE_WIDEWINPORT", 1}, +#else + {"UNICODE_WIDEWINPORT", 0}, +#endif +#if defined(UNIX) + {"UNIX", 1}, +#else + {"UNIX", 0}, +#endif +#if defined(USER_SOUNDS) + {"USER_SOUNDS", 1}, +#else + {"USER_SOUNDS", 0}, +#endif +#if defined(USE_TILES) + {"USE_TILES", 1}, +#else + {"USE_TILES", 0}, +#endif +#if defined(VAR_PLAYGROUND) + {"VAR_PLAYGROUND", 1}, +#else + {"VAR_PLAYGROUND", 0}, +#endif +#if defined(VMS) + {"VMS", 1}, +#else + {"VMS", 0}, +#endif +#if defined(WIN32) + {"WIN32", 1}, +#else + {"WIN32", 0}, +#endif +#if defined(WIN32_PLATFORM_HPCPRO) + {"WIN32_PLATFORM_HPCPRO", 1}, +#else + {"WIN32_PLATFORM_HPCPRO", 0}, +#endif +#if defined(WIN32_PLATFORM_WFSP) + {"WIN32_PLATFORM_WFSP", 1}, +#else + {"WIN32_PLATFORM_WFSP", 0}, +#endif +#if defined(WINNT) + {"WINNT", 1}, +#else + {"WINNT", 0}, +#endif +#if defined(WIN_CE) + {"WIN_CE", 1}, +#else + {"WIN_CE", 0}, +#endif +#if defined(WIN_CE_POCKETPC) + {"WIN_CE_POCKETPC", 1}, +#else + {"WIN_CE_POCKETPC", 0}, +#endif +#if defined(WIN_CE_PS2xx) + {"WIN_CE_PS2xx", 1}, +#else + {"WIN_CE_PS2xx", 0}, +#endif +#if defined(WIN_CE_SMARTPHONE) + {"WIN_CE_SMARTPHONE", 1}, +#else + {"WIN_CE_SMARTPHONE", 0}, +#endif +#if defined(WIZARD) + {"WIZARD", 1}, +#else + {"WIZARD", 0}, +#endif +#if defined(X11_GRAPHICS) + {"X11_GRAPHICS", 1}, +#else + {"X11_GRAPHICS", 0}, +#endif +#if defined(ZEROCOMP) + {"ZEROCOMP", 1}, +#else + {"ZEROCOMP", 0}, +#endif +#if defined(ZLIB_COMP) + {"ZLIB_COMP", 1}, +#else + {"ZLIB_COMP", 0}, +#endif +#if defined(__BEOS__) + {"__BEOS__", 1}, +#else + {"__BEOS__", 0}, +#endif + {0,0} +}; +/* End of file */ diff --git a/util/mdgrep.pl b/util/mdgrep.pl new file mode 100644 index 000000000..472a3611b --- /dev/null +++ b/util/mdgrep.pl @@ -0,0 +1,94 @@ +#!perl +# NetHack 3.5 makedefs.c $Date$ $Revision$ +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008 +# NetHack may be freely redistributed. See license for details. + +# Operating Systems: +@os = qw/WIN32 MSDOS VMS UNIX TOS AMIGA MAC WINNT __BEOS__ WIN_CE OS2 + WIN_CE_SMARTPHONE WIN_CE_POCKETPC WIN_CE_PS2xx + WIN32_PLATFORM_HPCPRO WIN32_PLATFORM_WFSP/; + +# Window Systems: +@win = qw/TTY_GRAPHICS MAC_GRAPHICS AMII_GRAPHICS MSWIN_GRAPHICS X11_GRAPHICS + QT_GRAPHICS GNOME_GRAPHICS GEM_GRAPHICS/; + +# Game Features: +@feature = qw/ZEROCOMP USE_TILES ASCIIGRAPH CLIPPING TEXTCOLOR + COMPRESS ZLIB_COMP RANDOM SECURE USER_SOUNDS WIZARD + SAFERHANGUP MFLOPPY NOCWD_ASSUMPTIONS + VAR_PLAYGROUND DLB SHELL SUSPEND NOSAVEONHANGUP HANGUPHANDLING + BSD_JOB_CONTROL MAIL POSIX_JOB_CONTROL + UNICODE_DRAWING UNICODE_WIDEWINPORT UNICODE_PLAYERTEXT +/; + +# Miscellaneous +@misc = qw/BETA/; + +# JUNK: +# MICRO BSD __GNUC__ NHSTDC TERMLIB __linux__ LINUX WIN32CON NO_TERMS +# ULTRIX_PROTO TERMINFO _DCC DISPMAP OPT_DISPMAP TARGET_API_MAC_CARBON +# NOTTYGRAPHICS SYSV ULTRIX MAKEDEFS LEV_LEX_C __STDC__ +# BITCOUNT TILE_X COLORS_IN_USE CHDIR KR1ED +# apollo __APPLE__ AIX_31 PC9800 __MACH__ _GNU_SOURCE __EMX__ DGUX +# __MWERKS__ __MRC__ __BORLANDC__ LINT THINK_C __SC__ AZTEC_C __FreeBSD__ +# USE_PROTOTYPES __DJGPP__ macintosh POSIX_TYPES SUNOS4 _MSC_VER __OpenBSD__ +# GCC_WARN VOIDYYPUT FLEX_SCANNER FLEXHACK_SCANNER WIERD_LEX +# NeXT __osf__ SVR4 _AIX32 _BULL_SOURCE AUX __sgi GNUDOS +# TIMED_DELAY DEF_MAILREADER DEF_PAGER NO_SIGNAL PC_LOCKING LATTICE __GO32__ +# msleep NO_FILE_LINKS bsdi HPUX AMIFLUSH SYSFLAGS +# OVERLAY USE_TRAMPOLI USE_OVLx SPEC_LEV DGN_COMP +# SCREEN_BIOS SCREEN_DJGPPFAST SCREEN_VGA SCREEN_8514 +# EXEPATH NOTSTDC SELECTSAVED NOTPARMDECL + +# constants +@const_true = qw/1 TRUE/; +@const_false = qw/0 FALSE/; + +sub start_file { + ($rev) = ('$Revision$') =~ m/: (.*) .$/; + open(OUT, ">mdgrep.h") || die "open mkgrep.h: $!"; + print OUT <