-//\r
-// This software is now distributed according to\r
-// the Lesser Gnu Public License. Please see\r
-// http://www.gnu.org/copyleft/lesser.txt for\r
-// the details.\r
-// -- Happy Computing!\r
-//\r
-package com.stevesoft.pat;\r
-\r
-/** This class is used internally to search ahead for some\r
- optimized Regex objects. It searches within a String\r
- for occrences of a given String -- like a more flexible\r
- version of String.indexOf.\r
- @see com.stevesoft.pat.Skip2\r
- @see com.stevesoft.pat.SkipBMH\r
- */\r
-public class Skip\r
-{\r
- static int mkmask(int c)\r
- {\r
- char x = (char) c;\r
- return~ (CaseMgr.toUpperCase(x) |\r
- CaseMgr.toLowerCase(x) |\r
- CaseMgr.toTitleCase(x));\r
- }\r
-\r
- String src;\r
- int c, mask;\r
- int offset;\r
- boolean ign, m1;\r
- /** Examine a Regex to determine what String it will\r
- attempt to skip to when searching for patterns.\r
- Return -1 if we aren't doing this. */\r
- public static String string(Regex r)\r
- {\r
- return r.skipper == null ? null : r.skipper.src;\r
- }\r
-\r
- /** Determine the offset of the String within the pattern\r
- that we are skipping to. Return -1 if we aren't doing\r
- this. */\r
- public static int offset(Regex r)\r
- {\r
- return r.skipper == null ? -1 : r.skipper.offset;\r
- }\r
-\r
- /** Initialize, give it a String to search for, tell it\r
- whether or not to ignoreCase, and what the offset is\r
- of the String within the String to be searched. */\r
- public Skip(String s, boolean ign, int o)\r
- {\r
- src = s;\r
- c = s.charAt(0);\r
- if (ign)\r
- {\r
- mask = mkmask(c);\r
- }\r
- else\r
- {\r
- mask = 0;\r
- }\r
- offset = o;\r
- this.ign = ign;\r
- m1 = (s.length() == 1);\r
- }\r
-\r
- /** The same as find(s,0,s.length()) */\r
- public final int find(StringLike s)\r
- {\r
- return find(s, 0, s.length());\r
- }\r
-\r
- static final int min(int a, int b)\r
- {\r
- return a < b ? a : b;\r
- }\r
-\r
- /** Searches a given region of text beginning at position start\r
- and ending at position end for the skip object. */\r
- public int find(StringLike s, int start, int end)\r
- {\r
- if (start > end)\r
- {\r
- return -1;\r
- }\r
- start += offset;\r
- int vend = min(s.length() - 1, end + offset);\r
- if (mask != c)\r
- {\r
- for (int i = start; i <= vend; i++)\r
- {\r
- if (0 == (s.charAt(i) & mask))\r
- {\r
- //if(m1||s.regionMatches(ign,i,src,0,src.length()) )\r
- if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))\r
- {\r
- return i - offset;\r
- }\r
- }\r
- }\r
- }\r
- else\r
- {\r
- for (int i = start; i <= vend; i++)\r
- {\r
- if (c == s.charAt(i))\r
- {\r
- //if(m1||s.regionMatches(ign,i,src,0,src.length()) )\r
- if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))\r
- {\r
- return i - offset;\r
- }\r
- }\r
- }\r
- }\r
- return -1;\r
- }\r
-\r
- static Skip findSkip(Regex r)\r
- {\r
- return findSkip(r.thePattern, r.ignoreCase, !r.dontMatchInQuotes);\r
- }\r
-\r
- // look for things that can be skipped\r
- static Skip findSkip(Pattern p, boolean ignoreCase, boolean trnc)\r
- {\r
- StringBuffer sb = new StringBuffer();\r
- Skip subsk = null;\r
- int offset = 0;\r
- int skipc = -1, skipoff = 0;\r
- for (; p != null; p = p.next)\r
- {\r
- if (p instanceof oneChar)\r
- {\r
- skipc = ( (oneChar) p).c;\r
- skipoff = offset;\r
- }\r
- if (p instanceof oneChar && p.next instanceof oneChar)\r
- {\r
- Pattern psav = p;\r
- sb.append( ( (oneChar) p).c);\r
- while (p.next instanceof oneChar)\r
- {\r
- sb.append( ( (oneChar) p.next).c);\r
- p = p.next;\r
- }\r
- String st = sb.toString();\r
- Skip sk = null;\r
- if (st.length() > 2)\r
- {\r
- sk = new SkipBMH(st, ignoreCase, offset);\r
- }\r
- else\r
- {\r
- sk = new Skip2(st, ignoreCase, offset);\r
- }\r
- if (trnc && st.length() > 2)\r
- { // chop out a whole string...\r
- psav.next = new Skipped(st.substring(1));\r
- psav.next.next = p.next;\r
- psav.next.parent = p.parent;\r
- }\r
- return sk;\r
- }\r
- else if (p instanceof Or && ( (Or) p).v.size() == 1\r
- && ! ( (Or) p).leftForm().equals("(?!")\r
- && null != (subsk =\r
- findSkip( (Pattern) ( (Or) p).v.elementAt(0),\r
- ignoreCase, trnc)))\r
- {\r
- subsk.offset += offset;\r
- return subsk;\r
- }\r
- else if (p.minChars().equals(p.maxChars()))\r
- {\r
- offset += p.minChars().intValue();\r
- }\r
- else\r
- {\r
- return skipc < 0 ? null :\r
- new Skip("" + (char) skipc, ignoreCase, skipoff);\r
- }\r
- }\r
- return null;\r
- }\r
-}\r
+//
+// 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;
+
+/**
+ * This class is used internally to search ahead for some optimized Regex
+ * objects. It searches within a String for occrences of a given String -- like
+ * a more flexible version of String.indexOf.
+ *
+ * @see com.stevesoft.pat.Skip2
+ * @see com.stevesoft.pat.SkipBMH
+ */
+public class Skip
+{
+ static int mkmask(int c)
+ {
+ char x = (char) c;
+ return ~(CaseMgr.toUpperCase(x) | CaseMgr.toLowerCase(x) | CaseMgr
+ .toTitleCase(x));
+ }
+
+ String src;
+
+ int c, mask;
+
+ int offset;
+
+ boolean ign, m1;
+
+ /**
+ * Examine a Regex to determine what String it will attempt to skip to when
+ * searching for patterns. Return -1 if we aren't doing this.
+ */
+ public static String string(Regex r)
+ {
+ return r.skipper == null ? null : r.skipper.src;
+ }
+
+ /**
+ * Determine the offset of the String within the pattern that we are skipping
+ * to. Return -1 if we aren't doing this.
+ */
+ public static int offset(Regex r)
+ {
+ return r.skipper == null ? -1 : r.skipper.offset;
+ }
+
+ /**
+ * Initialize, give it a String to search for, tell it whether or not to
+ * ignoreCase, and what the offset is of the String within the String to be
+ * searched.
+ */
+ public Skip(String s, boolean ign, int o)
+ {
+ src = s;
+ c = s.charAt(0);
+ if (ign)
+ {
+ mask = mkmask(c);
+ }
+ else
+ {
+ mask = 0;
+ }
+ offset = o;
+ this.ign = ign;
+ m1 = (s.length() == 1);
+ }
+
+ /** The same as find(s,0,s.length()) */
+ public final int find(StringLike s)
+ {
+ return find(s, 0, s.length());
+ }
+
+ static final int min(int a, int b)
+ {
+ return a < b ? a : b;
+ }
+
+ /**
+ * Searches a given region of text beginning at position start and ending at
+ * position end for the skip object.
+ */
+ public int find(StringLike s, int start, int end)
+ {
+ if (start > end)
+ {
+ return -1;
+ }
+ start += offset;
+ int vend = min(s.length() - 1, end + offset);
+ if (mask != c)
+ {
+ for (int i = start; i <= vend; i++)
+ {
+ if (0 == (s.charAt(i) & mask))
+ {
+ // if(m1||s.regionMatches(ign,i,src,0,src.length()) )
+ if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))
+ {
+ return i - offset;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (int i = start; i <= vend; i++)
+ {
+ if (c == s.charAt(i))
+ {
+ // if(m1||s.regionMatches(ign,i,src,0,src.length()) )
+ if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))
+ {
+ return i - offset;
+ }
+ }
+ }
+ }
+ return -1;
+ }
+
+ static Skip findSkip(Regex r)
+ {
+ return findSkip(r.thePattern, r.ignoreCase, !r.dontMatchInQuotes);
+ }
+
+ // look for things that can be skipped
+ static Skip findSkip(Pattern p, boolean ignoreCase, boolean trnc)
+ {
+ StringBuffer sb = new StringBuffer();
+ Skip subsk = null;
+ int offset = 0;
+ int skipc = -1, skipoff = 0;
+ for (; p != null; p = p.next)
+ {
+ if (p instanceof oneChar)
+ {
+ skipc = ((oneChar) p).c;
+ skipoff = offset;
+ }
+ if (p instanceof oneChar && p.next instanceof oneChar)
+ {
+ Pattern psav = p;
+ sb.append(((oneChar) p).c);
+ while (p.next instanceof oneChar)
+ {
+ sb.append(((oneChar) p.next).c);
+ p = p.next;
+ }
+ String st = sb.toString();
+ Skip sk = null;
+ if (st.length() > 2)
+ {
+ sk = new SkipBMH(st, ignoreCase, offset);
+ }
+ else
+ {
+ sk = new Skip2(st, ignoreCase, offset);
+ }
+ if (trnc && st.length() > 2)
+ { // chop out a whole string...
+ psav.next = new Skipped(st.substring(1));
+ psav.next.next = p.next;
+ psav.next.parent = p.parent;
+ }
+ return sk;
+ }
+ else if (p instanceof Or
+ && ((Or) p).v.size() == 1
+ && !((Or) p).leftForm().equals("(?!")
+ && null != (subsk = findSkip((Pattern) ((Or) p).v
+ .elementAt(0), ignoreCase, trnc)))
+ {
+ subsk.offset += offset;
+ return subsk;
+ }
+ else if (p.minChars().equals(p.maxChars()))
+ {
+ offset += p.minChars().intValue();
+ }
+ else
+ {
+ return skipc < 0 ? null : new Skip("" + (char) skipc, ignoreCase,
+ skipoff);
+ }
+ }
+ return null;
+ }
+}