aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/org/anarres/cpp
diff options
context:
space:
mode:
authorShevek <[email protected]>2014-09-09 04:16:03 -0700
committerShevek <[email protected]>2014-09-09 04:16:03 -0700
commitb6a44c31015a71f4624b3ab0b36503a90023c244 (patch)
tree70e953547493a674053926a1c2895678474bb3c0 /src/main/java/org/anarres/cpp
parent09e951892e640874756690d3e9f7d07613b4f67b (diff)
Fix #16: NPE on unterminated ifdef.
Diffstat (limited to 'src/main/java/org/anarres/cpp')
-rw-r--r--src/main/java/org/anarres/cpp/MacroTokenSource.java7
-rw-r--r--src/main/java/org/anarres/cpp/Preprocessor.java40
2 files changed, 35 insertions, 12 deletions
diff --git a/src/main/java/org/anarres/cpp/MacroTokenSource.java b/src/main/java/org/anarres/cpp/MacroTokenSource.java
index 516e4f2..92317eb 100644
--- a/src/main/java/org/anarres/cpp/MacroTokenSource.java
+++ b/src/main/java/org/anarres/cpp/MacroTokenSource.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.util.Iterator;
import java.util.List;
+import javax.annotation.Nonnull;
import static org.anarres.cpp.Token.*;
/* This source should always be active, since we don't expand macros
@@ -50,7 +51,11 @@ import static org.anarres.cpp.Token.*;
}
/* XXX Called from Preprocessor [ugly]. */
- /* pp */ static void escape(StringBuilder buf, CharSequence cs) {
+ /* pp */ static void escape(@Nonnull StringBuilder buf, @Nonnull CharSequence cs) {
+ if (buf == null)
+ throw new NullPointerException("Buffer was null.");
+ if (cs == null)
+ throw new NullPointerException("CharSequence was null.");
for (int i = 0; i < cs.length(); i++) {
char c = cs.charAt(i);
switch (c) {
diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java
index 0ad1538..f96eb4a 100644
--- a/src/main/java/org/anarres/cpp/Preprocessor.java
+++ b/src/main/java/org/anarres/cpp/Preprocessor.java
@@ -495,6 +495,7 @@ public class Preprocessor implements Closeable {
* @see #push_source(Source,boolean)
* @see #pop_source()
*/
+ @CheckForNull
protected Source getSource() {
return source;
}
@@ -552,18 +553,30 @@ public class Preprocessor implements Closeable {
pop_source(false);
}
+ @Nonnull
+ private Token next_source() {
+ if (inputs.isEmpty())
+ return new Token(EOF);
+ Source s = inputs.remove(0);
+ push_source(s, true);
+ return line_token(s.getLine(), s.getName(), " 1");
+ }
+
/* Source tokens */
private Token source_token;
/* XXX Make this include the NL, and make all cpp directives eat
* their own NL. */
@Nonnull
- private Token line_token(int line, String name, String extra) {
+ private Token line_token(int line, @CheckForNull String name, @Nonnull String extra) {
StringBuilder buf = new StringBuilder();
buf.append("#line ").append(line)
.append(" \"");
/* XXX This call to escape(name) is correct but ugly. */
- MacroTokenSource.escape(buf, name);
+ if (name == null)
+ buf.append("<unnamed-source>");
+ else
+ MacroTokenSource.escape(buf, name);
buf.append("\"").append(extra).append("\n");
return new Token(P_LINE, line, 0, buf.toString(), null);
}
@@ -583,13 +596,10 @@ public class Preprocessor implements Closeable {
for (;;) {
Source s = getSource();
if (s == null) {
- if (inputs.isEmpty())
- return new Token(EOF);
- Source t = inputs.remove(0);
- push_source(t, true);
- if (getFeature(Feature.LINEMARKERS))
- return line_token(t.getLine(), t.getName(), " 1");
- continue;
+ Token t = next_source();
+ if (t.getType() == P_LINE && !getFeature(Feature.LINEMARKERS))
+ continue;
+ return t;
}
Token tok = s.token();
/* XXX Refactor with skipline() */
@@ -1675,13 +1685,21 @@ public class Preprocessor implements Closeable {
for (;;) {
Token tok;
if (!isActive()) {
+ Source s = getSource();
+ if (s == null) {
+ Token t = next_source();
+ if (t.getType() == P_LINE && !getFeature(Feature.LINEMARKERS))
+ continue;
+ return t;
+ }
+
try {
/* XXX Tell lexer to ignore warnings. */
- source.setActive(false);
+ s.setActive(false);
tok = source_token();
} finally {
/* XXX Tell lexer to stop ignoring warnings. */
- source.setActive(true);
+ s.setActive(true);
}
switch (tok.getType()) {
case HASH: