From 3c462539a6ebef7226385bdd4ca825f242e76319 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Sat, 28 Jul 2012 12:36:20 +0200 Subject: [PATCH] Commandline handling first draft --- gmqcc.h | 46 +++++++++ main.c | 291 +++++++++++++++++++++++++++++--------------------------- 2 files changed, 197 insertions(+), 140 deletions(-) diff --git a/gmqcc.h b/gmqcc.h index 90d1e05..072048d 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -960,4 +960,50 @@ prog_section_def* prog_getdef (qc_program *prog, qcint off); qcany* prog_getedict (qc_program *prog, qcint e); qcint prog_tempstring(qc_program *prog, const char *_str); +/*===================================================================*/ +/*======================= main.c commandline ========================*/ +/*===================================================================*/ + +#if 0 +/* Helpers to allow for a whole lot of flags. Otherwise we'd limit + * to 32 or 64 -f options... + */ +typedef struct { + size_t idx; /* index into an array of 32 bit words */ + uint8_t bit; /* index _into_ the 32 bit word, thus just uint8 */ +} longbit; +#define LONGBIT(bit) { ((bit)/32), ((bit)%32) } +#else +typedef uint32_t longbit; +#define LONGBIT(bit) (bit) +#endif + +/* Used to store the list of flags with names */ +typedef struct { + const char *name; + longbit bit; +} opt_flag_def; + +/*===================================================================*/ +/* list of -f flags, like -fdarkplaces-string-table-bug */ +enum { + DP_STRING_TABLE_BUG, + OMIT_NULLBYTES, + + NUM_F_FLAGS +}; +static const opt_flag_def opt_flag_list[] = { + { "darkplaces-string-table-bug", LONGBIT(DP_STRING_TABLE_BUG) }, + { "omit-nullbytes", LONGBIT(OMIT_NULLBYTES) }, +}; +static const size_t opt_flag_list_count = sizeof(opt_flag_list) / sizeof(opt_flag_list[0]); + +/* other options: */ +extern uint32_t opt_O; /* -Ox */ +extern const char *opt_output; /* -o file */ + +/*===================================================================*/ +#define OPT_FLAG(i) (!! (opt_flags[(i)/32] & (1<< ((i)%32)))) +extern uint32_t opt_flags[1 + (NUM_F_FLAGS / 32)]; + #endif diff --git a/main.c b/main.c index 1ffcd99..60aa8bc 100644 --- a/main.c +++ b/main.c @@ -21,160 +21,171 @@ * SOFTWARE. */ #include "gmqcc.h" -typedef struct { char *name, type; } argitem; -VECTOR_MAKE(argitem, items); - -static int usage(const char *app) { - printf("usage:\n" - " %s -c -oprog.dat -- compile file\n" - " %s -a -oprog.dat -- assemble file\n" - " %s -c -i -oprog.dat -- compile together (allowed multiple -i)\n" - " %s -a -i -oprog.dat -- assemble together(allowed multiple -i)\n" - " example:\n" - " %s -cfoo.qc -ibar.qc -oqc.dat -afoo.qs -ibar.qs -oqs.dat\n", app, app, app, app, app); - - printf(" additional flags:\n" - " -debug -- turns on compiler debug messages\n" - " -memchk -- turns on compiler memory leak check\n" - " -help -- prints this help/usage text\n" - " -std -- select the QuakeC compile type (types below):\n"); - - printf(" -std=qcc -- original QuakeC\n" - " -std=ftqecc -- fteqcc QuakeC\n" - " -std=qccx -- qccx QuakeC\n" - " -std=gmqcc -- this compiler QuakeC (default selection)\n"); - - printf(" codegen flags:\n" - " -fdarkplaces-string-table-bug -- patches the string table to work with bugged versions of darkplaces\n" - " -fomit-nullcode -- omits the generation of null code (will break everywhere see propsal.txt)\n"); + +uint32_t opt_flags[1 + (NUM_F_FLAGS / 32)]; +uint32_t opt_O = 1; +const char *opt_output = "progs.dat"; + +static int usage() { + printf("Usage:\n"); return -1; } -int main(int argc, char **argv) { - size_t itr = 0; - char *app = &argv[0][0]; - FILE *fpp = NULL; - lex_file *lex = NULL; - - /* - * Parse all command line arguments. This is rather annoying to do - * because of all tiny corner cases. - */ - if (argc <= 1 || (argv[1][0] != '-')) - return usage(app); - - while ((argc > 1) && argv[1][0] == '-') { - switch (argv[1][1]) { - case 'v': { - printf("GMQCC:\n" - " version: %d.%d.%d (0x%08X)\n" - " build date: %s\n" - " build time: %s\n", - (GMQCC_VERSION >> 16) & 0xFF, - (GMQCC_VERSION >> 8) & 0xFF, - (GMQCC_VERSION >> 0) & 0xFF, - (GMQCC_VERSION), - __DATE__, - __TIME__ - ); - return 0; - } - #define param_argument(argtype) do { \ - argitem item; \ - if (argv[1][2]) { \ - item.name = util_strdup(&argv[1][2]); \ - item.type = argtype; \ - items_add(item); \ - } else { \ - ++argv; \ - --argc; \ - if (argc <= 1) \ - goto clean_params_usage; \ - item.name = util_strdup(argv[1]); \ - item.type = argtype; \ - items_add(item); \ - } \ - } while (0) - - case 'c': { param_argument(0); break; } /* compile */ - case 'a': { param_argument(1); break; } /* assemble */ - case 'i': { param_argument(2); break; } /* includes */ - #undef parm_argument - default: - if (util_strncmpexact(&argv[1][1], "debug" , 5)) { opts_debug = true; break; } - if (util_strncmpexact(&argv[1][1], "memchk", 6)) { opts_memchk = true; break; } - if (util_strncmpexact(&argv[1][1], "help", 4)) { - return usage(app); - } - /* compiler type selection */ - if (util_strncmpexact(&argv[1][1], "std=qcc" , 7 )) { opts_compiler = COMPILER_QCC; break; } - if (util_strncmpexact(&argv[1][1], "std=fteqcc", 10)) { opts_compiler = COMPILER_FTEQCC; break; } - if (util_strncmpexact(&argv[1][1], "std=qccx", 8 )) { opts_compiler = COMPILER_QCCX; break; } - if (util_strncmpexact(&argv[1][1], "std=gmqcc", 9 )) { opts_compiler = COMPILER_GMQCC; break; } - if (util_strncmpexact(&argv[1][1], "std=", 4 )) { - printf("invalid std selection, supported types:\n" - " -std=qcc -- original QuakeC\n" - " -std=ftqecc -- fteqcc QuakeC\n" - " -std=qccx -- qccx QuakeC\n" - " -std=gmqcc -- this compiler QuakeC (default selection)\n"); - return 0; - } - - /* code specific switches */ - if (util_strncmpexact(&argv[1][1], "fdarkplaces-stringtablebug", 26)) { - opts_darkplaces_stringtablebug = true; +static bool options_setflag(const char *name, bool on) { + size_t i; + + for (i = 0; i < opt_flag_list_count; ++i) { + if (!strcmp(name, opt_flag_list[i].name)) { + longbit lb = opt_flag_list[i].bit; +#if 0 + if (on) + opt_flags[lb.idx] |= (1<<(lb.bit)); + else + opt_flags[lb.idx] &= ~(1<<(lb.bit)); +#else + if (on) + opt_flags[0] |= (1<