needed for applet search
[jalview.git] / src / com / stevesoft / pat / Multi_stage2.java
diff --git a/src/com/stevesoft/pat/Multi_stage2.java b/src/com/stevesoft/pat/Multi_stage2.java
new file mode 100755 (executable)
index 0000000..41afa39
--- /dev/null
@@ -0,0 +1,103 @@
+//\r
+// This software is now distributed according to\r
+// the Lesser Gnu Public License.  Please see\r
+// http://www.gnu.org/copyleft/lesser.txt for\r
+// the details.\r
+//    -- Happy Computing!\r
+//\r
+package com.stevesoft.pat;\r
+import java.util.Hashtable;\r
+\r
+/** If Multi were not split into a second stage, then\r
+ a nested Multi would try to re-use the same count\r
+ variable and the whole thing would break. */\r
+class Multi_stage2 extends PatternSub {\r
+    Pattern nextRet;\r
+    patInt count;\r
+    patInt matchMin,matchMax;\r
+    public boolean matchFewest = false;\r
+    public String toString() {\r
+        String ret = "";\r
+        ret += sub.toString();\r
+        ret += "{"+matchMin+","+matchMax+"}";\r
+        if(matchFewest) ret += "?";\r
+        ret += parent.nextString();\r
+        return ret;\r
+    }\r
+    Multi_stage2(patInt a,patInt b,Pattern p) throws RegSyntax {\r
+        if(p == null) RegSyntaxError.endItAll(\r
+                "Multiple match of Null pattern requested.");\r
+        sub = p;\r
+        nextRet = this;\r
+        sub.setParent(this);\r
+        matchMin = a;\r
+        matchMax = b;\r
+        count = new patInt(0);\r
+        // we must have b > a > -1 for this\r
+        // to make sense.\r
+        if(!a.lessEq(b))\r
+            //throw new BadMultiArgs();\r
+            RegSyntaxError.endItAll("Bad Multi Args: "+a+">"+b);\r
+        patInt i = new patInt(-1);\r
+        if(a.lessEq(i))\r
+            //throw new BadMultiArgs();\r
+            RegSyntaxError.endItAll("Bad Multi Args: "+a+"< 0");\r
+    }\r
+    public Pattern getNext() {\r
+        return nextRet;\r
+    }\r
+    int pos_old = -1;\r
+    public int matchInternal(int pos,Pthings pt) {\r
+        sub.setParent(this);\r
+\r
+        int canUse = -1;\r
+\r
+        // check for some forms of infinite recursion...\r
+        if(pos_old >= 0 && pos == pos_old) {\r
+            return -1;\r
+        }\r
+        pos_old = pos;\r
+\r
+        if(matchMin.lessEq(count))\r
+            canUse = pos;\r
+        if(!count.lessEq(matchMax) || pos > pt.src.length())\r
+            return -1;\r
+\r
+        if((matchFewest||count.equals(matchMax)) && canUse >= 0) {\r
+            Pattern n = super.getNext();\r
+            if(n == null)\r
+                return canUse;\r
+            int ret = testMatch(n,pos,pt);\r
+            if(ret >= 0) {\r
+               return ret;\r
+            }\r
+            else canUse = -1;\r
+        }\r
+\r
+        count.inc();\r
+        try {\r
+            if(count.lessEq(matchMax)) {\r
+                int r = testMatch(sub,pos,pt);\r
+                if(r >= 0)\r
+                    return r;\r
+            }\r
+        } finally { count.dec(); }\r
+\r
+        if(!matchFewest && canUse >= 0) {\r
+            Pattern n = super.getNext();\r
+            if(n == null)\r
+                return canUse;\r
+            int ret = testMatch(n,pos,pt);\r
+            return ret;\r
+        } else return canUse;\r
+    }\r
+    public Pattern clone1(Hashtable h) {\r
+        try {\r
+            Multi_stage2 m = new Multi_stage2(matchMin,matchMax,sub.clone(h));\r
+            m.matchFewest = matchFewest;\r
+            return m;\r
+        } catch(RegSyntax rs) {\r
+            return null;\r
+        }\r
+    }\r
+};\r