Work in progress options cleanup.
authorDale Weiler <killfieldengine@gmail.com>
Wed, 30 Jan 2013 05:24:30 +0000 (05:24 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Wed, 30 Jan 2013 05:24:30 +0000 (05:24 +0000)
12 files changed:
ast.c
code.c
ftepp.c
gmqcc.h
ir.c
lexer.c
main.c
opts.c
opts.def
parser.c
test.c
util.c

diff --git a/ast.c b/ast.c
index 108489f..41eadfa 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1124,8 +1124,12 @@ const char* ast_function_label(ast_function *self, const char *prefix)
     size_t len;
     char  *from;
 
-    if (!opts.dump && !opts.dumpfin && !opts.debug)
+    if (!OPTION_VALUE_BOOL(OPTION_DUMP)    &&
+        !OPTION_VALUE_BOOL(OPTION_DUMPFIN) &&
+        !OPTION_VALUE_BOOL(OPTION_DEBUG))
+    {
         return NULL;
+    }
 
     id  = (self->labelcount++);
     len = strlen(prefix);
@@ -1231,7 +1235,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
             }
 
             /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
-            if (!array->expression.count || array->expression.count > opts.max_array_size)
+            if (!array->expression.count || array->expression.count > OPTION_VALUE_U32(OPTION_MAX_ARRAY_SIZE))
                 compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->expression.count);
 
             elemtype = &array->expression.next->expression;
@@ -1293,7 +1297,7 @@ bool ast_global_codegen(ast_value *self, ir_builder *ir, bool isfield)
         int vtype = elemtype->vtype;
 
         /* same as with field arrays */
-        if (!self->expression.count || self->expression.count > opts.max_array_size)
+        if (!self->expression.count || self->expression.count > OPTION_VALUE_U32(OPTION_MAX_ARRAY_SIZE))
             compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
 
         v = ir_builder_create_global(ir, self->name, vtype);
@@ -1430,7 +1434,7 @@ bool ast_local_codegen(ast_value *self, ir_function *func, bool param)
         }
 
         /* we are lame now - considering the way QC works we won't tolerate arrays > 1024 elements */
