aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/util
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>2007-01-09 19:58:05 +0000
committerTom Tromey <tromey@gcc.gnu.org>2007-01-09 19:58:05 +0000
commit97b8365cafc3a344a22d3980b8ed885f5c6d8357 (patch)
tree996a5f57d4a68c53473382e45cb22f574cb3e4db /libjava/classpath/gnu/java/util
parentc648dedbde727ca3f883bb5fd773aa4af70d3369 (diff)
downloadgcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.zip
gcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.tar.gz
gcc-97b8365cafc3a344a22d3980b8ed885f5c6d8357.tar.bz2
Merged gcj-eclipse branch to trunk.
From-SVN: r120621
Diffstat (limited to 'libjava/classpath/gnu/java/util')
-rw-r--r--libjava/classpath/gnu/java/util/DoubleEnumeration.java12
-rw-r--r--libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java27
-rw-r--r--libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java53
-rw-r--r--libjava/classpath/gnu/java/util/regex/CharIndexed.java17
-rw-r--r--libjava/classpath/gnu/java/util/regex/CharIndexedCharSequence.java13
-rw-r--r--libjava/classpath/gnu/java/util/regex/CharIndexedInputStream.java14
-rw-r--r--libjava/classpath/gnu/java/util/regex/RE.java34
-rw-r--r--libjava/classpath/gnu/java/util/regex/REMatch.java4
-rw-r--r--libjava/classpath/gnu/java/util/regex/RESyntax.java11
-rw-r--r--libjava/classpath/gnu/java/util/regex/REToken.java15
-rw-r--r--libjava/classpath/gnu/java/util/regex/RETokenChar.java12
-rw-r--r--libjava/classpath/gnu/java/util/regex/RETokenEnd.java15
-rw-r--r--libjava/classpath/gnu/java/util/regex/RETokenEndSub.java4
-rw-r--r--libjava/classpath/gnu/java/util/regex/RETokenNamedProperty.java8
-rw-r--r--libjava/classpath/gnu/java/util/regex/RETokenOneOf.java1
-rw-r--r--libjava/classpath/gnu/java/util/regex/RETokenRepeated.java199
16 files changed, 359 insertions, 80 deletions
diff --git a/libjava/classpath/gnu/java/util/DoubleEnumeration.java b/libjava/classpath/gnu/java/util/DoubleEnumeration.java
index 1fc37f8..94efb923 100644
--- a/libjava/classpath/gnu/java/util/DoubleEnumeration.java
+++ b/libjava/classpath/gnu/java/util/DoubleEnumeration.java
@@ -1,5 +1,5 @@
/* gnu.java.util.DoubleEnumeration
- Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2001, 2004 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -63,7 +63,7 @@ import java.util.NoSuchElementException;
* @author Jochen Hoenicke
* @author Mark Wielaard (mark@klomp.org)
*/
-public class DoubleEnumeration implements Enumeration
+public class DoubleEnumeration<T> implements Enumeration<T>
{
/**
* This is true as long as one of the enumerations has more
@@ -82,17 +82,17 @@ public class DoubleEnumeration implements Enumeration
/**
* The first enumeration.
*/
- private Enumeration e1;
+ private Enumeration<T> e1;
/**
* The second enumeration.
*/
- private Enumeration e2;
+ private Enumeration<T> e2;
/**
* Creates a new Enumeration combining the given two enumerations.
* The enumerations mustn't be accessed by other classes.
*/
- public DoubleEnumeration(Enumeration e1, Enumeration e2)
+ public DoubleEnumeration(Enumeration<T> e1, Enumeration<T> e2)
{
this.e1 = e1;
this.e2 = e2;
@@ -126,7 +126,7 @@ public class DoubleEnumeration implements Enumeration
* element of the second enumeration. If both enumeration don't have
* any elements it throws a <code>NoSuchElementException</code>.
*/
- public Object nextElement()
+ public T nextElement()
{
if (!hasMoreElements())
throw new NoSuchElementException();
diff --git a/libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java b/libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java
index 5702751..a7e2322 100644
--- a/libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java
+++ b/libjava/classpath/gnu/java/util/prefs/GConfBasedPreferences.java
@@ -72,7 +72,6 @@ import java.util.prefs.BackingStoreException;
* <br />
*
* @author Mario Torre <neugens@limasoftware.net>
- * @version 1.0.1
*/
public class GConfBasedPreferences
extends AbstractPreferences
@@ -136,12 +135,20 @@ public class GConfBasedPreferences
absolutePath = absolutePath.substring(0, absolutePath.length() - 1);
}
+ // strip invalid characters
+ // please, note that all names are unescaped into the native peer
+ int index = absolutePath.lastIndexOf('/');
+ if (index > -1)
+ {
+ absolutePath = absolutePath.substring(0, index + 1);
+ absolutePath = absolutePath + GConfNativePeer.escapeString(name);
+ }
+
this.node = this.getRealRoot(isUser) + absolutePath;
boolean nodeExist = backend.nodeExist(this.node);
this.newNode = !nodeExist;
- backend.startWatchingNode(this.node);
}
/**
@@ -156,7 +163,15 @@ public class GConfBasedPreferences
// we don't check anything here, if the node is a new node this will be
// detected in the constructor, so we simply return a new reference to
// the requested node.
- return new GConfBasedPreferences(this, name, this.isUser);
+
+ GConfBasedPreferences preferenceNode
+ = new GConfBasedPreferences(this, name, this.isUser);
+
+ // register the node for to GConf so that it can listen
+ // events outside the scope of the application
+ backend.startWatchingNode(this.node);
+
+ return preferenceNode;
}
/**
@@ -365,6 +380,10 @@ public class GConfBasedPreferences
{
String nodeName = "";
+ // strip key
+ // please, note that all names are unescaped into the native peer
+ key = GConfNativePeer.escapeString(key);
+
if (this.node.endsWith("/"))
{
nodeName = this.node + key;
@@ -373,7 +392,7 @@ public class GConfBasedPreferences
{
nodeName = this.node + "/" + key;
}
-
+
return nodeName;
}
diff --git a/libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java b/libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java
index f1cb627..6049863 100644
--- a/libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java
+++ b/libjava/classpath/gnu/java/util/prefs/gconf/GConfNativePeer.java
@@ -45,7 +45,6 @@ import java.util.prefs.BackingStoreException;
* Native peer for GConf based preference backend.
*
* @author Mario Torre <neugens@limasoftware.net>
- * @version 1.0.1
*/
public final class GConfNativePeer
{
@@ -150,7 +149,7 @@ public final class GConfNativePeer
*/
public List getKeys(String node) throws BackingStoreException
{
- return gconf_client_gconf_client_all_keys(node);
+ return gconf_client_all_keys(node);
}
/**
@@ -162,10 +161,26 @@ public final class GConfNativePeer
*/
public List getChildrenNodes(String node) throws BackingStoreException
{
- return gconf_client_gconf_client_all_nodes(node);
+ return gconf_client_all_nodes(node);
}
/**
+ * Escape the given string so the it is a valid GConf name.
+ */
+ public static String escapeString(String plain)
+ {
+ return gconf_escape_key(plain);
+ }
+
+ /**
+ * Unescape a string escaped with {@link #escapeString}.
+ */
+ public static String unescapeString(String escaped)
+ {
+ return gconf_unescape_key(escaped);
+ }
+
+ /**
* Suggest to the backend GConf daemon to synch with the database.
*/
public void suggestSync() throws BackingStoreException
@@ -270,8 +285,9 @@ public final class GConfNativePeer
* Suggest to the GConf native peer a sync with the database.
*
*/
- native static final protected void gconf_client_suggest_sync();
-
+ native static final protected void gconf_client_suggest_sync()
+ throws BackingStoreException;
+
/**
* Returns a list of all nodes under the given node.
*
@@ -279,8 +295,9 @@ public final class GConfNativePeer
* @return A list of nodes under the given source node.
*/
native
- static final protected List gconf_client_gconf_client_all_nodes(String node);
-
+ static final protected List gconf_client_all_nodes(String node)
+ throws BackingStoreException;
+
/**
* Returns a list of all keys stored in the given node.
*
@@ -288,8 +305,28 @@ public final class GConfNativePeer
* @return A list of all keys stored in the given node.
*/
native
- static final protected List gconf_client_gconf_client_all_keys(String node);
+ static final protected List gconf_client_all_keys(String node)
+ throws BackingStoreException;
+ /**
+ * Escape the input String so that it's a valid element for GConf.
+ *
+ * @param plain the String to escape.
+ * @return An escaped String for use with GConf.
+ */
+ native
+ static final protected String gconf_escape_key(String plain);
+
+ /**
+ * Converts a string escaped with gconf_escape_key back into its
+ * original form.
+ *
+ * @param escaped key as returned by gconf_escape_key
+ * @return An unescaped key.
+ */
+ native
+ static final protected String gconf_unescape_key(String escaped);
+
static
{
System.loadLibrary("gconfpeer");
diff --git a/libjava/classpath/gnu/java/util/regex/CharIndexed.java b/libjava/classpath/gnu/java/util/regex/CharIndexed.java
index 6cd857e..27e07b2 100644
--- a/libjava/classpath/gnu/java/util/regex/CharIndexed.java
+++ b/libjava/classpath/gnu/java/util/regex/CharIndexed.java
@@ -77,6 +77,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.
*/
@@ -105,6 +112,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.
*/
int getAnchor();
diff --git a/libjava/classpath/gnu/java/util/regex/CharIndexedCharSequence.java b/libjava/classpath/gnu/java/util/regex/CharIndexedCharSequence.java
index 2eb753b..8a0578e 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 77cd1ab..844fada 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 1aab3b7..09ff74b 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 3ff5ad7..d899482 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 b66b32f..db11e2d 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 155c018..9affd4e 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 92d3efc..b70e6b1 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<z; i++) {
@@ -74,6 +79,7 @@ final class RETokenChar extends REToken {
if (! charEquals(c, ch[i])) {
return false;
}
+ ++matchedLength;
}
return true;
}
diff --git a/libjava/classpath/gnu/java/util/regex/RETokenEnd.java b/libjava/classpath/gnu/java/util/regex/RETokenEnd.java
index 00efdb6..294e320 100644
--- a/libjava/classpath/gnu/java/util/regex/RETokenEnd.java
+++ b/libjava/classpath/gnu/java/util/regex/RETokenEnd.java
@@ -45,6 +45,12 @@ final class RETokenEnd extends REToken {
private String newline;
private boolean check_java_line_terminators;
+ /**
+ * Indicates whether this token is a real one generated at compile time,
+ * or a fake one temporarily added by RE#getMatchImpl.
+ */
+ private boolean fake = false;
+
RETokenEnd(int subIndex,String newline) {
super(subIndex);
this.newline = newline;
@@ -57,10 +63,19 @@ final class RETokenEnd extends REToken {
this.check_java_line_terminators = b;
}
+ void setFake(boolean fake) {
+ this.fake = fake;
+ }
+
int getMaximumLength() {
return 0;
}
+ boolean match(CharIndexed input, REMatch mymatch) {
+ if (!fake) return super.match(input, mymatch);
+ return super.matchFake(input, mymatch);
+ }
+
REMatch matchThis(CharIndexed input, REMatch mymatch) {
char ch = input.charAt(mymatch.index);
if (ch == CharIndexed.OUT_OF_BOUNDS)
diff --git a/libjava/classpath/gnu/java/util/regex/RETokenEndSub.java b/libjava/classpath/gnu/java/util/regex/RETokenEndSub.java
index 57a146d..b3a28a3 100644
--- a/libjava/classpath/gnu/java/util/regex/RETokenEndSub.java
+++ b/libjava/classpath/gnu/java/util/regex/RETokenEndSub.java
@@ -58,6 +58,10 @@ final class RETokenEndSub extends REToken {
return super.findMatch(input, mymatch);
}
+ void setHitEnd(CharIndexed input, REMatch mymatch) {
+ // Do nothing
+ }
+
void dump(StringBuffer os) {
// handled by RE
// But add something for debugging.
diff --git a/libjava/classpath/gnu/java/util/regex/RETokenNamedProperty.java b/libjava/classpath/gnu/java/util/regex/RETokenNamedProperty.java
index a286c5b..aec2758 100644
--- a/libjava/classpath/gnu/java/util/regex/RETokenNamedProperty.java
+++ b/libjava/classpath/gnu/java/util/regex/RETokenNamedProperty.java
@@ -260,6 +260,14 @@ final class RETokenNamedProperty extends REToken {
return new UnicodeCategoryHandler(Character.UNASSIGNED);
if (name.equals("Lu"))
return new UnicodeCategoryHandler(Character.UPPERCASE_LETTER);
+ if (name.equals("all"))
+ return new Handler()
+ {
+ public boolean includes(char c)
+ {
+ return true;
+ }
+ };
throw new REException("unsupported name " + name, REException.REG_ESCAPE, 0);
}
diff --git a/libjava/classpath/gnu/java/util/regex/RETokenOneOf.java b/libjava/classpath/gnu/java/util/regex/RETokenOneOf.java
index bccc783..239c220 100644
--- a/libjava/classpath/gnu/java/util/regex/RETokenOneOf.java
+++ b/libjava/classpath/gnu/java/util/regex/RETokenOneOf.java
@@ -120,6 +120,7 @@ final class RETokenOneOf extends REToken {
}
boolean match(CharIndexed input, REMatch mymatch) {
+ setHitEnd(input, mymatch);
if (matchesOneChar) return matchOneChar(input, mymatch);
else return matchOneRE(input, mymatch);
}
diff --git a/libjava/classpath/gnu/java/util/regex/RETokenRepeated.java b/libjava/classpath/gnu/java/util/regex/RETokenRepeated.java
index 531c4a3..7f5e562 100644
--- a/libjava/classpath/gnu/java/util/regex/RETokenRepeated.java
+++ b/libjava/classpath/gnu/java/util/regex/RETokenRepeated.java
@@ -38,8 +38,7 @@ exception statement from your version. */
package gnu.java.util.regex;
-// import java.util.Vector;
-// import java.util.Stack;
+import java.util.ArrayList;
final class RETokenRepeated extends REToken {
private REToken token;
@@ -168,19 +167,63 @@ final class RETokenRepeated extends REToken {
}
}
+ private static class FindMatchControlStack extends ArrayList {
+ private void push(FindMatchControl control) {
+ add(control);
+ }
+ private FindMatchControl pop() {
+ return (FindMatchControl)remove(size()-1);
+ }
+ private boolean empty() {
+ return isEmpty();
+ }
+ }
+
+ private static class FindMatchControl {
+ DoablesFinder finder;
+ FindMatchControl(DoablesFinder finder) {
+ this.finder = finder;
+ }
+ }
+
private REMatch findMatch(BacktrackStack stack) {
- // Avoid using recursive calls.
+ return findMatch(stack, new FindMatchControlStack());
+ }
+
+ private REMatch findMatch(BacktrackStack stack,
+ FindMatchControlStack controlStack) {
+ REMatch result = null;
+ StackedInfo si = null;
+ CharIndexed input = null;
+ int numRepeats = 0;
+ REMatch mymatch = null;
+ int[] visited = null;
+ DoablesFinder finder = null;
+
+ // Avoid using recursive calls because a match can be very long.
+
+ // This is the first entry point of this method.
+ // If you want to call this method recursively and you need the
+ // result returned, save necessary information in a FindMatchControl
+ // object and push it to controlStack, then continue from this point.
+ // You can check the result after exiting MAIN_LOOP.
+ MAIN_LOOP0:
+ while (true) {
+
+ // This is the second entry point of this method.
+ // If you want to call this method recursively but you do not need the
+ // result returned, just continue from this point.
MAIN_LOOP:
while (true) {
- if (stack.empty()) return null;
- StackedInfo si = (StackedInfo)(stack.peek());
- CharIndexed input = si.input;
- int numRepeats = si.numRepeats;
- REMatch mymatch = si.match;
- int[] visited = si.visited;
- DoablesFinder finder = si.finder;
-
+ if (stack.empty()) break MAIN_LOOP;
+ si = (StackedInfo)(stack.peek());
+ input = si.input;
+ numRepeats = si.numRepeats;
+ mymatch = si.match;
+ visited = si.visited;
+ finder = si.finder;
+
if (mymatch.backtrackStack == null)
mymatch.backtrackStack = new BacktrackStack();
@@ -192,12 +235,13 @@ final class RETokenRepeated extends REToken {
m1.backtrackStack.push(new BacktrackStack.Backtrack(
this, input, mymatch, stack));
}
- return m1;
+ result = m1;
+ break MAIN_LOOP;
}
if (stingy) {
continue MAIN_LOOP;
}
- return null;
+ break MAIN_LOOP;
}
if (finder == null) {
@@ -238,7 +282,8 @@ final class RETokenRepeated extends REToken {
m1.backtrackStack.push(new BacktrackStack.Backtrack(
this, input, mymatch, stack));
}
- return m1;
+ result = m1;
+ break MAIN_LOOP;
}
else {
continue MAIN_LOOP;
@@ -247,8 +292,82 @@ final class RETokenRepeated extends REToken {
visited = addVisited(mymatch.index, visited);
+ TryAnotherResult taresult = tryAnother(stack, input, mymatch, numRepeats, finder, visited);
+ visited = taresult.visited;
+ switch (taresult.status) {
+ case TryAnotherResult.TRY_FURTHER:
+ controlStack.push(new FindMatchControl(
+ finder));
+ continue MAIN_LOOP0;
+ case TryAnotherResult.RESULT_FOUND:
+ result = taresult.result;
+ break MAIN_LOOP;
+ }
+
+ if (!stack.empty()) {
+ stack.pop();
+ }
+ if (possessive) {
+ stack.clear();
+ }
+ REMatch m1 = matchRest(input, mymatch);
+ if (m1 != null) {
+ if (! stack.empty()) {
+ m1.backtrackStack.push(new BacktrackStack.Backtrack(
+ this, input, mymatch, stack));
+ }
+ result = m1;
+ break MAIN_LOOP;
+ }
+
+ } // MAIN_LOOP
+
+ if (controlStack.empty()) return result;
+ FindMatchControl control = controlStack.pop();
+ if (possessive) {
+ return result;
+ }
+ if (result != null) {
+ result.backtrackStack.push(new BacktrackStack.Backtrack(
+ this, input, mymatch, stack));
+ return result;
+ }
+
+ finder = control.finder;
+
+ TryAnotherResult taresult = tryAnother(stack, input, mymatch, numRepeats, finder, visited);
+ visited = taresult.visited;
+ switch (taresult.status) {
+ case TryAnotherResult.TRY_FURTHER:
+ controlStack.push(new FindMatchControl(
+ finder));
+ continue MAIN_LOOP0;
+ case TryAnotherResult.RESULT_FOUND:
+ return taresult.result;
+ }
+ continue MAIN_LOOP0;
+
+ } // MAIN_LOOP0
+ }
+
+ private static class TryAnotherResult {
+ REMatch result;
+ int status;
+ static final int RESULT_FOUND = 1;
+ static final int TRY_FURTHER = 2;
+ static final int NOTHING_FOUND = 3;
+ int[] visited;
+ }
+
+ private TryAnotherResult tryAnother(BacktrackStack stack,
+ CharIndexed input, REMatch mymatch, int numRepeats,
+ DoablesFinder finder, int[] visited) {
+
+ TryAnotherResult taresult = new TryAnotherResult();
+ taresult.visited = visited;
+
DO_THIS:
- do {
+ {
boolean emptyMatchFound = false;
@@ -263,61 +382,45 @@ final class RETokenRepeated extends REToken {
if (!emptyMatchFound) {
int n = doable.index;
- if (! visitedContains(n, visited)) {
- visited = addVisited(n, visited);
- }
- else {
+ if (visitedContains(n, visited)) {
continue DO_ONE_DOABLE;
}
+ visited = addVisited(n, visited);
stack.push(new StackedInfo(
- input, numRepeats + 1, doable, visited, null));
- REMatch m1 = findMatch(stack);
- if (possessive) {
- return m1;
- }
- if (m1 != null) {
- m1.backtrackStack.push(new BacktrackStack.Backtrack(
- this, input, mymatch, stack));
- return m1;
- }
+ input, numRepeats + 1, doable, visited, null));
+ taresult.visited = visited;
+ taresult.status = TryAnotherResult.TRY_FURTHER;
+ return taresult;
}
else {
REMatch m1 = matchRest(input, doable);
if (possessive) {
- return m1;
+ taresult.result = m1;
+ taresult.status = TryAnotherResult.RESULT_FOUND;
+ return taresult;
}
if (m1 != null) {
if (! stack.empty()) {
m1.backtrackStack.push(new BacktrackStack.Backtrack(
this, input, mymatch, stack));
- }
- return m1;
+ }
+ taresult.result = m1;
+ taresult.status = TryAnotherResult.RESULT_FOUND;
+ return taresult;
}
}
} // DO_ONE_DOABLE
- } while (false); // DO_THIS only once;
+ } // DO_THIS
- if (!stack.empty()) {
- stack.pop();
- }
- if (possessive) {
- stack.clear();
- }
- REMatch m1 = matchRest(input, mymatch);
- if (m1 != null) {
- if (! stack.empty()) {
- m1.backtrackStack.push(new BacktrackStack.Backtrack(
- this, input, mymatch, stack));
- }
- return m1;
- }
+ taresult.status = TryAnotherResult.NOTHING_FOUND;
+ return taresult;
- } // MAIN_LOOP
}
boolean match(CharIndexed input, REMatch mymatch) {
+ setHitEnd(input, mymatch);
REMatch m1 = findMatch(input, mymatch);
if (m1 != null) {
mymatch.assignFrom(m1);