public int find_split( Context cx, Scriptable scope, String target, String separator, Scriptable reObj, int[] ip, int[] matchlen, boolean[] matched, String[][] parensp) { int i = ip[0]; int length = target.length(); int result; int version = cx.getLanguageVersion(); NativeRegExp re = (NativeRegExp) reObj; again: while (true) { // imitating C label /* JS1.2 deviated from Perl by never matching at end of string. */ int ipsave = ip[0]; // reuse ip to save object creation ip[0] = i; Object ret = re.executeRegExp(cx, scope, this, target, ip, NativeRegExp.TEST); if (ret != Boolean.TRUE) { // Mismatch: ensure our caller advances i past end of string. ip[0] = ipsave; matchlen[0] = 1; matched[0] = false; return length; } i = ip[0]; ip[0] = ipsave; matched[0] = true; SubString sep = this.lastMatch; matchlen[0] = sep.length; if (matchlen[0] == 0) { /* * Empty string match: never split on an empty * match at the start of a find_split cycle. Same * rule as for an empty global match in * match_or_replace. */ if (i == ip[0]) { /* * "Bump-along" to avoid sticking at an empty * match, but don't bump past end of string -- * our caller must do that by adding * sep->length to our return value. */ if (i == length) { if (version == Context.VERSION_1_2) { matchlen[0] = 1; result = i; } else result = -1; break; } i++; continue again; // imitating C goto } } // PR_ASSERT((size_t)i >= sep->length); result = i - matchlen[0]; break; } int size = (parens == null) ? 0 : parens.length; parensp[0] = new String[size]; for (int num = 0; num < size; num++) { SubString parsub = getParenSubString(num); parensp[0][num] = parsub.toString(); } return result; }
/** Analog of C match_or_replace. */ private static Object matchOrReplace( Context cx, Scriptable scope, Scriptable thisObj, Object[] args, RegExpImpl reImpl, GlobData data, boolean forceFlat) { NativeRegExp re; String str = ScriptRuntime.toString(thisObj); data.str = str; Scriptable topScope = ScriptableObject.getTopLevelScope(scope); if (args.length == 0) { Object compiled = NativeRegExp.compileRE(cx, "", "", false); re = new NativeRegExp(topScope, compiled); } else if (args[0] instanceof NativeRegExp) { re = (NativeRegExp) args[0]; } else { String src = ScriptRuntime.toString(args[0]); String opt; if (data.optarg < args.length) { args[0] = src; opt = ScriptRuntime.toString(args[data.optarg]); } else { opt = null; } Object compiled = NativeRegExp.compileRE(cx, src, opt, forceFlat); re = new NativeRegExp(topScope, compiled); } data.regexp = re; data.global = (re.getFlags() & NativeRegExp.JSREG_GLOB) != 0; int[] indexp = {0}; Object result = null; if (data.mode == RA_SEARCH) { result = re.executeRegExp(cx, scope, reImpl, str, indexp, NativeRegExp.TEST); if (result != null && result.equals(Boolean.TRUE)) result = new Integer(reImpl.leftContext.length); else result = new Integer(-1); } else if (data.global) { re.lastIndex = 0; for (int count = 0; indexp[0] <= str.length(); count++) { result = re.executeRegExp(cx, scope, reImpl, str, indexp, NativeRegExp.TEST); if (result == null || !result.equals(Boolean.TRUE)) break; if (data.mode == RA_MATCH) { match_glob(data, cx, scope, count, reImpl); } else { if (data.mode != RA_REPLACE) Kit.codeBug(); SubString lastMatch = reImpl.lastMatch; int leftIndex = data.leftIndex; int leftlen = lastMatch.index - leftIndex; data.leftIndex = lastMatch.index + lastMatch.length; replace_glob(data, cx, scope, reImpl, leftIndex, leftlen); } if (reImpl.lastMatch.length == 0) { if (indexp[0] == str.length()) break; indexp[0]++; } } } else { result = re.executeRegExp( cx, scope, reImpl, str, indexp, ((data.mode == RA_REPLACE) ? NativeRegExp.TEST : NativeRegExp.MATCH)); } return result; }