Moving all the global opts_ variables into a struct, now there's one global 'opts...
authorWolfgang (Blub) Bumiller <blub@speed.at>
Thu, 6 Dec 2012 12:23:53 +0000 (13:23 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Thu, 6 Dec 2012 12:23:53 +0000 (13:23 +0100)
ast.c
code.c
exec.c
ftepp.c
gmqcc.h
ir.c
lexer.c
main.c
parser.c
test.c
util.c

diff --git a/ast.c b/ast.c
index 28179a3..993ef38 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1040,7 +1040,7 @@ const char* ast_function_label(ast_function *self, const char *prefix)
     size_t len;
     char  *from;
 
-    if (!opts_dump && !opts_dumpfin)
+    if (!opts.dump && !opts.dumpfin)
         return NULL;
 
     id  = (self->labelcount++);
@@ -1137,7 +1137,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 > opts.max_array_size)
                 compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)array->expression.count);
 
             elemtype = &array->expression.next->expression;
@@ -1191,7 +1191,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 > opts.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);
@@ -1312,7 +1312,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 > opts.max_array_size) {
             compile_error(ast_ctx(self), "Invalid array of size %lu", (unsigned long)self->expression.count);
         }
 
@@ -1413,14 +1413,14 @@ bool ast_generate_accessors(ast_value *self, ir_builder *ir)
         }
     }
 
-    options_set(opts_warn, WARN_USED_UNINITIALIZED, false);
+    options_set(opts.warn, WARN_USED_UNINITIALIZED, false);
     if (self->setter) {
         if (!ast_global_codegen  (self->setter, ir, false) ||
             !ast_function_codegen(self->setter->constval.vfunc, ir) ||
             !ir_function_finalize(self->setter->constval.vfunc->ir_func))
         {
             compile_error(ast_ctx(self), "internal error: failed to generate setter for `%s`", self->name);
-            options_set(opts_warn, WARN_USED_UNINITIALIZED, warn);
+            options_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
             return false;
         }
     }
@@ -1430,14 +1430,14 @@ bool ast_generate_accessors(ast_value *self, ir_builder *ir)
             !ir_function_finalize(self->getter->constval.vfunc->ir_func))
         {
             compile_error(ast_ctx(self), "internal error: failed to generate getter for `%s`", self->name);
-            options_set(opts_warn, WARN_USED_UNINITIALIZED, warn);
+            options_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
             return false;
         }
     }
     for (i = 0; i < self->expression.count; ++i) {
         vec_free(self->ir_values[i]->life);
     }
-    options_set(opts_warn, WARN_USED_UNINITIALIZED, warn);
+    options_set(opts.warn, WARN_USED_UNINITIALIZED, warn);
     return true;
 }
 
