/* @@@HEAD@@@ // */ #define _coldcc_ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include "cdc_string.h" /* strccmp() */ #include "config.h" #include "defs.h" #include "y.tab.h" #include "codegen.h" #include "cdc_types.h" #include "ident.h" #include "match.h" #include "opcodes.h" #include "util.h" #include "sig.h" #include "execute.h" #include "token.h" #include "dump.h" #include "modules.h" #include "db.h" #include "cache.h" #include "object.h" #include "data.h" #include "io.h" #if DISABLED #include <unistd.h> #include <time.h> #endif #define OPT_COMP 0 #define OPT_DECOMP 1 #define OPT_PARSE 2 int c_nowrite = 1; int c_opt = OPT_COMP; /* function prototypes */ internal void initialize(int argc, char **argv); internal void usage(char * name); internal FILE * find_text_db(void); internal void compile_db(void); /* // -------------------------------------------------------------------- */ int main(int argc, char **argv) { initialize(argc, argv); if (c_opt == OPT_DECOMP) { fprintf(stderr, "Decompiling database...\n"); init_binary_db(); text_dump(); } else if (c_opt == OPT_COMP) { fprintf(stderr, "Compiling database...\n"); compile_db(); } else if (c_opt == OPT_PARSE) { fprintf(stderr, "This option is not yet supported, sorry\n"); return 0; } cache_sync(); db_close(); flush_output(); return 0; } /* // -------------------------------------------------------------------- */ internal void compile_db() { FILE * fp; object_t * obj; list_t * parents; data_t * d; init_new_db(); fp = find_text_db(); /* create the root object */ obj = cache_retrieve(ROOT_DBREF); if (!obj) { parents = list_new(0); obj = object_new(ROOT_DBREF, parents); list_discard(parents); } cache_discard(obj); /* create the system object */ obj = cache_retrieve(SYSTEM_DBREF); if (!obj) { parents = list_new(1); d = list_empty_spaces(parents, 1); d->type = DBREF; d->u.dbref = ROOT_DBREF; obj = object_new(SYSTEM_DBREF, parents); list_discard(parents); } cache_discard(obj); fp = fopen(c_dir_textdump, "r"); if (!fp) { fprintf(stderr, "Couldn't open text dump file \"%s\".\n", c_dir_textdump); exit(1); } else { text_dump_read(fp); fclose(fp); } fprintf(stderr, "Database compiled from \"%s\" to \"%s\".\n", c_dir_textdump, c_dir_binary); } /* // -------------------------------------------------------------------- // Finds target the database is, based off input name. // // If name is: // // "stdin", will read from stdin. // a directory, will do directory compilation (unsupported) // a valid file, will use that (textdump) // // Will output to global name "output", set by options */ internal FILE * find_text_db(void) { FILE * fp = NULL; if (strccmp(c_dir_textdump, "stdin") == F_SUCCESS) { fputs("Reading from stdin.\n", stderr); fp = stdin; } else { struct stat sbuf; if (stat(c_dir_textdump, &sbuf) == F_FAILURE) { fprintf(stderr, "** Unable to open target \"%s\".\n", c_dir_textdump); exit(1); } if (S_ISDIR(sbuf.st_mode)) { fputs("** Directory based compilation is currently unsupported.\n", stderr); fclose(fp); exit(0); } /* just let fopen deal with the other perms */ fp = fopen(c_dir_textdump, "r"); if (fp == NULL) { fprintf(stderr, "** bad happened.\n"); exit(1); } fprintf(stderr, "Reading from \"%s\".\n", c_dir_textdump); } return fp; } /* // -------------------------------------------------------------------- // Initializes tables, variables and other aspects for use */ #define nextarg() { \ argv++; \ argc--; \ if (!argc) { \ usage(name); \ fprintf(stderr, "** No followup argument to -%s.\n", opt); \ exit(0); \ } \ } internal void initialize(int argc, char **argv) { char * name = NULL, * opt = NULL; name = *argv; argv++; argc--; while (argc) { if (**argv == '-') { opt = *argv; opt++; switch (*opt) { case 'c': c_opt = OPT_COMP; break; case 'd': c_opt = OPT_DECOMP; break; case 'p': c_opt = OPT_PARSE; fputs("\n** Unsupported option: -p\n", stderr); break; case 'w': fputs("\n** Unsupported option: -w\n", stderr); c_nowrite = 0; break; case 't': nextarg(); strcpy(c_dir_textdump, *argv); break; case 'o': case 'b': nextarg(); strcpy(c_dir_binary, *argv); case '-': case 'h': usage(name); exit(0); default: usage(name); fprintf(stderr, "\n** Invalid Option: -%s\n", opt); exit(1); } } argv++; argc--; } init_codegen(); init_ident(); init_op_table(); init_match(); init_util(); init_sig(); init_execute(); init_scratch_file(); init_token(); init_modules(argc, argv); init_defs(); init_cache(); } /* // -------------------------------------------------------------------- // Simple usage message, rather explanatory */ internal void usage (char * name) { fprintf(stderr, "\n-- %s %d.%d-%d --\n\nUsage: %s <target> [options]\n", SERVER_NAME, VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, name); fputs("\n\ Takes input from <target>. If <target> is \"stdin\" will read from\n\ standard input instead. <target> may be a directory or file.\n\n\ Options:\n\n\ -h This message.\n\ -d Decompile.\n\ -c Compile (default).\n\ -b <binary> binary db directory name, default: \"binary\"\n\ -t <textdump> textdump filename, default: \"textdump\"\n\n\ Anticipated Options:\n\n\ -p Partial compile, compile object(s) and insert\n\ into database accordingly. Can be used with -w\n\ for a ColdC verifier.\n\ -w Compile for parse only, do not write output.\n\ This option can only be used with partial compile.\n\ \n", stderr); } #undef _coldcc_