You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/03/20 17:31:33 UTC

svn commit: r387239 [10/21] - in /incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math: ./ Harmony/ doc/ doc/images/ make/ src/ src/common/ src/common/javasrc/ src/common/javasrc/java/ src/common/javasrc/java/applet/ src/common/javasrc/ja...

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/DotSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/DotSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/DotSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/DotSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,55 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Node accepting any character except line terminators;
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+final class DotSet extends LeafSet {
+    
+    AbstractLineTerminator lt;
+
+    public DotSet(AbstractLineTerminator lt) {
+        super();
+        this.lt = lt;
+    }
+
+    public int accepts(int strIndex, CharSequence testString) {
+        char ch = testString.charAt(strIndex);
+        return lt.isLineTerminator(ch) ? -1 : 1;
+
+        /*
+         * return (strIndex<testString.length() && testString.charAt(strIndex) !=
+         * '\n') ? 1 : -1;
+         */
+    }
+
+    protected String getName() {
+        return ".";
+    }
+
+    public int getType() {
+        return AbstractSet.TYPE_DOTSET;
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EOISet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EOISet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EOISet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EOISet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,54 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.3.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Represents end of input '\z', i.e. matches only character after the last one;
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.3.2.2 $
+ */
+class EOISet extends AbstractSet {
+
+    public int matches(int stringIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+        int rightBound = matchResult.hasTransparentBounds() ? testString
+                .length() : matchResult.getRightBound();
+        if (stringIndex < rightBound)
+            return -1;
+
+        matchResult.hitEnd = true;
+        matchResult.requireEnd = true;
+
+        return next.matches(stringIndex, testString, matchResult);
+    }
+
+    /**
+     * Returns false, enough for quantifiers
+     */
+    public boolean hasConsumed(MatchResultImpl matchResult) {
+        return false;
+    }
+
+    protected String getName() {
+        return "EOI";
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EOLSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EOLSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EOLSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EOLSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,75 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.8.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Represents node accepting single character.
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.8.2.2 $
+ */
+final class EOLSet extends AbstractSet {
+    
+    private int consCounter;
+
+    public EOLSet(int counter) {
+        this.consCounter = counter;
+    }
+
+    public int matches(int strIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+        int rightBound = matchResult.hasAnchoringBounds() ? matchResult
+                .getRightBound() : testString.length();
+
+        if (strIndex >= rightBound) {
+            matchResult.setConsumed(consCounter, 0);
+            return next.matches(strIndex, testString, matchResult);
+        }
+
+        // check final line terminator;
+        if ((rightBound - strIndex) == 2 && testString.charAt(strIndex) == '\r'
+                && testString.charAt(strIndex + 1) == '\n') {
+            matchResult.setConsumed(consCounter, 0);
+            return next.matches(strIndex, testString, matchResult);
+        }
+        char ch;
+
+        if ((rightBound - strIndex) == 1
+                && (((ch = testString.charAt(strIndex)) == '\n' || ch == '\r'
+                        || ch == '\u0085' || (ch | 1) == '\u2029'))) {
+            matchResult.setConsumed(consCounter, 0);
+            return next.matches(strIndex, testString, matchResult);
+        }
+
+        return -1;
+    }
+
+    public boolean hasConsumed(MatchResultImpl matchResult) {
+        int cons;
+        boolean res = ((cons = matchResult.getConsumed(consCounter)) < 0 || cons > 0);
+        matchResult.setConsumed(consCounter, -1);
+        return res;
+    }
+
+    protected String getName() {
+        return "<EOL>";
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EmptySet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EmptySet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EmptySet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/EmptySet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,54 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.4.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Valid constatnt zero character match.
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.4.2.2 $
+ */
+class EmptySet extends LeafSet {
+
+    public EmptySet(AbstractSet next) {
+        super(next);
+        charCount = 0;
+    }
+
+    /*
+     * @see java.util.regex.LeafSet#accepts(int, java.lang.CharSequence)
+     */
+    public int accepts(int stringIndex, CharSequence testString) {
+        return 0;
+    }
+
+    /*
+     * @see java.util.regex.AbstractSet#getName()
+     */
+    protected String getName() {
+        return "<Empty set>";
+    }
+
+    public boolean hasConsumed(MatchResultImpl mr) {
+        return false;
+    }
+
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/FSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/FSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/FSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/FSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,84 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.8.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * The node which marks end of the particular group.
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.8.2.2 $
+ */
+class FSet extends AbstractSet {
+    
+    static PossessiveFSet posFSet = new PossessiveFSet();
+
+    private int groupIndex;
+
+    public FSet(int groupIndex) {
+        this.groupIndex = groupIndex;
+    }
+
+    public int matches(int stringIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+        int end = matchResult.getEnd(groupIndex);
+        matchResult.setEnd(groupIndex, stringIndex);
+        int shift = next.matches(stringIndex, testString, matchResult);
+        /*
+         * if(shift >=0 && matchResult.getEnd(groupIndex) == -1) {
+         * matchResult.setEnd(groupIndex, stringIndex); }
+         */
+        if (shift < 0)
+            matchResult.setEnd(groupIndex, end);
+        return shift;
+    }
+
+    public int getGroupIndex() {
+        return groupIndex;
+    }
+
+    protected String getName() {
+        return "fSet";
+    }
+
+    public boolean hasConsumed(MatchResultImpl mr) {
+        return false;
+    }
+
+    /**
+     * Marks the end of the particular group and not take into account possible
+     * kickbacks(required for atomic groups, for instance)
+     * 
+     */
+    static class PossessiveFSet extends AbstractSet {
+
+        public int matches(int stringIndex, CharSequence testString,
+                MatchResultImpl matchResult) {
+            return stringIndex;
+        }
+
+        protected String getName() {
+            return "posFSet";
+        }
+
+        public boolean hasConsumed(MatchResultImpl mr) {
+            return false;
+        }
+    }
+}
\ No newline at end of file

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/FinalSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/FinalSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/FinalSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/FinalSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,49 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.6.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Special construction which marks end of pattern.
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.6.2.2 $
+ */
+class FinalSet extends FSet {
+
+    public FinalSet() {
+        super(0);
+    }
+
+    public int matches(int stringIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+        if (matchResult.mode() == Matcher.MODE_FIND
+                || stringIndex == testString.length()) {
+            matchResult.setValid();
+            matchResult.setEnd(0, stringIndex);
+            return stringIndex;
+        }
+        return -1;
+    }
+
+    protected String getName() {
+        return "FinalSet";
+    }
+}
\ No newline at end of file

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/GroupQuantifierSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/GroupQuantifierSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/GroupQuantifierSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/GroupQuantifierSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,56 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Default quantifier over groups, in fact this type of quantifiier is
+ * generally used for constructions we cant identify number of characters they 
+ * consume.
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+class GroupQuantifierSet extends QuantifierSet {
+   
+    public GroupQuantifierSet(AbstractSet innerSet, AbstractSet next, int type) {
+        super(innerSet, next, type);
+    }
+
+    public int matches(int stringIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+
+        if (!innerSet.hasConsumed(matchResult))
+            return next.matches(stringIndex, testString, matchResult);// return
+                                                                        // -1;
+
+        int nextIndex = innerSet.matches(stringIndex, testString, matchResult);
+
+        if (nextIndex < 0) {
+            return next.matches(stringIndex, testString, matchResult);
+        } else {
+            return nextIndex;
+        }
+    }
+
+    protected String getName() {
+        return "<GroupQuant>";
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/I18n.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/I18n.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/I18n.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/I18n.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,47 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.1.2.3 $
+ */
+
+package java.util.regex;
+import java.text.MessageFormat;
+
+/**
+ * Internationalization stub. All the messages in java.util.regexp
+ * package done though this class. This class should be lately replaced with 
+ * real internationalization utility.
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.1.2.3 $
+ * 
+ */
+class I18n {
+	public static String getMessage(String message) {
+		return message;
+	}
+	
+	public static String getFormattedMessage(String message, Object arg1) {
+		return MessageFormat.format(message, new Object[] {arg1});
+	}
+	
+	public static String getFormattedMessage(String message, Object arg1, Object arg2) {
+		return MessageFormat.format(message, new Object[] {arg1, arg2});
+	}
+	
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/JointSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/JointSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/JointSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/JointSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,99 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+package java.util.regex;
+
+import java.util.ArrayList;
+
+/**
+ * Represents group, which is alternation of other subexpression.
+ * One should think about "group" in this model as JointSet opening
+ * group and corresponding FSet closing group.
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.12.2.2 $
+ */
+class JointSet extends AbstractSet {
+    
+    protected ArrayList children;
+
+    protected AbstractSet fSet;
+
+    protected int groupIndex;
+
+    protected JointSet() {
+    }
+
+    public JointSet(ArrayList children, FSet fSet) {
+        this.children = children;
+        this.fSet = fSet;
+        this.groupIndex = fSet.getGroupIndex();
+    }
+
+    /**
+     * Returns stringIndex+shift, the next position to match
+     */
+    public int matches(int stringIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+        int start = matchResult.getStart(groupIndex);
+        matchResult.setStart(groupIndex, stringIndex);
+        int size = children.size();
+        for (int i = 0; i < size; i++) {
+            AbstractSet e = (AbstractSet) children.get(i);
+            int shift = e.matches(stringIndex, testString, matchResult);
+            if (shift >= 0) {
+                return shift;
+            }
+        }
+        matchResult.setStart(groupIndex, start);
+        return -1;
+    }
+
+    public void setNext(AbstractSet next) {
+        fSet.setNext(next);
+    }
+
+    public AbstractSet getNext() {
+        return fSet.getNext();
+    }
+
+    protected String getName() {
+        return "JointSet";
+    }
+
+    public int getGroup() {
+        return groupIndex;
+    }
+
+    public boolean first(AbstractSet set) {
+        for (java.util.Iterator i = children.iterator(); i.hasNext();) {
+            if (((AbstractSet) i.next()).first(set)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public boolean hasConsumed(MatchResultImpl matchResult) {
+        return !(matchResult.getEnd(groupIndex) >= 0 && matchResult
+                .getStart(groupIndex) == matchResult.getEnd(groupIndex));
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/LeafQuantifierSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/LeafQuantifierSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/LeafQuantifierSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/LeafQuantifierSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,73 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.4.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.4.2.2 $
+ */
+class LeafQuantifierSet extends QuantifierSet {
+   
+    protected LeafSet leaf;
+
+    public LeafQuantifierSet(LeafSet innerSet, AbstractSet next, int type) {
+        super(innerSet, next, type);
+        this.leaf = innerSet;
+    }
+
+    public int matches(int stringIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+        int i = 0;
+        int shift = 0;
+
+        while (stringIndex + leaf.charCount() <= matchResult.getRightBound()
+                && (shift = leaf.accepts(stringIndex, testString)) > 0) {
+            stringIndex += shift;
+            i++;
+        }
+
+        for (; i >= 0; i--) {
+            shift = next.matches(stringIndex, testString, matchResult);
+            if (shift >= 0) {
+                return shift;
+            }
+
+            stringIndex--;
+        }
+        return -1;
+    }
+
+    protected String getName() {
+        return "<Quant>";
+    }
+
+    /**
+     * Sets an inner set.
+     * @param innerSet
+     *            The innerSet to set.
+     */
+    public void setInnerSet(AbstractSet innerSet) {
+        if (!(innerSet instanceof LeafSet))
+            throw new RuntimeException("Internal Error");
+        super.setInnerSet(innerSet);
+        this.leaf = (LeafSet) innerSet;
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/LeafSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/LeafSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/LeafSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/LeafSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,79 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.10.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Base class for nodes representing leaf tokens of the RE, those who consumes
+ * fixed number of characters.
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.10.2.2 $
+ */
+abstract class LeafSet extends AbstractSet {
+    
+    protected int charCount = 1;
+
+    public LeafSet(AbstractSet next) {
+        super(next);
+        setType(AbstractSet.TYPE_LEAF);
+    }
+
+    public LeafSet() {
+    }
+
+    /**
+     * Returns "shift", the number of accepted chars commonly internal function,
+     * but called by quantifiers.
+     */
+    public abstract int accepts(int stringIndex, CharSequence testString);
+
+    /**
+     * Checks if we can enter this state and pass the control to the next one.
+     * Return positive value if match succeeds, negative otherwise.
+     */
+    public int matches(int stringIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+
+        if (stringIndex + charCount() > matchResult.getRightBound()) {
+            matchResult.hitEnd = true;
+            return -1;
+        }
+
+        int shift = accepts(stringIndex, testString);
+        if (shift < 0) {
+            return -1;
+        }
+
+        return next.matches(stringIndex + shift, testString, matchResult);
+    }
+
+    /**
+     * Returns number of characters this node consumes.
+     * @return number of characters this node consumes.
+     */
+    public int charCount() {
+        return charCount;
+    }
+
+    public boolean hasConsumed(MatchResultImpl mr) {
+        return true;
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/Lexer.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/Lexer.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/Lexer.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/Lexer.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,918 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.21.2.2 $
+ */
+package java.util.regex;
+
+import java.util.MissingResourceException;
+
+/**
+ * The purpose of this class is to break given pattern into RE tokens; 
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.21.2.2 $
+ */
+class Lexer {
+
+    public static final int CHAR_DOLLAR = 0xe0000000 | '$';
+
+    public static final int CHAR_RIGHT_PARENTHESIS = 0xe0000000 | ')';
+
+    public static final int CHAR_LEFT_SQUARE_BRACKET = 0xe0000000 | '[';
+
+    public static final int CHAR_RIGHT_SQUARE_BRACKET = 0xe0000000 | ']';
+
+    public static final int CHAR_CARET = 0xe0000000 | '^';
+
+    public static final int CHAR_VERTICAL_BAR = 0xe0000000 | '|';
+
+    public static final int CHAR_AMPERSAND = 0xe0000000 | '&';
+
+    public static final int CHAR_HYPHEN = 0xe0000000 | '-';
+
+    public static final int CHAR_DOT = 0xe0000000 | '.';
+
+    public static final int QMOD_GREEDY = 0xe0000000;
+
+    public static final int QMOD_RELUCTANT = 0xc0000000;
+
+    public static final int QMOD_POSSESSIVE = 0x80000000;
+
+    public static final int QUANT_STAR = QMOD_GREEDY | '*';
+
+    public static final int QUANT_STAR_P = QMOD_POSSESSIVE | '*';
+
+    public static final int QUANT_STAR_R = QMOD_RELUCTANT | '*';
+
+    public static final int QUANT_PLUS = QMOD_GREEDY | '+';
+
+    public static final int QUANT_PLUS_P = QMOD_POSSESSIVE | '+';
+
+    public static final int QUANT_PLUS_R = QMOD_RELUCTANT | '+';
+
+    public static final int QUANT_ALT = QMOD_GREEDY | '?';
+
+    public static final int QUANT_ALT_P = QMOD_POSSESSIVE | '?';
+
+    public static final int QUANT_ALT_R = QMOD_RELUCTANT | '?';
+
+    public static final int QUANT_COMP = QMOD_GREEDY | '{';
+
+    public static final int QUANT_COMP_P = QMOD_POSSESSIVE | '{';
+
+    public static final int QUANT_COMP_R = QMOD_RELUCTANT | '{';
+
+    public static final int CHAR_LEFT_PARENTHESIS = 0x80000000 | '(';
+
+    public static final int CHAR_NONCAP_GROUP = 0xc0000000 | '(';
+
+    public static final int CHAR_POS_LOOKAHEAD = 0xe0000000 | '(';
+
+    public static final int CHAR_NEG_LOOKAHEAD = 0xf0000000 | '(';
+
+    public static final int CHAR_POS_LOOKBEHIND = 0xf8000000 | '(';
+
+    public static final int CHAR_NEG_LOOKBEHIND = 0xfc000000 | '(';
+
+    public static final int CHAR_ATOMIC_GROUP = 0xfe000000 | '(';
+
+    public static final int CHAR_FLAGS = 0xff000000 | '(';
+
+    public static final int CHAR_START_OF_INPUT = 0x80000000 | 'A';
+
+    public static final int CHAR_WORD_BOUND = 0x80000000 | 'b';
+
+    public static final int CHAR_NONWORD_BOUND = 0x80000000 | 'B';
+
+    public static final int CHAR_PREVIOUS_MATCH = 0x80000000 | 'G';
+
+    public static final int CHAR_END_OF_INPUT = 0x80000000 | 'z';
+
+    public static final int CHAR_END_OF_LINE = 0x80000000 | 'Z';
+
+    public static final int MODE_PATTERN = 1 << 0;
+
+    public static final int MODE_RANGE = 1 << 1;
+
+    public static final int MODE_ESCAPE = 1 << 2;
+
+    private char[] pattern = null;
+
+    private int flags = 0;
+
+    private int mode = 1;
+
+    // when in literal mode, this field will save the previous one
+    private int saved_mode = 0;
+
+    private int length = 0;
+
+    // previous char read
+    private int lookBack;
+
+    //current character read
+    private int ch;
+
+    //next character
+    private int lookAhead;
+
+    // cur special token
+    private SpecialToken curST = null;
+    
+    // next special token
+    private SpecialToken lookAheadST = null;
+
+    //  cur char being processed
+    private int index = 0; 
+
+    //  previous non-whitespace character index;
+    private int prevNW = 0; 
+
+    //  cur token start index
+    private int curToc = 0; 
+
+    //  look ahead token index
+    private int lookAheadToc = 0; 
+
+    //  original string representing pattern    
+    private String orig = null; 
+
+    public Lexer(String pattern, int flags) {
+        orig = pattern;
+        if ((flags & Pattern.LITERAL) > 0) {
+            pattern = Pattern.quote(pattern);
+        } else if ((flags & Pattern.CANON_EQ) > 0) {
+            pattern = normalize(pattern);
+        }
+
+        this.pattern = new char[pattern.length() + 2];
+        System.arraycopy(pattern.toCharArray(), 0, this.pattern, 0, pattern
+                .length());
+        this.pattern[this.pattern.length - 1] = this.pattern[this.pattern.length - 2] = 0;
+
+        this.flags = flags;
+        // read first two tokens;
+        movePointer();
+        movePointer();
+
+    }
+
+    /**
+     * Returns current character w/o reading next one; if there are no more
+     * characters returns 0;
+     * 
+     * @return current character;
+     */
+    public int peek() {
+        return ch;
+    }
+
+    /**
+     * Set the Lexer to PATTERN or RANGE mode; Lexer interpret character two
+     * different ways in parser or range modes.
+     * 
+     * @param mode
+     *            Lexer.PATTERN or Lexer.RANGE
+     */
+    public void setMode(int mode) {
+        if (mode > 0 && mode < 3) {
+            this.mode = mode;
+        }
+
+        if (mode == Lexer.MODE_PATTERN) {
+            reread();
+        }
+    }
+
+    public void setFlags(int flags) {
+        if (((this.flags ^ flags) & Pattern.COMMENTS) != 0) {
+            this.flags = flags;
+            reread();
+        }
+
+        this.flags = flags;
+    }
+
+    public SpecialToken peekSpecial() {
+        return curST;
+    }
+
+    /**
+     * Returns true, if current token is special, i.e. quantifier, or other 
+     * compound token.
+     * 
+     * @return - true if current token is special, false otherwise.
+     */
+    public boolean isSpecial() {
+        return curST != null;
+    }
+
+    public boolean isQuantifier() {
+        return isSpecial() && curST.getType() == SpecialToken.TOK_QUANTIFIER;
+    }
+
+    public boolean isNextSpecial() {
+        return lookAheadST != null;
+    }
+
+    /**
+     * Returns current character and moves string index to the next one;
+     * 
+     */
+    public int next() {
+        movePointer();
+        return lookBack;
+    }
+
+    /**
+     * Returns current special token and moves string index to the next one;
+     */
+    public SpecialToken nextSpecial() {
+        SpecialToken res = curST;
+        movePointer();
+        return res;
+    }
+
+    /**
+     * Returns nest symbol read.
+     */
+    public int lookAhead() {
+        return lookAhead;
+    }
+
+    /**
+     * Returns previous character.
+     */
+    public int back() {
+        return lookBack;
+    }
+
+    /**
+     * Normalize given expression
+     */
+    private String normalize(String pattern) {
+        // TODO this code is workaround in the abcence of unicode normalization
+        return pattern;
+    }
+
+    /**
+     * Reread current character, may be require if previous token changes mode
+     * to one with different character interpretation.
+     *
+     */
+    private void reread() {
+        lookAhead = ch;
+        lookAheadST = curST;
+        index = lookAheadToc;
+        lookAheadToc = curToc;
+        movePointer();
+    }
+
+    /**
+     * Moves pointer one position right; save current character to lookBack;
+     * lookAhead to current one and finaly read one more to lookAhead;
+     */
+    private void movePointer() {
+        // swap pointers
+        lookBack = ch;
+        ch = lookAhead;
+        curST = lookAheadST;
+        curToc = lookAheadToc;
+        lookAheadToc = index;
+        boolean reread;
+        do {
+            reread = false;
+            // read next character analize it and construct token:
+            // //
+            lookAhead = (index < pattern.length) ? pattern[nextIndex()] : 0;
+            lookAheadST = null;
+
+            if (mode == Lexer.MODE_ESCAPE) {
+                if (lookAhead == '\\') {
+                    lookAhead = (index < pattern.length) ? pattern[nextIndex()]
+                            : 0;
+
+                    switch (lookAhead) {
+                    case 'E': {
+                        mode = saved_mode;
+                        lookAhead = (index < pattern.length - 2) ? pattern[nextIndex()]
+                                : 0;
+                        break;
+                    }
+
+                    default: {
+                        lookAhead = '\\';
+                        index = prevNW;
+                        return;
+                    }
+                    }
+                } else {
+                    return;
+                }
+            }
+
+            if (lookAhead == '\\') {
+                lookAhead = (index < pattern.length - 2) ? pattern[nextIndex()]
+                        : -1;
+                switch (lookAhead) {
+                case -1:
+                    throw new PatternSyntaxException(I18n
+                            .getMessage("Trailing \\"), this.toString(), index);
+                case 'P':
+                case 'p': {
+                    String cs = parseCharClassName();
+                    boolean negative = false;
+
+                    if (lookAhead == 'P')
+                        negative = true;
+                    ;
+                    try {
+                        lookAheadST = AbstractCharClass.getPredefinedClass(cs,
+                                negative);
+                    } catch (MissingResourceException mre) {
+                        throw new PatternSyntaxException(I18n
+                                .getFormattedMessage(
+                                        "Character Class \\p'{'{0}'}'"
+                                                + "is not supported", cs), this
+                                .toString(), index);
+                    }
+                    lookAhead = 0;
+                    break;
+                }
+
+                case 'w':
+                case 's':
+                case 'd':
+                case 'W':
+                case 'S':
+                case 'D': {
+                    lookAheadST = CharClass.getPredefinedClass(new String(
+                            pattern, prevNW, 1), false);
+                    lookAhead = 0;
+                    break;
+                }
+
+                case 'Q': {
+                    saved_mode = mode;
+                    mode = Lexer.MODE_ESCAPE;
+                    reread = true;
+                    break;
+                }
+
+                case 't':
+                    lookAhead = '\t';
+                    break;
+                case 'n':
+                    lookAhead = '\n';
+                    break;
+                case 'r':
+                    lookAhead = '\r';
+                    break;
+                case 'f':
+                    lookAhead = '\f';
+                    break;
+                case 'a':
+                    lookAhead = '\u0007';
+                    break;
+                case 'e':
+                    lookAhead = '\u001B';
+                    break;
+
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9': {
+                    if (mode == Lexer.MODE_PATTERN) {
+                        lookAhead = 0x80000000 | lookAhead;
+                    }
+                    break;
+                }
+
+                case '0':
+                    lookAhead = readOctals();
+                    break;
+                case 'x':
+                    lookAhead = readHex("hexadecimal", 2);
+                    break;
+                case 'u':
+                    lookAhead = readHex("Unicode", 4);
+                    break;
+
+                case 'b':
+                    lookAhead = CHAR_WORD_BOUND;
+                    break;
+                case 'B':
+                    lookAhead = CHAR_NONWORD_BOUND;
+                    break;
+                case 'A':
+                    lookAhead = CHAR_START_OF_INPUT;
+                    break;
+                case 'G':
+                    lookAhead = CHAR_PREVIOUS_MATCH;
+                    break;
+                case 'Z':
+                    lookAhead = CHAR_END_OF_LINE;
+                    break;
+                case 'z':
+                    lookAhead = CHAR_END_OF_INPUT;
+                    break;
+                case 'c': {
+                    if (index < pattern.length - 2) {
+                        lookAhead = (pattern[nextIndex()] & 0x1f);
+                        break;
+                    } else {
+                        throw new PatternSyntaxException("Illegal unsupported "
+                                + "control sequence", this.toString(), index);
+                    }
+                }
+                case 'C':
+                case 'E':
+                case 'F':
+                case 'H':
+                case 'I':
+                case 'J':
+                case 'K':
+                case 'L':
+                case 'M':
+                case 'N':
+                case 'O':
+                case 'R':
+                case 'T':
+                case 'U':
+                case 'V':
+                case 'X':
+                case 'Y':
+                case 'g':
+                case 'h':
+                case 'i':
+                case 'j':
+                case 'k':
+                case 'l':
+                case 'm':
+                case 'o':
+                case 'q':
+                case 'y':
+                    throw new PatternSyntaxException("Illegal unsupported "
+                            + "escape sequence", this.toString(), index);
+
+                default:
+                    break;
+                }
+            } else if (mode == Lexer.MODE_PATTERN) {
+                switch (lookAhead) {
+                case '+':
+                case '*':
+                case '?': {
+                    char mod = (index < pattern.length) ? pattern[index] : '*';
+                    switch (mod) {
+                    case '+': {
+                        lookAhead = lookAhead | Lexer.QMOD_POSSESSIVE;
+                        nextIndex();
+                        break;
+                    }
+                    case '?': {
+                        lookAhead = lookAhead | Lexer.QMOD_RELUCTANT;
+                        nextIndex();
+                        break;
+                    }
+                    default: {
+                        lookAhead = lookAhead | Lexer.QMOD_GREEDY;
+                        break;
+                    }
+                    }
+
+                    break;
+                }
+
+                case '{': {
+                    lookAheadST = processQuantifier(lookAhead);
+                    break;
+                }
+
+                case '$':
+                    lookAhead = CHAR_DOLLAR;
+                    break;
+                case '(': {
+                    if (pattern[index] == '?') {
+                        nextIndex();
+                        char nonCap = pattern[index];
+                        boolean behind = false;
+                        do {
+                            if (!behind) {
+                                switch (nonCap) {
+                                case '!':
+                                    lookAhead = CHAR_NEG_LOOKAHEAD;
+                                    nextIndex();
+                                    break;
+                                case '=':
+                                    lookAhead = CHAR_POS_LOOKAHEAD;
+                                    nextIndex();
+                                    break;
+                                case '>':
+                                    lookAhead = CHAR_ATOMIC_GROUP;
+                                    nextIndex();
+                                    break;
+                                case '<': {
+                                    nextIndex();
+                                    nonCap = pattern[index];
+                                    behind = true;
+                                    break;
+                                }
+                                default: {
+                                    lookAhead = readFlags();
+                                    if (lookAhead >= 128) {
+                                        lookAhead = (lookAhead & 0x7f) << 16;
+                                        flags = lookAhead;
+                                        lookAhead = CHAR_FLAGS | lookAhead;
+                                    } else {
+                                        lookAhead = lookAhead << 16;
+                                        lookAhead = CHAR_NONCAP_GROUP
+                                                | lookAhead;
+                                    }
+                                    break;
+                                }
+                                }
+                            } else {
+                                behind = false;
+                                switch (nonCap) {
+                                case '!':
+                                    lookAhead = CHAR_NEG_LOOKBEHIND;
+                                    nextIndex();
+                                    break;
+                                case '=':
+                                    lookAhead = CHAR_POS_LOOKBEHIND;
+                                    nextIndex();
+                                    break;
+                                default:
+                                    throw new PatternSyntaxException("Unknown "
+                                            + "look behind", this.toString(),
+                                            index);
+                                }
+                            }
+                        } while (behind);
+                    } else {
+                        lookAhead = CHAR_LEFT_PARENTHESIS;
+                    }
+                    break;
+                }
+
+                case ')':
+                    lookAhead = CHAR_RIGHT_PARENTHESIS;
+                    break;
+                case '[': {
+                    lookAhead = CHAR_LEFT_SQUARE_BRACKET;
+                    setMode(Lexer.MODE_RANGE);
+                    break;
+                }
+                case ']': {
+                    if (mode == Lexer.MODE_RANGE) {
+                        lookAhead = CHAR_RIGHT_SQUARE_BRACKET;
+                    }
+                    break;
+                }
+                case '^':
+                    lookAhead = CHAR_CARET;
+                    break;
+                case '|':
+                    lookAhead = CHAR_VERTICAL_BAR;
+                    break;
+                case '.':
+                    lookAhead = CHAR_DOT;
+                    break;
+                default:
+                    break;
+                }
+            } else if (mode == Lexer.MODE_RANGE) {
+                switch (lookAhead) {
+                case '[':
+                    lookAhead = CHAR_LEFT_SQUARE_BRACKET;
+                    break;
+                case ']':
+                    lookAhead = CHAR_RIGHT_SQUARE_BRACKET;
+                    break;
+                case '^':
+                    lookAhead = CHAR_CARET;
+                    break;
+                case '&':
+                    lookAhead = CHAR_AMPERSAND;
+                    break;
+                case '-':
+                    lookAhead = CHAR_HYPHEN;
+                    break;
+                default:
+                    break;
+                }
+            }
+        } while (reread);
+    }
+
+    /**
+     * Parse character classes names and verifies correction of the syntax;
+     */
+    private String parseCharClassName() {
+        StringBuffer sb = new StringBuffer(10);
+        if (index < pattern.length - 2) {
+            // one symbol family
+            if (pattern[index] != '{') {
+                return "Is" + new String(pattern, nextIndex(), 1);
+            }
+
+            nextIndex();
+            char ch = 0;
+            while (index < pattern.length - 2
+                    && (ch = pattern[nextIndex()]) != '}') {
+                sb.append((char) ch);
+            }
+            if (ch != '}')
+                throw new PatternSyntaxException(I18n
+                        .getMessage("Unclosed character family"), this
+                        .toString(), index);
+        }
+
+        if (sb.length() == 0)
+            throw new PatternSyntaxException(I18n
+                    .getMessage("Empty character family"), this.toString(),
+                    index);
+
+        String res = sb.toString();
+        if (res.length() == 1)
+            return "Is" + res;
+        return (res.length() > 3 && (res.startsWith("Is") || res
+                .startsWith("In"))) ? res.substring(2) : res;
+    }
+
+    /**
+     * Process given character in assumption that it's quantifier.
+     */
+    private Quantifier processQuantifier(int ch) {
+        StringBuffer sb = new StringBuffer(4);
+        int min = -1;
+        int max = Integer.MAX_VALUE;
+        while (index < pattern.length && (ch = pattern[nextIndex()]) != '}') {
+            if (ch == ',' && min < 0) {
+                try {
+                    min = Integer.parseInt(sb.toString(), 10);
+                    sb.delete(0, sb.length());
+                } catch (NumberFormatException nfe) {
+                    throw new PatternSyntaxException(I18n
+                            .getMessage("Incorrect Quantifier Syntax"), this
+                            .toString(), index);
+                }
+            } else {
+                sb.append((char) ch);
+            }
+        }
+        if (ch != '}') {
+            throw new PatternSyntaxException(I18n
+                    .getMessage("Incorrect Quantifier Syntax"),
+                    this.toString(), index);
+        }
+        if (sb.length() > 0) {
+            try {
+                max = Integer.parseInt(sb.toString(), 10);
+                if (min < 0)
+                    min = max;
+            } catch (NumberFormatException nfe) {
+                throw new PatternSyntaxException(I18n
+                        .getMessage("Incorrect Quantifier Syntax"), this
+                        .toString(), index);
+            }
+        } else if (min < 0) {
+            throw new PatternSyntaxException(I18n
+                    .getMessage("Incorrect Quantifier Syntax"),
+                    this.toString(), index);
+        }
+        if ((min | max | max - min) < 0) {
+            throw new PatternSyntaxException(I18n
+                    .getMessage("Incorrect Quantifier Syntax"),
+                    this.toString(), index);
+        }
+
+        char mod = (index < pattern.length) ? pattern[index] : '*';
+
+        switch (mod) {
+        case '+':
+            lookAhead = Lexer.QUANT_COMP_P;
+            nextIndex();
+            break;
+        case '?':
+            lookAhead = Lexer.QUANT_COMP_R;
+            nextIndex();
+            break;
+        default:
+            lookAhead = Lexer.QUANT_COMP;
+            break;
+        }
+        return new Quantifier(min, max);
+    }
+
+    public String toString() {
+        return orig;
+    }
+
+    /**
+     * Checks if there are any characters in the pattern.
+     * 
+     * @return true if there are no more characters in the pattern.
+     */
+    public boolean isEmpty() {
+        return ch == 0 && lookAhead == 0 && !isSpecial();
+    }
+
+    /**
+     * Returns true if current character is plain token.
+     */
+    public static boolean isLetter(int ch) {
+        return ch >= 0;
+    }
+
+    /**
+     * Return true if current character is letter, false otherwise; This is
+     * shortcut to static method isLetter to check the current character.
+     * 
+     * @return true if current character is letter, false otherwise
+     */
+    public boolean isLetter() {
+        return !isEmpty() && !isSpecial() && isLetter(ch);
+    }
+
+    /**
+     * Process hexadecimal integer. 
+     */
+    private int readHex(String radixName, int max) {
+        StringBuffer st = new StringBuffer(max);
+        int length = pattern.length - 2;
+        int i;
+        for (i = 0; i < max && index < length; i++) {
+            st.append((char) pattern[nextIndex()]);
+        }
+        if (i == max) {
+            try {
+                return Integer.parseInt(st.toString(), 16);
+            } catch (NumberFormatException nfe) {
+            }
+        }
+
+        throw new PatternSyntaxException(I18n.getMessage("Invalid " + radixName
+                + "escape sequence"), this.toString(), index);
+    }
+
+    /**
+     * Process octal integer.
+     */
+    private int readOctals() {
+        char ch;
+        int max = 3;
+        int i = 1;
+        int first;
+        int res;
+        int length = pattern.length - 2;
+
+        switch (first = Character.digit((ch = pattern[index]), 8)) {
+        case -1:
+            throw new PatternSyntaxException(I18n.getMessage("Invalid "
+                    + "octal escape sequence"), this.toString(), index);
+        default: {
+            if (first > 3)
+                max--;
+            nextIndex();
+            res = first;
+        }
+        }
+
+        while (i < max && index < length
+                && (first = Character.digit((ch = pattern[index]), 8)) >= 0) {
+            res = res * 8 + first;
+            nextIndex();
+            i++;
+        }
+
+        return res;
+    }
+
+    /**
+     * Process expression flags givent with (?idmsux-idmsux)
+     */
+    private int readFlags() {
+        char ch;
+        boolean pos = true;
+        int res = flags;
+        int neg = 0;
+        while (index < pattern.length) {
+            ch = pattern[index];
+            switch (ch) {
+            case '-': {
+                if (!pos)
+                    throw new PatternSyntaxException("Illegal "
+                            + "inline construct", this.toString(), index);
+                pos = false;
+            }
+
+            case 'i':
+                res = pos ? res | Pattern.CASE_INSENSITIVE : res
+                        ^ Pattern.CASE_INSENSITIVE & res;
+                break;
+            case 'd':
+                res = pos ? res | Pattern.UNIX_LINES : res ^ Pattern.UNIX_LINES
+                        & res;
+                break;
+            case 'm':
+                res = pos ? res | Pattern.MULTILINE : res ^ Pattern.MULTILINE
+                        & res;
+                break;
+            case 's':
+                res = pos ? res | Pattern.DOTALL : res ^ Pattern.DOTALL & res;
+                break;
+            case 'u':
+                res = pos ? res | Pattern.UNICODE_CASE : res
+                        ^ Pattern.UNICODE_CASE & res;
+                break;
+            case 'x':
+                res = pos ? res | Pattern.COMMENTS : res ^ Pattern.COMMENTS
+                        & res;
+                break;
+            case ':':
+                nextIndex();
+                return res;
+            case ')':
+                nextIndex();
+                return res | (1 << 7);
+            default:
+                throw new PatternSyntaxException("Illegal inline construct",
+                        this.toString(), index);
+            }
+            nextIndex();
+        }
+        throw new PatternSyntaxException("Illegal inline construct", this
+                .toString(), index);
+    }
+
+    /**
+     * Returns next character index to read and moves pointer to the next one.
+     * If comments flag is on this method will skip comments and whitespaces.
+     * 
+     * The following actions are equivalent if comments flag is off ch =
+     * pattern[index++] == ch = pattern[nextIndex]
+     * 
+     * @return next character index to read.
+     */
+    private int nextIndex() {
+        prevNW = index;
+        if ((flags & Pattern.COMMENTS) != 0) {
+            skipComments();
+        } else {
+            index++;
+        }
+        return prevNW;
+    }
+
+    /**
+     * Skips comments and whitespaces
+     */
+    private int skipComments() {
+        int length = pattern.length - 2;
+        index++;
+        do {
+            while (index < length && Character.isWhitespace(pattern[index]))
+                index++;
+            if (index < length && pattern[index] == '#') {
+                index++;
+                while (index < length && !isLineSeparator(pattern[index]))
+                    index++;
+            } else
+                return index;
+        } while (true);
+    }
+
+    private boolean isLineSeparator(int ch) {
+        return (ch == '\n' || ch == '\r' || ch == '\u0085' || (ch | 1) == '\u2029');
+    }
+
+    /**
+     * Returns the curr. character index.
+     */
+    public int getIndex() {
+        return curToc;
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MatchResult.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MatchResult.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MatchResult.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MatchResult.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,65 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.6.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * @com.intel.drl.spec_ref
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.6.2.2 $
+ */
+public interface MatchResult {
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    int end();
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    int end(int group);
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    String group();
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    String group(int group);
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    int groupCount();
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    int start();
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    int start(int group);
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MatchResultImpl.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MatchResultImpl.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MatchResultImpl.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MatchResultImpl.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,261 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.15.2.2 $
+ */
+package java.util.regex;
+
+import java.util.Arrays;
+
+/**
+ * Match result implementaion
+ * Note: probably it might make sense to combine this class with Matcher.
+ *  
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.15.2.2 $
+ */
+class MatchResultImpl implements MatchResult {
+
+    private int[] groupBounds = null;
+
+    private int[] consumers = null;
+
+    private int[] compQuantCounters = null;
+
+    private CharSequence string = null;
+
+    private int groupCount = 0;
+
+    private boolean valid = false;
+
+    private int leftBound;
+
+    private int rightBound;
+
+    int startIndex;
+
+    private boolean transparentBounds = false;
+
+    private boolean anchoringBounds = false;
+
+    boolean hitEnd = false;
+
+    boolean requireEnd = false;
+
+    int previousMatch = -1;
+
+    private int mode;
+
+    MatchResultImpl(CharSequence string, int leftBound, int rightBound,
+            int groupCount, int compQuantCount, int consumersCount) {
+        this.groupCount = ++groupCount;
+        this.groupBounds = new int[groupCount * 2];
+
+        this.consumers = new int[consumersCount];
+        Arrays.fill(consumers, -1);
+
+        if (compQuantCount > 0)
+            this.compQuantCounters = new int[compQuantCount];
+        Arrays.fill(groupBounds, -1);
+        reset(string, leftBound, rightBound);
+    }
+
+    MatchResult cloneImpl() {
+        MatchResultImpl res = new MatchResultImpl(this.string, this.leftBound,
+                this.rightBound, this.groupCount - 1, 0, 0);
+
+        System.arraycopy(groupBounds, 0, res.groupBounds, 0,
+                this.groupBounds.length);
+
+        return res;
+    }
+
+    public void setConsumed(int counter, int value) {
+        this.consumers[counter] = value;
+    }
+
+    public int getConsumed(int counter) {
+        return this.consumers[counter];
+    }
+
+    public int end() {
+        return end(0);
+    }
+
+    public int end(int group) {
+        checkGroup(group);
+        return groupBounds[group * 2 + 1];
+    }
+
+    void setStart(int group, int offset) {
+        groupBounds[group * 2] = offset;
+    }
+
+    void setEnd(int group, int offset) {
+        groupBounds[group * 2 + 1] = offset;
+    }
+
+    int getStart(int group) {
+        return groupBounds[group * 2];
+    }
+
+    int getEnd(int group) {
+        return groupBounds[group * 2 + 1];
+    }
+
+    public String group() {
+        return group(0);
+    }
+
+    public String group(int group) {
+        if (start(group) < 0)
+            return null;
+        return string.subSequence(start(group), end(group)).toString();
+    }
+
+    String getGroupNoCheck(int group) {
+        int st = getStart(group);
+        int end = getEnd(group);
+        if ((end | st | (end - st)) < 0 || end > string.length())
+            return null;
+
+        return string.subSequence(st, end).toString();
+    }
+
+    public int groupCount() {
+        return groupCount - 1;
+    }
+
+    public int start() {
+        return start(0);
+    }
+
+    public int start(int group) {
+        checkGroup(group);
+        return groupBounds[group * 2];
+    }
+
+    /*
+     * This method being called after any successfull match; For now it's being
+     * used to check zero group for empty match;
+     */
+    public void finalizeMatch() {
+        if (this.groupBounds[0] == -1) {
+            this.groupBounds[0] = this.startIndex;
+            this.groupBounds[1] = this.startIndex;
+        }
+
+        previousMatch = end();
+    }
+
+    public int getEnterCounter(int setCounter) {
+        return compQuantCounters[setCounter];
+    }
+
+    public void setEnterCounter(int setCounter, int value) {
+        compQuantCounters[setCounter] = value;
+    }
+
+    private void checkGroup(int group) {
+        if (!valid) {
+            throw new IllegalStateException(I18n.getMessage("No match found"));
+        }
+
+        if (group < 0 || group > groupCount) {
+            throw new IndexOutOfBoundsException(I18n.getFormattedMessage(
+                    "Group index out of bounds: {0}", new Integer(group)));
+        }
+    }
+
+    void updateGroup(int index, int srtOffset, int endOffset) {
+        checkGroup(index);
+        groupBounds[index * 2] = srtOffset;
+        groupBounds[index * 2 + 1] = endOffset;
+    }
+
+    protected void setValid() {
+        this.valid = true;
+    }
+
+    protected boolean isValid() {
+        return this.valid;
+    }
+
+    protected void reset(CharSequence newSequence, int leftBound, int rightBound) {
+        valid = false;
+        mode = Matcher.MODE_MATCH;
+        Arrays.fill(groupBounds, -1);
+        Arrays.fill(consumers, -1);
+
+        if (newSequence != null)
+            this.string = newSequence;
+        if (leftBound >= 0)
+            this.setBounds(leftBound, rightBound);
+        this.startIndex = this.leftBound;
+    }
+
+    protected void reset() {
+        reset(null, -1, -1);
+    }
+
+    private void setBounds(int leftBound, int rightBound) {
+        this.leftBound = leftBound;
+        this.rightBound = rightBound;
+    }
+
+    protected void setStartIndex(int startIndex) {
+        this.startIndex = startIndex;
+        previousMatch = previousMatch >= 0 ? previousMatch : startIndex;
+    }
+
+    public int getLeftBound() {
+        return this.leftBound;
+    }
+
+    public int getRightBound() {
+        return this.rightBound;
+    }
+
+    protected void setMode(int mode) {
+        this.mode = mode;
+    }
+
+    protected int mode() {
+        return mode;
+    }
+
+    protected void useAnchoringBounds(boolean value) {
+        this.anchoringBounds = value;
+    }
+
+    protected boolean hasAnchoringBounds() {
+        return this.anchoringBounds;
+    }
+
+    protected void useTransparentBounds(boolean value) {
+        this.transparentBounds = value;
+    }
+
+    protected boolean hasTransparentBounds() {
+        return this.transparentBounds;
+    }
+
+    int getPreviousMatchEnd() {
+        return previousMatch;
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/Matcher.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/Matcher.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/Matcher.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/Matcher.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,514 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.22.2.2 $
+ */
+package java.util.regex;
+
+import java.util.ArrayList;
+
+/**
+ * @com.intel.drl.spec_ref
+ * 
+ * Note: main functionality of this class is hidden into nodes match methods. 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.22.2.2 $
+ */
+public final class Matcher implements MatchResult {
+
+    static int MODE_FIND = 1 << 0;
+
+    static int MODE_MATCH = 1 << 1;
+
+    private Pattern pat = null;
+
+    private AbstractSet start = null;
+
+    private CharSequence string = null;
+
+    private MatchResultImpl matchResult = null;
+
+    // bounds
+    private int leftBound = -1;
+
+    private int rightBound = -1;
+
+    // replacements
+    private int appendPos = 0;
+
+    private String replacement = null;
+
+    private String processedRepl = null;
+
+    private ArrayList replacementParts = null;
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public Matcher appendReplacement(StringBuffer sb, String replacement) {
+        processedRepl = processReplacement(replacement);
+        sb.append(string.subSequence(appendPos, start()));
+        sb.append(processedRepl);
+        appendPos = end();
+        return this;
+    }
+
+    /**
+     * Parses replacement string and creates pattern
+     */
+    private String processReplacement(String replacement) {
+        if (this.replacement == replacement) {
+            if (replacementParts == null) {
+                return processedRepl;
+            } else {
+                StringBuffer sb = new StringBuffer();
+                for (int i = 0; i < replacementParts.size(); i++) {
+                    sb.append(replacementParts.get(i));
+                }
+
+                return sb.toString();
+            }
+        } else {
+            this.replacement = replacement;
+            char[] repl = replacement.toCharArray();
+            StringBuffer res = new StringBuffer();
+            replacementParts = null;
+
+            int index = 0;
+            int replacementPos = 0;
+            boolean nextBackSlashed = false;
+
+            while (index < repl.length) {
+                if (repl[index] == '\\' && !nextBackSlashed) {
+                    nextBackSlashed = true;
+                } else {
+                    if (nextBackSlashed) {
+                        res.append(repl[index]);
+                        nextBackSlashed = false;
+                    } else {
+                        if (repl[index] == '$') {
+                            if (replacementParts == null) {
+                                replacementParts = new ArrayList();
+                            }
+                            try {
+                                final int gr = Integer.parseInt(new String(
+                                        repl, ++index, 1));
+
+                                if (replacementPos != res.length()) {
+                                    replacementParts.add(res.subSequence(
+                                            replacementPos, res.length()));
+                                    replacementPos = res.length();
+                                }
+
+                                replacementParts.add(new Object() {
+                                    private final int grN = gr;
+
+                                    public String toString() {
+                                        return group(grN);
+                                    }
+                                });
+                                String group = group(gr);
+                                replacementPos += group.length();
+                                res.append(group);
+
+                            } catch (IndexOutOfBoundsException iob) {
+                                throw iob;
+                            } catch (Exception e) {
+                                throw new IllegalArgumentException(I18n
+                                        .getMessage("Illegal group reference"));
+                            }
+                        } else {
+                            res.append(repl[index]);
+                        }
+                    }
+                }
+
+                index++;
+            }
+
+            if (replacementParts != null && replacementPos != res.length()) {
+                replacementParts.add(res.subSequence(replacementPos, res
+                        .length()));
+            }
+            return res.toString();
+        }
+    }
+
+    /**
+     * Shortcut for resetImpl(CharSequence)
+     * 
+     */
+    /*
+     * private void resetImpl() { //matchResult.reset() resetImpl(null); }
+     */
+
+    /**
+     * Reset(CharacterSequence) implementation;
+     * 
+     */
+    private void resetImpl(CharSequence string) {
+        if (string != null) {
+            this.string = string;
+            this.leftBound = 0;
+            this.rightBound = string.length();
+            matchResult.reset(string, leftBound, rightBound);
+        } else {
+            matchResult.reset();
+        }
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public Matcher reset(CharSequence newSequence) {
+        if (newSequence == null) {
+            throw new NullPointerException(I18n.getMessage("Incorrect input"));
+        }
+        this.string = newSequence;
+        return reset();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public Matcher reset() {
+        this.leftBound = 0;
+        this.rightBound = string.length();
+        matchResult.reset(string, leftBound, rightBound);
+        appendPos = 0;
+        replacement = null;
+        matchResult.previousMatch = -1;
+        return this;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public Matcher region(int leftBound, int rightBound) {
+
+        if (leftBound > rightBound || leftBound < 0 || rightBound < 0
+                || leftBound > string.length() || rightBound > string.length()) {
+            throw new IndexOutOfBoundsException(I18n.getFormattedMessage(
+                    "Region indices out of bounds: " + "from {0} to {1}",
+                    Integer.toString(leftBound), Integer.toString(rightBound)));
+        }
+
+        this.leftBound = leftBound;
+        this.rightBound = rightBound;
+        matchResult.reset(null, leftBound, rightBound);
+        appendPos = 0;
+        replacement = null;
+
+        return this;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public StringBuffer appendTail(StringBuffer sb) {
+        return sb.append(string.subSequence(appendPos, string.length()));
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public String replaceFirst(String replacement) {
+        reset();
+        if (find()) {
+            StringBuffer sb = new StringBuffer();
+            appendReplacement(sb, replacement);
+            return appendTail(sb).toString();
+        }
+
+        return string.toString();
+
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public String replaceAll(String replacement) {
+        StringBuffer sb = new StringBuffer();
+        reset();
+        while (find()) {
+            appendReplacement(sb, replacement);
+        }
+
+        return appendTail(sb).toString();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public Pattern pattern() {
+        return pat;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public String group(int groupIndex) {
+        return matchResult.group(groupIndex);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public String group() {
+        return group(0);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean find(int startIndex) {
+        int stringLength = string.length();
+        if (startIndex < 0 || startIndex > stringLength)
+            throw new IndexOutOfBoundsException(I18n.getFormattedMessage(
+                    "Start index " + "out of bounds: {0}", new Integer(
+                            startIndex)));
+
+        startIndex = findAt(startIndex);
+        if (startIndex >= 0 && matchResult.isValid()) {
+            matchResult.finalizeMatch();
+            return true;
+        }
+        matchResult.startIndex = -1;
+        return false;
+    }
+
+    private int findAt(int startIndex) {
+        matchResult.reset();
+        matchResult.setMode(Matcher.MODE_FIND);
+        matchResult.setStartIndex(startIndex);
+        return start.find(startIndex, string, matchResult);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean find() {
+        int length = string.length();
+        if (!hasTransparentBounds())
+            length = rightBound;
+        if (matchResult.startIndex >= 0
+                && matchResult.mode() == Matcher.MODE_FIND) {
+            matchResult.startIndex = matchResult.end();
+            if (matchResult.end() == matchResult.start()) {
+                matchResult.startIndex++;
+            }
+
+            return matchResult.startIndex <= length ? find(matchResult.startIndex)
+                    : false;
+        } else {
+            return find(leftBound);
+        }
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public int start(int groupIndex) {
+        return matchResult.start(groupIndex);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public int end(int groupIndex) {
+        return matchResult.end(groupIndex);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean matches() {
+        return lookingAt(leftBound, Matcher.MODE_MATCH);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public static String quoteReplacement(String string) {
+        // first check whether we have smth to quote
+        if (string.indexOf('\\') < 0 && string.indexOf('$') < 0)
+            return string;
+        StringBuffer res = new StringBuffer(string.length() * 2);
+        char ch;
+        int len = string.length();
+
+        for (int i = 0; i < len; i++) {
+
+            switch (ch = string.charAt(i)) {
+            case '$':
+                res.append('\\');
+                res.append('$');
+                break;
+            case '\\':
+                res.append('\\');
+                res.append('\\');
+                break;
+            default:
+                res.append(ch);
+            }
+        }
+
+        return res.toString();
+    }
+
+    /**
+     * Runs match starting from <code>set</code> specified against input
+     * sequence starting at <code>index</code> specified; Result of the match
+     * will be stored into matchResult instance;
+     */
+    private boolean runMatch(AbstractSet set, int index,
+            MatchResultImpl matchResult) {
+
+        if (set.matches(index, string, matchResult) >= 0) {
+            matchResult.finalizeMatch();
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean lookingAt() {
+        return lookingAt(leftBound, Matcher.MODE_FIND);
+    }
+
+    private boolean lookingAt(int startIndex, int mode) {
+        matchResult.reset();
+        matchResult.setMode(mode);
+        matchResult.setStartIndex(startIndex);
+        return runMatch(start, startIndex, matchResult);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public int start() {
+        return start(0);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public int groupCount() {
+        return matchResult.groupCount();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public int end() {
+        return end(0);
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public MatchResult toMatchResult() {
+        return this.matchResult.cloneImpl();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public Matcher useAnchoringBounds(boolean value) {
+        matchResult.useAnchoringBounds(value);
+        return this;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean hasAnchoringBounds() {
+        return matchResult.hasAnchoringBounds();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public Matcher useTransparentBounds(boolean value) {
+        matchResult.useTransparentBounds(value);
+        return this;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean hasTransparentBounds() {
+        return matchResult.hasTransparentBounds();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public int regionStart() {
+        return matchResult.getLeftBound();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public int regionEnd() {
+        return matchResult.getRightBound();
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean requireEnd() {
+        return matchResult.requireEnd;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public boolean hitEnd() {
+        return matchResult.hitEnd;
+    }
+
+    /**
+     * @com.intel.drl.spec_ref
+     */
+    public Matcher usePattern(Pattern pat) {
+        int startIndex = matchResult.getPreviousMatchEnd();
+        int mode = matchResult.mode();
+        this.pat = pat;
+        this.start = pat.start;
+        matchResult = new MatchResultImpl(this.string, leftBound, rightBound,
+                pat.groupCount(), pat.compCount(), pat.consCount());
+        matchResult.setStartIndex(startIndex);
+        matchResult.setMode(mode);
+        return this;
+    }
+
+    Matcher(Pattern pat, CharSequence cs) {
+        this.pat = pat;
+        this.start = pat.start;
+        this.string = cs;
+        this.leftBound = 0;
+        this.rightBound = string.length();
+        matchResult = new MatchResultImpl(cs, leftBound, rightBound, pat
+                .groupCount(), pat.compCount(), pat.consCount());
+    }
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MultiLineEOLSet.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MultiLineEOLSet.java?rev=387239&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MultiLineEOLSet.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/regex-beans-math/src/common/javasrc/java/util/regex/MultiLineEOLSet.java Mon Mar 20 08:31:09 2006
@@ -0,0 +1,88 @@
+/*
+ *  Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.8.2.2 $
+ */
+package java.util.regex;
+
+/**
+ * Represents multiline version of the dollar sign.
+ * 
+ * @author Nikolay A. Kuznetsov
+ * @version $Revision: 1.8.2.2 $
+ */
+class MultiLineEOLSet extends AbstractSet {
+   
+    private int consCounter;
+
+    public MultiLineEOLSet(int counter) {
+        this.consCounter = counter;
+    }
+
+    public int matches(int strIndex, CharSequence testString,
+            MatchResultImpl matchResult) {
+        int strDif = matchResult.hasAnchoringBounds() ? matchResult
+                .getLeftBound()
+                - strIndex : testString.length() - strIndex;
+        char ch1;
+        char ch2;
+        if (strDif == 0) {
+            matchResult.setConsumed(consCounter, 0);
+            return next.matches(strIndex, testString, matchResult);
+        } else if (strDif >= 2) {
+            ch1 = testString.charAt(strIndex);
+            ch2 = testString.charAt(strIndex + 1);
+        } else {
+            ch1 = testString.charAt(strIndex);
+            ch2 = 'a';
+        }
+
+        switch (ch1) {
+        case '\r': {
+            if (ch2 == '\n') {
+                matchResult.setConsumed(consCounter, 0);
+                return next.matches(strIndex, testString, matchResult);
+            }
+            matchResult.setConsumed(consCounter, 0);
+            return next.matches(strIndex, testString, matchResult);
+        }
+
+        case '\n':
+        case '\u0085':
+        case '\u2028':
+        case '\u2029': {
+            matchResult.setConsumed(consCounter, 0);
+            return next.matches(strIndex, testString, matchResult);
+        }
+
+        default:
+            return -1;
+        }
+    }
+
+    public boolean hasConsumed(MatchResultImpl matchResult) {
+        int cons;
+        boolean res = ((cons = matchResult.getConsumed(consCounter)) < 0 || cons > 0);
+        matchResult.setConsumed(consCounter, -1);
+        return res;
+    }
+
+    protected String getName() {
+        return "<MultiLine $>";
+    }
+}