use of processing.app.SketchException in project processing by processing.
the class PdePreprocessor method checkForUnterminatedMultilineComment.
private static void checkForUnterminatedMultilineComment(final String program) throws SketchException {
final int length = program.length();
for (int i = 0; i < length; i++) {
// for any double slash comments, ignore until the end of the line
if ((program.charAt(i) == '/') && (i < length - 1) && (program.charAt(i + 1) == '/')) {
i += 2;
while ((i < length) && (program.charAt(i) != '\n')) {
i++;
}
// check to see if this is the start of a new multiline comment.
// if it is, then make sure it's actually terminated somewhere.
} else if ((program.charAt(i) == '/') && (i < length - 1) && (program.charAt(i + 1) == '*')) {
final int startOfComment = i;
i += 2;
boolean terminated = false;
while (i < length - 1) {
if ((program.charAt(i) == '*') && (program.charAt(i + 1) == '/')) {
i += 2;
terminated = true;
break;
} else {
i++;
}
}
if (!terminated) {
throw new SketchException("Unclosed /* comment */", 0, countNewlines(program.substring(0, startOfComment)));
}
} else if (program.charAt(i) == '"') {
final int stringStart = i;
boolean terminated = false;
for (i++; i < length; i++) {
final char c = program.charAt(i);
if (c == '"') {
terminated = true;
break;
} else if (c == '\\') {
if (i == length - 1) {
break;
}
i++;
} else if (c == '\n') {
break;
}
}
if (!terminated) {
throw new SketchException("Unterminated string constant", 0, countNewlines(program.substring(0, stringStart)));
}
} else if (program.charAt(i) == '\'') {
// step over the initial quote
i++;
if (i >= length) {
throw new SketchException("Unterminated character constant (after initial quote)", 0, countNewlines(program.substring(0, i)));
}
boolean escaped = false;
if (program.charAt(i) == '\\') {
// step over the backslash
i++;
escaped = true;
}
if (i >= length) {
throw new SketchException("Unterminated character constant (after backslash)", 0, countNewlines(program.substring(0, i)));
}
if (escaped && program.charAt(i) == 'u') {
// unicode escape sequence?
// step over the u
i++;
//i += 4; // and the four digit unicode constant
for (int j = 0; j < 4; j++) {
if (UNICODE_ESCAPES.indexOf(program.charAt(i)) == -1) {
throw new SketchException("Bad or unfinished \\uXXXX sequence " + "(malformed Unicode character constant)", 0, countNewlines(program.substring(0, i)));
}
i++;
}
} else {
// step over a single character
i++;
}
if (i >= length) {
throw new SketchException("Unterminated character constant", 0, countNewlines(program.substring(0, i)));
}
if (program.charAt(i) != '\'') {
throw new SketchException("Badly formed character constant " + "(expecting quote, got " + program.charAt(i) + ")", 0, countNewlines(program.substring(0, i)));
}
}
}
}
use of processing.app.SketchException in project processing by processing.
the class PdePreprocessor method parseSketchSize.
/**
* Parse a chunk of code and extract the size() command and its contents.
* Also goes after fullScreen(), smooth(), and noSmooth().
* @param code The code from the main tab in the sketch
* @param fussy true if it should show an error message if bad size()
* @return null if there was an error, otherwise an array (might contain some/all nulls)
*/
public static SurfaceInfo parseSketchSize(String code, boolean fussy) throws SketchException {
// This matches against any uses of the size() function, whether numbers
// or variables or whatever. This way, no warning is shown if size() isn't
// actually used in the applet, which is the case especially for anyone
// who is cutting/pasting from the reference.
// String scrubbed = scrubComments(sketch.getCode(0).getProgram());
// String[] matches = PApplet.match(scrubbed, SIZE_REGEX);
// String[] matches = PApplet.match(scrubComments(code), SIZE_REGEX);
/*
1. no size() or fullScreen() method at all
will use the non-overridden settings() method in PApplet
2. size() or fullScreen() found inside setup() (static mode sketch or otherwise)
make sure that it uses numbers (or displayWidth/Height), copy into settings
3. size() or fullScreen() already in settings()
don't mess with the sketch, don't insert any defaults
really only need to deal with situation #2.. nothing to be done for 1 and 3
*/
// if static mode sketch, all we need is regex
// easy proxy for static in this case is whether [^\s]void\s is present
String uncommented = scrubComments(code);
Mode mode = parseMode(uncommented);
String searchArea = null;
switch(mode) {
case JAVA:
// it's up to the user
searchArea = null;
break;
case ACTIVE:
// active mode, limit scope to setup
// Find setup() in global scope
MatchResult setupMatch = findInCurrentScope(VOID_SETUP_REGEX, uncommented);
if (setupMatch != null) {
int start = uncommented.indexOf("{", setupMatch.end());
if (start >= 0) {
// Find a closing brace
MatchResult match = findInCurrentScope(CLOSING_BRACE, uncommented, start);
if (match != null) {
searchArea = uncommented.substring(start + 1, match.end() - 1);
} else {
throw new SketchException("Found a { that's missing a matching }", false);
}
}
}
break;
case STATIC:
// static mode, look everywhere
searchArea = uncommented;
break;
}
if (searchArea == null) {
return new SurfaceInfo();
}
StringList extraStatements = new StringList();
// First look for noSmooth() or smooth(N) so we can hoist it into settings.
String[] smoothContents = matchMethod("smooth", searchArea);
if (smoothContents != null) {
extraStatements.append(smoothContents[0]);
}
String[] noContents = matchMethod("noSmooth", searchArea);
if (noContents != null) {
if (extraStatements.size() != 0) {
throw new SketchException("smooth() and noSmooth() cannot be used in the same sketch");
} else {
extraStatements.append(noContents[0]);
}
}
String[] pixelDensityContents = matchMethod("pixelDensity", searchArea);
if (pixelDensityContents != null) {
extraStatements.append(pixelDensityContents[0]);
} else {
pixelDensityContents = matchDensityMess(searchArea);
if (pixelDensityContents != null) {
extraStatements.append(pixelDensityContents[0]);
}
}
String[] sizeContents = matchMethod("size", searchArea);
String[] fullContents = matchMethod("fullScreen", searchArea);
// throw a confusing state exception error that one "can't be used here".
if (sizeContents != null && fullContents != null) {
throw new SketchException("size() and fullScreen() cannot be used in the same sketch", false);
}
//String[] contents = PApplet.match(searchArea, SIZE_CONTENTS_REGEX);
if (sizeContents != null) {
StringList args = breakCommas(sizeContents[1]);
SurfaceInfo info = new SurfaceInfo();
// info.statement = sizeContents[0];
info.addStatement(sizeContents[0]);
info.width = args.get(0).trim();
info.height = args.get(1).trim();
info.renderer = (args.size() >= 3) ? args.get(2).trim() : null;
info.path = (args.size() >= 4) ? args.get(3).trim() : null;
if (info.hasOldSyntax()) {
// return null;
throw new SketchException("Please update your code to continue.", false);
}
if (info.hasBadSize() && fussy) {
// found a reference to size, but it didn't seem to contain numbers
final String message = "The size of this sketch could not be determined from your code.\n" + "Use only numbers (not variables) for the size() command.\n" + "Read the size() reference for more details.";
Messages.showWarning("Could not find sketch size", message, null);
// return null;
throw new SketchException("Please fix the size() line to continue.", false);
}
info.addStatements(extraStatements);
info.checkEmpty();
return info;
//return new String[] { contents[0], width, height, renderer, path };
}
//contents = PApplet.match(searchArea, FULL_SCREEN_CONTENTS_REGEX);
if (fullContents != null) {
SurfaceInfo info = new SurfaceInfo();
// info.statement = fullContents[0];
info.addStatement(fullContents[0]);
StringList args = breakCommas(fullContents[1]);
if (args.size() > 0) {
// might have no args
String args0 = args.get(0).trim();
if (args.size() == 1) {
// could be either fullScreen(1) or fullScreen(P2D), figure out which
if (args0.equals("SPAN") || PApplet.parseInt(args0, -1) != -1) {
// it's the display parameter, not the renderer
info.display = args0;
} else {
info.renderer = args0;
}
} else if (args.size() == 2) {
info.renderer = args0;
info.display = args.get(1).trim();
} else {
throw new SketchException("That's too many parameters for fullScreen()");
}
}
info.width = "displayWidth";
info.height = "displayHeight";
// if (extraStatements.size() != 0) {
// info.statement += extraStatements.join(" ");
// }
info.addStatements(extraStatements);
info.checkEmpty();
return info;
}
// need to pull out the noSmooth() and smooth(N) methods.
if (extraStatements.size() != 0) {
SurfaceInfo info = new SurfaceInfo();
// info.statement = extraStatements.join(" ");
info.addStatements(extraStatements);
return info;
}
//return new String[] { null, null, null, null, null };
return new SurfaceInfo();
}
Aggregations