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

View File

@ -1,6 +1,10 @@
void setup() {
// 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: \\"); // */*");
}
void loop() {

View File

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