@see com.stevesoft.pat.LeftRule\r
@see com.stevesoft.pat.RightRule\r
@see com.stevesoft.pat.StringRule\r
- */\r
-public abstract class ReplaceRule {\r
- /** points to the next ReplaceRule in the linked list. */\r
- protected ReplaceRule next = null;\r
- /** This function appends to the StringBufferLike the text you want\r
- to replaced the portion of the String last matched. */\r
- public abstract void apply(StringBufferLike sb,RegRes r);\r
-\r
- /** A rule describing how to clone only the current ReplaceRule,\r
- and none of the others in this linked list. It is called by\r
- clone() for each item in the list. */\r
- public Object clone1() {\r
- return new RuleHolder(this);\r
- }\r
- public final Object clone() {\r
- ReplaceRule x = (ReplaceRule)clone1();\r
- ReplaceRule xsav = x;\r
- ReplaceRule y = this;\r
- while(y.next != null) {\r
- x.next = (ReplaceRule)y.next.clone1();\r
- x.name = y.name;\r
- x = x.next;\r
- y = y.next;\r
- }\r
- return xsav;\r
+ */\r
+public abstract class ReplaceRule\r
+{\r
+ /** points to the next ReplaceRule in the linked list. */\r
+ protected ReplaceRule next = null;\r
+ /** This function appends to the StringBufferLike the text you want\r
+ to replaced the portion of the String last matched. */\r
+ public abstract void apply(StringBufferLike sb, RegRes r);\r
+\r
+ /** A rule describing how to clone only the current ReplaceRule,\r
+ and none of the others in this linked list. It is called by\r
+ clone() for each item in the list. */\r
+ public Object clone1()\r
+ {\r
+ return new RuleHolder(this);\r
+ }\r
+\r
+ public final Object clone()\r
+ {\r
+ ReplaceRule x = (ReplaceRule) clone1();\r
+ ReplaceRule xsav = x;\r
+ ReplaceRule y = this;\r
+ while (y.next != null)\r
+ {\r
+ x.next = (ReplaceRule) y.next.clone1();\r
+ x.name = y.name;\r
+ x = x.next;\r
+ y = y.next;\r
}\r
- static ReplaceRule add(ReplaceRule head,ReplaceRule adding) {\r
- if(head == null)\r
- return head = adding;\r
- head.addRule(adding);\r
- return head;\r
+ return xsav;\r
+ }\r
+\r
+ static ReplaceRule add(ReplaceRule head, ReplaceRule adding)\r
+ {\r
+ if (head == null)\r
+ {\r
+ return head = adding;\r
}\r
- public ReplaceRule add(ReplaceRule adding) {\r
- return add(this,adding);\r
+ head.addRule(adding);\r
+ return head;\r
+ }\r
+\r
+ public ReplaceRule add(ReplaceRule adding)\r
+ {\r
+ return add(this, adding);\r
+ }\r
+\r
+ /** Add another ReplaceRule to the linked list. */\r
+ public void addRule(ReplaceRule r)\r
+ {\r
+ if (next == null)\r
+ {\r
+ next = r;\r
}\r
- /** Add another ReplaceRule to the linked list. */\r
- public void addRule(ReplaceRule r) {\r
- if(next == null) next = r;\r
- else next.addRule(r);\r
+ else\r
+ {\r
+ next.addRule(r);\r
}\r
- static Regex getvar = null;\r
- final static Regex getv() {\r
- // Thanks to Michael Jimenez for pointing out the need\r
- // to clone getvar rather than simply returning it.\r
- // Previously this was not thread safe.\r
- //if(getvar != null) return getvar;\r
- if(getvar != null) return (Regex)getvar.clone();\r
- getvar=\r
- new Regex(\r
- "(?:\\\\(\\d+)|"+ // ref 1\r
- "\\$(?:"+\r
- "(\\d+)|"+ // ref 2\r
- "(\\w+)|"+ // ref 3\r
- "([&'`])|"+ // ref 4\r
- "\\{(?:(\\d+)|"+ // ref 5\r
- "([^\n}\\\\]+))}"+ // ref 6\r
- ")|"+ \r
- "\\\\([nrbtaef])|"+ // ref 7\r
- "\\\\c([\u0000-\uFFFF])|"+ // ref 8\r
- "\\\\x([A-Fa-f0-9]{2})|"+ // ref 9\r
- "\\\\([\u0000-\uFFFF])"+ // ref 10\r
- ")");\r
- getvar.optimize();\r
- return getvar;\r
+ }\r
+\r
+ static Regex getvar = null;\r
+ final static Regex getv()\r
+ {\r
+ // Thanks to Michael Jimenez for pointing out the need\r
+ // to clone getvar rather than simply returning it.\r
+ // Previously this was not thread safe.\r
+ //if(getvar != null) return getvar;\r
+ if (getvar != null)\r
+ {\r
+ return (Regex) getvar.clone();\r
}\r
- /** Compile a ReplaceRule using the text that would go between\r
- the second and third /'s in a typical substitution pattern\r
- in Perl: s/ ... / <i>The argument to ReplaceRule.perlCode</i> /.\r
- */\r
- public static ReplaceRule perlCode(String s) {\r
- //String sav_backGs = Regex.backGs;\r
- //int sav_backGto = Regex.backGto;\r
- try {\r
- int mf = 0, mt = 0;\r
- Regex gv = getv();\r
- ReplaceRule head = null;\r
- Object tmp = null;\r
- while(gv.searchFrom(s,mt)) {\r
- int off=Regex.BackRefOffset-1;\r
- mf = gv.matchedFrom();\r
- if(mf > mt)\r
- head=add(head,\r
- new StringRule(s.substring(mt,mf)));\r
- String var = null;\r
- if((var=gv.stringMatched(1+off)) != null\r
- || (var=gv.stringMatched(2+off)) != null\r
- || (var=gv.stringMatched(5+off)) != null) {\r
- int d=0;\r
- for(int i=0;i<var.length();i++)\r
- d = 8*d+( var.charAt(i)-'0' );\r
- if(var.length() == 1)\r
- head=add(head,new BackRefRule(d));\r
- else\r
- head=new StringRule(""+(char)d);\r
- } else if(\r
- (var=gv.stringMatched(10+off)) != null) {\r
- if("QELlUu".indexOf(var) >= 0)\r
- head=add(head,new CodeRule(var.charAt(0)) );\r
- else\r
- head=add(head,new StringRule(var) );\r
- } else if(\r
- (var=gv.stringMatched(3+off)) != null\r
- || (var=gv.stringMatched(4+off)) != null\r
- || (var=gv.stringMatched(6+off)) != null) {\r
- String arg = "";\r
- int pc;\r
- if((pc=var.indexOf(':')) > 0) {\r
- arg = var.substring(pc+1);\r
- var = var.substring(0,pc);\r
- }\r
- if(var.equals("&")||var.equals("MATCH")) {\r
- head=add(head,new AmpersandRule());\r
- } else if(var.equals("`")||var.equals("PREMATCH")) {\r
- head=add(head,new LeftRule());\r
- } else if(var.equals("'")||var.equals("POSTMATCH")) {\r
- head=add(head,new RightRule());\r
- } else if(var.equals("WANT_MORE_TEXT")) {\r
- head=add(head,new WantMoreTextReplaceRule());\r
- } else if(var.equals("POP")) {\r
- head=add(head,new PopRule());\r
- } else if(var.startsWith("+") && (tmp=defs.get(var.substring(1))) != null) {\r
- if(tmp instanceof Regex)\r
- head=add(head,new PushRule(var.substring(1),(Regex)tmp));\r
- else if(tmp instanceof Transformer)\r
- head=add(head,new PushRule(var.substring(1),(Transformer)tmp));\r
- else head=add(head,new StringRule("${"+var+"}"));\r
- } else if(var.startsWith("=") && (tmp=defs.get(var.substring(1))) != null) {\r
- if(tmp instanceof Regex)\r
- head=add(head,new ChangeRule(var.substring(1),(Regex)tmp));\r
- else if(tmp instanceof Transformer)\r
- head=add(head,new ChangeRule(var.substring(1),(Transformer)tmp));\r
- else head=add(head,new StringRule("${"+var+"}"));\r
- } else if( (tmp=defs.get(var)) != null) {\r
- if(tmp instanceof ReplaceRule) {\r
- ReplaceRule alt = ((ReplaceRule)tmp).arg(arg);\r
- if(alt == null) alt = ((ReplaceRule)tmp);\r
- head=add(head,(ReplaceRule)(alt.clone()));\r
- }\r
- } else // can't figure out how to transform this thing...\r
- head=add(head,new StringRule("${"+var+"}"));\r
- } else if(\r
- (var = gv.stringMatched(7+off)) != null) {\r
- char c = var.charAt(0);\r
- if(c == 'n')\r
- head=add(head,new StringRule("\n"));\r
- else if(c == 't')\r
- head=add(head,new StringRule("\t"));\r
- else if(c == 'r')\r
- head=add(head,new StringRule("\r"));\r
- else if(c == 'b')\r
- head=add(head,new StringRule("\r"));\r
- else if(c == 'a')\r
- head=add(head,new StringRule(""+(char)7));\r
- else if(c == 'e')\r
- head=add(head,new StringRule(""+(char)27));\r
- else if(c == 'f')\r
- head=add(head,new StringRule(""+(char)12));\r
- } else if(\r
- (var = gv.stringMatched(8+off)) != null) {\r
- char c = var.charAt(0);\r
- if(c < Ctrl.cmap.length)\r
- c = Ctrl.cmap[c];\r
- head=add(head,new StringRule(""+c));\r
- } else if(\r
- (var = gv.stringMatched(9+off)) != null) {\r
- int d =\r
- 16*getHexDigit(var.charAt(0))+\r
- getHexDigit(var.charAt(1));\r
- head=add(head,new StringRule(""+(char)d));\r
- }\r
- mt = gv.matchedTo();\r
+ getvar =\r
+ new Regex(\r
+ "(?:\\\\(\\d+)|" + // ref 1\r
+ "\\$(?:" +\r
+ "(\\d+)|" + // ref 2\r
+ "(\\w+)|" + // ref 3\r
+ "([&'`])|" + // ref 4\r
+ "\\{(?:(\\d+)|" + // ref 5\r
+ "([^\n}\\\\]+))}" + // ref 6\r
+ ")|" +\r
+ "\\\\([nrbtaef])|" + // ref 7\r
+ "\\\\c([\u0000-\uFFFF])|" + // ref 8\r
+ "\\\\x([A-Fa-f0-9]{2})|" + // ref 9\r
+ "\\\\([\u0000-\uFFFF])" + // ref 10\r
+ ")");\r
+ getvar.optimize();\r
+ return getvar;\r
+ }\r
+\r
+ /** Compile a ReplaceRule using the text that would go between\r
+ the second and third /'s in a typical substitution pattern\r
+ in Perl: s/ ... / <i>The argument to ReplaceRule.perlCode</i> /.\r
+ */\r
+ public static ReplaceRule perlCode(String s)\r
+ {\r
+ //String sav_backGs = Regex.backGs;\r
+ //int sav_backGto = Regex.backGto;\r
+ try\r
+ {\r
+ int mf = 0, mt = 0;\r
+ Regex gv = getv();\r
+ ReplaceRule head = null;\r
+ Object tmp = null;\r
+ while (gv.searchFrom(s, mt))\r
+ {\r
+ int off = Regex.BackRefOffset - 1;\r
+ mf = gv.matchedFrom();\r
+ if (mf > mt)\r
+ {\r
+ head = add(head,\r
+ new StringRule(s.substring(mt, mf)));\r
+ }\r
+ String var = null;\r
+ if ( (var = gv.stringMatched(1 + off)) != null\r
+ || (var = gv.stringMatched(2 + off)) != null\r
+ || (var = gv.stringMatched(5 + off)) != null)\r
+ {\r
+ int d = 0;\r
+ for (int i = 0; i < var.length(); i++)\r
+ {\r
+ d = 8 * d + (var.charAt(i) - '0');\r
+ }\r
+ if (var.length() == 1)\r
+ {\r
+ head = add(head, new BackRefRule(d));\r
+ }\r
+ else\r
+ {\r
+ head = new StringRule("" + (char) d);\r
+ }\r
+ }\r
+ else if (\r
+ (var = gv.stringMatched(10 + off)) != null)\r
+ {\r
+ if ("QELlUu".indexOf(var) >= 0)\r
+ {\r
+ head = add(head, new CodeRule(var.charAt(0)));\r
+ }\r
+ else\r
+ {\r
+ head = add(head, new StringRule(var));\r
+ }\r
+ }\r
+ else if (\r
+ (var = gv.stringMatched(3 + off)) != null\r
+ || (var = gv.stringMatched(4 + off)) != null\r
+ || (var = gv.stringMatched(6 + off)) != null)\r
+ {\r
+ String arg = "";\r
+ int pc;\r
+ if ( (pc = var.indexOf(':')) > 0)\r
+ {\r
+ arg = var.substring(pc + 1);\r
+ var = var.substring(0, pc);\r
+ }\r
+ if (var.equals("&") || var.equals("MATCH"))\r
+ {\r
+ head = add(head, new AmpersandRule());\r
+ }\r
+ else if (var.equals("`") || var.equals("PREMATCH"))\r
+ {\r
+ head = add(head, new LeftRule());\r
+ }\r
+ else if (var.equals("'") || var.equals("POSTMATCH"))\r
+ {\r
+ head = add(head, new RightRule());\r
+ }\r
+ else if (var.equals("WANT_MORE_TEXT"))\r
+ {\r
+ head = add(head, new WantMoreTextReplaceRule());\r
+ }\r
+ else if (var.equals("POP"))\r
+ {\r
+ head = add(head, new PopRule());\r
+ }\r
+ else if (var.startsWith("+") && (tmp = defs.get(var.substring(1))) != null)\r
+ {\r
+ if (tmp instanceof Regex)\r
+ {\r
+ head = add(head, new PushRule(var.substring(1), (Regex) tmp));\r
+ }\r
+ else if (tmp instanceof Transformer)\r
+ {\r
+ head = add(head, new PushRule(var.substring(1), (Transformer) tmp));\r
+ }\r
+ else\r
+ {\r
+ head = add(head, new StringRule("${" + var + "}"));\r
+ }\r
+ }\r
+ else if (var.startsWith("=") && (tmp = defs.get(var.substring(1))) != null)\r
+ {\r
+ if (tmp instanceof Regex)\r
+ {\r
+ head = add(head, new ChangeRule(var.substring(1), (Regex) tmp));\r
+ }\r
+ else if (tmp instanceof Transformer)\r
+ {\r
+ head = add(head,\r
+ new ChangeRule(var.substring(1), (Transformer) tmp));\r
}\r
- if(mt <= s.length())\r
- head=add(head,new StringRule(s.substring(mt)));\r
- return head;\r
- } finally {\r
- //Regex.backGs = sav_backGs;\r
- //Regex.backGto = sav_backGto;\r
+ else\r
+ {\r
+ head = add(head, new StringRule("${" + var + "}"));\r
+ }\r
+ }\r
+ else if ( (tmp = defs.get(var)) != null)\r
+ {\r
+ if (tmp instanceof ReplaceRule)\r
+ {\r
+ ReplaceRule alt = ( (ReplaceRule) tmp).arg(arg);\r
+ if (alt == null)\r
+ {\r
+ alt = ( (ReplaceRule) tmp);\r
+ }\r
+ head = add(head, (ReplaceRule) (alt.clone()));\r
+ }\r
+ }\r
+ else // can't figure out how to transform this thing...\r
+ {\r
+ head = add(head, new StringRule("${" + var + "}"));\r
+ }\r
+ }\r
+ else if (\r
+ (var = gv.stringMatched(7 + off)) != null)\r
+ {\r
+ char c = var.charAt(0);\r
+ if (c == 'n')\r
+ {\r
+ head = add(head, new StringRule("\n"));\r
+ }\r
+ else if (c == 't')\r
+ {\r
+ head = add(head, new StringRule("\t"));\r
+ }\r
+ else if (c == 'r')\r
+ {\r
+ head = add(head, new StringRule("\r"));\r
+ }\r
+ else if (c == 'b')\r
+ {\r
+ head = add(head, new StringRule("\r"));\r
+ }\r
+ else if (c == 'a')\r
+ {\r
+ head = add(head, new StringRule("" + (char) 7));\r
+ }\r
+ else if (c == 'e')\r
+ {\r
+ head = add(head, new StringRule("" + (char) 27));\r
+ }\r
+ else if (c == 'f')\r
+ {\r
+ head = add(head, new StringRule("" + (char) 12));\r
+ }\r
+ }\r
+ else if (\r
+ (var = gv.stringMatched(8 + off)) != null)\r
+ {\r
+ char c = var.charAt(0);\r
+ if (c < Ctrl.cmap.length)\r
+ {\r
+ c = Ctrl.cmap[c];\r
+ }\r
+ head = add(head, new StringRule("" + c));\r
}\r
+ else if (\r
+ (var = gv.stringMatched(9 + off)) != null)\r
+ {\r
+ int d =\r
+ 16 * getHexDigit(var.charAt(0)) +\r
+ getHexDigit(var.charAt(1));\r
+ head = add(head, new StringRule("" + (char) d));\r
+ }\r
+ mt = gv.matchedTo();\r
+ }\r
+ if (mt <= s.length())\r
+ {\r
+ head = add(head, new StringRule(s.substring(mt)));\r
+ }\r
+ return head;\r
}\r
- static Hashtable defs = new Hashtable();\r
- public static boolean isDefined(String s) { return defs.get(s) != null; }\r
- public static void define(String s,Regex r) { defs.put(s,r); }\r
- public static void define(String s,ReplaceRule r) {\r
- defs.put(s,r);\r
- r.name = s;\r
+ finally\r
+ {\r
+ //Regex.backGs = sav_backGs;\r
+ //Regex.backGto = sav_backGto;\r
}\r
- String name = getClass().getName();\r
- public static void define(String s,Transformer t) { defs.put(s,t); }\r
- public static void undefine(String s) { defs.remove(s); }\r
- /** This tells how to convert just the current element (and none\r
- of the other items in the linked list) to a String. This\r
- method is called by toString() for each item in the linked\r
- list. */\r
- public String toString1() {\r
- return "${"+name+"}";\r
+ }\r
+\r
+ static Hashtable defs = new Hashtable();\r
+ public static boolean isDefined(String s)\r
+ {\r
+ return defs.get(s) != null;\r
+ }\r
+\r
+ public static void define(String s, Regex r)\r
+ {\r
+ defs.put(s, r);\r
+ }\r
+\r
+ public static void define(String s, ReplaceRule r)\r
+ {\r
+ defs.put(s, r);\r
+ r.name = s;\r
+ }\r
+\r
+ String name = getClass().getName();\r
+\r
+ public static void define(String s, Transformer t)\r
+ {\r
+ defs.put(s, t);\r
+ }\r
+\r
+ public static void undefine(String s)\r
+ {\r
+ defs.remove(s);\r
+ }\r
+\r
+ /** This tells how to convert just the current element (and none\r
+ of the other items in the linked list) to a String. This\r
+ method is called by toString() for each item in the linked\r
+ list. */\r
+ public String toString1()\r
+ {\r
+ return "${" + name + "}";\r
+ }\r
+\r
+ /** Convert to a String. */\r
+ public final String toString()\r
+ {\r
+ StringBuffer sb = new StringBuffer();\r
+ sb.append(toString1());\r
+ ReplaceRule rr = this.next;\r
+ while (rr != null)\r
+ {\r
+ sb.append(rr.toString1());\r
+ rr = rr.next;\r
}\r
- /** Convert to a String. */\r
- public final String toString() {\r
- StringBuffer sb = new StringBuffer();\r
- sb.append(toString1());\r
- ReplaceRule rr = this.next;\r
- while(rr != null) {\r
- sb.append(rr.toString1());\r
- rr = rr.next;\r
- }\r
- return sb.toString();\r
+ return sb.toString();\r
+ }\r
+\r
+ /** Modified the behavior of a ReplaceRule by supplying\r
+ an argument. If a ReplaceRule named "foo" is defined\r
+ and the pattern "s/x/${foo:5}/" is given to Regex.perlCode,\r
+ then the "foo" the definition of "foo" will be retrieved\r
+ and arg("5") will be called. If the result is non-null,\r
+ that is the ReplaceRule that will be used. If the result\r
+ is null, then the pattern works just as if it were\r
+ "s/x/${foo}/".\r
+ @see com.stevesoft.pat.Validator#arg(java.lang.String)\r
+ */\r
+ public ReplaceRule arg(String s)\r
+ {\r
+ return null;\r
+ }\r
+\r
+ static int getHexDigit(char c)\r
+ {\r
+ if (c >= '0' && c <= '9')\r
+ {\r
+ return c - '0';\r
}\r
- /** Modified the behavior of a ReplaceRule by supplying\r
- an argument. If a ReplaceRule named "foo" is defined\r
- and the pattern "s/x/${foo:5}/" is given to Regex.perlCode,\r
- then the "foo" the definition of "foo" will be retrieved\r
- and arg("5") will be called. If the result is non-null,\r
- that is the ReplaceRule that will be used. If the result\r
- is null, then the pattern works just as if it were\r
- "s/x/${foo}/".\r
- @see com.stevesoft.pat.Validator#arg(java.lang.String)\r
- */\r
- public ReplaceRule arg(String s) { return null; }\r
- static int getHexDigit(char c) {\r
- if(c >= '0' && c <= '9')\r
- return c - '0';\r
- if(c >= 'a' && c <= 'f')\r
- return c - 'a'+10;\r
- return c - 'A'+10;\r
+ if (c >= 'a' && c <= 'f')\r
+ {\r
+ return c - 'a' + 10;\r
}\r
+ return c - 'A' + 10;\r
+ }\r
}\r