Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/org/anarres/cpp/Feature.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@ public enum Feature {
/** Supports lexing of objective-C. */
OBJCSYNTAX,
INCLUDENEXT,
/** Random extensions. */
GCC_SUFFIXES, /** Random extensions. */
PRAGMA_ONCE
}
37 changes: 31 additions & 6 deletions src/main/java/org/anarres/cpp/LexerSource.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ protected static BufferedReader toBufferedReader(@Nonnull Reader r) {
private boolean include;

private boolean digraphs;
private boolean gccSuffixes;

/* Unread. */
private int u0, u1;
Expand All @@ -60,6 +61,7 @@ public LexerSource(Reader r, boolean ppvalid) {
this.include = false;

this.digraphs = true;
this.gccSuffixes = false;

this.ucount = 0;

Expand All @@ -73,6 +75,7 @@ public LexerSource(Reader r, boolean ppvalid) {
/* pp */ void init(Preprocessor pp) {
super.init(pp);
this.digraphs = pp.getFeature(Feature.DIGRAPHS);
this.gccSuffixes = pp.getFeature(Feature.GCC_SUFFIXES);
this.reader.init(pp, this);
}

Expand Down Expand Up @@ -512,8 +515,20 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d)
text.append((char) d);
d = read();
} else if (d == 'L' || d == 'l') {
if ((flags & NumericValue.FF_SIZE) != 0)
warning("Multiple length suffixes after " + text);
if ((flags & NumericValue.FF_SIZE) != 0) {
// Added special code for GCC extended numeric types
if (gccSuffixes) {
if ((flags & NumericValue.F_UNSIGNED) != 0) {
flags |= NumericValue.F_GCC_ULONGLONG; // UL gcc type
} else if ((flags & NumericValue.F_DOUBLE) != 0) {
flags |= NumericValue.F_GCC_DEC128; // DL gcc type
} else {
warning("Multiple length suffixes after " + text);
}
} else {
warning("Multiple length suffixes after " + text);
}
}
text.append((char) d);
int e = read();
if (e == d) { // Case must match. Ll is Welsh.
Expand All @@ -531,14 +546,24 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d)
text.append((char) d);
d = read();
} else if (d == 'F' || d == 'f') {
if ((flags & NumericValue.FF_SIZE) != 0)
warning("Multiple length suffixes after " + text);
if ((flags & NumericValue.FF_SIZE) != 0) {
if (gccSuffixes && ((flags & NumericValue.F_DOUBLE) != 0)) {
flags |= NumericValue.F_GCC_DEC32; // GCC DF suffic
} else {
warning("Multiple length suffixes after " + text);
}
}
flags |= NumericValue.F_FLOAT;
text.append((char) d);
d = read();
} else if (d == 'D' || d == 'd') {
if ((flags & NumericValue.FF_SIZE) != 0)
warning("Multiple length suffixes after " + text);
if ((flags & NumericValue.FF_SIZE) != 0) {
if (gccSuffixes && ((flags & NumericValue.F_DOUBLE) != 0)) {
flags |= NumericValue.F_GCC_DEC64; // GCC DD suffic
} else {
warning("Multiple length suffixes after " + text);
}
}
flags |= NumericValue.F_DOUBLE;
text.append((char) d);
d = read();
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/anarres/cpp/NumericValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ public class NumericValue extends Number {
public static final int F_LONGLONG = 8;
public static final int F_FLOAT = 16;
public static final int F_DOUBLE = 32;
public static final int F_GCC_DEC64 = 64; // these are out of order, but I like
public static final int F_GCC_DEC128 = 128; // having GCC_DEC128 = 128...
public static final int F_GCC_DEC32 = 256;
public static final int F_GCC_ULONGLONG = 512;

public static final int FF_SIZE = F_INT | F_LONG | F_LONGLONG | F_FLOAT | F_DOUBLE;
public static final int FF_GCC_EXTENDED_SIZES = F_GCC_DEC32 | F_GCC_DEC64 | F_GCC_DEC128 | F_GCC_ULONGLONG;

private final int base;
private final String integer;
Expand Down
68 changes: 56 additions & 12 deletions src/main/java/org/anarres/cpp/Preprocessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public Preprocessor() {
this.features = EnumSet.noneOf(Feature.class);
this.warnings = EnumSet.noneOf(Warning.class);
this.filesystem = new JavaFileSystem();
this.listener = null;
this.listener = new DefaultPreprocessorListener();
}

public Preprocessor(@Nonnull Source initial) {
Expand Down Expand Up @@ -188,6 +188,12 @@ public void setListener(@Nonnull PreprocessorListener listener) {
s.init(this);
s = s.getParent();
}

// Make sure that any input sources know about this feature
for (Source source: inputs) {
source.init(this);
}

}

/**
Expand All @@ -214,6 +220,11 @@ public Set<Feature> getFeatures() {
*/
public void addFeature(@Nonnull Feature f) {
features.add(f);

// Make sure that any input sources know about this feature
for (Source source: inputs) {
source.init(this);
}
}

/**
Expand Down Expand Up @@ -376,6 +387,10 @@ public void addMacro(@Nonnull String name, @Nonnull String value)
try {
Macro m = new Macro(name);
StringLexerSource s = new StringLexerSource(value);

// In order to make sure that the source honors all the features of this preprocessor, we have to init it
s.init(this);

for (;;) {
Token tok = s.token();
if (tok.getType() == EOF)
Expand Down Expand Up @@ -701,9 +716,9 @@ private boolean macro(Macro m, Token orig)
throws IOException,
LexerException {
Token tok;
List<Argument> args;
List<Argument> args = new ArrayList<Argument>();

// System.out.println("pp: expanding " + m);
//System.out.println("pp: expanding " + m);
if (m.isFunctionLike()) {
OPEN:
for (;;) {
Expand Down Expand Up @@ -732,7 +747,6 @@ private boolean macro(Macro m, Token orig)
* This deals elegantly with the case that we have
* one empty arg. */
if (tok.getType() != ')' || m.getArgs() > 0) {
args = new ArrayList<Argument>();

Argument arg = new Argument();
int depth = 0;
Expand Down Expand Up @@ -832,12 +846,10 @@ private boolean macro(Macro m, Token orig)
// System.out.println("Macro " + m + " args " + args);
} else {
/* nargs == 0 and we (correctly) got () */
args = null;
}

} else {
/* Macro without args. */
args = null;
}

if (m == __LINE__) {
Expand Down Expand Up @@ -1153,13 +1165,22 @@ protected boolean include(@Nonnull VirtualFile file)
*
* @param path The list of virtual directories to search for the given name.
* @param name The name of the file to attempt to include.
* @param next
* @return true if the file was successfully included, false otherwise.
* @throws IOException if an I/O error occurs.
*/
protected boolean include(@Nonnull Iterable<String> path, @Nonnull String name)
protected boolean include(@Nonnull Iterable<String> path, @Nonnull String name, boolean next)
throws IOException {
for (String dir : path) {
VirtualFile file = getFileSystem().getFile(dir, name);

// Implement the next functionality here. This is actually
// not exactly right because it should be based on the include
// we are currently parsing, but it works _almost_ the same given
// how limited the usage of #include_next is.
if (includes.contains(file) && next) {
continue;
}
if (include(file))
return true;
}
Expand Down Expand Up @@ -1198,20 +1219,20 @@ private void include(
if (include(ifile))
return;
}
if (include(quoteincludepath, name))
if (include(quoteincludepath, name, next))
return;
} else {
int idx = name.indexOf('/');
if (idx != -1) {
String frameworkName = name.substring(0, idx);
String headerName = name.substring(idx + 1);
String headerPath = frameworkName + ".framework/Headers/" + headerName;
if (include(frameworkspath, headerPath))
if (include(frameworkspath, headerPath, next))
return;
}
}

if (include(sysincludepath, name))
if (include(sysincludepath, name, next))
return;

StringBuilder buf = new StringBuilder();
Expand Down Expand Up @@ -1265,9 +1286,33 @@ private Token include(boolean next)
name = (String) tok.getValue();
quoted = false;
tok = source_skipline(true);
} else if ((tok.getType() == '"') || (tok.getType() == '<')) {
// Handle the case where the actual include target was a macro that expanded into
// a string. We should have a stream of tokens than terminates in a quote
// Figure out the closing token
int closer = tok.getType() == '<' ? '>' : '"';
StringBuilder buf = new StringBuilder();
MACRO:
for (;;) {
tok = token_nonwhite();
switch (tok.getType()) {
case NL:
case EOF:
break MACRO;
default:
if (tok.getType() == closer) {
tok = token_nonwhite();
break MACRO;
} else {
buf.append(tok.getText());
}
}
}
name = buf.toString();
quoted = closer == '"';
} else {
error(tok,
"Expected string or header, not " + tok.getText());
"Expected string or header, not " + tok.getText() + " of type " + tok.getType() + " at " + tok.getLine() + "," + tok.getColumn());
switch (tok.getType()) {
case NL:
case EOF:
Expand Down Expand Up @@ -2165,7 +2210,6 @@ public String toString() {
return buf.toString();
}

@Override
public void close()
throws IOException {
{
Expand Down