]> de.git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ftepp.c
Update license headers
[xonotic/gmqcc.git] / ftepp.c
diff --git a/ftepp.c b/ftepp.c
index 943411eef09c7f5707a2936ae2d5c676448bb360..d2c01df501d2a1b301d076b06226c3d2043ce5fd 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013
+ * Copyright (C) 2012, 2013, 2014, 2015
  *     Wolfgang Bumiller
  *     Dale Weiler
  *
@@ -498,10 +498,29 @@ static bool ftepp_define_body(ftepp_t *ftepp, ppmacro *macro)
     return true;
 }
 
+static const char *ftepp_math_constants[][2] = {
+    { "M_E",        "2.7182818284590452354"  }, /* e          */
+    { "M_LOG2E",    "1.4426950408889634074"  }, /* log_2 e    */
+    { "M_LOG10E",   "0.43429448190325182765" }, /* log_10 e   */
+    { "M_LN2",      "0.69314718055994530942" }, /* log_e 2    */
+    { "M_LN10",     "2.30258509299404568402" }, /* log_e 10   */
+    { "M_PI",       "3.14159265358979323846" }, /* pi         */
+    { "M_PI_2",     "1.57079632679489661923" }, /* pi/2       */
+    { "M_PI_4",     "0.78539816339744830962" }, /* pi/4       */
+    { "M_1_PI",     "0.31830988618379067154" }, /* 1/pi       */
+    { "M_2_PI",     "0.63661977236758134308" }, /* 2/pi       */
+    { "M_2_SQRTPI", "1.12837916709551257390" }, /* 2/sqrt(pi) */
+    { "M_SQRT2",    "1.41421356237309504880" }, /* sqrt(2)    */
+    { "M_SQRT1_2",  "0.70710678118654752440" }, /* 1/sqrt(2)  */
+    { "M_TAU",      "6.28318530717958647692" }  /* pi*2       */
+};
+
 static bool ftepp_define(ftepp_t *ftepp)
 {
     ppmacro *macro = NULL;
     size_t l = ftepp_ctx(ftepp).line;
+    size_t i;
+    bool   mathconstant = false;
 
     (void)ftepp_next(ftepp);
     if (!ftepp_skipspace(ftepp))
@@ -511,7 +530,25 @@ static bool ftepp_define(ftepp_t *ftepp)
         case TOKEN_IDENT:
         case TOKEN_TYPENAME:
         case TOKEN_KEYWORD:
+            if (OPTS_FLAG(FTEPP_MATHDEFS)) {
+                for (i = 0; i < GMQCC_ARRAY_COUNT(ftepp_math_constants); i++) {
+                    if (!strcmp(ftepp_math_constants[i][0], ftepp_tokval(ftepp))) {
+                        mathconstant = true;
+                        break;
+                    }
+                }
+            }
+
             macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp));
+
+            if (OPTS_FLAG(FTEPP_MATHDEFS)) {
+                /* user defined ones take precedence */
+                if (macro && mathconstant) {
+                    ftepp_macro_delete(ftepp, ftepp_tokval(ftepp));
+                    macro = NULL;
+                }
+            }
+
             if (macro && ftepp->output_on) {
                 if (ftepp_warn(ftepp, WARN_CPP, "redefining `%s`", ftepp_tokval(ftepp)))
                     return false;
@@ -666,9 +703,9 @@ static void ftepp_stringify_token(ftepp_t *ftepp, pptoken *token)
                 ++ch;
             }
             break;
-        case TOKEN_WHITE:
+        /*case TOKEN_WHITE:
             ftepp_out(ftepp, " ", false);
-            break;
+            break;*/
         case TOKEN_EOL:
             ftepp_out(ftepp, "\\n", false);
             break;
@@ -697,6 +734,7 @@ static void ftepp_recursion_footer(ftepp_t *ftepp)
     ftepp_out(ftepp, "\n#pragma pop(line)\n", false);
 }
 
+static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *params, bool resetline);
 static void ftepp_param_out(ftepp_t *ftepp, macroparam *param)
 {
     size_t   i;
@@ -705,8 +743,13 @@ static void ftepp_param_out(ftepp_t *ftepp, macroparam *param)
         out = param->tokens[i];
         if (out->token == TOKEN_EOL)
             ftepp_out(ftepp, "\n", false);
-        else
-            ftepp_out(ftepp, out->value, false);
+        else {
+            ppmacro *find = ftepp_macro_find(ftepp, out->value);
+            if (OPTS_FLAG(FTEPP_INDIRECT_EXPANSION) && find && !find->has_params)
+                ftepp_macro_expand(ftepp, find, NULL, false);
+            else
+                ftepp_out(ftepp, out->value, false);
+        }
     }
 }
 
@@ -726,6 +769,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
     lex_file *inlex;
 
     bool      old_inmacro;
+    bool      strip = false;
 
     int nextok;
 
@@ -790,6 +834,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
                     if (nextok == '#') {
                         /* raw concatenation */
                         ++o;
+                        strip = true;
                         break;
                     }
                     if ( (nextok == TOKEN_IDENT    ||
@@ -798,6 +843,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
                         macro_params_find(macro, macro->output[o+1]->value, &pi))
                     {
                         ++o;
+
                         ftepp_stringify(ftepp, &params[pi]);
                         break;
                     }
@@ -808,7 +854,15 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
                 ftepp_out(ftepp, "\n", false);
                 break;
             default:
-                ftepp_out(ftepp, out->value, false);
+                buffer = out->value;
+                #define buffer_stripable(X) ((X) == ' ' || (X) == '\t')
+                if (vec_size(macro->output) > o + 1 && macro->output[o+1]->token == '#' && buffer_stripable(*buffer))
+                    buffer++;
+                if (strip) {
+                    while (buffer_stripable(*buffer)) buffer++;
+                    strip = false;
+                }
+                ftepp_out(ftepp, buffer, false);
                 break;
         }
     }
