-//
-// 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.*;
-
-/** This class is just like oneChar, but doesn't worry about case. */
-class FastChar extends oneChar
-{
- FastChar(char c)
- {
- super(c);
- }
-
- public int matchInternal(int p, Pthings pt)
- {
- return (p < pt.src.length() && pt.src.charAt(p) == c) ? nextMatch(
- p + 1, pt) : -1;
- }
-
- Pattern clone1(Hashtable h)
- {
- return new FastChar(c);
- }
-}
-
-/**
- * This class is a hashtable keyed by Character Objects. It is used to match
- * things of the form (?:a..|b..|c..|..) match with greater efficiency -- by
- * using a Hashtable that indexes into the group of patterns.
- */
-class Branch extends Pattern
-{
- Hashtable h = new Hashtable();
-
- // We need to keep track of the order
- // of the keys -- if we don't then
- // recompiling the output of toString
- // may produce errors by re-ordering
- // ()'s and changing the id number of
- // the backreference associated with
- // a subpattern.
- Vector keys = new Vector();
-
- Branch()
- {
- }
-
- Pattern clone1(Hashtable x)
- {
- Branch b = new Branch();
- b.keys = (Vector) keys.clone();
- x.put(this, b);
- x.put(b, b);
-
- for (int i = 0; i < keys.size(); i++)
- {
- Pattern p = (Pattern) h.get(keys.elementAt(i));
- b.h.put(keys.elementAt(i), p.clone(x));
- }
- return b;
- }
-
- // this function eliminates Branches with 0 or 1 elements.
- final Pattern reduce(boolean ignoreCase, boolean dontMinQ)
- {
- if (h.size() == 1)
- {
- Enumeration e = h.keys();
- Character c = (Character) e.nextElement();
- Pattern oc;
- if (ignoreCase || dontMinQ)
- {
- oc = new oneChar(c.charValue());
- }
- else
- {
- oc = new FastChar(c.charValue());
- }
- oc.next = (Pattern) h.get(c);
- oc.add(next);
- return oc;
- }
- else if (h.size() == 0)
- {
- return null;
- }
- return this;
- }
-
- public patInt maxChars()
- {
- Enumeration e = h.keys();
- patInt count = new patInt(0);
- while (e.hasMoreElements())
- {
- Object key = e.nextElement();
- Pattern pa = (Pattern) h.get(key);
- patInt pi = pa.maxChars();
- pi.inc();
- count.maxeq(pi);
- }
- return count;
- }
-
- public patInt minChars()
- {
- Enumeration e = h.keys();
- patInt count = new patInt(0);
- while (e.hasMoreElements())
- {
- Object key = e.nextElement();
- Pattern pa = (Pattern) h.get(key);
- patInt pi = pa.minChars();
- pi.inc();
- count.mineq(pi);
- }
- return count;
- }
-
- // adds a oneChar object to this Branch
- void addc(oneChar o, boolean ignoreCase, boolean dontMinQ)
- {
- Pattern n = o.next;
- if (n == null)
- {
- n = new NullPattern();
- }
- else
- {
- n = RegOpt.opt(n, ignoreCase, dontMinQ);
- }
- n.setParent(this);
- set(new Character(o.c), n, ignoreCase, dontMinQ);
- if (ignoreCase)
- {
- if (o.c != o.altc)
- {
- set(new Character(o.altc), n, ignoreCase, dontMinQ);
- }
- if (o.c != o.altc2 && o.altc != o.altc2)
- {
- set(new Character(o.altc2), n, ignoreCase, dontMinQ);
- }
- }
- }
-
- void set(Character c, Pattern n, boolean igc, boolean dontMinQ)
- {
- Pattern p = (Pattern) h.get(c);
- next = null;
- // This letter is not yet used in the Branch object.
- // We need to add it.
- if (p == null)
- {
- if (n instanceof Or)
- {
- // A NullPattern is prepended to an Or
- // to prevent confusing this object.
- // For example: (boo|bug) => (b(?:oo|ug))
- // during this process. However, we
- // want (b(?:oo|ell)|bug)
- NullPattern np = new NullPattern();
- np.add(n);
- h.put(c, np);
- }
- else
- {
- h.put(c, n);
- }
- // Make sure we remember the order things were
- // added into the Branch object so that we can
- // properly convert it to a String.
- keys.addElement(c);
- }
- else if (p instanceof Or)
- {
- ((Or) p).addOr(n);
- }
- else if (p instanceof oneChar && n instanceof oneChar
- && ((oneChar) p).c != ((oneChar) n).c)
- {
- Branch b = new Branch();
- b.addc((oneChar) p, igc, dontMinQ);
- b.addc((oneChar) n, igc, dontMinQ);
- h.put(c, b);
- b.setParent(this);
- }
- else if (p instanceof Branch && n instanceof oneChar)
- {
- ((Branch) p).addc((oneChar) n, igc, dontMinQ);
- n.setParent(p);
- }
- else
- {
- // Create an Or object to receive the variety
- // of branches in the pattern if the current letter
- // is matched. We do not attempt to make these
- // sub-branches into a Branch object yet.
- Or o = new Or();
- o.setParent(this);
-
- // Remove NullPattern from p -- it's no longer needed.
- if (p instanceof NullPattern && p.parent == null && p.next != null)
- {
- o.addOr(p.next);
- }
- else
- {
- o.addOr(p);
- }
- o.addOr(n);
-
- Pattern optpat = RegOpt.opt(o, igc, dontMinQ);
- h.put(c, optpat);
- optpat.setParent(this);
- }
- }
-
- public String toString()
- {
- javajs.util.SB sb = new javajs.util.SB();
- // should protect this...
- sb.append("(?:(?#branch)"); // Hashtable)");
- for (int i = 0; i < keys.size(); i++)
- {
- Character c = (Character) keys.elementAt(i);
- sb.appendC(c);
- sb.append((String) h.get(c));
- if (i + 1 < keys.size())
- {
- sb.append("|");
- }
- }
- sb.append(")");
- sb.append(nextString());
- return sb.toString();
- }
-
- public int matchInternal(int pos, Pthings pt)
- {
- if (pos >= pt.src.length())
- {
- return -1;
- }
- Pattern n = (Pattern) h.get(new Character(pt.src.charAt(pos)));
- if (n == null)
- {
- return -1;
- }
- if (pt.cbits != null && pt.cbits.get(pos))
- {
- return -1;
- }
- return n.matchInternal(pos + 1, pt);
- }
-}
-
-/**
- * This is just a place to put the optimizing function. It is never instantiated
- * as an Object. It just sorts through the RegOpt looking for things it can
- * change and make faster.
- */
-public class RegOpt
-{
- static Pattern opt(Pattern p, boolean ignoreCase, boolean dontMinQ)
- {
- if (p == null)
- {
- return p;
- }
- if (p instanceof Bracket)
- {
- Bracket b = (Bracket) p;
- // FastBracket is the only special
- // optimized class to have its own
- // source file.
- p = FastBracket.process(b, ignoreCase);
- // if(!(p instanceof FastBracket)
- // p = Switch.process(b,ignoreCase);
- p.next = b.next;
- p.parent = b.parent;
- }
- else if (p instanceof oneChar && !ignoreCase && !dontMinQ)
- {
- oneChar o = (oneChar) p;
- p = new FastChar(o.c);
- p.next = o.next;
- p.parent = o.parent;
- }
- else if (p instanceof Or && ((Or) p).leftForm().equals("(?:")
- && ((Or) p).v.size() == 1)
- { // Eliminate this Or Object.
- Or o = (Or) p;
- p = (Pattern) o.v.elementAt(0);
- p.setParent(null);
- p = RegOpt.opt(p, ignoreCase, dontMinQ);
- p.add(o.next);
- }
- else if (p instanceof Or)
- {
- Or o = (Or) p;
- o.pv = null;
- Vector v = o.v;
- o.v = new Vector();
- Branch b = new Branch();
- b.parent = o.parent;
- for (int i = 0; i < v.size(); i++)
- {
- Pattern pp = (Pattern) v.elementAt(i);
- // We want to have at least two oneChar's in
- // the Or Object to consider making a Branch.
- if (pp instanceof oneChar
- && (b.h.size() >= 1 || (i + 1 < v.size() && v
- .elementAt(i + 1) instanceof oneChar)))
- {
- b.addc((oneChar) pp, ignoreCase, dontMinQ);
- }
- else
- {
- if (b.keys.size() > 0)
- {
- Pattern p2 = (Pattern) b.reduce(ignoreCase, dontMinQ);
- if (p2 != null)
- {
- o.addOr(p2);
- b = new Branch();
- b.parent = o.parent;
- }
- }
- o.addOr(opt(pp, ignoreCase, dontMinQ));
- }
- }
- if (b.keys.size() > 0)
- {
- Pattern p2 = (Pattern) b.reduce(ignoreCase, dontMinQ);
- if (p2 != null)
- {
- o.addOr(p2);
- }
- }
- if (o.v.size() == 1 && o.leftForm().equals("(?:"))
- { // Eliminate Or Object
- p = (Pattern) o.v.elementAt(0);
- p.setParent(null);
- p = RegOpt.opt(p, ignoreCase, dontMinQ);
- p.add(o.next);
- }
- }
- else if (p instanceof FastMulti)
- {
- PatternSub ps = (PatternSub) p;
- ps.sub = RegOpt.opt(ps.sub, ignoreCase, dontMinQ);
- }
- else if (p instanceof Multi && safe4fm(((PatternSub) p).sub))
- {
- Multi m = (Multi) p;
- FastMulti fm = null;
- try
- {
- fm = new FastMulti(m.a, m.b, opt(m.sub, ignoreCase, dontMinQ));
- } catch (RegSyntax rs)
- {
- }
- fm.parent = m.parent;
- fm.matchFewest = m.matchFewest;
- fm.next = m.next;
- p = fm;
- }
- if (p.next != null)
- {
- p.next = opt(p.next, ignoreCase, dontMinQ);
- }
- return p;
- }
-
- final static boolean safe4fm(Pattern x)
- {
- while (x != null)
- {
- if (x instanceof Bracket)
- {
- ;
- }
- else if (x instanceof Range)
- {
- ;
- }
- else if (x instanceof oneChar)
- {
- ;
- }
- else if (x instanceof Any)
- {
- ;
- }
- else if (x instanceof Custom
- && ((Custom) x).v instanceof UniValidator)
- {
- ;
- }
- else if (x instanceof Or)
- {
- Or o = (Or) x;
- if (!o.leftForm().equals("(?:"))
- {
- return false;
- }
- patInt lo = o.countMinChars();
- patInt hi = o.countMaxChars();
- if (!lo.equals(hi))
- {
- return false;
- }
- for (int i = 0; i < o.v.size(); i++)
- {
- if (!safe4fm((Pattern) o.v.elementAt(i)))
- {
- return false;
- }
- }
- }
- else
- {
- return false;
- }
- x = x.next;
- }
- return true;
- }
- /*
- * public static void setParents(Regex r) { setParents(r.thePattern,null); }
- * static void setParents(Pattern p,Pattern x) { if(p instanceof PatternSub &&
- * !(p instanceof FastMulti) && !(p instanceof DotMulti)) RegOpt.setParents(
- * ((PatternSub)p).sub, p); else if(p instanceof Or && !(p instanceof
- * Bracket)) { Or o = (Or)p; for(int i=0;i<o.v.size();i++)
- * RegOpt.setParents((Pattern)o.v.elementAt(i),o); } else if(p instanceof
- * Branch) { Branch b = (Branch)p; Enumeration e = b.h.keys();
- * while(e.hasMoreElements()) { Object o = e.nextElement(); RegOpt.setParents(
- * (Pattern)b.h.get(o), b); } } if(p.next == null) p.parent = x; else {
- * p.parent = null; RegOpt.setParents(p.next,x); } }
- */
-}
+//\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
+import java.util.*;\r
+\r
+/** This class is just like oneChar, but doesn't worry about case. */\r
+class FastChar extends oneChar\r
+{\r
+ FastChar(char c)\r
+ {\r
+ super(c);\r
+ }\r
+\r
+ public int matchInternal(int p, Pthings pt)\r
+ {\r
+ return (p < pt.src.length() && pt.src.charAt(p) == c) ? nextMatch(\r
+ p + 1, pt) : -1;\r
+ }\r
+\r
+ Pattern clone1(Hashtable h)\r
+ {\r
+ return new FastChar(c);\r
+ }\r
+}\r
+\r
+/**\r
+ * This class is a hashtable keyed by Character Objects. It is used to match\r
+ * things of the form (?:a..|b..|c..|..) match with greater efficiency -- by\r
+ * using a Hashtable that indexes into the group of patterns.\r
+ */\r
+class Branch extends Pattern\r
+{\r
+ Hashtable h = new Hashtable();\r
+\r
+ // We need to keep track of the order\r
+ // of the keys -- if we don't then\r
+ // recompiling the output of toString\r
+ // may produce errors by re-ordering\r
+ // ()'s and changing the id number of\r
+ // the backreference associated with\r
+ // a subpattern.\r
+ Vector keys = new Vector();\r
+\r
+ Branch()\r
+ {\r
+ }\r
+\r
+ Pattern clone1(Hashtable x)\r
+ {\r
+ Branch b = new Branch();\r
+ b.keys = (Vector) keys.clone();\r
+ x.put(this, b);\r
+ x.put(b, b);\r
+\r
+ for (int i = 0; i < keys.size(); i++)\r
+ {\r
+ Pattern p = (Pattern) h.get(keys.elementAt(i));\r
+ b.h.put(keys.elementAt(i), p.clone(x));\r
+ }\r
+ return b;\r
+ }\r
+\r
+ // this function eliminates Branches with 0 or 1 elements.\r
+ final Pattern reduce(boolean ignoreCase, boolean dontMinQ)\r
+ {\r
+ if (h.size() == 1)\r
+ {\r
+ Enumeration e = h.keys();\r
+ Character c = (Character) e.nextElement();\r
+ Pattern oc;\r
+ if (ignoreCase || dontMinQ)\r
+ {\r
+ oc = new oneChar(c.charValue());\r
+ }\r
+ else\r
+ {\r
+ oc = new FastChar(c.charValue());\r
+ }\r
+ oc.next = (Pattern) h.get(c);\r
+ oc.add(next);\r
+ return oc;\r
+ }\r
+ else if (h.size() == 0)\r
+ {\r
+ return null;\r
+ }\r
+ return this;\r
+ }\r
+\r
+ public patInt maxChars()\r
+ {\r
+ Enumeration e = h.keys();\r
+ patInt count = new patInt(0);\r
+ while (e.hasMoreElements())\r
+ {\r
+ Object key = e.nextElement();\r
+ Pattern pa = (Pattern) h.get(key);\r
+ patInt pi = pa.maxChars();\r
+ pi.inc();\r
+ count.maxeq(pi);\r
+ }\r
+ return count;\r
+ }\r
+\r
+ public patInt minChars()\r
+ {\r
+ Enumeration e = h.keys();\r
+ patInt count = new patInt(0);\r
+ while (e.hasMoreElements())\r
+ {\r
+ Object key = e.nextElement();\r
+ Pattern pa = (Pattern) h.get(key);\r
+ patInt pi = pa.minChars();\r
+ pi.inc();\r
+ count.mineq(pi);\r
+ }\r
+ return count;\r
+ }\r
+\r
+ // adds a oneChar object to this Branch\r
+ void addc(oneChar o, boolean ignoreCase, boolean dontMinQ)\r
+ {\r
+ Pattern n = o.next;\r
+ if (n == null)\r
+ {\r
+ n = new NullPattern();\r
+ }\r
+ else\r
+ {\r
+ n = RegOpt.opt(n, ignoreCase, dontMinQ);\r
+ }\r
+ n.setParent(this);\r
+ set(new Character(o.c), n, ignoreCase, dontMinQ);\r
+ if (ignoreCase)\r
+ {\r
+ if (o.c != o.altc)\r
+ {\r
+ set(new Character(o.altc), n, ignoreCase, dontMinQ);\r
+ }\r
+ if (o.c != o.altc2 && o.altc != o.altc2)\r
+ {\r
+ set(new Character(o.altc2), n, ignoreCase, dontMinQ);\r
+ }\r
+ }\r
+ }\r
+\r
+ void set(Character c, Pattern n, boolean igc, boolean dontMinQ)\r
+ {\r
+ Pattern p = (Pattern) h.get(c);\r
+ next = null;\r
+ // This letter is not yet used in the Branch object.\r
+ // We need to add it.\r
+ if (p == null)\r
+ {\r
+ if (n instanceof Or)\r
+ {\r
+ // A NullPattern is prepended to an Or\r
+ // to prevent confusing this object.\r
+ // For example: (boo|bug) => (b(?:oo|ug))\r
+ // during this process. However, we\r
+ // want (b(?:oo|ell)|bug)\r
+ NullPattern np = new NullPattern();\r
+ np.add(n);\r
+ h.put(c, np);\r
+ }\r
+ else\r
+ {\r
+ h.put(c, n);\r
+ }\r
+ // Make sure we remember the order things were\r
+ // added into the Branch object so that we can\r
+ // properly convert it to a String.\r
+ keys.addElement(c);\r
+ }\r
+ else if (p instanceof Or)\r
+ {\r
+ ((Or) p).addOr(n);\r
+ }\r
+ else if (p instanceof oneChar && n instanceof oneChar\r
+ && ((oneChar) p).c != ((oneChar) n).c)\r
+ {\r
+ Branch b = new Branch();\r
+ b.addc((oneChar) p, igc, dontMinQ);\r
+ b.addc((oneChar) n, igc, dontMinQ);\r
+ h.put(c, b);\r
+ b.setParent(this);\r
+ }\r
+ else if (p instanceof Branch && n instanceof oneChar)\r
+ {\r
+ ((Branch) p).addc((oneChar) n, igc, dontMinQ);\r
+ n.setParent(p);\r
+ }\r
+ else\r
+ {\r
+ // Create an Or object to receive the variety\r
+ // of branches in the pattern if the current letter\r
+ // is matched. We do not attempt to make these\r
+ // sub-branches into a Branch object yet.\r
+ Or o = new Or();\r
+ o.setParent(this);\r
+\r
+ // Remove NullPattern from p -- it's no longer needed.\r
+ if (p instanceof NullPattern && p.parent == null && p.next != null)\r
+ {\r
+ o.addOr(p.next);\r
+ }\r
+ else\r
+ {\r
+ o.addOr(p);\r
+ }\r
+ o.addOr(n);\r
+\r
+ Pattern optpat = RegOpt.opt(o, igc, dontMinQ);\r
+ h.put(c, optpat);\r
+ optpat.setParent(this);\r
+ }\r
+ }\r
+\r
+ public String toString()\r
+ {\r
+ javajs.util.SB sb = new javajs.util.SB();\r
+ // should protect this...\r
+ sb.append("(?:(?#branch)"); // Hashtable)");\r
+ for (int i = 0; i < keys.size(); i++)\r
+ {\r
+ Character c = (Character) keys.elementAt(i);\r
+ sb.appendC(c);\r
+ sb.append((String) h.get(c));\r
+ if (i + 1 < keys.size())\r
+ {\r
+ sb.append("|");\r
+ }\r
+ }\r
+ sb.append(")");\r
+ sb.append(nextString());\r
+ return sb.toString();\r
+ }\r
+\r
+ public int matchInternal(int pos, Pthings pt)\r
+ {\r
+ if (pos >= pt.src.length())\r
+ {\r
+ return -1;\r
+ }\r
+ Pattern n = (Pattern) h.get(new Character(pt.src.charAt(pos)));\r
+ if (n == null)\r
+ {\r
+ return -1;\r
+ }\r
+ if (pt.cbits != null && pt.cbits.get(pos))\r
+ {\r
+ return -1;\r
+ }\r
+ return n.matchInternal(pos + 1, pt);\r
+ }\r
+}\r
+\r
+/**\r
+ * This is just a place to put the optimizing function. It is never instantiated\r
+ * as an Object. It just sorts through the RegOpt looking for things it can\r
+ * change and make faster.\r
+ */\r
+public class RegOpt\r
+{\r
+ static Pattern opt(Pattern p, boolean ignoreCase, boolean dontMinQ)\r
+ {\r
+ if (p == null)\r
+ {\r
+ return p;\r
+ }\r
+ if (p instanceof Bracket)\r
+ {\r
+ Bracket b = (Bracket) p;\r
+ // FastBracket is the only special\r
+ // optimized class to have its own\r
+ // source file.\r
+ p = FastBracket.process(b, ignoreCase);\r
+ // if(!(p instanceof FastBracket)\r
+ // p = Switch.process(b,ignoreCase);\r
+ p.next = b.next;\r
+ p.parent = b.parent;\r
+ }\r
+ else if (p instanceof oneChar && !ignoreCase && !dontMinQ)\r
+ {\r
+ oneChar o = (oneChar) p;\r
+ p = new FastChar(o.c);\r
+ p.next = o.next;\r
+ p.parent = o.parent;\r
+ }\r
+ else if (p instanceof Or && ((Or) p).leftForm().equals("(?:")\r
+ && ((Or) p).v.size() == 1)\r
+ { // Eliminate this Or Object.\r
+ Or o = (Or) p;\r
+ p = (Pattern) o.v.elementAt(0);\r
+ p.setParent(null);\r
+ p = RegOpt.opt(p, ignoreCase, dontMinQ);\r
+ p.add(o.next);\r
+ }\r
+ else if (p instanceof Or)\r
+ {\r
+ Or o = (Or) p;\r
+ o.pv = null;\r
+ Vector v = o.v;\r
+ o.v = new Vector();\r
+ Branch b = new Branch();\r
+ b.parent = o.parent;\r
+ for (int i = 0; i < v.size(); i++)\r
+ {\r
+ Pattern pp = (Pattern) v.elementAt(i);\r
+ // We want to have at least two oneChar's in\r
+ // the Or Object to consider making a Branch.\r
+ if (pp instanceof oneChar\r
+ && (b.h.size() >= 1 || (i + 1 < v.size() && v\r
+ .elementAt(i + 1) instanceof oneChar)))\r
+ {\r
+ b.addc((oneChar) pp, ignoreCase, dontMinQ);\r
+ }\r
+ else\r
+ {\r
+ if (b.keys.size() > 0)\r
+ {\r
+ Pattern p2 = (Pattern) b.reduce(ignoreCase, dontMinQ);\r
+ if (p2 != null)\r
+ {\r
+ o.addOr(p2);\r
+ b = new Branch();\r
+ b.parent = o.parent;\r
+ }\r
+ }\r
+ o.addOr(opt(pp, ignoreCase, dontMinQ));\r
+ }\r
+ }\r
+ if (b.keys.size() > 0)\r
+ {\r
+ Pattern p2 = (Pattern) b.reduce(ignoreCase, dontMinQ);\r
+ if (p2 != null)\r
+ {\r
+ o.addOr(p2);\r
+ }\r
+ }\r
+ if (o.v.size() == 1 && o.leftForm().equals("(?:"))\r
+ { // Eliminate Or Object\r
+ p = (Pattern) o.v.elementAt(0);\r
+ p.setParent(null);\r
+ p = RegOpt.opt(p, ignoreCase, dontMinQ);\r
+ p.add(o.next);\r
+ }\r
+ }\r
+ else if (p instanceof FastMulti)\r
+ {\r
+ PatternSub ps = (PatternSub) p;\r
+ ps.sub = RegOpt.opt(ps.sub, ignoreCase, dontMinQ);\r
+ }\r
+ else if (p instanceof Multi && safe4fm(((PatternSub) p).sub))\r
+ {\r
+ Multi m = (Multi) p;\r
+ FastMulti fm = null;\r
+ try\r
+ {\r
+ fm = new FastMulti(m.a, m.b, opt(m.sub, ignoreCase, dontMinQ));\r
+ } catch (RegSyntax rs)\r
+ {\r
+ }\r
+ fm.parent = m.parent;\r
+ fm.matchFewest = m.matchFewest;\r
+ fm.next = m.next;\r
+ p = fm;\r
+ }\r
+ if (p.next != null)\r
+ {\r
+ p.next = opt(p.next, ignoreCase, dontMinQ);\r
+ }\r
+ return p;\r
+ }\r
+\r
+ final static boolean safe4fm(Pattern x)\r
+ {\r
+ while (x != null)\r
+ {\r
+ if (x instanceof Bracket)\r
+ {\r
+ ;\r
+ }\r
+ else if (x instanceof Range)\r
+ {\r
+ ;\r
+ }\r
+ else if (x instanceof oneChar)\r
+ {\r
+ ;\r
+ }\r
+ else if (x instanceof Any)\r
+ {\r
+ ;\r
+ }\r
+ else if (x instanceof Custom\r
+ && ((Custom) x).v instanceof UniValidator)\r
+ {\r
+ ;\r
+ }\r
+ else if (x instanceof Or)\r
+ {\r
+ Or o = (Or) x;\r
+ if (!o.leftForm().equals("(?:"))\r
+ {\r
+ return false;\r
+ }\r
+ patInt lo = o.countMinChars();\r
+ patInt hi = o.countMaxChars();\r
+ if (!lo.equals(hi))\r
+ {\r
+ return false;\r
+ }\r
+ for (int i = 0; i < o.v.size(); i++)\r
+ {\r
+ if (!safe4fm((Pattern) o.v.elementAt(i)))\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ return false;\r
+ }\r
+ x = x.next;\r
+ }\r
+ return true;\r
+ }\r
+ /*\r
+ * public static void setParents(Regex r) { setParents(r.thePattern,null); }\r
+ * static void setParents(Pattern p,Pattern x) { if(p instanceof PatternSub &&\r
+ * !(p instanceof FastMulti) && !(p instanceof DotMulti)) RegOpt.setParents(\r
+ * ((PatternSub)p).sub, p); else if(p instanceof Or && !(p instanceof\r
+ * Bracket)) { Or o = (Or)p; for(int i=0;i<o.v.size();i++)\r
+ * RegOpt.setParents((Pattern)o.v.elementAt(i),o); } else if(p instanceof\r
+ * Branch) { Branch b = (Branch)p; Enumeration e = b.h.keys();\r
+ * while(e.hasMoreElements()) { Object o = e.nextElement(); RegOpt.setParents(\r
+ * (Pattern)b.h.get(o), b); } } if(p.next == null) p.parent = x; else {\r
+ * p.parent = null; RegOpt.setParents(p.next,x); } }\r
+ */\r
+}\r