Beispiel #1
0
 public Object compileRegExp(Context cx, String source, String flags) {
   return NativeRegExp.compileRE(cx, source, flags, false);
 }
Beispiel #2
0
  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;
  }
Beispiel #3
0
  private static SubString interpretDollar(
      Context cx, RegExpImpl res, String da, int dp, int[] skip) {
    char dc;
    int num, tmp;

    if (da.charAt(dp) != '$') Kit.codeBug();

    /* Allow a real backslash (literal "\\") to escape "$1" etc. */
    int version = cx.getLanguageVersion();
    if (version != Context.VERSION_DEFAULT && version <= Context.VERSION_1_4) {
      if (dp > 0 && da.charAt(dp - 1) == '\\') return null;
    }
    int daL = da.length();
    if (dp + 1 >= daL) return null;
    /* Interpret all Perl match-induced dollar variables. */
    dc = da.charAt(dp + 1);
    if (NativeRegExp.isDigit(dc)) {
      int cp;
      if (version != Context.VERSION_DEFAULT && version <= Context.VERSION_1_4) {
        if (dc == '0') return null;
        /* Check for overflow to avoid gobbling arbitrary decimal digits. */
        num = 0;
        cp = dp;
        while (++cp < daL && NativeRegExp.isDigit(dc = da.charAt(cp))) {
          tmp = 10 * num + (dc - '0');
          if (tmp < num) break;
          num = tmp;
        }
      } else {
          /* ECMA 3, 1-9 or 01-99 */
        int parenCount = (res.parens == null) ? 0 : res.parens.length;
        num = dc - '0';
        if (num > parenCount) return null;
        cp = dp + 2;
        if ((dp + 2) < daL) {
          dc = da.charAt(dp + 2);
          if (NativeRegExp.isDigit(dc)) {
            tmp = 10 * num + (dc - '0');
            if (tmp <= parenCount) {
              cp++;
              num = tmp;
            }
          }
        }
        if (num == 0) return null; /* $0 or $00 is not valid */
      }
      /* Adjust num from 1 $n-origin to 0 array-index-origin. */
      num--;
      skip[0] = cp - dp;
      return res.getParenSubString(num);
    }

    skip[0] = 2;
    switch (dc) {
      case '$':
        return new SubString("$");
      case '&':
        return res.lastMatch;
      case '+':
        return res.lastParen;
      case '`':
        if (version == Context.VERSION_1_2) {
          /*
           * JS1.2 imitated the Perl4 bug where left context at each step
           * in an iterative use of a global regexp started from last match,
           * not from the start of the target string.  But Perl4 does start
           * $` at the beginning of the target string when it is used in a
           * substitution, so we emulate that special case here.
           */
          res.leftContext.index = 0;
          res.leftContext.length = res.lastMatch.index;
        }
        return res.leftContext;
      case '\'':
        return res.rightContext;
    }
    return null;
  }
Beispiel #4
0
  /** 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;
  }