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
6 // -- Happy Computing!
\r
8 package com.stevesoft.pat;
\r
12 /** A special case of Multi, implemented when minChars().equals(maxChars()),
\r
13 * and some other conditions spelled out in RegOpt.safe4fm "Safe for
\r
14 * FastMulti." It avoids stack growth problems as well as being slightly
\r
20 patInt fewestMatches, mostMatches;
\r
21 public patInt minChars()
\r
23 return sub.countMinChars().mul(fewestMatches);
\r
26 public patInt maxChars()
\r
28 return sub.countMaxChars().mul(mostMatches);
\r
31 public boolean matchFewest = false;
\r
33 FastMulti(patInt a, patInt b, Pattern p)
\r
38 RegSyntaxError.endItAll("Null length pattern " +
\r
39 "followed by *, +, or other Multi.");
\r
44 step = p.countMinChars().intValue();
\r
45 sub.setParent(null);
\r
48 public String toString()
\r
50 return sub.toString() + "{"
\r
51 + fewestMatches + "," + mostMatches + "}" +
\r
52 (matchFewest ? "?" : "") + "(?# <= fast multi)" +
\r
57 public int matchInternal(int pos, Pthings pt)
\r
61 int endstr = pt.src.length() - step;
\r
62 patInt matches = new patInt(0);
\r
65 if (fewestMatches.lessEq(matches))
\r
67 int ii = nextMatch(i, pt);
\r
73 while (i >= 0 && i <= endstr)
\r
75 i = sub.matchInternal(i, pt);
\r
79 if (fewestMatches.lessEq(matches))
\r
81 int ii = nextMatch(i, pt);
\r
87 if (matches.equals(mostMatches))
\r
96 while (fewestMatches.intValue() > nMatches)
\r
98 i = sub.matchInternal(i, pt);
\r
109 if (mostMatches.finite())
\r
111 while (nMatches < mostMatches.intValue())
\r
113 i = sub.matchInternal(i, pt);
\r
129 i = sub.matchInternal(i, pt);
\r
143 int r = nextMatch(m, pt);
\r
150 if (nMatches < fewestMatches.intValue())
\r
158 public Pattern clone1(Hashtable h)
\r
162 FastMulti fm = new FastMulti(fewestMatches, mostMatches, sub.clone(h));
\r
163 fm.matchFewest = matchFewest;
\r
166 catch (RegSyntax rs)
\r