From 65bf3316cf384588453604be6b4f0ed3751a8b0f Mon Sep 17 00:00:00 2001 From: tromey Date: Tue, 9 Jan 2007 19:58:05 +0000 Subject: Merged gcj-eclipse branch to trunk. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120621 138bc75d-0d04-0410-961f-82ee72b054a4 --- .../classpath/gnu/java/util/regex/CharIndexed.java | 17 ++ .../java/util/regex/CharIndexedCharSequence.java | 13 ++ .../java/util/regex/CharIndexedInputStream.java | 14 ++ libjava/classpath/gnu/java/util/regex/RE.java | 34 +++- libjava/classpath/gnu/java/util/regex/REMatch.java | 4 +- .../classpath/gnu/java/util/regex/RESyntax.java | 11 +- libjava/classpath/gnu/java/util/regex/REToken.java | 15 ++ .../classpath/gnu/java/util/regex/RETokenChar.java | 12 +- .../classpath/gnu/java/util/regex/RETokenEnd.java | 15 ++ .../gnu/java/util/regex/RETokenEndSub.java | 4 + .../gnu/java/util/regex/RETokenNamedProperty.java | 8 + .../gnu/java/util/regex/RETokenOneOf.java | 1 + .../gnu/java/util/regex/RETokenRepeated.java | 199 ++++++++++++++++----- 13 files changed, 285 insertions(+), 62 deletions(-) (limited to 'libjava/classpath/gnu/java/util/regex') diff --git a/libjava/classpath/gnu/java/util/regex/CharIndexed.java b/libjava/classpath/gnu/java/util/regex/CharIndexed.java index 6cd857e3bc0..27e07b2f8ff 100644 --- a/libjava/classpath/gnu/java/util/regex/CharIndexed.java +++ b/libjava/classpath/gnu/java/util/regex/CharIndexed.java @@ -76,6 +76,13 @@ public interface CharIndexed { */ boolean move(int index); + /** + * Shifts the input buffer by a given number of positions. Returns + * true if the new cursor position is valid or cursor position is at + * the end of input. + */ + boolean move1(int index); // I cannot think of a better name for this. + /** * Returns true if the most recent move() operation placed the cursor * position at a valid position in the input. @@ -104,6 +111,16 @@ public interface CharIndexed { */ REMatch getLastMatch(); + /** + * Sets the information used for hitEnd(). + */ + void setHitEnd(REMatch match); + + /** + * Returns whether the matcher has hit the end of input. + */ + boolean hitEnd(); + /** * Returns the anchor. */ diff --git a/libjava/classpath/gnu/java/util/regex/CharIndexedCharSequence.java b/libjava/classpath/gnu/java/util/regex/CharIndexedCharSequence.java index 2eb753b0f5c..8a0578eb80f 100644 --- a/libjava/classpath/gnu/java/util/regex/CharIndexedCharSequence.java +++ b/libjava/classpath/gnu/java/util/regex/CharIndexedCharSequence.java @@ -62,6 +62,10 @@ class CharIndexedCharSequence implements CharIndexed, Serializable { return ((anchor += index) < len); } + public boolean move1(int index) { + return ((anchor += index) <= len); + } + public CharIndexed lookBehind(int index, int length) { if (length > (anchor + index)) length = anchor + index; return new CharIndexedCharSequence(s, anchor + index - length); @@ -77,6 +81,15 @@ class CharIndexedCharSequence implements CharIndexed, Serializable { lastMatch.anchor = anchor; } public REMatch getLastMatch() { return lastMatch; } + + private int rightmostTriedPosition = 0; + public void setHitEnd(REMatch match) { + int pos = anchor + match.index; + if (pos > rightmostTriedPosition) rightmostTriedPosition = pos; + } + public boolean hitEnd() { return rightmostTriedPosition >= len; } + public int getAnchor() { return anchor; } public void setAnchor(int anchor) { this.anchor = anchor; } + } diff --git a/libjava/classpath/gnu/java/util/regex/CharIndexedInputStream.java b/libjava/classpath/gnu/java/util/regex/CharIndexedInputStream.java index 77cd1abd5cc..844fada51fc 100644 --- a/libjava/classpath/gnu/java/util/regex/CharIndexedInputStream.java +++ b/libjava/classpath/gnu/java/util/regex/CharIndexedInputStream.java @@ -166,6 +166,16 @@ class CharIndexedInputStream implements CharIndexed { "difficult to support getLastMatch for an input stream"); } + public void setHitEnd(REMatch match) { + throw new UnsupportedOperationException( + "difficult to support setHitEnd for an input stream"); + } + + public boolean hitEnd() { + throw new UnsupportedOperationException( + "difficult to support hitEnd for an input stream"); + } + public int getAnchor() { throw new UnsupportedOperationException( "difficult to support getAnchor for an input stream"); @@ -176,6 +186,10 @@ class CharIndexedInputStream implements CharIndexed { "difficult to support setAnchor for an input stream"); } + public boolean move1(int index) { + throw new UnsupportedOperationException( + "difficult to support move1 for an input stream"); + } } diff --git a/libjava/classpath/gnu/java/util/regex/RE.java b/libjava/classpath/gnu/java/util/regex/RE.java index 1aab3b781a2..09ff74b908f 100644 --- a/libjava/classpath/gnu/java/util/regex/RE.java +++ b/libjava/classpath/gnu/java/util/regex/RE.java @@ -130,7 +130,11 @@ public class RE extends REToken { private static final String VERSION = "1.1.5-dev"; // The localized strings are kept in a separate file - private static ResourceBundle messages = PropertyResourceBundle.getBundle("gnu/java/util/regex/MessagesBundle", Locale.getDefault()); + // Used by getLocalizedMessage(). + private static ResourceBundle messages; + + // Name of the bundle that contains the localized messages. + private static final String bundle = "gnu/java/util/regex/MessagesBundle"; // These are, respectively, the first and last tokens in our linked list // If there is only one token, firstToken == lastToken @@ -252,6 +256,13 @@ public class RE extends REToken { */ public static final int REG_ICASE_USASCII = 0x0800; + /** + * Execution flag. + * Do not move the position at which the search begins. If not set, + * the starting position will be moved until a match is found. + */ + public static final int REG_FIX_STARTING_POSITION = 0x1000; + /** Returns a string representing the version of the gnu.regexp package. */ public static final String version() { return VERSION; @@ -259,6 +270,8 @@ public class RE extends REToken { // Retrieves a message from the ResourceBundle static final String getLocalizedMessage(String key) { + if (messages == null) + messages = PropertyResourceBundle.getBundle(bundle, Locale.getDefault()); return messages.getString(key); } @@ -1643,6 +1656,7 @@ public class RE extends REToken { /* Implements abstract method REToken.match() */ boolean match(CharIndexed input, REMatch mymatch) { + input.setHitEnd(mymatch); if (firstToken == null) { return next(input, mymatch); } @@ -1720,15 +1734,23 @@ public class RE extends REToken { REMatch getMatchImpl(CharIndexed input, int anchor, int eflags, StringBuffer buffer) { boolean tryEntireMatch = ((eflags & REG_TRY_ENTIRE_MATCH) != 0); + boolean doMove = ((eflags & REG_FIX_STARTING_POSITION) == 0); RE re = (tryEntireMatch ? (RE) this.clone() : this); if (tryEntireMatch) { - re.chain(new RETokenEnd(0, null)); + RETokenEnd reEnd = new RETokenEnd(0, null); + reEnd.setFake(true); + re.chain(reEnd); } // Create a new REMatch to hold results REMatch mymatch = new REMatch(numSubs, anchor, eflags); do { + /* The following potimization is commented out because + the matching should be tried even if the length of + input is obviously too short in order that + java.util.regex.Matcher#hitEnd() may work correctly. // Optimization: check if anchor + minimumLength > length if (minimumLength == 0 || input.charAt(minimumLength-1) != CharIndexed.OUT_OF_BOUNDS) { + */ if (re.match(input, mymatch)) { REMatch best = mymatch; // We assume that the match that coms first is the best. @@ -1749,13 +1771,17 @@ public class RE extends REToken { input.setLastMatch(best); return best; } - } + /* End of the optimization commented out + } + */ mymatch.clear(++anchor); // Append character to buffer if needed if (buffer != null && input.charAt(0) != CharIndexed.OUT_OF_BOUNDS) { buffer.append(input.charAt(0)); } - } while (input.move(1)); + // java.util.regex.Matcher#hitEnd() requires that the search should + // be tried at the end of input, so we use move1(1) instead of move(1) + } while (doMove && input.move1(1)); // Special handling at end of input for e.g. "$" if (minimumLength == 0) { diff --git a/libjava/classpath/gnu/java/util/regex/REMatch.java b/libjava/classpath/gnu/java/util/regex/REMatch.java index 3ff5ad794b8..d8994829323 100644 --- a/libjava/classpath/gnu/java/util/regex/REMatch.java +++ b/libjava/classpath/gnu/java/util/regex/REMatch.java @@ -307,12 +307,12 @@ public final class REMatch implements Serializable, Cloneable { } /* The following are used for debugging purpose - static String d(REMatch m) { + public static String d(REMatch m) { if (m == null) return "null"; else return "[" + m.index + "]"; } - String substringUptoIndex(CharIndexed input) { + public String substringUptoIndex(CharIndexed input) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < index; i++) { sb.append(input.charAt(i)); diff --git a/libjava/classpath/gnu/java/util/regex/RESyntax.java b/libjava/classpath/gnu/java/util/regex/RESyntax.java index b66b32f5878..db11e2db450 100644 --- a/libjava/classpath/gnu/java/util/regex/RESyntax.java +++ b/libjava/classpath/gnu/java/util/regex/RESyntax.java @@ -54,8 +54,6 @@ import java.util.BitSet; public final class RESyntax implements Serializable { static final String DEFAULT_LINE_SEPARATOR = System.getProperty("line.separator"); - private static final String SYNTAX_IS_FINAL = RE.getLocalizedMessage("syntax.final"); - private BitSet bits; // true for the constant defined syntaxes @@ -513,7 +511,8 @@ public final class RESyntax implements Serializable { * @return a reference to this object for easy chaining. */ public RESyntax set(int index) { - if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL); + if (isFinal) + throw new IllegalAccessError(RE.getLocalizedMessage("syntax.final")); bits.set(index); return this; } @@ -525,7 +524,8 @@ public final class RESyntax implements Serializable { * @return a reference to this object for easy chaining. */ public RESyntax clear(int index) { - if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL); + if (isFinal) + throw new IllegalAccessError(RE.getLocalizedMessage("syntax.final")); bits.clear(index); return this; } @@ -548,7 +548,8 @@ public final class RESyntax implements Serializable { * @return this object for convenient chaining */ public RESyntax setLineSeparator(String aSeparator) { - if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL); + if (isFinal) + throw new IllegalAccessError(RE.getLocalizedMessage("syntax.final")); lineSeparator = aSeparator; return this; } diff --git a/libjava/classpath/gnu/java/util/regex/REToken.java b/libjava/classpath/gnu/java/util/regex/REToken.java index 155c01878e8..9affd4ee3c9 100644 --- a/libjava/classpath/gnu/java/util/regex/REToken.java +++ b/libjava/classpath/gnu/java/util/regex/REToken.java @@ -72,6 +72,16 @@ abstract class REToken implements Serializable, Cloneable { /** Returns true if the match succeeded, false if it failed. */ boolean match(CharIndexed input, REMatch mymatch) { + return match(input, mymatch, false); + } + boolean matchFake(CharIndexed input, REMatch mymatch) { + return match(input, mymatch, true); + } + + private boolean match(CharIndexed input, REMatch mymatch, boolean fake) { + if (!fake) { + setHitEnd(input, mymatch); + } REMatch m = matchThis(input, mymatch); if (m == null) return false; if (next(input, m)) { @@ -81,6 +91,11 @@ abstract class REToken implements Serializable, Cloneable { return false; } + /** Sets whether the matching occurs at the end of input */ + void setHitEnd(CharIndexed input, REMatch mymatch) { + input.setHitEnd(mymatch); + } + /** Returns true if the match succeeded, false if it failed. * The matching is done against this REToken only. Chained * tokens are not checked. diff --git a/libjava/classpath/gnu/java/util/regex/RETokenChar.java b/libjava/classpath/gnu/java/util/regex/RETokenChar.java index 92d3efcf85b..b70e6b1d843 100644 --- a/libjava/classpath/gnu/java/util/regex/RETokenChar.java +++ b/libjava/classpath/gnu/java/util/regex/RETokenChar.java @@ -58,15 +58,20 @@ final class RETokenChar extends REToken { } REMatch matchThis(CharIndexed input, REMatch mymatch) { - int z = ch.length; if (matchOneString(input, mymatch.index)) { - mymatch.index += z; + mymatch.index += matchedLength; return mymatch; } + // java.util.regex.Matcher#hitEnd() requires that the length of + // partial match be counted. + mymatch.index += matchedLength; + input.setHitEnd(mymatch); return null; } - boolean matchOneString(CharIndexed input, int index) { + private int matchedLength; + private boolean matchOneString(CharIndexed input, int index) { + matchedLength = 0; int z = ch.length; char c; for (int i=0; i