Match C's preprocessor semantics for token pasting with '##'.

This commit is contained in:
Dale Weiler 2014-04-07 06:00:04 -04:00
parent 606d7ac110
commit f1650c42d9
3 changed files with 14 additions and 4 deletions

12
ftepp.c
View file

@ -763,6 +763,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
lex_file *inlex; lex_file *inlex;
bool old_inmacro; bool old_inmacro;
bool strip = false;
int nextok; int nextok;
@ -827,6 +828,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
if (nextok == '#') { if (nextok == '#') {
/* raw concatenation */ /* raw concatenation */
++o; ++o;
strip = true;
break; break;
} }
if ( (nextok == TOKEN_IDENT || if ( (nextok == TOKEN_IDENT ||
@ -835,6 +837,7 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
macro_params_find(macro, macro->output[o+1]->value, &pi)) macro_params_find(macro, macro->output[o+1]->value, &pi))
{ {
++o; ++o;
ftepp_stringify(ftepp, &params[pi]); ftepp_stringify(ftepp, &params[pi]);
break; break;
} }
@ -845,7 +848,14 @@ static bool ftepp_macro_expand(ftepp_t *ftepp, ppmacro *macro, macroparam *param
ftepp_out(ftepp, "\n", false); ftepp_out(ftepp, "\n", false);
break; break;
default: default:
ftepp_out(ftepp, out->value, false); buffer = out->value;
if (vec_size(macro->output) > o + 1 && macro->output[o+1]->token == '#')
buffer++;
if (strip) {
while (util_isspace(*buffer)) buffer++;
strip = false;
}
ftepp_out(ftepp, buffer, false);
break; break;
} }
} }

View file

@ -26,7 +26,7 @@
# define ALPHA(SEL) ALPHA_##SEL # define ALPHA(SEL) ALPHA_##SEL
# define ABC ALPHA(a)##ALPHA(b)##ALPHA(c) # define ABC ALPHA(a)ALPHA(b)ALPHA(c)
void() main = { void() main = {
if (ABC == "abc") if (ABC == "abc")

View file

@ -8,6 +8,6 @@ REDIR(CAT(hello, world), CAT(world, hello))
SCONS(hello, world) SCONS(hello, world)
#define FOO(X) X##X #define FOO(X) X##X
#define BAR(X) FOO(X)##FOO(X) #define BAR(X) FOO(X)FOO(X)
REDIR(BAR(hello),BAR(world)) REDIR(BAR(hello),BAR(world))