From f7736110d200ccb3f592cf3e73e712ab2618b1e7 Mon Sep 17 00:00:00 2001 From: datadiode Date: Thu, 29 Aug 2024 17:30:01 +0200 Subject: [PATCH] Expand varargs when referenced as per the nonstandard gcc/clang extension for empty varargs, to yield gcc-like behavior also in cases where varargs isn't empty (#66, #130) --- simplecpp.cpp | 8 ++++++++ test.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/simplecpp.cpp b/simplecpp.cpp index d5abb31..9adbfd2 100755 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1895,6 +1895,14 @@ namespace simplecpp { if (sameline(tok, tok->next) && tok->next && tok->next->op == '#' && tok->next->next && tok->next->next->op == '#') { if (!sameline(tok, tok->next->next->next)) throw invalidHashHash::unexpectedNewline(tok->location, name()); + if (variadic && tok->op == ',' && tok->next->next->next->str() == args.back()) { + Token *const comma = newMacroToken(tok->str(), loc, isReplaced(expandedmacros), tok); + output->push_back(comma); + tok = expandToken(output, loc, tok->next->next->next, macros, expandedmacros, parametertokens2); + if (output->back() == comma) + output->deleteToken(comma); + continue; + } TokenList new_output(files); if (!expandArg(&new_output, tok, parametertokens2)) output->push_back(newMacroToken(tok->str(), loc, isReplaced(expandedmacros), tok)); diff --git a/test.cpp b/test.cpp index b5850ba..f340ff8 100644 --- a/test.cpp +++ b/test.cpp @@ -1074,6 +1074,16 @@ static void hashhash4() // nonstandard gcc/clang extension for empty varargs ASSERT_EQUALS("\n\na ( 1 ) ;", preprocess(code)); } +static void hashhash4a() +{ + const char code[] = "#define GETMYID(a) ((a))+1\n" + "#define FIGHT_FOO(c, ...) foo(c, ##__VA_ARGS__)\n" + "#define FIGHT_BAR(c, args...) bar(c, ##args)\n" + "FIGHT_FOO(1, GETMYID(a));\n" + "FIGHT_BAR(1, GETMYID(b));"; + ASSERT_EQUALS("\n\n\nfoo ( 1 , ( ( a ) ) + 1 ) ;\nbar ( 1 , ( ( b ) ) + 1 ) ;", preprocess(code)); +} + static void hashhash5() { ASSERT_EQUALS("x1", preprocess("x##__LINE__")); @@ -2909,6 +2919,7 @@ int main(int argc, char **argv) TEST_CASE(hashhash2); TEST_CASE(hashhash3); TEST_CASE(hashhash4); + TEST_CASE(hashhash4a); // #66, #130 TEST_CASE(hashhash5); TEST_CASE(hashhash6); TEST_CASE(hashhash7); // # ## # (C standard; 6.10.3.3.p4)