]> de.git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ftepp.c
Implement support for #include MACRO and #include __LINE__
[xonotic/gmqcc.git] / ftepp.c
diff --git a/ftepp.c b/ftepp.c
index 7947b918f2b5056f92041b8ae0bf80654c782090..d53fd9e8876338ec8880694301130aeb558aeac0 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -1461,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);
@@ -1468,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);