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