@@ -1551,7 +1551,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 (opts.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 73d63b4..ca6c3ad 100644 (file)
--- a/code.c
+++ b/code.c
@@ -113,8 +113,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 (opts.forcecrc)
+        code_header.crc16         = opts.forced_crc;
     else
         code_header.crc16         = code_crc;
     code_header.entfield          = code_entfields;
diff --git a/exec.c b/exec.c
index bea8ce4..3955371 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -617,6 +617,8 @@ cleanup:
 #if defined(QCVM_EXECUTOR)
 #include <math.h>
 
+cmd_options opts;
+
 const char *type_name[TYPE_COUNT] = {
     "void",
     "string",
@@ -632,9 +634,6 @@ const char *type_name[TYPE_COUNT] = {
     "variant"
 };
 
-bool        opts_debug    = false;
-bool        opts_memchk   = false;
-
 typedef struct {
     int         vtype;
     const char *value;
diff --git a/ftepp.c b/ftepp.c
index 7aa1c54..d28b19a 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -101,7 +101,7 @@ static bool GMQCC_WARN ftepp_warn(ftepp_t *ftepp, int warntype, const char *fmt,
     if (!OPTS_WARN(warntype))
         return false;
 
-    if (opts_werror) {
+    if (opts.werror) {
            lvl = LVL_ERROR;
         ftepp->errors++;
     }
@@ -109,7 +109,7 @@ static bool GMQCC_WARN ftepp_warn(ftepp_t *ftepp, int warntype, const char *fmt,
     va_start(ap, fmt);
     con_cvprintmsg((void*)&ftepp->lex->tok.ctx, lvl, "error", fmt, ap);
     va_end(ap);
-    return opts_werror;
+    return opts.werror;
 }
 
 static pptoken *pptoken_make(ftepp_t *ftepp)
@@ -1382,16 +1382,16 @@ bool ftepp_init()
 
     /* set the right macro based on the selected standard */
     ftepp_add_define(NULL, "GMQCC");
-    if (opts_standard == COMPILER_FTEQCC) {
+    if (opts.standard == COMPILER_FTEQCC) {
         ftepp_add_define(NULL, "__STD_FTEQCC__");
         /* 1.00 */
         major[0] = '1';
         minor[0] = '0';
-    } else if (opts_standard == COMPILER_GMQCC) {
+    } else if (opts.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_QCC) {
+    } else if (opts.standard == COMPILER_QCC) {
         ftepp_add_define(NULL, "__STD_QCC__");
         /* 1.0 */
         major[0] = '1';
diff --git a/gmqcc.h b/gmqcc.h
index 34367b8..2ccaafe 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -926,27 +926,32 @@ enum {
     COMPILER_GMQCC    /* this   QuakeC */
 };
 
-extern uint32_t    opts_O;      /* -Ox */
-extern const char *opts_output; /* -o file */
-extern int         opts_standard;
-extern bool        opts_debug;
-extern bool        opts_memchk;
-extern bool        opts_dumpfin;
-extern bool        opts_dump;
-extern bool        opts_werror;
-extern bool        opts_forcecrc;
-extern uint16_t    opts_forced_crc;
-extern bool        opts_pp_only;
-extern size_t      opts_max_array_size;
+typedef struct {
+    uint32_t    O;              /* -Ox           */
+    const char *output;         /* -o file       */
+    bool        g;              /* -g            */
+    int         standard;       /* -std=         */
+    bool        debug;          /* -debug        */
+    bool        memchk;         /* -memchk       */
+    bool        dumpfin;        /* -dumpfin      */
+    bool        dump;           /* -dump         */
+    bool        werror;         /* -Werror       */
+    bool        forcecrc;       /* --force-crc=  */
+    uint16_t    forced_crc;     /* --force-crc=  */
+    bool        pp_only;        /* -E            */
+    size_t      max_array_size; /* --max-array=  */
+
+    uint32_t flags       [1 + (COUNT_FLAGS         / 32)];
+    uint32_t warn        [1 + (COUNT_WARNINGS      / 32)];
+    uint32_t optimization[1 + (COUNT_OPTIMIZATIONS / 32)];
+} cmd_options;
+
+extern cmd_options opts;
 
 /*===================================================================*/
-#define OPTS_FLAG(i)         (!! (opts_flags       [(i)/32] & (1<< ((i)%32))))
-#define OPTS_WARN(i)         (!! (opts_warn        [(i)/32] & (1<< ((i)%32))))
-#define OPTS_OPTIMIZATION(i) (!! (opts_optimization[(i)/32] & (1<< ((i)%32))))
-
-extern uint32_t opts_flags       [1 + (COUNT_FLAGS         / 32)];
-extern uint32_t opts_warn        [1 + (COUNT_WARNINGS      / 32)];
-extern uint32_t opts_optimization[1 + (COUNT_OPTIMIZATIONS / 32)];
+#define OPTS_FLAG(i)         (!! (opts.flags       [(i)/32] & (1<< ((i)%32))))
+#define OPTS_WARN(i)         (!! (opts.warn        [(i)/32] & (1<< ((i)%32))))
+#define OPTS_OPTIMIZATION(i) (!! (opts.optimization[(i)/32] & (1<< ((i)%32))))
 
 void options_set(uint32_t *flags, size_t idx, bool on);
 
diff --git a/ir.c b/ir.c
index 38e243a..eb2e6b5 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -214,14 +214,14 @@ static bool irwarning(lex_ctx ctx, int warntype, const char *fmt, ...)
     if (warntype && !OPTS_WARN(warntype))
         return false;
 
-    if (opts_werror)
+    if (opts.werror)
            lvl = LVL_ERROR;
 
        va_start(ap, fmt);
-    con_vprintmsg(lvl, ctx.file, ctx.line, (opts_werror ? "error" : "warning"), fmt, ap);
+    con_vprintmsg(lvl, ctx.file, ctx.line, (opts.werror ? "error" : "warning"), fmt, ap);
        va_end(ap);
 
-       return opts_werror;
+       return opts.werror;
 }
 
 /***********************************************************************
@@ -3258,7 +3258,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 (opts.standard == COMPILER_GMQCC) {
         /* in our standard, the global gets a dot prefix */
         size_t len = strlen(field->name);
         char name[1024];
@@ -3364,7 +3364,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
     stmt.o3.u1 = 0;
     code_push_statement(&stmt, vec_last(code_linenums));
 
-    if (opts_pp_only)
+    if (opts.pp_only)
         return true;
 
     if (vec_size(code_statements) != vec_size(code_linenums)) {
diff --git a/lexer.c b/lexer.c
index 8fb7ef0..f1ef767 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -80,14 +80,14 @@ bool lexwarn(lex_file *lex, int warntype, const char *fmt, ...)
     if (!OPTS_WARN(warntype))
         return false;
 
-    if (opts_werror)
+    if (opts.werror)
         lvl = LVL_ERROR;
 
     va_start(ap, fmt);
-    con_vprintmsg(lvl, lex->name, lex->sline, (opts_werror ? "error" : "warning"), fmt, ap);
+    con_vprintmsg(lvl, lex->name, lex->sline, (opts.werror ? "error" : "warning"), fmt, ap);
     va_end(ap);
 
-    return opts_werror;
+    return opts.werror;
 }
 
 
@@ -1304,7 +1304,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 (opts.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 79b70fe..0165fe6 100644 (file)
--- a/main.c
+++ b/main.c
 #include "gmqcc.h"
 #include "lexer.h"
 
-uint32_t    opts_flags[1 + (COUNT_FLAGS / 32)];
-uint32_t    opts_optimization[1 + (COUNT_OPTIMIZATIONS / 32)];
-
 /* counter increased in ir.c */
 unsigned int optimization_count[COUNT_OPTIMIZATIONS];
-
-uint32_t    opts_O        = 1;
-const char *opts_output   = "progs.dat";
-int         opts_standard = COMPILER_GMQCC;
-bool        opts_debug    = false;
-bool        opts_memchk   = false;
-bool        opts_dumpfin  = false;
-bool        opts_dump     = false;
-bool        opts_forcecrc = false;
-bool        opts_pp_only  = false;
-size_t      opts_max_array_size = (1024 << 3);
-
-uint16_t    opts_forced_crc;
-
 static bool opts_output_wasset = false;
 
+cmd_options opts;
+
 /* set by the standard */
 const oper_info *operators      = NULL;
 size_t           operator_count = 0;
@@ -110,13 +95,13 @@ static bool options_setflag_all(const char *name, bool on, uint32_t *flags, cons
     return false;
 }
 static bool options_setflag(const char *name, bool on) {
-    return options_setflag_all(name, on, opts_flags, opts_flag_list, COUNT_FLAGS);
+    return options_setflag_all(name, on, opts.flags, opts_flag_list, COUNT_FLAGS);
 }
 static bool options_setwarn(const char *name, bool on) {
-    return options_setflag_all(name, on, opts_warn, opts_warn_list, COUNT_WARNINGS);
+    return options_setflag_all(name, on, opts.warn, opts_warn_list, COUNT_WARNINGS);
 }
 static bool options_setoptim(const char *name, bool on) {
-    return options_setflag_all(name, on, opts_optimization, opts_opt_list, COUNT_OPTIMIZATIONS);
+    return options_setflag_all(name, on, opts.optimization, opts_opt_list, COUNT_OPTIMIZATIONS);
 }
 
 static bool options_witharg(int *argc_, char ***argv_, char **out) {
@@ -189,7 +174,7 @@ static void set_optimizations(unsigned int level)
 {
     size_t i;
     for (i = 0; i < COUNT_OPTIMIZATIONS; ++i)
-        options_set(opts_optimization, i, level >= opts_opt_oflag[i]);
+        options_set(opts.optimization, i, level >= opts_opt_oflag[i]);
 }
 
 static bool options_parse(int argc, char **argv) {
@@ -210,23 +195,23 @@ static bool options_parse(int argc, char **argv) {
     /* All gcc-type long options */
             if (options_long_gcc("std", &argc, &argv, &argarg)) {
                 if      (!strcmp(argarg, "gmqcc") || !strcmp(argarg, "default")) {
-                    options_set(opts_flags, ADJUST_VECTOR_FIELDS, true);
-                    opts_standard = COMPILER_GMQCC;
+                    options_set(opts.flags, ADJUST_VECTOR_FIELDS, true);
+                    opts.standard = COMPILER_GMQCC;
                 } else if (!strcmp(argarg, "qcc")) {
-                    options_set(opts_flags, ADJUST_VECTOR_FIELDS, false);
-                    options_set(opts_flags, ASSIGN_FUNCTION_TYPES, true);
-                    opts_standard = COMPILER_QCC;
+                    options_set(opts.flags, ADJUST_VECTOR_FIELDS, false);
+                    options_set(opts.flags, ASSIGN_FUNCTION_TYPES, true);
+                    opts.standard = COMPILER_QCC;
                 } else if (!strcmp(argarg, "fte") || !strcmp(argarg, "fteqcc")) {
-                    options_set(opts_flags, FTEPP,                true);
-                    options_set(opts_flags, TRANSLATABLE_STRINGS, true);
-                    options_set(opts_flags, ADJUST_VECTOR_FIELDS, false);
-                    options_set(opts_flags, ASSIGN_FUNCTION_TYPES, true);
-                    options_set(opts_warn, WARN_TERNARY_PRECEDENCE, true);
-                    options_set(opts_flags, CORRECT_TERNARY, false);
-                    opts_standard = COMPILER_FTEQCC;
+                    options_set(opts.flags, FTEPP,                true);
+                    options_set(opts.flags, TRANSLATABLE_STRINGS, true);
+                    options_set(opts.flags, ADJUST_VECTOR_FIELDS, false);
+                    options_set(opts.flags, ASSIGN_FUNCTION_TYPES, true);
+                    options_set(opts.warn, WARN_TERNARY_PRECEDENCE, true);
+                    options_set(opts.flags, CORRECT_TERNARY, false);
+                    opts.standard = COMPILER_FTEQCC;
                 } else if (!strcmp(argarg, "qccx")) {
-                    options_set(opts_flags, ADJUST_VECTOR_FIELDS, false);
-                    opts_standard = COMPILER_QCCX;
+                    options_set(opts.flags, ADJUST_VECTOR_FIELDS, false);
+                    opts.standard = COMPILER_QCCX;
                 } else {
                     con_out("Unknown standard: %s\n", argarg);
                     return false;
@@ -234,8 +219,8 @@ 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);
+                opts.forcecrc = true;
+                opts.forced_crc = strtol(argarg, NULL, 0);
                 continue;
             }
             if (options_long_gcc("redirout", &argc, &argv, &redirout)) {
@@ -273,19 +258,19 @@ static bool options_parse(int argc, char **argv) {
             }
 
             if (!strcmp(argv[0]+1, "debug")) {
-                opts_debug = true;
+                opts.debug = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "dump")) {
-                opts_dump = true;
+                opts.dump = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "dumpfin")) {
-                opts_dumpfin = true;
+                opts.dumpfin = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "memchk")) {
-                opts_memchk = true;
+                opts.memchk = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "nocolor")) {
@@ -301,7 +286,7 @@ static bool options_parse(int argc, char **argv) {
                     /* break; never reached because of exit(0) */
 
                 case 'E':
-                    opts_pp_only = true;
+                    opts.pp_only = true;
                     break;
 
                 /* debug turns on -flno */
@@ -342,21 +327,21 @@ static bool options_parse(int argc, char **argv) {
                         exit(0);
                     }
                     else if (!strcmp(argv[0]+2, "NO_ERROR")) {
-                        opts_werror = false;
+                        opts.werror = false;
                         break;
                     }
                     else if (!strcmp(argv[0]+2, "ERROR")) {
-                        opts_werror = true;
+                        opts.werror = true;
                         break;
                     }
                     else if (!strcmp(argv[0]+2, "NONE")) {
-                        for (itr = 0; itr < sizeof(opts_warn)/sizeof(opts_warn[0]); ++itr)
-                            opts_warn[itr] = 0;
+                        for (itr = 0; itr < sizeof(opts.warn)/sizeof(opts.warn[0]); ++itr)
+                            opts.warn[itr] = 0;
                         break;
                     }
                     else if (!strcmp(argv[0]+2, "ALL")) {
-                        for (itr = 0; itr < sizeof(opts_warn)/sizeof(opts_warn[0]); ++itr)
-                            opts_warn[itr] = 0xFFFFFFFFL;
+                        for (itr = 0; itr < sizeof(opts.warn)/sizeof(opts.warn[0]); ++itr)
+                            opts.warn[itr] = 0xFFFFFFFFL;
                         break;
                     }
                     if (!strncmp(argv[0]+2, "NO_", 3)) {
@@ -377,8 +362,8 @@ static bool options_parse(int argc, char **argv) {
                         return false;
                     }
                     if (isdigit(argarg[0])) {
-                        opts_O = atoi(argarg);
-                        set_optimizations(opts_O);
+                        opts.O = atoi(argarg);
+                        set_optimizations(opts.O);
                     } else {
                         util_strtocmd(argarg, argarg, strlen(argarg)+1);
                         if (!strcmp(argarg, "HELP")) {
@@ -390,7 +375,7 @@ static bool options_parse(int argc, char **argv) {
                             exit(0);
                         }
                         else if (!strcmp(argarg, "ALL"))
-                            set_optimizations(opts_O = 9999);
+                            set_optimizations(opts.O = 9999);
                         else if (!strncmp(argarg, "NO_", 3)) {
                             if (!options_setoptim(argarg+3, false)) {
                                 con_out("unknown optimization: %s\n", argarg+3);
@@ -411,7 +396,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;
+                    opts.output = argarg;
                     opts_output_wasset = true;
                     break;
 
@@ -441,7 +426,7 @@ static bool options_parse(int argc, char **argv) {
                     else {
             /* All long options with arguments */
                         if (options_long_witharg("output", &argc, &argv, &argarg)) {
-                            opts_output = argarg;
+                            opts.output = argarg;
                             opts_output_wasset = true;
                         } else {
                             con_out("Unknown parameter: %s\n", argv[0]);
@@ -500,44 +485,49 @@ int main(int argc, char **argv) {
     bool progs_src = false;
     FILE *outfile = NULL;
 
+    memset(&opts, 0, sizeof(opts));
+    opts.output         = "progs.dat";
+    opts.standard       = COMPILER_GMQCC;
+    opts.max_array_size = (1024<<3);
+
     app_name = argv[0];
     con_init();
 
     /* default options / warn flags */
-    options_set(opts_warn, WARN_UNKNOWN_CONTROL_SEQUENCE, true);
-    options_set(opts_warn, WARN_EXTENSIONS, true);
-    options_set(opts_warn, WARN_FIELD_REDECLARED, true);
-    options_set(opts_warn, WARN_TOO_FEW_PARAMETERS, true);
-    options_set(opts_warn, WARN_MISSING_RETURN_VALUES, true);
-    options_set(opts_warn, WARN_USED_UNINITIALIZED, true);
-    options_set(opts_warn, WARN_LOCAL_CONSTANTS, true);
-    options_set(opts_warn, WARN_VOID_VARIABLES, true);
-    options_set(opts_warn, WARN_IMPLICIT_FUNCTION_POINTER, true);
-    options_set(opts_warn, WARN_VARIADIC_FUNCTION, true);
-    options_set(opts_warn, WARN_FRAME_MACROS, true);
-    options_set(opts_warn, WARN_UNUSED_VARIABLE, true);
-    options_set(opts_warn, WARN_EFFECTLESS_STATEMENT, true);
-    options_set(opts_warn, WARN_END_SYS_FIELDS, true);
-    options_set(opts_warn, WARN_ASSIGN_FUNCTION_TYPES, true);
-    options_set(opts_warn, WARN_PREPROCESSOR, true);
-    options_set(opts_warn, WARN_MULTIFILE_IF, true);
-    options_set(opts_warn, WARN_DOUBLE_DECLARATION, true);
-    options_set(opts_warn, WARN_CONST_VAR, true);
-    options_set(opts_warn, WARN_MULTIBYTE_CHARACTER, true);
-
-    options_set(opts_flags, ADJUST_VECTOR_FIELDS, true);
-    options_set(opts_flags, FTEPP, false);
-    options_set(opts_flags, CORRECT_TERNARY, true);
+    options_set(opts.warn, WARN_UNKNOWN_CONTROL_SEQUENCE, true);
+    options_set(opts.warn, WARN_EXTENSIONS, true);
+    options_set(opts.warn, WARN_FIELD_REDECLARED, true);
+    options_set(opts.warn, WARN_TOO_FEW_PARAMETERS, true);
+    options_set(opts.warn, WARN_MISSING_RETURN_VALUES, true);
+    options_set(opts.warn, WARN_USED_UNINITIALIZED, true);
+    options_set(opts.warn, WARN_LOCAL_CONSTANTS, true);
+    options_set(opts.warn, WARN_VOID_VARIABLES, true);
+    options_set(opts.warn, WARN_IMPLICIT_FUNCTION_POINTER, true);
+    options_set(opts.warn, WARN_VARIADIC_FUNCTION, true);
+    options_set(opts.warn, WARN_FRAME_MACROS, true);
+    options_set(opts.warn, WARN_UNUSED_VARIABLE, true);
+    options_set(opts.warn, WARN_EFFECTLESS_STATEMENT, true);
+    options_set(opts.warn, WARN_END_SYS_FIELDS, true);
+    options_set(opts.warn, WARN_ASSIGN_FUNCTION_TYPES, true);
+    options_set(opts.warn, WARN_PREPROCESSOR, true);
+    options_set(opts.warn, WARN_MULTIFILE_IF, true);
+    options_set(opts.warn, WARN_DOUBLE_DECLARATION, true);
+    options_set(opts.warn, WARN_CONST_VAR, true);
+    options_set(opts.warn, WARN_MULTIBYTE_CHARACTER, true);
+
+    options_set(opts.flags, ADJUST_VECTOR_FIELDS, true);
+    options_set(opts.flags, FTEPP, false);
+    options_set(opts.flags, CORRECT_TERNARY, true);
 
     if (!options_parse(argc, argv)) {
         return usage();
     }
 
     /* the standard decides which set of operators to use */
-    if (opts_standard == COMPILER_GMQCC) {
+    if (opts.standard == COMPILER_GMQCC) {
         operators = c_operators;
         operator_count = c_operator_count;
-    } else if (opts_standard == COMPILER_FTEQCC) {
+    } else if (opts.standard == COMPILER_FTEQCC) {
         operators = fte_operators;
         operator_count = fte_operator_count;
     } else {
@@ -565,23 +555,23 @@ int main(int argc, char **argv) {
         }
     }
 
-    if (opts_dump) {
+    if (opts.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 = %i\n", (int)opts_O);
-        con_out("standard = %i\n", opts_standard);
+        con_out("output = %s\n", opts.output);
+        con_out("optimization level = %i\n", (int)opts.O);
+        con_out("standard = %i\n", opts.standard);
     }
 
-    if (opts_pp_only) {
+    if (opts.pp_only) {
         if (opts_output_wasset) {
-            outfile = util_fopen(opts_output, "wb");
+            outfile = util_fopen(opts.output, "wb");
             if (!outfile) {
-                con_err("failed to open `%s` for writing\n", opts_output);
+                con_err("failed to open `%s` for writing\n", opts.output);
                 retval = 1;
                 goto cleanup;
             }
@@ -590,14 +580,14 @@ int main(int argc, char **argv) {
             outfile = stdout;
     }
 
-    if (!opts_pp_only) {
+    if (!opts.pp_only) {
         if (!parser_init()) {
             con_err("failed to initialize parser\n");
             retval = 1;
             goto cleanup;
         }
     }
-    if (opts_pp_only || OPTS_FLAG(FTEPP)) {
+    if (opts.pp_only || OPTS_FLAG(FTEPP)) {
         if (!ftepp_init()) {
             con_err("failed to initialize parser\n");
             retval = 1;
@@ -629,7 +619,7 @@ int main(int argc, char **argv) {
         }
 
         if (!opts_output_wasset) {
-            opts_output = util_strdup(line);
+            opts.output = util_strdup(line);
             opts_output_free = true;
         }
 
@@ -651,12 +641,12 @@ srcdone:
         goto cleanup;
 
     if (vec_size(items)) {
-        if (!opts_pp_only) {
+        if (!opts.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_pp_only) {
+            if (!opts.pp_only) {
                 con_out("  item: %s (%s)\n",
                        items[itr].filename,
                        ( (items[itr].type == TYPE_QC ? "qc" :
@@ -665,7 +655,7 @@ srcdone:
                          ("unknown"))))));
             }
 
-            if (opts_pp_only) {
+            if (opts.pp_only) {
                 const char *out;
                 if (!ftepp_preprocess_file(items[itr].filename)) {
                     retval = 1;
@@ -707,8 +697,8 @@ srcdone:
         }
 
         ftepp_finish();
-        if (!opts_pp_only) {
-            if (!parser_finish(opts_output)) {
+        if (!opts.pp_only) {
+            if (!parser_finish(opts.output)) {
                 retval = 1;
                 goto cleanup;
             }
@@ -717,7 +707,7 @@ srcdone:
 
     /* stuff */
 
-    if (!opts_pp_only) {
+    if (!opts.pp_only) {
         for (itr = 0; itr < COUNT_OPTIMIZATIONS; ++itr) {
             if (optimization_count[itr]) {
                 con_out("%s: %u\n", opts_opt_list[itr].name, (unsigned int)optimization_count[itr]);
@@ -731,10 +721,10 @@ cleanup:
     con_close();
     vec_free(items);
 
-    if (!opts_pp_only)
+    if (!opts.pp_only)
         parser_cleanup();
     if (opts_output_free)
-        mem_d((char*)opts_output);
+        mem_d((char*)opts.output);
     if (operators_free)
         mem_d((void*)operators);
 
index 488d5ce..84413fd 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -130,16 +130,16 @@ static bool GMQCC_WARN parsewarning(parser_t *parser, int warntype, const char *
     if (!OPTS_WARN(warntype))
         return false;
 
-    if (opts_werror) {
+    if (opts.werror) {
            parser->errors++;
            lvl = LVL_ERROR;
        }
 
        va_start(ap, fmt);
-    con_vprintmsg(lvl, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, (opts_werror ? "error" : "warning"), fmt, ap);
+    con_vprintmsg(lvl, parser->lex->tok.ctx.file, parser->lex->tok.ctx.line, (opts.werror ? "error" : "warning"), fmt, ap);
        va_end(ap);
 
-       return opts_werror;
+       return opts.werror;
 }
 
 static bool GMQCC_WARN genwarning(lex_ctx ctx, int warntype, const char *fmt, ...)
@@ -150,14 +150,14 @@ static bool GMQCC_WARN genwarning(lex_ctx ctx, int warntype, const char *fmt, ..
     if (!OPTS_WARN(warntype))
         return false;
 
-    if (opts_werror)
+    if (opts.werror)
            lvl = LVL_ERROR;
 
        va_start(ap, fmt);
-    con_vprintmsg(lvl, ctx.file, ctx.line, (opts_werror ? "error" : "warning"), fmt, ap);
+    con_vprintmsg(lvl, ctx.file, ctx.line, (opts.werror ? "error" : "warning"), fmt, ap);
        va_end(ap);
 
-       return opts_werror;
+       return opts.werror;
 }
 
 /**********************************************************************
@@ -591,7 +591,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 (opts.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"
@@ -853,7 +853,7 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
                 return false;
             }
 #endif
-            if (opts_standard == COMPILER_GMQCC)
+            if (opts.standard == COMPILER_GMQCC)
                 con_out("TODO: early out logic\n");
             if (CanConstFold(exprs[0], exprs[1]))
                 out = (ast_expression*)parser_const_float(parser,
@@ -1258,7 +1258,7 @@ static bool parser_close_call(parser_t *parser, shunt *sy)
             const char *fewmany = (vec_size(fun->expression.params) > paramcount) ? "few" : "many";
 
             fval = (ast_istype(fun, ast_value) ? ((ast_value*)fun) : NULL);
-            if (opts_standard == COMPILER_GMQCC)
+            if (opts.standard == COMPILER_GMQCC)
             {
                 if (fval)
                     parseerror(parser, "too %s parameters for call to %s: expected %i, got %i\n"
@@ -1423,7 +1423,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
             }
             wantop = true;
             /* variable */
-            if (opts_standard == COMPILER_GMQCC)
+            if (opts.standard == COMPILER_GMQCC)
             {
                 if (parser->memberof == TYPE_ENTITY) {
                     /* still get vars first since there could be a fieldpointer */
@@ -1637,7 +1637,7 @@ static ast_expression* parse_expression_leave(parser_t *parser, bool stopatcomma
                     olast = NULL;
             }
 
-            if (op->id == opid1('.') && opts_standard == COMPILER_GMQCC) {
+            if (op->id == opid1('.') && opts.standard == COMPILER_GMQCC) {
                 /* for gmqcc standard: open up the namespace of the previous type */
                 ast_expression *prevex = vec_last(sy.out).out;
                 if (!prevex) {
@@ -2034,7 +2034,7 @@ static bool parse_for(parser_t *parser, ast_block *block, ast_expression **out)
         typevar = parser_find_typedef(parser, parser_tokval(parser), 0);
 
     if (typevar || parser->tok == TOKEN_TYPENAME) {
-        if (opts_standard != COMPILER_GMQCC) {
+        if (opts.standard != COMPILER_GMQCC) {
             if (parsewarning(parser, WARN_EXTENSIONS,
                              "current standard does not allow variable declarations in for-loop initializers"))
                 goto onerr;
@@ -2147,7 +2147,7 @@ static bool parse_return(parser_t *parser, ast_block *block, ast_expression **ou
         if (!parser_next(parser))
             parseerror(parser, "parse error");
         if (expected->expression.next->expression.vtype != TYPE_VOID) {
-            if (opts_standard != COMPILER_GMQCC)
+            if (opts.standard != COMPILER_GMQCC)
                 (void)!parsewarning(parser, WARN_MISSING_RETURN_VALUES, "return without value");
             else
                 parseerror(parser, "return without value");
@@ -2521,7 +2521,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 (opts.standard == COMPILER_QCC) {
             if (parsewarning(parser, WARN_EXTENSIONS, "missing 'local' keyword when declaring a local variable"))
                 return false;
         }
@@ -2588,7 +2588,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 (opts.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;
             }
@@ -3052,7 +3052,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 (opts.standard == COMPILER_QCC)
         parseerror(parser, "missing semicolon after function body (mandatory with -std=qcc)");
     return retval;
 
@@ -3511,7 +3511,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 && opts.standard == COMPILER_QCC)
         (void)!parsewarning(parser, WARN_EXTENSIONS, "more than 8 parameters are not supported by this standard");
 
     /* parse-out */
@@ -3720,7 +3720,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 == '(' && opts.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");
@@ -3819,7 +3819,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 (opts.standard == COMPILER_QCC)
                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
             var = parse_parameter_list(parser, var);
             if (!var) {
@@ -3842,7 +3842,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 (opts.standard == COMPILER_QCC)
                 parseerror(parser, "C-style function syntax is not allowed in -std=qcc");
             var = parse_parameter_list(parser, var);
             if (!var) {
@@ -3905,7 +3905,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                     goto cleanup;
                     */
                 }
-                if (opts_standard == COMPILER_QCC &&
+                if (opts.standard == COMPILER_QCC &&
                     (old = parser_find_global(parser, var->name)))
                 {
                     parseerror(parser, "cannot declare a field and a global of the same name with -std=qcc");
@@ -3945,7 +3945,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                 {
                     /* other globals */
                     if (old) {
-                        if (opts_standard == COMPILER_GMQCC) {
+                        if (opts.standard == COMPILER_GMQCC) {
                             parseerror(parser, "global `%s` already declared here: %s:%i",
                                        var->name, ast_ctx(old).file, ast_ctx(old).line);
                             retval = false;
@@ -3969,7 +3969,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                             var = proto;
                         }
                     }
-                    if (opts_standard == COMPILER_QCC &&
+                    if (opts.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");
@@ -4000,7 +4000,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield
                     retval = false;
                     goto cleanup;
                 }
-                if (opts_standard != COMPILER_GMQCC) {
+                if (opts.standard != COMPILER_GMQCC) {
                     ast_delete(var);
                     var = NULL;
                     goto skipvar;
@@ -4124,7 +4124,7 @@ skipvar:
             break;
         }
 
-        if (localblock && opts_standard == COMPILER_QCC) {
+        if (localblock && opts.standard == COMPILER_QCC) {
             if (parsewarning(parser, WARN_LOCAL_CONSTANTS,
                              "initializing expression turns variable `%s` into a constant in this standard",
                              var->name) )
@@ -4144,7 +4144,7 @@ skipvar:
                 break;
             }
         }
-        else if (opts_standard == COMPILER_QCC) {
+        else if (opts.standard == COMPILER_QCC) {
             parseerror(parser, "expected '=' before function body in this standard");
         }
 
@@ -4231,7 +4231,7 @@ skipvar:
                     parseerror(parser, "cannot initialize a global constant variable with a non-constant expression");
                 else
                 {
-                    if (opts_standard != COMPILER_GMQCC &&
+                    if (opts.standard != COMPILER_GMQCC &&
                         !OPTS_FLAG(INITIALIZED_NONCONSTANTS) &&
                         qualifier != CV_VAR)
                     {
@@ -4699,7 +4699,7 @@ bool parser_finish(const char *output)
                 return false;
             }
         }
-        if (opts_dump)
+        if (opts.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)) {
@@ -4710,7 +4710,7 @@ bool parser_finish(const char *output)
         }
 
         if (retval) {
-            if (opts_dumpfin)
+            if (opts.dumpfin)
                 ir_builder_dump(ir, con_out);
 
             generate_checksum(parser);
diff --git a/test.c b/test.c
index 7af705f..54fb2aa 100644 (file)
--- a/test.c
+++ b/test.c
@@ -25,8 +25,8 @@
 #include <sys/stat.h>
 #include <dirent.h>
 
-bool  opts_memchk = false;
-bool  opts_debug  = false;
+cmd_options opts;
+
 char *task_bins[] = {
     "./gmqcc",
     "./qcvm"
@@ -1095,11 +1095,11 @@ int main(int argc, char **argv) {
             con_change(redirout, redirerr);
 
             if (!strcmp(argv[0]+1, "debug")) {
-                opts_debug = true;
+                opts.debug = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "memchk")) {
-                opts_memchk = true;
+                opts.memchk = true;
                 continue;
             }
             if (!strcmp(argv[0]+1, "nocolor")) {
diff --git a/util.c b/util.c
index d7e325d..f213e2f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -135,7 +135,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 (!opts.memchk)
         return;
 
     for (info = mem_start; info; info = info->next) {
@@ -246,10 +246,10 @@ bool util_strncmpexact(const char *src, const char *ned, size_t len) {
 
 void util_debug(const char *area, const char *ms, ...) {
     va_list  va;
-    if (!opts_debug)
+    if (!opts.debug)
         return;
 
-    if (!strcmp(area, "MEM") && !opts_memchk)
+    if (!strcmp(area, "MEM") && !opts.memchk)
         return;
 
     va_start(va, ms);