From 529bf18bef0977c863e6e924e7e824243328e0f0 Mon Sep 17 00:00:00 2001 From: Jonas Lund Date: Thu, 22 May 2014 04:01:23 +0200 Subject: [PATCH 1/4] Fix misidentified identifiers --- src/main/java/org/anarres/cpp/LexerSource.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index 0b381b9..a6b3ca3 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -510,11 +510,14 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d) d = read(); } // This should probably be isPunct() || isWhite(). else if (Character.isLetter(d) || d == '_') { + // We've encountered an identifier initially identified as a number. + // Read it in completely and return it correctly. + while(Character.isLetterOrDigit(d) || d == '_') { + text.append((char)d); + d = read(); + } unread(d); - value.setFlags(flags); - return invalid(text, - "Invalid suffix \"" + (char) d - + "\" on numeric constant"); + return new Token(IDENTIFIER,text.toString()); } else { unread(d); value.setFlags(flags); From d67cee293da3e7235b4279f35f563cd223b00567 Mon Sep 17 00:00:00 2001 From: Jonas Lund Date: Thu, 22 May 2014 04:05:32 +0200 Subject: [PATCH 2/4] Added code to handle #import directives, ?: conditional expressions and a couple of small bugfixes --- .../java/org/anarres/cpp/Preprocessor.java | 45 ++++++++++++++----- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index 0ad1538..949ae77 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -119,6 +119,9 @@ public String getName() { private VirtualFileSystem filesystem; private PreprocessorListener listener; + HashSet quotedImports=new HashSet(); + HashSet sysImports=new HashSet(); + public Preprocessor() { this.inputs = new ArrayList(); @@ -737,6 +740,7 @@ private boolean macro(Macro m, Token orig) case WHITESPACE: case CCOMMENT: case CPPCOMMENT: + case NL: /* Avoid duplicating spaces. */ space = true; break; @@ -1146,7 +1150,7 @@ private void include( } @Nonnull - private Token include(boolean next) + private Token include(boolean next,boolean isImport) throws IOException, LexerException { LexerSource lexer = (LexerSource) source; @@ -1196,13 +1200,20 @@ private Token include(boolean next) } } - /* Do the inclusion. */ - include(source.getPath(), tok.getLine(), name, quoted, next); + HashSet importMap=quoted?quotedImports:sysImports; + if (!isImport || !importMap.contains(name)) { + /* Do the inclusion. */ + include(source.getPath(), tok.getLine(), name, quoted, next); + + importMap.add(name); - /* 'tok' is the 'nl' after the include. We use it after the - * #line directive. */ - if (getFeature(Feature.LINEMARKERS)) - return line_token(1, source.getName(), " 1"); + /* 'tok' is the 'nl' after the include. We use it after the + * #line directive. */ + if (getFeature(Feature.LINEMARKERS)) + return line_token(1, source.getName(), " 1"); + } else { + warning(tok,"Already imported:"+name); + } return tok; } finally { lexer.setInclude(false); @@ -1494,7 +1505,7 @@ private long expr(int priority) tok = expr_token(); if (tok.getType() != ')') { expr_untoken(tok); - error(tok, "missing ) in expression"); + error(tok, "missing ) in expression at "+tok); return 0; } break; @@ -1609,7 +1620,17 @@ private long expr(int priority) break; case '?': - /* XXX Handle this? */ + { + tok = expr_token(); + if (tok.getType() != ':') { + expr_untoken(tok); + error(tok, "missing : in conditional expression"); + return 0; + } + long falseResult=expr(0); + lhs = (lhs!=0) ? rhs : falseResult; + } + break; default: error(op, @@ -1781,6 +1802,7 @@ private Token _token() case RSH: case RSH_EQ: case STRING: + case SQSTRING : case XOR_EQ: return tok; @@ -1851,11 +1873,12 @@ private Token _token() return undef(); // break; + case PP_IMPORT : case PP_INCLUDE: if (!isActive()) return source_skipline(false); else - return include(false); + return include(false,ppcmd==PP_IMPORT); // break; case PP_INCLUDE_NEXT: if (!isActive()) @@ -1866,7 +1889,7 @@ private Token _token() ); return source_skipline(false); } - return include(true); + return include(true,false); // break; case PP_WARNING: From 8bc6a31dacbe024dc2d972ef3297b59692f25fa1 Mon Sep 17 00:00:00 2001 From: Jonas Lund Date: Fri, 23 May 2014 17:33:03 +0200 Subject: [PATCH 3/4] Added actual code for including files from frameworks (similiar placement to the nativelibs4java version) --- .../java/org/anarres/cpp/Preprocessor.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java index 949ae77..180684f 100644 --- a/src/main/java/org/anarres/cpp/Preprocessor.java +++ b/src/main/java/org/anarres/cpp/Preprocessor.java @@ -1131,6 +1131,25 @@ private void include( } if (include(quoteincludepath, name)) return; + } else { + int forwardSlashPos=name.indexOf('/'); + if (forwardSlashPos!=-1) { + String frameworkName=name.substring(0,forwardSlashPos); + String includeName=name.substring(forwardSlashPos+1); + for (String frameworkPath:frameworkspath) { + File frameworkFile=new File(frameworkPath,frameworkName+".framework"); + if (!frameworkFile.exists() || !frameworkFile.isDirectory()) + continue; + File frameworkHeadersFile=new File(frameworkFile,"Headers"); + if (!frameworkHeadersFile.exists() || !frameworkHeadersFile.isDirectory()) + continue; + File includeFile=new File(frameworkHeadersFile,includeName); + if (!includeFile.exists() || !includeFile.isFile()) + continue; + if (include(filesystem.getFile(includeFile.getCanonicalPath()))) + return; + } + } } if (include(sysincludepath, name)) From a4ce2c8055cbeb9fdc834ce5b94353dedd03533d Mon Sep 17 00:00:00 2001 From: Jonas Lund Date: Fri, 23 May 2014 18:36:54 +0200 Subject: [PATCH 4/4] Return invalid number tokens as such instead of identifiers, macro expansions will still work --- src/main/java/org/anarres/cpp/LexerSource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java index a6b3ca3..98e146b 100644 --- a/src/main/java/org/anarres/cpp/LexerSource.java +++ b/src/main/java/org/anarres/cpp/LexerSource.java @@ -510,14 +510,14 @@ private Token _number_suffix(StringBuilder text, NumericValue value, int d) d = read(); } // This should probably be isPunct() || isWhite(). else if (Character.isLetter(d) || d == '_') { - // We've encountered an identifier initially identified as a number. - // Read it in completely and return it correctly. + // We've encountered something initially identified as a number. + // Read in the rest of this token as an identifer but return it as an invalid. while(Character.isLetterOrDigit(d) || d == '_') { text.append((char)d); d = read(); } unread(d); - return new Token(IDENTIFIER,text.toString()); + return new Token(INVALID,text.toString()); } else { unread(d); value.setFlags(flags);