From 2208136403121ecd81704b026daa371823bb61bb Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 27 Sep 2014 01:48:03 -0400 Subject: [PATCH] Implement support for indirect macro expansions in the preprocessor. This closes #36 --- doc/gmqcc.1 | 19 +++++++++++++++++++ ftepp.c | 10 ++++++++-- gmqcc.ini.example | 19 +++++++++++++++++++ opts.def | 1 + test.c | 6 ++++-- tests/ppindirectexpand.qc | 6 ++++++ tests/ppindirectexpand.tmpl | 7 +++++++ 7 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 tests/ppindirectexpand.qc create mode 100644 tests/ppindirectexpand.tmpl diff --git a/doc/gmqcc.1 b/doc/gmqcc.1 index 50bce0e..566346a 100644 --- a/doc/gmqcc.1 +++ b/doc/gmqcc.1 @@ -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 --- 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); + } } } diff --git a/gmqcc.ini.example b/gmqcc.ini.example index ceacf28..adc6624 100644 --- a/gmqcc.ini.example +++ b/gmqcc.ini.example @@ -84,6 +84,25 @@ 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 diff --git a/opts.def b/opts.def index 1157194..5a4746c 100644 --- 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 --- 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 index 0000000..09333f9 --- /dev/null +++ b/tests/ppindirectexpand.qc @@ -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 index 0000000..8813f65 --- /dev/null +++ b/tests/ppindirectexpand.tmpl @@ -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" + -- 2.39.2