-//
-// 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 jalview.util.MessageManager;
-
-import java.util.*;
-
-/**
- Shareware: package pat
- <a href="copyright.html">Copyright 2001, Steven R. Brandt</a>
- */
-/**
- * Class Pattern is the base class on which all the other pattern elements are
- * built.
- */
-
-public abstract class Pattern
-{
- /**
- * The ESC character, the user can provide his own value for the escape
- * character through regex.esc
- */
- public final static char ESC = '\\';
-
- final static String PROTECT_THESE = "[]{}(),$,-\"^.";
-
- /**
- * The interal match function, it must be provided by any class which wishes
- * to extend Pattern.
- */
- public abstract int matchInternal(int i, Pthings p);
-
- public abstract String toString();
-
- // Class Pattern is a singly linked list
- // chained together by member next. The member
- // parent is used so that sub patterns can access
- // the chain they are branching from.
- Pattern next = null, parent = null;
-
- /**
- * This gets the next element of a Pattern that we wish to match. If we are at
- * the end of a subchain of patterns, it will return us to the parent chain.
- */
- public Pattern getNext()
- {
- return next != null ? next : (parent == null ? null : parent.getNext());
- }
-
- /**
- * Call this method if you have a pattern element that takes a sub pattern
- * (such as Or), and after you have added a sub pattern to the current pattern
- * element.
- */
- public void setParent(Pattern p)
- {
- if (next != null)
- {
- next.setParent(p);
- }
- else
- {
- parent = p;
- }
- }
-
- /**
- * This determines if the remainder of a Pattern matches. Type "return
- * nextMatch" from within matchInternal if the current Pattern matches.
- * Otherwise, return a -1.
- */
- public int nextMatch(int i, Pthings pt)
- {
- Pattern p = getNext();
- /*
- * if(p == null) return i; return p.matchInternal(i,pt);
- */
- return p == null ? i : p.matchInternal(i, pt);
- }
-
- /**
- * This is a toString() for the remainder of the Pattern elements after this
- * one. use this when overriding toString(). Called from within toString().
- */
- public String nextString()
- {
- if (next == null)
- {
- return "";
- }
- return next.toString();
- }
-
- /** a method to detect whether char c is in String s */
- final static boolean inString(char c, String s)
- {
- int i;
- for (i = 0; i < s.length(); i++)
- {
- if (s.charAt(i) == c)
- {
- return true;
- }
- }
- return false;
- }
-
- /**
- * A method to create a string that protects the characters listed in
- * PROTECT_THESE by prepending the esc character. The esc character itself is
- * automatically protected.
- */
- final static String protect(String s, String PROTECT_THESE, char esc)
- {
- int i;
- javajs.util.SB sb = new javajs.util.SB();
- String p = PROTECT_THESE + esc;
- for (i = 0; i < s.length(); i++)
- {
- char c = s.charAt(i);
- if (inString(c, p))
- {
- sb.appendC(esc);
- }
- sb.appendC(c);
- }
- return sb.toString();
- }
-
- /**
- * This can be used to perform a match test from within class Pattern.
- */
- public int match(StringLike s, Pthings pt)
- {
- return matchAt(s, 0, pt);
- }
-
- /**
- * This can be used to perform a match test from within class Pattern.
- */
- public int matchAt(StringLike s, int i, Pthings pt)
- {
- pt.src = s;
- int r = matchInternal(i, pt);
- if (r < 0)
- {
- return -1;
- }
- mfrom = r < i ? r + 1 : i;
- return r < i ? i - r - 1 : r - i;
- }
-
- int mfrom = 0;
-
- // Detect masked characters
- final boolean Masked(int i, Pthings pt)
- {
- return pt.cbits == null ? false : pt.cbits.get(i);
- }
-
- /** add a Pattern to the singly-linked Pattern chain. */
- public Pattern add(Pattern p)
- {
- if (next == null)
- {
- if (p == null)
- {
- return this;
- }
- next = p;
- p.parent = parent;
- parent = null;
- }
- else
- {
- next.add(p);
- }
- return this;
- }
-
- /**
- * The minimum number of characters which this pattern element can match.
- */
- public patInt minChars()
- {
- return new patInt(0);
- }
-
- /**
- * The maximum number of characters which this pattern element can match.
- */
- public patInt maxChars()
- {
- return new patInf();
- }
-
- /** return minimum number of characters in pattern */
- public final patInt countMinChars()
- {
- Pattern p = this;
- patInt sum = new patInt(0);
- while (p != null)
- {
- sum.pluseq(p.minChars());
- p = p.next;
- }
- return sum;
- }
-
- /** return maximum number of characters in pattern */
- public final patInt countMaxChars()
- {
- Pattern p = this;
- patInt sum = new patInt(0);
- while (p != null)
- {
- sum.pluseq(p.maxChars());
- p = p.next;
- }
- return sum;
- }
-
- // This method is only needed by Multi_stage2 so far...
- // the reason is that it may try something else after a
- // match succeeds. OrMark will only record the last thing
- // tried in marks, so we need to backup the result of the
- // last successful match and restore it if the next one
- // does not succeed.
- final int testMatch(Pattern p, int pos, Pthings pt)
- {
- int[] tab = null;
- if (pt.marks != null)
- {
- try
- {
- tab = new int[pt.marks.length];
- for (int i = 0; i < tab.length; i++)
- {
- tab[i] = pt.marks[i];
- }
- } catch (Throwable t)
- {
- }
- }
- int ret = p.matchInternal(pos, pt);
- if (ret < 0)
- {
- pt.marks = tab;
- }
- return ret;
- }
-
- /**
- * Clones this pattern elements without cloning others in the linked list.
- */
- Pattern clone1(Hashtable h)
- {
- throw new Error(MessageManager.formatMessage("error.no_such_method_as_clone1_for", new String[]{getClass().getName()}));
- }
-
- Pattern clone(Hashtable h)
- {
- Pattern p = (Pattern) h.get(this);
- if (p != null)
- {
- return p;
- }
- p = clone1(h);
- if (p == null)
- {
- throw new Error(MessageManager.getString("error.null_from_clone1"));
- }
- h.put(this, p);
- h.put(p, p);
- if (next != null)
- {
- p.next = next.clone(h);
- }
- if (parent != null)
- {
- p.parent = parent.clone(h);
- }
- return p;
- }
-
- public boolean equals(Object o)
- {
- return o == this;
- }
-};
+//\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 jalview.util.MessageManager;\r
+\r
+import java.util.*;\r
+\r
+/**\r
+ Shareware: package pat\r
+ <a href="copyright.html">Copyright 2001, Steven R. Brandt</a>\r
+ */\r
+/**\r
+ * Class Pattern is the base class on which all the other pattern elements are\r
+ * built.\r
+ */\r
+\r
+public abstract class Pattern\r
+{\r
+ /**\r
+ * The ESC character, the user can provide his own value for the escape\r
+ * character through regex.esc\r
+ */\r
+ public final static char ESC = '\\';\r
+\r
+ final static String PROTECT_THESE = "[]{}(),$,-\"^.";\r
+\r
+ /**\r
+ * The interal match function, it must be provided by any class which wishes\r
+ * to extend Pattern.\r
+ */\r
+ public abstract int matchInternal(int i, Pthings p);\r
+\r
+ public abstract String toString();\r
+\r
+ // Class Pattern is a singly linked list\r
+ // chained together by member next. The member\r
+ // parent is used so that sub patterns can access\r
+ // the chain they are branching from.\r
+ Pattern next = null, parent = null;\r
+\r
+ /**\r
+ * This gets the next element of a Pattern that we wish to match. If we are at\r
+ * the end of a subchain of patterns, it will return us to the parent chain.\r
+ */\r
+ public Pattern getNext()\r
+ {\r
+ return next != null ? next : (parent == null ? null : parent.getNext());\r
+ }\r
+\r
+ /**\r
+ * Call this method if you have a pattern element that takes a sub pattern\r
+ * (such as Or), and after you have added a sub pattern to the current pattern\r
+ * element.\r
+ */\r
+ public void setParent(Pattern p)\r
+ {\r
+ if (next != null)\r
+ {\r
+ next.setParent(p);\r
+ }\r
+ else\r
+ {\r
+ parent = p;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * This determines if the remainder of a Pattern matches. Type "return\r
+ * nextMatch" from within matchInternal if the current Pattern matches.\r
+ * Otherwise, return a -1.\r
+ */\r
+ public int nextMatch(int i, Pthings pt)\r
+ {\r
+ Pattern p = getNext();\r
+ /*\r
+ * if(p == null) return i; return p.matchInternal(i,pt);\r
+ */\r
+ return p == null ? i : p.matchInternal(i, pt);\r
+ }\r
+\r
+ /**\r
+ * This is a toString() for the remainder of the Pattern elements after this\r
+ * one. use this when overriding toString(). Called from within toString().\r
+ */\r
+ public String nextString()\r
+ {\r
+ if (next == null)\r
+ {\r
+ return "";\r
+ }\r
+ return next.toString();\r
+ }\r
+\r
+ /** a method to detect whether char c is in String s */\r
+ final static boolean inString(char c, String s)\r
+ {\r
+ int i;\r
+ for (i = 0; i < s.length(); i++)\r
+ {\r
+ if (s.charAt(i) == c)\r
+ {\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * A method to create a string that protects the characters listed in\r
+ * PROTECT_THESE by prepending the esc character. The esc character itself is\r
+ * automatically protected.\r
+ */\r
+ final static String protect(String s, String PROTECT_THESE, char esc)\r
+ {\r
+ int i;\r
+ javajs.util.SB sb = new javajs.util.SB();\r
+ String p = PROTECT_THESE + esc;\r
+ for (i = 0; i < s.length(); i++)\r
+ {\r
+ char c = s.charAt(i);\r
+ if (inString(c, p))\r
+ {\r
+ sb.appendC(esc);\r
+ }\r
+ sb.appendC(c);\r
+ }\r
+ return sb.toString();\r
+ }\r
+\r
+ /**\r
+ * This can be used to perform a match test from within class Pattern.\r
+ */\r
+ public int match(StringLike s, Pthings pt)\r
+ {\r
+ return matchAt(s, 0, pt);\r
+ }\r
+\r
+ /**\r
+ * This can be used to perform a match test from within class Pattern.\r
+ */\r
+ public int matchAt(StringLike s, int i, Pthings pt)\r
+ {\r
+ pt.src = s;\r
+ int r = matchInternal(i, pt);\r
+ if (r < 0)\r
+ {\r
+ return -1;\r
+ }\r
+ mfrom = r < i ? r + 1 : i;\r
+ return r < i ? i - r - 1 : r - i;\r
+ }\r
+\r
+ int mfrom = 0;\r
+\r
+ // Detect masked characters\r
+ final boolean Masked(int i, Pthings pt)\r
+ {\r
+ return pt.cbits == null ? false : pt.cbits.get(i);\r
+ }\r
+\r
+ /** add a Pattern to the singly-linked Pattern chain. */\r
+ public Pattern add(Pattern p)\r
+ {\r
+ if (next == null)\r
+ {\r
+ if (p == null)\r
+ {\r
+ return this;\r
+ }\r
+ next = p;\r
+ p.parent = parent;\r
+ parent = null;\r
+ }\r
+ else\r
+ {\r
+ next.add(p);\r
+ }\r
+ return this;\r
+ }\r
+\r
+ /**\r
+ * The minimum number of characters which this pattern element can match.\r
+ */\r
+ public patInt minChars()\r
+ {\r
+ return new patInt(0);\r
+ }\r
+\r
+ /**\r
+ * The maximum number of characters which this pattern element can match.\r
+ */\r
+ public patInt maxChars()\r
+ {\r
+ return new patInf();\r
+ }\r
+\r
+ /** return minimum number of characters in pattern */\r
+ public final patInt countMinChars()\r
+ {\r
+ Pattern p = this;\r
+ patInt sum = new patInt(0);\r
+ while (p != null)\r
+ {\r
+ sum.pluseq(p.minChars());\r
+ p = p.next;\r
+ }\r
+ return sum;\r
+ }\r
+\r
+ /** return maximum number of characters in pattern */\r
+ public final patInt countMaxChars()\r
+ {\r
+ Pattern p = this;\r
+ patInt sum = new patInt(0);\r
+ while (p != null)\r
+ {\r
+ sum.pluseq(p.maxChars());\r
+ p = p.next;\r
+ }\r
+ return sum;\r
+ }\r
+\r
+ // This method is only needed by Multi_stage2 so far...\r
+ // the reason is that it may try something else after a\r
+ // match succeeds. OrMark will only record the last thing\r
+ // tried in marks, so we need to backup the result of the\r
+ // last successful match and restore it if the next one\r
+ // does not succeed.\r
+ final int testMatch(Pattern p, int pos, Pthings pt)\r
+ {\r
+ int[] tab = null;\r
+ if (pt.marks != null)\r
+ {\r
+ try\r
+ {\r
+ tab = new int[pt.marks.length];\r
+ for (int i = 0; i < tab.length; i++)\r
+ {\r
+ tab[i] = pt.marks[i];\r
+ }\r
+ } catch (Throwable t)\r
+ {\r
+ }\r
+ }\r
+ int ret = p.matchInternal(pos, pt);\r
+ if (ret < 0)\r
+ {\r
+ pt.marks = tab;\r
+ }\r
+ return ret;\r
+ }\r
+\r
+ /**\r
+ * Clones this pattern elements without cloning others in the linked list.\r
+ */\r
+ Pattern clone1(Hashtable h)\r
+ {\r
+ throw new Error(MessageManager.formatMessage("error.no_such_method_as_clone1_for", new String[]{getClass().getName()}));\r
+ }\r
+\r
+ Pattern clone(Hashtable h)\r
+ {\r
+ Pattern p = (Pattern) h.get(this);\r
+ if (p != null)\r
+ {\r
+ return p;\r
+ }\r
+ p = clone1(h);\r
+ if (p == null)\r
+ {\r
+ throw new Error(MessageManager.getString("error.null_from_clone1"));\r
+ }\r
+ h.put(this, p);\r
+ h.put(p, p);\r
+ if (next != null)\r
+ {\r
+ p.next = next.clone(h);\r
+ }\r
+ if (parent != null)\r
+ {\r
+ p.parent = parent.clone(h);\r
+ }\r
+ return p;\r
+ }\r
+\r
+ public boolean equals(Object o)\r
+ {\r
+ return o == this;\r
+ }\r
+};\r