diff options
-rw-r--r-- | src/main/java/org/anarres/cpp/Preprocessor.java | 30 | ||||
-rw-r--r-- | src/test/java/org/anarres/cpp/PreprocessorTest.java | 21 |
2 files changed, 42 insertions, 9 deletions
diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index f4e93cd..af3b896 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -784,15 +784,27 @@ public class Preprocessor implements Closeable { * is stripped from arguments. */ if (args.size() != m.getArgs()) { - error(tok, - "macro " + m.getName() - + " has " + m.getArgs() + " parameters " - + "but given " + args.size() + " args"); - /* We could replay the arg tokens, but I - * note that GNU cpp does exactly what we do, - * i.e. output the macro name and chew the args. - */ - return false; + if (m.isVariadic()) { + if (args.size() == m.getArgs() - 1) { + args.add(new Argument()); + } else { + error(tok, + "variadic macro " + m.getName() + + " has at least " + (m.getArgs() - 1) + " parameters " + + "but given " + args.size() + " args"); + return false; + } + } else { + error(tok, + "macro " + m.getName() + + " has " + m.getArgs() + " parameters " + + "but given " + args.size() + " args"); + /* We could replay the arg tokens, but I + * note that GNU cpp does exactly what we do, + * i.e. output the macro name and chew the args. + */ + return false; + } } for (Argument a : args) { diff --git a/src/test/java/org/anarres/cpp/PreprocessorTest.java b/src/test/java/org/anarres/cpp/PreprocessorTest.java index 80d0cba..13bd944 100644 --- a/src/test/java/org/anarres/cpp/PreprocessorTest.java +++ b/src/test/java/org/anarres/cpp/PreprocessorTest.java @@ -132,6 +132,14 @@ public class PreprocessorTest { I("__VA_ARGS__"), WHITESPACE, // __VA_ARGS__ is not expanded in this case. I("b") ); + /* Missing arguments are fine. */ + testInput("var()\n", NL, + I("a"), WHITESPACE, + /* No expansion for 'x'. */ WHITESPACE, + I("__VA_ARGS__"), WHITESPACE, + I("b") + ); + /* Variadic macros with anonymous args. */ testInput("#define var2(x, ...) a x __VA_ARGS__ e\n", NL); testInput("var2(b, c, d)\n", NL, @@ -141,6 +149,14 @@ public class PreprocessorTest { I("d"), WHITESPACE, I("e") ); + /* Missing arguments are fine. */ + testInput("var2(b)\n", NL, + I("a"), WHITESPACE, + I("b"), WHITESPACE, + /* No expansion for '__VA_ARGS__'. */ WHITESPACE, + I("e") + ); + testInput("#define var3(...) a __VA_ARGS__ d\n", NL); testInput("var3(b, c)\n", NL, I("a"), WHITESPACE, @@ -148,6 +164,11 @@ public class PreprocessorTest { I("c"), WHITESPACE, I("d") ); + testInput("var3()\n", NL, + I("a"), WHITESPACE, + /* No expansion for '__VA_ARGS__'. */ WHITESPACE, + I("d") + ); testInput("#define _Widen(x) L ## x\n", NL); testInput("#define Widen(x) _Widen(x)\n", NL); |