X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fcom%2Fstevesoft%2Fpat%2FPattern.java;h=1bc74f83f70c0965de138595d6ae8165ab9d7edb;hb=86e844061a6202e657f2a6886c5ce0057952995a;hp=a441b3774153e8af8214368b392e43ac8958cd81;hpb=7bc226b58110fa26d9dbd3f0c78095d06909ffc3;p=jalview.git
diff --git a/src/com/stevesoft/pat/Pattern.java b/src/com/stevesoft/pat/Pattern.java
index a441b37..1bc74f8 100755
--- a/src/com/stevesoft/pat/Pattern.java
+++ b/src/com/stevesoft/pat/Pattern.java
@@ -1,280 +1,298 @@
-//
-// 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.*;
-
-/**
- Shareware: package pat
- Copyright 2001, Steven R. Brandt
- */
-/**
- 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;
- StringBuffer sb = new StringBuffer();
- String p = PROTECT_THESE + esc;
- for (i = 0; i < s.length(); i++)
- {
- char c = s.charAt(i);
- if (inString(c, p))
- {
- sb.append(esc);
- }
- sb.append(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("No such method as clone1 for " + 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("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;
- }
-};
+//
+// 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.Hashtable;
+
+/**
+ Shareware: package pat
+ Copyright 2001, Steven R. Brandt
+ */
+/**
+ * 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;
+ StringBuffer sb = new StringBuffer();
+ String p = PROTECT_THESE + esc;
+ for (i = 0; i < s.length(); i++)
+ {
+ char c = s.charAt(i);
+ if (inString(c, p))
+ {
+ sb.append(esc);
+ }
+ sb.append(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;
+ }
+};