aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/anarres/cpp/Preprocessor.java30
-rw-r--r--src/test/java/org/anarres/cpp/PreprocessorTest.java21
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);