#define CONFIGURE_VERSION 5 #define EDIT_SOURCE #define NO_MALLOC #define NO_SOCKETS #define NO_OPCODES #include "std.h" #include "lex.h" #include "preprocess.h" #include "make_func.h" #include "cc.h" #include "hash.h" #include #include #ifdef WIN32 #include #include #endif #if defined(DEBUG) || defined(WIN32) #define TO_DEV_NULL "" #else #define TO_DEV_NULL ">/dev/null 2>&1" #endif /* Using an include file at this point would be bad */ #ifdef PEDANTIC char *malloc(int); char *realloc(char *, int); void free(char *); #endif char *outp; static int buffered = 0; static int nexpands = 0; FILE *yyin = 0, *yyout = 0; #define SYNTAX "edit_source [-process file] [-options] [-malloc] [-build_func_spec 'command'] [-build_efuns] [-configure]\n" /* The files we fool with. (Actually, there are more. See -process). * * TODO: teach this file how to fix bugs in the source code :) */ #define OPTIONS_INCL "options_incl.h" #define PACKAGES "packages/packages" #define OPTIONS_H "options.h" #define LOCAL_OPTIONS "local_options" #define OPTION_DEFINES "option_defs.c" #define FUNC_SPEC "func_spec.c" #define FUNC_SPEC_CPP "func_spec.cpp" #define EFUN_TABLE "efunctions.h" #define OPC_PROF "opc.h" #define OPCODES "opcodes.h" #define EFUN_PROTO "efun_protos.h" #define EFUN_DEFS "efun_defs.c" #define PRAGMA_NOTE_CASE_START 1 int num_packages = 0; char *packages[100]; char ppchar; char *current_file = 0; int current_line; int grammar_mode = 0; /* which section we're in for .y files */ int in_c_case, cquote, pragmas, block_nest; char yytext[MAXLINE]; static char defbuf[DEFMAX]; typedef struct incstate_t { struct incstate_t *next; FILE *yyin; int line; char *file; } incstate; static incstate *inctop = 0; #define CHAR_QUOTE 1 #define STRING_QUOTE 2 static void add_define (const char *, int, const char *); #ifdef WIN32 #include int compile(char *command) { FILE *tf = fopen("trash_me.bat","wt+"); fprintf(tf,"%s%s\n%s", "@echo off\n", command, "if errorlevel == 1 goto error\n" "del trash_me.err >nul\n" "goto ok\n" ":error\n" "echo ERROR > trash_me.err\n" ":ok\n"); fclose(tf); if (!system("trash_me.bat > nul")) return 1; if (_access("trash_me.err",0) ) return 1; return 0; } #else int compile (char * str) { return system(str); } #endif #if defined(WIN32) int dos_style_link (char * x, char * y) { char link_cmd[100]; sprintf(link_cmd, "copy %s %s", x, y); return system(link_cmd); } #endif void yyerror (const char * str) { fprintf(stderr, "%s:%d: %s\n", current_file, current_line, str); exit(1); } void mf_fatal (const char * str) { yyerror(str); } void yywarn (char * str) { /* ignore errors :) local_options generates redefinition warnings, which we don't want to see */ } void yyerrorp (const char * str) { char buff[200]; sprintf(buff, str, ppchar); fprintf(stderr, "%s:%d: %s\n", current_file, current_line, buff); exit(1); } static void add_input (const char * p) { int l = strlen(p); if (outp - l < defbuf) yyerror("Macro expansion buffer overflow.\n"); strncpy(outp - l, p, l); outp -= l; } #define SKIPW(foo) while (isspace(*foo)) foo++; static char *skip_comment(char *tmp, int flag) { int c; for (;;) { while ((c = *++tmp) != '*') { if (c == EOF) yyerror("End of file in a comment"); if (c == '\n') { nexpands = 0; current_line++; if (!fgets(yytext, MAXLINE - 1, yyin)) yyerror("End of file in a comment"); if (flag && yyout) fputs(yytext, yyout); tmp = yytext - 1; } } do { if ((c = *++tmp) == '/') return tmp + 1; if (c == '\n') { nexpands = 0; current_line++; if (!fgets(yytext, MAXLINE - 1, yyin)) yyerror("End of file in a comment"); if (flag && yyout) fputs(yytext, yyout); tmp = yytext - 1; } } while (c == '*'); } } static void refill() { register char *p, *yyp; int c; if (fgets(p = yyp = defbuf + (DEFMAX >> 1), MAXLINE - 1, yyin)) { while (((c = *yyp++) != '\n') && (c != EOF)) { if (c == '/') { if ((c = *yyp) == '*') { yyp = skip_comment(yyp, 0); continue; } else if (c == '/') break; } *p++ = c; } } else yyerror("End of macro definition in \\"); nexpands = 0; current_line++; *p = 0; return; } static void handle_define() { char namebuf[NSIZE]; char args[NARGS][NSIZE]; char mtext[MLEN]; char *end; register char *tmp = outp, *q; q = namebuf; end = q + NSIZE - 1; while (isalunum(*tmp)) { if (q < end) *q++ = *tmp++; else yyerror("Name too long.\n"); } if (q == namebuf) yyerror("Macro name missing.\n"); if (*namebuf != '_' && !isalpha(*namebuf)) yyerror("Invalid macro name.\n"); *q = 0; if (*tmp == '(') { /* if "function macro" */ int arg; int inid; char *ids = (char *) NULL; tmp++; /* skip '(' */ SKIPW(tmp); if (*tmp == ')') { arg = 0; } else { for (arg = 0; arg < NARGS;) { end = (q = args[arg]) + NSIZE - 1; while (isalunum(*tmp) || (*tmp == '#')) { if (q < end) *q++ = *tmp++; else yyerror("Name too long.\n"); } if (q == args[arg]) { char buff[200]; sprintf(buff, "Missing argument %d in #define parameter list", arg + 1); yyerror(buff); } arg++; SKIPW(tmp); if (*tmp == ')') break; if (*tmp++ != ',') { yyerror("Missing ',' in #define parameter list"); } SKIPW(tmp); } if (arg == NARGS) yyerror("Too many macro arguments"); } tmp++; /* skip ')' */ end = mtext + MLEN - 2; for (inid = 0, q = mtext; *tmp;) { if (isalunum(*tmp)) { if (!inid) { inid++; ids = tmp; } } else { if (inid) { int idlen = tmp - ids; int n, l; for (n = 0; n < arg; n++) { l = strlen(args[n]); if (l == idlen && strncmp(args[n], ids, l) == 0) { q -= idlen; *q++ = MARKS; *q++ = n + MARKS + 1; break; } } inid = 0; } } if ((*q = *tmp++) == MARKS) *++q = MARKS; if (q < end) q++; else yyerror("Macro text too long"); if (!*tmp && tmp[-2] == '\\') { q -= 2; refill(); tmp = defbuf + (DEFMAX >> 1); } } *--q = 0; add_define(namebuf, arg, mtext); } else if (isspace(*tmp) || (!*tmp && (*(tmp+1) = '\0', *tmp = ' '))) { end = mtext + MLEN - 2; for (q = mtext; *tmp;) { *q = *tmp++; if (q < end) q++; else yyerror("Macro text too long"); if (!*tmp && tmp[-2] == '\\') { q -= 2; refill(); tmp = defbuf + (DEFMAX >> 1); } } *q = 0; add_define(namebuf, -1, mtext); } else { yyerror("Illegal macro symbol"); } return; } #define SKPW while (isspace(*outp)) outp++ static int cmygetc() { int c; for (;;) { if ((c = *outp++) == '/') { if ((c = *outp) == '*') outp = skip_comment(outp, 0); else if (c == '/') return -1; else return c; } else return c; } } /* Check if yytext is a macro and expand if it is. */ static int expand_define() { defn_t *p; char expbuf[DEFMAX]; char *args[NARGS]; char buf[DEFMAX]; char *q, *e, *b; if (nexpands++ > EXPANDMAX) yyerror("Too many macro expansions"); if (!(p = lookup_define(yytext))) return 0; if (p->nargs == -1) { add_input(p->exps); } else { int c, parcnt = 0, dquote = 0, squote = 0; int n; SKPW; if (*outp++ != '(') yyerror("Missing '(' in macro call"); SKPW; if ((c = *outp++) == ')') n = 0; else { q = expbuf; args[0] = q; for (n = 0; n < NARGS;) { switch (c) { case '"': if (!squote) dquote ^= 1; break; case '\'': if (!dquote) squote ^= 1; break; case '(': if (!squote && !dquote) parcnt++; break; case ')': if (!squote && !dquote) parcnt--; break; case '#': if (!squote && !dquote) { *q++ = c; if (*outp++ != '#') yyerror("'#' expected"); } break; case '\\': if (squote || dquote) { *q++ = c; c = *outp++; } break; case '\n': if (squote || dquote) yyerror("Newline in string"); break; } if (c == ',' && !parcnt && !dquote && !squote) { *q++ = 0; args[++n] = q; } else if (parcnt < 0) { *q++ = 0; n++; break; } else { if (c == EOF) yyerror("Unexpected end of file"); if (q >= expbuf + DEFMAX - 5) { yyerror("Macro argument overflow"); } else { *q++ = c; } } if (!squote && !dquote) { if ((c = cmygetc()) < 0) yyerror("End of macro in // comment"); } else c = *outp++; } if (n == NARGS) { yyerror("Maximum macro argument count exceeded"); return 0; } } if (n != p->nargs) { yyerror("Wrong number of macro arguments"); return 0; } /* Do expansion */ b = buf; e = p->exps; while (*e) { if (*e == '#' && *(e + 1) == '#') e += 2; if (*e == MARKS) { if (*++e == MARKS) *b++ = *e++; else { for (q = args[*e++ - MARKS - 1]; *q;) { *b++ = *q++; if (b >= buf + DEFMAX) yyerror("Macro expansion overflow"); } } } else { *b++ = *e++; if (b >= buf + DEFMAX) yyerror("Macro expansion overflow"); } } *b++ = 0; add_input(buf); } return 1; } static int exgetc() { register char c, *yyp; SKPW; while (isalpha(c = *outp) || c == '_') { yyp = yytext; do { *yyp++ = c; } while (isalnum(c = *++outp) || (c == '_')); *yyp = '\0'; if (!strcmp(yytext, "defined")) { /* handle the defined "function" in #/%if */ SKPW; if (*outp++ != '(') yyerror("Missing ( after 'defined'"); SKPW; yyp = yytext; if (isalpha(c = *outp) || c == '_') { do { *yyp++ = c; } while (isalnum(c = *++outp) || (c == '_')); *yyp = '\0'; } else yyerror("Incorrect definition macro after defined(\n"); SKPW; if (*outp != ')') yyerror("Missing ) in defined"); if (lookup_define(yytext)) add_input("1 "); else add_input("0 "); } else { if (!expand_define()) add_input("0 "); else SKPW; } } return c; } static int skip_to(const char *token, const char *atoken) { char b[20], *p, *end; int c; int nest; for (nest = 0;;) { if (!fgets(outp = defbuf + (DEFMAX >> 1), MAXLINE-1,yyin)) { yyerror("Unexpected end of file while skipping"); } current_line++; if ((c = *outp++) == ppchar) { while (isspace(*outp)) outp++; end = b + sizeof b - 1; for (p = b; (c = *outp++) != '\n' && !isspace(c) && c != EOF;) { if (p < end) *p++ = c; } *p = 0; if (!strcmp(b, "if") || !strcmp(b, "ifdef") || !strcmp(b, "ifndef")) { nest++; } else if (nest > 0) { if (!strcmp(b, "endif")) nest--; } else { if (!strcmp(b, token)) { *--outp = c; add_input(b); *--outp = ppchar; buffered = 1; return 1; } else if (atoken && !strcmp(b, atoken)) { *--outp = c; add_input(b); *--outp = ppchar; buffered = 1; return 0; } else if (!strcmp(b, "elif")) { *--outp = c; add_input(b); *--outp = ppchar; buffered = 1; return !atoken; } } } } } #include "preprocess.c" static int maybe_open_input_file (const char * fn) { if ((yyin = fopen(fn, "r")) == NULL) { return 0; } if (current_file) free((char *)current_file); current_file = (char *)malloc(strlen(fn) + 1); current_line = 0; strcpy(current_file, fn); return 1; } static void open_input_file (const char * fn) { if (!maybe_open_input_file(fn)) { perror(fn); exit(-1); } } static void open_output_file (const char * fn) { if ((yyout = fopen(fn, "w")) == NULL) { perror(fn); exit(-1); } } static void close_output_file() { fclose(yyout); yyout = 0; } static char *protect (const char * p) { static char buf[1024]; char *bufp = buf; while (*p) { if (*p=='"' || *p == '\\') *bufp++ = '\\'; *bufp++ = *p++; } *bufp = 0; return buf; } static void create_option_defines() { defn_t *p; int count = 0; int i; fprintf(stderr, "Writing build options to %s ...\n", OPTION_DEFINES); open_output_file(OPTION_DEFINES); fprintf(yyout, "{\n"); for (i = 0; i < DEFHASH; i++) { for (p = defns[i]; p; p = p->next) if (!(p->flags & DEF_IS_UNDEFINED)) { count++; fprintf(yyout, " \"__%s__\", \"%s\",\n", p->name, protect(p->exps)); if (strncmp(p->name, "PACKAGE_", 8)==0) { int len; char *tmp, *t; len = strlen(p->name + 8); t = tmp = (char *)malloc(len + 1); strcpy(tmp, p->name + 8); while (*t) { if (isupper(*t)) *t = tolower(*t); t++; } if (num_packages == 100) { fprintf(stderr, "Too many packages.\n"); exit(-1); } packages[num_packages++] = tmp; } } } fprintf(yyout,"};\n\n#define NUM_OPTION_DEFS %d\n\n", count); close_output_file(); } static void deltrail() { register char *p; p = outp; while (*p && !isspace(*p) && *p != '\n') { p++; } *p = 0; } static void handle_include (char * name) { char *p; static char buf[1024]; FILE *f; incstate *is; if (*name != '"') { defn_t *d; if ((d = lookup_define(name)) && d->nargs == -1) { char *q; q = d->exps; while (isspace(*q)) q++; handle_include(q); } else { yyerrorp("Missing leading \" in %cinclude"); } return; } for (p = ++name; *p && *p != '"'; p++); if (!*p) yyerrorp("Missing trailing \" in %cinclude"); *p = 0; if ((f = fopen(name, "r")) != NULL) { is = (incstate *) malloc(sizeof(incstate) /*, 61, "handle_include: 1" */); is->yyin = yyin; is->line = current_line; is->file = current_file; is->next = inctop; inctop = is; current_line = 0; current_file = (char *)malloc(strlen(name) + 1 /*, 62, "handle_include: 2" */); strcpy(current_file, name); yyin = f; } else { sprintf(buf, "Cannot %cinclude %s", ppchar, name); yyerror(buf); } } static void handle_pragma (char * name) { if (!strcmp(name, "auto_note_compiler_case_start")) pragmas |= PRAGMA_NOTE_CASE_START; else if (!strcmp(name, "no_auto_note_compiler_case_start")) pragmas &= ~PRAGMA_NOTE_CASE_START; else if (!strncmp(name, "ppchar:", 7) && *(name + 8)) ppchar = *(name + 8); else yyerrorp("Unidentified %cpragma"); } static void preprocess() { register char *yyp, *yyp2; int c; int cond; while (buffered ? (yyp = yyp2 = outp) : fgets(yyp = yyp2 = defbuf + (DEFMAX >> 1), MAXLINE-1, yyin)) { if (!buffered) current_line++; else buffered = 0; while (isspace(*yyp2)) yyp2++; if ((c = *yyp2) == ppchar) { int quote = 0; char sp_buf = 0, *oldoutp; if (c == '%' && yyp2[1] == '%') grammar_mode++; outp = 0; if (yyp != yyp2) yyerrorp("Misplaced '%c'.\n"); while (isspace(*++yyp2)); yyp++; for (;;) { if ((c = *yyp2++) == '"') quote ^= 1; else{ if (!quote && c == '/') { if (*yyp2 == '*') { yyp2 = skip_comment(yyp2, 0); continue; } else if (*yyp2 == '/') break; } if (!outp && isspace(c)) outp = yyp; if (c == '\n' || c == EOF) break; } *yyp++ = c; } if (outp) { if (yyout) sp_buf = *(oldoutp = outp); *outp++ = 0; while (isspace(*outp)) outp++; } else outp = yyp; *yyp = 0; yyp = defbuf + (DEFMAX >> 1) + 1; if (!strcmp("define", yyp)) { handle_define(); } else if (!strcmp("if", yyp)) { cond = cond_get_exp(0); if (*outp != '\n') yyerrorp("Condition too complex in %cif"); else handle_cond(cond); } else if (!strcmp("ifdef", yyp)) { deltrail(); handle_cond(lookup_define(outp) != 0); } else if (!strcmp("ifndef", yyp)) { deltrail(); handle_cond(!lookup_define(outp)); } else if (!strcmp("elif", yyp)) { handle_elif(); } else if (!strcmp("else", yyp)) { handle_else(); } else if (!strcmp("endif", yyp)) { handle_endif(); } else if (!strcmp("undef", yyp)) { defn_t *d; deltrail(); if ((d = lookup_definition(outp))) { d->flags |= DEF_IS_UNDEFINED; d->flags &= ~DEF_IS_NOT_LOCAL; } else { add_define(outp, -1, " "); d = lookup_definition(outp); d->flags |= DEF_IS_UNDEFINED; d->flags &= ~DEF_IS_NOT_LOCAL; } } else if (!strcmp("echo", yyp)) { fprintf(stderr, "echo at line %d of %s: %s\n", current_line, current_file, outp); } else if (!strcmp("include", yyp)) { handle_include(outp); } else if (!strcmp("pragma", yyp)) { handle_pragma(outp); } else if (yyout) { if (!strcmp("line", yyp)) { fprintf(yyout, "#line %d \"%s\"\n", current_line, current_file); } else { if (sp_buf) *oldoutp = sp_buf; if (pragmas & PRAGMA_NOTE_CASE_START) { if (*yyp == '%') pragmas &= ~PRAGMA_NOTE_CASE_START; } fprintf(yyout, "%s\n", yyp-1); } } else { char buff[200]; sprintf(buff, "Unrecognised %c directive : %s\n", ppchar, yyp); yyerror(buff); } } else if (c == '/') { if ((c = *++yyp2) == '*') { if (yyout) fputs(yyp, yyout); yyp2 = skip_comment(yyp2, 1); } else if (c == '/' && !yyout) continue; else if (yyout) { fprintf(yyout, "%s", yyp); } } else if (yyout) { fprintf(yyout, "%s", yyp); if (pragmas & PRAGMA_NOTE_CASE_START) { static int line_to_print; line_to_print = 0; if (!in_c_case) { while (isalunum(*yyp2)) yyp2++; while (isspace(*yyp2)) yyp2++; if (*yyp2 == ':') { in_c_case = 1; yyp2++; } } if (in_c_case) { while ((c = *yyp2++)) { switch(c) { case '{': { if (!cquote && (++block_nest == 1)) line_to_print = 1; break; } case '}': { if (!cquote) { if (--block_nest < 0) yyerror("Too many }'s"); } break; } case '"': if (!(cquote & CHAR_QUOTE)) cquote ^= STRING_QUOTE; break; case '\'': if (!(cquote & STRING_QUOTE)) cquote ^= CHAR_QUOTE; break; case '\\': if (cquote && *yyp2) yyp2++; break; case '/': if (!cquote) { if ((c = *yyp2) == '*') { yyp2 = skip_comment(yyp2, 1); } else if (c == '/') { *(yyp2-1) = '\n'; *yyp2 = '\0'; } } break; case ':': if (!cquote && !block_nest) yyerror("Case started before ending previous case with ;"); break; case ';': if (!cquote && !block_nest) in_c_case = 0; } } } if (line_to_print) fprintf(yyout, "#line %d \"%s\"\n", current_line + 1,current_file); } } } if (iftop) { ifstate_t *p = iftop; while (iftop) { p = iftop; iftop = p->next; free((char *)p); } yyerrorp("Missing %cendif"); } fclose(yyin); free(current_file); current_file = 0; nexpands = 0; if (inctop) { incstate *p = inctop; current_file = p->file; current_line = p->line; yyin = p->yyin; inctop = p->next; free((char *) p); preprocess(); } else yyin = 0; } void make_efun_tables() { #define NUM_FILES 5 static const char* outfiles[NUM_FILES] = { EFUN_TABLE, OPC_PROF, OPCODES, EFUN_PROTO, EFUN_DEFS }; FILE *files[NUM_FILES]; int i; fprintf(stderr, "Building efun tables ...\n"); for (i = 0; i < NUM_FILES; i++) { files[i] = fopen(outfiles[i], "w"); if (!files[i]) { fprintf(stderr, "make_func: unable to open %s\n", outfiles[i]); exit(-1); } fprintf(files[i], "/*\n\tThis file is automatically generated by make_func.\n"); fprintf(files[i], "\tdo not make any manual changes to this file.\n*/\n\n"); } fprintf(files[0],"\n#include \"efun_protos.h\"\n\n"); fprintf(files[0],"\ntypedef void (*func_t) (void);\n\n"); fprintf(files[0],"func_t efun_table[] = {\n"); fprintf(files[1],"\ntypedef struct opc_s { char *name; int count; } opc_t;\n\n"); fprintf(files[1],"opc_t opc_efun[] = {\n"); fprintf(files[2], "\n/* operators */\n\n"); for (i = 0; i < op_code; i++) { fprintf(files[2],"#define %-30s %d\n", oper_codes[i], i+1); } fprintf(files[2],"\n/* 1 arg efuns */\n#define BASE %d\n\n", op_code+1); for (i = 0; i < efun1_code; i++) { fprintf(files[0],"\tf_%s,\n", efun1_names[i]); fprintf(files[1],"{\"%s\", 0},\n", efun1_names[i]); fprintf(files[2],"#define %-30s %d\n", efun1_codes[i], i+op_code+1); fprintf(files[3],"void f_%s (void);\n", efun1_names[i]); } fprintf(files[2],"\n/* efuns */\n#define ONEARG_MAX %d\n\n", efun1_code + op_code+1); for (i = 0; i < efun_code; i++) { fprintf(files[0],"\tf_%s,\n", efun_names[i]); fprintf(files[1],"{\"%s\", 0},\n", efun_names[i]); fprintf(files[2],"#define %-30s %d\n", efun_codes[i], i+op_code+efun1_code+1); fprintf(files[3],"void f_%s (void);\n", efun_names[i]); } fprintf(files[0], "};\n"); fprintf(files[1], "};\n"); if (efun1_code + op_code >= 256) { fprintf(stderr, "You have way too many efuns. Contact the MudOS developers if you really need this many.\n"); } if (efun_code >= 256) { fprintf(stderr, "You have way too many efuns. Contact the MudOS developers if you really need this many.\n"); } fprintf(files[2],"\n/* efuns */\n#define NUM_OPCODES %d\n\n", efun_code + efun1_code + op_code); /* Now sort the main_list */ for (i = 0; i < num_buff; i++) { int j; for (j = 0; j < i; j++) if (strcmp(key[i], key[j]) < 0) { const char *tmp; tmp = key[i]; key[i] = key[j]; key[j] = tmp; tmp = buf[i]; buf[i] = buf[j]; buf[j] = tmp; } } /* Now display it... */ fprintf(files[4], "{\n"); for (i = 0; i < num_buff; i++) fprintf(files[4], "%s", buf[i]); fprintf(files[4], "\n};\nint efun_arg_types[] = {\n"); for (i=0; i < last_current_type; i++) { if (arg_types[i] == 0) fprintf(files[4], "0,\n"); else fprintf(files[4], "%s,", ctype(arg_types[i])); } fprintf(files[4],"};\n"); for (i=0; i < NUM_FILES; i++) fclose(files[i]); } static void handle_local_defines(int check) { defn_t *p; int i; int problem = 0; for (i = 0; i < DEFHASH; i++) for (p = defns[i]; p; p = p->next) p->flags |= DEF_IS_NOT_LOCAL; /* undefine _OPTIONS_H_ so it doesn't get propagated to the mudlib or interfere with copies of options.h */ if ((p = lookup_define("_OPTIONS_H_"))) { p->flags |= DEF_IS_UNDEFINED; p->flags &= ~DEF_IS_NOT_LOCAL; } if ((p = lookup_define("DEBUG"))) p->flags &= ~DEF_IS_NOT_LOCAL; ppchar = '#'; preprocess(); if ((p = lookup_define("_OPTIONS_H_"))) p->flags |= DEF_IS_UNDEFINED; if (!check) return; for (i = 0; i < DEFHASH; i++) for (p = defns[i]; p; p = p->next) if (p->flags & DEF_IS_NOT_LOCAL) { fprintf(stderr, "No setting for %s in '%s'.\n", p->name, LOCAL_OPTIONS); problem = 1; } if (problem) { fprintf(stderr, "\ ***This local_options file appears to have been written for an\n\ ***earlier version of the MudOS driver. Please lookup the new options\n\ ***(mentioned above) in the options.h file, decide how you would like them\n\ ***set, and add those settings to the local_options file.\n"); exit(-1); } } static void write_options_incl (int local) { open_output_file(OPTIONS_INCL); if (local) { fprintf(yyout, "#include \"%s\"\n", LOCAL_OPTIONS); } else { fprintf(yyout, "#include \"%s\"\n", OPTIONS_H); } close_output_file(); } static void handle_options(int full) { open_input_file(OPTIONS_H); ppchar = '#'; preprocess(); if (!full) { /* don't do any checking, just find out what is defined */ if (maybe_open_input_file(LOCAL_OPTIONS)) handle_local_defines(0); return; } if (maybe_open_input_file(LOCAL_OPTIONS)) { fprintf(stdout, "Using '%s' file ...\n", LOCAL_OPTIONS); handle_local_defines(1); write_options_incl(1); } else { fprintf(stderr, "No \"%s\" file present. If you create one from \"%s\",\nyou can use it when you get a new driver, and you will be warned if there are\nchanges to the real %s which you should include in your local file.\n", LOCAL_OPTIONS, OPTIONS_H, OPTIONS_H); write_options_incl(0); } create_option_defines(); } static void handle_build_func_spec (char * command) { char buf[1024]; int i; fprintf(stderr, "Building compiler files ...\n"); sprintf(buf, "%s %s >%s", command, FUNC_SPEC, FUNC_SPEC_CPP); system(buf); for (i = 0; i < num_packages; i++) { sprintf(buf, "%s -I. packages/%s_spec.c >>%s", command, packages[i], FUNC_SPEC_CPP); system(buf); } open_output_file(PACKAGES); fprintf(yyout, "SRC="); for (i=0; i < num_packages; i++) fprintf(yyout, "%s.c ", packages[i]); fprintf(yyout, "\nOBJ="); for (i=0; i < num_packages; i++) fprintf(yyout, "%s.$(O) ", packages[i]); fprintf(yyout, "\n"); close_output_file(); } static void handle_process (char * file) { char buf[1024]; int l; strcpy(buf, file); l = strlen(buf); if (strcmp(buf + l - 4, ".pre")) { fprintf(stderr, "Filename for -process must end in .pre\n"); exit(-1); } *(buf + l - 4) = 0; fprintf(stderr, "Creating '%s' from '%s' ...\n", buf, file); #ifdef DEBUG /* pass down the DEBUG define from CFLAGS */ add_define("DEBUG", -1, " "); #endif open_input_file(file); open_output_file(buf); ppchar = '%'; preprocess(); close_output_file(); } static void handle_build_efuns() { void yyparse(); num_buff = op_code = efun_code = efun1_code = 0; open_input_file(FUNC_SPEC_CPP); yyparse(); make_efun_tables(); } static void handle_applies() { FILE *f = fopen("applies", "r"); FILE *out = fopen("applies.h", "w"); FILE *table = fopen("applies_table.c", "w"); char buf[8192]; char *colon; char *p; int apply_number = 0; fprintf(out, "/* autogenerated from 'applies' */\n#ifndef APPLIES_H\n#define APPLIES_H\n\nextern const char *applies_table[];\n\n/* the folowing must be the first character of __INIT */\n#define APPLY___INIT_SPECIAL_CHAR\t\t'#'\n"); fprintf(table, "/* autogenerated from 'applies' */\n\nconst char *applies_table[] = {\n"); while (fgets(buf, 8192, f)) { buf[strlen(buf)-1] = 0; if (buf[0] == '#') break; if ((colon = strchr(buf, ':'))) { *colon++ = 0; fprintf(out, "#define APPLY_%-30s\t\"%s\"\n", buf, colon); } else { fprintf(out, "#define APPLY_%-30s\t", buf); p = buf; while (*p) { *p = tolower(*p); p++; } fprintf(out, "\"%s\"\n", buf); } } while (fgets(buf, 8192, f)) { buf[strlen(buf)-1] = 0; if ((colon = strchr(buf, ':'))) { *colon++ = 0; fprintf(table, "\t\"%s\",\n", colon); fprintf(out, "#define APPLY_%-30s\t%i\n", buf, apply_number++); } else { fprintf(out, "#define APPLY_%-30s\t%i\n", buf, apply_number++); p = buf; while (*p) { *p = tolower(*p); p++; } fprintf(table, "\t\"%s\",\n", buf); } } fprintf(table, "};\n"); fprintf(out, "\n#define NUM_MASTER_APPLIES\t%i\n\n#endif\n", apply_number); fclose(out); fclose(table); fclose(f); } static void handle_malloc() { #ifdef PEDANTIC int unlink(char *); int link(char *, char *); #endif const char *the_malloc = 0, *the_wrapper = 0; if (lookup_define("SYSMALLOC")) the_malloc = "sysmalloc.c"; if (lookup_define("SMALLOC")) the_malloc = "smalloc.c"; if (lookup_define("BSDMALLOC")) the_malloc = "bsdmalloc.c"; if (lookup_define("MMALLOC")) the_malloc = "mmalloc.c"; if(lookup_define("MALLOC64")) the_malloc = "64bitmalloc.c"; if(lookup_define("MALLOC32")) the_malloc = "32bitmalloc.c"; if (lookup_define("GNUMALLOC")) the_malloc = "gnumalloc.c"; if (lookup_define("WRAPPEDMALLOC")) the_wrapper = "wrappedmalloc.c"; if (lookup_define("DEBUGMALLOC")) the_wrapper = "debugmalloc.c"; if (!the_malloc && !the_wrapper) { fprintf(stderr, "Memory package and/or malloc wrapper incorrectly specified in options.h\n"); exit(-1); } if (unlink("malloc.c") == -1 && errno != ENOENT) perror("unlink malloc.c"); if (unlink("mallocwrapper.c") == -1 && errno != ENOENT) perror("unlink mallocwrapper.c"); if (the_wrapper) { printf("Using memory allocation package: %s\n\t\tWrapped with: %s\n", the_malloc, the_wrapper); if (link(the_wrapper, "mallocwrapper.c") == -1) perror("link mallocwrapper.c"); } else { printf("Using memory allocation package: %s\n", the_malloc); } if (link(the_malloc, "malloc.c") == -1) perror("link malloc.c"); } static int check_include2 (const char * tag, const char * file, const char * before, const char * after) { char buf[1024]; FILE *ct; printf("Checking for include file <%s> ... ", file); ct = fopen("comptest.c", "w"); fprintf(ct, "#include \"configure.h\"\n#include \"std_incl.h\"\n%s\n#include <%s>\n%s\n", before, file, after); fclose(ct); sprintf(buf, "%s %s -c comptest.c " TO_DEV_NULL, COMPILER, CFLAGS); if (!compile(buf)) { fprintf(yyout, "#define %s\n", tag); /* Make sure the define exists for later checks */ fflush(yyout); printf("exists\n"); return 1; } printf("does not exist or is unusable\n"); return 0; } static int check_include (const char * tag, const char * file) { char buf[1024]; FILE *ct; printf("Checking for include file <%s> ... ", file); ct = fopen("comptest.c", "w"); fprintf(ct, "#include \"configure.h\"\n#include \"std_incl.h\"\n#include \"file_incl.h\"\n#include <%s>\n", file); fclose(ct); sprintf(buf, "%s %s -c comptest.c " TO_DEV_NULL, COMPILER, CFLAGS); if (!compile(buf)) { fprintf(yyout, "#define %s\n", tag); /* Make sure the define exists for later checks */ fflush(yyout); printf("exists\n"); return 1; } printf("does not exist\n"); return 0; } static int check_library (const char * lib) { char buf[1024]; FILE *ct; printf("Checking for library %s ... ", lib); ct = fopen("comptest.c", "w"); fprintf(ct, "int main() { return 0; }\n"); fclose(ct); sprintf(buf, "%s %s comptest.c %s" TO_DEV_NULL, COMPILER, CFLAGS, lib); if (!compile(buf)) { fprintf(yyout, " %s", lib); printf("exists\n"); return 1; } printf("does not exist\n"); return 0; } #if 0 /* not used any more */ static int check_ret_type (char * tag, char * pre, char * type, char * func) { char buf[1024]; FILE *ct; printf("Checking return type of %s() ...", func); ct = fopen("comptest.c", "w"); fprintf(ct, "%s\n\n%s%s();\n", pre, type, func); fclose(ct); sprintf(buf, "%s %s -c comptest.c >/dev/null 2>&1", COMPILER, CFLAGS); if (!system(buf)) { fprintf(yyout, "#define %s\n", tag); printf("returns %s\n", type); return 1; } printf("does not return %s\n", type); return 0; } #endif /* This should check a.out existence, not exit value */ static int check_prog (const char * tag, const char * pre, const char * code, int andrun) { char buf[1024]; FILE *ct; ct = fopen("comptest.c", "w"); fprintf(ct, "#include \"configure.h\"\n#include \"std_incl.h\"\n%s\n\nint main() {%s}\n", (pre ? pre : ""), code); fclose(ct); sprintf(buf, "%s %s comptest.c -o comptest" TO_DEV_NULL, COMPILER, CFLAGS); if (!compile(buf) && (!andrun || !system("./comptest"))) { if (tag) { fprintf(yyout, "#define %s\n", tag); fflush(yyout); } return 1; } return 0; } static int check_code (const char * pre, const char * code) { char buf[1024]; FILE *ct; int rc; ct = fopen("comptest.c", "w"); fprintf(ct, "#include \"configure.h\"\n#include \"std_incl.h\"\n%s\n\nint main() {%s}\n", (pre ? pre : ""), code); fclose(ct); sprintf(buf, "%s %s comptest.c -o comptest" TO_DEV_NULL, COMPILER, CFLAGS); if (compile(buf) || (rc = system("./comptest")) == 127 || rc == -1) { return -1; } return rc; } static void check_linux_libc() { char buf[1024]; FILE *ct; ct = fopen("comptest.c", "w"); fprintf(ct, "int main() { }\n"); fclose(ct); sprintf(buf, "%s -g comptest.c -o comptest >/dev/null 2>&1", COMPILER); if (system(buf)) { fprintf(stderr, " libg.a/so installed wrong, trying workaround ...\n"); sprintf(buf, "%s -g comptest.c -lc -o comptest >/dev/null 2>&1", COMPILER); if (system(buf)) { fprintf(stderr, "*** FAILED.\n"); exit(-1); } fprintf(yyout, " -lc"); } } static const char *memmove_prog = "\ char buf[80];\n\ strcpy(buf,\"0123456789ABCDEF\");\n\ memmove(&buf[1],&buf[4],13);\n\ if(strcmp(buf,\"0456789ABCDEF\")) exit(-1);\n\ memmove(&buf[8],&buf[6],9);\n\ if(strcmp(buf,\"0456789A9ABCDEF\")) exit(-1);\n\ return 0;\n"; static int check_memmove (const char * tag, const char * str) { return check_prog(tag, str, memmove_prog, 1); } static void find_memmove() { printf("Checking for memmove() ..."); if (check_memmove(0, "")) { printf(" exists\n"); return; } if (check_memmove("USE_BCOPY", "#define memmove(a,b,c) bcopy(b,a,c)")) { printf(" simulating via bcopy()\n"); return; } printf(" missing; using MudOS's version\n"); fprintf(yyout, "#define MEMMOVE_MISSING\n"); } static void verbose_check_prog (const char * msg, const char * def, const char * pre, const char * prog, int andrun) { printf("%s ...", msg); if (check_prog(def, pre, prog, andrun)) printf(" exists\n"); else printf(" does not exist\n"); } static int check_configure_version() { char buf[1024]; FILE *ct; ct = fopen("comptest.c", "w"); fprintf(ct, "#include \"configure.h\"\n\n#if CONFIGURE_VERSION < %i\nthrash and die\n#endif\n\nint main() { }\n", CONFIGURE_VERSION); fclose(ct); sprintf(buf, "%s %s comptest.c -o comptest " TO_DEV_NULL, COMPILER, CFLAGS); return !compile(buf); } static void handle_configure() { if (check_configure_version()) return; open_output_file("configure.h"); #ifndef WIN32 check_include("INCL_STDLIB_H", "stdlib.h"); check_include("INCL_UNISTD_H", "unistd.h"); if (check_include("INCL_TIME_H", "time.h")) { if (!check_prog(0, "#include ", "tzset();", 0)) { if (check_prog(0, 0, "void tzset(); tzset();", 0)) fprintf(yyout, "#define PROTO_TZSET\n#define USE_TZSET\n"); } else fprintf(yyout, "#define USE_TZSET\n"); } else { if (check_prog(0, 0, "void tzset(); tzset();", 0)) fprintf(yyout, "#define PROTO_TZSET\n#define USE_TZSET\n"); } check_include("INCL_SYS_TIMES_H", "sys/times.h"); check_include("INCL_FCNTL_H", "fcntl.h"); check_include("INCL_SYS_TIME_H", "sys/time.h"); check_include("INCL_DOS_H", "dos.h"); check_include("INCL_USCLKC_H", "usclkc.h"); check_include("INCL_LIMITS_H", "limits.h"); check_include("INCL_LOCALE_H", "locale.h"); if (!check_prog(0, 0, "int x = USHRT_MAX;", 0)) { if (!check_prog(0, 0, "int x = MAXSHORT;", 0)) check_include("INCL_VALUES_H", "values.h"); fprintf(yyout, "#define USHRT_MAX (MAXSHORT)\n"); } check_include("INCL_NETINET_IN_H", "netinet/in.h"); check_include("INCL_ARPA_INET_H", "arpa/inet.h"); check_include("INCL_SYS_TYPES_H", "sys/types.h"); check_include("INCL_SYS_IOCTL_H", "sys/ioctl.h"); check_include("INCL_SYS_SOCKET_H", "sys/socket.h"); check_include("INCL_NETDB_H", "netdb.h"); /* TELOPT_NAWS is missing from on some systems */ check_include2("INCL_ARPA_TELNET_H", "arpa/telnet.h", "", "int i=TELOPT_NAWS;"); check_include("INCL_SYS_SEMA_H", "sys/sema.h"); check_include("INCL_SYS_SOCKETVAR_H", "sys/socketvar.h"); check_include("INCL_SOCKET_H", "socket.h"); check_include("INCL_RESOLVE_H", "resolve.h"); check_include("INCL_SYS_STAT_H", "sys/stat.h"); /* sys/dir.h is BSD, dirent is sys V. Try to do it the BSD way first. */ /* If that fails, fall back to sys V */ if (check_prog("BSD_READDIR", "#include ", "struct direct *d; d->d_namlen;", 0)) { check_include("INCL_SYS_DIR_H", "sys/dir.h"); } else { /* could be either of these */ check_include("INCL_DIRENT_H", "dirent.h"); check_include("INCL_SYS_DIRENT_H", "sys/dirent.h"); fprintf(yyout, "#define USE_STRUCT_DIRENT\n"); } check_include("INCL_SYS_FILIO_H", "sys/filio.h"); check_include("INCL_SYS_SOCKIO_H", "sys/sockio.h"); check_include("INCL_SYS_MKDEV_H", "sys/mkdev.h"); check_include("INCL_SYS_RESOURCE_H", "sys/resource.h"); check_include("INCL_SYS_RUSAGE_H", "sys/rusage.h"); check_include("INCL_SYS_WAIT_H", "sys/wait.h"); check_include("INCL_SYS_CRYPT_H", "sys/crypt.h"); check_include("INCL_CRYPT_H", "crypt.h"); check_include("INCL_MALLOC_H", "my_malloc.h"); /* for NeXT */ if (!check_include("INCL_MACH_MACH_H", "mach/mach.h")) check_include("INCL_MACH_H", "mach.h"); /* figure out what we need to do to get major()/minor() */ check_include("INCL_SYS_SYSMACROS_H", "sys/sysmacros.h"); #ifdef DEBUG /* includes just to shut up gcc's warnings on some systems */ check_include("INCL_BSTRING_H", "bstring.h"); #endif /* Runtime loading support */ if (check_include("INCL_DLFCN_H", "dlfcn.h")) { if (!check_prog(0, "#include ", "int x = RTLD_LAZY;", 0)) fprintf(yyout, "#define RTLD_LAZY 1\n"); } else { if (!check_prog(0, 0, "int x = RTLD_LAZY;", 0)) fprintf(yyout, "#define RTLD_LAZY 1\n"); } /* SunOS is missing definition for INADDR_NONE */ printf("Checking for missing INADDR_NONE ... "); if (!check_prog(0, "#include ", "int x = INADDR_NONE;", 0)) { printf("missing\n"); fprintf(yyout, "#define INADDR_NONE (unsigned int)0xffffffff\n"); } else printf("ok\n"); printf("Checking for random number generator ..."); if (check_prog("DRAND48", 0, "srand48(0);", 0)) { printf(" using drand48()\n"); } else if (check_prog("RAND", 0, "srand(0);", 0)) { printf(" using rand()\n"); } else if (check_prog("RANDOM", 0, "srandom(0);", 0)) { printf("using random()\n"); } else { printf("WARNING: did not find a random number generator\n"); exit(-1); } if (check_prog("USE_BSD_SIGNALS", 0, "SIGCHLD; wait3(0, 0, 0);", 0)) { printf("Using BSD signals.\n"); } else { printf("Using System V signals.\n"); } printf("Checking if signal() returns SIG_ERR on error ..."); if (check_prog("SIGNAL_ERROR SIG_ERR", 0, "if (signal(0, 0) == SIG_ERR) ;", 0)) { printf(" yes\n"); } else { fprintf(yyout, "#define SIGNAL_ERROR BADSIG\n"); printf(" no\n"); } printf("Not Checking for inline ...(usage in driver code all broken anyway)"); //if (!check_prog("INLINE inline", "inline void foo() { }", "foo();", 0)) { //printf(" __inline ..."); //if (!check_prog("INLINE __inline", "__inline void foo() {}", "foo();", 0)) { fprintf(yyout, "#define INLINE\n"); //} //} printf(" const ...\n"); if (!check_prog("CONST const", "int foo(const int *, const int *);", "", 0)) fprintf(yyout, "#define CONST\n"); verbose_check_prog("Checking for strerror()", "HAS_STRERROR", "", "strerror(12);", 0); verbose_check_prog("Checking for POSIX getcwd()", "HAS_GETCWD", "", "getcwd(\"\", 1000);", 0); verbose_check_prog("Checking for getrusage()", "RUSAGE", "", "getrusage(0, 0);", 0); verbose_check_prog("Checking for times()", "TIMES", "", "times(0);", 0); verbose_check_prog("Checking for gettimeofday()", "HAS_GETTIMEOFDAY", "", "gettimeofday(0, 0);", 0); verbose_check_prog("Checking for fchmod()", "HAS_FCHMOD", "", "fchmod(0, 0);", 0); printf("Checking for big or little endian ... "); if (!check_code("char num[] = { 0x11, 0x22, 0x33, 0x44 }; int *foo = (int *)num;", "return (*foo == 0x44332211);")) { printf("big\n"); fprintf(yyout, "#define BIGENDIAN 1\n"); fflush(yyout); } else printf("little\n"); find_memmove(); #endif fprintf(yyout, "#define SIZEOF_INT %i\n", sizeof(int)); fprintf(yyout, "#define SIZEOF_PTR %i\n", sizeof(char *)); fprintf(yyout, "#define SIZEOF_SHORT %i\n", sizeof(short)); fprintf(yyout, "#define SIZEOF_FLOAT %i\n", sizeof(float)); fprintf(yyout, "#define SIZEOF_LONG %i\n", sizeof(long)); if (sizeof(unsigned long) == 4) fprintf(yyout, "#define UINT32 unsigned long\n"); else if (sizeof(unsigned int) == 4) fprintf(yyout, "#define UINT32 unsigned int\n"); else { printf("WARNING: could not find a 32 bit integral type.\n"); exit(-1); } /* PACKAGE_DB stuff */ if (lookup_define("PACKAGE_DB")) { /* -I would be nicer for added include paths, but we don't have an easy way to * set -I paths right now */ if (lookup_define("USE_MSQL")) { if (!(check_include("INCL_LOCAL_MSQL_H", "/usr/local/include/msql.h") || check_include("INCL_LOCAL_MSQL_MSQL_H", "/usr/local/msql/include/msql.h") || check_include("INCL_LOCAL_MINERVA_MSQL_H", "/usr/local/Minerva/include/msql.h") || check_include("INCL_LIB_HUGHES_MSQL_H", "/usr/lib/Hughes/include/msql.h"))) { fprintf(stderr, "Cannot find msql.h, compilation is going to fail miserably.\n"); } } if (lookup_define("USE_MYSQL")) { if (!(check_include("INCL_LOCAL_MYSQL_H", "/usr/local/include/mysql.h") || check_include("INCL_LOCAL_INCLUDE_MYSQL_MYSQL_H", "/usr/local/include/mysql/mysql.h") || check_include("INCL_LOCAL_MYSQL_MYSQL_H", "/usr/local/mysql/include/mysql.h") || check_include("INCL_MYSQL_MYSQL_H", "/usr/include/mysql/mysql.h") || check_include("INCL_MYSQL_INCLUDE_MYSQL_H", "/usr/mysql/include/mysql/mysql.h"))) { fprintf(stderr, "Cannot find mysql.h, compilation is going to fail miserably.\n"); } } if (lookup_define("USE_POSTGRES")) { if (!(check_include("USE_POSTGRES", "/usr/include/postgresql/libpq-fe.h"))) { fprintf(stderr, "Cannot find libpq-fe.h, compilation is going to fail miserably.\n"); } } } fprintf(yyout, "#define CONFIGURE_VERSION %i\n\n", CONFIGURE_VERSION); close_output_file(); #ifdef WIN32 system("echo Windows detected. Applying libs."); if (lookup_define("HAVE_ZLIB")){ system("echo -lwsock32 -lws2_32 -lz> system_libs"); } else system("echo -lwsock32 -lws2_32 > system_libs"); system("copy windows\\configure.h tmp.config.h"); system("type configure.h >> tmp.config.h"); system("del configure.h"); system("rename tmp.config.h configure.h"); #else open_output_file("system_libs"); check_library("-lresolv"); check_library("-lbsd"); check_library("-lBSD"); check_library("-ly"); /* don't add -lcrypt if crypt() is in libc.a */ if (!check_prog(0, "#include \"lint.h\"", "char *x = crypt(\"foo\", \"bar\");", 0)) check_library("-lcrypt"); /* don't add -lmalloc if malloc() works */ if (!check_prog(0, "", "char *x = malloc(100);", 0)) check_library("-lmalloc"); /* we don't currently use it anywhere if (!check_prog(0, "", "void *x = dlopen(0, 0);", 0)) check_library("-ldl"); */ check_library("-lsocket"); check_library("-linet"); check_library("-lnsl"); check_library("-lnsl_s"); check_library("-lseq"); check_library("-lm"); if (lookup_define("CYGWIN")) check_library("-liconv"); if (lookup_define("MINGW")){ check_library("-lwsock32"); check_library("-lws2_32"); } if (lookup_define("HAVE_ZLIB")) check_library("-lz"); if (lookup_define("PACKAGE_ASYNC")) check_library("-lpthread"); if (lookup_define("PACKAGE_HASH")) check_library("-lssl"); if (lookup_define("PACKAGE_PCRE")) check_library("-lpcre"); fprintf(stderr, "Checking for flaky Linux systems ...\n"); check_linux_libc(); /* PACKAGE_DB stuff */ if (lookup_define("PACKAGE_DB") && lookup_define("USE_MSQL")) { if (!(check_library("-lmsql") || check_library("-L/usr/local/lib -lmsql") || check_library("-L/usr/local/msql/lib -lmsql") || check_library("-L/usr/local/Minerva/lib -lmsql") || check_library("-L/usr/lib/Hughes/lib -lmsql"))) { fprintf(stderr, "Cannot find libmsql.a, compilation is going to fail miserably\n"); } } if (lookup_define("PACKAGE_DB") && lookup_define("USE_MYSQL")) { if (!(check_library("-lmysqlclient") || check_library("-L/usr/local/lib -lmysqlclient") || check_library("-L/usr/local/lib/mysql -lmysqlclient") || check_library("-L/usr/local/mysql/lib -lmysqlclient") || check_library("-L/usr/lib64/mysql -lmysqlclient") || check_library("-L/usr/lib/mysql -lmysqlclient") || check_library("-L/usr/mysql/lib/64/mysql -lmysqlclient"))) { fprintf(stderr, "Cannot find libmysqlclient.a, compilation is going to fail miserably\n"); } } if (lookup_define("PACKAGE_DB") && lookup_define("USE_POSTGRES")) { if (!(check_library("-lpq"))) { fprintf(stderr, "Cannot find libpq.a, compilation is going to fail miserably\n"); } } fprintf(yyout, "\n\n"); close_output_file(); #endif } int main (int argc, char ** argv) { int idx = 1; while (idx < argc) { if (argv[idx][0] != '-') { fprintf(stderr, SYNTAX); exit(-1); } if (strcmp(argv[idx], "-configure")==0) { handle_options(0); handle_configure(); } else if (strcmp(argv[idx], "-process")==0) { handle_process(argv[++idx]); } else if (strcmp(argv[idx], "-options")==0) { handle_options(1); } else if (strcmp(argv[idx], "-malloc")==0) { handle_malloc(); } else if (strcmp(argv[idx], "-build_applies")==0) { handle_applies(); } else if (strcmp(argv[idx], "-build_func_spec")==0) { handle_build_func_spec(argv[++idx]); } else if (strcmp(argv[idx], "-build_efuns")==0) { handle_build_efuns(); } else { fprintf(stderr, "Unrecognized flag %s\n", argv[idx]); exit(-1); } idx++; } printf("\n"); return 0; }