diff options
author | Shevek <[email protected]> | 2009-04-08 12:24:53 +0000 |
---|---|---|
committer | Shevek <[email protected]> | 2009-04-08 12:24:53 +0000 |
commit | 130f6b820dcb1a835b7bd9333f0cb9702793e262 (patch) | |
tree | 155f0f68ba65c56ca7d588ff9c33f0910a2ecc53 | |
parent | d46bffd718bb44013c981d4f29bd8d58b39bd3b6 (diff) |
fix widening macro case
-rw-r--r-- | src/java/org/anarres/cpp/Macro.java | 5 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/MacroTokenSource.java | 8 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Preprocessor.java | 3 | ||||
-rw-r--r-- | src/tests/org/anarres/cpp/PreprocessorTestCase.java | 19 |
4 files changed, 32 insertions, 3 deletions
diff --git a/src/java/org/anarres/cpp/Macro.java b/src/java/org/anarres/cpp/Macro.java index b62810b..ca024bc 100644 --- a/src/java/org/anarres/cpp/Macro.java +++ b/src/java/org/anarres/cpp/Macro.java @@ -139,12 +139,17 @@ public class Macro { return tokens; } + /* Paste tokens are inserted before the first of the two pasted + * tokens, so it's a kind of bytecode notation. This method + * swaps them around again. We know that there will never be two + * sequential paste tokens, so a boolean is sufficient. */ public String getText() { StringBuilder buf = new StringBuilder(); boolean paste = false; for (int i = 0; i < tokens.size(); i++) { Token tok = tokens.get(i); if (tok.getType() == Token.M_PASTE) { + assert paste == false : "Two sequential pastes."; paste = true; continue; } diff --git a/src/java/org/anarres/cpp/MacroTokenSource.java b/src/java/org/anarres/cpp/MacroTokenSource.java index 264a1a6..53b0932 100644 --- a/src/java/org/anarres/cpp/MacroTokenSource.java +++ b/src/java/org/anarres/cpp/MacroTokenSource.java @@ -89,9 +89,11 @@ import static org.anarres.cpp.Token.*; private Token stringify(Token pos, Argument arg) { StringBuilder buf = new StringBuilder(); concat(buf, arg); + // System.out.println("Concat: " + arg + " -> " + buf); StringBuilder str = new StringBuilder("\""); escape(str, buf); - str.append('\"'); + str.append("\""); + // System.out.println("Escape: " + buf + " -> " + str); return new Token(STRING, pos.getLine(), pos.getColumn(), str.toString(), buf.toString()); @@ -118,6 +120,7 @@ import static org.anarres.cpp.Token.*; break; } Token tok = tokens.next(); + // System.out.println("Paste " + tok); switch (tok.getType()) { case M_PASTE: /* One extra to paste, plus one because the @@ -140,9 +143,12 @@ import static org.anarres.cpp.Token.*; } /* Push and re-lex. */ + /* StringBuilder src = new StringBuilder(); escape(src, buf); StringLexerSource sl = new StringLexerSource(src.toString()); + */ + StringLexerSource sl = new StringLexerSource(buf.toString()); /* XXX Check that concatenation produces a valid token. */ diff --git a/src/java/org/anarres/cpp/Preprocessor.java b/src/java/org/anarres/cpp/Preprocessor.java index 3604abd..282c432 100644 --- a/src/java/org/anarres/cpp/Preprocessor.java +++ b/src/java/org/anarres/cpp/Preprocessor.java @@ -323,6 +323,7 @@ public class Preprocessor implements Closeable { * and the expansion. */ public void addMacro(Macro m) throws LexerException { + // System.out.println("Macro " + m); String name = m.getName(); /* Already handled as a source error in macro(). */ if ("defined".equals(name)) @@ -1582,6 +1583,8 @@ public class Preprocessor implements Closeable { /* From Olivier Chafik for Objective C? */ case '@': + /* The one remaining ASCII, might as well. */ + case '`': // case '#': diff --git a/src/tests/org/anarres/cpp/PreprocessorTestCase.java b/src/tests/org/anarres/cpp/PreprocessorTestCase.java index e07b085..63e4009 100644 --- a/src/tests/org/anarres/cpp/PreprocessorTestCase.java +++ b/src/tests/org/anarres/cpp/PreprocessorTestCase.java @@ -33,12 +33,22 @@ public class PreprocessorTestCase extends BaseTestCase { public String getText() { return t; } + public String toString() { + return getText(); + } } private static I I(String t) { return new I(t); } +/* + * When writing tests in this file, remember the preprocessor + * stashes NLs, so you won't see an immediate NL at the end of any + * input line. You will see it right before the next nonblank on + * the following input line. + */ + public void testPreprocessor() throws Exception { /* Magic macros */ testInput("line = __LINE__\n", @@ -98,7 +108,7 @@ testInput("one /* one */\n", NL, I("one"), WHITESPACE, CCOMMENT); /* Variadic macros. */ testInput("#define var(x...) a x b\n", NL); - testInput("var(e, f, g)", NL, + testInput("var(e, f, g)\n", NL, I("a"), WHITESPACE, I("e"), ',', WHITESPACE, I("f"), ',', WHITESPACE, @@ -106,6 +116,11 @@ testInput("one /* one */\n", NL, I("one"), WHITESPACE, CCOMMENT); I("b") ); + testInput("#define _Widen(x) L ## x\n", NL); + testInput("#define Widen(x) _Widen(x)\n", NL); + testInput("#define LStr(x) _Widen(#x)\n", NL); + testInput("LStr(x);\n", NL, I("L"), "x"); + writer.close(); Token t; @@ -131,7 +146,7 @@ testInput("one /* one */\n", NL, I("one"), WHITESPACE, CCOMMENT); } else if (v instanceof I) { if (t.getType() != IDENTIFIER) - fail("Expected IDENTIFIER, but got " + t); + fail("Expected IDENTIFIER " + v + ", but got " + t); assertEquals( ((I)v).getText(), (String)t.getText()); } else if (v instanceof Character) |