]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - main.c
Remove fs.c ansi.c and PORTING guide
[xonotic/gmqcc.git] / main.c
diff --git a/main.c b/main.c
index 37638e92ae4fb8b0202116f596d48e3d1d27e127..3f6f6ef29318a6df614fa1eb25d24864c5a2118a 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013
+ * Copyright (C) 2012, 2013, 2014, 2015
  *     Dale Weiler
  *     Wolfgang Bumiller
  *
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include <time.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>
-
 
 #include "gmqcc.h"
 #include "lexer.h"
@@ -47,7 +43,6 @@ static ppitem  *ppems = NULL;
 #define TYPE_ASM 1
 #define TYPE_SRC 2
 
-
 static const char *app_name;
 
 static void version(void) {
@@ -90,6 +85,8 @@ static int usage(void) {
             "  -Ono-<name>            disable specific optimization\n"
             "  -Ohelp                 list optimizations\n");
     con_out("  -force-crc=num         force a specific checksum into the header\n");
+    con_out("  -state-fps=num         emulate OP_STATE with the specified FPS\n");
+    con_out("  -coverage              add coverage support\n");
     return -1;
 }
 
@@ -168,6 +165,9 @@ static bool options_parse(int argc, char **argv) {
 
                     opts_set(opts.flags, ADJUST_VECTOR_FIELDS,          true);
                     opts_set(opts.flags, CORRECT_LOGIC,                 true);
+                    opts_set(opts.flags, SHORT_LOGIC,                   true);
+                    opts_set(opts.flags, UNTYPED_NIL,                   true);
+                    opts_set(opts.flags, VARIADIC_ARGS,                 true);
                     opts_set(opts.flags, FALSE_EMPTY_STRINGS,           false);
                     opts_set(opts.flags, TRUE_EMPTY_STRINGS,            true);
                     opts_set(opts.flags, LOOP_LABELS,                   true);
@@ -176,10 +176,11 @@ static bool options_parse(int argc, char **argv) {
                     opts_set(opts.werror, WARN_INVALID_PARAMETER_COUNT, true);
                     opts_set(opts.werror, WARN_MISSING_RETURN_VALUES,   true);
                     opts_set(opts.flags,  EXPRESSIONS_FOR_BUILTINS,     true);
+                    opts_set(opts.warn,   WARN_BREAKDEF,                true);
+
 
 
                     OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_GMQCC;
-                    OPTS_OPTION_BOOL(OPTION_STATISTICS) = true;
 
                 } else if (!strcmp(argarg, "qcc")) {
 
@@ -196,6 +197,7 @@ 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_set(opts.warn, WARN_BREAKDEF,             true);
 
                     OPTS_OPTION_U32(OPTION_STANDARD) = COMPILER_FTEQCC;
 
@@ -216,12 +218,9 @@ static bool options_parse(int argc, char **argv) {
                 OPTS_OPTION_U16 (OPTION_FORCED_CRC) = strtol(argarg, NULL, 0);
                 continue;
             }
-            if (options_long_gcc("redirout", &argc, &argv, &redirout)) {
-                con_change(redirout, redirerr);
-                continue;
-            }
-            if (options_long_gcc("redirerr", &argc, &argv, &redirerr)) {
-                con_change(redirout, redirerr);
+            if (options_long_gcc("state-fps", &argc, &argv, &argarg)) {
+                OPTS_OPTION_U32(OPTION_STATE_FPS) = strtol(argarg, NULL, 0);
+                opts_set(opts.flags, EMULATE_STATE, true);
                 continue;
             }
             if (options_long_gcc("config", &argc, &argv, &argarg)) {
@@ -232,6 +231,10 @@ static bool options_parse(int argc, char **argv) {
                 OPTS_OPTION_U16(OPTION_MEMDUMPCOLS) = (uint16_t)strtol(memdumpcols, NULL, 10);
                 continue;
             }
+            if (options_long_gcc("progsrc", &argc, &argv, &argarg)) {
+                OPTS_OPTION_STR(OPTION_PROGSRC) = argarg;
+                continue;
+            }
 
             /* show defaults (like pathscale) */
             if (!strcmp(argv[0]+1, "show-defaults")) {
@@ -276,6 +279,10 @@ static bool options_parse(int argc, char **argv) {
                 con_color(0);
                 continue;
             }
+            if (!strcmp(argv[0]+1, "coverage")) {
+                OPTS_OPTION_BOOL(OPTION_COVERAGE) = true;
+                continue;
+            }
 
             switch (argv[0][1]) {
                 /* -h, show usage but exit with 0 */
@@ -357,7 +364,7 @@ static bool options_parse(int argc, char **argv) {
                     else if (!strcmp(argv[0]+2, "NO_ERROR") ||
                              !strcmp(argv[0]+2, "NO_ERROR_ALL"))
                     {
-                        for (itr = 0; itr < sizeof(opts.werror)/sizeof(opts.werror[0]); ++itr)
+                        for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.werror); ++itr)
                             opts.werror[itr] = 0;
                         break;
                     }
@@ -365,19 +372,19 @@ static bool options_parse(int argc, char **argv) {
                              !strcmp(argv[0]+2, "ERROR_ALL"))
                     {
                         opts_backup_non_Werror_all();
-                        for (itr = 0; itr < sizeof(opts.werror)/sizeof(opts.werror[0]); ++itr)
+                        for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.werror); ++itr)
                             opts.werror[itr] = 0xFFFFFFFFL;
                         opts_restore_non_Werror_all();
                         break;
                     }
                     else if (!strcmp(argv[0]+2, "NONE")) {
-                        for (itr = 0; itr < sizeof(opts.warn)/sizeof(opts.warn[0]); ++itr)
+                        for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.warn); ++itr)
                             opts.warn[itr] = 0;
                         break;
                     }
                     else if (!strcmp(argv[0]+2, "ALL")) {
                         opts_backup_non_Wall();
-                        for (itr = 0; itr < sizeof(opts.warn)/sizeof(opts.warn[0]); ++itr)
+                        for (itr = 0; itr < GMQCC_ARRAY_COUNT(opts.warn); ++itr)
                             opts.warn[itr] = 0xFFFFFFFFL;
                         opts_restore_non_Wall();
                         break;
@@ -411,7 +418,7 @@ static bool options_parse(int argc, char **argv) {
                         con_out("option -O requires a numerical argument, or optimization name with an optional 'no-' prefix\n");
                         return false;
                     }
-                    if (isdigit(argarg[0])) {
+                    if (util_isdigit(argarg[0])) {
                         uint32_t val = (uint32_t)strtol(argarg, NULL, 10);
                         OPTS_OPTION_U32(OPTION_O) = val;
                         opts_setoptimlevel(val);
@@ -428,7 +435,8 @@ static bool options_parse(int argc, char **argv) {
                         else if (!strcmp(argarg, "ALL"))
                             opts_setoptimlevel(OPTS_OPTION_U32(OPTION_O) = 9999);
                         else if (!strncmp(argarg, "NO_", 3)) {
-                            if (!opts_setoptim(argarg+3, false)) {
+                            /* constant folding cannot be turned off for obvious reasons */
+                            if (!strcmp(argarg, "NO_CONST_FOLD") || !opts_setoptim(argarg+3, false)) {
                                 con_out("unknown optimization: %s\n", argarg+3);
                                 return false;
                             }
@@ -482,14 +490,6 @@ static bool options_parse(int argc, char **argv) {
                         OPTS_OPTION_BOOL(OPTION_QUIET) = true;
                         break;
                     }
-                    else if (!strcmp(argv[0]+2, "correct")) {
-                        OPTS_OPTION_BOOL(OPTION_CORRECTION) = true;
-                        break;
-                    }
-                    else if (!strcmp(argv[0]+2, "no-correct")) {
-                        OPTS_OPTION_BOOL(OPTION_CORRECTION) = false;
-                        break;
-                    }
                     else if (!strcmp(argv[0]+2, "add-info")) {
                         OPTS_OPTION_BOOL(OPTION_ADD_INFO) = true;
                         break;
@@ -524,21 +524,21 @@ static bool options_parse(int argc, char **argv) {
 }
 
 /* returns the line number, or -1 on error */
-static bool progs_nextline(char **out, size_t *alen,FILE *src) {
+static bool progs_nextline(char **out, size_t *alen, FILE *src) {
     int    len;
     char  *line;
     char  *start;
     char  *end;
 
     line = *out;
-    len  = fs_file_getline(&line, alen, src);
+    len  = util_getline(&line, alen, src);
     if (len == -1)
         return false;
 
     /* start at first non-blank */
-    for (start = line; isspace(*start); ++start) {}
+    for (start = line; util_isspace(*start); ++start) {}
     /* end at the first non-blank */
-    for (end = start;  *end && !isspace(*end);  ++end)   {}
+    for (end = start; *end && !util_isspace(*end);  ++end)   {}
 
     *out = line;
     /* move the actual filename to the beginning */
@@ -552,16 +552,15 @@ static bool progs_nextline(char **out, size_t *alen,FILE *src) {
 int main(int argc, char **argv) {
     size_t          itr;
     int             retval           = 0;
-    bool            opts_output_free = false;
     bool            operators_free   = false;
     bool            progs_src        = false;
-    FILE            *outfile         = NULL;
+    FILE       *outfile         = NULL;
     struct parser_s *parser          = NULL;
     struct ftepp_s  *ftepp           = NULL;
 
     app_name = argv[0];
     con_init ();
-    opts_init("progs.dat", COMPILER_GMQCC, (1024 << 3));
+    opts_init("progs.dat", COMPILER_QCC, (1024 << 3));
 
     util_seed(time(0));
 
@@ -577,13 +576,13 @@ int main(int argc, char **argv) {
     /* the standard decides which set of operators to use */
     if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) {
         operators      = c_operators;
-        operator_count = c_operator_count;
+        operator_count = GMQCC_ARRAY_COUNT(c_operators);
     } else if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_FTEQCC) {
         operators      = fte_operators;
-        operator_count = fte_operator_count;
+        operator_count = GMQCC_ARRAY_COUNT(fte_operators);
     } else {
         operators      = qcc_operators;
-        operator_count = qcc_operator_count;
+        operator_count = GMQCC_ARRAY_COUNT(qcc_operators);
     }
 
     if (operators == fte_operators) {
@@ -619,7 +618,7 @@ int main(int argc, char **argv) {
 
     if (OPTS_OPTION_BOOL(OPTION_PP_ONLY)) {
         if (opts_output_wasset) {
-            outfile = fs_file_open(OPTS_OPTION_STR(OPTION_OUTPUT), "wb");
+            outfile = fopen(OPTS_OPTION_STR(OPTION_OUTPUT), "wb");
             if (!outfile) {
                 con_err("failed to open `%s` for writing\n", OPTS_OPTION_STR(OPTION_OUTPUT));
                 retval = 1;
@@ -647,8 +646,6 @@ int main(int argc, char **argv) {
         }
     }
 
-    util_debug("COM", "starting ...\n");
-
     /* add macros */
     if (OPTS_OPTION_BOOL(OPTION_PP_ONLY) || OPTS_FLAG(FTEPP)) {
         for (itr = 0; itr < vec_size(ppems); itr++) {
@@ -663,47 +660,39 @@ int main(int argc, char **argv) {
 
     if (!vec_size(items)) {
         FILE *src;
-        char *line;
-        size_t linelen = 0;
+        char      *line    = NULL;
+        size_t     linelen = 0;
+        bool       hasline = false;
 
         progs_src = true;
 
-        src = fs_file_open("progs.src", "rb");
+        src = fopen(OPTS_OPTION_STR(OPTION_PROGSRC), "rb");
         if (!src) {
-            con_err("failed to open `progs.src` for reading\n");
+            con_err("failed to open `%s` for reading\n", OPTS_OPTION_STR(OPTION_PROGSRC));
             retval = 1;
             goto cleanup;
         }
 
-        line = NULL;
-        if (!progs_nextline(&line, &linelen, src) || !line[0]) {
-            con_err("illformatted progs.src file: expected output filename in first line\n");
-            retval = 1;
-            goto srcdone;
-        }
-
-        if (!opts_output_wasset) {
-            OPTS_OPTION_STR(OPTION_OUTPUT) = util_strdup(line);
-            opts_output_free = true;
-        }
-
         while (progs_nextline(&line, &linelen, src)) {
             argitem item;
+
             if (!line[0] || (line[0] == '/' && line[1] == '/'))
                 continue;
-            item.filename = util_strdup(line);
-            item.type     = TYPE_QC;
-            vec_push(items, item);
+
+            if (hasline) {
+                item.filename = util_strdup(line);
+                item.type     = TYPE_QC;
+                vec_push(items, item);
+            } else if (!opts_output_wasset) {
+                OPTS_OPTION_DUP(OPTION_OUTPUT) = util_strdup(line);
+                hasline                        = true;
+            }
         }
 
-srcdone:
-        fs_file_close(src);
+        fclose(src);
         mem_d(line);
     }
 
-    if (retval)
-        goto cleanup;
-
     if (vec_size(items)) {
         if (!OPTS_OPTION_BOOL(OPTION_QUIET) &&
             !OPTS_OPTION_BOOL(OPTION_PP_ONLY))
@@ -732,7 +721,7 @@ srcdone:
                 }
                 out = ftepp_get(ftepp);
                 if (out)
-                    fs_file_printf(outfile, "%s", out);
+                    fprintf(outfile, "%s", out);
                 ftepp_flush(ftepp);
             }
             else {
@@ -775,19 +764,7 @@ srcdone:
         }
     }
 
-    /* stuff */
-    if (!OPTS_OPTION_BOOL(OPTION_QUIET) &&
-        !OPTS_OPTION_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]);
-            }
-        }
-    }
-
 cleanup:
-    util_debug("COM", "cleaning ...\n");
     if (ftepp)
         ftepp_finish(ftepp);
     con_close();
@@ -795,14 +772,19 @@ cleanup:
     vec_free(ppems);
 
     if (!OPTS_OPTION_BOOL(OPTION_PP_ONLY))
-        parser_cleanup(parser);
-    if (opts_output_free)
-        mem_d(OPTS_OPTION_STR(OPTION_OUTPUT));
+        if(parser) parser_cleanup(parser);
+
+    /* free allocated option strings */
+    for (itr = 0; itr < OPTION_COUNT; itr++)
+        if (OPTS_OPTION_DUPED(itr))
+            mem_d(OPTS_OPTION_STR(itr));
+
     if (operators_free)
         mem_d((void*)operators);
 
     lex_cleanup();
-    stat_info();
 
+    if (!retval && compile_errors)
+        retval = 1;
     return retval;
 }