X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java index 1ff0619..d7c2618 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Scanner.java @@ -22,19 +22,16 @@ import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral; public class Scanner implements IScanner, ITerminalSymbols { - /* APIs ares - - getNextToken() which return the current type of the token - (this value is not memorized by the scanner) - - getCurrentTokenSource() which provides with the token "REAL" source - (aka all unicode have been transformed into a correct char) - - sourceStart gives the position into the stream - - currentPosition-1 gives the sourceEnd position into the stream - */ - - // 1.4 feature + /* + * APIs ares - getNextToken() which return the current type of the token (this value is not memorized by the scanner) - + * getCurrentTokenSource() which provides with the token "REAL" source (aka all unicode have been transformed into a correct + * char) - sourceStart gives the position into the stream - currentPosition-1 gives the sourceEnd position into the stream + */ + + // 1.4 feature private boolean assertMode; public boolean useAssertAsAnIndentifier = false; - //flag indicating if processed source contains occurrences of keyword assert + //flag indicating if processed source contains occurrences of keyword assert public boolean containsAssertKeyword = false; public boolean recordLineSeparator; @@ -70,7 +67,7 @@ public class Scanner implements IScanner, ITerminalSymbols { //diet parsing support - jump over some method body when requested public boolean diet = false; - //support for the poor-line-debuggers .... + //support for the poor-line-debuggers .... //remember the position of the cr/lf public int[] lineEnds = new int[250]; public int linePtr = -1; @@ -123,7 +120,7 @@ public class Scanner implements IScanner, ITerminalSymbols { static final int TableSize = 30, InternalTableSize = 6; //30*6 = 180 entries public static final int OptimizedLength = 6; - public /*static*/ + public /* static */ final char[][][][] charArray_length = new char[OptimizedLength][TableSize][InternalTableSize][]; // support for detecting non-externalized string literals int currentLineNr = -1; @@ -138,7 +135,7 @@ public class Scanner implements IScanner, ITerminalSymbols { public boolean checkNonExternalizedStringLiterals = true; public boolean wasNonExternalizedStringLiteral = false; - /*static*/ { + /* static */ { for (int i = 0; i < 6; i++) { for (int j = 0; j < TableSize; j++) { for (int k = 0; k < InternalTableSize; k++) { @@ -153,17 +150,17 @@ public class Scanner implements IScanner, ITerminalSymbols { public static final int SquareBracket = 1; public static final int CurlyBracket = 2; public static final int BracketKinds = 3; - - // task tag support - public char[][] foundTaskTags = null; - public char[][] foundTaskMessages; - public char[][] foundTaskPriorities = null; - public int[][] foundTaskPositions; - public int foundTaskCount = 0; - public char[][] taskTags = null; - public char[][] taskPriorities = null; - - public static final boolean DEBUG = false; + + // task tag support + public char[][] foundTaskTags = null; + public char[][] foundTaskMessages; + public char[][] foundTaskPriorities = null; + public int[][] foundTaskPositions; + public int foundTaskCount = 0; + public char[][] taskTags = null; + public char[][] taskPriorities = null; + + public static final boolean DEBUG = true; public Scanner() { this(false, false); @@ -173,23 +170,21 @@ public class Scanner implements IScanner, ITerminalSymbols { } /** - * Determines if the specified character is - * permissible as the first character in a PHP identifier + * Determines if the specified character is permissible as the first character in a PHP identifier */ public static boolean isPHPIdentifierStart(char ch) { return Character.isLetter(ch) || (ch == '_') || (0x7F <= ch && ch <= 0xFF); } /** - * Determines if the specified character may be part of a PHP identifier as - * other than the first character + * Determines if the specified character may be part of a PHP identifier as other than the first character */ public static boolean isPHPIdentifierPart(char ch) { return Character.isLetterOrDigit(ch) || (ch == '_') || (0x7F <= ch && ch <= 0xFF); } public final boolean atEnd() { - // This code is not relevant if source is + // This code is not relevant if source is // Only a part of the real stream input return source.length == currentPosition; @@ -302,10 +297,9 @@ public class Scanner implements IScanner, ITerminalSymbols { /* * Search the source position corresponding to the end of a given line number - * - * Line numbers are 1-based, and relative to the scanner initialPosition. - * Character positions are 0-based. - * + * + * Line numbers are 1-based, and relative to the scanner initialPosition. Character positions are 0-based. + * * In case the given line number is inconsistent, answers -1. */ public final int getLineEnd(int lineNumber) { @@ -324,12 +318,11 @@ public class Scanner implements IScanner, ITerminalSymbols { } /** * Search the source position corresponding to the beginning of a given line number - * - * Line numbers are 1-based, and relative to the scanner initialPosition. - * Character positions are 0-based. - * - * e.g. getLineStart(1) --> 0 i.e. first line starts at character 0. - * + * + * Line numbers are 1-based, and relative to the scanner initialPosition. Character positions are 0-based. + * + * e.g. getLineStart(1) --> 0 i.e. first line starts at character 0. + * * In case the given line number is inconsistent, answers -1. */ public final int getLineStart(int lineNumber) { @@ -355,7 +348,7 @@ public class Scanner implements IScanner, ITerminalSymbols { //Both previous lines are true if the currentCharacter is == to the testedChar //On false, no side effect has occured. - //ALL getNextChar.... ARE OPTIMIZED COPIES + //ALL getNextChar.... ARE OPTIMIZED COPIES int temp = currentPosition; try { @@ -432,7 +425,7 @@ public class Scanner implements IScanner, ITerminalSymbols { //Both previous lines are true if the currentCharacter is == to the testedChar1/2 //On false, no side effect has occured. - //ALL getNextChar.... ARE OPTIMIZED COPIES + //ALL getNextChar.... ARE OPTIMIZED COPIES int temp = currentPosition; try { @@ -514,7 +507,7 @@ public class Scanner implements IScanner, ITerminalSymbols { //Both previous lines are true if the currentCharacter is a digit //On false, no side effect has occured. - //ALL getNextChar.... ARE OPTIMIZED COPIES + //ALL getNextChar.... ARE OPTIMIZED COPIES int temp = currentPosition; try { @@ -586,7 +579,7 @@ public class Scanner implements IScanner, ITerminalSymbols { //Both previous lines are true if the currentCharacter is a digit base on radix //On false, no side effect has occured. - //ALL getNextChar.... ARE OPTIMIZED COPIES + //ALL getNextChar.... ARE OPTIMIZED COPIES int temp = currentPosition; try { @@ -658,7 +651,7 @@ public class Scanner implements IScanner, ITerminalSymbols { //Both previous lines are true if the currentCharacter is a JavaIdentifierPart //On false, no side effect has occured. - //ALL getNextChar.... ARE OPTIMIZED COPIES + //ALL getNextChar.... ARE OPTIMIZED COPIES int temp = currentPosition; try { @@ -748,7 +741,7 @@ public class Scanner implements IScanner, ITerminalSymbols { if (test >= 0) { test = getNextChar('P', 'p'); if (test >= 0) { - // 0) && (lineEnds[linePtr] >= separatorPos)) return; - // System.out.println("LF-" + separatorPos); + // System.out.println("LF-" + separatorPos); try { lineEnds[++linePtr] = separatorPos; } catch (IndexOutOfBoundsException e) { @@ -2358,7 +2352,7 @@ public class Scanner implements IScanner, ITerminalSymbols { } // look-ahead for merged cr+lf if (source[currentPosition] == '\n') { - //System.out.println("look-ahead LF-" + currentPosition); + //System.out.println("look-ahead LF-" + currentPosition); lineEnds[linePtr] = currentPosition; currentPosition++; wasAcr = false; @@ -2370,13 +2364,13 @@ public class Scanner implements IScanner, ITerminalSymbols { if (currentCharacter == '\n') { //must merge eventual cr followed by lf if (wasAcr && (lineEnds[linePtr] == (currentPosition - 7))) { - //System.out.println("merge LF-" + (currentPosition - 1)); + //System.out.println("merge LF-" + (currentPosition - 1)); lineEnds[linePtr] = currentPosition - 6; } else { int separatorPos = currentPosition - 6; if ((linePtr > 0) && (lineEnds[linePtr] >= separatorPos)) return; - // System.out.println("LF-" + separatorPos); + // System.out.println("LF-" + separatorPos); try { lineEnds[++linePtr] = separatorPos; } catch (IndexOutOfBoundsException e) { @@ -2524,7 +2518,7 @@ public class Scanner implements IScanner, ITerminalSymbols { } else { // has read \OctalDigit NonDigit--> ignore last character currentPosition--; } - } else { // has read \OctalDigit NonOctalDigit--> ignore last character + } else { // has read \OctalDigit NonOctalDigit--> ignore last character currentPosition--; } } else { // has read \OctalDigit --> ignore last character @@ -2595,7 +2589,7 @@ public class Scanner implements IScanner, ITerminalSymbols { firstLetter = data[index]; switch (firstLetter) { - case 'a' : // as and array + case 'a' : // as and array abstract switch (length) { case 2 : //as if ((data[++index] == 's')) { @@ -2609,11 +2603,22 @@ public class Scanner implements IScanner, ITerminalSymbols { } else { return TokenNameIdentifier; } - // case 5 : - // if ((data[++index] == 'r') && (data[++index] == 'r') && (data[++index] == 'a') && (data[++index] == 'y')) - // return TokenNamearray; - // else - // return TokenNameIdentifier; + case 5 : // array + if ((data[++index] == 'r') && (data[++index] == 'r') && (data[++index] == 'a') && (data[++index] == 'y')) + return TokenNamearray; + else + return TokenNameIdentifier; + case 8 : + if ((data[++index] == 'b') + && (data[++index] == 's') + && (data[++index] == 't') + && (data[++index] == 'r') + && (data[++index] == 'a') + && (data[++index] == 'c') + && (data[++index] == 't')) + return TokenNameabstract; + else + return TokenNameIdentifier; default : return TokenNameIdentifier; } @@ -2628,7 +2633,7 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameIdentifier; } - case 'c' : //case class continue + case 'c' : //case catch class const continue switch (length) { case 4 : if ((data[++index] == 'a') && (data[++index] == 's') && (data[++index] == 'e')) @@ -2636,8 +2641,12 @@ public class Scanner implements IScanner, ITerminalSymbols { else return TokenNameIdentifier; case 5 : - if ((data[++index] == 'l') && (data[++index] == 'a') && (data[++index] == 's') && (data[++index] == 's')) + if ((data[++index] == 'a') && (data[++index] == 't') && (data[++index] == 'c') && (data[++index] == 'h')) + return TokenNamecatch; + if ((data[index] == 'l') && (data[++index] == 'a') && (data[++index] == 's') && (data[++index] == 's')) return TokenNameclass; + if ((data[index] == 'o') && (data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 't')) + return TokenNameconst; else return TokenNameIdentifier; case 8 : @@ -2655,13 +2664,18 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameIdentifier; } - case 'd' : //define default do + case 'd' : //define declare default do die switch (length) { case 2 : if ((data[++index] == 'o')) return TokenNamedo; else return TokenNameIdentifier; + case 3 : + if ((data[++index] == 'i') && (data[++index] == 'e')) + return TokenNamedie; + else + return TokenNameIdentifier; case 6 : if ((data[++index] == 'e') && (data[++index] == 'f') @@ -2673,6 +2687,14 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameIdentifier; case 7 : if ((data[++index] == 'e') + && (data[++index] == 'c') + && (data[++index] == 'l') + && (data[++index] == 'a') + && (data[++index] == 'r') + && (data[++index] == 'e')) + return TokenNamedeclare; + index = 0; + if ((data[++index] == 'e') && (data[++index] == 'f') && (data[++index] == 'a') && (data[++index] == 'u') @@ -2684,18 +2706,24 @@ public class Scanner implements IScanner, ITerminalSymbols { default : return TokenNameIdentifier; } - case 'e' : //echo else elseif extends + case 'e' : //echo else exit elseif extends eval switch (length) { case 4 : if ((data[++index] == 'c') && (data[++index] == 'h') && (data[++index] == 'o')) return TokenNameecho; else if ((data[index] == 'l') && (data[++index] == 's') && (data[++index] == 'e')) return TokenNameelse; + else if ((data[index] == 'x') && (data[++index] == 'i') && (data[++index] == 't')) + return TokenNameexit; + else if ((data[index] == 'v') && (data[++index] == 'a') && (data[++index] == 'l')) + return TokenNameeval; else return TokenNameIdentifier; - case 5 : // endif + case 5 : // endif empty if ((data[++index] == 'n') && (data[++index] == 'd') && (data[++index] == 'i') && (data[++index] == 'f')) return TokenNameendif; + if ((data[index] == 'm') && (data[++index] == 'p') && (data[++index] == 't') && (data[++index] == 'y')) + return TokenNameempty; else return TokenNameIdentifier; case 6 : // endfor @@ -2747,9 +2775,20 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameendswitch; else return TokenNameIdentifier; - case 10 : // endforeach + case 10 : // enddeclare if ((data[++index] == 'n') && (data[++index] == 'd') + && (data[++index] == 'd') + && (data[++index] == 'e') + && (data[++index] == 'c') + && (data[++index] == 'l') + && (data[++index] == 'a') + && (data[++index] == 'r') + && (data[++index] == 'e')) + return TokenNameendforeach; + index = 0; + if ((data[++index] == 'n') // endforeach + && (data[++index] == 'd') && (data[++index] == 'f') && (data[++index] == 'o') && (data[++index] == 'r') @@ -2765,7 +2804,7 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameIdentifier; } - case 'f' : //for false function + case 'f' : //for false final function switch (length) { case 3 : if ((data[++index] == 'o') && (data[++index] == 'r')) @@ -2775,9 +2814,11 @@ public class Scanner implements IScanner, ITerminalSymbols { case 5 : if ((data[++index] == 'a') && (data[++index] == 'l') && (data[++index] == 's') && (data[++index] == 'e')) return TokenNamefalse; + if ((data[index] == 'i') && (data[++index] == 'n') && (data[++index] == 'a') && (data[++index] == 'l')) + return TokenNamefinal; else return TokenNameIdentifier; - case 7 : // function + case 7 : // foreach if ((data[++index] == 'o') && (data[++index] == 'r') && (data[++index] == 'e') @@ -2813,7 +2854,7 @@ public class Scanner implements IScanner, ITerminalSymbols { } return TokenNameIdentifier; - case 'i' : //if int + case 'i' : //if int isset include include_once instanceof interface implements switch (length) { case 2 : if (data[++index] == 'f') @@ -2825,6 +2866,11 @@ public class Scanner implements IScanner, ITerminalSymbols { // return TokenNameint; // else // return TokenNameIdentifier; + case 5 : + if ((data[++index] == 's') && (data[++index] == 's') && (data[++index] == 'e') && (data[++index] == 't')) + return TokenNameisset; + else + return TokenNameIdentifier; case 7 : if ((data[++index] == 'n') && (data[++index] == 'c') @@ -2835,6 +2881,41 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameinclude; else return TokenNameIdentifier; + case 9 : // interface + if ((data[++index] == 'n') + && (data[++index] == 't') + && (data[++index] == 'e') + && (data[++index] == 'r') + && (data[++index] == 'f') + && (data[++index] == 'a') + && (data[++index] == 'c') + && (data[++index] == 'e')) + return TokenNameinterface; + else + return TokenNameIdentifier; + case 10 : // instanceof + if ((data[++index] == 'n') + && (data[++index] == 's') + && (data[++index] == 't') + && (data[++index] == 'a') + && (data[++index] == 'n') + && (data[++index] == 'c') + && (data[++index] == 'e') + && (data[++index] == 'o') + && (data[++index] == 'f')) + return TokenNameinstanceof; + if ((data[index] == 'm') + && (data[++index] == 'p') + && (data[++index] == 'l') + && (data[++index] == 'e') + && (data[++index] == 'm') + && (data[++index] == 'e') + && (data[++index] == 'n') + && (data[++index] == 't') + && (data[++index] == 's')) + return TokenNameimplements; + else + return TokenNameIdentifier; case 12 : if ((data[++index] == 'n') && (data[++index] == 'c') @@ -2901,11 +2982,44 @@ public class Scanner implements IScanner, ITerminalSymbols { // } return TokenNameIdentifier; - case 'p' : // print - if (length == 5) { - if ((data[++index] == 'r') && (data[++index] == 'i') && (data[++index] == 'n') && (data[++index] == 't')) { - return TokenNameprint; - } + case 'p' : // print public private protected + switch (length) { + case 5 : + if ((data[++index] == 'r') && (data[++index] == 'i') && (data[++index] == 'n') && (data[++index] == 't')) { + return TokenNameprint; + } else + return TokenNameIdentifier; + case 6 : + if ((data[++index] == 'u') + && (data[++index] == 'b') + && (data[++index] == 'l') + && (data[++index] == 'i') + && (data[++index] == 'c')) { + return TokenNamepublic; + } else + return TokenNameIdentifier; + case 7 : + if ((data[++index] == 'r') + && (data[++index] == 'i') + && (data[++index] == 'v') + && (data[++index] == 'a') + && (data[++index] == 't') + && (data[++index] == 'e')) { + return TokenNameprivate; + } else + return TokenNameIdentifier; + case 9 : + if ((data[++index] == 'r') + && (data[++index] == 'o') + && (data[++index] == 't') + && (data[++index] == 'e') + && (data[++index] == 'c') + && (data[++index] == 't') + && (data[++index] == 'e') + && (data[++index] == 'd')) { + return TokenNameprotected; + } else + return TokenNameIdentifier; } return TokenNameIdentifier; case 'r' : //return require require_once @@ -2943,7 +3057,7 @@ public class Scanner implements IScanner, ITerminalSymbols { } else return TokenNameIdentifier; - case 's' : //static switch + case 's' : //static switch switch (length) { case 6 : if (data[++index] == 't') @@ -2964,22 +3078,43 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameIdentifier; } - case 't' : // true + case 't' : // try true throw switch (length) { - + case 3 : + if ((data[++index] == 'r') && (data[++index] == 'y')) + return TokenNametry; + else + return TokenNameIdentifier; case 4 : if ((data[++index] == 'r') && (data[++index] == 'u') && (data[++index] == 'e')) return TokenNametrue; else return TokenNameIdentifier; - // if ((data[++index] == 'h') && (data[++index] == 'i') && (data[++index] == 's')) - // return TokenNamethis; + case 5 : + if ((data[++index] == 'h') && (data[++index] == 'r') && (data[++index] == 'o') && (data[++index] == 'w')) + return TokenNamethrow; + else + return TokenNameIdentifier; default : return TokenNameIdentifier; } - - case 'v' : //var + case 'u' : //use unset + switch (length) { + case 3 : + if ((data[++index] == 's') && (data[++index] == 'e')) + return TokenNameuse; + else + return TokenNameIdentifier; + case 5 : + if ((data[++index] == 'n') && (data[++index] == 's') && (data[++index] == 'e') && (data[++index] == 't')) + return TokenNameunset; + else + return TokenNameIdentifier; + default : + return TokenNameIdentifier; + } + case 'v' : //var switch (length) { case 3 : if ((data[++index] == 'a') && (data[++index] == 'r')) @@ -2991,14 +3126,15 @@ public class Scanner implements IScanner, ITerminalSymbols { return TokenNameIdentifier; } - case 'w' : //while + case 'w' : //while switch (length) { case 5 : if ((data[++index] == 'h') && (data[++index] == 'i') && (data[++index] == 'l') && (data[++index] == 'e')) return TokenNamewhile; else return TokenNameIdentifier; - //case 6:if ( (data[++index] =='i') && (data[++index]=='d') && (data[++index]=='e') && (data[++index]=='f')&& (data[++index]=='p')) + //case 6:if ( (data[++index] =='i') && (data[++index]=='d') && (data[++index]=='e') && (data[++index]=='f')&& + // (data[++index]=='p')) //return TokenNamewidefp ; //else //return TokenNameIdentifier; @@ -3176,7 +3312,7 @@ public class Scanner implements IScanner, ITerminalSymbols { } /** * Search the line number corresponding to a specific position - * + * */ public final int getLineNumber(int position) { @@ -3528,177 +3664,195 @@ public class Scanner implements IScanner, ITerminalSymbols { } currentLine = null; } - - - public final void scanEscapeCharacter() throws InvalidInputException { - // the string with "\\u" is a legal string of two chars \ and u - //thus we use a direct access to the source (for regular cases). - - if (unicodeAsBackSlash) { - // consume next character - unicodeAsBackSlash = false; -// if (((currentCharacter = source[currentPosition++]) == '\\') && (source[currentPosition] == 'u')) { -// getNextUnicodeChar(); -// } else { - if (withoutUnicodePtr != 0) { - withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter; -// } - } - } else - currentCharacter = source[currentPosition++]; - switch (currentCharacter) { - case 'b' : - currentCharacter = '\b'; - break; - case 't' : - currentCharacter = '\t'; - break; - case 'n' : - currentCharacter = '\n'; - break; - case 'f' : - currentCharacter = '\f'; - break; - case 'r' : - currentCharacter = '\r'; - break; - case '\"' : - currentCharacter = '\"'; - break; - case '\'' : - currentCharacter = '\''; - break; - case '\\' : - currentCharacter = '\\'; - break; - default : - // -----------octal escape-------------- - // OctalDigit - // OctalDigit OctalDigit - // ZeroToThree OctalDigit OctalDigit - - int number = Character.getNumericValue(currentCharacter); - if (number >= 0 && number <= 7) { - boolean zeroToThreeNot = number > 3; - if (Character.isDigit(currentCharacter = source[currentPosition++])) { - int digit = Character.getNumericValue(currentCharacter); - if (digit >= 0 && digit <= 7) { - number = (number * 8) + digit; - if (Character.isDigit(currentCharacter = source[currentPosition++])) { - if (zeroToThreeNot) {// has read \NotZeroToThree OctalDigit Digit --> ignore last character - currentPosition--; - } else { - digit = Character.getNumericValue(currentCharacter); - if (digit >= 0 && digit <= 7){ // has read \ZeroToThree OctalDigit OctalDigit - number = (number * 8) + digit; - } else {// has read \ZeroToThree OctalDigit NonOctalDigit --> ignore last character - currentPosition--; - } - } - } else { // has read \OctalDigit NonDigit--> ignore last character - currentPosition--; - } - } else { // has read \OctalDigit NonOctalDigit--> ignore last character - currentPosition--; - } - } else { // has read \OctalDigit --> ignore last character - currentPosition--; - } - if (number > 255) - throw new InvalidInputException(INVALID_ESCAPE); - currentCharacter = (char) number; - } else - throw new InvalidInputException(INVALID_ESCAPE); - } - } - -// chech presence of task: tags -public void checkTaskTag(int commentStart, int commentEnd) { - - // only look for newer task: tags - if (this.foundTaskCount > 0 && this.foundTaskPositions[this.foundTaskCount-1][0] >= commentStart) { - return; - } - int foundTaskIndex = this.foundTaskCount; - nextChar: for (int i = commentStart; i < commentEnd && i < this.eofPosition; i++) { - - char[] tag = null; - char[] priority = null; - - // check for tag occurrence - nextTag: for (int itag = 0; itag < this.taskTags.length; itag++){ - tag = this.taskTags[itag]; - priority = - this.taskPriorities != null && itag < this.taskPriorities.length ? - this.taskPriorities[itag] : - null; - int tagLength = tag.length; - for (int t = 0; t < tagLength; t++){ - if (this.source[i+t] != tag[t]) continue nextTag; - } - - if (this.foundTaskTags == null){ - this.foundTaskTags = new char[5][]; - this.foundTaskMessages = new char[5][]; - this.foundTaskPriorities = new char[5][]; - this.foundTaskPositions = new int[5][]; - } else if (this.foundTaskCount == this.foundTaskTags.length) { - System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount*2][], 0, this.foundTaskCount); - System.arraycopy(this.foundTaskMessages, 0, this.foundTaskMessages = new char[this.foundTaskCount*2][], 0, this.foundTaskCount); - System.arraycopy(this.foundTaskPriorities, 0, this.foundTaskPriorities = new char[this.foundTaskCount*2][], 0, this.foundTaskCount); - System.arraycopy(this.foundTaskPositions, 0, this.foundTaskPositions = new int[this.foundTaskCount*2][], 0, this.foundTaskCount); - } - this.foundTaskTags[this.foundTaskCount] = tag; - this.foundTaskPriorities[this.foundTaskCount] = priority; - this.foundTaskPositions[this.foundTaskCount] = new int[]{ i, i+tagLength-1 }; - this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR; - this.foundTaskCount++; - - i += tagLength-1; // will be incremented when looping - } - } - - for (int i = foundTaskIndex; i < this.foundTaskCount; i++) { - // retrieve message start and end positions - int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length; - int max_value = i + 1 < this.foundTaskCount ? this.foundTaskPositions[i + 1][0] - 1 : commentEnd-1; // at most beginning of next task - if (max_value < msgStart) max_value = msgStart; // would only occur if tag is before EOF. - int end = -1; - char c; - - for (int j = msgStart; j < max_value; j++){ - if ((c = this.source[j]) == '\n' || c == '\r'){ - end = j-1; - break; - } - } - - if (end == -1){ - for (int j = max_value; j > msgStart; j--){ - if ((c = this.source[j]) == '*') { - end = j-1; - break; - } - } - if (end == -1) end = max_value; - } - - if (msgStart == end) continue; // empty - - // trim the message - while (CharOperation.isWhitespace(source[end]) && msgStart <= end) end--; - while (CharOperation.isWhitespace(source[msgStart]) && msgStart <= end) msgStart++; - - // update the end position of the task - this.foundTaskPositions[i][1] = end; - - // get the message source - final int messageLength = end-msgStart+1; - char[] message = new char[messageLength]; - - System.arraycopy(source, msgStart, message, 0, messageLength); - this.foundTaskMessages[i] = message; - } -} + + public final void scanEscapeCharacter() throws InvalidInputException { + // the string with "\\u" is a legal string of two chars \ and u + //thus we use a direct access to the source (for regular cases). + + if (unicodeAsBackSlash) { + // consume next character + unicodeAsBackSlash = false; + // if (((currentCharacter = source[currentPosition++]) == '\\') && (source[currentPosition] == 'u')) { + // getNextUnicodeChar(); + // } else { + if (withoutUnicodePtr != 0) { + withoutUnicodeBuffer[++withoutUnicodePtr] = currentCharacter; + // } + } + } else + currentCharacter = source[currentPosition++]; + switch (currentCharacter) { + case 'b' : + currentCharacter = '\b'; + break; + case 't' : + currentCharacter = '\t'; + break; + case 'n' : + currentCharacter = '\n'; + break; + case 'f' : + currentCharacter = '\f'; + break; + case 'r' : + currentCharacter = '\r'; + break; + case '\"' : + currentCharacter = '\"'; + break; + case '\'' : + currentCharacter = '\''; + break; + case '\\' : + currentCharacter = '\\'; + break; + default : + // -----------octal escape-------------- + // OctalDigit + // OctalDigit OctalDigit + // ZeroToThree OctalDigit OctalDigit + + int number = Character.getNumericValue(currentCharacter); + if (number >= 0 && number <= 7) { + boolean zeroToThreeNot = number > 3; + if (Character.isDigit(currentCharacter = source[currentPosition++])) { + int digit = Character.getNumericValue(currentCharacter); + if (digit >= 0 && digit <= 7) { + number = (number * 8) + digit; + if (Character.isDigit(currentCharacter = source[currentPosition++])) { + if (zeroToThreeNot) { // has read \NotZeroToThree OctalDigit Digit --> ignore last character + currentPosition--; + } else { + digit = Character.getNumericValue(currentCharacter); + if (digit >= 0 && digit <= 7) { // has read \ZeroToThree OctalDigit OctalDigit + number = (number * 8) + digit; + } else { // has read \ZeroToThree OctalDigit NonOctalDigit --> ignore last character + currentPosition--; + } + } + } else { // has read \OctalDigit NonDigit--> ignore last character + currentPosition--; + } + } else { // has read \OctalDigit NonOctalDigit--> ignore last character + currentPosition--; + } + } else { // has read \OctalDigit --> ignore last character + currentPosition--; + } + if (number > 255) + throw new InvalidInputException(INVALID_ESCAPE); + currentCharacter = (char) number; + } else + throw new InvalidInputException(INVALID_ESCAPE); + } + } + + // chech presence of task: tags + public void checkTaskTag(int commentStart, int commentEnd) { + + // only look for newer task: tags + if (this.foundTaskCount > 0 && this.foundTaskPositions[this.foundTaskCount - 1][0] >= commentStart) { + return; + } + int foundTaskIndex = this.foundTaskCount; + nextChar : for (int i = commentStart; i < commentEnd && i < this.eofPosition; i++) { + + char[] tag = null; + char[] priority = null; + + // check for tag occurrence + nextTag : for (int itag = 0; itag < this.taskTags.length; itag++) { + tag = this.taskTags[itag]; + priority = this.taskPriorities != null && itag < this.taskPriorities.length ? this.taskPriorities[itag] : null; + int tagLength = tag.length; + for (int t = 0; t < tagLength; t++) { + if (this.source[i + t] != tag[t]) + continue nextTag; + } + + if (this.foundTaskTags == null) { + this.foundTaskTags = new char[5][]; + this.foundTaskMessages = new char[5][]; + this.foundTaskPriorities = new char[5][]; + this.foundTaskPositions = new int[5][]; + } else if (this.foundTaskCount == this.foundTaskTags.length) { + System.arraycopy(this.foundTaskTags, 0, this.foundTaskTags = new char[this.foundTaskCount * 2][], 0, this.foundTaskCount); + System.arraycopy( + this.foundTaskMessages, + 0, + this.foundTaskMessages = new char[this.foundTaskCount * 2][], + 0, + this.foundTaskCount); + System.arraycopy( + this.foundTaskPriorities, + 0, + this.foundTaskPriorities = new char[this.foundTaskCount * 2][], + 0, + this.foundTaskCount); + System.arraycopy( + this.foundTaskPositions, + 0, + this.foundTaskPositions = new int[this.foundTaskCount * 2][], + 0, + this.foundTaskCount); + } + this.foundTaskTags[this.foundTaskCount] = tag; + this.foundTaskPriorities[this.foundTaskCount] = priority; + this.foundTaskPositions[this.foundTaskCount] = new int[] { i, i + tagLength - 1 }; + this.foundTaskMessages[this.foundTaskCount] = CharOperation.NO_CHAR; + this.foundTaskCount++; + + i += tagLength - 1; // will be incremented when looping + } + } + + for (int i = foundTaskIndex; i < this.foundTaskCount; i++) { + // retrieve message start and end positions + int msgStart = this.foundTaskPositions[i][0] + this.foundTaskTags[i].length; + int max_value = i + 1 < this.foundTaskCount ? this.foundTaskPositions[i + 1][0] - 1 : commentEnd - 1; + // at most beginning of next task + if (max_value < msgStart) + max_value = msgStart; // would only occur if tag is before EOF. + int end = -1; + char c; + + for (int j = msgStart; j < max_value; j++) { + if ((c = this.source[j]) == '\n' || c == '\r') { + end = j - 1; + break; + } + } + + if (end == -1) { + for (int j = max_value; j > msgStart; j--) { + if ((c = this.source[j]) == '*') { + end = j - 1; + break; + } + } + if (end == -1) + end = max_value; + } + + if (msgStart == end) + continue; // empty + + // trim the message + while (CharOperation.isWhitespace(source[end]) && msgStart <= end) + end--; + while (CharOperation.isWhitespace(source[msgStart]) && msgStart <= end) + msgStart++; + + // update the end position of the task + this.foundTaskPositions[i][1] = end; + + // get the message source + final int messageLength = end - msgStart + 1; + char[] message = new char[messageLength]; + + System.arraycopy(source, msgStart, message, 0, messageLength); + this.foundTaskMessages[i] = message; + } + } }