Implement support for indirect macro expansions in the preprocessor. This closes #36
authorDale Weiler <weilercdale@gmail.com>
Sat, 27 Sep 2014 05:48:03 +0000 (01:48 -0400)
committerDale Weiler <weilercdale@gmail.com>
Sat, 27 Sep 2014 05:48:03 +0000 (01:48 -0400)
doc/gmqcc.1
ftepp.c
gmqcc.ini.example
opts.def
test.c
tests/ppindirectexpand.qc [new file with mode: 0644]
tests/ppindirectexpand.tmpl [new file with mode: 0644]

index 50bce0e..566346a 100644 (file)
@@ -426,6 +426,25 @@ M_SQRT2
 M_SQRT1_2
 M_TAU
 .Ed
+.It Fl f Ns Cm ftepp-indirect-expansion
+Enable indirect macro expansion. This only works in combination
+with '-fftepp' and is currently not included by '-std=fteqcc'.
+Enabling this behavior will allow the preprocessor to operate more
+like the standard C preprocessor in that it will allow arguments
+of macros which are macro-expanded to be substituted into the
+definition of the macro.
+.Pp
+As an example:
+.Bd -literal -offset indent
+#define STR1(x) #x
+#define STR2(x) STR1(x)
+#define THE_ANSWER 42
+#define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
+
+.Ed
+With this enabled, an expansion of THE_ANSWER_STR will yield
+the string "42". With this disabled an expansion of THE_ANSWER_STR
+will yield "THE_ANSWER"
 .It Fl f Ns Cm relaxed-switch
 Allow switch cases to use non constant variables.
 .It Fl f Ns Cm short-logic
diff --git a/ftepp.c b/ftepp.c
index 8f45275..7b24c64 100644 (file)
--- a/ftepp.c
+++ b/ftepp.c
@@ -734,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;
@@ -742,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);
+        }
     }
 }
 
index ceacf28..adc6624 100644 (file)
     FTEPP_MATHDEFS = false
 
 
+    #Enable indirect macro expansion. This only works in combination
+    #with '-fftepp' and is currently not included by '-std=fteqcc'.
+    #Enabling this behavior will allow the preprocessor to operate more
+    #like the standard C preprocessor in that it will allow arguments
+    #of macros which are macro-expanded to be substituted into the
+    #definition of the macro. As an example:
+    #
+    #   #define STR1(x) #x
+    #   #define STR2(x) STR1(x)
+    #   #define THE_ANSWER 42
+    #   #define THE_ANSWER_STR STR2(THE_ANSWER) /* "42" */
+    #
+    #With this enabled, an expansion of THE_ANSWER_STR will yield
+    #the string "42". With this disabled an expansion of THE_ANSWER_STR
+    #will yield "THE_ANSWER"
+
+    FTEPP_INDIRECT_EXPANSION = false
+
+
     #Allow switch cases to use non constant variables.
 
     RELAXED_SWITCH = true
index 1157194..5a4746c 100644 (file)
--- a/opts.def
+++ b/opts.def
@@ -32,6 +32,7 @@
     GMQCC_DEFINE_FLAG(FTEPP)
     GMQCC_DEFINE_FLAG(FTEPP_PREDEFS)
     GMQCC_DEFINE_FLAG(FTEPP_MATHDEFS)
+    GMQCC_DEFINE_FLAG(FTEPP_INDIRECT_EXPANSION)
     GMQCC_DEFINE_FLAG(RELAXED_SWITCH)
     GMQCC_DEFINE_FLAG(SHORT_LOGIC)
     GMQCC_DEFINE_FLAG(PERL_LOGIC)
diff --git a/test.c b/test.c
index 23fbfb6..bf42985 100644 (file)
--- a/test.c
+++ b/test.c
@@ -806,19 +806,21 @@ static bool task_propagate(const char *curdir, size_t *pad, const char *defs) {
                 } else {
                     /* Preprocessing (qcflags mean shit all here we don't allow them) */
                     if (tmpl->testflags && !strcmp(tmpl->testflags, "-no-defs")) {
-                        util_snprintf(buf, sizeof(buf), "%s -E %s/%s -o %s",
+                        util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s -o %s",
                             task_bins[TASK_COMPILE],
                             directories[i],
                             tmpl->sourcefile,
+                            tmpl->compileflags,
                             tmpl->tempfilename
                         );
                     } else {
-                        util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s -o %s",
+                        util_snprintf(buf, sizeof(buf), "%s -E %s/%s %s/%s %s -o %s",
                             task_bins[TASK_COMPILE],
                             curdir,
                             defs,
                             directories[i],
                             tmpl->sourcefile,
+                            tmpl->compileflags,
                             tmpl->tempfilename
                         );
                     }
diff --git a/tests/ppindirectexpand.qc b/tests/ppindirectexpand.qc
new file mode 100644 (file)
index 0000000..09333f9
--- /dev/null
@@ -0,0 +1,6 @@
+#define STR1(x) #x
+#define STR2(x) STR1(x)
+#define THE_ANSWER 42
+#define THE_ANSWER_STR STR2(THE_ANSWER)
+
+THE_ANSWER_STR
diff --git a/tests/ppindirectexpand.tmpl b/tests/ppindirectexpand.tmpl
new file mode 100644 (file)
index 0000000..8813f65
--- /dev/null
@@ -0,0 +1,7 @@
+I: ppindirectexpand.qc
+D: test preprocessor indirect macro expansion
+T: -pp
+C: -fftepp-indirect-expansion -std=gmqcc
+F: -no-defs
+M: "42"
+