990b0e61e43e95b7c3884fd6357f8a1f7cd7e31d
[jalview.git] / src / com / stevesoft / pat / Multi_stage2.java
1 //\r
2 // This software is now distributed according to\r
3 // the Lesser Gnu Public License.  Please see\r
4 // http://www.gnu.org/copyleft/lesser.txt for\r
5 // the details.\r
6 //    -- Happy Computing!\r
7 //\r
8 package com.stevesoft.pat;\r
9 \r
10 import java.util.*;\r
11 \r
12 /** If Multi were not split into a second stage, then\r
13  a nested Multi would try to re-use the same count\r
14  variable and the whole thing would break. */\r
15 class Multi_stage2\r
16     extends PatternSub\r
17 {\r
18   Pattern nextRet;\r
19   patInt count;\r
20   patInt matchMin, matchMax;\r
21   public boolean matchFewest = false;\r
22   public String toString()\r
23   {\r
24     String ret = "";\r
25     ret += sub.toString();\r
26     ret += "{" + matchMin + "," + matchMax + "}";\r
27     if (matchFewest)\r
28     {\r
29       ret += "?";\r
30     }\r
31     ret += parent.nextString();\r
32     return ret;\r
33   }\r
34 \r
35   Multi_stage2(patInt a, patInt b, Pattern p)\r
36       throws RegSyntax\r
37   {\r
38     if (p == null)\r
39     {\r
40       RegSyntaxError.endItAll(\r
41           "Multiple match of Null pattern requested.");\r
42     }\r
43     sub = p;\r
44     nextRet = this;\r
45     sub.setParent(this);\r
46     matchMin = a;\r
47     matchMax = b;\r
48     count = new patInt(0);\r
49     // we must have b > a > -1 for this\r
50     // to make sense.\r
51     if (!a.lessEq(b))\r
52     {\r
53       //throw new BadMultiArgs();\r
54       RegSyntaxError.endItAll("Bad Multi Args: " + a + ">" + b);\r
55     }\r
56     patInt i = new patInt( -1);\r
57     if (a.lessEq(i))\r
58     {\r
59       //throw new BadMultiArgs();\r
60       RegSyntaxError.endItAll("Bad Multi Args: " + a + "< 0");\r
61     }\r
62   }\r
63 \r
64   public Pattern getNext()\r
65   {\r
66     return nextRet;\r
67   }\r
68 \r
69   int pos_old = -1;\r
70   public int matchInternal(int pos, Pthings pt)\r
71   {\r
72     sub.setParent(this);\r
73 \r
74     int canUse = -1;\r
75 \r
76     // check for some forms of infinite recursion...\r
77     if (pos_old >= 0 && pos == pos_old)\r
78     {\r
79       return -1;\r
80     }\r
81     pos_old = pos;\r
82 \r
83     if (matchMin.lessEq(count))\r
84     {\r
85       canUse = pos;\r
86     }\r
87     if (!count.lessEq(matchMax) || pos > pt.src.length())\r
88     {\r
89       return -1;\r
90     }\r
91 \r
92     if ( (matchFewest || count.equals(matchMax)) && canUse >= 0)\r
93     {\r
94       Pattern n = super.getNext();\r
95       if (n == null)\r
96       {\r
97         return canUse;\r
98       }\r
99       int ret = testMatch(n, pos, pt);\r
100       if (ret >= 0)\r
101       {\r
102         return ret;\r
103       }\r
104       else\r
105       {\r
106         canUse = -1;\r
107       }\r
108     }\r
109 \r
110     count.inc();\r
111     try\r
112     {\r
113       if (count.lessEq(matchMax))\r
114       {\r
115         int r = testMatch(sub, pos, pt);\r
116         if (r >= 0)\r
117         {\r
118           return r;\r
119         }\r
120       }\r
121     }\r
122     finally\r
123     {\r
124       count.dec();\r
125     }\r
126 \r
127     if (!matchFewest && canUse >= 0)\r
128     {\r
129       Pattern n = super.getNext();\r
130       if (n == null)\r
131       {\r
132         return canUse;\r
133       }\r
134       int ret = testMatch(n, pos, pt);\r
135       return ret;\r
136     }\r
137     else\r
138     {\r
139       return canUse;\r
140     }\r
141   }\r
142 \r
143   public Pattern clone1(Hashtable h)\r
144   {\r
145     try\r
146     {\r
147       Multi_stage2 m = new Multi_stage2(matchMin, matchMax, sub.clone(h));\r
148       m.matchFewest = matchFewest;\r
149       return m;\r
150     }\r
151     catch (RegSyntax rs)\r
152     {\r
153       return null;\r
154     }\r
155   }\r
156 };\r