Example #1
0
  /*
   * Analog of replace_glob() in jsstr.c
   */
  private static void replace_glob(
      GlobData rdata, Context cx, Scriptable scope, RegExpImpl reImpl, int leftIndex, int leftlen) {
    int replen;
    String lambdaStr;
    if (rdata.lambda != null) {
      // invoke lambda function with args lastMatch, $1, $2, ... $n,
      // leftContext.length, whole string.
      SubString[] parens = reImpl.parens;
      int parenCount = (parens == null) ? 0 : parens.length;
      Object[] args = new Object[parenCount + 3];
      args[0] = reImpl.lastMatch.toString();
      for (int i = 0; i < parenCount; i++) {
        SubString sub = parens[i];
        if (sub != null) {
          args[i + 1] = sub.toString();
        } else {
          args[i + 1] = Undefined.instance;
        }
      }
      args[parenCount + 1] = new Integer(reImpl.leftContext.length);
      args[parenCount + 2] = rdata.str;
      // This is a hack to prevent expose of reImpl data to
      // JS function which can run new regexps modifing
      // regexp that are used later by the engine.
      // TODO: redesign is necessary
      if (reImpl != ScriptRuntime.getRegExpProxy(cx)) Kit.codeBug();
      RegExpImpl re2 = new RegExpImpl();
      re2.multiline = reImpl.multiline;
      re2.input = reImpl.input;
      ScriptRuntime.setRegExpProxy(cx, re2);
      try {
        Scriptable parent = ScriptableObject.getTopLevelScope(scope);
        Object result = rdata.lambda.call(cx, parent, parent, args);
        lambdaStr = ScriptRuntime.toString(result);
      } finally {
        ScriptRuntime.setRegExpProxy(cx, reImpl);
      }
      replen = lambdaStr.length();
    } else {
      lambdaStr = null;
      replen = rdata.repstr.length();
      if (rdata.dollar >= 0) {
        int[] skip = new int[1];
        int dp = rdata.dollar;
        do {
          SubString sub = interpretDollar(cx, reImpl, rdata.repstr, dp, skip);
          if (sub != null) {
            replen += sub.length - skip[0];
            dp += skip[0];
          } else {
            ++dp;
          }
          dp = rdata.repstr.indexOf('$', dp);
        } while (dp >= 0);
      }
    }

    int growth = leftlen + replen + reImpl.rightContext.length;
    StringBuffer charBuf = rdata.charBuf;
    if (charBuf == null) {
      charBuf = new StringBuffer(growth);
      rdata.charBuf = charBuf;
    } else {
      charBuf.ensureCapacity(rdata.charBuf.length() + growth);
    }

    charBuf.append(reImpl.leftContext.charArray, leftIndex, leftlen);
    if (rdata.lambda != null) {
      charBuf.append(lambdaStr);
    } else {
      do_replace(rdata, cx, reImpl);
    }
  }