summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShevek <[email protected]>2009-04-08 12:24:53 +0000
committerShevek <[email protected]>2009-04-08 12:24:53 +0000
commit130f6b820dcb1a835b7bd9333f0cb9702793e262 (patch)
tree155f0f68ba65c56ca7d588ff9c33f0910a2ecc53
parentd46bffd718bb44013c981d4f29bd8d58b39bd3b6 (diff)
fix widening macro case
-rw-r--r--src/java/org/anarres/cpp/Macro.java5
-rw-r--r--src/java/org/anarres/cpp/MacroTokenSource.java8
-rw-r--r--src/java/org/anarres/cpp/Preprocessor.java3
-rw-r--r--src/tests/org/anarres/cpp/PreprocessorTestCase.java19
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)