@@ -49,7 +49,7 @@ public class PdePreprocessor {
4949 // stores number of included library headers written
5050 // we always write one header: Arduino.h
5151 public int headerCount = 1 ;
52-
52+
5353 // the prototypes that are generated by the preprocessor
5454 List <String > prototypes ;
5555
@@ -68,11 +68,11 @@ public class PdePreprocessor {
6868 /**
6969 * Setup a new preprocessor.
7070 */
71- public PdePreprocessor () {
71+ public PdePreprocessor () {
7272 }
7373
7474 /**
75- * Writes out the head of the c++ code generated for a sketch.
75+ * Writes out the head of the c++ code generated for a sketch.
7676 * Called from processing.app.Sketch.
7777 * @param program the concatenated code from all tabs containing pde-files
7878 */
@@ -115,7 +115,7 @@ public int writePrefix(String program)
115115
116116 // store # of prototypes so that line number reporting can be adjusted
117117 prototypeCount = prototypes .size ();
118-
118+
119119 // do this after the program gets re-combobulated
120120 this .program = program ;
121121
@@ -164,7 +164,7 @@ static String substituteUnicode(String program) {
164164 /**
165165 * preprocesses a pde file and writes out a cpp file into the specified
166166 * OutputStream
167- *
167+ *
168168 * @param output
169169 * @throws Exception
170170 */
@@ -177,10 +177,10 @@ public void write(OutputStream output) throws Exception {
177177 // Write the pde program to the cpp file
178178 protected void writeProgram (PrintStream out , String program , List <String > prototypes ) {
179179 int prototypeInsertionPoint = firstStatement (program );
180-
180+
181181 out .print (program .substring (0 , prototypeInsertionPoint ));
182- out .print ("#include \" Arduino.h\" \n " );
183-
182+ out .print ("#include \" Arduino.h\" \n " );
183+
184184 // print user defined prototypes
185185 for (int i = 0 ; i < prototypes .size (); i ++) {
186186 out .print (prototypes .get (i ) + "\n " );
@@ -214,26 +214,26 @@ public List<String> getExtraImports() {
214214 public int firstStatement (String in ) {
215215 // whitespace
216216 String p = "\\ s+" ;
217-
217+
218218 // multi-line and single-line comment
219219 //p += "|" + "(//\\s*?$)|(/\\*\\s*?\\*/)";
220220 p += "|(/\\ *[^*]*(?:\\ *(?!/)[^*]*)*\\ */)|(//.*?$)" ;
221221
222222 // pre-processor directive
223223 p += "|(#(?:\\ \\ \\ n|.)*)" ;
224224 Pattern pattern = Pattern .compile (p , Pattern .MULTILINE );
225-
225+
226226 Matcher matcher = pattern .matcher (in );
227227 int i = 0 ;
228228 while (matcher .find ()) {
229229 if (matcher .start ()!=i )
230230 break ;
231231 i = matcher .end ();
232232 }
233-
233+
234234 return i ;
235235 }
236-
236+
237237 /**
238238 * Strips comments, pre-processor directives, single- and double-quoted
239239 * strings from a string.
@@ -271,7 +271,7 @@ private String collapseBraces(String in) {
271271 StringBuffer buffer = new StringBuffer ();
272272 int nesting = 0 ;
273273 int start = 0 ;
274-
274+
275275 // XXX: need to keep newlines inside braces so we can determine the line
276276 // number of a prototype
277277 for (int i = 0 ; i < in .length (); i ++) {
@@ -288,32 +288,32 @@ private String collapseBraces(String in) {
288288 }
289289 }
290290 }
291-
291+
292292 buffer .append (in .substring (start ));
293-
293+
294294 return buffer .toString ();
295295 }
296-
296+
297297 public ArrayList <String > prototypes (String in ) {
298298 in = collapseBraces (strip (in ));
299299
300300 // XXX: doesn't handle ... varargs
301301 // XXX: doesn't handle function pointers
302302 Pattern prototypePattern = Pattern .compile ("[\\ w\\ [\\ ]\\ *]+\\ s+[&\\ [\\ ]\\ *\\ w\\ s]+\\ ([&,\\ [\\ ]\\ *\\ w\\ s]*\\ )(?=\\ s*;)" );
303303 Pattern functionPattern = Pattern .compile ("[\\ w\\ [\\ ]\\ *]+\\ s+[&\\ [\\ ]\\ *\\ w\\ s]+\\ ([&,\\ [\\ ]\\ *\\ w\\ s]*\\ )(?=\\ s*\\ {)" );
304-
304+
305305 // Find already declared prototypes
306306 ArrayList <String > prototypeMatches = new ArrayList <String >();
307307 Matcher prototypeMatcher = prototypePattern .matcher (in );
308308 while (prototypeMatcher .find ())
309309 prototypeMatches .add (prototypeMatcher .group (0 ) + ";" );
310-
310+
311311 // Find all functions and generate prototypes for them
312312 ArrayList <String > functionMatches = new ArrayList <String >();
313313 Matcher functionMatcher = functionPattern .matcher (in );
314314 while (functionMatcher .find ())
315315 functionMatches .add (functionMatcher .group (0 ) + ";" );
316-
316+
317317 // Remove generated prototypes that exactly match ones found in the source file
318318 for (int functionIndex =functionMatches .size () - 1 ; functionIndex >= 0 ; functionIndex --) {
319319 for (int prototypeIndex =0 ; prototypeIndex < prototypeMatches .size (); prototypeIndex ++) {
@@ -323,10 +323,29 @@ public ArrayList<String> prototypes(String in) {
323323 }
324324 }
325325 }
326-
326+
327327 return functionMatches ;
328328 }
329329
330+ private boolean isStartOrEndOfString (char p [], int index ) {
331+ if (p [index ] != '\"' ) {
332+ return false ;
333+ }
334+
335+ if (index == 0 ) {
336+ return true ;
337+ }
338+
339+ if (p [index - 1 ] == '\\' ) {
340+ return false ;
341+ }
342+
343+ if (index - 2 >= 0 && p [index - 2 ] == '\\' ) {
344+ return true ;
345+ }
346+
347+ return true ;
348+ }
330349
331350 /**
332351 * Replace all commented portions of a given String as spaces.
@@ -338,7 +357,7 @@ public String scrubComments(String what) {
338357 int index = 0 ;
339358 boolean insideString = false ;
340359 while (index < p .length ) {
341- if (p [ index ] == '\"' ) {
360+ if (isStartOrEndOfString ( p , index ) ) {
342361 insideString = !insideString ;
343362 }
344363 // for any double slash comments, ignore until the end of the line
0 commit comments