Search in sources :

Example 6 with SketchException

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)));
            }
        }
    }
}
Also used : SketchException(processing.app.SketchException)

Example 7 with SketchException

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();
}
Also used : SketchException(processing.app.SketchException) StringList(processing.data.StringList) MatchResult(java.util.regex.MatchResult)

Aggregations

SketchException (processing.app.SketchException)7 SketchCode (processing.app.SketchCode)2 StringList (processing.data.StringList)2 AST (antlr.collections.AST)1 Point (java.awt.Point)1 java.awt.print (java.awt.print)1 MatchResult (java.util.regex.MatchResult)1 ZipFile (java.util.zip.ZipFile)1 BuildException (org.apache.tools.ant.BuildException)1 Library (processing.app.Library)1 PreprocessorResult (processing.mode.java.preproc.PreprocessorResult)1 SurfaceInfo (processing.mode.java.preproc.SurfaceInfo)1