@@ -1407,6 +1461,7 @@ static bool ftepp_include(ftepp_t *ftepp)
     lex_ctx_t ctx;
     char     lineno[128];
     char     *filename;
+    char     *parsename = NULL;
     char     *old_includename;
 
     (void)ftepp_next(ftepp);
@@ -1414,28 +1469,56 @@ static bool ftepp_include(ftepp_t *ftepp)
         return false;
 
     if (ftepp->token != TOKEN_STRINGCONST) {
-        ftepp_error(ftepp, "expected filename to include");
-        return false;
+        ppmacro *macro = ftepp_macro_find(ftepp, ftepp_tokval(ftepp));
+        if (macro) {
+            char *backup = ftepp->output_string;
+            ftepp->output_string = NULL;
+            if (ftepp_macro_expand(ftepp, macro, NULL, true)) {
+                parsename = util_strdup(ftepp->output_string);
+                vec_free(ftepp->output_string);
+                ftepp->output_string = backup;
+            } else {
+                ftepp->output_string = backup;
+                ftepp_error(ftepp, "expected filename to include");
+                return false;
+            }
+        } else if (OPTS_FLAG(FTEPP_PREDEFS)) {
+            /* Well it could be a predefine like __LINE__ */
+            char *(*predef)(ftepp_t*) = ftepp_predef(ftepp_tokval(ftepp));
+            if (predef) {
+                parsename = predef(ftepp);
+            } else {
+                ftepp_error(ftepp, "expected filename to include");
+                return false;
+            }
+        }
     }
 
     if (!ftepp->output_on) {
-        ftepp_next(ftepp);
+        (void)ftepp_next(ftepp);
         return true;
     }
 
-    ctx = ftepp_ctx(ftepp);
-
-    unescape(ftepp_tokval(ftepp), ftepp_tokval(ftepp));
+    if (parsename)
+        unescape(parsename, parsename);
+    else {
+        char *tokval = ftepp_tokval(ftepp);
+        unescape(tokval, tokval);
+        parsename = util_strdup(tokval);
+    }
 
+    ctx = ftepp_ctx(ftepp);
     ftepp_out(ftepp, "\n#pragma file(", false);
-    ftepp_out(ftepp, ftepp_tokval(ftepp), false);
+    ftepp_out(ftepp, parsename, false);
     ftepp_out(ftepp, ")\n#pragma line(1)\n", false);
 
-    filename = ftepp_include_find(ftepp, ftepp_tokval(ftepp));
+    filename = ftepp_include_find(ftepp, parsename);
     if (!filename) {
-        ftepp_error(ftepp, "failed to open include file `%s`", ftepp_tokval(ftepp));
+        ftepp_error(ftepp, "failed to open include file `%s`", parsename);
+        mem_d(parsename);
         return false;
     }
+    mem_d(parsename);
     inlex = lex_open(filename);
     if (!inlex) {
         ftepp_error(ftepp, "open failed on include file `%s`", filename);
@@ -1811,23 +1894,6 @@ void ftepp_add_macro(ftepp_t *ftepp, const char *name, const char *value) {
     vec_free  (create);
 }
 
-static const char *ftepp_math_constants[][2] = {
-    { "M_E",        "2.7182818284590452354"  }, /* e          */
-    { "M_LOG2E",    "1.4426950408889634074"  }, /* log_2 e    */
-    { "M_LOG10E",   "0.43429448190325182765" }, /* log_10 e   */
-    { "M_LN2",      "0.69314718055994530942" }, /* log_e 2    */
-    { "M_LN10",     "2.30258509299404568402" }, /* log_e 10   */
-    { "M_PI",       "3.14159265358979323846" }, /* pi         */
-    { "M_PI_2",     "1.57079632679489661923" }, /* pi/2       */
-    { "M_PI_4",     "0.78539816339744830962" }, /* pi/4       */
-    { "M_1_PI",     "0.31830988618379067154" }, /* 1/pi       */
-    { "M_2_PI",     "0.63661977236758134308" }, /* 2/pi       */
-    { "M_2_SQRTPI", "1.12837916709551257390" }, /* 2/sqrt(pi) */
-    { "M_SQRT2",    "1.41421356237309504880" }, /* sqrt(2)    */
-    { "M_SQRT1_2",  "0.70710678118654752440" }, /* 1/sqrt(2)  */
-    { "M_TAU",      "6.28318530717958647692" }  /* pi*2       */
-};
-
 ftepp_t *ftepp_create()
 {
     ftepp_t *ftepp;
@@ -1883,9 +1949,12 @@ ftepp_t *ftepp_create()
      */
     ftepp_add_macro(ftepp, "__NULL__", "nil");
 
-    /* add all the math constants */
-    for (i = 0; i < GMQCC_ARRAY_COUNT(ftepp_math_constants); i++)
-        ftepp_add_macro(ftepp, ftepp_math_constants[i][0], ftepp_math_constants[i][1]);
+    /* add all the math constants if they can be */
+    if (OPTS_FLAG(FTEPP_MATHDEFS)) {
+        for (i = 0; i < GMQCC_ARRAY_COUNT(ftepp_math_constants); i++)
+            if (!ftepp_macro_find(ftepp, ftepp_math_constants[i][0]))
+                ftepp_add_macro(ftepp, ftepp_math_constants[i][0], ftepp_math_constants[i][1]);
+    }
 
     return ftepp;
 }