aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/trigraph.c1
-rw-r--r--src/java/org/anarres/cpp/JoinReader.java67
-rw-r--r--src/java/org/anarres/cpp/LexerSource.java71
-rw-r--r--src/java/org/anarres/cpp/Preprocessor.java19
-rw-r--r--src/java/org/anarres/cpp/Source.java16
-rw-r--r--src/tests/org/anarres/cpp/CppReaderTestCase.java2
-rw-r--r--src/tests/org/anarres/cpp/JoinReaderTestCase.java2
-rw-r--r--src/tests/org/anarres/cpp/LexerSourceTestCase.java2
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;",