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 $>";
+ }
+}