// // 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.pat; import java.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; } }