X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2Fjs%2FJSRegexp.java;h=3bb5ab973c6688ae5c5ad54a7e2521be0dd40b6c;hb=6261c41b2ac9d182d8c3541e8e0e5fd00062fa43;hp=b0359ba4b5f073afd13db2aa295cbb14e6ee8ff7;hpb=67eeff476179a91ae930ea89cbecde22132ca532;p=org.ibex.core.git diff --git a/src/org/xwt/js/JSRegexp.java b/src/org/xwt/js/JSRegexp.java index b0359ba..3bb5ab9 100644 --- a/src/org/xwt/js/JSRegexp.java +++ b/src/org/xwt/js/JSRegexp.java @@ -1,20 +1,22 @@ +// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt.js; import gnu.regexp.*; -public class JSRegexp extends JSCallable { +/** A JavaScript regular expression object */ +public class JSRegexp extends JS { private boolean global; private RE re; private int lastIndex; - public JSRegexp(Object arg0, Object arg1) throws JS.Exn { + public JSRegexp(Object arg0, Object arg1) throws JSExn { if(arg0 instanceof JSRegexp) { JSRegexp r = (JSRegexp) arg0; this.global = r.global; this.re = r.re; this.lastIndex = r.lastIndex; } else { - String pattern = arg0.toString(); + String pattern = (String)arg0; String sFlags = null; int flags = 0; if(arg1 != null) sFlags = (String)arg1; @@ -24,110 +26,100 @@ public class JSRegexp extends JSCallable { case 'i': flags |= RE.REG_ICASE; break; case 'm': flags |= RE.REG_MULTILINE; break; case 'g': global = true; break; - default: throw new JS.Exn("Invalid flag in regexp \"" + sFlags.charAt(i) + "\""); + default: throw new JSExn("Invalid flag in regexp \"" + sFlags.charAt(i) + "\""); } } re = newRE(pattern,flags); - _put("source",pattern); - _put("global",wrapBool(global)); - _put("ignoreCase",wrapBool(flags & RE.REG_ICASE)); - _put("multiline",wrapBool(flags & RE.REG_MULTILINE)); + put("source", pattern); + put("global", B(global)); + put("ignoreCase", B(flags & RE.REG_ICASE)); + put("multiline", B(flags & RE.REG_MULTILINE)); } } - public Object call(Object method, JSArray args) throws JS.Exn { - if (method.equals("exec")) { - return exec(args); - } else if (method.equals("test")) { - return test(args); - } else if (method.equals("toString")) { - return toString(); + public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn { + switch(nargs) { + case 1: { + //#switch(method) + case "exec": { + String s = (String)a0; + int start = global ? lastIndex : 0; + if(start < 0 || start >= s.length()) { lastIndex = 0; return null; } + REMatch match = re.getMatch(s,start); + if(global) lastIndex = match == null ? s.length() : match.getEndIndex(); + return match == null ? null : matchToExecResult(match,re,s); + } + case "test": { + String s = (String)a0; + if (!global) return B(re.getMatch(s) != null); + int start = global ? lastIndex : 0; + if(start < 0 || start >= s.length()) { lastIndex = 0; return null; } + REMatch match = re.getMatch(s,start); + lastIndex = match != null ? s.length() : match.getEndIndex(); + return B(match != null); + } + case "toString": return toString(a0); + case "stringMatch": return stringMatch(a0,a1); + case "stringSearch": return stringSearch(a0,a1); + //#end + break; + } + case 2: { + //#switch(method) + case "stringReplace": return stringReplace(a0, a1,a2); + //#end + break; + } } - return null; + return super.callMethod(method, a0, a1, a2, rest, nargs); } - // gcj bug... - public Object get(Object key) { return _get(key); } - public void put(Object key,Object value) { _put(key,value); } - - public Object _get(Object key) { - if(key.equals("lastIndex")) return new Integer(lastIndex); + public Object get(Object key) throws JSExn { + //#switch(key) + case "exec": return METHOD; + case "test": return METHOD; + case "toString": return METHOD; + case "lastIndex": return N(lastIndex); + //#end return super.get(key); } - public void _put(Object key, Object value) { + public void put(Object key, Object value) throws JSExn { if(key.equals("lastIndex")) lastIndex = JS.toNumber(value).intValue(); super.put(key,value); } - - private Object exec(String s) throws JS.Exn { - int start = global ? lastIndex : 0; - if(start < 0 || start >= s.length()) { - lastIndex = 0; - return null; - } - - REMatch match = re.getMatch(s,start); - if(global) - lastIndex = match == null ? s.length() : match.getEndIndex(); - if(match == null) - return null; - else - return matchToExecResult(match,re,s); - } - + private static Object matchToExecResult(REMatch match, RE re, String s) { - JSObj ret = new JSObj(); - ret.put("index",new Integer(match.getStartIndex())); - ret.put("input",s); - int n = re.getNumSubs(); - ret.put("length",new Integer(n+1)); - ret.put("0",match.toString()); - for(int i=1;i<=n;i++) - ret.put(Integer.toString(i),match.toString(i)); - return ret; - } - - - private Object exec(JSArray args) throws JS.Exn { - if(args.length() < 1) throw new JS.Exn("Not enough args to exec"); - String s = args.elementAt(0).toString(); - return exec(s); - } - - private Object test(JSArray args) throws JS.Exn { - if(args.length() < 1) throw new JS.Exn("Not enough args to match"); - String s = args.elementAt(0).toString(); - - if(global) { - int start = global ? lastIndex : 0; - if(start < 0 || start >= s.length()) { - lastIndex = 0; - return null; - } - - REMatch match = re.getMatch(s,start); - lastIndex = match != null ? s.length() : match.getEndIndex(); - return wrapBool(match != null); - } else { - return wrapBool(re.getMatch(s) != null); + try { + JS ret = new JS(); + ret.put("index", N(match.getStartIndex())); + ret.put("input",s); + int n = re.getNumSubs(); + ret.put("length", N(n+1)); + ret.put("0",match.toString()); + for(int i=1;i<=n;i++) ret.put(Integer.toString(i),match.toString(i)); + return ret; + } catch (JSExn e) { + throw new Error("this should never happen"); } } public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append('/'); - sb.append(_get("source")); - sb.append('/'); - if(global) sb.append('g'); - if(Boolean.TRUE.equals(_get("ignoreCase"))) sb.append('i'); - if(Boolean.TRUE.equals(_get("multiline"))) sb.append('m'); - return sb.toString(); + try { + StringBuffer sb = new StringBuffer(); + sb.append('/'); + sb.append(get("source")); + sb.append('/'); + if(global) sb.append('g'); + if(Boolean.TRUE.equals(get("ignoreCase"))) sb.append('i'); + if(Boolean.TRUE.equals(get("multiline"))) sb.append('m'); + return sb.toString(); + } catch (JSExn e) { + throw new Error("this should never happen"); + } } - public static Object stringMatch(Object o, JSArray args) throws JS.Exn { - if(args.length() < 1) throw new JS.Exn("not enough args to match"); - Object arg0 = args.elementAt(0); + public static Object stringMatch(Object o, Object arg0) throws JSExn { String s = o.toString(); RE re; JSRegexp regexp = null; @@ -142,41 +134,26 @@ public class JSRegexp extends JSCallable { REMatch match = re.getMatch(s); return matchToExecResult(match,re,s); } - if(!regexp.global) - return regexp.exec(s); + if(!regexp.global) return regexp.callMethod("exec", s, null, null, null, 1); JSArray ret = new JSArray(); REMatch[] matches = re.getAllMatches(s); - for(int i=0;i 0) - regexp.lastIndex = matches[matches.length-1].getEndIndex(); - else - regexp.lastIndex = s.length(); + for(int i=0;i 0 ? matches[matches.length-1].getEndIndex() : s.length(); return ret; } - public static Object stringSearch(Object o, JSArray args) throws JS.Exn { - if(args.length() < 1) throw new JS.Exn("not enough args to match"); - Object arg0 = args.elementAt(0); + public static Object stringSearch(Object o, Object arg0) throws JSExn { String s = o.toString(); - RE re; - if(arg0 instanceof JSRegexp) - re = ((JSRegexp)arg0).re; - else - re = newRE(arg0.toString(),0); + RE re = arg0 instanceof JSRegexp ? ((JSRegexp)arg0).re : newRE(arg0.toString(),0); REMatch match = re.getMatch(s); - if(match == null) return new Integer(-1); - return new Integer(match.getStartIndex()); + return match == null ? N(-1) : N(match.getStartIndex()); } - public static Object stringReplace(Object o, JSArray args) throws JS.Exn { - if(args.length() < 2) throw new JS.Exn("not enough args to replace"); - Object arg0 = args.elementAt(0); - Object arg1 = args.elementAt(1); + public static Object stringReplace(Object o, Object arg0, Object arg1) throws JSExn { String s = o.toString(); RE re; - JSCallable replaceFunc = null; + JS replaceFunc = null; String replaceString = null; JSRegexp regexp = null; if(arg0 instanceof JSRegexp) { @@ -185,8 +162,8 @@ public class JSRegexp extends JSCallable { } else { re = newRE(arg0.toString(),0); } - if(arg1 instanceof JSCallable) - replaceFunc = (JSCallable) arg1; + if(arg1 instanceof JS) + replaceFunc = (JS) arg1; else replaceString = arg1.toString(); REMatch[] matches; @@ -214,21 +191,35 @@ public class JSRegexp extends JSCallable { sb.append(sa,pos,match.getStartIndex()-pos); pos = match.getEndIndex(); if(replaceFunc != null) { - // FEATURE: reintroduce - throw new JS.Exn("stringReplace() with a replacement function is temporarily disabled"); - /* - JSArray a = new JSArray(); - a.addElement(match.toString()); - if(regexp != null) { - int n = re.getNumSubs(); - for(int j=1;j<=n;j++) - a.addElement(match.toString(j)); + int n = (regexp == null ? 0 : re.getNumSubs()); + int numArgs = 3 + n; + Object[] rest = new Object[numArgs - 3]; + Object a0 = match.toString(); + Object a1 = null; + Object a2 = null; + for(int j=1;j<=n;j++) + switch(j) { + case 1: a1 = match.toString(j); break; + case 2: a2 = match.toString(j); break; + default: rest[j - 3] = match.toString(j); break; + } + switch(numArgs) { + case 3: + a1 = N(match.getStartIndex()); + a2 = s; + break; + case 4: + a2 = N(match.getStartIndex()); + rest[0] = s; + break; + default: + rest[rest.length - 2] = N(match.getStartIndex()); + rest[rest.length - 1] = s; } - a.addElement(new Integer(match.getStartIndex())); - a.addElement(s); - Object ret = replaceFunc.call(a, null); - sb.append(ret.toString()); - */ + + // note: can't perform pausing operations in here + sb.append((String)replaceFunc.call(a0, a1, a2, rest, numArgs)); + } else { sb.append(mySubstitute(match,replaceString,s)); } @@ -280,16 +271,8 @@ public class JSRegexp extends JSCallable { } - public static Object stringSplit(Object o,JSArray args) { - String s = o.toString(); - if(args.length() < 1 || args.elementAt(0) == null || s.length() == 0) { - JSArray ret = new JSArray(); - ret.addElement(s); - return ret; - } - Object arg0 = args.elementAt(0); - - int limit = args.length() < 2 ? Integer.MAX_VALUE : JS.toInt(args.elementAt(1)); + public static Object stringSplit(String s, Object arg0, Object arg1, int nargs) { + int limit = nargs < 2 ? Integer.MAX_VALUE : JS.toInt(arg1); if(limit < 0) limit = Integer.MAX_VALUE; if(limit == 0) return new JSArray(); @@ -341,21 +324,13 @@ public class JSRegexp extends JSCallable { return ret; } - public static RE newRE(String pattern, int flags) throws JS.Exn { + public static RE newRE(String pattern, int flags) throws JSExn { try { return new RE(pattern,flags,RESyntax.RE_SYNTAX_PERL5); } catch(REException e) { - throw new JS.Exn(e.toString()); + throw new JSExn(e.toString()); } } - private static Boolean wrapBool(boolean b) { - return b ? Boolean.TRUE : Boolean.FALSE; - } - - private static Boolean wrapBool(int n) { - return wrapBool(n != 0); - } - public String typeName() { return "regexp"; } }