diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/input/trigraph.c | 1 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/JoinReader.java | 67 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/LexerSource.java | 71 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Preprocessor.java | 19 | ||||
-rw-r--r-- | src/java/org/anarres/cpp/Source.java | 16 | ||||
-rw-r--r-- | src/tests/org/anarres/cpp/CppReaderTestCase.java | 2 | ||||
-rw-r--r-- | src/tests/org/anarres/cpp/JoinReaderTestCase.java | 2 | ||||
-rw-r--r-- | src/tests/org/anarres/cpp/LexerSourceTestCase.java | 2 |
8 files changed, 140 insertions, 40 deletions
diff --git a/src/input/trigraph.c b/src/input/trigraph.c new file mode 100644 index 0000000..89615fe --- /dev/null +++ b/src/input/trigraph.c @@ -0,0 +1 @@ +??/ diff --git a/src/java/org/anarres/cpp/JoinReader.java b/src/java/org/anarres/cpp/JoinReader.java index 298f49d..13c706a 100644 --- a/src/java/org/anarres/cpp/JoinReader.java +++ b/src/java/org/anarres/cpp/JoinReader.java @@ -23,10 +23,13 @@ import java.io.Reader; import java.io.PushbackReader; import java.io.IOException; -/* pp */ class JoinReader extends Reader { +/* pp */ class JoinReader /* extends Reader */ { private Reader in; + private PreprocessorListener listener; + private LexerSource source; private boolean trigraphs; + private boolean warnings; private int newlines; private boolean flushnl; @@ -46,8 +49,16 @@ import java.io.IOException; this(in, false); } - public void setTrigraphs(boolean enable) { + public void setTrigraphs(boolean enable, boolean warnings) { this.trigraphs = enable; + this.warnings = warnings; + } + + /* pp */ void init(Preprocessor pp, LexerSource s) { + this.listener = pp.getListener(); + this.source = s; + setTrigraphs(pp.getFeature(Feature.TRIGRAPHS), + pp.getWarning(Warning.TRIGRAPHS)); } private int __read() throws IOException { @@ -61,22 +72,47 @@ import java.io.IOException; unget[uptr++] = c; } - private int _read() throws IOException { + protected void warning(String msg) + throws LexerException { + if (source != null) + source.warning(msg); + else + throw new LexerException(msg); + } + + private char trigraph(char raw, char repl) + throws IOException, LexerException { + if (trigraphs) { + if (warnings) + warning("trigraph ??" + raw + " converted to " + repl); + return repl; + } + else { + if (warnings) + warning("trigraph ??" + raw + " ignored"); + _unread(raw); + _unread('?'); + return '?'; + } + } + + private int _read() + throws IOException, LexerException { int c = __read(); - if (c == '?' && trigraphs) { + if (c == '?' && (trigraphs || warnings)) { int d = __read(); if (d == '?') { int e = __read(); switch (e) { - case '(': return '['; - case ')': return ']'; - case '<': return '{'; - case '>': return '}'; - case '=': return '#'; - case '/': return '\\'; - case '\'': return '^'; - case '!': return '|'; - case '-': return '~'; + case '(': return trigraph('(', '['); + case ')': return trigraph(')', ']'); + case '<': return trigraph('<', '{'); + case '>': return trigraph('>', '}'); + case '=': return trigraph('=', '#'); + case '/': return trigraph('/', '\\'); + case '\'': return trigraph('\'', '^'); + case '!': return trigraph('!', '|'); + case '-': return trigraph('-', '~'); } _unread(e); } @@ -85,7 +121,8 @@ import java.io.IOException; return c; } - public int read() throws IOException { + public int read() + throws IOException, LexerException { if (flushnl) { if (newlines > 0) { newlines--; @@ -134,7 +171,7 @@ import java.io.IOException; } public int read(char cbuf[], int off, int len) - throws IOException { + throws IOException, LexerException { for (int i = 0; i < len; i++) { int ch = read(); if (ch == -1) diff --git a/src/java/org/anarres/cpp/LexerSource.java b/src/java/org/anarres/cpp/LexerSource.java index c3ee982..11a8538 100644 --- a/src/java/org/anarres/cpp/LexerSource.java +++ b/src/java/org/anarres/cpp/LexerSource.java @@ -32,14 +32,17 @@ import static org.anarres.cpp.Token.*; public class LexerSource extends Source { private static final boolean DEBUG = false; - private JoinReader _reader; - private PushbackReader reader; + private JoinReader reader; private boolean ppvalid; private boolean bol; private boolean include; private boolean digraphs; + /* Unread. */ + private int u0, u1; + private int ucount; + private int line; private int column; private int lastcolumn; @@ -49,14 +52,15 @@ public class LexerSource extends Source { * false in StringLexerSource, * true in FileLexerSource */ public LexerSource(Reader r, boolean ppvalid) { - this._reader = new JoinReader(r); - this.reader = new PushbackReader(_reader, 5); + this.reader = new JoinReader(r); this.ppvalid = ppvalid; this.bol = true; this.include = false; this.digraphs = true; + this.ucount = 0; + this.line = 1; this.column = 0; this.lastcolumn = -1; @@ -64,10 +68,10 @@ public class LexerSource extends Source { } @Override - public void setFeatures(Set<Feature> features) { - super.setFeatures(features); - this.digraphs = features.contains(Feature.DIGRAPHS); - this._reader.setTrigraphs(features.contains(Feature.TRIGRAPHS)); + /* pp */ void init(Preprocessor pp) { + super.init(pp); + this.digraphs = pp.getFeature(Feature.DIGRAPHS); + this.reader.init(pp, this); } @Override @@ -75,6 +79,7 @@ public class LexerSource extends Source { return line; } + @Override public int getColumn() { return column; } @@ -102,12 +107,14 @@ public class LexerSource extends Source { super.warning(_l, _c, msg); } - private final void error(String msg) + /* Allow JoinReader to call this. */ + /* pp */ final void error(String msg) throws LexerException { _error(msg, true); } - private final void warning(String msg) + /* Allow JoinReader to call this. */ + /* pp */ final void warning(String msg) throws LexerException { _error(msg, false); } @@ -142,7 +149,19 @@ public class LexerSource extends Source { } - private int read() throws IOException { + private int read() + throws IOException, + LexerException { + assert ucount <= 2 : "Illegal ucount: " + ucount; + switch (ucount) { + case 2: + ucount = 1; + return u1; + case 1: + ucount = 0; + return u0; + } + int c = reader.read(); switch (c) { case '\r': @@ -199,12 +218,27 @@ public class LexerSource extends Source { else { column--; } - reader.unread(c); + switch (ucount) { + case 0: + u0 = c; + ucount = 1; + break; + case 1: + u1 = c; + ucount = 2; + break; + default: + throw new IllegalStateException( + "Cannot unget another character!" + ); + } + // reader.unread(c); } } private Token ccomment() - throws IOException { + throws IOException, + LexerException { StringBuilder text = new StringBuilder("/*"); int d; do { @@ -221,7 +255,8 @@ public class LexerSource extends Source { } private Token cppcomment() - throws IOException { + throws IOException, + LexerException { StringBuilder text = new StringBuilder("//"); int d = read(); while (!isLineSeparator(d)) { @@ -370,7 +405,8 @@ public class LexerSource extends Source { } private void number_suffix(StringBuilder text, int d) - throws IOException { + throws IOException, + LexerException { if (d == 'U') { text.append((char)d); d = read(); @@ -485,7 +521,8 @@ public class LexerSource extends Source { /* No token processed by cond() contains a newline. */ private Token cond(char c, int yes, int no) - throws IOException { + throws IOException, + LexerException { int d = read(); if (c == d) return new Token(yes); @@ -593,7 +630,7 @@ public class LexerSource extends Source { } d = read(); if (d != ':') { - unread(d); + unread(d); // Unread 2 chars here. unread('%'); tok = new Token('#'); // digraph break PASTE; diff --git a/src/java/org/anarres/cpp/Preprocessor.java b/src/java/org/anarres/cpp/Preprocessor.java index 59f8991..9c3bfa8 100644 --- a/src/java/org/anarres/cpp/Preprocessor.java +++ b/src/java/org/anarres/cpp/Preprocessor.java @@ -93,11 +93,16 @@ public class Preprocessor { this.listener = listener; Source s = source; while (s != null) { - s.setListener(listener); + // s.setListener(listener); + s.init(this); s = s.getParent(); } } + public PreprocessorListener getListener() { + return listener; + } + public Set<Feature> getFeatures() { return features; } @@ -110,6 +115,10 @@ public class Preprocessor { features.addAll(f); } + public boolean getFeature(Feature f) { + return features.contains(f); + } + public Set<Warning> getWarnings() { return warnings; } @@ -122,7 +131,12 @@ public class Preprocessor { warnings.addAll(w); } + public boolean getWarning(Warning w) { + return warnings.contains(w); + } + public void addInput(Source source) { + source.init(this); if (this.source == null) { this.source = source; /* We need to get a \n onto the end of this somehow. */ @@ -309,8 +323,9 @@ public class Preprocessor { * @see #pop_source() */ protected void push_source(Source source, boolean autopop) { + source.init(this); source.setParent(this.source, autopop); - source.setListener(listener); + // source.setListener(listener); if (listener != null) listener.handleSourceChange(this.source, "suspend"); this.source = source; diff --git a/src/java/org/anarres/cpp/Source.java b/src/java/org/anarres/cpp/Source.java index 0bc1476..e7a6d2d 100644 --- a/src/java/org/anarres/cpp/Source.java +++ b/src/java/org/anarres/cpp/Source.java @@ -98,11 +98,14 @@ public abstract class Source implements Iterable<Token> { return parent; } - public void setListener(PreprocessorListener listener) { - this.listener = listener; + // @OverrideMustInvoke + /* pp */ void init(Preprocessor pp) { + setListener(pp.getListener()); } - public void setFeatures(Set<Feature> features) { + /* Actually just used for testing. */ + public void setListener(PreprocessorListener pl) { + this.listener = pl; } /** @@ -141,6 +144,13 @@ public abstract class Source implements Iterable<Token> { return parent.getLine(); } + public int getColumn() { + Source parent = getParent(); + if (parent == null) + return 0; + return parent.getColumn(); + } + /* pp */ boolean isExpanding(Macro m) { Source parent = getParent(); if (parent != null) diff --git a/src/tests/org/anarres/cpp/CppReaderTestCase.java b/src/tests/org/anarres/cpp/CppReaderTestCase.java index 92ade21..df3aeb5 100644 --- a/src/tests/org/anarres/cpp/CppReaderTestCase.java +++ b/src/tests/org/anarres/cpp/CppReaderTestCase.java @@ -26,7 +26,7 @@ public class CppReaderTestCase extends BaseTestCase implements Test { } } - public void testJoinReader() + public void testCppReader() throws Exception { testCppReader("#include <test0.h>\n", "ab"); } diff --git a/src/tests/org/anarres/cpp/JoinReaderTestCase.java b/src/tests/org/anarres/cpp/JoinReaderTestCase.java index 2b99c2f..6c11449 100644 --- a/src/tests/org/anarres/cpp/JoinReaderTestCase.java +++ b/src/tests/org/anarres/cpp/JoinReaderTestCase.java @@ -14,7 +14,7 @@ public class JoinReaderTestCase extends BaseTestCase implements Test { for (int i = 0; i < out.length(); i++) { int c = j.read(); - // System.out.println("At offset " + i + ": " + (char)c); + System.out.println("At offset " + i + ": " + (char)c); assertEquals((char)out.charAt(i), c); } assertEquals(-1, j.read()); diff --git a/src/tests/org/anarres/cpp/LexerSourceTestCase.java b/src/tests/org/anarres/cpp/LexerSourceTestCase.java index 2d61e28..7fa788c 100644 --- a/src/tests/org/anarres/cpp/LexerSourceTestCase.java +++ b/src/tests/org/anarres/cpp/LexerSourceTestCase.java @@ -26,7 +26,7 @@ public class LexerSourceTestCase extends BaseTestCase implements Test { assertEquals(EOF, s.token().getType()); } - public void testJoinReader() + public void testLexerSource() throws Exception { testLexerSource("int a = 5;", |