-        if (!self->expression.count || self->expression.count > opts.max_array_size) {
+        if (!self->expression.count || self->expression.count > OPTION_VALUE_U32(OPTION_MAX_ARRAY_SIZE)) {
             compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
         }
 
@@ -1702,7 +1706,7 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu
     for (i = 0; i < vec_size(self->locals); ++i)
     {
         if (!ast_local_codegen(self->locals[i], func->ir_func, false)) {
-            if (opts.debug)
+            if (OPTION_VALUE_BOOL(OPTION_DEBUG))
                 compile_error(ast_ctx(self), "failed to generate local `%s`", self->locals[i]->name);
             return false;
         }
diff --git a/code.c b/code.c
index 713d98d..e480ed2 100644 (file)
--- a/code.c
+++ b/code.c
@@ -137,8 +137,8 @@ bool code_write(const char *filename, const char *lnofile) {
     code_header.strings.offset    = code_header.globals.offset    + (sizeof(int32_t)                * vec_size(code_globals));
     code_header.strings.length    = vec_size(code_chars);
     code_header.version           = 6;
-    if (opts.forcecrc)
-        code_header.crc16         = opts.forced_crc;
+    if (OPTION_VALUE_BOOL(OPTION_FORCECRC))
+        code_header.crc16         = OPTION_VALUE_U16(OPTION_FORCED_CRC);
     else
         code_header.crc16         = code_crc;
     code_header.entfield          = code_entfields;
diff --git a/ftepp.c b/ftepp.c
index 11b4465..04d64e7 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -1011,7 +1011,7 @@ static bool ftepp_if_value(ftepp_t *ftepp, bool *out, double *value_out)
 
         default:
             ftepp_error(ftepp, "junk in #if: `%s` ...", ftepp_tokval(ftepp));
-            if (opts.debug)
+            if (OPTION_VALUE_BOOL(OPTION_DEBUG))
                 ftepp_error(ftepp, "internal: token %i\n", ftepp->token);
             return false;
     }
@@ -1670,7 +1670,7 @@ bool ftepp_init()
 
     /* set the right macro based on the selected standard */
     ftepp_add_define(NULL, "GMQCC");
-    if (opts.standard == COMPILER_FTEQCC) {
+    if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_FTEQCC) {
         ftepp_add_define(NULL, "__STD_FTEQCC__");
         /* 1.00 */
         major[0] = '"';
@@ -1680,15 +1680,15 @@ bool ftepp_init()
         minor[0] = '"';
         minor[1] = '0';
         minor[2] = '"';
-    } else if (opts.standard == COMPILER_GMQCC) {
+    } else if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
         ftepp_add_define(NULL, "__STD_GMQCC__");
         sprintf(major, "\"%d\"", GMQCC_VERSION_MAJOR);
         sprintf(minor, "\"%d\"", GMQCC_VERSION_MINOR);
-    } else if (opts.standard == COMPILER_QCCX) {
+    } else if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCCX) {
         ftepp_add_define(NULL, "__STD_QCCX__");
         sprintf(major, "\"%d\"", GMQCC_VERSION_MAJOR);
         sprintf(minor, "\"%d\"", GMQCC_VERSION_MINOR);
-    } else if (opts.standard == COMPILER_QCC) {
+    } else if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC) {
         ftepp_add_define(NULL, "__STD_QCC__");
         /* 1.0 */
         major[0] = '"';
diff --git a/gmqcc.h b/gmqcc.h
index 515ce2d..fed9b31 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -1124,6 +1124,20 @@ static const unsigned int opts_opt_oflag[] = {
 #  include "opts.def"
     0
 };
+
+enum {
+#   define GMQCC_TYPE_OPTIONS
+#   define GMQCC_DEFINE_FLAG(X, Y) OPTION_##X,
+#   include "opts.def"
+    OPTION_COUNT
+};
+static const char *opts_options_descriptions[OPTION_COUNT + 1] = {
+#   define GMQCC_TYPE_OPTIONS
+#   define GMQCC_DEFINE_FLAG(X, Y) Y,
+#   include "opts.def"
+    ""
+};
+
 extern unsigned int opts_optimizationcount[COUNT_OPTIMIZATIONS];
 
 /* other options: */
@@ -1134,30 +1148,33 @@ typedef enum {
     COMPILER_GMQCC    /* this   QuakeC */
 } opts_std_t;
 
-/* TODO: cleanup this */
+typedef enum {
+    OPT_TYPE_BOOL,
+    OPT_TYPE_U16,
+    OPT_TYPE_U32,
+    OPT_TYPE_STR
+} opt_type_t;
+
+typedef union {
+    bool     B;
+    uint16_t U16;
+    uint32_t U32;
+    char    *STR;
+} opt_value_t;
+
+
+#define OPTION_VALUE_BOOL(X) (opts.options[X].B)
+#define OPTION_VALUE_U16(X)  (opts.options[X].U16)
+#define OPTION_VALUE_U32(X)  (opts.options[X].U32)
+#define OPTION_VALUE_STR(X)  (opts.options[X].STR)
 typedef struct {
-    uint32_t    O;              /* -Ox           */
-    const char *output;         /* -o file       */
-    bool        quiet;          /* -q --quiet    */
-    bool        g;              /* -g            */
-    opts_std_t  standard;       /* -std=         */
-    bool        debug;          /* -debug        */
-    bool        memchk;         /* -memchk       */
-    bool        dumpfin;        /* -dumpfin      */
-    bool        dump;           /* -dump         */
-    bool        forcecrc;       /* --force-crc=  */
-    uint16_t    forced_crc;     /* --force-crc=  */
-    bool        pp_only;        /* -E            */
-    size_t      max_array_size; /* --max-array=  */
-    bool        add_info;       /* --add-info    */
-    bool        correction;     /* --correct     */
-
-    uint32_t flags        [1 + (COUNT_FLAGS         / 32)];
-    uint32_t warn         [1 + (COUNT_WARNINGS      / 32)];
-    uint32_t werror       [1 + (COUNT_WARNINGS      / 32)];
-    uint32_t warn_backup  [1 + (COUNT_WARNINGS      / 32)];
-    uint32_t werror_backup[1 + (COUNT_WARNINGS      / 32)];
-    uint32_t optimization [1 + (COUNT_OPTIMIZATIONS / 32)];
+    opt_value_t  options      [OPTION_COUNT];
+    uint32_t     flags        [1 + (COUNT_FLAGS         / 32)];
+    uint32_t     warn         [1 + (COUNT_WARNINGS      / 32)];
+    uint32_t     werror       [1 + (COUNT_WARNINGS      / 32)];
+    uint32_t     warn_backup  [1 + (COUNT_WARNINGS      / 32)];
+    uint32_t     werror_backup[1 + (COUNT_WARNINGS      / 32)];
+    uint32_t     optimization [1 + (COUNT_OPTIMIZATIONS / 32)];
 } opts_cmd_t;
 
 extern opts_cmd_t opts;
diff --git a/ir.c b/ir.c
index ad86914..0f437aa 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -3228,9 +3228,12 @@ static bool gen_function_locals(ir_builder *ir, ir_value *global)
     irfun = global->constval.vfunc;
     def   = code_functions + irfun->code_function_def;
 
-    if (opts.g || !OPTS_OPTIMIZATION(OPTIM_OVERLAP_LOCALS) || (irfun->flags & IR_FLAG_MASK_NO_OVERLAP))
+    if (OPTION_VALUE_BOOL(OPTION_G) ||
+        !OPTS_OPTIMIZATION(OPTIM_OVERLAP_LOCALS)        ||
+        (irfun->flags & IR_FLAG_MASK_NO_OVERLAP))
+    {
         firstlocal = def->firstlocal = vec_size(code_globals);
-    else {
+    else {
         firstlocal = def->firstlocal = ir->first_common_local;
         ++opts_optimizationcount[OPTIM_OVERLAP_LOCALS];
     }
@@ -3376,7 +3379,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
     def.type   = global->vtype;
     def.offset = vec_size(code_globals);
     def.name   = 0;
-    if (opts.g || !islocal)
+    if (OPTION_VALUE_BOOL(OPTION_G) || !islocal)
     {
         pushdef = true;
 
@@ -3552,7 +3555,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
     def.offset = (uint16_t)vec_size(code_globals);
 
     /* create a global named the same as the field */
-    if (opts.standard == COMPILER_GMQCC) {
+    if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
         /* in our standard, the global gets a dot prefix */
         size_t len = strlen(field->name);
         char name[1024];
@@ -3690,7 +3693,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
         code_push_statement(&stmt, vec_last(code_linenums));
     }
 
-    if (opts.pp_only)
+    if (OPTION_VALUE_BOOL(OPTION_PP_ONLY))
         return true;
 
     if (vec_size(code_statements) != vec_size(code_linenums)) {
@@ -3711,7 +3714,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
         memcpy(vec_add(lnofile, 5), ".lno", 5);
     }
 
-    if (!opts.quiet) {
+    if (!OPTION_VALUE_BOOL(OPTION_QUIET)) {
         if (lnofile)
             con_out("writing '%s' and '%s'...\n", filename, lnofile);
         else
diff --git a/lexer.c b/lexer.c
index 3781496..c8001d6 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -1387,7 +1387,7 @@ int lex_do(lex_file *lex)
                 if (!strcmp(v, keywords_qc[kw]))
                     return (lex->tok.ttype = TOKEN_KEYWORD);
             }
-            if (opts.standard != COMPILER_QCC) {
+            if (OPTION_VALUE_U32(OPTION_STANDARD) != COMPILER_QCC) {
                 for (kw = 0; kw < num_keywords_fg; ++kw) {
                     if (!strcmp(v, keywords_fg[kw]))
                         return (lex->tok.ttype = TOKEN_KEYWORD);
diff --git a/main.c b/main.c
index f6d9b31..5849b53 100644 (file)
--- a/main.c
+++ b/main.c
@@ -172,13 +172,16 @@ static bool options_parse(int argc, char **argv) {
                     opts_set(opts.flags, INITIALIZED_NONCONSTANTS,      true);
                     opts_set(opts.werror, WARN_INVALID_PARAMETER_COUNT, true);
                     opts_set(opts.werror, WARN_MISSING_RETURN_VALUES,   true);
-                    opts.standard = COMPILER_GMQCC;
+
+
+                    OPTION_VALUE_U32(OPTION_STANDARD) = COMPILER_GMQCC;
 
                 } else if (!strcmp(argarg, "qcc")) {
 
                     opts_set(opts.flags, ADJUST_VECTOR_FIELDS,  false);
                     opts_set(opts.flags, ASSIGN_FUNCTION_TYPES, true);
-                    opts.standard = COMPILER_QCC;
+
+                    OPTION_VALUE_U32(OPTION_STANDARD) = COMPILER_QCC;
 
                 } else if (!strcmp(argarg, "fte") || !strcmp(argarg, "fteqcc")) {
 
@@ -188,12 +191,13 @@ static bool options_parse(int argc, char **argv) {
                     opts_set(opts.flags, ASSIGN_FUNCTION_TYPES,    true);
                     opts_set(opts.flags, CORRECT_TERNARY,          false);
                     opts_set(opts.warn, WARN_TERNARY_PRECEDENCE,   true);
-                    opts.standard = COMPILER_FTEQCC;
+
+                    OPTION_VALUE_U32(OPTION_STANDARD) = COMPILER_FTEQCC;
 
                 } else if (!strcmp(argarg, "qccx")) {
 
                     opts_set(opts.flags, ADJUST_VECTOR_FIELDS,  false);
-                    opts.standard = COMPILER_QCCX;
+                    OPTION_VALUE_U32(OPTION_STANDARD) = COMPILER_QCCX;
 
                 } else {
                     con_out("Unknown standard: %s\n", argarg);
@@ -202,8 +206,9 @@ static bool options_parse(int argc, char **argv) {
                 continue;
             }
             if (options_long_gcc("force-crc", &argc, &argv, &argarg)) {
-                opts.forcecrc   = true;
-                opts.forced_crc = strtol(argarg, NULL, 0);
+
+                OPTION_VALUE_BOOL(OPTION_FORCECRC)   = true;
+                OPTION_VALUE_U16 (OPTION_FORCED_CRC) = strtol(argarg, NULL, 0);
                 continue;
             }
             if (options_long_gcc("redirout", &argc, &argv, &redirout)) {
@@ -243,19 +248,19 @@ static bool options_parse(int argc, char **argv) {
             }
 
             if (!strcmp(argv[0]+1, "debug")) {
-                opts.debug = true;
+                OPTION_VALUE_BOOL(OPTION_DEBUG) = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "dump")) {
-                opts.dump = true;
+                OPTION_VALUE_BOOL(OPTION_DUMP)  = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "dumpfin")) {
-                opts.dumpfin = true;
+                OPTION_VALUE_BOOL(OPTION_DUMPFIN) = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "memchk")) {
-                opts.memchk = true;
+                OPTION_VALUE_BOOL(OPTION_MEMCHK) = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "nocolor")) {
@@ -275,18 +280,18 @@ static bool options_parse(int argc, char **argv) {
                     exit(0);
 
                 case 'E':
-                    opts.pp_only = true;
+                    OPTION_VALUE_BOOL(OPTION_PP_ONLY) = true;
                     opts_set(opts.flags, FTEPP_PREDEFS, true); /* predefs on for -E */
                     break;
 
                 /* debug turns on -flno */
                 case 'g':
                     opts_setflag("LNO", true);
-                    opts.g = true;
+                    OPTION_VALUE_BOOL(OPTION_G) = true;
                     break;
 
                 case 'q':
-                    opts.quiet = true;
+                    OPTION_VALUE_BOOL(OPTION_QUIET) = true;
                     break;
 
                 case 'D':
@@ -396,8 +401,9 @@ static bool options_parse(int argc, char **argv) {
                         return false;
                     }
                     if (isdigit(argarg[0])) {
-                        opts.O = atoi(argarg);
-                        opts_setoptimlevel(opts.O);
+                        uint32_t val = atoi(argarg);
+                        OPTION_VALUE_U32(OPTION_O) = val;
+                        opts_setoptimlevel(val);
                     } else {
                         util_strtocmd(argarg, argarg, strlen(argarg)+1);
                         if (!strcmp(argarg, "HELP")) {
@@ -409,7 +415,7 @@ static bool options_parse(int argc, char **argv) {
                             exit(0);
                         }
                         else if (!strcmp(argarg, "ALL"))
-                            opts_setoptimlevel(opts.O = 9999);
+                            opts_setoptimlevel(OPTION_VALUE_U32(OPTION_O) = 9999);
                         else if (!strncmp(argarg, "NO_", 3)) {
                             if (!opts_setoptim(argarg+3, false)) {
                                 con_out("unknown optimization: %s\n", argarg+3);
@@ -430,7 +436,7 @@ static bool options_parse(int argc, char **argv) {
                         con_out("option -o requires an argument: the output file name\n");
                         return false;
                     }
-                    opts.output = argarg;
+                    OPTION_VALUE_STR(OPTION_OUTPUT) = argarg;
                     opts_output_wasset = true;
                     break;
 
@@ -462,25 +468,25 @@ static bool options_parse(int argc, char **argv) {
                         exit(0);
                     }
                     else if (!strcmp(argv[0]+2, "quiet")) {
-                        opts.quiet = true;
+                        OPTION_VALUE_BOOL(OPTION_QUIET) = true;
                         break;
                     }
                     else if (!strcmp(argv[0]+2, "correct")) {
-                        opts.correction = true;
+                        OPTION_VALUE_BOOL(OPTION_CORRECTION) = true;
                         break;
                     }
                     else if (!strcmp(argv[0]+2, "no-correct")) {
-                        opts.correction = false;
+                        OPTION_VALUE_BOOL(OPTION_CORRECTION) = false;
                         break;
                     }
                     else if (!strcmp(argv[0]+2, "add-info")) {
-                        opts.add_info = true;
+                        OPTION_VALUE_BOOL(OPTION_ADD_INFO) = true;
                         break;
                     }
                     else {
             /* All long options with arguments */
                         if (options_long_witharg("output", &argc, &argv, &argarg)) {
-                            opts.output = argarg;
+                            OPTION_VALUE_STR(OPTION_OUTPUT) = argarg;
                             opts_output_wasset = true;
                         } else {
                             con_out("Unknown parameter: %s\n", argv[0]);
@@ -556,10 +562,10 @@ int main(int argc, char **argv) {
     }
 
     /* the standard decides which set of operators to use */
-    if (opts.standard == COMPILER_GMQCC) {
+    if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
         operators      = c_operators;
         operator_count = c_operator_count;
-    } else if (opts.standard == COMPILER_FTEQCC) {
+    } else if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_FTEQCC) {
         operators      = fte_operators;
         operator_count = fte_operator_count;
     } else {
@@ -587,22 +593,22 @@ int main(int argc, char **argv) {
         }
     }
 
-    if (opts.dump) {
+    if (OPTION_VALUE_BOOL(OPTION_DUMP)) {
         for (itr = 0; itr < COUNT_FLAGS; ++itr)
             con_out("Flag %s = %i\n",    opts_flag_list[itr].name, OPTS_FLAG(itr));
         for (itr = 0; itr < COUNT_WARNINGS; ++itr)
             con_out("Warning %s = %i\n", opts_warn_list[itr].name, OPTS_WARN(itr));
 
-        con_out("output             = %s\n", opts.output);
-        con_out("optimization level = %d\n", opts.O);
-        con_out("standard           = %i\n", opts.standard);
+        con_out("output             = %s\n", OPTION_VALUE_STR(OPTION_OUTPUT));
+        con_out("optimization level = %u\n", OPTION_VALUE_U32(OPTION_O));
+        con_out("standard           = %u\n", OPTION_VALUE_U32(OPTION_STANDARD));
     }
 
-    if (opts.pp_only) {
+    if (OPTION_VALUE_BOOL(OPTION_PP_ONLY)) {
         if (opts_output_wasset) {
-            outfile = file_open(opts.output, "wb");
+            outfile = file_open(OPTION_VALUE_STR(OPTION_OUTPUT), "wb");
             if (!outfile) {
-                con_err("failed to open `%s` for writing\n", opts.output);
+                con_err("failed to open `%s` for writing\n", OPTION_VALUE_STR(OPTION_OUTPUT));
                 retval = 1;
                 goto cleanup;
             }
@@ -612,7 +618,7 @@ int main(int argc, char **argv) {
         }
     }
 
-    if (!opts.pp_only) {
+    if (!OPTION_VALUE_BOOL(OPTION_PP_ONLY)) {
         if (!parser_init()) {
             con_err("failed to initialize parser\n");
             retval = 1;
@@ -620,7 +626,7 @@ int main(int argc, char **argv) {
         }
     }
 
-    if (opts.pp_only || OPTS_FLAG(FTEPP)) {
+    if (OPTION_VALUE_BOOL(OPTION_PP_ONLY) || OPTS_FLAG(FTEPP)) {
         if (!ftepp_init()) {
             con_err("failed to initialize parser\n");
             retval = 1;
@@ -634,7 +640,7 @@ int main(int argc, char **argv) {
     util_debug("COM", "starting ...\n");
 
     /* add macros */
-    if (opts.pp_only || OPTS_FLAG(FTEPP)) {
+    if (OPTION_VALUE_BOOL(OPTION_PP_ONLY) || OPTS_FLAG(FTEPP)) {
         for (itr = 0; itr < vec_size(ppems); itr++) {
             ftepp_add_macro(ppems[itr].name, ppems[itr].value);
             mem_d(ppems[itr].name);
@@ -667,7 +673,7 @@ int main(int argc, char **argv) {
         }
 
         if (!opts_output_wasset) {
-            opts.output = util_strdup(line);
+            OPTION_VALUE_STR(OPTION_OUTPUT) = util_strdup(line);
             opts_output_free = true;
         }
 
@@ -689,12 +695,16 @@ srcdone:
         goto cleanup;
 
     if (vec_size(items)) {
-        if (!opts.quiet && !opts.pp_only) {
+        if (!OPTION_VALUE_BOOL(OPTION_QUIET) &&
+            !OPTION_VALUE_BOOL(OPTION_PP_ONLY))
+        {
             con_out("Mode: %s\n", (progs_src ? "progs.src" : "manual"));
             con_out("There are %lu items to compile:\n", (unsigned long)vec_size(items));
         }
         for (itr = 0; itr < vec_size(items); ++itr) {
-            if (!opts.quiet && !opts.pp_only) {
+            if (!OPTION_VALUE_BOOL(OPTION_QUIET) &&
+                !OPTION_VALUE_BOOL(OPTION_PP_ONLY))
+            {
                 con_out("  item: %s (%s)\n",
                        items[itr].filename,
                        ( (items[itr].type == TYPE_QC ? "qc" :
@@ -703,7 +713,7 @@ srcdone:
                          ("unknown"))))));
             }
 
-            if (opts.pp_only) {
+            if (OPTION_VALUE_BOOL(OPTION_PP_ONLY)) {
                 const char *out;
                 if (!ftepp_preprocess_file(items[itr].filename)) {
                     retval = 1;
@@ -745,8 +755,8 @@ srcdone:
         }
 
         ftepp_finish();
-        if (!opts.pp_only) {
-            if (!parser_finish(opts.output)) {
+        if (!OPTION_VALUE_BOOL(OPTION_PP_ONLY)) {
+            if (!parser_finish(OPTION_VALUE_STR(OPTION_OUTPUT))) {
                 retval = 1;
                 goto cleanup;
             }
@@ -754,7 +764,9 @@ srcdone:
     }
 
     /* stuff */
-    if (!opts.quiet && !opts.pp_only) {
+    if (!OPTION_VALUE_BOOL(OPTION_QUIET) &&
+        !OPTION_VALUE_BOOL(OPTION_PP_ONLY))
+    {
         for (itr = 0; itr < COUNT_OPTIMIZATIONS; ++itr) {
             if (opts_optimizationcount[itr]) {
                 con_out("%s: %u\n", opts_opt_list[itr].name, (unsigned int)opts_optimizationcount[itr]);
@@ -769,10 +781,10 @@ cleanup:
     vec_free(items);
     vec_free(ppems);
 
-    if (!opts.pp_only)
+    if (!OPTION_VALUE_BOOL(OPTION_PP_ONLY))
         parser_cleanup();
     if (opts_output_free)
-        mem_d((char*)opts.output);
+        mem_d(OPTION_VALUE_STR(OPTION_OUTPUT));
     if (operators_free)
         mem_d((void*)operators);
 
diff --git a/opts.c b/opts.c
index f0dc326..5ea4f6e 100644 (file)
--- a/opts.c
+++ b/opts.c
@@ -27,7 +27,7 @@ opts_cmd_t   opts; /* command lien options */
 
 static void opts_setdefault() {
     memset(&opts, 0, sizeof(opts_cmd_t));
-    opts.correction = true;
+    OPTION_VALUE_BOOL(OPTION_CORRECTION) = true;
 
     /* warnings */
     opts_set(opts.warn,  WARN_UNUSED_VARIABLE,           true);
@@ -37,7 +37,6 @@ static void opts_setdefault() {
     opts_set(opts.warn,  WARN_FIELD_REDECLARED,          true);
     opts_set(opts.warn,  WARN_MISSING_RETURN_VALUES,     true);
     opts_set(opts.warn,  WARN_INVALID_PARAMETER_COUNT,   true);
-    opts_set(opts.warn,  WARN_LOCAL_SHADOWS,             false);
     opts_set(opts.warn,  WARN_LOCAL_CONSTANTS,           true);
     opts_set(opts.warn,  WARN_VOID_VARIABLES,            true);
     opts_set(opts.warn,  WARN_IMPLICIT_FUNCTION_POINTER, true);
@@ -56,13 +55,11 @@ static void opts_setdefault() {
     opts_set(opts.warn,  WARN_UNKNOWN_ATTRIBUTE,         true);
     opts_set(opts.warn,  WARN_RESERVED_NAMES,            true);
     opts_set(opts.warn,  WARN_UNINITIALIZED_CONSTANT,    true);
-    opts_set(opts.warn,  WARN_UNINITIALIZED_GLOBAL,      false);
     opts_set(opts.warn,  WARN_DEPRECATED,                true);
     opts_set(opts.warn,  WARN_PARENTHESIS,               true);
+
     /* flags */
     opts_set(opts.flags, ADJUST_VECTOR_FIELDS,           true);
-    opts_set(opts.flags, FTEPP,                          false);
-    opts_set(opts.flags, FTEPP_PREDEFS,                  false);
     opts_set(opts.flags, CORRECT_TERNARY,                true);
     opts_set(opts.flags, BAIL_ON_WERROR,                 true);
     opts_set(opts.flags, LEGACY_VECTOR_MATHS,            true);
@@ -95,9 +92,9 @@ void opts_restore_non_Werror_all() {
 void opts_init(const char *output, int standard, size_t arraysize) {
     opts_setdefault();
 
-    opts.output         = output;
-    opts.standard       = (opts_std_t)standard; /* C++ ... y u no like me? */
-    opts.max_array_size = arraysize;
+    OPTION_VALUE_STR(OPTION_OUTPUT)         = (char*)output;
+    OPTION_VALUE_U32(OPTION_STANDARD)       = standard;
+    OPTION_VALUE_U32(OPTION_MAX_ARRAY_SIZE) = arraysize;
 }
 
 static bool opts_setflag_all(const char *name, bool on, uint32_t *flags, const opts_flag_def *list, size_t listsize) {
@@ -106,17 +103,12 @@ static bool opts_setflag_all(const char *name, bool on, uint32_t *flags, const o
     for (i = 0; i < listsize; ++i) {
         if (!strcmp(name, list[i].name)) {
             longbit lb = list[i].bit;
-#if 1
+
             if (on)
                 flags[lb.idx] |= (1<<(lb.bit));
             else
                 flags[lb.idx] &= ~(1<<(lb.bit));
-#else
-            if (on)
-                flags[0] |= (1<<lb);
-            else
-                flags[0] &= ~(1<<(lb));
-#endif
+
             return true;
         }
     }
@@ -138,17 +130,11 @@ bool opts_setoptim (const char *name, bool on) {
 void opts_set(uint32_t *flags, size_t idx, bool on) {
     longbit lb;
     LONGBIT_SET(lb, idx);
-#if 1
+
     if (on)
         flags[lb.idx] |= (1<<(lb.bit));
     else
         flags[lb.idx] &= ~(1<<(lb.bit));
-#else
-    if (on)
-        flags[0] |= (1<<(lb));
-    else
-        flags[0] &= ~(1<<(lb));
-#endif
 }
 
 void opts_setoptimlevel(unsigned int level) {
index 7aad708..dae08be 100644 (file)
--- a/opts.def
+++ b/opts.def
     )
 #endif
 
+#ifdef GMQCC_TYPE_OPTIONS
+    GMQCC_DEFINE_FLAG (
+        O,
+
+        ""
+    )
+    GMQCC_DEFINE_FLAG (
+        OUTPUT,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        QUIET,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        G,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        STANDARD,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        DEBUG,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        MEMCHK,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        DUMPFIN,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        DUMP,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        FORCECRC,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        FORCED_CRC,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        PP_ONLY,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        MAX_ARRAY_SIZE,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        ADD_INFO,
+
+        ""
+    )
+
+    GMQCC_DEFINE_FLAG (
+        CORRECTION,
+
+        ""
+    )
+#endif
+
 /* some cleanup so we don't have to */
 #undef GMQCC_TYPE_FLAGS
 #undef GMQCC_TYPE_WARNS
+#undef GMQCC_TYPE_OPTIONS
 #undef GMQCC_TYPE_OPTIMIZATIONS
 #undef GMQCC_DEFINE_FLAG
index 62f2714..f407690 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -630,7 +630,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             {
 #if 0
                 /* This is not broken in fteqcc anymore */
-                if (opts.standard != COMPILER_GMQCC) {
+                if (OPTION_VALUE_U32(OPTION_STANDARD) != COMPILER_GMQCC) {
                     /* this error doesn't need to make us bail out */
                     (void)!parsewarning(parser, WARN_EXTENSIONS,
                                         "accessing array-field members of an entity without parenthesis\n"
@@ -1784,7 +1784,7 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels)
                  * We should also consider adding correction tables for
                  * other things as well.
                  */
-                if (opts.correction) {
+                if (OPTION_VALUE_BOOL(OPTION_CORRECTION)) {
                     correction_t corr;
                     correct_init(&corr);
 
@@ -2635,7 +2635,7 @@ static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **ou
 
     if (typevar || parser->tok == TOKEN_TYPENAME) {
 #if 0
-        if (opts.standard != COMPILER_GMQCC) {
+        if (OPTION_VALUE_U32(OPTION_STANDARD) != COMPILER_GMQCC) {
             if (parsewarning(parser, WARN_EXTENSIONS,
                              "current standard does not allow variable declarations in for-loop initializers"))
                 goto onerr;
@@ -3440,7 +3440,7 @@ static bool parse_statement(parser_t *parser, ast_block *block, ast_expression *
             parseerror(parser, "cannot declare a variable from here");
             return false;
         }
-        if (opts.standard == COMPILER_QCC) {
+        if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC) {
             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
                 return false;
         }
@@ -3507,7 +3507,7 @@ static bool parse_statement(parser_t *parser, ast_block *block, ast_expression *
         }
         else if (!strcmp(parser_tokval(parser), "for"))
         {
-            if (opts.standard == COMPILER_QCC) {
+            if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC) {
                 if (parsewarning(parser, WARN_EXTENSIONS, "for loops are not recognized in the original Quake C standard, to enable try an alternate standard --std=?"))
                     return false;
             }
@@ -4109,7 +4109,7 @@ static bool parse_function_body(parser_t *parser, ast_value *var)
 
     if (parser->tok == ';')
         return parser_next(parser);
-    else if (opts.standard == COMPILER_QCC)
+    else if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC)
         parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
     return retval;
 
@@ -4625,7 +4625,7 @@ static ast_value *parse_parameter_list(parser_t *parser, ast_value *var)
         vec_free(params);
 
     /* sanity check */
-    if (vec_size(params) > 8 && opts.standard == COMPILER_QCC)
+    if (vec_size(params) > 8 && OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC)
         (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard");
 
     /* parse-out */
@@ -4839,7 +4839,7 @@ static ast_value *parse_typename(parser_t *parser, ast_value **storebase, ast_va
     }
 
     /* now there may be function parens again */
-    if (parser->tok == '(' && opts.standard == COMPILER_QCC)
+    if (parser->tok == '(' && OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC)
         parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
     if (parser->tok == '(' && wasarray)
         parseerror(parser, "arrays as part of a return type is not supported");
@@ -4978,7 +4978,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
 
         /* Part 0: finish the type */
         if (parser->tok == '(') {
-            if (opts.standard == COMPILER_QCC)
+            if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC)
                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
             var = parse_parameter_list(parser, var);
             if (!var) {
@@ -5001,7 +5001,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
         }
         /* for functions returning functions */
         while (parser->tok == '(') {
-            if (opts.standard == COMPILER_QCC)
+            if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC)
                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
             var = parse_parameter_list(parser, var);
             if (!var) {
@@ -5071,7 +5071,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                     goto cleanup;
                     */
                 }
-                if ((opts.standard == COMPILER_QCC || opts.standard == COMPILER_FTEQCC) &&
+                if ((OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC || OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_FTEQCC) &&
                     (old = parser_find_global(parser, var->name)))
                 {
                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
@@ -5143,7 +5143,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                         ast_delete(var);
                         var = proto;
                     }
-                    if (opts.standard == COMPILER_QCC &&
+                    if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC &&
                         (old = parser_find_field(parser, var->name)))
                     {
                         parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
@@ -5174,7 +5174,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                     retval = false;
                     goto cleanup;
                 }
-                if (opts.standard != COMPILER_GMQCC) {
+                if (OPTION_VALUE_U32(OPTION_STANDARD) != COMPILER_GMQCC) {
                     ast_delete(var);
                     var = NULL;
                     goto skipvar;
@@ -5354,7 +5354,7 @@ skipvar:
             break;
         }
 
-        if (localblock && opts.standard == COMPILER_QCC) {
+        if (localblock && OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC) {
             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
                              "initializing expression turns variable `%s` into a constant in this standard",
                              var->name) )
@@ -5374,7 +5374,7 @@ skipvar:
                 break;
             }
         }
-        else if (opts.standard == COMPILER_QCC) {
+        else if (OPTION_VALUE_U32(OPTION_STANDARD) == COMPILER_QCC) {
             parseerror(parser, "expected '=' before function body in this standard");
         }
 
@@ -5735,7 +5735,7 @@ bool parser_init()
     parser->const_vec[1] = ast_value_new(empty_ctx, "<vector.y>", TYPE_NOEXPR);
     parser->const_vec[2] = ast_value_new(empty_ctx, "<vector.z>", TYPE_NOEXPR);
 
-    if (opts.add_info) {
+    if (OPTION_VALUE_BOOL(OPTION_ADD_INFO)) {
         parser->reserved_version = ast_value_new(empty_ctx, "reserved:version", TYPE_STRING);
         parser->reserved_version->cvq = CV_CONST;
         parser->reserved_version->hasvalue = true;
@@ -6024,7 +6024,7 @@ bool parser_finish(const char *output)
             return false;
         }
     }
-    if (opts.dump)
+    if (OPTION_VALUE_BOOL(OPTION_DUMP))
         ir_builder_dump(ir, con_out);
     for (i = 0; i < vec_size(parser->functions); ++i) {
         if (!ir_function_finalize(parser->functions[i]->ir_func)) {
@@ -6041,7 +6041,7 @@ bool parser_finish(const char *output)
     }
 
     if (retval) {
-        if (opts.dumpfin)
+        if (OPTION_VALUE_BOOL(OPTION_DUMPFIN))
             ir_builder_dump(ir, con_out);
 
         generate_checksum(parser);
diff --git a/test.c b/test.c
index eed80ef..c33b4ac 100644 (file)
--- a/test.c
+++ b/test.c
@@ -1242,11 +1242,11 @@ int main(int argc, char **argv) {
             con_change(redirout, redirerr);
 
             if (!strcmp(argv[0]+1, "debug")) {
-                opts.debug = true;
+                OPTION_VALUE_BOOL(OPTION_DEBUG) = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "memchk")) {
-                opts.memchk = true;
+                OPTION_VALUE_BOOL(OPTION_MEMCHK) = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "nocolor")) {
diff --git a/util.c b/util.c
index d427c38..0ac4df3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -132,7 +132,7 @@ void *util_memory_r(void *ptrn, size_t byte, unsigned int line, const char *file
 void util_meminfo() {
     struct memblock_t *info;
 
-    if (!opts.memchk)
+    if (!OPTION_VALUE_BOOL(OPTION_MEMCHK))
         return;
 
     for (info = mem_start; info; info = info->next) {
@@ -175,10 +175,10 @@ char *util_strdup(const char *s) {
 
 void util_debug(const char *area, const char *ms, ...) {
     va_list  va;
-    if (!opts.debug)
+    if (!OPTION_VALUE_BOOL(OPTION_DEBUG))
         return;
 
-    if (!strcmp(area, "MEM") && !opts.memchk)
+    if (!strcmp(area, "MEM") && !OPTION_VALUE_BOOL(OPTION_MEMCHK))
         return;
 
     va_start(va, ms);