示例#1
0
 /*
  * Analog of match_glob() in jsstr.c
  */
 private static void match_glob(
     GlobData mdata, Context cx, Scriptable scope, int count, RegExpImpl reImpl) {
   if (mdata.arrayobj == null) {
     Scriptable s = ScriptableObject.getTopLevelScope(scope);
     mdata.arrayobj = ScriptRuntime.newObject(cx, s, "Array", null);
   }
   SubString matchsub = reImpl.lastMatch;
   String matchstr = matchsub.toString();
   mdata.arrayobj.put(count, mdata.arrayobj, matchstr);
 }
示例#2
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);
    }
  }
示例#3
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;
  }