/************************************************************************************* ** ** pDirt World/Verb/Spell Generation utility ** ** This program was made came about due to great efforts on the part of Slate ** (George Noel) and some help by Marty (Peter Eussen). Please be so kind to ** give us some credit for this! ** ** Functions provided: ** main - the main procedure for the generate program ** ** *************************************************************************************/ #define GENMAIN_C #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <string.h> #include <strings.h> #include <errno.h> #include <unistd.h> #include "gen.h" #include "semantic.h" #include "codegen.h" #include "config.h" #include "events.h" #ifdef NOSTRSIGNAL_DEV char *strsignal(int sig); #endif void error_trap(int signal); void abort_trap(int signal); void add_zone(zone_record **root, zone_record *addition); void set_signals(); int read_area_listfile(char *fn); void show_usage(char *executable); static hashTable *the_hash; static zone_record *world = NULL; static mudcode_record *mudcode; Boolean supress_warnings = False; /************************************************************************************* ** ** main - the main procedure for the generate function ** ** Parameters: argc - the number of arguments ** argv - the array of arguments ** *************************************************************************************/ int main(int argc, char *argv[]) { int argcount; Boolean in_error = False; Boolean memstat = False; Boolean worldgen = False; Boolean verbgen = False; Boolean spellgen = False; char *arealist = NULL; char *verbfile = NULL; /* Show who made it.. We should be proud of our work ;) */ printf("\033[1;37mpDirt Area Compiler - (c) 1997/1998 George Noel, Peter Eussen ("GEN_VERSION")\033[40m\033[0m\n"); /* Initialise global data structures */ initializeMemStat(); the_hash = createHashTable(HASHTABLESIZE); if (read_configuration("../compiler/mudc.config") < 0) { return 1; } arealist = request_char_value("AREALIST"); verbfile = request_char_value("VERBFILE"); /* Check Parameters */ if (argc == 1) { show_usage(argv[0]); return 0; } if (request_char_value("AREAS_DIR") != NULL) { if (chdir(request_char_value("AREAS_DIR")) < 0) { perror("Unable to switch to areas directory"); return 1; } } mudcode = load_mudcode(); if (mudcode == NULL) return 1; if (load_events(request_char_value("EVENTS_LIBRARY")) < 0) { return 1; } set_signals(); /*printf("%ld memory used by global data structures.\n",mem_usage);*/ for (argcount = 1; argcount < argc && !in_error; argcount++) { if (strncasecmp(argv[argcount],"-world",strlen(argv[argcount])) == 0) worldgen = True; else if (strncasecmp(argv[argcount],"-verbs",strlen(argv[argcount])) == 0) verbgen = True; else if (strncasecmp(argv[argcount],"-spells",strlen(argv[argcount])) == 0) spellgen = True; else if (strncasecmp(argv[argcount],"-memstat",strlen(argv[argcount])) == 0) memstat = True; else if (strncasecmp(argv[argcount],"-help",strlen(argv[argcount])) == 0) { show_usage(argv[0]); return 0; } else if (strncasecmp(argv[argcount],"-file",strlen(argv[argcount])) == 0) { zone_record *zon; if (++argcount >= argc) { printf("Missing zone file name.\n"); return 1; } printf(" [F] Checking file %s\n",argv[argcount]); zon = get_zone(argv[argcount],the_hash,mudcode); if (zon != NULL) { if (!semantic_check(the_hash,zon)) { printf(" File didnt pass semantic checking.\n"); return 0; } printf(" Done, file passed semantic checking.\n"); return 0; } else printf(" The file didnt pass the first phase.\n"); return 0; } else if (strncasecmp(argv[argcount],"-ignore",strlen(argv[argcount])) == 0) supress_warnings = True; else { show_usage(argv[0]); return 1; } } /* Read Process */ if (worldgen && arealist != NULL) { printf(" [W] Starting World Generation...\n"); if (read_area_listfile(arealist) == 0) { printf("\n Checking semantics of the zones.\n"); /* semantically check zone data trees */ if (!(semantic_check(the_hash,world))) { printf("Error in semantic check, no code will be generated.\n"); return 1; } else { printf(" Generating Database, Include and Code files.\n"); if (gen_code(the_hash, world) == -1) { printf("Eek! Unexpected error generating code. Code may be corrupted.\n"); return 1; } } } printf("\n"); } if (verbgen) { /* Verb generation */ printf(" [V] Starting Verbs generation..."); if (verbfile == NULL) { printf("Verb file not defined in configuration file.\n"); return 1; } if (generate_verb_files(verbfile,request_char_value("DATA_DIR")) < 0) in_error = True; } if (spellgen) { /* get spell data and generate code */ printf(" [S] Starting Spell Table generation..."); printf("Done.\n"); } /* generate spell code */ if (in_error) printf("Error occured during the read process, aborting compilation.\n"); /* cleanup */ if (memstat) { printMemStat(); printHashTableStatistics(the_hash); } deleteHashTable(the_hash); printf("\nDone.\n"); return 0; } void show_usage(char *executable) { printf("\nUsage: %s [-world] [-verbs] [-spells] [-memstat] [-file <filename>]\n\n" " -world : Generate new world database & code files.\n" " -verbs : Generate new verbs file and include file.\n" " -spells : Generate a new spell table file.\n" " -memstat: Create a memory statistic overview.\n" " -file : Do a check of the specified file only.\n" " -ignore : Ignore semantic check warnings.\n", executable); } void set_signals() { signal(SIGSEGV,error_trap); signal(SIGPIPE,error_trap); signal(SIGFPE,error_trap); signal(SIGBUS,error_trap); signal(SIGILL,error_trap); signal(SIGTERM,abort_trap); signal(SIGINT,abort_trap); signal(SIGABRT,abort_trap); signal(SIGTRAP,SIG_DFL); signal(SIGCHLD,SIG_IGN); } void error_trap(int sig) { extern int theline; extern char thezonenam[MAXNAMLEN]; printf("\n\bAn unrecoverable error occured while compiling, causing the following error\n" "to occur: the compiler received the signal[%d] - %s\n",sig,(char *)strsignal(sig)); printf("\n\nDumping debugging information.\n" "Zone file name : %s\n" "Zone file line number : %d\n\n" "Current Location number: %d\n" "Current Mobile number : %d\n" "Current Object number : %d\n\n" "Total Memory usage : %ld\n", thezonenam,theline,cur_loc,cur_mob,cur_obj,mem_usage); exit(sig); } void abort_trap(int sig) { printf("\nCompiler aborted by user (signal[%d]: %s).\n",sig,(char *)strsignal(sig)); exit(sig); } void add_zone(zone_record **root, zone_record *addition) { if (*root == NULL) { *root = addition; addition->next_zone = NULL; } else { zone_record *tmp_ptr = *root; while (tmp_ptr->next_zone != NULL) tmp_ptr = tmp_ptr->next_zone; tmp_ptr->next_zone = addition; addition->next_zone = NULL; } } int read_area_listfile(char *fn) { char argbuffer[120],*p; FILE *fp; Boolean in_error = False; zone_record *the_zone = NULL; if ((fp = fopen(fn,"r")) == NULL) { printf("Unable to open listfile %s\n",fn); return -1; } printf(" Reading zones from file: %s\n",fn); fgets(argbuffer,100,fp); while (!feof(fp) && !in_error) { if ((p = strstr(argbuffer,fn_extension)) != NULL) *p = '\0'; printf("\r Reading zone %-16.16s",argbuffer); fflush(stdout); the_zone = get_zone(argbuffer, the_hash, mudcode); if (the_zone != NULL) { add_zone(&world,the_zone); num_zones++; } else { printf("Nothing found for this zone, or error(s) occured while reading.\n"); in_error = True; } fgets(argbuffer,100,fp); } fclose(fp); if (in_error) printf("\nError(s) occured during reading.\n"); return in_error ? -1 : 0; }