]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ftepp.c
Moving all the global opts_ variables into a struct, now there's one global 'opts...
[xonotic/gmqcc.git] / ftepp.c
diff --git a/ftepp.c b/ftepp.c
index 3700fd39a49878c8742773ac18dc4fcf6e668f82..d28b19a7563a3b1fbf0cff8c0a503b3784efbcb4 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2012
  *     Wolfgang Bumiller
+ *     Dale Weiler 
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
  * this software and associated documentation files (the "Software"), to deal in
@@ -55,7 +56,6 @@ typedef struct {
 typedef struct {
     lex_file    *lex;
     int          token;
-    bool         newline;
     unsigned int errors;
 
     bool         output_on;
@@ -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)
@@ -1214,8 +1214,13 @@ static bool ftepp_hash(ftepp_t *ftepp)
                 break;
             }
             else {
-                ftepp_error(ftepp, "unrecognized preprocessor directive: `%s`", ftepp_tokval(ftepp));
-                return false;
+                if (ftepp->output_on) {
+                    ftepp_error(ftepp, "unrecognized preprocessor directive: `%s`", ftepp_tokval(ftepp));
+                    return false;
+                } else {
+                    ftepp_next(ftepp);
+                    break;
+                }
             }
             /* break; never reached */
         default:
@@ -1254,18 +1259,17 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
         if (ftepp->token >= TOKEN_EOF)
             break;
 #if 0
-        ftepp->newline = newline;
-        newline = false;
-#else
-        /* For the sake of FTE compatibility... FU, really */
-        ftepp->newline = newline = true;
+        newline = true;
 #endif
 
         switch (ftepp->token) {
             case TOKEN_KEYWORD:
             case TOKEN_IDENT:
             case TOKEN_TYPENAME:
-                macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp));
+                if (ftepp->output_on)
+                    macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp));
+                else
+                    macro = NULL;
                 if (!macro) {
                     ftepp_out(ftepp, ftepp_tokval(ftepp), false);
                     ftepp_next(ftepp);
@@ -1275,7 +1279,7 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
                     ftepp->token = TOKEN_ERROR;
                 break;
             case '#':
-                if (!ftepp->newline) {
+                if (!newline) {
                     ftepp_out(ftepp, ftepp_tokval(ftepp), false);
                     ftepp_next(ftepp);
                     break;
@@ -1295,7 +1299,13 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
                 ftepp_out(ftepp, "\n", true);
                 ftepp_next(ftepp);
                 break;
+            case TOKEN_WHITE:
+                /* same as default but don't set newline=false */
+                ftepp_out(ftepp, ftepp_tokval(ftepp), false);
+                ftepp_next(ftepp);
+                break;
             default:
+                newline = false;
                 ftepp_out(ftepp, ftepp_tokval(ftepp), false);
                 ftepp_next(ftepp);
                 break;
@@ -1306,8 +1316,7 @@ static bool ftepp_preprocess(ftepp_t *ftepp)
     vec_push(ftepp->output_string, 0);
     vec_shrinkby(ftepp->output_string, 1);
 
-    newline = ftepp->token == TOKEN_EOF;
-    return newline;
+    return (ftepp->token == TOKEN_EOF);
 }
 
 /* Like in parser.c - files keep the previous state so we have one global
@@ -1359,19 +1368,50 @@ bool ftepp_preprocess_string(const char *name, const char *str)
 
 bool ftepp_init()
 {
+    char minor[32];
+    char major[32];
+    char *verminor = NULL;
+    char *vermajor = NULL;
+
     ftepp = ftepp_new();
     if (!ftepp)
         return false;
 
+    memset(minor, 0, sizeof(minor));
+    memset(major, 0, sizeof(major));
+
     /* 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__");
-    else if (opts_standard == COMPILER_GMQCC)
+        /* 1.00 */
+        major[0] = '1';
+        minor[0] = '0';
+    } else if (opts.standard == COMPILER_GMQCC) {
         ftepp_add_define(NULL, "__STD_GMQCC__");
-    else if (opts_standard == COMPILER_QCC)
+        sprintf(major, "%d", GMQCC_VERSION_MAJOR);
+        sprintf(minor, "%d", GMQCC_VERSION_MINOR);
+    } else if (opts.standard == COMPILER_QCC) {
         ftepp_add_define(NULL, "__STD_QCC__");
+        /* 1.0 */
+        major[0] = '1';
+        minor[0] = '0';
+    }
+
+    vec_upload(verminor, "#define __STD_VERSION_MINOR__ \"", 31);
+    vec_upload(vermajor, "#define __STD_VERSION_MAJOR__ \"", 31);
+    vec_upload(verminor, minor, strlen(minor));
+    vec_upload(vermajor, major, strlen(major));
+    vec_push  (verminor, '"');
+    vec_push  (vermajor, '"');
+    vec_push  (verminor, 0);
+    vec_push  (vermajor, 0);
+
+    ftepp_preprocess_string("__builtin__", verminor);
+    ftepp_preprocess_string("__builtin__", vermajor);
 
+    vec_free(verminor);
+    vec_free(vermajor);
     return true;
 }