needed for applet search
[jalview.git] / src / com / stevesoft / pat / parsePerl.java
diff --git a/src/com/stevesoft/pat/parsePerl.java b/src/com/stevesoft/pat/parsePerl.java
new file mode 100755 (executable)
index 0000000..5cdbabe
--- /dev/null
@@ -0,0 +1,266 @@
+//\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 provides a method for parsing the "s/.../.../" constructs\r
+of Regex.perlCode.\r
+@see Regex#perlCode\r
+*/\r
+class parsePerl {\r
+    final static char close(char c) {\r
+        // This switch statement does not behave\r
+        // properly when compiled with jdk1.1.5\r
+        // and the -O flag.\r
+        /*\r
+        switch(c) {\r
+        case '[':\r
+          return ']';\r
+        case '(':\r
+          return ')';\r
+        case '{':\r
+          return '}';\r
+        }\r
+        return c;*/\r
+       if(c == '<')\r
+           return '>';\r
+        if(c == '[')\r
+            return ']';\r
+        if(c == '(')\r
+            return ')';\r
+        if(c == '{')\r
+            return '}';\r
+        return c;\r
+    }\r
+\r
+    final public static String codify(String s,boolean keepbs) {\r
+        return codify(s,0,s.length(),keepbs);\r
+    }\r
+    final public static String codify(String s,int i0,int iN,boolean keepbs) {\r
+        StringBuffer sb = new StringBuffer();\r
+        boolean ucmode = false, lcmode = false, litmode = false;\r
+        boolean uc1 = false, lc1 = false;\r
+        boolean modified = false;\r
+        for(int i=i0;i<iN;i++) {\r
+            char c = s.charAt(i);\r
+            boolean mf = true, app=true;\r
+            if(c=='\\') {\r
+                app=false;\r
+                i++;\r
+                if(i<s.length()) {\r
+                    char c2 = s.charAt(i);\r
+                    switch(c2) {\r
+                    case 'Q':\r
+                        litmode = true;\r
+                        break;\r
+                    case 'U':\r
+                        ucmode = true;\r
+                        break;\r
+                    case 'L':\r
+                        lcmode = true;\r
+                        break;\r
+                    case 'u':\r
+                        uc1 = true;\r
+                        break;\r
+                    case 'l':\r
+                        lc1 = true;\r
+                        break;\r
+                    case 'E':\r
+                        uc1=lc1=ucmode=lcmode=litmode=false;\r
+                        break;\r
+                    default:\r
+                        if(keepbs)\r
+                            sb.append('\\');\r
+                        c=c2;\r
+                        if(keepbs) mf = false;\r
+                        app = true;\r
+                        break;\r
+                    }\r
+                    modified |= mf;\r
+                }\r
+            }\r
+            if(app) {\r
+                if(lc1) {\r
+                    c=lc(c);\r
+                    lc1=false;\r
+                } else if(uc1) {\r
+                    c=uc(c);\r
+                    uc1=false;\r
+                } else if(ucmode) {\r
+                    c=uc(c);\r
+                } else if(lcmode) {\r
+                    c=lc(c);\r
+                }\r
+                if(litmode && needbs(c))\r
+                    sb.append('\\');\r
+                sb.append(c);\r
+            }\r
+        }\r
+        return modified ? sb.toString() : s;\r
+    }\r
+    final static char uc(char c) {\r
+        return CaseMgr.toUpperCase(c);\r
+    }\r
+    final static char lc(char c) {\r
+        return CaseMgr.toLowerCase(c);\r
+    }\r
+    final static boolean needbs(char c) {\r
+        if(c >= 'a' && c <= 'z')\r
+            return false;\r
+        if(c >= 'A' && c <= 'Z')\r
+            return false;\r
+        if(c >= '0' && c <= '9')\r
+            return false;\r
+        if(c == '_')\r
+            return false;\r
+        return true;\r
+    }\r
+    final static Regex parse(String s) {\r
+        boolean igncase = false, optim = false, gFlag = false;\r
+        boolean sFlag = false, mFlag = false, xFlag = false;\r
+\r
+        StringBuffer s1 = new StringBuffer();\r
+        StringBuffer s2 = new StringBuffer();\r
+        int i=0,count=0;\r
+        char mode,delim='/',cdelim='/';\r
+        if(s.length() >= 3 && s.charAt(0)=='s') {\r
+            mode = 's';\r
+            delim = s.charAt(1);\r
+            cdelim = close(delim);\r
+            i=2;\r
+        } else if(s.length() >= 2 && s.charAt(0)=='m') {\r
+            mode = 'm';\r
+            delim = s.charAt(1);\r
+            cdelim = close(delim);\r
+            i=2;\r
+        } else if(s.length() >= 1 && s.charAt(0)=='/') {\r
+            mode = 'm';\r
+            i=1;\r
+        } else {\r
+            try {\r
+                RegSyntaxError.endItAll(\r
+                   "Regex.perlCode should be of the "+\r
+                    "form s/// or m// or //");\r
+            } catch(RegSyntax rs) {}\r
+            return null;\r
+        }\r
+        for(;i<s.length();i++) {\r
+            if(s.charAt(i)=='\\') {\r
+                s1.append('\\');\r
+                i++;\r
+            } else if(s.charAt(i)==cdelim && count==0) {\r
+                i++;\r
+                break;\r
+            } else if(s.charAt(i)==delim && cdelim != delim) {\r
+                count++;\r
+            } else if(s.charAt(i)==cdelim && cdelim != delim) {\r
+                count--;\r
+            }\r
+            s1.append(s.charAt(i));\r
+        }\r
+        if(mode=='s' && cdelim != delim) {\r
+            while(i<s.length() && Prop.isWhite(s.charAt(i)) )\r
+                i++;\r
+            if(i>=s.length()) {\r
+                try {\r
+                    RegSyntaxError.endItAll(""+mode+delim+" needs "+cdelim);\r
+                } catch(RegSyntax rs) {}\r
+                return null;\r
+            }\r
+            cdelim = close(delim = s.charAt(i));\r
+            i++;\r
+        }\r
+        count=0;\r
+        if(mode=='s') {\r
+            for(;i<s.length();i++) {\r
+                if(s.charAt(i)=='\\') {\r
+                    s2.append('\\');\r
+                    i++;\r
+                } else if(s.charAt(i)==cdelim && count==0) {\r
+                    i++;\r
+                    break;\r
+                } else if(s.charAt(i)==delim && cdelim != delim) {\r
+                    count++;\r
+                } else if(s.charAt(i)==cdelim && cdelim != delim) {\r
+                    count--;\r
+                }\r
+                s2.append(s.charAt(i));\r
+            }\r
+        }\r
+        for(;i<s.length();i++) {\r
+            char c = s.charAt(i);\r
+            switch(c) {\r
+           case 'x':\r
+               xFlag = true;\r
+               break;\r
+            case 'i':\r
+                igncase = true;\r
+                break;\r
+            case 'o':\r
+                optim = true;\r
+                break;\r
+            case 's':\r
+                sFlag = true;\r
+                break;\r
+            case 'm':\r
+               mFlag = true;\r
+                break;\r
+            case 'g':\r
+                gFlag = true;\r
+                break;\r
+            default:\r
+                // syntax error!\r
+                try {\r
+                    RegSyntaxError.endItAll("Illegal flag to pattern: "+c);\r
+                } catch(RegSyntax rs) {}\r
+                return null;\r
+            }\r
+        }\r
+        Regex r = new Regex();\r
+        try {\r
+            String pat=s1.toString(),reprul=s2.toString();\r
+           if(xFlag) {\r
+             pat = strip(pat);\r
+             reprul = strip(reprul);\r
+           }\r
+            r.compile(pat);\r
+            r.ignoreCase |= igncase;\r
+            r.gFlag |= gFlag;\r
+            r.sFlag |= sFlag;\r
+           r.mFlag |= mFlag;\r
+            if(optim) r.optimize();\r
+           if(delim=='\'')\r
+              r.setReplaceRule(new StringRule(reprul));\r
+           else\r
+              r.setReplaceRule(ReplaceRule.perlCode(reprul));\r
+        } catch(RegSyntax rs) {\r
+            r = null;\r
+        }\r
+        return r;\r
+    }\r
+    static String strip(String s) {\r
+      StringBuffer sb = new StringBuffer();\r
+      for(int i=0;i<s.length();i++) {\r
+        char c = s.charAt(i);\r
+       if(Prop.isWhite(c)) {\r
+         ;\r
+       } else if(c == '#') {\r
+         i++;\r
+         while(i<s.length()) {\r
+           if(s.charAt(i) == '\n')\r
+             break;\r
+           i++;\r
+         }\r
+        } else if(c == '\\') {\r
+         sb.append(c);\r
+         sb.append(s.charAt(++i));\r
+       } else\r
+         sb.append(c);\r
+      }\r
+      return sb.toString();\r
+    }\r
+}\r