//
// This software is now distributed according to
// the Lesser Gnu Public License. Please see
// http://www.gnu.org/copyleft/lesser.txt for
// the details.
// -- Happy Computing!
//
package com.stevesoft.ewe_pat;
import ewe.util.Hashtable;
/** A special optimization of multi that is used when the
* common subpattern ".*" is encountered.
*/
class DotMulti extends PatternSub {
patInt fewestMatches,mostMatches;
public patInt minChars() {
return fewestMatches;
}
public patInt maxChars() {
return mostMatches;
}
public boolean matchFewest = false;
StringLike src=null;
int srclength=0;
boolean dotDoesntMatchCR=true;
DotMulti(patInt a,patInt b) {
fewestMatches = a;
mostMatches = b;
}
public String toString() {
return ".{"
+fewestMatches+","+mostMatches+"}"+
(matchFewest ? "?" : "")+"(?# <= dot multi)"+
nextString();
}
final int submatchInternal(int pos,Pthings pt) {
if(pos < srclength) {
if(dotDoesntMatchCR) {
if(src.charAt(pos) != '\n')
return 1+pos;
} else return 1+pos;
}
return -1;
}
final static int step = 1;
static int idcount = 1;
public int matchInternal(int pos,Pthings pt) {
int m=-1;
int i=pos;
src = pt.src;
srclength = src.length();
dotDoesntMatchCR = pt.dotDoesntMatchCR;
if(matchFewest) {
int nMatches = 0;
while(fewestMatches.intValue() > nMatches) {
i=submatchInternal(i,pt);
if(i<0) return -1;
nMatches++;
}
if(i<0) return -1;
int ii = nextMatch(i,pt);
if(ii >= 0) return ii;
if(!mostMatches.finite()) {
while(i >= 0) {
i = submatchInternal(i,pt);
if(i < 0) return -1;
ii = nextMatch(i,pt);
if(ii >= 0) return ii;
}
} else {
while(i > 0) {
i = submatchInternal(i,pt);
if(i < 0) return -1;
nMatches++;
if(nMatches > mostMatches.intValue())
return -1;
ii = nextMatch(i,pt);
if(ii >= 0) return ii;
}
}
return -1;
}
int nMatches = 0;
while(fewestMatches.intValue() > nMatches) {
i=submatchInternal(i,pt);
if(i >= 0)
nMatches++;
else
return -1;
}
m=i;
if(mostMatches.finite()) {
while(nMatches < mostMatches.intValue()) {
i = submatchInternal(i,pt);
if(i>=0) {
m=i;
nMatches++;
} else break;
}
} else {
while(true) {
i = submatchInternal(i,pt);
if(i>=0) {
m=i;
nMatches++;
} else break;
}
}
while(m >= pos) {
int r=nextMatch(m,pt);
if(r >= 0) return r;
m -= step;
nMatches--;
if(nMatches < fewestMatches.intValue())
return -1;
}
return -1;
}
Pattern clone1(Hashtable h) {
DotMulti dm = new DotMulti(fewestMatches,mostMatches);
dm.matchFewest = matchFewest;
return dm;
}
}