merge from 2_4_Release branch
[jalview.git] / src / com / stevesoft / pat / Replacer.java
index 77570f9..062a548 100755 (executable)
-//\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 com.stevesoft.pat.wrap.*;\r
-\r
-/** Internally used class. */\r
-class RegHolder\r
-{\r
-  Regex me = null;\r
-  RegHolder prev = null;\r
-}\r
-\r
-/** Internally used class.\r
- * @see CodeRule\r
- */\r
-class CodeVal\r
-{\r
-  int pos;\r
-  char code;\r
-  CodeVal(int p, char c)\r
-  {\r
-    pos = p;\r
-    code = c;\r
-  }\r
-\r
-  public String toString()\r
-  {\r
-    return "(" + pos + "," + code + ")";\r
-  }\r
-}\r
-\r
-/**\r
-  To use this class, first use either the getReplacer() method from\r
-  Transformer or Regex.  You can then use replaceAll, replaceFirst,\r
-  etc. methods on the Replacer in the same way that you can from\r
-  either of those two classes.\r
-  <p>\r
-  The only potential difference between using the methods of\r
-  Replacer to do the replacing is that Replacer remembers changes\r
-  to the replacing object between calls to replaceAll, replaceFirst\r
-  etc.  For details, see the example file\r
-  <a href="http://javaregex.com/code/trans3.java.html">trans3.java</a>.\r
-  @see com.stevesoft.pat.Transformer\r
-  @see com.stevesoft.pat.Regex\r
- */\r
-public class Replacer\r
-{\r
-  boolean first;\r
-\r
-  /** Instantiate a new Replacer. */\r
-  public Replacer()\r
-  {}\r
-\r
-  public StringLike replaceFirstRegion(String s, Regex r,\r
-                                       int start, int end)\r
-  {\r
-    return replaceFirstRegion(new StringWrap(s), r, start, end);\r
-  }\r
-\r
-  /** This method replaces the first occurence of the Regex in the\r
-      String starting with position pos\r
-      according to the Replacer rule of this object. */\r
-  public StringLike replaceFirstRegion(StringLike s, Regex r,\r
-                                       int start, int end)\r
-  {\r
-    first = true;\r
-    rh.me = r;\r
-    rh.prev = null;\r
-    return dorep(s, start, end);\r
-  }\r
-\r
-  public StringLike replaceFirst(StringLike s)\r
-  {\r
-    return replaceFirstRegion(s, 0, s.length());\r
-  }\r
-\r
-  public StringLike replaceFirstFrom(StringLike s, int start)\r
-  {\r
-    return replaceFirstRegion(s, start, s.length());\r
-  }\r
-\r
-  public StringLike replaceFirstRegion(StringLike s, int start, int end)\r
-  {\r
-    first = true;\r
-    return dorep(s, start, end);\r
-  }\r
-\r
-  RegHolder rh = new RegHolder();\r
-\r
-  public StringLike replaceAllRegion(String s, Regex r,\r
-                                     int start, int end)\r
-  {\r
-    return replaceAllRegion(new StringWrap(s), r, start, end);\r
-  }\r
-\r
-  /** This method replaces all occurences of the Regex in the\r
-      String starting with postition pos\r
-      according to the Replacer rule of this object. */\r
-  public StringLike replaceAllRegion(StringLike s, Regex r,\r
-                                     int start, int end)\r
-  {\r
-    first = false;\r
-    // reset\r
-    rh.me = r;\r
-    rh.prev = null;\r
-    return dorep(s, start, end);\r
-  }\r
-\r
-  public StringLike replaceAll(StringLike s)\r
-  {\r
-    return replaceAllRegion(s, 0, s.length());\r
-  }\r
-\r
-  public StringLike replaceAllFrom(StringLike s, int start)\r
-  {\r
-    return replaceAllRegion(s, start, s.length());\r
-  }\r
-\r
-  public StringLike replaceAllRegion(StringLike s, int start, int end)\r
-  {\r
-    first = false;\r
-    return dorep(s, start, end);\r
-  }\r
-\r
-  public String replaceAll(String s)\r
-  {\r
-    return replaceAllRegion(new StringWrap(s), 0, s.length()).toString();\r
-  }\r
-\r
-  public String replaceAllFrom(String s, int start)\r
-  {\r
-    return replaceAllRegion(new StringWrap(s), start, s.length()).toString();\r
-  }\r
-\r
-  public String replaceAllRegion(String s, int start, int end)\r
-  {\r
-    first = false;\r
-    return dorep(new StringWrap(s), start, end).toString();\r
-  }\r
-\r
-  final public boolean isSpecial(ReplaceRule x)\r
-  {\r
-    while (x != null)\r
-    {\r
-      if (x instanceof SpecialRule\r
-          ||\r
-          (x instanceof RuleHolder && ( (RuleHolder) x).held instanceof SpecialRule))\r
-      {\r
-        return true;\r
-      }\r
-      x = x.next;\r
-    }\r
-    return false;\r
-  }\r
-\r
-  final public void apply1(RegRes rr)\r
-  {\r
-    rr.charsMatched_++;\r
-    apply(rr, null);\r
-    rr.charsMatched_--;\r
-  }\r
-\r
-  final StringLike dorep(StringLike s, int start, int end)\r
-  {\r
-    StringLike ret = s;\r
-    want_more_text = false;\r
-    lastMatchedTo = 0;\r
-    if (rh.me == null)\r
-    {\r
-      throw new NullPointerException("Replacer has null Regex pointer");\r
-    }\r
-    if (rh.me._search(s, start, end))\r
-    {\r
-      int rmn = rh.me.matchedTo();\r
-      if (rh.me.charsMatched() == 0 && !isSpecial(rh.me.getReplaceRule()))\r
-      {\r
-        apply1(rh.me);\r
-        rmn++;\r
-      }\r
-      apply(rh.me);\r
-      if (!first)\r
-      {\r
-        for (int i = rmn;\r
-             !want_more_text && rh.me._search(s, i, end); i = rmn)\r
-        {\r
-          rmn = rh.me.matchedTo();\r
-          if (rh.me.charsMatched() == 0)\r
-          {\r
-            if (!isSpecial(rh.me.getReplaceRule()))\r
-            {\r
-              apply1(rh.me);\r
-            }\r
-            rmn++;\r
-          }\r
-          apply(rh.me);\r
-        }\r
-      }\r
-      ret = finish();\r
-      ret = ret == null ? s : ret;\r
-    }\r
-    return ret;\r
-  }\r
-\r
-  StringBufferLike sb = null;\r
-  StringLike src = null;\r
-  int pos = 0;\r
-  /** This method allows you to apply the results of several\r
-      matches in a sequence to modify a String of text.  Each\r
-      call in the sequence must operate on the same piece of\r
-      text and the matchedFrom() of each RegRes given to this\r
-      method must be greater in value than the preceeding\r
-      RegRes's matchedTo() value.\r
-   */\r
-  public void apply(RegRes r, ReplaceRule rp)\r
-  {\r
-    if (rp == null || (rp.next == null && rp instanceof AmpersandRule))\r
-    {\r
-      return;\r
-    }\r
-    if (r.didMatch())\r
-    {\r
-      if (src == null)\r
-      {\r
-        src = r.getStringLike();\r
-      }\r
-      if (sb == null)\r
-      {\r
-        sb = new StringBufferLike(src.newStringBufferLike());\r
-      }\r
-      int rmf = r.matchedFrom();\r
-      for (int ii = pos; ii < rmf; ii++)\r
-      {\r
-        sb.append(src.charAt(ii));\r
-      }\r
-\r
-      for (ReplaceRule x = rp; x != null; x = x.next)\r
-      {\r
-        x.apply(sb, r);\r
-        if (x instanceof SpecialRule)\r
-        {\r
-          if (x instanceof WantMoreTextReplaceRule\r
-              && want_more_text_enable)\r
-          {\r
-            want_more_text = true;\r
-          }\r
-          else if (x instanceof PushRule)\r
-          {\r
-            RegHolder rh2 = new RegHolder();\r
-            rh2.me = ( (PushRule) x).NewRule;\r
-            rh2.prev = rh;\r
-            rh = rh2;\r
-          }\r
-          else if (x instanceof PopRule)\r
-          {\r
-            if (rh.prev != null)\r
-            {\r
-              rh = rh.prev;\r
-            }\r
-          }\r
-          else if (x instanceof ChangeRule)\r
-          {\r
-            rh.me = ( (ChangeRule) x).NewRule;\r
-          }\r
-        }\r
-      }\r
-      if (!want_more_text)\r
-      {\r
-        pos = r.matchedTo();\r
-      }\r
-    }\r
-  }\r
-\r
-  boolean want_more_text = false, want_more_text_enable = false;\r
-  public boolean WantMoreText()\r
-  {\r
-    return want_more_text;\r
-  }\r
-\r
-  /** Another form of apply, it is the same as\r
-      apply(r,r.getReplaceRule()). */\r
-  public void apply(Regex r)\r
-  {\r
-    apply(r, r.getReplaceRule());\r
-  }\r
-\r
-  /** This finishes the replacement, appending the right() part of\r
-      the last RegRes given to substitute(RegRes).  After this method\r
-      is called, the Replace object is reset to perform another\r
-      substitution. If no RegRes objects with a true didMatch are\r
-      applied, this returns null. */\r
-  public StringLike finish()\r
-  {\r
-    if (src == null)\r
-    {\r
-      return null;\r
-    }\r
-    //sb.append(src.substring(pos,src.length()));\r
-    int s_end = src.length();\r
-    for (int ii = pos; ii < s_end; ii++)\r
-    {\r
-      sb.append(src.charAt(ii));\r
-    }\r
-    src = null;\r
-    lastMatchedTo = pos;\r
-    pos = 0;\r
-    StringLike retstr = sb.toStringLike();\r
-    sb = null;\r
-    return retstr;\r
-  }\r
-\r
-  int lastMatchedTo = 0;\r
-  public Object clone()\r
-  {\r
-    Replacer r = new Replacer();\r
-    r.first = first;\r
-    r.src = src;\r
-    r.sb = sb;\r
-    r.pos = pos;\r
-    r.lastMatchedTo = lastMatchedTo;\r
-    r.want_more_text = want_more_text;\r
-    r.want_more_text_enable = want_more_text_enable;\r
-    r.rh.me = rh.me;\r
-    r.rh.prev = rh.prev;\r
-    return r;\r
-  }\r
-\r
-  public int lastMatchedTo()\r
-  {\r
-    return lastMatchedTo;\r
-  }\r
-\r
-  public Regex getRegex()\r
-  {\r
-    return rh.me;\r
-  }\r
-\r
-  public void setSource(StringLike sl)\r
-  {\r
-    src = sl;\r
-  }\r
-\r
-  public void setBuffer(StringBufferLike sbl)\r
-  {\r
-    sb = sbl;\r
-  }\r
-\r
-  public void setPos(int pos)\r
-  {\r
-    this.pos = pos;\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;
+
+import com.stevesoft.pat.wrap.*;
+
+/** Internally used class. */
+class RegHolder
+{
+  Regex me = null;
+
+  RegHolder prev = null;
+}
+
+/**
+ * Internally used class.
+ * 
+ * @see CodeRule
+ */
+class CodeVal
+{
+  int pos;
+
+  char code;
+
+  CodeVal(int p, char c)
+  {
+    pos = p;
+    code = c;
+  }
+
+  public String toString()
+  {
+    return "(" + pos + "," + code + ")";
+  }
+}
+
+/**
+ * To use this class, first use either the getReplacer() method from Transformer
+ * or Regex. You can then use replaceAll, replaceFirst, etc. methods on the
+ * Replacer in the same way that you can from either of those two classes.
+ * <p>
+ * The only potential difference between using the methods of Replacer to do the
+ * replacing is that Replacer remembers changes to the replacing object between
+ * calls to replaceAll, replaceFirst etc. For details, see the example file <a
+ * href="http://javaregex.com/code/trans3.java.html">trans3.java</a>.
+ * 
+ * @see com.stevesoft.pat.Transformer
+ * @see com.stevesoft.pat.Regex
+ */
+public class Replacer
+{
+  boolean first;
+
+  /** Instantiate a new Replacer. */
+  public Replacer()
+  {
+  }
+
+  public StringLike replaceFirstRegion(String s, Regex r, int start, int end)
+  {
+    return replaceFirstRegion(new StringWrap(s), r, start, end);
+  }
+
+  /**
+   * This method replaces the first occurence of the Regex in the String
+   * starting with position pos according to the Replacer rule of this object.
+   */
+  public StringLike replaceFirstRegion(StringLike s, Regex r, int start,
+          int end)
+  {
+    first = true;
+    rh.me = r;
+    rh.prev = null;
+    return dorep(s, start, end);
+  }
+
+  public StringLike replaceFirst(StringLike s)
+  {
+    return replaceFirstRegion(s, 0, s.length());
+  }
+
+  public StringLike replaceFirstFrom(StringLike s, int start)
+  {
+    return replaceFirstRegion(s, start, s.length());
+  }
+
+  public StringLike replaceFirstRegion(StringLike s, int start, int end)
+  {
+    first = true;
+    return dorep(s, start, end);
+  }
+
+  RegHolder rh = new RegHolder();
+
+  public StringLike replaceAllRegion(String s, Regex r, int start, int end)
+  {
+    return replaceAllRegion(new StringWrap(s), r, start, end);
+  }
+
+  /**
+   * This method replaces all occurences of the Regex in the String starting
+   * with postition pos according to the Replacer rule of this object.
+   */
+  public StringLike replaceAllRegion(StringLike s, Regex r, int start,
+          int end)
+  {
+    first = false;
+    // reset
+    rh.me = r;
+    rh.prev = null;
+    return dorep(s, start, end);
+  }
+
+  public StringLike replaceAll(StringLike s)
+  {
+    return replaceAllRegion(s, 0, s.length());
+  }
+
+  public StringLike replaceAllFrom(StringLike s, int start)
+  {
+    return replaceAllRegion(s, start, s.length());
+  }
+
+  public StringLike replaceAllRegion(StringLike s, int start, int end)
+  {
+    first = false;
+    return dorep(s, start, end);
+  }
+
+  public String replaceAll(String s)
+  {
+    return replaceAllRegion(new StringWrap(s), 0, s.length()).toString();
+  }
+
+  public String replaceAllFrom(String s, int start)
+  {
+    return replaceAllRegion(new StringWrap(s), start, s.length())
+            .toString();
+  }
+
+  public String replaceAllRegion(String s, int start, int end)
+  {
+    first = false;
+    return dorep(new StringWrap(s), start, end).toString();
+  }
+
+  final public boolean isSpecial(ReplaceRule x)
+  {
+    while (x != null)
+    {
+      if (x instanceof SpecialRule
+              || (x instanceof RuleHolder && ((RuleHolder) x).held instanceof SpecialRule))
+      {
+        return true;
+      }
+      x = x.next;
+    }
+    return false;
+  }
+
+  final public void apply1(RegRes rr)
+  {
+    rr.charsMatched_++;
+    apply(rr, null);
+    rr.charsMatched_--;
+  }
+
+  final StringLike dorep(StringLike s, int start, int end)
+  {
+    StringLike ret = s;
+    want_more_text = false;
+    lastMatchedTo = 0;
+    if (rh.me == null)
+    {
+      throw new NullPointerException("Replacer has null Regex pointer");
+    }
+    if (rh.me._search(s, start, end))
+    {
+      int rmn = rh.me.matchedTo();
+      if (rh.me.charsMatched() == 0 && !isSpecial(rh.me.getReplaceRule()))
+      {
+        apply1(rh.me);
+        rmn++;
+      }
+      apply(rh.me);
+      if (!first)
+      {
+        for (int i = rmn; !want_more_text && rh.me._search(s, i, end); i = rmn)
+        {
+          rmn = rh.me.matchedTo();
+          if (rh.me.charsMatched() == 0)
+          {
+            if (!isSpecial(rh.me.getReplaceRule()))
+            {
+              apply1(rh.me);
+            }
+            rmn++;
+          }
+          apply(rh.me);
+        }
+      }
+      ret = finish();
+      ret = ret == null ? s : ret;
+    }
+    return ret;
+  }
+
+  StringBufferLike sb = null;
+
+  StringLike src = null;
+
+  int pos = 0;
+
+  /**
+   * This method allows you to apply the results of several matches in a
+   * sequence to modify a String of text. Each call in the sequence must operate
+   * on the same piece of text and the matchedFrom() of each RegRes given to
+   * this method must be greater in value than the preceeding RegRes's
+   * matchedTo() value.
+   */
+  public void apply(RegRes r, ReplaceRule rp)
+  {
+    if (rp == null || (rp.next == null && rp instanceof AmpersandRule))
+    {
+      return;
+    }
+    if (r.didMatch())
+    {
+      if (src == null)
+      {
+        src = r.getStringLike();
+      }
+      if (sb == null)
+      {
+        sb = new StringBufferLike(src.newStringBufferLike());
+      }
+      int rmf = r.matchedFrom();
+      for (int ii = pos; ii < rmf; ii++)
+      {
+        sb.append(src.charAt(ii));
+      }
+
+      for (ReplaceRule x = rp; x != null; x = x.next)
+      {
+        x.apply(sb, r);
+        if (x instanceof SpecialRule)
+        {
+          if (x instanceof WantMoreTextReplaceRule && want_more_text_enable)
+          {
+            want_more_text = true;
+          }
+          else if (x instanceof PushRule)
+          {
+            RegHolder rh2 = new RegHolder();
+            rh2.me = ((PushRule) x).NewRule;
+            rh2.prev = rh;
+            rh = rh2;
+          }
+          else if (x instanceof PopRule)
+          {
+            if (rh.prev != null)
+            {
+              rh = rh.prev;
+            }
+          }
+          else if (x instanceof ChangeRule)
+          {
+            rh.me = ((ChangeRule) x).NewRule;
+          }
+        }
+      }
+      if (!want_more_text)
+      {
+        pos = r.matchedTo();
+      }
+    }
+  }
+
+  boolean want_more_text = false, want_more_text_enable = false;
+
+  public boolean WantMoreText()
+  {
+    return want_more_text;
+  }
+
+  /**
+   * Another form of apply, it is the same as apply(r,r.getReplaceRule()).
+   */
+  public void apply(Regex r)
+  {
+    apply(r, r.getReplaceRule());
+  }
+
+  /**
+   * This finishes the replacement, appending the right() part of the last
+   * RegRes given to substitute(RegRes). After this method is called, the
+   * Replace object is reset to perform another substitution. If no RegRes
+   * objects with a true didMatch are applied, this returns null.
+   */
+  public StringLike finish()
+  {
+    if (src == null)
+    {
+      return null;
+    }
+    // sb.append(src.substring(pos,src.length()));
+    int s_end = src.length();
+    for (int ii = pos; ii < s_end; ii++)
+    {
+      sb.append(src.charAt(ii));
+    }
+    src = null;
+    lastMatchedTo = pos;
+    pos = 0;
+    StringLike retstr = sb.toStringLike();
+    sb = null;
+    return retstr;
+  }
+
+  int lastMatchedTo = 0;
+
+  public Object clone()
+  {
+    Replacer r = new Replacer();
+    r.first = first;
+    r.src = src;
+    r.sb = sb;
+    r.pos = pos;
+    r.lastMatchedTo = lastMatchedTo;
+    r.want_more_text = want_more_text;
+    r.want_more_text_enable = want_more_text_enable;
+    r.rh.me = rh.me;
+    r.rh.prev = rh.prev;
+    return r;
+  }
+
+  public int lastMatchedTo()
+  {
+    return lastMatchedTo;
+  }
+
+  public Regex getRegex()
+  {
+    return rh.me;
+  }
+
+  public void setSource(StringLike sl)
+  {
+    src = sl;
+  }
+
+  public void setBuffer(StringBufferLike sbl)
+  {
+    sb = sbl;
+  }
+
+  public void setPos(int pos)
+  {
+    this.pos = pos;
+  }
+}