Enforcing string start/end check. See #1687

This commit is contained in:
Federico Fissore 2013-11-16 14:39:50 +01:00
parent 139dd6bf6a
commit e6698e4baa
3 changed files with 48 additions and 21 deletions

View File

@ -49,7 +49,7 @@ public class PdePreprocessor {
// stores number of included library headers written // stores number of included library headers written
// we always write one header: Arduino.h // we always write one header: Arduino.h
public int headerCount = 1; public int headerCount = 1;
// the prototypes that are generated by the preprocessor // the prototypes that are generated by the preprocessor
List<String> prototypes; List<String> prototypes;
@ -68,11 +68,11 @@ public class PdePreprocessor {
/** /**
* Setup a new preprocessor. * Setup a new preprocessor.
*/ */
public PdePreprocessor() { public PdePreprocessor() {
} }
/** /**
* Writes out the head of the c++ code generated for a sketch. * Writes out the head of the c++ code generated for a sketch.
* Called from processing.app.Sketch. * Called from processing.app.Sketch.
* @param program the concatenated code from all tabs containing pde-files * @param program the concatenated code from all tabs containing pde-files
*/ */
@ -115,7 +115,7 @@ public class PdePreprocessor {
// store # of prototypes so that line number reporting can be adjusted // store # of prototypes so that line number reporting can be adjusted
prototypeCount = prototypes.size(); prototypeCount = prototypes.size();
// do this after the program gets re-combobulated // do this after the program gets re-combobulated
this.program = program; this.program = program;
@ -164,7 +164,7 @@ public class PdePreprocessor {
/** /**
* preprocesses a pde file and writes out a cpp file into the specified * preprocesses a pde file and writes out a cpp file into the specified
* OutputStream * OutputStream
* *
* @param output * @param output
* @throws Exception * @throws Exception
*/ */
@ -177,10 +177,10 @@ public class PdePreprocessor {
// Write the pde program to the cpp file // Write the pde program to the cpp file
protected void writeProgram(PrintStream out, String program, List<String> prototypes) { protected void writeProgram(PrintStream out, String program, List<String> prototypes) {
int prototypeInsertionPoint = firstStatement(program); int prototypeInsertionPoint = firstStatement(program);
out.print(program.substring(0, prototypeInsertionPoint)); out.print(program.substring(0, prototypeInsertionPoint));
out.print("#include \"Arduino.h\"\n"); out.print("#include \"Arduino.h\"\n");
// print user defined prototypes // print user defined prototypes
for (int i = 0; i < prototypes.size(); i++) { for (int i = 0; i < prototypes.size(); i++) {
out.print(prototypes.get(i) + "\n"); out.print(prototypes.get(i) + "\n");
@ -214,7 +214,7 @@ public class PdePreprocessor {
public int firstStatement(String in) { public int firstStatement(String in) {
// whitespace // whitespace
String p = "\\s+"; String p = "\\s+";
// multi-line and single-line comment // multi-line and single-line comment
//p += "|" + "(//\\s*?$)|(/\\*\\s*?\\*/)"; //p += "|" + "(//\\s*?$)|(/\\*\\s*?\\*/)";
p += "|(/\\*[^*]*(?:\\*(?!/)[^*]*)*\\*/)|(//.*?$)"; p += "|(/\\*[^*]*(?:\\*(?!/)[^*]*)*\\*/)|(//.*?$)";
@ -222,7 +222,7 @@ public class PdePreprocessor {
// pre-processor directive // pre-processor directive
p += "|(#(?:\\\\\\n|.)*)"; p += "|(#(?:\\\\\\n|.)*)";
Pattern pattern = Pattern.compile(p, Pattern.MULTILINE); Pattern pattern = Pattern.compile(p, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(in); Matcher matcher = pattern.matcher(in);
int i = 0; int i = 0;
while (matcher.find()) { while (matcher.find()) {
@ -230,10 +230,10 @@ public class PdePreprocessor {
break; break;
i = matcher.end(); i = matcher.end();
} }
return i; return i;
} }
/** /**
* Strips comments, pre-processor directives, single- and double-quoted * Strips comments, pre-processor directives, single- and double-quoted
* strings from a string. * strings from a string.
@ -271,7 +271,7 @@ public class PdePreprocessor {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
int nesting = 0; int nesting = 0;
int start = 0; int start = 0;
// XXX: need to keep newlines inside braces so we can determine the line // XXX: need to keep newlines inside braces so we can determine the line
// number of a prototype // number of a prototype
for (int i = 0; i < in.length(); i++) { for (int i = 0; i < in.length(); i++) {
@ -288,12 +288,12 @@ public class PdePreprocessor {
} }
} }
} }
buffer.append(in.substring(start)); buffer.append(in.substring(start));
return buffer.toString(); return buffer.toString();
} }
public ArrayList<String> prototypes(String in) { public ArrayList<String> prototypes(String in) {
in = collapseBraces(strip(in)); in = collapseBraces(strip(in));
@ -301,19 +301,19 @@ public class PdePreprocessor {
// XXX: doesn't handle function pointers // XXX: doesn't handle function pointers
Pattern prototypePattern = Pattern.compile("[\\w\\[\\]\\*]+\\s+[&\\[\\]\\*\\w\\s]+\\([&,\\[\\]\\*\\w\\s]*\\)(?=\\s*;)"); Pattern prototypePattern = Pattern.compile("[\\w\\[\\]\\*]+\\s+[&\\[\\]\\*\\w\\s]+\\([&,\\[\\]\\*\\w\\s]*\\)(?=\\s*;)");
Pattern functionPattern = Pattern.compile("[\\w\\[\\]\\*]+\\s+[&\\[\\]\\*\\w\\s]+\\([&,\\[\\]\\*\\w\\s]*\\)(?=\\s*\\{)"); Pattern functionPattern = Pattern.compile("[\\w\\[\\]\\*]+\\s+[&\\[\\]\\*\\w\\s]+\\([&,\\[\\]\\*\\w\\s]*\\)(?=\\s*\\{)");
// Find already declared prototypes // Find already declared prototypes
ArrayList<String> prototypeMatches = new ArrayList<String>(); ArrayList<String> prototypeMatches = new ArrayList<String>();
Matcher prototypeMatcher = prototypePattern.matcher(in); Matcher prototypeMatcher = prototypePattern.matcher(in);
while (prototypeMatcher.find()) while (prototypeMatcher.find())
prototypeMatches.add(prototypeMatcher.group(0) + ";"); prototypeMatches.add(prototypeMatcher.group(0) + ";");
// Find all functions and generate prototypes for them // Find all functions and generate prototypes for them
ArrayList<String> functionMatches = new ArrayList<String>(); ArrayList<String> functionMatches = new ArrayList<String>();
Matcher functionMatcher = functionPattern.matcher(in); Matcher functionMatcher = functionPattern.matcher(in);
while (functionMatcher.find()) while (functionMatcher.find())
functionMatches.add(functionMatcher.group(0) + ";"); functionMatches.add(functionMatcher.group(0) + ";");
// Remove generated prototypes that exactly match ones found in the source file // Remove generated prototypes that exactly match ones found in the source file
for (int functionIndex=functionMatches.size() - 1; functionIndex >= 0; functionIndex--) { for (int functionIndex=functionMatches.size() - 1; functionIndex >= 0; functionIndex--) {
for (int prototypeIndex=0; prototypeIndex < prototypeMatches.size(); prototypeIndex++) { for (int prototypeIndex=0; prototypeIndex < prototypeMatches.size(); prototypeIndex++) {
@ -323,10 +323,29 @@ public class PdePreprocessor {
} }
} }
} }
return functionMatches; return functionMatches;
} }
private boolean isStartOrEndOfString(char p[], int index) {
if (p[index] != '\"') {
return false;
}
if (index == 0) {
return true;
}
if (p[index - 1] == '\\') {
return false;
}
if (index - 2 >= 0 && p[index - 2] == '\\') {
return true;
}
return true;
}
/** /**
* Replace all commented portions of a given String as spaces. * Replace all commented portions of a given String as spaces.
@ -338,7 +357,7 @@ public class PdePreprocessor {
int index = 0; int index = 0;
boolean insideString = false; boolean insideString = false;
while (index < p.length) { while (index < p.length) {
if (p[index] == '\"') { if (isStartOrEndOfString(p, index)) {
insideString = !insideString; insideString = !insideString;
} }
// for any double slash comments, ignore until the end of the line // for any double slash comments, ignore until the end of the line

View File

@ -1,6 +1,10 @@
void setup() { void setup() {
// put your setup code here, to run once: // put your setup code here, to run once:
// "comment with a double quote
/* \" other comment with double quote */
Serial.println("Accept: */*"); Serial.println("Accept: */*");
Serial.println("Accept: \" */*");
Serial.println("Accept: \\"); // */*");
} }
void loop() { void loop() {

View File

@ -1,6 +1,10 @@
void setup() { void setup() {
Serial.println( ); Serial.println( );
Serial.println( );
Serial.println( );
} }
void loop() { void loop() {