Commit message: Merge Onigmo 6.0.0

* https://github.com/k-takata/Onigmo/blob/Onigmo-6.0.0/HISTORY
* fix for ruby 2.4: https://github.com/k-takata/Onigmo/pull/78
* suppress warning: https://github.com/k-takata/Onigmo/pull/79
* include/ruby/oniguruma.h: include onigmo.h.
* template/encdb.h.tmpl: ignore duplicated definition of EUC-CN in
  enc/euc_kr.c. It is defined in enc/gb2313.c with CRuby macro.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57045 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
CVE: CVE-2019-19204
Vulnerability description: An issue was discovered in Oniguruma 6.x before 6.9.4_rc2. In the function fetch_interval_quantifier (formerly known as fetch_range_quantifier) in regparse.c, PFETCH is called without checking PEND. This leads to a heap-based buffer over-read.

Project: ruby
File: regexec.c

bm_search_notrev_ic(regex_t* reg, const UChar* target, const UChar* target_end,
		    const UChar* text, const UChar* text_end,
		    const UChar* text_range)
{
  const UChar *s, *se, *t, *end;
  const UChar *tail;
  ptrdiff_t skip, tlen1;
  OnigEncoding enc = reg->enc;
  int case_fold_flag = reg->case_fold_flag;

# ifdef ONIG_DEBUG_SEARCH
  fprintf(stderr, "bm_search_notrev_ic: text: %d (%p), text_end: %d (%p), text_range: %d (%p)\n",
	  (int )text, text, (int )text_end, text_end, (int )text_range, text_range);
# endif

  tail = target_end - 1;
  tlen1 = tail - target;
  end = text_range;
  if (end + tlen1 > text_end)
    end = text_end - tlen1;

  s = text;

  if (IS_NULL(reg->int_map)) {
    while (s < end) {
      se = s + tlen1;
      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
			       s, se + 1))
	return (UChar* )s;
      skip = reg->map[*se];
      t = s;
      do {
	s += enclen(reg->enc, s, end);
      } while ((s - t) < skip && s < end);
    }
  }
  else {
# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
    while (s < end) {
      se = s + tlen1;
      if (str_lower_case_match(enc, case_fold_flag, target, target_end,
			       s, se + 1))
	return (UChar* )s;
      skip = reg->int_map[*se];
      t = s;
      do {
	s += enclen(reg->enc, s, end);
      } while ((s - t) < skip && s < end);
    }
# endif
  }

  return (UChar* )NULL;
}

Project: ruby
File: regenc.c

onigenc_ascii_mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED, const UChar** p,
			    const UChar* end, UChar* lower, OnigEncoding enc ARG_UNUSED)
{
  *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(**p);

  (*p)++;
  return 1; /* return byte length of converted char to lower */
}

Project: ruby
File: re.c

match_regexp(VALUE match)
{
    VALUE regexp;
    match_check(match);
    regexp = RMATCH(match)->regexp;
    if (NIL_P(regexp)) {
	VALUE str = rb_reg_nth_match(0, match);
	regexp = rb_reg_regcomp(rb_reg_quote(str));
	RMATCH(match)->regexp = regexp;
    }
    return regexp;
}

Project: ruby
File: re.c

rb_reg_named_captures(VALUE re)
{
    VALUE hash = rb_hash_new();
    rb_reg_check(re);
    onig_foreach_name(RREGEXP_PTR(re), reg_named_captures_iter, (void*)hash);
    return hash;
}

Project: ruby
File: re.c

rb_enc_reg_new(const char *s, long len, rb_encoding *enc, int options)
{
    VALUE re = rb_reg_alloc();
    onig_errmsg_buffer err = "";

    if (rb_reg_initialize(re, s, len, enc, options, err, NULL, 0) != 0) {
	rb_enc_reg_raise(s, len, enc, options, err);
    }
    RB_OBJ_WRITE(re, &RREGEXP(re)->src, rb_fstring(rb_enc_str_new(s, len, enc)));

    return re;
}

Project: ruby
File: regcomp.c

get_min_match_length(Node* node, OnigDistance *min, ScanEnv* env)
{
  OnigDistance tmin;
  int r = 0;

  *min = 0;
  switch (NTYPE(node)) {
  case NT_BREF:
    {
      int i;
      int* backs;
      Node** nodes = SCANENV_MEM_NODES(env);
      BRefNode* br = NBREF(node);
      if (br->state & NST_RECURSION) break;

      backs = BACKREFS_P(br);
      if (backs[0] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
      r = get_min_match_length(nodes[backs[0]], min, env);
      if (r != 0) break;
      for (i = 1; i < br->back_num; i++) {
	if (backs[i] > env->num_mem)  return ONIGERR_INVALID_BACKREF;
	r = get_min_match_length(nodes[backs[i]], &tmin, env);
	if (r != 0) break;
	if (*min > tmin) *min = tmin;
      }
    }
    break;

#ifdef USE_SUBEXP_CALL
  case NT_CALL:
    if (IS_CALL_RECURSION(NCALL(node))) {
      EncloseNode* en = NENCLOSE(NCALL(node)->target);
      if (IS_ENCLOSE_MIN_FIXED(en))
	*min = en->min_len;
    }
    else
      r = get_min_match_length(NCALL(node)->target, min, env);
    break;
#endif

  case NT_LIST:
    do {
      r = get_min_match_length(NCAR(node), &tmin, env);
      if (r == 0) *min += tmin;
    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
    break;

  case NT_ALT:
    {
      Node *x, *y;
      y = node;
      do {
	x = NCAR(y);
	r = get_min_match_length(x, &tmin, env);
	if (r != 0) break;
	if (y == node) *min = tmin;
	else if (*min > tmin) *min = tmin;
      } while (r == 0 && IS_NOT_NULL(y = NCDR(y)));
    }
    break;

  case NT_STR:
    {
      StrNode* sn = NSTR(node);
      *min = sn->end - sn->s;
    }
    break;

  case NT_CTYPE:
    *min = 1;
    break;

  case NT_CCLASS:
  case NT_CANY:
    *min = 1;
    break;

  case NT_QTFR:
    {
      QtfrNode* qn = NQTFR(node);

      if (qn->lower > 0) {
	r = get_min_match_length(qn->target, min, env);
	if (r == 0)
	  *min = distance_multiply(*min, qn->lower);
      }
    }
    break;

  case NT_ENCLOSE:
    {
      EncloseNode* en = NENCLOSE(node);
      switch (en->type) {
      case ENCLOSE_MEMORY:
        if (IS_ENCLOSE_MIN_FIXED(en))
          *min = en->min_len;
        else {
	  if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
	    *min = 0;  // recursive
	  else {
	    SET_ENCLOSE_STATUS(node, NST_MARK1);
	    r = get_min_match_length(en->target, min, env);
	    CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
	    if (r == 0) {
	      en->min_len = *min;
	      SET_ENCLOSE_STATUS(node, NST_MIN_FIXED);
	    }
	  }
        }
        break;

      case ENCLOSE_OPTION:
      case ENCLOSE_STOP_BACKTRACK:
      case ENCLOSE_CONDITION:
	r = get_min_match_length(en->target, min, env);
	break;
      }
    }
    break;

  case NT_ANCHOR:
  default:
    break;
  }

  return r;
}

Project: ruby
File: regexec.c

bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
		 const UChar* text, const UChar* text_end,
		 const UChar* text_range)
{
  const UChar *s, *se, *t, *p, *end;
  const UChar *tail;
  ptrdiff_t skip, tlen1;
  OnigEncoding enc = reg->enc;

# ifdef ONIG_DEBUG_SEARCH
  fprintf(stderr, "bm_search_notrev: text: %"PRIdPTR" (%p), text_end: %"PRIdPTR" (%p), text_range: %"PRIdPTR" (%p)\n",
	  (intptr_t )text, text, (intptr_t )text_end, text_end, (intptr_t )text_range, text_range);
# endif

  tail = target_end - 1;
  tlen1 = tail - target;
  end = text_range;
  if (end + tlen1 > text_end)
    end = text_end - tlen1;

  s = text;

  if (IS_NULL(reg->int_map)) {
    while (s < end) {
      p = se = s + tlen1;
      t = tail;
      while (*p == *t) {
	if (t == target) return (UChar* )s;
	p--; t--;
      }
      if (s + 1 >= end) break;
      skip = reg->map[se[1]];
      t = s;
      do {
	s += enclen(enc, s, end);
      } while ((s - t) < skip && s < end);
    }
  }
  else {
# if OPT_EXACT_MAXLEN >= ONIG_CHAR_TABLE_SIZE
    while (s < end) {
      p = se = s + tlen1;
      t = tail;
      while (*p == *t) {
	if (t == target) return (UChar* )s;
	p--; t--;
      }
      if (s + 1 >= end) break;
      skip = reg->int_map[se[1]];
      t = s;
      do {
	s += enclen(enc, s, end);
      } while ((s - t) < skip && s < end);
    }
# endif
  }

  return (UChar* )NULL;
}

Project: ruby
File: regparse.c

conv_backslash_value(OnigCodePoint c, ScanEnv* env)
{
  if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_CONTROL_CHARS)) {
    switch (c) {
    case 'n': return '\n';
    case 't': return '\t';
    case 'r': return '\r';
    case 'f': return '\f';
    case 'a': return '\007';
    case 'b': return '\010';
    case 'e': return '\033';
    case 'v':
      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_V_VTAB))
	return '\v';
      break;

    default:
      if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
	  UNKNOWN_ESC_WARN(env, c);
      break;
    }
  }
  return c;
}

Project: ruby
File: re.c

rb_reg_nth_defined(int nth, VALUE match)
{
    struct re_registers *regs;
    if (NIL_P(match)) return Qnil;
    match_check(match);
    regs = RMATCH_REGS(match);
    if (nth >= regs->num_regs) {
	return Qnil;
    }
    if (nth < 0) {
	nth += regs->num_regs;
	if (nth <= 0) return Qnil;
    }
    if (BEG(nth) == -1) return Qfalse;
    return Qtrue;
}

Project: ruby
File: re.c

re_warn(const char *s)
{
    rb_warn("%s", s);
}

Project: ruby
File: regcomp.c

set_mml(MinMaxLen* mml, OnigDistance min, OnigDistance max)
{
  mml->min = min;
  mml->max = max;
}

Project: ruby
File: windows_1250.c

cp1250_mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED,
             const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower, OnigEncoding enc ARG_UNUSED)
{
  const UChar* p = *pp;

  *lower = ENC_CP1250_TO_LOWER_CASE(*p);
  (*pp)++;
  return 1;
}

Project: ruby
File: re.c

rb_reg_fixed_encoding_p(VALUE re)
{
    if (FL_TEST(re, KCODE_FIXED))
        return Qtrue;
    else
        return Qfalse;
}

Project: ruby
File: re.c

rb_memcmp(const void *p1, const void *p2, long len)
{
    return memcmp(p1, p2, len);
}

Project: ruby
File: regcomp.c

numbered_ref_check(Node* node)
{
  int r = 0;

  switch (NTYPE(node)) {
  case NT_LIST:
  case NT_ALT:
    do {
      r = numbered_ref_check(NCAR(node));
    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
    break;
  case NT_QTFR:
    r = numbered_ref_check(NQTFR(node)->target);
    break;
  case NT_ENCLOSE:
    r = numbered_ref_check(NENCLOSE(node)->target);
    break;

  case NT_BREF:
    if (! IS_BACKREF_NAME_REF(NBREF(node)))
      return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
    break;

  case NT_ANCHOR:
    if (NANCHOR(node)->target)
      r = numbered_ref_check(NANCHOR(node)->target);
    break;

  default:
    break;
  }

  return r;
}

Project: ruby
File: iso_8859_13.c

mbc_case_fold(OnigCaseFoldType flag,
			  const UChar** pp, const UChar* end ARG_UNUSED,
			  UChar* lower, OnigEncoding enc ARG_UNUSED)
{
  const UChar* p = *pp;

  if (*p == SHARP_s && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
    *lower++ = 's';
    *lower   = 's';
    (*pp)++;
    return 2;
  }

  *lower = ENC_ISO_8859_13_TO_LOWER_CASE(*p);
  (*pp)++;
  return 1;
}

Project: ruby
File: re.c

rb_reg_options(VALUE re)
{
    int options;

    rb_reg_check(re);
    options = RREGEXP_PTR(re)->options & ARG_REG_OPTION_MASK;
    if (RBASIC(re)->flags & KCODE_FIXED) options |= ARG_ENCODING_FIXED;
    if (RBASIC(re)->flags & REG_ENCODING_NONE) options |= ARG_ENCODING_NONE;
    return options;
}

Project: ruby
File: regcomp.c

copy_opt_exact_info(OptExactInfo* to, OptExactInfo* from)
{
  *to = *from;
}

Project: ruby
File: unicode.c

onigenc_unicode_property_name_to_ctype(OnigEncoding enc, const UChar* name, const UChar* end)
{
  int len;
  int ctype;
  UChar buf[PROPERTY_NAME_MAX_SIZE];
  const UChar *p;
  OnigCodePoint code;

  len = 0;
  for (p = name; p < end; p += enclen(enc, p, end)) {
    code = ONIGENC_MBC_TO_CODE(enc, p, end);
    if (code == ' ' || code == '-' || code == '_')
      continue;
    if (code >= 0x80)
      return ONIGERR_INVALID_CHAR_PROPERTY_NAME;

    buf[len++] = ONIGENC_ASCII_CODE_TO_LOWER_CASE(code);
    if (len >= PROPERTY_NAME_MAX_SIZE)
      return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
  }

  buf[len] = 0;

  if ((ctype = uniname2ctype(buf, len)) < 0) {
    return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
  }

  return ctype;
}

Project: ruby
File: re.c

unescape_escaped_nonascii(const char **pp, const char *end, rb_encoding *enc,
        VALUE buf, rb_encoding **encp, onig_errmsg_buffer err)
{
    const char *p = *pp;
    int chmaxlen = rb_enc_mbmaxlen(enc);
    char *chbuf = ALLOCA_N(char, chmaxlen);
    int chlen = 0;
    int byte;
    int l;

    memset(chbuf, 0, chmaxlen);

    byte = read_escaped_byte(&p, end, err);
    if (byte == -1) {
        return -1;
    }

    chbuf[chlen++] = byte;
    while (chlen < chmaxlen &&
           MBCLEN_NEEDMORE_P(rb_enc_precise_mbclen(chbuf, chbuf+chlen, enc))) {
        byte = read_escaped_byte(&p, end, err);
        if (byte == -1) {
            return -1;
        }
        chbuf[chlen++] = byte;
    }

    l = rb_enc_precise_mbclen(chbuf, chbuf+chlen, enc);
    if (MBCLEN_INVALID_P(l)) {
        errcpy(err, "invalid multibyte escape");
        return -1;
    }
    if (1 < chlen || (chbuf[0] & 0x80)) {
        rb_str_buf_cat(buf, chbuf, chlen);

        if (*encp == 0)
            *encp = enc;
        else if (*encp != enc) {
            errcpy(err, "escaped non ASCII character in UTF-8 regexp");
            return -1;
        }
    }
    else {
        char escbuf[5];
        snprintf(escbuf, sizeof(escbuf), "\\x%02X", chbuf[0]&0xff);
        rb_str_buf_cat(buf, escbuf, 4);
    }
    *pp = p;
    return 0;
}

Project: ruby
File: regcomp.c

setup_subexp_call(Node* node, ScanEnv* env)
{
  int type;
  int r = 0;

  type = NTYPE(node);
  switch (type) {
  case NT_LIST:
    do {
      r = setup_subexp_call(NCAR(node), env);
    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
    break;

  case NT_ALT:
    do {
      r = setup_subexp_call(NCAR(node), env);
    } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
    break;

  case NT_QTFR:
    r = setup_subexp_call(NQTFR(node)->target, env);
    break;
  case NT_ENCLOSE:
    r = setup_subexp_call(NENCLOSE(node)->target, env);
    break;

  case NT_CALL:
    {
      CallNode* cn = NCALL(node);
      Node** nodes = SCANENV_MEM_NODES(env);

      if (cn->group_num != 0) {
	int gnum = cn->group_num;

# ifdef USE_NAMED_GROUP
	if (env->num_named > 0 &&
	    IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
	    !ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_CAPTURE_GROUP)) {
	  return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
	}
# endif
	if (gnum > env->num_mem) {
	  onig_scan_env_set_error_string(env,
		 ONIGERR_UNDEFINED_GROUP_REFERENCE, cn->name, cn->name_end);
	  return ONIGERR_UNDEFINED_GROUP_REFERENCE;
	}

# ifdef USE_NAMED_GROUP
      set_call_attr:
# endif
	cn->target = nodes[cn->group_num];
	if (IS_NULL(cn->target)) {
	  onig_scan_env_set_error_string(env,
		 ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
	  return ONIGERR_UNDEFINED_NAME_REFERENCE;
	}
	SET_ENCLOSE_STATUS(cn->target, NST_CALLED);
	BIT_STATUS_ON_AT(env->bt_mem_start, cn->group_num);
	cn->unset_addr_list = env->unset_addr_list;
      }
# ifdef USE_NAMED_GROUP
#  ifdef USE_PERL_SUBEXP_CALL
      else if (cn->name == cn->name_end) {
	goto set_call_attr;
      }
#  endif
      else {
	int *refs;

	int n = onig_name_to_group_numbers(env->reg, cn->name, cn->name_end,
					   &refs);
	if (n <= 0) {
	  onig_scan_env_set_error_string(env,
		 ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
	  return ONIGERR_UNDEFINED_NAME_REFERENCE;
	}
	else if (n > 1 &&
	    ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME_CALL)) {
	  onig_scan_env_set_error_string(env,
	    ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL, cn->name, cn->name_end);
	  return ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL;
	}
	else {
	  cn->group_num = refs[0];
	  goto set_call_attr;
	}
      }
# endif
    }
    break;

  case NT_ANCHOR:
    {
      AnchorNode* an = NANCHOR(node);

      switch (an->type) {
      case ANCHOR_PREC_READ:
      case ANCHOR_PREC_READ_NOT:
      case ANCHOR_LOOK_BEHIND:
      case ANCHOR_LOOK_BEHIND_NOT:
	r = setup_subexp_call(an->target, env);
	break;
      }
    }
    break;

  default:
    break;
  }

  return r;
}

Project: ruby
File: regparse.c

node_extended_grapheme_cluster(Node** np, ScanEnv* env)
{
  Node* tmp = NULL;
  Node* np1 = NULL;
  Node* list = NULL;
  Node* list2 = NULL;
  Node* alt = NULL;
  Node* alt2 = NULL;
  BBuf *pbuf1 = NULL;
  int r = 0;
  int num1;
  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN * 2];
  OnigOptionType option;

#ifdef USE_UNICODE_PROPERTIES
  if (ONIGENC_IS_UNICODE(env->enc)) {
    /* UTF-8, UTF-16BE/LE, UTF-32BE/LE */
    CClassNode* cc;
    OnigCodePoint sb_out = (ONIGENC_MBC_MINLEN(env->enc) > 1) ? 0x00 : 0x80;
    int extend = propname2ctype(env, "Grapheme_Cluster_Break=Extend");

    /* Prepend*
     * ( RI-sequence | Hangul-Syllable | !Control )
     * ( Grapheme_Extend | SpacingMark )* */

    /* ( Grapheme_Extend | SpacingMark )* */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, extend, 0, 0, env);
    if (r != 0) goto err;
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=SpacingMark"), 0, 0, env);
    if (r != 0) goto err;
    r = add_code_range(&(cc->mbuf), env, 0x200D, 0x200D);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list = tmp;
    np1 = NULL;

    /* ( RI-sequence | Hangul-Syllable | !Control ) */
    /* !Control */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Control"), 1, 0, env);
    if (r != 0) goto err;
    if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
      BBuf *pbuf2 = NULL;
      r = add_code_range(&pbuf1, env, 0x0a, 0x0a);
      if (r != 0) goto err;
      r = add_code_range(&pbuf1, env, 0x0d, 0x0d);
      if (r != 0) goto err;
      r = and_code_range_buf(cc->mbuf, 0, pbuf1, 1, &pbuf2, env);
      if (r != 0) {
	bbuf_free(pbuf2);
	goto err;
      }
      bbuf_free(pbuf1);
      pbuf1 = NULL;
      bbuf_free(cc->mbuf);
      cc->mbuf = pbuf2;
    }
    else {
      BITSET_CLEAR_BIT(cc->bs, 0x0a);
      BITSET_CLEAR_BIT(cc->bs, 0x0d);
    }

    tmp = onig_node_new_alt(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    np1 = NULL;

    /* Hangul-Syllable
     *  := L* V+ T*
     *  | L* LV V* T*
     *  | L* LVT T*
     *  | L+
     *  | T+ */

    /* T+ */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = onig_node_new_alt(np1, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    np1 = NULL;

    /* L+ */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = onig_node_new_alt(np1, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    np1 = NULL;

    /* L* LVT T* */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=LVT"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    list2 = NULL;

    /* L* LV V* T* */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=V"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=LV"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    list2 = NULL;

    /* L* V+ T* */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=T"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=V"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=L"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    list2 = NULL;

    /* Emoji sequence := (E_Base | EBG) Extend* E_Modifier?
     *                   (ZWJ (Glue_After_Zwj | EBG Extend* E_Modifier?) )* */

    /* ZWJ (Glue_After_Zwj | E_Base_GAZ Extend* E_Modifier?) */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, 1, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, extend, 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    alt2 = tmp;
    list2 = NULL;

    /* Glue_After_Zwj */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, extend, 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    {
      static const OnigCodePoint ranges[] = {
	13,
	0x1F308, 0x1F308,
	0x1F33E, 0x1F33E,
	0x1F373, 0x1F373,
	0x1F393, 0x1F393,
	0x1F3A4, 0x1F3A4,
	0x1F3A8, 0x1F3A8,
	0x1F3EB, 0x1F3EB,
	0x1F3ED, 0x1F3ED,
	0x1F4BB, 0x1F4BC,
	0x1F527, 0x1F527,
	0x1F52C, 0x1F52C,
	0x1F680, 0x1F680,
	0x1F692, 0x1F692,
      };
      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
      if (r != 0) goto err;
    }
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Glue_After_Zwj"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt2);
    if (IS_NULL(tmp)) goto err;
    alt2 = tmp;
    list2 = NULL;

    /* Emoji variation sequence
     * http://unicode.org/Public/emoji/4.0/emoji-zwj-sequences.txt
     */
    r = ONIGENC_CODE_TO_MBC(env->enc, 0xfe0f, buf);
    if (r < 0) goto err;
    np1 = node_new_str_raw(buf, buf + r);
    if (IS_NULL(np1)) goto err;

    tmp = node_new_quantifier(0, 1, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    {
      static const OnigCodePoint ranges[] = {
	4,
	0x2640, 0x2640,
	0x2642, 0x2642,
	0x2695, 0x2696,
	0x2708, 0x2708,
      };
      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
      if (r != 0) goto err;
    }

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt2);
    if (IS_NULL(tmp)) goto err;
    alt2 = tmp;
    list2 = NULL;

    tmp = node_new_list(alt2, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    alt2 = NULL;

    /* ZWJ */
    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
    if (r < 0) goto err;
    np1 = node_new_str_raw(buf, buf + r);
    if (IS_NULL(np1)) goto err;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = list2;
    np1 = tmp;
    list2 = NULL;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    /* E_Modifier? */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, 1, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    /* Extend* */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, extend, 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    /* (E_Base | EBG) */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    {
      static const OnigCodePoint ranges[] = {
	8,
	0x1F3C2, 0x1F3C2,
	0x1F3C7, 0x1F3C7,
	0x1F3CC, 0x1F3CC,
	0x1F3F3, 0x1F3F3,
	0x1F441, 0x1F441,
	0x1F46F, 0x1F46F,
	0x1F574, 0x1F574,
	0x1F6CC, 0x1F6CC,
      };
      r = add_ctype_to_cc_by_range(cc, -1, 0, env, sb_out, ranges);
      if (r != 0) goto err;
    }
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base"), 0, 0, env);
    if (r != 0) goto err;
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    list2 = NULL;

    /* ZWJ (E_Base_GAZ | Glue_After_Zwj) E_Modifier? */
    /* a sequence starting with ZWJ seems artificial, but GraphemeBreakTest
     * has such examples.
     * http://www.unicode.org/Public/9.0.0/ucd/auxiliary/GraphemeBreakTest.html
     */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Modifier"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, 1, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Glue_After_Zwj"), 0, 0, env);
    if (r != 0) goto err;
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=E_Base_GAZ"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
    if (r < 0) goto err;
    np1 = node_new_str_raw(buf, buf + r);
    if (IS_NULL(np1)) goto err;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    list2 = NULL;

    /* RI-Sequence := Regional_Indicator{2} */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_code_range(&(cc->mbuf), env, 0x1F1E6, 0x1F1FF);
    if (r != 0) goto err;

    tmp = node_new_quantifier(2, 2, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    list2 = NULL;

    tmp = node_new_list(alt, list);
    if (IS_NULL(tmp)) goto err;
    list = tmp;
    alt = NULL;

    /* Prepend* */
    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Prepend"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(0, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list);
    if (IS_NULL(tmp)) goto err;
    list = tmp;
    np1 = NULL;

    /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
    np1 = node_new_anychar();
    if (IS_NULL(np1)) goto err;

    option = env->option;
    ONOFF(option, ONIG_OPTION_MULTILINE, 0);
    tmp = node_new_option(option);
    if (IS_NULL(tmp)) goto err;
    NENCLOSE(tmp)->target = np1;
    np1 = tmp;

    tmp = onig_node_new_alt(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    np1 = NULL;

    /* Prepend+ */
    r = ONIGENC_CODE_TO_MBC(env->enc, 0x200D, buf);
    if (r < 0) goto err;
    np1 = node_new_str_raw(buf, buf + r);
    if (IS_NULL(np1)) goto err;

    tmp = node_new_quantifier(0, 1, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, NULL_NODE);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    np1 = node_new_cclass();
    if (IS_NULL(np1)) goto err;
    cc = NCCLASS(np1);
    r = add_ctype_to_cc(cc, propname2ctype(env, "Grapheme_Cluster_Break=Prepend"), 0, 0, env);
    if (r != 0) goto err;

    tmp = node_new_quantifier(1, REPEAT_INFINITE, 0);
    if (IS_NULL(tmp)) goto err;
    NQTFR(tmp)->target = np1;
    np1 = tmp;

    tmp = node_new_list(np1, list2);
    if (IS_NULL(tmp)) goto err;
    list2 = tmp;
    np1 = NULL;

    tmp = onig_node_new_alt(list2, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    list2 = NULL;

    tmp = onig_node_new_alt(list, alt);
    if (IS_NULL(tmp)) goto err;
    alt = tmp;
    list = NULL;
  }
  else
#endif /* USE_UNICODE_PROPERTIES */
  {
    /* PerlSyntax: (?s:.), RubySyntax: (?m:.) */
    np1 = node_new_anychar();
    if (IS_NULL(np1)) goto err;

    option = env->option;
    ONOFF(option, ONIG_OPTION_MULTILINE, 0);
    tmp = node_new_option(option);
    if (IS_NULL(tmp)) goto err;
    NENCLOSE(tmp)->target = np1;
    np1 = tmp;

    alt = onig_node_new_alt(np1, NULL_NODE);
    if (IS_NULL(alt)) goto err;
    np1 = NULL;
  }

  /* \x0D\x0A */
  r = ONIGENC_CODE_TO_MBC(env->enc, 0x0D, buf);
  if (r < 0) goto err;
  num1 = r;
  r = ONIGENC_CODE_TO_MBC(env->enc, 0x0A, buf + num1);
  if (r < 0) goto err;
  np1 = node_new_str_raw(buf, buf + num1 + r);
  if (IS_NULL(np1)) goto err;

  tmp = onig_node_new_alt(np1, alt);
  if (IS_NULL(tmp)) goto err;
  alt = tmp;
  np1 = NULL;

  /* (?>\x0D\x0A|...) */
  tmp = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
  if (IS_NULL(tmp)) goto err;
  NENCLOSE(tmp)->target = alt;
  np1 = tmp;

#ifdef USE_UNICODE_PROPERTIES
  if (ONIGENC_IS_UNICODE(env->enc)) {
    /* Don't ignore case. */
    option = env->option;
    ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
    *np = node_new_option(option);
    if (IS_NULL(*np)) goto err;
    NENCLOSE(*np)->target = np1;
  }
  else
#endif
  {
    *np = np1;
  }
  return ONIG_NORMAL;

 err:
  onig_node_free(np1);
  onig_node_free(list);
  onig_node_free(list2);
  onig_node_free(alt);
  onig_node_free(alt2);
  bbuf_free(pbuf1);
  return (r == 0) ? ONIGERR_MEMORY : r;
}

Project: ruby
File: re.c

match_ary_aref(VALUE match, VALUE idx, VALUE result)
{
    long beg, len;
    int num_regs = RMATCH_REGS(match)->num_regs;

    /* check if idx is Range */
    switch (rb_range_beg_len(idx, &beg, &len, (long)num_regs, !NIL_P(result))) {
      case Qfalse:
	if (NIL_P(result)) return rb_reg_nth_match(NUM2INT(idx), match);
	rb_ary_push(result, rb_reg_nth_match(NUM2INT(idx), match));
	return result;
      case Qnil:
	return Qnil;
      default:
	return match_ary_subseq(match, beg, len, result);
    }
}

Project: ruby
File: regparse.c

bitset_invert_to(BitSetRef from, BitSetRef to)
{
  int i;
  for (i = 0; i < BITSET_SIZE; i++) { to[i] = ~(from[i]); }
}

Project: ruby
File: regcomp.c

Indent(FILE* f, int indent)
{
  int i;
  for (i = 0; i < indent; i++) putc(' ', f);
}

Project: ruby
File: regcomp.c

add_bytes(regex_t* reg, UChar* bytes, OnigDistance len)
{
  BBUF_ADD(reg, bytes, len);
  return 0;
}

Project: ruby
File: regcomp.c

add_len_mml(MinMaxLen* to, OnigDistance len)
{
  to->min = distance_add(to->min, len);
  to->max = distance_add(to->max, len);
}

Project: ruby
File: regcomp.c

onig_free(regex_t* reg)
{
  if (IS_NOT_NULL(reg)) {
    onig_free_body(reg);
    xfree(reg);
  }
}

Project: ruby
File: re.c

rb_memsearch_qs(const unsigned char *xs, long m, const unsigned char *ys, long n)
{
    const unsigned char *x = xs, *xe = xs + m;
    const unsigned char *y = ys;
    VALUE i, qstable[256];

    /* Preprocessing */
    for (i = 0; i < 256; ++i)
	qstable[i] = m + 1;
    for (; x < xe; ++x)
	qstable[*x] = xe - x;
    /* Searching */
    for (; y + m <= ys + n; y += *(qstable + y[m])) {
	if (*xs == *y && memcmp(xs, y, m) == 0)
	    return y - ys;
    }
    return -1;
}

Project: ruby
File: iso_8859_1.c

is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc ARG_UNUSED)
{
  if (code < 256)
    return ENC_IS_ISO_8859_1_CTYPE(code, ctype);
  else
    return FALSE;
}

Project: ruby
File: regcomp.c

compile_tree_empty_check(Node* node, regex_t* reg, int empty_info)
{
  int r;
  int saved_num_null_check = reg->num_null_check;

  if (empty_info != 0) {
    r = add_opcode(reg, OP_NULL_CHECK_START);
    if (r) return r;
    r = add_mem_num(reg, reg->num_null_check); /* NULL CHECK ID */
    if (r) return r;
    reg->num_null_check++;
  }

  r = compile_tree(node, reg);
  if (r) return r;

  if (empty_info != 0) {
    if (empty_info == NQ_TARGET_IS_EMPTY)
      r = add_opcode(reg, OP_NULL_CHECK_END);
    else if (empty_info == NQ_TARGET_IS_EMPTY_MEM)
      r = add_opcode(reg, OP_NULL_CHECK_END_MEMST);
    else if (empty_info == NQ_TARGET_IS_EMPTY_REC)
      r = add_opcode(reg, OP_NULL_CHECK_END_MEMST_PUSH);

    if (r) return r;
    r = add_mem_num(reg, saved_num_null_check); /* NULL CHECK ID */
  }
  return r;
}

Project: ruby
File: regenc.c

onigenc_mb2_is_code_ctype(OnigEncoding enc, OnigCodePoint code,
			  unsigned int ctype)
{
  if (code < 128)
    return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
  else {
    if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
      return (ONIGENC_CODE_TO_MBCLEN(enc, code) > 1 ? TRUE : FALSE);
    }
  }

  return FALSE;
}

Project: ruby
File: regparse.c

strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_end,
	      size_t capa)
{
  UChar* r;

  if (dest)
    r = (UChar* )xrealloc(dest, capa + 1);
  else
    r = (UChar* )xmalloc(capa + 1);

  CHECK_NULL_RETURN(r);
  onig_strcpy(r + (dest_end - dest), src, src_end);
  return r;
}

Project: ruby
File: regparse.c

and_cclass(CClassNode* dest, CClassNode* cc, ScanEnv* env)
{
  OnigEncoding enc = env->enc;
  int r, not1, not2;
  BBuf *buf1, *buf2, *pbuf = 0;
  BitSetRef bsr1, bsr2;
  BitSet bs1, bs2;

  not1 = IS_NCCLASS_NOT(dest);
  bsr1 = dest->bs;
  buf1 = dest->mbuf;
  not2 = IS_NCCLASS_NOT(cc);
  bsr2 = cc->bs;
  buf2 = cc->mbuf;

  if (not1 != 0) {
    bitset_invert_to(bsr1, bs1);
    bsr1 = bs1;
  }
  if (not2 != 0) {
    bitset_invert_to(bsr2, bs2);
    bsr2 = bs2;
  }
  bitset_and(bsr1, bsr2);
  if (bsr1 != dest->bs) {
    bitset_copy(dest->bs, bsr1);
    bsr1 = dest->bs;
  }
  if (not1 != 0) {
    bitset_invert(dest->bs);
  }

  if (! ONIGENC_IS_SINGLEBYTE(enc)) {
    if (not1 != 0 && not2 != 0) {
      r = or_code_range_buf(enc, buf1, 0, buf2, 0, &pbuf, env);
    }
    else {
      r = and_code_range_buf(buf1, not1, buf2, not2, &pbuf, env);
      if (r == 0 && not1 != 0) {
	BBuf *tbuf = 0;
	r = not_code_range_buf(enc, pbuf, &tbuf, env);
	bbuf_free(pbuf);
	pbuf = tbuf;
      }
    }
    if (r != 0) {
      bbuf_free(pbuf);
      return r;
    }

    dest->mbuf = pbuf;
    bbuf_free(buf1);
    return r;
  }
  return 0;
}

Project: ruby
File: re.c

rb_reg_source(VALUE re)
{
    VALUE str;

    rb_reg_check(re);
    str = rb_str_dup(RREGEXP_SRC(re));
    if (OBJ_TAINTED(re)) OBJ_TAINT(str);
    return str;
}

Project: ruby
File: regenc.c

onigenc_mbclen_approximate(const OnigUChar* p,const OnigUChar* e, OnigEncoding enc)
{
  int ret = ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e);
  if (ONIGENC_MBCLEN_CHARFOUND_P(ret))
    return ONIGENC_MBCLEN_CHARFOUND_LEN(ret);
  else if (ONIGENC_MBCLEN_NEEDMORE_P(ret))
    return (int)(e-p)+ONIGENC_MBCLEN_NEEDMORE_LEN(ret);
  return 1;
}

Project: ruby
File: regparse.c

cclass_case_fold(Node** np, CClassNode* cc, CClassNode* asc_cc, ScanEnv* env)
{
  int r;
  IApplyCaseFoldArg iarg;

  iarg.env         = env;
  iarg.cc          = cc;
  iarg.asc_cc      = asc_cc;
  iarg.alt_root    = NULL_NODE;
  iarg.ptail       = &(iarg.alt_root);

  r = ONIGENC_APPLY_ALL_CASE_FOLD(env->enc, env->case_fold_flag,
				  i_apply_case_fold, &iarg);
  if (r != 0) {
    onig_node_free(iarg.alt_root);
    return r;
  }
  if (IS_NOT_NULL(iarg.alt_root)) {
    Node* work = onig_node_new_alt(*np, iarg.alt_root);
    if (IS_NULL(work)) {
      onig_node_free(iarg.alt_root);
      return ONIGERR_MEMORY;
    }
    *np = work;
  }
  return r;
}

Project: ruby
File: regcomp.c

compile_length_quantifier_node(QtfrNode* qn, regex_t* reg)
{
  int len, mod_tlen;
  int infinite = IS_REPEAT_INFINITE(qn->upper);
  int empty_info = qn->target_empty_info;
  int tlen = compile_length_tree(qn->target, reg);

  if (tlen < 0) return tlen;

  /* anychar repeat */
  if (NTYPE(qn->target) == NT_CANY) {
    if (qn->greedy && infinite) {
      if (IS_NOT_NULL(qn->next_head_exact))
	return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower;
      else
	return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower;
    }
  }

  if (empty_info != 0)
    mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
  else
    mod_tlen = tlen;

  if (infinite &&
      (qn->lower <= 1 || tlen * qn->lower <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
    if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
      len = SIZE_OP_JUMP;
    }
    else {
      len = tlen * qn->lower;
    }

    if (qn->greedy) {
#ifdef USE_OP_PUSH_OR_JUMP_EXACT
      if (IS_NOT_NULL(qn->head_exact))
	len += SIZE_OP_PUSH_OR_JUMP_EXACT1 + mod_tlen + SIZE_OP_JUMP;
      else
#endif
      if (IS_NOT_NULL(qn->next_head_exact))
	len += SIZE_OP_PUSH_IF_PEEK_NEXT + mod_tlen + SIZE_OP_JUMP;
      else
	len += SIZE_OP_PUSH + mod_tlen + SIZE_OP_JUMP;
    }
    else
      len += SIZE_OP_JUMP + mod_tlen + SIZE_OP_PUSH;
  }
  else if (qn->upper == 0 && qn->is_refered != 0) { /* /(?<n>..){0}/ */
    len = SIZE_OP_JUMP + tlen;
  }
  else if (!infinite && qn->greedy &&
           (qn->upper == 1 || (tlen + SIZE_OP_PUSH) * qn->upper
                                      <= QUANTIFIER_EXPAND_LIMIT_SIZE)) {
    len = tlen * qn->lower;
    len += (SIZE_OP_PUSH + tlen) * (qn->upper - qn->lower);
  }
  else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
    len = SIZE_OP_PUSH + SIZE_OP_JUMP + tlen;
  }
  else {
    len = SIZE_OP_REPEAT_INC
        + mod_tlen + SIZE_OPCODE + SIZE_RELADDR + SIZE_MEMNUM;
  }

  return len;
}

Project: ruby
File: mktable.c

static int IsWord(int enc, int c)
{
  if (enc == ASCII) {
    return (isalpha(c) || isdigit(c) || c == 0x5f);
  }

  if (c >= 0x30 && c <= 0x39) return 1;
  if (c >= 0x41 && c <= 0x5a) return 1;
  if (c == 0x5f) return 1;
  if (c >= 0x61 && c <= 0x7a) return 1;

  switch (enc) {
  case UNICODE_ISO_8859_1:
  case ISO_8859_1:
  case ISO_8859_9:
    if (c == 0xaa) return 1;
    if (c >= 0xb2 && c <= 0xb3) return 1;
    if (c == 0xb5) return 1;
    if (c >= 0xb9 && c <= 0xba) return 1;
    if (c >= 0xbc && c <= 0xbe) return 1;
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xf6) return 1;
    if (c >= 0xf8 && c <= 0xff) return 1;
    break;

  case ISO_8859_2:
    if (c == 0xa1 || c == 0xa3) return 1;
    if (c == 0xa5 || c == 0xa6) return 1;
    if (c >= 0xa9 && c <= 0xac) return 1;
    if (c >= 0xae && c <= 0xaf) return 1;
    if (c == 0xb1 || c == 0xb3) return 1;
    if (c == 0xb5 || c == 0xb6) return 1;
    if (c >= 0xb9 && c <= 0xbc) return 1;
    if (c >= 0xbe && c <= 0xbf) return 1;
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xf6) return 1;
    if (c >= 0xf8 && c <= 0xfe) return 1;
    break;

  case ISO_8859_3:
    if (c == 0xa1) return 1;
    if (c == 0xa6) return 1;
    if (c >= 0xa9 && c <= 0xac) return 1;
    if (c == 0xaf) return 1;
    if (c >= 0xb1 && c <= 0xb3) return 1;
    if (c == 0xb5 || c == 0xb6) return 1;
    if (c >= 0xb9 && c <= 0xbd) return 1;
    if (c == 0xbf) return 1;
    if (c >= 0xc0 && c <= 0xc2) return 1;
    if (c >= 0xc4 && c <= 0xcf) return 1;
    if (c >= 0xd1 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xe2) return 1;
    if (c >= 0xe4 && c <= 0xef) return 1;
    if (c >= 0xf1 && c <= 0xf6) return 1;
    if (c >= 0xf8 && c <= 0xfe) return 1;
    break;

  case ISO_8859_4:
    if (c >= 0xa1 && c <= 0xa3) return 1;
    if (c == 0xa5 || c == 0xa6) return 1;
    if (c >= 0xa9 && c <= 0xac) return 1;
    if (c == 0xae) return 1;
    if (c == 0xb1 || c == 0xb3) return 1;
    if (c == 0xb5 || c == 0xb6) return 1;
    if (c >= 0xb9 && c <= 0xbf) return 1;
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xf6) return 1;
    if (c >= 0xf8 && c <= 0xfe) return 1;
    break;

  case ISO_8859_5:
    if (c >= 0xa1 && c <= 0xcf && c != 0xad) return 1;
    if (c >= 0xd0 && c <= 0xff && c != 0xf0 && c != 0xfd) return 1;
    break;

  case ISO_8859_6:
    if (c >= 0xc1 && c <= 0xda) return 1;
    if (c >= 0xe0 && c <= 0xea) return 1;
    if (c >= 0xeb && c <= 0xf2) return 1;
    break;

  case ISO_8859_7:
    if (c == 0xb2 || c == 0xb3) return 1;
    if (c == 0xb6) return 1;
    if (c >= 0xb8 && c <= 0xba) return 1;
    if (c >= 0xbc && c <= 0xbf) return 1;
    if (c == 0xc0) return 1;
    if (c >= 0xc1 && c <= 0xdb && c != 0xd2) return 1;
    if (c >= 0xdc && c <= 0xfe) return 1;
    break;

  case ISO_8859_8:
    if (c == 0xb2 || c == 0xb3 || c == 0xb5 || c == 0xb9) return 1;
    if (c >= 0xbc && c <= 0xbe) return 1;
    if (c >= 0xe0 && c <= 0xfa) return 1;
    break;

  case ISO_8859_10:
    if (c >= 0xa1 && c <= 0xff) {
      if (c != 0xa7 && c != 0xad && c != 0xb0 && c != 0xb7 && c != 0xbd)
	return 1;
    }
    break;

  case ISO_8859_11:
    if (c >= 0xa1 && c <= 0xda) return 1;
    if (c >= 0xdf && c <= 0xfb) return 1;
    break;

  case ISO_8859_13:
    if (c == 0xa8) return 1;
    if (c == 0xaa) return 1;
    if (c == 0xaf) return 1;
    if (c == 0xb2 || c == 0xb3 || c == 0xb5 || c == 0xb9) return 1;
    if (c >= 0xbc && c <= 0xbe) return 1;
    if (c == 0xb8) return 1;
    if (c == 0xba) return 1;
    if (c >= 0xbf && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xf6) return 1;
    if (c >= 0xf8 && c <= 0xfe) return 1;
    break;

  case ISO_8859_14:
    if (c >= 0xa1 && c <= 0xff) {
      if (c == 0xa3 || c == 0xa7 || c == 0xa9 || c == 0xad || c == 0xae ||
	  c == 0xb6) return 0;
      return 1;
    }
    break;

  case ISO_8859_15:
    if (c == 0xaa) return 1;
    if (c >= 0xb2 && c <= 0xb3) return 1;
    if (c == 0xb5) return 1;
    if (c >= 0xb9 && c <= 0xba) return 1;
    if (c >= 0xbc && c <= 0xbe) return 1;
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xf6) return 1;
    if (c >= 0xf8 && c <= 0xff) return 1;
    if (c == 0xa6) return 1;
    if (c == 0xa8) return 1;
    if (c == 0xb4) return 1;
    if (c == 0xb8) return 1;
    break;

  case ISO_8859_16:
    if (c == 0xa1) return 1;
    if (c == 0xa2) return 1;
    if (c == 0xa3) return 1;
    if (c == 0xa6) return 1;
    if (c == 0xa8) return 1;
    if (c == 0xaa) return 1;
    if (c == 0xac) return 1;
    if (c == 0xae) return 1;
    if (c == 0xaf) return 1;
    if (c == 0xb2) return 1;
    if (c == 0xb3) return 1;
    if (c == 0xb4) return 1;
    if (c >= 0xb8 && c <= 0xba) return 1;
    if (c == 0xbc) return 1;
    if (c == 0xbd) return 1;
    if (c == 0xbe) return 1;
    if (c == 0xbf) return 1;
    if (c >= 0xc0 && c <= 0xde) return 1;
    if (c >= 0xdf && c <= 0xff) return 1;
    break;

  case KOI8_R:
    if (c == 0x9d) return 1;
    if (c == 0xa3 || c == 0xb3) return 1;
    /* fall */
  case KOI8:
    if (c >= 0xc0 && c <= 0xff) return 1;
    break;

  default:
    exit(-1);
  }

  return 0;
}

Project: ruby
File: regcomp.c

is_case_fold_variable_len(int item_num, OnigCaseFoldCodeItem items[],
			  int slen)
{
  int i;

  for (i = 0; i < item_num; i++) {
    if (items[i].byte_len != slen) {
      return 1;
    }
    if (items[i].code_len != 1) {
      return 1;
    }
  }
  return 0;
}

Project: ruby
File: unicode.c

code1_equal(const OnigCodePoint x, const OnigCodePoint y)
{
  if (x != y) return 0;
  return 1;
}

Project: ruby
File: iso_8859_9.c

mbc_case_fold(OnigCaseFoldType flag,
	      const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower,
	      OnigEncoding enc ARG_UNUSED)
{
  const UChar* p = *pp;

  if (*p == SHARP_s && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
    *lower++ = 's';
    *lower   = 's';
    (*pp)++;
    return 2;
  }

  *lower = ENC_ISO_8859_9_TO_LOWER_CASE(*p);
  (*pp)++;
  return 1;
}

Project: ruby
File: regcomp.c

divide_look_behind_alternatives(Node* node)
{
  Node *head, *np, *insert_node;
  AnchorNode* an = NANCHOR(node);
  int anc_type = an->type;

  head = an->target;
  np = NCAR(head);
  swap_node(node, head);
  NCAR(node) = head;
  NANCHOR(head)->target = np;

  np = node;
  while ((np = NCDR(np)) != NULL_NODE) {
    insert_node = onig_node_new_anchor(anc_type);
    CHECK_NULL_RETURN_MEMERR(insert_node);
    NANCHOR(insert_node)->target = NCAR(np);
    NCAR(np) = insert_node;
  }

  if (anc_type == ANCHOR_LOOK_BEHIND_NOT) {
    np = node;
    do {
      SET_NTYPE(np, NT_LIST);  /* alt -> list */
    } while ((np = NCDR(np)) != NULL_NODE);
  }
  return 0;
}

Project: ruby
File: regexec.c

set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED,
		     int** skip)
{
  int i, len;

  if (IS_NULL(*skip)) {
    *skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
    if (IS_NULL(*skip)) return ONIGERR_MEMORY;
  }

  len = (int )(end - s);
  for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
    (*skip)[i] = len;

  for (i = len - 1; i > 0; i--)
    (*skip)[s[i]] = i;

  return 0;
}

Project: ruby
File: regenc.c

onigenc_minimum_property_name_to_ctype(OnigEncoding enc, const UChar* p, const UChar* end)
{
  static const PosixBracketEntryType PBS[] = {
    POSIX_BRACKET_ENTRY_INIT("Alnum",  ONIGENC_CTYPE_ALNUM),
    POSIX_BRACKET_ENTRY_INIT("Alpha",  ONIGENC_CTYPE_ALPHA),
    POSIX_BRACKET_ENTRY_INIT("Blank",  ONIGENC_CTYPE_BLANK),
    POSIX_BRACKET_ENTRY_INIT("Cntrl",  ONIGENC_CTYPE_CNTRL),
    POSIX_BRACKET_ENTRY_INIT("Digit",  ONIGENC_CTYPE_DIGIT),
    POSIX_BRACKET_ENTRY_INIT("Graph",  ONIGENC_CTYPE_GRAPH),
    POSIX_BRACKET_ENTRY_INIT("Lower",  ONIGENC_CTYPE_LOWER),
    POSIX_BRACKET_ENTRY_INIT("Print",  ONIGENC_CTYPE_PRINT),
    POSIX_BRACKET_ENTRY_INIT("Punct",  ONIGENC_CTYPE_PUNCT),
    POSIX_BRACKET_ENTRY_INIT("Space",  ONIGENC_CTYPE_SPACE),
    POSIX_BRACKET_ENTRY_INIT("Upper",  ONIGENC_CTYPE_UPPER),
    POSIX_BRACKET_ENTRY_INIT("XDigit", ONIGENC_CTYPE_XDIGIT),
    POSIX_BRACKET_ENTRY_INIT("ASCII",  ONIGENC_CTYPE_ASCII),
    POSIX_BRACKET_ENTRY_INIT("Word",   ONIGENC_CTYPE_WORD),
  };

  const PosixBracketEntryType *pb;
  int len;

  len = onigenc_strlen(enc, p, end);
  for (pb = PBS; pb < PBS + numberof(PBS); pb++) {
    if (len == pb->len &&
        onigenc_with_ascii_strnicmp(enc, p, end, pb->name, pb->len) == 0)
      return pb->ctype;
  }

  return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
}

Project: ruby
File: re.c

match_captures(VALUE match)
{
    return match_array(match, 1);
}

Project: ruby
File: regparse.c

bitset_set_range(ScanEnv *env, BitSetRef bs, int from, int to)
{
  int i;
  for (i = from; i <= to && i < SINGLE_BYTE_SIZE; i++) {
    BITSET_SET_BIT_CHKDUP(bs, i);
  }
}

Project: ruby
File: regparse.c

fetch_named_backref_token(OnigCodePoint c, OnigToken* tok, UChar** src,
			  UChar* end, ScanEnv* env)
{
  int r, num;
  const OnigSyntaxType* syn = env->syntax;
  UChar* prev;
  UChar* p = *src;
  UChar* name_end;
  int* backs;
  int back_num;

  prev = p;

# ifdef USE_BACKREF_WITH_LEVEL
  name_end = NULL_UCHARP; /* no need. escape gcc warning. */
  r = fetch_name_with_level(c, &p, end, &name_end,
			    env, &back_num, &tok->u.backref.level);
  if (r == 1) tok->u.backref.exist_level = 1;
  else        tok->u.backref.exist_level = 0;
# else
  r = fetch_name(&p, end, &name_end, env, &back_num, 1);
# endif
  if (r < 0) return r;

  if (back_num != 0) {
    if (back_num < 0) {
      back_num = BACKREF_REL_TO_ABS(back_num, env);
      if (back_num <= 0)
	return ONIGERR_INVALID_BACKREF;
    }

    if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
      if (back_num > env->num_mem ||
	  IS_NULL(SCANENV_MEM_NODES(env)[back_num]))
	return ONIGERR_INVALID_BACKREF;
    }
    tok->type = TK_BACKREF;
    tok->u.backref.by_name = 0;
    tok->u.backref.num  = 1;
    tok->u.backref.ref1 = back_num;
  }
  else {
    num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs);
    if (num <= 0) {
      onig_scan_env_set_error_string(env,
		     ONIGERR_UNDEFINED_NAME_REFERENCE, prev, name_end);
      return ONIGERR_UNDEFINED_NAME_REFERENCE;
    }
    if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
      int i;
      for (i = 0; i < num; i++) {
	if (backs[i] > env->num_mem ||
	    IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
	  return ONIGERR_INVALID_BACKREF;
      }
    }

    tok->type = TK_BACKREF;
    tok->u.backref.by_name = 1;
    if (num == 1 || IS_SYNTAX_BV(syn, ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP)) {
      tok->u.backref.num  = 1;
      tok->u.backref.ref1 = backs[0];
    }
    else {
      tok->u.backref.num  = num;
      tok->u.backref.refs = backs;
    }
  }
  *src = p;
  return 0;
}

Project: ruby
File: mktable.c

static int IsUpper(int enc, int c)
{
  if (enc == ASCII)
    return isupper(c);

  if (c >= 0x41 && c <= 0x5a) return 1;

  switch (enc) {
  case UNICODE_ISO_8859_1:
  case ISO_8859_1:
  case ISO_8859_9:
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xde) return 1;
    break;

  case ISO_8859_2:
    if (c == 0xa1 || c == 0xa3) return 1;
    if (c == 0xa5 || c == 0xa6) return 1;
    if (c >= 0xa9 && c <= 0xac) return 1;
    if (c >= 0xae && c <= 0xaf) return 1;
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xde) return 1;
    break;

  case ISO_8859_3:
    if (c == 0xa1) return 1;
    if (c == 0xa6) return 1;
    if (c >= 0xa9 && c <= 0xac) return 1;
    if (c == 0xaf) return 1;
    if (c >= 0xc0 && c <= 0xc2) return 1;
    if (c >= 0xc4 && c <= 0xcf) return 1;
    if (c >= 0xd1 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xde) return 1;
    break;

  case ISO_8859_4:
    if (c == 0xa1 || c == 0xa3) return 1;
    if (c == 0xa5 || c == 0xa6) return 1;
    if (c >= 0xa9 && c <= 0xac) return 1;
    if (c == 0xae) return 1;
    if (c == 0xbd) return 1;
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xde) return 1;
    break;

  case ISO_8859_5:
    if (c >= 0xa1 && c <= 0xcf && c != 0xad) return 1;
    break;

  case ISO_8859_6:
    break;

  case ISO_8859_7:
    if (c == 0xb6) return 1;
    if (c >= 0xb8 && c <= 0xba) return 1;
    if (c == 0xbc) return 1;
    if (c >= 0xbe && c <= 0xbf) return 1;
    if (c >= 0xc1 && c <= 0xdb && c != 0xd2) return 1;
    break;

  case ISO_8859_8:
  case ISO_8859_11:
    break;

  case ISO_8859_10:
    if (c >= 0xa1 && c <= 0xa6) return 1;
    if (c >= 0xa8 && c <= 0xac) return 1;
    if (c == 0xae || c == 0xaf) return 1;
    if (c >= 0xc0 && c <= 0xde) return 1;
    break;

  case ISO_8859_13:
    if (c == 0xa8) return 1;
    if (c == 0xaa) return 1;
    if (c == 0xaf) return 1;
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xde) return 1;
    break;

  case ISO_8859_14:
    if (c == 0xa1) return 1;
    if (c == 0xa4 || c == 0xa6) return 1;
    if (c == 0xa8) return 1;
    if (c == 0xaa || c == 0xac) return 1;
    if (c == 0xaf || c == 0xb0) return 1;
    if (c == 0xb2 || c == 0xb4 || c == 0xb7) return 1;
    if (c == 0xbb || c == 0xbd) return 1;
    if (c >= 0xc0 && c <= 0xde) return 1;
    break;

  case ISO_8859_15:
    if (c >= 0xc0 && c <= 0xd6) return 1;
    if (c >= 0xd8 && c <= 0xde) return 1;
    if (c == 0xa6) return 1;
    if (c == 0xb4) return 1;
    if (c == 0xbc) return 1;
    if (c == 0xbe) return 1;
    break;

  case ISO_8859_16:
    if (c == 0xa1) return 1;
    if (c == 0xa3) return 1;
    if (c == 0xa6) return 1;
    if (c == 0xaa) return 1;
    if (c == 0xac) return 1;
    if (c == 0xaf) return 1;
    if (c == 0xb2) return 1;
    if (c == 0xb4) return 1;
    if (c == 0xbc) return 1;
    if (c == 0xbe) return 1;
    if (c >= 0xc0 && c <= 0xde) return 1;
    break;

  case KOI8_R:
    if (c == 0xb3) return 1;
    /* fall */
  case KOI8:
    if (c >= 0xe0 && c <= 0xff) return 1;
    break;

  default:
    exit(-1);
  }

  return 0;
}

Project: ruby
File: regcomp.c

onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
	     OnigErrorInfo* einfo)
#endif
{
#define COMPILE_INIT_SIZE  20

  int r;
  OnigDistance init_size;
  Node*  root;
  ScanEnv  scan_env = {0};
#ifdef USE_SUBEXP_CALL
  UnsetAddrList  uslist;
#endif

  if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;

#ifdef RUBY
  scan_env.sourcefile = sourcefile;
  scan_env.sourceline = sourceline;
#endif

#ifdef ONIG_DEBUG
  print_enc_string(stderr, reg->enc, pattern, pattern_end);
#endif

  if (reg->alloc == 0) {
    init_size = (pattern_end - pattern) * 2;
    if (init_size <= 0) init_size = COMPILE_INIT_SIZE;
    r = BBUF_INIT(reg, init_size);
    if (r != 0) goto end;
  }
  else
    reg->used = 0;

  reg->num_mem            = 0;
  reg->num_repeat         = 0;
  reg->num_null_check     = 0;
  reg->repeat_range_alloc = 0;
  reg->repeat_range       = (OnigRepeatRange* )NULL;
#ifdef USE_COMBINATION_EXPLOSION_CHECK
  reg->num_comb_exp_check = 0;
#endif

  r = onig_parse_make_tree(&root, pattern, pattern_end, reg, &scan_env);
  if (r != 0) goto err;

#ifdef ONIG_DEBUG_PARSE_TREE
# if 0
  fprintf(stderr, "ORIGINAL PARSE TREE:\n");
  print_tree(stderr, root);
# endif
#endif

#ifdef USE_NAMED_GROUP
  /* mixed use named group and no-named group */
  if (scan_env.num_named > 0 &&
      IS_SYNTAX_BV(scan_env.syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
      !ONIG_IS_OPTION_ON(reg->options, ONIG_OPTION_CAPTURE_GROUP)) {
    if (scan_env.num_named != scan_env.num_mem)
      r = disable_noname_group_capture(&root, reg, &scan_env);
    else
      r = numbered_ref_check(root);

    if (r != 0) goto err;
  }
#endif

#ifdef USE_SUBEXP_CALL
  if (scan_env.num_call > 0) {
    r = unset_addr_list_init(&uslist, scan_env.num_call);
    if (r != 0) goto err;
    scan_env.unset_addr_list = &uslist;
    r = setup_subexp_call(root, &scan_env);
    if (r != 0) goto err_unset;
    r = subexp_recursive_check_trav(root, &scan_env);
    if (r  < 0) goto err_unset;
    r = subexp_inf_recursive_check_trav(root, &scan_env);
    if (r != 0) goto err_unset;

    reg->num_call = scan_env.num_call;
  }
  else
    reg->num_call = 0;
#endif

  r = setup_tree(root, reg, IN_ROOT, &scan_env);
  if (r != 0) goto err_unset;

#ifdef ONIG_DEBUG_PARSE_TREE
  print_tree(stderr, root);
#endif

  reg->capture_history  = scan_env.capture_history;
  reg->bt_mem_start     = scan_env.bt_mem_start;
  reg->bt_mem_start    |= reg->capture_history;
  if (IS_FIND_CONDITION(reg->options))
    BIT_STATUS_ON_ALL(reg->bt_mem_end);
  else {
    reg->bt_mem_end  = scan_env.bt_mem_end;
    reg->bt_mem_end |= reg->capture_history;
  }

#ifdef USE_COMBINATION_EXPLOSION_CHECK
  if (scan_env.backrefed_mem == 0
# ifdef USE_SUBEXP_CALL
      || scan_env.num_call == 0
# endif
      ) {
    setup_comb_exp_check(root, 0, &scan_env);
# ifdef USE_SUBEXP_CALL
    if (scan_env.has_recursion != 0) {
      scan_env.num_comb_exp_check = 0;
    }
    else
# endif
    if (scan_env.comb_exp_max_regnum > 0) {
      int i;
      for (i = 1; i <= scan_env.comb_exp_max_regnum; i++) {
	if (BIT_STATUS_AT(scan_env.backrefed_mem, i) != 0) {
	  scan_env.num_comb_exp_check = 0;
	  break;
	}
      }
    }
  }

  reg->num_comb_exp_check = scan_env.num_comb_exp_check;
#endif

  clear_optimize_info(reg);
#ifndef ONIG_DONT_OPTIMIZE
  r = set_optimize_info_from_tree(root, reg, &scan_env);
  if (r != 0) goto err_unset;
#endif

  if (IS_NOT_NULL(scan_env.mem_nodes_dynamic)) {
    xfree(scan_env.mem_nodes_dynamic);
    scan_env.mem_nodes_dynamic = (Node** )NULL;
  }

  r = compile_tree(root, reg);
  if (r == 0) {
    r = add_opcode(reg, OP_END);
#ifdef USE_SUBEXP_CALL
    if (scan_env.num_call > 0) {
      r = unset_addr_list_fix(&uslist, reg);
      unset_addr_list_end(&uslist);
      if (r) goto err;
    }
#endif

    if ((reg->num_repeat != 0) || (reg->bt_mem_end != 0))
      reg->stack_pop_level = STACK_POP_LEVEL_ALL;
    else {
      if (reg->bt_mem_start != 0)
	reg->stack_pop_level = STACK_POP_LEVEL_MEM_START;
      else
	reg->stack_pop_level = STACK_POP_LEVEL_FREE;
    }
  }
#ifdef USE_SUBEXP_CALL
  else if (scan_env.num_call > 0) {
    unset_addr_list_end(&uslist);
  }
#endif
  onig_node_free(root);

#ifdef ONIG_DEBUG_COMPILE
# ifdef USE_NAMED_GROUP
  onig_print_names(stderr, reg);
# endif
  print_compiled_byte_code_list(stderr, reg);
#endif

 end:
  return r;

 err_unset:
#ifdef USE_SUBEXP_CALL
  if (scan_env.num_call > 0) {
    unset_addr_list_end(&uslist);
  }
#endif
 err:
  if (IS_NOT_NULL(scan_env.error)) {
    if (IS_NOT_NULL(einfo)) {
      einfo->enc     = scan_env.enc;
      einfo->par     = scan_env.error;
      einfo->par_end = scan_env.error_end;
    }
  }

  onig_node_free(root);
  if (IS_NOT_NULL(scan_env.mem_nodes_dynamic))
      xfree(scan_env.mem_nodes_dynamic);
  return r;
}

Project: ruby
File: regcomp.c

remove_opt_anc_info(OptAncInfo* to, int anc)
{
  if (is_left_anchor(anc))
    to->left_anchor &= ~anc;
  else
    to->right_anchor &= ~anc;
}

Project: ruby
File: re.c

match_begin(VALUE match, VALUE n)
{
    int i = match_backref_number(match, n);
    struct re_registers *regs = RMATCH_REGS(match);

    match_check(match);
    if (i < 0 || regs->num_regs <= i)
	rb_raise(rb_eIndexError, "index %d out of matches", i);

    if (BEG(i) < 0)
	return Qnil;

    update_char_offset(match);
    return INT2FIX(RMATCH(match)->rmatch->char_offset[i].beg);
}

Project: ruby
File: regenc.c

onigenc_single_byte_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED,
				OnigEncoding enc ARG_UNUSED)
{
  return (OnigCodePoint )(*p);
}

Project: ruby
File: regexec.c

onig_search(regex_t* reg, const UChar* str, const UChar* end,
	    const UChar* start, const UChar* range, OnigRegion* region, OnigOptionType option)
{
  return onig_search_gpos(reg, str, end, start, start, range, region, option);
}

Project: ruby
File: regexec.c

onig_region_copy(OnigRegion* to, const OnigRegion* from)
{
#define RREGC_SIZE   (sizeof(int) * from->num_regs)
  int i, r;

  if (to == from) return;

  r = onig_region_resize(to, from->num_regs);
  if (r) return;

  for (i = 0; i < from->num_regs; i++) {
    to->beg[i] = from->beg[i];
    to->end[i] = from->end[i];
  }
  to->num_regs = from->num_regs;

#ifdef USE_CAPTURE_HISTORY
  history_root_free(to);

  if (IS_NOT_NULL(from->history_root)) {
    to->history_root = history_tree_clone(from->history_root);
  }
#endif
}

Project: ruby
File: regenc.c

onigenc_apply_all_case_fold_with_map(int map_size,
    const OnigPairCaseFoldCodes map[],
    int ess_tsett_flag, OnigCaseFoldType flag,
    OnigApplyAllCaseFoldFunc f, void* arg)
{
  OnigCodePoint code;
  int i, r;

  r = onigenc_ascii_apply_all_case_fold(flag, f, arg, 0);
  if (r != 0) return r;

  for (i = 0; i < map_size; i++) {
    code = map[i].to;
    r = (*f)(map[i].from, &code, 1, arg);
    if (r != 0) return r;

    code = map[i].from;
    r = (*f)(map[i].to, &code, 1, arg);
    if (r != 0) return r;
  }

  if (ess_tsett_flag != 0)
    return ss_apply_all_case_fold(flag, f, arg);

  return 0;
}

Project: ruby
File: regcomp.c

copy_opt_anc_info(OptAncInfo* to, OptAncInfo* from)
{
  *to = *from;
}

Project: ruby
File: regenc.c

ss_apply_all_case_fold(OnigCaseFoldType flag ARG_UNUSED,
		       OnigApplyAllCaseFoldFunc f, void* arg)
{
  OnigCodePoint ss[] = { 0x73, 0x73 };

  return (*f)((OnigCodePoint )0xdf, ss, 2, arg);
}

Project: ruby
File: regcomp.c

get_char_length_tree(Node* node, regex_t* reg, int* len)
{
  return get_char_length_tree1(node, reg, len, 0);
}

Project: ruby
File: regparse.c

onig_name_to_group_numbers(regex_t* reg, const UChar* name,
			   const UChar* name_end, int** nums)
{
  NameEntry* e = name_find(reg, name, name_end);

  if (IS_NULL(e)) return ONIGERR_UNDEFINED_NAME_REFERENCE;

  switch (e->back_num) {
  case 0:
    *nums = 0;
    break;
  case 1:
    *nums = &(e->back_ref1);
    break;
  default:
    *nums = e->back_refs;
    break;
  }
  return e->back_num;
}

Project: ruby
File: regenc.c

onigenc_mb2_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
{
  UChar *p = buf;

  if ((code & 0xff00) != 0) {
    *p++ = (UChar )((code >>  8) & 0xff);
  }
  *p++ = (UChar )(code & 0xff);

#if 1
  if (enclen(enc, buf, p) != (p - buf))
    return ONIGERR_INVALID_CODE_POINT_VALUE;
#endif
  return (int )(p - buf);
}

Project: ruby
File: regcomp.c

distance_add(OnigDistance d1, OnigDistance d2)
{
  if (d1 == ONIG_INFINITE_DISTANCE || d2 == ONIG_INFINITE_DISTANCE)
    return ONIG_INFINITE_DISTANCE;
  else {
    if (d1 <= ONIG_INFINITE_DISTANCE - d2) return d1 + d2;
    else return ONIG_INFINITE_DISTANCE;
  }
}

Project: ruby
File: regexec.c

match_at(regex_t* reg, const UChar* str, const UChar* end,
#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
	 const UChar* right_range,
#endif
	 const UChar* sstart, UChar* sprev, OnigMatchArg* msa)
{
  static const UChar FinishCode[] = { OP_FINISH };

  int i, num_mem, pop_level;
  ptrdiff_t n, best_len;
  LengthType tlen, tlen2;
  MemNumType mem;
  RelAddrType addr;
  OnigOptionType option = reg->options;
  OnigEncoding encode = reg->enc;
  OnigCaseFoldType case_fold_flag = reg->case_fold_flag;
  UChar *s, *q, *sbegin;
  UChar *p = reg->p;
  UChar *pkeep;
  char *alloca_base;
  char *xmalloc_base = NULL;
  OnigStackType *stk_alloc, *stk_base, *stk, *stk_end;
  OnigStackType *stkp; /* used as any purpose. */
  OnigStackIndex si;
  OnigStackIndex *repeat_stk;
  OnigStackIndex *mem_start_stk, *mem_end_stk;
#ifdef USE_COMBINATION_EXPLOSION_CHECK
  int scv;
  unsigned char* state_check_buff = msa->state_check_buff;
  int num_comb_exp_check = reg->num_comb_exp_check;
#endif

#if USE_TOKEN_THREADED_VM
# define OP_OFFSET  1
# define VM_LOOP JUMP;
# define VM_LOOP_END
# define CASE(x) L_##x: sbegin = s; OPCODE_EXEC_HOOK;
# define DEFAULT L_DEFAULT:
# define NEXT sprev = sbegin; JUMP
# define JUMP goto *oplabels[*p++]

  static const void *oplabels[] = {
    &&L_OP_FINISH,               /* matching process terminator (no more alternative) */
    &&L_OP_END,                  /* pattern code terminator (success end) */

    &&L_OP_EXACT1,               /* single byte, N = 1 */
    &&L_OP_EXACT2,               /* single byte, N = 2 */
    &&L_OP_EXACT3,               /* single byte, N = 3 */
    &&L_OP_EXACT4,               /* single byte, N = 4 */
    &&L_OP_EXACT5,               /* single byte, N = 5 */
    &&L_OP_EXACTN,               /* single byte */
    &&L_OP_EXACTMB2N1,           /* mb-length = 2 N = 1 */
    &&L_OP_EXACTMB2N2,           /* mb-length = 2 N = 2 */
    &&L_OP_EXACTMB2N3,           /* mb-length = 2 N = 3 */
    &&L_OP_EXACTMB2N,            /* mb-length = 2 */
    &&L_OP_EXACTMB3N,            /* mb-length = 3 */
    &&L_OP_EXACTMBN,             /* other length */

    &&L_OP_EXACT1_IC,            /* single byte, N = 1, ignore case */
    &&L_OP_EXACTN_IC,            /* single byte,        ignore case */

    &&L_OP_CCLASS,
    &&L_OP_CCLASS_MB,
    &&L_OP_CCLASS_MIX,
    &&L_OP_CCLASS_NOT,
    &&L_OP_CCLASS_MB_NOT,
    &&L_OP_CCLASS_MIX_NOT,

    &&L_OP_ANYCHAR,                 /* "."  */
    &&L_OP_ANYCHAR_ML,              /* "."  multi-line */
    &&L_OP_ANYCHAR_STAR,            /* ".*" */
    &&L_OP_ANYCHAR_ML_STAR,         /* ".*" multi-line */
    &&L_OP_ANYCHAR_STAR_PEEK_NEXT,
    &&L_OP_ANYCHAR_ML_STAR_PEEK_NEXT,

    &&L_OP_WORD,
    &&L_OP_NOT_WORD,
    &&L_OP_WORD_BOUND,
    &&L_OP_NOT_WORD_BOUND,
# ifdef USE_WORD_BEGIN_END
    &&L_OP_WORD_BEGIN,
    &&L_OP_WORD_END,
# else
    &&L_DEFAULT,
    &&L_DEFAULT,
# endif
    &&L_OP_ASCII_WORD,
    &&L_OP_NOT_ASCII_WORD,
    &&L_OP_ASCII_WORD_BOUND,
    &&L_OP_NOT_ASCII_WORD_BOUND,
# ifdef USE_WORD_BEGIN_END
    &&L_OP_ASCII_WORD_BEGIN,
    &&L_OP_ASCII_WORD_END,
# else
    &&L_DEFAULT,
    &&L_DEFAULT,
# endif

    &&L_OP_BEGIN_BUF,
    &&L_OP_END_BUF,
    &&L_OP_BEGIN_LINE,
    &&L_OP_END_LINE,
    &&L_OP_SEMI_END_BUF,
    &&L_OP_BEGIN_POSITION,
    &&L_OP_BEGIN_POS_OR_LINE,    /* used for implicit anchor optimization */

    &&L_OP_BACKREF1,
    &&L_OP_BACKREF2,
    &&L_OP_BACKREFN,
    &&L_OP_BACKREFN_IC,
    &&L_OP_BACKREF_MULTI,
    &&L_OP_BACKREF_MULTI_IC,
# ifdef USE_BACKREF_WITH_LEVEL
    &&L_OP_BACKREF_WITH_LEVEL,   /* \k<xxx+n>, \k<xxx-n> */
# else
    &&L_DEFAULT,
# endif
    &&L_OP_MEMORY_START,
    &&L_OP_MEMORY_START_PUSH,    /* push back-tracker to stack */
    &&L_OP_MEMORY_END_PUSH,      /* push back-tracker to stack */
# ifdef USE_SUBEXP_CALL
    &&L_OP_MEMORY_END_PUSH_REC,  /* push back-tracker to stack */
# else
    &&L_DEFAULT,
# endif
    &&L_OP_MEMORY_END,
# ifdef USE_SUBEXP_CALL
    &&L_OP_MEMORY_END_REC,       /* push marker to stack */
# else
    &&L_DEFAULT,
# endif

    &&L_OP_KEEP,

    &&L_OP_FAIL,                 /* pop stack and move */
    &&L_OP_JUMP,
    &&L_OP_PUSH,
    &&L_OP_POP,
# ifdef USE_OP_PUSH_OR_JUMP_EXACT
    &&L_OP_PUSH_OR_JUMP_EXACT1,  /* if match exact then push, else jump. */
# else
    &&L_DEFAULT,
# endif
    &&L_OP_PUSH_IF_PEEK_NEXT,    /* if match exact then push, else none. */
    &&L_OP_REPEAT,               /* {n,m} */
    &&L_OP_REPEAT_NG,            /* {n,m}? (non greedy) */
    &&L_OP_REPEAT_INC,
    &&L_OP_REPEAT_INC_NG,        /* non greedy */
    &&L_OP_REPEAT_INC_SG,        /* search and get in stack */
    &&L_OP_REPEAT_INC_NG_SG,     /* search and get in stack (non greedy) */
    &&L_OP_NULL_CHECK_START,     /* null loop checker start */
    &&L_OP_NULL_CHECK_END,       /* null loop checker end   */
# ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
    &&L_OP_NULL_CHECK_END_MEMST, /* null loop checker end (with capture status) */
# else
    &&L_DEFAULT,
# endif
# ifdef USE_SUBEXP_CALL
    &&L_OP_NULL_CHECK_END_MEMST_PUSH, /* with capture status and push check-end */
# else
    &&L_DEFAULT,
# endif

    &&L_OP_PUSH_POS,             /* (?=...)  start */
    &&L_OP_POP_POS,              /* (?=...)  end   */
    &&L_OP_PUSH_POS_NOT,         /* (?!...)  start */
    &&L_OP_FAIL_POS,             /* (?!...)  end   */
    &&L_OP_PUSH_STOP_BT,         /* (?>...)  start */
    &&L_OP_POP_STOP_BT,          /* (?>...)  end   */
    &&L_OP_LOOK_BEHIND,          /* (?<=...) start (no needs end opcode) */
    &&L_OP_PUSH_LOOK_BEHIND_NOT, /* (?<!...) start */
    &&L_OP_FAIL_LOOK_BEHIND_NOT, /* (?<!...) end   */

# ifdef USE_SUBEXP_CALL
    &&L_OP_CALL,                 /* \g<name> */
    &&L_OP_RETURN,
# else
    &&L_DEFAULT,
    &&L_DEFAULT,
# endif
    &&L_OP_CONDITION,

# ifdef USE_COMBINATION_EXPLOSION_CHECK
    &&L_OP_STATE_CHECK_PUSH,         /* combination explosion check and push */
    &&L_OP_STATE_CHECK_PUSH_OR_JUMP, /* check ok -> push, else jump  */
    &&L_OP_STATE_CHECK,              /* check only */
# else
    &&L_DEFAULT,
    &&L_DEFAULT,
    &&L_DEFAULT,
# endif
# ifdef USE_COMBINATION_EXPLOSION_CHECK
    &&L_OP_STATE_CHECK_ANYCHAR_STAR,
    &&L_OP_STATE_CHECK_ANYCHAR_ML_STAR,
# else
    &&L_DEFAULT,
    &&L_DEFAULT,
# endif
    /* no need: IS_DYNAMIC_OPTION() == 0 */
# if 0   /* no need: IS_DYNAMIC_OPTION() == 0 */
    &&L_OP_SET_OPTION_PUSH,    /* set option and push recover option */
    &&L_OP_SET_OPTION          /* set option */
# else
    &&L_DEFAULT,
    &&L_DEFAULT
# endif
  };
#else /* USE_TOKEN_THREADED_VM */

# define OP_OFFSET  0
# define VM_LOOP                                \
  while (1) {                                   \
  OPCODE_EXEC_HOOK;                             \
  sbegin = s;                                   \
  switch (*p++) {
# define VM_LOOP_END } sprev = sbegin; }
# define CASE(x) case x:
# define DEFAULT default:
# define NEXT break
# define JUMP continue; break
#endif /* USE_TOKEN_THREADED_VM */


#ifdef USE_SUBEXP_CALL
/* Stack #0 is used to store the pattern itself and used for (?R), \g<0>,
   etc. Additional space is required. */
# define ADD_NUMMEM 1
#else
/* Stack #0 not is used. */
# define ADD_NUMMEM 0
#endif

  n = reg->num_repeat + (reg->num_mem + ADD_NUMMEM) * 2;

  STACK_INIT(alloca_base, xmalloc_base, n, INIT_MATCH_STACK_SIZE);
  pop_level = reg->stack_pop_level;
  num_mem = reg->num_mem;
  repeat_stk = (OnigStackIndex* )alloca_base;

  mem_start_stk = (OnigStackIndex* )(repeat_stk + reg->num_repeat);
  mem_end_stk   = mem_start_stk + (num_mem + ADD_NUMMEM);
  {
    OnigStackIndex *pp = mem_start_stk;
    for (; pp < repeat_stk + n; pp += 2) {
      pp[0] = INVALID_STACK_INDEX;
      pp[1] = INVALID_STACK_INDEX;
    }
  }
#ifndef USE_SUBEXP_CALL
  mem_start_stk--; /* for index start from 1,
		      mem_start_stk[1]..mem_start_stk[num_mem] */
  mem_end_stk--;   /* for index start from 1,
		      mem_end_stk[1]..mem_end_stk[num_mem] */
#endif

#ifdef ONIG_DEBUG_MATCH
  fprintf(stderr, "match_at: str: %"PRIdPTR" (%p), end: %"PRIdPTR" (%p), start: %"PRIdPTR" (%p), sprev: %"PRIdPTR" (%p)\n",
	  (intptr_t )str, str, (intptr_t )end, end, (intptr_t )sstart, sstart, (intptr_t )sprev, sprev);
  fprintf(stderr, "size: %d, start offset: %d\n",
	  (int )(end - str), (int )(sstart - str));
  fprintf(stderr, "\n ofs> str                   stk:type   addr:opcode\n");
#endif

  STACK_PUSH_ENSURED(STK_ALT, (UChar* )FinishCode);  /* bottom stack */
  best_len = ONIG_MISMATCH;
  s = (UChar* )sstart;
  pkeep = (UChar* )sstart;


#ifdef ONIG_DEBUG_MATCH
# define OPCODE_EXEC_HOOK                                               \
    if (s) {                                                            \
      UChar *op, *q, *bp, buf[50];                                      \
      int len;                                                          \
      op = p - OP_OFFSET;                                               \
      fprintf(stderr, "%4"PRIdPTR"> \"", (*op == OP_FINISH) ? (ptrdiff_t )-1 : s - str); \
      bp = buf;                                                         \
      q = s;                                                            \
      if (*op != OP_FINISH) {    /* s may not be a valid pointer if OP_FINISH. */ \
	for (i = 0; i < 7 && q < end; i++) {                            \
	  len = enclen(encode, q, end);                                 \
	  while (len-- > 0) *bp++ = *q++;                               \
	}                                                               \
        if (q < end) { xmemcpy(bp, "...", 3); bp += 3; }                \
      }                                                                 \
      xmemcpy(bp, "\"", 1); bp += 1;                                    \
      *bp = 0;                                                          \
      fputs((char* )buf, stderr);                                       \
      for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);         \
      fprintf(stderr, "%4"PRIdPTR":%s %4"PRIdPTR":",                    \
	  stk - stk_base - 1,                                           \
	  (stk > stk_base) ? stack_type_str(stk[-1].type) : "      ",   \
	  (op == FinishCode) ? (ptrdiff_t )-1 : op - reg->p);           \
      onig_print_compiled_byte_code(stderr, op, reg->p+reg->used, NULL, encode); \
      fprintf(stderr, "\n");                                            \
    }
#else
# define OPCODE_EXEC_HOOK ((void) 0)
#endif


  VM_LOOP {
    CASE(OP_END)  MOP_IN(OP_END);
      n = s - sstart;
      if (n > best_len) {
	OnigRegion* region;
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
	if (IS_FIND_LONGEST(option)) {
	  if (n > msa->best_len) {
	    msa->best_len = n;
	    msa->best_s   = (UChar* )sstart;
	  }
	  else
	    goto end_best_len;
	}
#endif
	best_len = n;
	region = msa->region;
	if (region) {
	  region->beg[0] = ((pkeep > s) ? s : pkeep) - str;
	  region->end[0] = s - str;
	  for (i = 1; i <= num_mem; i++) {
	    if (mem_end_stk[i] != INVALID_STACK_INDEX) {
	      if (BIT_STATUS_AT(reg->bt_mem_start, i))
		region->beg[i] = STACK_AT(mem_start_stk[i])->u.mem.pstr - str;
	      else
		region->beg[i] = (UChar* )((void* )mem_start_stk[i]) - str;

	      region->end[i] = (BIT_STATUS_AT(reg->bt_mem_end, i)
				? STACK_AT(mem_end_stk[i])->u.mem.pstr
				: (UChar* )((void* )mem_end_stk[i])) - str;
	    }
	    else {
	      region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
	    }
	  }

#ifdef USE_CAPTURE_HISTORY
	  if (reg->capture_history != 0) {
	    int r;
	    OnigCaptureTreeNode* node;

	    if (IS_NULL(region->history_root)) {
	      region->history_root = node = history_node_new();
	      CHECK_NULL_RETURN_MEMERR(node);
	    }
	    else {
	      node = region->history_root;
	      history_tree_clear(node);
	    }

	    node->group = 0;
	    node->beg   = ((pkeep > s) ? s : pkeep) - str;
	    node->end   = s - str;

	    stkp = stk_base;
	    r = make_capture_history_tree(region->history_root, &stkp,
		stk, (UChar* )str, reg);
	    if (r < 0) {
	      best_len = r; /* error code */
	      goto finish;
	    }
	  }
#endif /* USE_CAPTURE_HISTORY */
	} /* if (region) */
      } /* n > best_len */

#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
    end_best_len:
#endif
      MOP_OUT;

      if (IS_FIND_CONDITION(option)) {
	if (IS_FIND_NOT_EMPTY(option) && s == sstart) {
	  best_len = ONIG_MISMATCH;
	  goto fail; /* for retry */
	}
	if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {
	  goto fail; /* for retry */
	}
      }

      /* default behavior: return first-matching result. */
      goto finish;
      NEXT;

    CASE(OP_EXACT1)  MOP_IN(OP_EXACT1);
#if 0
      DATA_ENSURE(1);
      if (*p != *s) goto fail;
      p++; s++;
#endif
      if (*p != *s++) goto fail;
      DATA_ENSURE(0);
      p++;
      MOP_OUT;
      NEXT;

    CASE(OP_EXACT1_IC)  MOP_IN(OP_EXACT1_IC);
      {
	int len;
	UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];

	DATA_ENSURE(1);
	len = ONIGENC_MBC_CASE_FOLD(encode,
		    /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
		    case_fold_flag,
		    &s, end, lowbuf);
	DATA_ENSURE(0);
	q = lowbuf;
	while (len-- > 0) {
	  if (*p != *q) {
	    goto fail;
	  }
	  p++; q++;
	}
      }
      MOP_OUT;
      NEXT;

    CASE(OP_EXACT2)  MOP_IN(OP_EXACT2);
      DATA_ENSURE(2);
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      sprev = s;
      p++; s++;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACT3)  MOP_IN(OP_EXACT3);
      DATA_ENSURE(3);
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      sprev = s;
      p++; s++;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACT4)  MOP_IN(OP_EXACT4);
      DATA_ENSURE(4);
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      sprev = s;
      p++; s++;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACT5)  MOP_IN(OP_EXACT5);
      DATA_ENSURE(5);
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      sprev = s;
      p++; s++;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACTN)  MOP_IN(OP_EXACTN);
      GET_LENGTH_INC(tlen, p);
      DATA_ENSURE(tlen);
      while (tlen-- > 0) {
	if (*p++ != *s++) goto fail;
      }
      sprev = s - 1;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACTN_IC)  MOP_IN(OP_EXACTN_IC);
      {
	int len;
	UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];

	GET_LENGTH_INC(tlen, p);
	endp = p + tlen;

	while (p < endp) {
	  sprev = s;
	  DATA_ENSURE(1);
	  len = ONIGENC_MBC_CASE_FOLD(encode,
		      /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
		      case_fold_flag,
		      &s, end, lowbuf);
	  DATA_ENSURE(0);
	  q = lowbuf;
	  while (len-- > 0) {
	    if (*p != *q) goto fail;
	    p++; q++;
	  }
	}
      }

      MOP_OUT;
      JUMP;

    CASE(OP_EXACTMB2N1)  MOP_IN(OP_EXACTMB2N1);
      DATA_ENSURE(2);
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      MOP_OUT;
      NEXT;

    CASE(OP_EXACTMB2N2)  MOP_IN(OP_EXACTMB2N2);
      DATA_ENSURE(4);
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      sprev = s;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACTMB2N3)  MOP_IN(OP_EXACTMB2N3);
      DATA_ENSURE(6);
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      sprev = s;
      if (*p != *s) goto fail;
      p++; s++;
      if (*p != *s) goto fail;
      p++; s++;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACTMB2N)  MOP_IN(OP_EXACTMB2N);
      GET_LENGTH_INC(tlen, p);
      DATA_ENSURE(tlen * 2);
      while (tlen-- > 0) {
	if (*p != *s) goto fail;
	p++; s++;
	if (*p != *s) goto fail;
	p++; s++;
      }
      sprev = s - 2;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACTMB3N)  MOP_IN(OP_EXACTMB3N);
      GET_LENGTH_INC(tlen, p);
      DATA_ENSURE(tlen * 3);
      while (tlen-- > 0) {
	if (*p != *s) goto fail;
	p++; s++;
	if (*p != *s) goto fail;
	p++; s++;
	if (*p != *s) goto fail;
	p++; s++;
      }
      sprev = s - 3;
      MOP_OUT;
      JUMP;

    CASE(OP_EXACTMBN)  MOP_IN(OP_EXACTMBN);
      GET_LENGTH_INC(tlen,  p);  /* mb-len */
      GET_LENGTH_INC(tlen2, p);  /* string len */
      tlen2 *= tlen;
      DATA_ENSURE(tlen2);
      while (tlen2-- > 0) {
	if (*p != *s) goto fail;
	p++; s++;
      }
      sprev = s - tlen;
      MOP_OUT;
      JUMP;

    CASE(OP_CCLASS)  MOP_IN(OP_CCLASS);
      DATA_ENSURE(1);
      if (BITSET_AT(((BitSetRef )p), *s) == 0) goto fail;
      p += SIZE_BITSET;
      s += enclen(encode, s, end);   /* OP_CCLASS can match mb-code. \D, \S */
      MOP_OUT;
      NEXT;

    CASE(OP_CCLASS_MB)  MOP_IN(OP_CCLASS_MB);
      if (! ONIGENC_IS_MBC_HEAD(encode, s, end)) goto fail;

    cclass_mb:
      GET_LENGTH_INC(tlen, p);
      {
	OnigCodePoint code;
	UChar *ss;
	int mb_len;

	DATA_ENSURE(1);
	mb_len = enclen(encode, s, end);
	DATA_ENSURE(mb_len);
	ss = s;
	s += mb_len;
	code = ONIGENC_MBC_TO_CODE(encode, ss, s);

#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
	if (! onig_is_in_code_range(p, code)) goto fail;
#else
	q = p;
	ALIGNMENT_RIGHT(q);
	if (! onig_is_in_code_range(q, code)) goto fail;
#endif
      }
      p += tlen;
      MOP_OUT;
      NEXT;

    CASE(OP_CCLASS_MIX)  MOP_IN(OP_CCLASS_MIX);
      DATA_ENSURE(1);
      if (ONIGENC_IS_MBC_HEAD(encode, s, end)) {
	p += SIZE_BITSET;
	goto cclass_mb;
      }
      else {
	if (BITSET_AT(((BitSetRef )p), *s) == 0)
	  goto fail;

	p += SIZE_BITSET;
	GET_LENGTH_INC(tlen, p);
	p += tlen;
	s++;
      }
      MOP_OUT;
      NEXT;

    CASE(OP_CCLASS_NOT)  MOP_IN(OP_CCLASS_NOT);
      DATA_ENSURE(1);
      if (BITSET_AT(((BitSetRef )p), *s) != 0) goto fail;
      p += SIZE_BITSET;
      s += enclen(encode, s, end);
      MOP_OUT;
      NEXT;

    CASE(OP_CCLASS_MB_NOT)  MOP_IN(OP_CCLASS_MB_NOT);
      DATA_ENSURE(1);
      if (! ONIGENC_IS_MBC_HEAD(encode, s, end)) {
	s++;
	GET_LENGTH_INC(tlen, p);
	p += tlen;
	goto cc_mb_not_success;
      }

    cclass_mb_not:
      GET_LENGTH_INC(tlen, p);
      {
	OnigCodePoint code;
	UChar *ss;
	int mb_len = enclen(encode, s, end);

	if (! DATA_ENSURE_CHECK(mb_len)) {
	  DATA_ENSURE(1);
	  s = (UChar* )end;
	  p += tlen;
	  goto cc_mb_not_success;
	}

	ss = s;
	s += mb_len;
	code = ONIGENC_MBC_TO_CODE(encode, ss, s);

#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
	if (onig_is_in_code_range(p, code)) goto fail;
#else
	q = p;
	ALIGNMENT_RIGHT(q);
	if (onig_is_in_code_range(q, code)) goto fail;
#endif
      }
      p += tlen;

    cc_mb_not_success:
      MOP_OUT;
      NEXT;

    CASE(OP_CCLASS_MIX_NOT)  MOP_IN(OP_CCLASS_MIX_NOT);
      DATA_ENSURE(1);
      if (ONIGENC_IS_MBC_HEAD(encode, s, end)) {
	p += SIZE_BITSET;
	goto cclass_mb_not;
      }
      else {
	if (BITSET_AT(((BitSetRef )p), *s) != 0)
	  goto fail;

	p += SIZE_BITSET;
	GET_LENGTH_INC(tlen, p);
	p += tlen;
	s++;
      }
      MOP_OUT;
      NEXT;

    CASE(OP_ANYCHAR)  MOP_IN(OP_ANYCHAR);
      DATA_ENSURE(1);
      n = enclen(encode, s, end);
      DATA_ENSURE(n);
      if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0)) goto fail;
      s += n;
      MOP_OUT;
      NEXT;

    CASE(OP_ANYCHAR_ML)  MOP_IN(OP_ANYCHAR_ML);
      DATA_ENSURE(1);
      n = enclen(encode, s, end);
      DATA_ENSURE(n);
      s += n;
      MOP_OUT;
      NEXT;

    CASE(OP_ANYCHAR_STAR)  MOP_IN(OP_ANYCHAR_STAR);
      while (DATA_ENSURE_CHECK1) {
	STACK_PUSH_ALT(p, s, sprev, pkeep);
	n = enclen(encode, s, end);
	DATA_ENSURE(n);
	if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))  goto fail;
	sprev = s;
	s += n;
      }
      MOP_OUT;
      NEXT;

    CASE(OP_ANYCHAR_ML_STAR)  MOP_IN(OP_ANYCHAR_ML_STAR);
      while (DATA_ENSURE_CHECK1) {
	STACK_PUSH_ALT(p, s, sprev, pkeep);
	n = enclen(encode, s, end);
	if (n > 1) {
	  DATA_ENSURE(n);
	  sprev = s;
	  s += n;
	}
	else {
	  sprev = s;
	  s++;
	}
      }
      MOP_OUT;
      NEXT;

    CASE(OP_ANYCHAR_STAR_PEEK_NEXT)  MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
      while (DATA_ENSURE_CHECK1) {
	if (*p == *s) {
	  STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
	}
	n = enclen(encode, s, end);
	DATA_ENSURE(n);
	if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))  goto fail;
	sprev = s;
	s += n;
      }
      p++;
      MOP_OUT;
      NEXT;

    CASE(OP_ANYCHAR_ML_STAR_PEEK_NEXT)MOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
      while (DATA_ENSURE_CHECK1) {
	if (*p == *s) {
	  STACK_PUSH_ALT(p + 1, s, sprev, pkeep);
	}
	n = enclen(encode, s, end);
	if (n > 1) {
	  DATA_ENSURE(n);
	  sprev = s;
	  s += n;
	}
	else {
	  sprev = s;
	  s++;
	}
      }
      p++;
      MOP_OUT;
      NEXT;

#ifdef USE_COMBINATION_EXPLOSION_CHECK
    CASE(OP_STATE_CHECK_ANYCHAR_STAR)  MOP_IN(OP_STATE_CHECK_ANYCHAR_STAR);
      GET_STATE_CHECK_NUM_INC(mem, p);
      while (DATA_ENSURE_CHECK1) {
	STATE_CHECK_VAL(scv, mem);
	if (scv) goto fail;

	STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
	n = enclen(encode, s, end);
	DATA_ENSURE(n);
	if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 0))  goto fail;
	sprev = s;
	s += n;
      }
      MOP_OUT;
      NEXT;

    CASE(OP_STATE_CHECK_ANYCHAR_ML_STAR)
      MOP_IN(OP_STATE_CHECK_ANYCHAR_ML_STAR);

      GET_STATE_CHECK_NUM_INC(mem, p);
      while (DATA_ENSURE_CHECK1) {
	STATE_CHECK_VAL(scv, mem);
	if (scv) goto fail;

	STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem, pkeep);
	n = enclen(encode, s, end);
	if (n > 1) {
	  DATA_ENSURE(n);
	  sprev = s;
	  s += n;
	}
	else {
	  sprev = s;
	  s++;
	}
      }
      MOP_OUT;
      NEXT;
#endif /* USE_COMBINATION_EXPLOSION_CHECK */

    CASE(OP_WORD)  MOP_IN(OP_WORD);
      DATA_ENSURE(1);
      if (! ONIGENC_IS_MBC_WORD(encode, s, end))
	goto fail;

      s += enclen(encode, s, end);
      MOP_OUT;
      NEXT;

    CASE(OP_ASCII_WORD)  MOP_IN(OP_ASCII_WORD);
      DATA_ENSURE(1);
      if (! ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
	goto fail;

      s += enclen(encode, s, end);
      MOP_OUT;
      NEXT;

    CASE(OP_NOT_WORD)  MOP_IN(OP_NOT_WORD);
      DATA_ENSURE(1);
      if (ONIGENC_IS_MBC_WORD(encode, s, end))
	goto fail;

      s += enclen(encode, s, end);
      MOP_OUT;
      NEXT;

    CASE(OP_NOT_ASCII_WORD)  MOP_IN(OP_NOT_ASCII_WORD);
      DATA_ENSURE(1);
      if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
	goto fail;

      s += enclen(encode, s, end);
      MOP_OUT;
      NEXT;

    CASE(OP_WORD_BOUND)  MOP_IN(OP_WORD_BOUND);
      if (ON_STR_BEGIN(s)) {
	DATA_ENSURE(1);
	if (! ONIGENC_IS_MBC_WORD(encode, s, end))
	  goto fail;
      }
      else if (ON_STR_END(s)) {
	if (! ONIGENC_IS_MBC_WORD(encode, sprev, end))
	  goto fail;
      }
      else {
	if (ONIGENC_IS_MBC_WORD(encode, s, end)
	    == ONIGENC_IS_MBC_WORD(encode, sprev, end))
	  goto fail;
      }
      MOP_OUT;
      JUMP;

    CASE(OP_ASCII_WORD_BOUND)  MOP_IN(OP_ASCII_WORD_BOUND);
      if (ON_STR_BEGIN(s)) {
	DATA_ENSURE(1);
	if (! ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
	  goto fail;
      }
      else if (ON_STR_END(s)) {
	if (! ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
	  goto fail;
      }
      else {
	if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)
	    == ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
	  goto fail;
      }
      MOP_OUT;
      JUMP;

    CASE(OP_NOT_WORD_BOUND)  MOP_IN(OP_NOT_WORD_BOUND);
      if (ON_STR_BEGIN(s)) {
	if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end))
	  goto fail;
      }
      else if (ON_STR_END(s)) {
	if (ONIGENC_IS_MBC_WORD(encode, sprev, end))
	  goto fail;
      }
      else {
	if (ONIGENC_IS_MBC_WORD(encode, s, end)
	    != ONIGENC_IS_MBC_WORD(encode, sprev, end))
	  goto fail;
      }
      MOP_OUT;
      JUMP;

    CASE(OP_NOT_ASCII_WORD_BOUND)  MOP_IN(OP_NOT_ASCII_WORD_BOUND);
      if (ON_STR_BEGIN(s)) {
	if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_ASCII_WORD(encode, s, end))
	  goto fail;
      }
      else if (ON_STR_END(s)) {
	if (ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
	  goto fail;
      }
      else {
	if (ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)
	    != ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end))
	  goto fail;
      }
      MOP_OUT;
      JUMP;

#ifdef USE_WORD_BEGIN_END
    CASE(OP_WORD_BEGIN)  MOP_IN(OP_WORD_BEGIN);
      if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end)) {
	if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
	  MOP_OUT;
	  JUMP;
	}
      }
      goto fail;
      NEXT;

    CASE(OP_ASCII_WORD_BEGIN)  MOP_IN(OP_ASCII_WORD_BEGIN);
      if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)) {
	if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end)) {
	  MOP_OUT;
	  JUMP;
	}
      }
      goto fail;
      NEXT;

    CASE(OP_WORD_END)  MOP_IN(OP_WORD_END);
      if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
	if (ON_STR_END(s) || !ONIGENC_IS_MBC_WORD(encode, s, end)) {
	  MOP_OUT;
	  JUMP;
	}
      }
      goto fail;
      NEXT;

    CASE(OP_ASCII_WORD_END)  MOP_IN(OP_ASCII_WORD_END);
      if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_ASCII_WORD(encode, sprev, end)) {
	if (ON_STR_END(s) || !ONIGENC_IS_MBC_ASCII_WORD(encode, s, end)) {
	  MOP_OUT;
	  JUMP;
	}
      }
      goto fail;
      NEXT;
#endif

    CASE(OP_BEGIN_BUF)  MOP_IN(OP_BEGIN_BUF);
      if (! ON_STR_BEGIN(s)) goto fail;
      if (IS_NOTBOS(msa->options)) goto fail;

      MOP_OUT;
      JUMP;

    CASE(OP_END_BUF)  MOP_IN(OP_END_BUF);
      if (! ON_STR_END(s)) goto fail;
      if (IS_NOTEOS(msa->options)) goto fail;

      MOP_OUT;
      JUMP;

    CASE(OP_BEGIN_LINE)  MOP_IN(OP_BEGIN_LINE);
    op_begin_line:
      if (ON_STR_BEGIN(s)) {
	if (IS_NOTBOL(msa->options)) goto fail;
	MOP_OUT;
	JUMP;
      }
      else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)
#ifdef USE_CRNL_AS_LINE_TERMINATOR
		&& !(IS_NEWLINE_CRLF(option)
		     && ONIGENC_IS_MBC_CRNL(encode, sprev, end))
#endif
		&& !ON_STR_END(s)) {
	MOP_OUT;
	JUMP;
      }
      goto fail;
      NEXT;

    CASE(OP_END_LINE)  MOP_IN(OP_END_LINE);
      if (ON_STR_END(s)) {
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
	if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE_EX(encode, sprev, str, end, option, 1)) {
#endif
	  if (IS_NOTEOL(msa->options)) goto fail;
	  MOP_OUT;
	  JUMP;
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
	}
#endif
      }
      else if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 1)) {
	MOP_OUT;
	JUMP;
      }
      goto fail;
      NEXT;

    CASE(OP_SEMI_END_BUF)  MOP_IN(OP_SEMI_END_BUF);
      if (ON_STR_END(s)) {
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
	if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE_EX(encode, sprev, str, end, option, 1)) {
#endif
	  if (IS_NOTEOL(msa->options)) goto fail;
	  MOP_OUT;
	  JUMP;
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
	}
#endif
      }
      else if (ONIGENC_IS_MBC_NEWLINE_EX(encode, s, str, end, option, 1)) {
	UChar* ss = s + enclen(encode, s, end);
	if (ON_STR_END(ss)) {
	  MOP_OUT;
	  JUMP;
	}
#ifdef USE_CRNL_AS_LINE_TERMINATOR
	else if (IS_NEWLINE_CRLF(option)
	    && ONIGENC_IS_MBC_CRNL(encode, s, end)) {
	  ss += enclen(encode, ss, end);
	  if (ON_STR_END(ss)) {
	    MOP_OUT;
	    JUMP;
	  }
	}
#endif
      }
      goto fail;
      NEXT;

    CASE(OP_BEGIN_POSITION)  MOP_IN(OP_BEGIN_POSITION);
      if (s != msa->gpos)
	goto fail;

      MOP_OUT;
      JUMP;

    CASE(OP_BEGIN_POS_OR_LINE)  MOP_IN(OP_BEGIN_POS_OR_LINE);
      if (s != msa->gpos)
	goto op_begin_line;

      MOP_OUT;
      JUMP;

    CASE(OP_MEMORY_START_PUSH)  MOP_IN(OP_MEMORY_START_PUSH);
      GET_MEMNUM_INC(mem, p);
      STACK_PUSH_MEM_START(mem, s);
      MOP_OUT;
      JUMP;

    CASE(OP_MEMORY_START)  MOP_IN(OP_MEMORY_START);
      GET_MEMNUM_INC(mem, p);
      mem_start_stk[mem] = (OnigStackIndex )((void* )s);
      MOP_OUT;
      JUMP;

    CASE(OP_MEMORY_END_PUSH)  MOP_IN(OP_MEMORY_END_PUSH);
      GET_MEMNUM_INC(mem, p);
      STACK_PUSH_MEM_END(mem, s);
      MOP_OUT;
      JUMP;

    CASE(OP_MEMORY_END)  MOP_IN(OP_MEMORY_END);
      GET_MEMNUM_INC(mem, p);
      mem_end_stk[mem] = (OnigStackIndex )((void* )s);
      MOP_OUT;
      JUMP;

    CASE(OP_KEEP)  MOP_IN(OP_KEEP);
      pkeep = s;
      MOP_OUT;
      JUMP;

#ifdef USE_SUBEXP_CALL
    CASE(OP_MEMORY_END_PUSH_REC)  MOP_IN(OP_MEMORY_END_PUSH_REC);
      GET_MEMNUM_INC(mem, p);
      STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */
      STACK_PUSH_MEM_END(mem, s);
      mem_start_stk[mem] = GET_STACK_INDEX(stkp);
      MOP_OUT;
      JUMP;

    CASE(OP_MEMORY_END_REC)  MOP_IN(OP_MEMORY_END_REC);
      GET_MEMNUM_INC(mem, p);
      mem_end_stk[mem] = (OnigStackIndex )((void* )s);
      STACK_GET_MEM_START(mem, stkp);

      if (BIT_STATUS_AT(reg->bt_mem_start, mem))
	mem_start_stk[mem] = GET_STACK_INDEX(stkp);
      else
	mem_start_stk[mem] = (OnigStackIndex )((void* )stkp->u.mem.pstr);

      STACK_PUSH_MEM_END_MARK(mem);
      MOP_OUT;
      JUMP;
#endif

    CASE(OP_BACKREF1)  MOP_IN(OP_BACKREF1);
      mem = 1;
      goto backref;
      NEXT;

    CASE(OP_BACKREF2)  MOP_IN(OP_BACKREF2);
      mem = 2;
      goto backref;
      NEXT;

    CASE(OP_BACKREFN)  MOP_IN(OP_BACKREFN);
      GET_MEMNUM_INC(mem, p);
    backref:
      {
	int len;
	UChar *pstart, *pend;

	/* if you want to remove following line,
	   you should check in parse and compile time. */
	if (mem > num_mem) goto fail;
	if (mem_end_stk[mem]   == INVALID_STACK_INDEX) goto fail;
	if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;

	if (BIT_STATUS_AT(reg->bt_mem_start, mem))
	  pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
	else
	  pstart = (UChar* )((void* )mem_start_stk[mem]);

	pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
		? STACK_AT(mem_end_stk[mem])->u.mem.pstr
		: (UChar* )((void* )mem_end_stk[mem]));
	n = pend - pstart;
	DATA_ENSURE(n);
	sprev = s;
	STRING_CMP(pstart, s, n);
	while (sprev + (len = enclen(encode, sprev, end)) < s)
	  sprev += len;

	MOP_OUT;
	JUMP;
      }

    CASE(OP_BACKREFN_IC)  MOP_IN(OP_BACKREFN_IC);
      GET_MEMNUM_INC(mem, p);
      {
	int len;
	UChar *pstart, *pend;

	/* if you want to remove following line,
	   you should check in parse and compile time. */
	if (mem > num_mem) goto fail;
	if (mem_end_stk[mem]   == INVALID_STACK_INDEX) goto fail;
	if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;

	if (BIT_STATUS_AT(reg->bt_mem_start, mem))
	  pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
	else
	  pstart = (UChar* )((void* )mem_start_stk[mem]);

	pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
		? STACK_AT(mem_end_stk[mem])->u.mem.pstr
		: (UChar* )((void* )mem_end_stk[mem]));
	n = pend - pstart;
	DATA_ENSURE(n);
	sprev = s;
	STRING_CMP_IC(case_fold_flag, pstart, &s, (int)n, end);
	while (sprev + (len = enclen(encode, sprev, end)) < s)
	  sprev += len;

	MOP_OUT;
	JUMP;
      }
      NEXT;

    CASE(OP_BACKREF_MULTI)  MOP_IN(OP_BACKREF_MULTI);
      {
	int len, is_fail;
	UChar *pstart, *pend, *swork;

	GET_LENGTH_INC(tlen, p);
	for (i = 0; i < tlen; i++) {
	  GET_MEMNUM_INC(mem, p);

	  if (mem_end_stk[mem]   == INVALID_STACK_INDEX) continue;
	  if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;

	  if (BIT_STATUS_AT(reg->bt_mem_start, mem))
	    pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
	  else
	    pstart = (UChar* )((void* )mem_start_stk[mem]);

	  pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
		  ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
		  : (UChar* )((void* )mem_end_stk[mem]));
	  n = pend - pstart;
	  DATA_ENSURE(n);
	  sprev = s;
	  swork = s;
	  STRING_CMP_VALUE(pstart, swork, n, is_fail);
	  if (is_fail) continue;
	  s = swork;
	  while (sprev + (len = enclen(encode, sprev, end)) < s)
	    sprev += len;

	  p += (SIZE_MEMNUM * (tlen - i - 1));
	  break; /* success */
	}
	if (i == tlen) goto fail;
	MOP_OUT;
	JUMP;
      }
      NEXT;

    CASE(OP_BACKREF_MULTI_IC)  MOP_IN(OP_BACKREF_MULTI_IC);
      {
	int len, is_fail;
	UChar *pstart, *pend, *swork;

	GET_LENGTH_INC(tlen, p);
	for (i = 0; i < tlen; i++) {
	  GET_MEMNUM_INC(mem, p);

	  if (mem_end_stk[mem]   == INVALID_STACK_INDEX) continue;
	  if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;

	  if (BIT_STATUS_AT(reg->bt_mem_start, mem))
	    pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
	  else
	    pstart = (UChar* )((void* )mem_start_stk[mem]);

	  pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
		  ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
		  : (UChar* )((void* )mem_end_stk[mem]));
	  n = pend - pstart;
	  DATA_ENSURE(n);
	  sprev = s;
	  swork = s;
	  STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, end, is_fail);
	  if (is_fail) continue;
	  s = swork;
	  while (sprev + (len = enclen(encode, sprev, end)) < s)
	    sprev += len;

	  p += (SIZE_MEMNUM * (tlen - i - 1));
	  break; /* success */
	}
	if (i == tlen) goto fail;
	MOP_OUT;
	JUMP;
      }

#ifdef USE_BACKREF_WITH_LEVEL
    CASE(OP_BACKREF_WITH_LEVEL)
      {
	int len;
	OnigOptionType ic;
	LengthType level;

	GET_OPTION_INC(ic,    p);
	GET_LENGTH_INC(level, p);
	GET_LENGTH_INC(tlen,  p);

	sprev = s;
	if (backref_match_at_nested_level(reg, stk, stk_base, ic,
		  case_fold_flag, (int )level, (int )tlen, p, &s, end)) {
	  while (sprev + (len = enclen(encode, sprev, end)) < s)
	    sprev += len;

	  p += (SIZE_MEMNUM * tlen);
	}
	else
	  goto fail;

	MOP_OUT;
	JUMP;
      }

#endif

#if 0   /* no need: IS_DYNAMIC_OPTION() == 0 */
    CASE(OP_SET_OPTION_PUSH)  MOP_IN(OP_SET_OPTION_PUSH);
      GET_OPTION_INC(option, p);
      STACK_PUSH_ALT(p, s, sprev, pkeep);
      p += SIZE_OP_SET_OPTION + SIZE_OP_FAIL;
      MOP_OUT;
      JUMP;

    CASE(OP_SET_OPTION)  MOP_IN(OP_SET_OPTION);
      GET_OPTION_INC(option, p);
      MOP_OUT;
      JUMP;
#endif

    CASE(OP_NULL_CHECK_START)  MOP_IN(OP_NULL_CHECK_START);
      GET_MEMNUM_INC(mem, p);    /* mem: null check id */
      STACK_PUSH_NULL_CHECK_START(mem, s);
      MOP_OUT;
      JUMP;

    CASE(OP_NULL_CHECK_END)  MOP_IN(OP_NULL_CHECK_END);
      {
	int isnull;

	GET_MEMNUM_INC(mem, p); /* mem: null check id */
	STACK_NULL_CHECK(isnull, mem, s);
	if (isnull) {
#ifdef ONIG_DEBUG_MATCH
	  fprintf(stderr, "NULL_CHECK_END: skip  id:%d, s:%"PRIdPTR" (%p)\n",
		  (int )mem, (intptr_t )s, s);
#endif
	null_check_found:
	  /* empty loop founded, skip next instruction */
	  switch (*p++) {
	  case OP_JUMP:
	  case OP_PUSH:
	    p += SIZE_RELADDR;
	    break;
	  case OP_REPEAT_INC:
	  case OP_REPEAT_INC_NG:
	  case OP_REPEAT_INC_SG:
	  case OP_REPEAT_INC_NG_SG:
	    p += SIZE_MEMNUM;
	    break;
	  default:
	    goto unexpected_bytecode_error;
	    break;
	  }
	}
      }
      MOP_OUT;
      JUMP;

#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
    CASE(OP_NULL_CHECK_END_MEMST)  MOP_IN(OP_NULL_CHECK_END_MEMST);
      {
	int isnull;

	GET_MEMNUM_INC(mem, p); /* mem: null check id */
	STACK_NULL_CHECK_MEMST(isnull, mem, s, reg);
	if (isnull) {
# ifdef ONIG_DEBUG_MATCH
	  fprintf(stderr, "NULL_CHECK_END_MEMST: skip  id:%d, s:%"PRIdPTR" (%p)\n",
		  (int )mem, (intptr_t )s, s);
# endif
	  if (isnull == -1) goto fail;
	  goto null_check_found;
	}
      }
      MOP_OUT;
      JUMP;
#endif

#ifdef USE_SUBEXP_CALL
    CASE(OP_NULL_CHECK_END_MEMST_PUSH)
      MOP_IN(OP_NULL_CHECK_END_MEMST_PUSH);
      {
	int isnull;

	GET_MEMNUM_INC(mem, p); /* mem: null check id */
# ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
	STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);
# else
	STACK_NULL_CHECK_REC(isnull, mem, s);
# endif
	if (isnull) {
# ifdef ONIG_DEBUG_MATCH
	  fprintf(stderr, "NULL_CHECK_END_MEMST_PUSH: skip  id:%d, s:%"PRIdPTR" (%p)\n",
		  (int )mem, (intptr_t )s, s);
# endif
	  if (isnull == -1) goto fail;
	  goto null_check_found;
	}
	else {
	  STACK_PUSH_NULL_CHECK_END(mem);
	}
      }
      MOP_OUT;
      JUMP;
#endif

    CASE(OP_JUMP)  MOP_IN(OP_JUMP);
      GET_RELADDR_INC(addr, p);
      p += addr;
      MOP_OUT;
      CHECK_INTERRUPT_IN_MATCH_AT;
      JUMP;

    CASE(OP_PUSH)  MOP_IN(OP_PUSH);
      GET_RELADDR_INC(addr, p);
      STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
      MOP_OUT;
      JUMP;

#ifdef USE_COMBINATION_EXPLOSION_CHECK
    CASE(OP_STATE_CHECK_PUSH)  MOP_IN(OP_STATE_CHECK_PUSH);
      GET_STATE_CHECK_NUM_INC(mem, p);
      STATE_CHECK_VAL(scv, mem);
      if (scv) goto fail;

      GET_RELADDR_INC(addr, p);
      STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
      MOP_OUT;
      JUMP;

    CASE(OP_STATE_CHECK_PUSH_OR_JUMP)  MOP_IN(OP_STATE_CHECK_PUSH_OR_JUMP);
      GET_STATE_CHECK_NUM_INC(mem, p);
      GET_RELADDR_INC(addr, p);
      STATE_CHECK_VAL(scv, mem);
      if (scv) {
	p += addr;
      }
      else {
	STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem, pkeep);
      }
      MOP_OUT;
      JUMP;

    CASE(OP_STATE_CHECK)  MOP_IN(OP_STATE_CHECK);
      GET_STATE_CHECK_NUM_INC(mem, p);
      STATE_CHECK_VAL(scv, mem);
      if (scv) goto fail;

      STACK_PUSH_STATE_CHECK(s, mem);
      MOP_OUT;
      JUMP;
#endif /* USE_COMBINATION_EXPLOSION_CHECK */

    CASE(OP_POP)  MOP_IN(OP_POP);
      STACK_POP_ONE;
      MOP_OUT;
      JUMP;

#ifdef USE_OP_PUSH_OR_JUMP_EXACT
    CASE(OP_PUSH_OR_JUMP_EXACT1)  MOP_IN(OP_PUSH_OR_JUMP_EXACT1);
      GET_RELADDR_INC(addr, p);
      if (*p == *s && DATA_ENSURE_CHECK1) {
	p++;
	STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
	MOP_OUT;
	JUMP;
      }
      p += (addr + 1);
      MOP_OUT;
      JUMP;
#endif

    CASE(OP_PUSH_IF_PEEK_NEXT)  MOP_IN(OP_PUSH_IF_PEEK_NEXT);
      GET_RELADDR_INC(addr, p);
      if (*p == *s) {
	p++;
	STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
	MOP_OUT;
	JUMP;
      }
      p++;
      MOP_OUT;
      JUMP;

    CASE(OP_REPEAT)  MOP_IN(OP_REPEAT);
      {
	GET_MEMNUM_INC(mem, p);    /* mem: OP_REPEAT ID */
	GET_RELADDR_INC(addr, p);

	STACK_ENSURE(1);
	repeat_stk[mem] = GET_STACK_INDEX(stk);
	STACK_PUSH_REPEAT(mem, p);

	if (reg->repeat_range[mem].lower == 0) {
	  STACK_PUSH_ALT(p + addr, s, sprev, pkeep);
	}
      }
      MOP_OUT;
      JUMP;

    CASE(OP_REPEAT_NG)  MOP_IN(OP_REPEAT_NG);
      {
	GET_MEMNUM_INC(mem, p);    /* mem: OP_REPEAT ID */
	GET_RELADDR_INC(addr, p);

	STACK_ENSURE(1);
	repeat_stk[mem] = GET_STACK_INDEX(stk);
	STACK_PUSH_REPEAT(mem, p);

	if (reg->repeat_range[mem].lower == 0) {
	  STACK_PUSH_ALT(p, s, sprev, pkeep);
	  p += addr;
	}
      }
      MOP_OUT;
      JUMP;

    CASE(OP_REPEAT_INC)  MOP_IN(OP_REPEAT_INC);
      GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
      si = repeat_stk[mem];
      stkp = STACK_AT(si);

    repeat_inc:
      stkp->u.repeat.count++;
      if (stkp->u.repeat.count >= reg->repeat_range[mem].upper) {
	/* end of repeat. Nothing to do. */
      }
      else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
	STACK_PUSH_ALT(p, s, sprev, pkeep);
	p = STACK_AT(si)->u.repeat.pcode; /* Don't use stkp after PUSH. */
      }
      else {
	p = stkp->u.repeat.pcode;
      }
      STACK_PUSH_REPEAT_INC(si);
      MOP_OUT;
      CHECK_INTERRUPT_IN_MATCH_AT;
      JUMP;

    CASE(OP_REPEAT_INC_SG)  MOP_IN(OP_REPEAT_INC_SG);
      GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
      STACK_GET_REPEAT(mem, stkp);
      si = GET_STACK_INDEX(stkp);
      goto repeat_inc;
      NEXT;

    CASE(OP_REPEAT_INC_NG)  MOP_IN(OP_REPEAT_INC_NG);
      GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
      si = repeat_stk[mem];
      stkp = STACK_AT(si);

    repeat_inc_ng:
      stkp->u.repeat.count++;
      if (stkp->u.repeat.count < reg->repeat_range[mem].upper) {
	if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
	  UChar* pcode = stkp->u.repeat.pcode;

	  STACK_PUSH_REPEAT_INC(si);
	  STACK_PUSH_ALT(pcode, s, sprev, pkeep);
	}
	else {
	  p = stkp->u.repeat.pcode;
	  STACK_PUSH_REPEAT_INC(si);
	}
      }
      else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {
	STACK_PUSH_REPEAT_INC(si);
      }
      MOP_OUT;
      CHECK_INTERRUPT_IN_MATCH_AT;
      JUMP;

    CASE(OP_REPEAT_INC_NG_SG)  MOP_IN(OP_REPEAT_INC_NG_SG);
      GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
      STACK_GET_REPEAT(mem, stkp);
      si = GET_STACK_INDEX(stkp);
      goto repeat_inc_ng;
      NEXT;

    CASE(OP_PUSH_POS)  MOP_IN(OP_PUSH_POS);
      STACK_PUSH_POS(s, sprev, pkeep);
      MOP_OUT;
      JUMP;

    CASE(OP_POP_POS)  MOP_IN(OP_POP_POS);
      {
	STACK_POS_END(stkp);
	s     = stkp->u.state.pstr;
	sprev = stkp->u.state.pstr_prev;
      }
      MOP_OUT;
      JUMP;

    CASE(OP_PUSH_POS_NOT)  MOP_IN(OP_PUSH_POS_NOT);
      GET_RELADDR_INC(addr, p);
      STACK_PUSH_POS_NOT(p + addr, s, sprev, pkeep);
      MOP_OUT;
      JUMP;

    CASE(OP_FAIL_POS)  MOP_IN(OP_FAIL_POS);
      STACK_POP_TIL_POS_NOT;
      goto fail;
      NEXT;

    CASE(OP_PUSH_STOP_BT)  MOP_IN(OP_PUSH_STOP_BT);
      STACK_PUSH_STOP_BT;
      MOP_OUT;
      JUMP;

    CASE(OP_POP_STOP_BT)  MOP_IN(OP_POP_STOP_BT);
      STACK_STOP_BT_END;
      MOP_OUT;
      JUMP;

    CASE(OP_LOOK_BEHIND)  MOP_IN(OP_LOOK_BEHIND);
      GET_LENGTH_INC(tlen, p);
      s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, end, (int )tlen);
      if (IS_NULL(s)) goto fail;
      sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s, end);
      MOP_OUT;
      JUMP;

    CASE(OP_PUSH_LOOK_BEHIND_NOT)  MOP_IN(OP_PUSH_LOOK_BEHIND_NOT);
      GET_RELADDR_INC(addr, p);
      GET_LENGTH_INC(tlen, p);
      q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, end, (int )tlen);
      if (IS_NULL(q)) {
	/* too short case -> success. ex. /(?<!XXX)a/.match("a")
	   If you want to change to fail, replace following line. */
	p += addr;
	/* goto fail; */
      }
      else {
	STACK_PUSH_LOOK_BEHIND_NOT(p + addr, s, sprev, pkeep);
	s = q;
	sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s, end);
      }
      MOP_OUT;
      JUMP;

    CASE(OP_FAIL_LOOK_BEHIND_NOT)  MOP_IN(OP_FAIL_LOOK_BEHIND_NOT);
      STACK_POP_TIL_LOOK_BEHIND_NOT;
      goto fail;
      NEXT;

#ifdef USE_SUBEXP_CALL
    CASE(OP_CALL)  MOP_IN(OP_CALL);
      GET_ABSADDR_INC(addr, p);
      STACK_PUSH_CALL_FRAME(p);
      p = reg->p + addr;
      MOP_OUT;
      JUMP;

    CASE(OP_RETURN)  MOP_IN(OP_RETURN);
      STACK_RETURN(p);
      STACK_PUSH_RETURN;
      MOP_OUT;
      JUMP;
#endif

    CASE(OP_CONDITION)  MOP_IN(OP_CONDITION);
      GET_MEMNUM_INC(mem, p);
      GET_RELADDR_INC(addr, p);
      if ((mem > num_mem) ||
	  (mem_end_stk[mem]   == INVALID_STACK_INDEX) ||
	  (mem_start_stk[mem] == INVALID_STACK_INDEX)) {
	p += addr;
      }
      MOP_OUT;
      JUMP;

    CASE(OP_FINISH)
      goto finish;
      NEXT;

    CASE(OP_FAIL)
      if (0) {
	/* fall */
      fail:
	MOP_OUT;
      }
      MOP_IN(OP_FAIL);
      STACK_POP;
      p     = stk->u.state.pcode;
      s     = stk->u.state.pstr;
      sprev = stk->u.state.pstr_prev;
      pkeep = stk->u.state.pkeep;

#ifdef USE_COMBINATION_EXPLOSION_CHECK
      if (stk->u.state.state_check != 0) {
	stk->type = STK_STATE_CHECK_MARK;
	stk++;
      }
#endif

      MOP_OUT;
      JUMP;

    DEFAULT
      goto bytecode_error;
  } VM_LOOP_END

 finish:
  STACK_SAVE;
  if (xmalloc_base) xfree(xmalloc_base);
  return best_len;

#ifdef ONIG_DEBUG
 stack_error:
  STACK_SAVE;
  if (xmalloc_base) xfree(xmalloc_base);
  return ONIGERR_STACK_BUG;
#endif

 bytecode_error:
  STACK_SAVE;
  if (xmalloc_base) xfree(xmalloc_base);
  return ONIGERR_UNDEFINED_BYTECODE;

 unexpected_bytecode_error:
  STACK_SAVE;
  if (xmalloc_base) xfree(xmalloc_base);
  return ONIGERR_UNEXPECTED_BYTECODE;
}

Project: ruby
File: regcomp.c

onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag)
{
  OnigDefaultCaseFoldFlag = case_fold_flag;
  return 0;
}

Project: ruby
File: regsyntax.c

onig_set_syntax_op(OnigSyntaxType* syntax, unsigned int op)
{
  syntax->op = op;
}

Project: ruby
File: iso_8859_10.c

is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
  int v;
  const UChar* p = *pp;

  if (*p == SHARP_s && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
    (*pp)++;
    return TRUE;
  }

  (*pp)++;
  v = (EncISO_8859_10_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
  if ((v | BIT_CTYPE_LOWER) != 0) {
    return TRUE;
  }

  return (v != 0 ? TRUE : FALSE);
}

Project: ruby
File: re.c

rb_match_nth_defined(int nth, VALUE match)
{
    struct re_registers *regs;
    if (NIL_P(match)) return FALSE;
    regs = RMATCH_REGS(match);
    if (!regs) return FALSE;
    if (nth >= regs->num_regs) {
	return FALSE;
    }
    if (nth < 0) {
	nth += regs->num_regs;
	if (nth <= 0) return FALSE;
    }
    return (BEG(nth) != -1);
}

Project: ruby
File: regcomp.c

is_full_opt_exact_info(OptExactInfo* ex)
{
  return (ex->len >= OPT_EXACT_MAXLEN ? 1 : 0);
}

Project: ruby
File: re.c

rb_reg_match_m(int argc, VALUE *argv, VALUE re)
{
    VALUE result, str, initpos;
    long pos;

    if (rb_scan_args(argc, argv, "11", &str, &initpos) == 2) {
	pos = NUM2LONG(initpos);
    }
    else {
	pos = 0;
    }

    pos = reg_match_pos(re, &str, pos);
    if (pos < 0) {
	rb_backref_set(Qnil);
	return Qnil;
    }
    result = rb_backref_get();
    rb_match_busy(result);
    if (!NIL_P(result) && rb_block_given_p()) {
	return rb_yield(result);
    }
    return result;
}

Project: ruby
File: regcomp.c

compile_length_anchor_node(AnchorNode* node, regex_t* reg)
{
  int len;
  int tlen = 0;

  if (node->target) {
    tlen = compile_length_tree(node->target, reg);
    if (tlen < 0) return tlen;
  }

  switch (node->type) {
  case ANCHOR_PREC_READ:
    len = SIZE_OP_PUSH_POS + tlen + SIZE_OP_POP_POS;
    break;
  case ANCHOR_PREC_READ_NOT:
    len = SIZE_OP_PUSH_POS_NOT + tlen + SIZE_OP_FAIL_POS;
    break;
  case ANCHOR_LOOK_BEHIND:
    len = SIZE_OP_LOOK_BEHIND + tlen;
    break;
  case ANCHOR_LOOK_BEHIND_NOT:
    len = SIZE_OP_PUSH_LOOK_BEHIND_NOT + tlen + SIZE_OP_FAIL_LOOK_BEHIND_NOT;
    break;

  default:
    len = SIZE_OPCODE;
    break;
  }

  return len;
}

Project: ruby
File: regparse.c

bitset_copy(BitSetRef dest, BitSetRef bs)
{
  int i;
  for (i = 0; i < BITSET_SIZE; i++) { dest[i] = bs[i]; }
}

Project: ruby
File: iso_8859_9.c

is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
  int v;
  const UChar* p = *pp;

  if (*p == SHARP_s && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
    (*pp)++;
    return TRUE;
  }

  (*pp)++;
  v = (EncISO_8859_9_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
  if ((v | BIT_CTYPE_LOWER) != 0) {
    /* 0xdf etc..  are lower case letter, but can't convert. */
    if (*p >= 0xaa && *p <= 0xba)
      return FALSE;
    else
      return TRUE;
  }

  return (v != 0 ? TRUE : FALSE);
}

Project: ruby
File: windows_1253.c

case_map(OnigCaseFoldType* flagP, const OnigUChar** pp,
	 const OnigUChar* end, OnigUChar* to, OnigUChar* to_end,
	 const struct OnigEncodingTypeST* enc)
{
  OnigCodePoint code;
  OnigUChar *to_start = to;
  OnigCaseFoldType flags = *flagP;

  while (*pp < end && to < to_end) {
    code = *(*pp)++;
    if (code == 0xF2) {
      if (flags & ONIGENC_CASE_UPCASE) {
	flags |= ONIGENC_CASE_MODIFIED;
	code = 0xD3;
      }
      else if (flags & ONIGENC_CASE_FOLD) {
	flags |= ONIGENC_CASE_MODIFIED;
	code = 0xF3;
      }
    }
    else if (code == 0xB5) {
      if (flags & ONIGENC_CASE_UPCASE) {
	flags |= ONIGENC_CASE_MODIFIED;
	code = 0xCC;
      }
      else if (flags & ONIGENC_CASE_FOLD) {
	flags |= ONIGENC_CASE_MODIFIED;
	code = 0xEC;
      }
    }
    else if (code == 0xC0 || code == 0xE0 || code == 0xB6)
      ;
    else if ((EncCP1253_CtypeTable[code] & BIT_CTYPE_UPPER)
	     && (flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD))) {
      flags |= ONIGENC_CASE_MODIFIED;
      code = ENC_CP1253_TO_LOWER_CASE(code);
    }
    else if ((EncCP1253_CtypeTable[code] & BIT_CTYPE_LOWER)
	     && (flags & ONIGENC_CASE_UPCASE)) {
      flags |= ONIGENC_CASE_MODIFIED;
      if (code == 0xDC)
	code = 0xA2;
      else if (code >= 0xDD && code <= 0xDF)
	code -= 0x25;
      else if (code == 0xFC)
	code = 0xBC;
      else if (code == 0xFD || code == 0xFE)
	code -= 0x3F;
      else
	code -= 0x20;
    }
    *to++ = code;
    if (flags & ONIGENC_CASE_TITLECASE)  /* switch from titlecase to lowercase for capitalize */
      flags ^= (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_TITLECASE);
  }
  *flagP = flags;
  return (int )(to - to_start);
}

Project: ruby
File: regenc.c

onigenc_mbn_mbc_to_code(OnigEncoding enc, const UChar* p, const UChar* end)
{
  int c, i, len;
  OnigCodePoint n;

  len = enclen(enc, p, end);
  n = (OnigCodePoint )(*p++);
  if (len == 1) return n;

  for (i = 1; i < len; i++) {
    if (p >= end) break;
    c = *p++;
    n <<= 8;  n += c;
  }
  return n;
}

Project: ruby
File: regenc.c

onigenc_step(OnigEncoding enc, const UChar* p, const UChar* end, int n)
{
  UChar* q = (UChar* )p;
  while (n-- > 0) {
    q += ONIGENC_MBC_ENC_LEN(enc, q, end);
  }
  return (q <= end ? q : NULL);
}

Project: ruby
File: re.c

update_char_offset(VALUE match)
{
    struct rmatch *rm = RMATCH(match)->rmatch;
    struct re_registers *regs;
    int i, num_regs, num_pos;
    long c;
    char *s, *p, *q;
    rb_encoding *enc;
    pair_t *pairs;

    if (rm->char_offset_updated)
        return;

    regs = &rm->regs;
    num_regs = rm->regs.num_regs;

    if (rm->char_offset_num_allocated < num_regs) {
        REALLOC_N(rm->char_offset, struct rmatch_offset, num_regs);
        rm->char_offset_num_allocated = num_regs;
    }

    enc = rb_enc_get(RMATCH(match)->str);
    if (rb_enc_mbmaxlen(enc) == 1) {
        for (i = 0; i < num_regs; i++) {
            rm->char_offset[i].beg = BEG(i);
            rm->char_offset[i].end = END(i);
        }
        rm->char_offset_updated = 1;
        return;
    }

    pairs = ALLOCA_N(pair_t, num_regs*2);
    num_pos = 0;
    for (i = 0; i < num_regs; i++) {
        if (BEG(i) < 0)
            continue;
        pairs[num_pos++].byte_pos = BEG(i);
        pairs[num_pos++].byte_pos = END(i);
    }
    qsort(pairs, num_pos, sizeof(pair_t), pair_byte_cmp);

    s = p = RSTRING_PTR(RMATCH(match)->str);
    c = 0;
    for (i = 0; i < num_pos; i++) {
        q = s + pairs[i].byte_pos;
        c += rb_enc_strlen(p, q, enc);
        pairs[i].char_pos = c;
        p = q;
    }

    for (i = 0; i < num_regs; i++) {
        pair_t key, *found;
        if (BEG(i) < 0) {
            rm->char_offset[i].beg = -1;
            rm->char_offset[i].end = -1;
            continue;
        }

        key.byte_pos = BEG(i);
        found = bsearch(&key, pairs, num_pos, sizeof(pair_t), pair_byte_cmp);
        rm->char_offset[i].beg = found->char_pos;

        key.byte_pos = END(i);
        found = bsearch(&key, pairs, num_pos, sizeof(pair_t), pair_byte_cmp);
        rm->char_offset[i].end = found->char_pos;
    }

    rm->char_offset_updated = 1;
}

Project: ruby
File: regparse.c

strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
{
  ptrdiff_t slen;
  int term_len, i;
  UChar *r;

  slen = end - s;
  term_len = ONIGENC_MBC_MINLEN(enc);

  r = (UChar* )xmalloc(slen + term_len);
  CHECK_NULL_RETURN(r);
  xmemcpy(r, s, slen);

  for (i = 0; i < term_len; i++)
    r[slen + i] = (UChar )0;

  return r;
}

Project: ruby
File: windows_1251.c

case_map(OnigCaseFoldType* flagP, const OnigUChar** pp,
	 const OnigUChar* end, OnigUChar* to, OnigUChar* to_end,
	 const struct OnigEncodingTypeST* enc)
{
  OnigCodePoint code;
  OnigUChar *to_start = to;
  OnigCaseFoldType flags = *flagP;

  while (*pp < end && to < to_end) {
    code = *(*pp)++;
    if ((EncCP1251_CtypeTable[code] & BIT_CTYPE_UPPER)
	     && (flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD))) {
      flags |= ONIGENC_CASE_MODIFIED;
      code = ENC_CP1251_TO_LOWER_CASE(code);
    }
    else if (code == 0xB5)
      ;
    else if ((EncCP1251_CtypeTable[code]&BIT_CTYPE_LOWER)
	     && (flags & ONIGENC_CASE_UPCASE)) {
      flags |= ONIGENC_CASE_MODIFIED;
      if ((0x61 <= code && code <= 0x7A) || (0xE0 <= code && code <= 0xFF))
	code -= 0x20;
      else if (code == 0xA2 || code == 0xB3 || code == 0xBE)
	code -= 0x01;
      else if (code == 0x83)
	code = 0x81;
      else if (code == 0xBC)
	code = 0xA3;
      else if (code == 0xB4)
	code = 0xA5;
      else
	code -= 0x10;
    }
    *to++ = code;
    if (flags & ONIGENC_CASE_TITLECASE)  /* switch from titlecase to lowercase for capitalize */
      flags ^= (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_TITLECASE);
  }
  *flagP = flags;
  return (int )(to - to_start);
}

Project: ruby
File: re.c

unescape_unicode_list(const char **pp, const char *end,
        VALUE buf, rb_encoding **encp, onig_errmsg_buffer err)
{
    const char *p = *pp;
    int has_unicode = 0;
    unsigned long code;
    size_t len;

    while (p < end && ISSPACE(*p)) p++;

    while (1) {
        code = ruby_scan_hex(p, end-p, &len);
        if (len == 0)
            break;
        if (6 < len) { /* max 10FFFF */
            errcpy(err, "invalid Unicode range");
            return -1;
        }
        p += len;
        if (append_utf8(code, buf, encp, err) != 0)
            return -1;
        has_unicode = 1;

        while (p < end && ISSPACE(*p)) p++;
    }

    if (has_unicode == 0) {
        errcpy(err, "invalid Unicode list");
        return -1;
    }

    *pp = p;

    return 0;
}

Project: ruby
File: regparse.c

add_ctype_to_cc(CClassNode* cc, int ctype, int not, int ascii_range, ScanEnv* env)
{
  int maxcode;
  int c, r;
  const OnigCodePoint *ranges;
  OnigCodePoint sb_out;
  OnigEncoding enc = env->enc;

  r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sb_out, &ranges);
  if (r == 0) {
    if (ascii_range) {
      CClassNode ccwork;
      initialize_cclass(&ccwork);
      r = add_ctype_to_cc_by_range(&ccwork, ctype, not, env, sb_out,
				   ranges);
      if (r == 0) {
	if (not) {
	  r = add_code_range_to_buf0(&(ccwork.mbuf), env, 0x80, ONIG_LAST_CODE_POINT, FALSE);
	}
	else {
	  CClassNode ccascii;
	  initialize_cclass(&ccascii);
	  if (ONIGENC_MBC_MINLEN(env->enc) > 1) {
	    r = add_code_range(&(ccascii.mbuf), env, 0x00, 0x7F);
	  }
	  else {
	    bitset_set_range(env, ccascii.bs, 0x00, 0x7F);
	    r = 0;
	  }
	  if (r == 0) {
	    r = and_cclass(&ccwork, &ccascii, env);
	  }
	  if (IS_NOT_NULL(ccascii.mbuf)) bbuf_free(ccascii.mbuf);
	}
	if (r == 0) {
	  r = or_cclass(cc, &ccwork, env);
	}
	if (IS_NOT_NULL(ccwork.mbuf)) bbuf_free(ccwork.mbuf);
      }
    }
    else {
      r = add_ctype_to_cc_by_range(cc, ctype, not, env, sb_out, ranges);
    }
    return r;
  }
  else if (r != ONIG_NO_SUPPORT_CONFIG) {
    return r;
  }

  maxcode = ascii_range ? 0x80 : SINGLE_BYTE_SIZE;
  r = 0;
  switch (ctype) {
  case ONIGENC_CTYPE_ALPHA:
  case ONIGENC_CTYPE_BLANK:
  case ONIGENC_CTYPE_CNTRL:
  case ONIGENC_CTYPE_DIGIT:
  case ONIGENC_CTYPE_LOWER:
  case ONIGENC_CTYPE_PUNCT:
  case ONIGENC_CTYPE_SPACE:
  case ONIGENC_CTYPE_UPPER:
  case ONIGENC_CTYPE_XDIGIT:
  case ONIGENC_CTYPE_ASCII:
  case ONIGENC_CTYPE_ALNUM:
    if (not != 0) {
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
	if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
      }
      ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    }
    else {
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
	if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
      }
    }
    break;

  case ONIGENC_CTYPE_GRAPH:
  case ONIGENC_CTYPE_PRINT:
    if (not != 0) {
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
	if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype)
	    || c >= maxcode)
	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
      }
      if (ascii_range)
	ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    }
    else {
      for (c = 0; c < maxcode; c++) {
	if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
      }
      if (! ascii_range)
	ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    }
    break;

  case ONIGENC_CTYPE_WORD:
    if (not == 0) {
      for (c = 0; c < maxcode; c++) {
	if (ONIGENC_IS_CODE_WORD(enc, c)) BITSET_SET_BIT_CHKDUP(cc->bs, c);
      }
      if (! ascii_range)
	ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    }
    else {
      for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
	if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* check invalid code point */
	    && (! ONIGENC_IS_CODE_WORD(enc, c) || c >= maxcode))
	  BITSET_SET_BIT_CHKDUP(cc->bs, c);
      }
      if (ascii_range)
	ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    }
    break;

  default:
    return ONIGERR_PARSER_BUG;
    break;
  }

  return r;
}

Project: ruby
File: regexec.c

history_tree_clone(OnigCaptureTreeNode* node)
{
  int i, r;
  OnigCaptureTreeNode *clone, *child;

  clone = history_node_new();
  CHECK_NULL_RETURN(clone);

  clone->beg = node->beg;
  clone->end = node->end;
  for (i = 0; i < node->num_childs; i++) {
    child = history_tree_clone(node->childs[i]);
    if (IS_NULL(child)) {
      history_tree_free(clone);
      return (OnigCaptureTreeNode* )0;
    }
    r = history_tree_add_child(clone, child);
    if (r != 0) {
      history_tree_free(child);
      history_tree_free(clone);
      return (OnigCaptureTreeNode* )0;
    }
  }

  return clone;
}

Project: ruby
File: re.c

kcode_getter(void)
{
    rb_warn("variable $KCODE is no longer effective");
    return Qnil;
}

Project: ruby
File: regenc.c

onigenc_single_byte_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp,
					const OnigUChar* end, OnigUChar* to, OnigUChar* to_end,
					const struct OnigEncodingTypeST* enc)
{
  OnigCodePoint code;
  OnigUChar *to_start = to;
  OnigCaseFoldType flags = *flagP;

  while (*pp < end && to < to_end) {
    code = *(*pp)++;

    if (code >= 'a' && code <= 'z' && (flags & ONIGENC_CASE_UPCASE)) {
      flags |= ONIGENC_CASE_MODIFIED;
      code += 'A' - 'a';
    } else if (code >= 'A' && code <= 'Z' &&
	(flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD))) {
      flags |= ONIGENC_CASE_MODIFIED;
      code += 'a' - 'A';
    }
    *to++ = code;
    if (flags & ONIGENC_CASE_TITLECASE)  /* switch from titlecase to lowercase for capitalize */
      flags ^= (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_TITLECASE);
  }
  *flagP = flags;
  return (int )(to - to_start);
}

Project: ruby
File: regcomp.c

map_position_value(OnigEncoding enc, int i)
{
  static const short int ByteValTable[] = {
     5,  1,  1,  1,  1,  1,  1,  1,  1, 10, 10,  1,  1, 10,  1,  1,
     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
    12,  4,  7,  4,  4,  4,  4,  4,  4,  5,  5,  5,  5,  5,  5,  5,
     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  5,  5,
     5,  6,  6,  6,  6,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  6,  5,  5,  5,
     5,  6,  6,  6,  6,  7,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
     6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  5,  5,  5,  5,  1
  };

  if (i < numberof(ByteValTable)) {
    if (i == 0 && ONIGENC_MBC_MINLEN(enc) > 1)
      return 20;
    else
      return (int )ByteValTable[i];
  }
  else
    return 4;   /* Take it easy. */
}

Project: ruby
File: regcomp.c

clear_mml(MinMaxLen* mml)
{
  mml->min = mml->max = 0;
}

Project: ruby
File: re.c

match_alloc(VALUE klass)
{
    NEWOBJ_OF(match, struct RMatch, klass, T_MATCH);

    match->str = 0;
    match->rmatch = 0;
    match->regexp = 0;
    match->rmatch = ZALLOC(struct rmatch);

    return (VALUE)match;
}

Project: ruby
File: iso_8859_9.c

case_map(OnigCaseFoldType* flagP, const OnigUChar** pp,
	 const OnigUChar* end, OnigUChar* to, OnigUChar* to_end,
	 const struct OnigEncodingTypeST* enc)
{
  OnigCodePoint code;
  OnigUChar *to_start = to;
  OnigCaseFoldType flags = *flagP;

  while (*pp < end && to < to_end) {
    code = *(*pp)++;
    if (code == SHARP_s) {
      if (flags & ONIGENC_CASE_UPCASE) {
	flags |= ONIGENC_CASE_MODIFIED;
	*to++ = 'S';
	code = (flags & ONIGENC_CASE_TITLECASE) ? 's' : 'S';
      }
      else if (flags & ONIGENC_CASE_FOLD) {
	flags |= ONIGENC_CASE_MODIFIED;
	*to++ = 's';
	code = 's';
      }
    }
    else if (code == 0xAA || code == 0xB5 || code == 0xBA || code == 0xFF)
      ;
    else if ((EncISO_8859_9_CtypeTable[code] & BIT_CTYPE_UPPER)
	     && (flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD))) {
      flags |= ONIGENC_CASE_MODIFIED;
      if (code == 'I')
	code = flags & ONIGENC_CASE_FOLD_TURKISH_AZERI ? DOTLESS_i : 'i';
      else
	code = ENC_ISO_8859_9_TO_LOWER_CASE(code);
    }
    else if ((EncISO_8859_9_CtypeTable[code]&BIT_CTYPE_LOWER)
	     && (flags & ONIGENC_CASE_UPCASE)) {
      flags |= ONIGENC_CASE_MODIFIED;
      if (code == 'i')
	code = flags & ONIGENC_CASE_FOLD_TURKISH_AZERI ? I_WITH_DOT_ABOVE : 'I';
      else if (code == DOTLESS_i)
	code = 'I';
      else
	code -= 0x20;
    }
    *to++ = code;
    if (flags & ONIGENC_CASE_TITLECASE)  /* switch from titlecase to lowercase for capitalize */
      flags ^= (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_TITLECASE);
  }
  *flagP = flags;
  return (int )(to - to_start);
}

Project: ruby
File: regcomp.c

compile_length_quantifier_node(QtfrNode* qn, regex_t* reg)
{
  int len, mod_tlen, cklen;
  int ckn;
  int infinite = IS_REPEAT_INFINITE(qn->upper);
  int empty_info = qn->target_empty_info;
  int tlen = compile_length_tree(qn->target, reg);

  if (tlen < 0) return tlen;

  ckn = ((reg->num_comb_exp_check > 0) ? qn->comb_exp_check_num : 0);

  cklen = (CKN_ON ? SIZE_STATE_CHECK_NUM: 0);

  /* anychar repeat */
  if (NTYPE(qn->target) == NT_CANY) {
    if (qn->greedy && infinite) {
      if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON)
	return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower + cklen;
      else
	return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower + cklen;
    }
  }

  if (empty_info != 0)
    mod_tlen = tlen + (SIZE_OP_NULL_CHECK_START + SIZE_OP_NULL_CHECK_END);
  else
    mod_tlen = tlen;

  if (infinite && qn->lower <= 1) {
    if (qn->greedy) {
      if (qn->lower == 1)
	len = SIZE_OP_JUMP;
      else
	len = 0;

      len += SIZE_OP_PUSH + cklen + mod_tlen + SIZE_OP_JUMP;
    }
    else {
      if (qn->lower == 0)
	len = SIZE_OP_JUMP;
      else
	len = 0;

      len += mod_tlen + SIZE_OP_PUSH + cklen;
    }
  }
  else if (qn->upper == 0) {
    if (qn->is_refered != 0) /* /(?<n>..){0}/ */
      len = SIZE_OP_JUMP + tlen;
    else
      len = 0;
  }
  else if (qn->upper == 1 && qn->greedy) {
    if (qn->lower == 0) {
      if (CKN_ON) {
	len = SIZE_OP_STATE_CHECK_PUSH + tlen;
      }
      else {
	len = SIZE_OP_PUSH + tlen;
      }
    }
    else {
      len = tlen;
    }
  }
  else if (!qn->greedy && qn->upper == 1 && qn->lower == 0) { /* '??' */
    len = SIZE_OP_PUSH + cklen + SIZE_OP_JUMP + tlen;
  }
  else {
    len = SIZE_OP_REPEAT_INC
        + mod_tlen + SIZE_OPCODE + SIZE_RELADDR + SIZE_MEMNUM;
    if (CKN_ON)
      len += SIZE_OP_STATE_CHECK;
  }

  return len;
}

Project: ruby
File: regcomp.c

set_optimize_map_info(regex_t* reg, OptMapInfo* m)
{
  int i;

  for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
    reg->map[i] = m->map[i];

  reg->optimize   = ONIG_OPTIMIZE_MAP;
  reg->dmin       = m->mmd.min;
  reg->dmax       = m->mmd.max;

  if (reg->dmin != ONIG_INFINITE_DISTANCE) {
    reg->threshold_len = (int )(reg->dmin + 1);
  }
}

Project: ruby
File: regexec.c

rb_enc_asciicompat(OnigEncoding enc)
{
  return ONIGENC_MBC_MINLEN(enc)==1 && !((enc)->ruby_encoding_index & ENC_DUMMY_FLAG);
}

Project: ruby
File: iso_8859_14.c

mbc_case_fold(OnigCaseFoldType flag,
			  const UChar** pp, const UChar* end ARG_UNUSED,
			  UChar* lower, OnigEncoding enc ARG_UNUSED)
{
  const UChar* p = *pp;

  if (*p == SHARP_s && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
    *lower++ = 's';
    *lower   = 's';
    (*pp)++;
    return 2;
  }

  *lower = ENC_ISO_8859_14_TO_LOWER_CASE(*p);
  (*pp)++;
  return 1; /* return byte length of converted char to lower */
}

Project: ruby
File: regenc.c

onigenc_get_prev_char_head(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end)
{
  if (s <= start)
    return (UChar* )NULL;

  return ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s - 1, end);
}

Project: ruby
File: re.c

str_coderange(VALUE str)
{
    int cr = ENC_CODERANGE(str);
    if (cr == ENC_CODERANGE_UNKNOWN) {
	cr = rb_enc_str_coderange(str);
    }
    return cr;
}

Project: ruby
File: mktable.c

static int IsXDigit(int enc, int c)
{
  if (enc == ASCII)
    return isxdigit(c);

  if (c >= 0x30 && c <= 0x39) return 1;
  if (c >= 0x41 && c <= 0x46) return 1;
  if (c >= 0x61 && c <= 0x66) return 1;
  return 0;
}

Project: ruby
File: re.c

rb_reg_nth_match(int nth, VALUE match)
{
    VALUE str;
    long start, end, len;
    struct re_registers *regs;

    if (NIL_P(match)) return Qnil;
    match_check(match);
    regs = RMATCH_REGS(match);
    if (nth >= regs->num_regs) {
	return Qnil;
    }
    if (nth < 0) {
	nth += regs->num_regs;
	if (nth <= 0) return Qnil;
    }
    start = BEG(nth);
    if (start == -1) return Qnil;
    end = END(nth);
    len = end - start;
    str = rb_str_subseq(RMATCH(match)->str, start, len);
    OBJ_INFECT(str, match);
    return str;
}

Project: ruby
File: re.c

rb_reg_s_alloc(VALUE klass)
{
    NEWOBJ_OF(re, struct RRegexp, klass, T_REGEXP | (RGENGC_WB_PROTECTED_REGEXP ? FL_WB_PROTECTED : 0));

    re->ptr = 0;
    RB_OBJ_WRITE(re, &re->src, 0);
    re->usecnt = 0;

    return (VALUE)re;
}

Project: ruby
File: mktable.c

static int IsSpace(int enc, int c)
{
  if (enc == ASCII)
    return isspace(c);

  if (c >= 0x09 && c <= 0x0d) return 1;
  if (c == 0x20) return 1;

  switch (enc) {
  case UNICODE_ISO_8859_1:
    if (c == 0x85) return 1;
    /* fall */
  case ISO_8859_1:
  case ISO_8859_2:
  case ISO_8859_3:
  case ISO_8859_4:
  case ISO_8859_5:
  case ISO_8859_6:
  case ISO_8859_7:
  case ISO_8859_8:
  case ISO_8859_9:
  case ISO_8859_10:
  case ISO_8859_11:
  case ISO_8859_13:
  case ISO_8859_14:
  case ISO_8859_15:
  case ISO_8859_16:
  case KOI8:
    if (c == 0xa0) return 1;
    break;

  case KOI8_R:
    if (c == 0x9a) return 1;
    break;

  default:
    exit(-1);
  }

  return 0;
}

Project: ruby
File: iso_8859_15.c

case_map(OnigCaseFoldType* flagP, const OnigUChar** pp,
	 const OnigUChar* end, OnigUChar* to, OnigUChar* to_end,
	 const struct OnigEncodingTypeST* enc)
{
  OnigCodePoint code;
  OnigUChar *to_start = to;
  OnigCaseFoldType flags = *flagP;

  while (*pp < end && to < to_end) {
    code = *(*pp)++;
    if (code == SHARP_s) {
      if (flags & ONIGENC_CASE_UPCASE) {
	flags |= ONIGENC_CASE_MODIFIED;
	*to++ = 'S';
	code = (flags & ONIGENC_CASE_TITLECASE) ? 's' : 'S';
      }
      else if (flags & ONIGENC_CASE_FOLD) {
	flags |= ONIGENC_CASE_MODIFIED;
	*to++ = 's';
	code = 's';
      }
    }
    else if (code == 0xAA || code == 0xBA || code == 0xB5)
      ;
    else if ((EncISO_8859_15_CtypeTable[code] & BIT_CTYPE_UPPER)
	     && (flags & (ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_FOLD))) {
      flags |= ONIGENC_CASE_MODIFIED;
      code = ENC_ISO_8859_15_TO_LOWER_CASE(code);
    }
    else if ((EncISO_8859_15_CtypeTable[code] & BIT_CTYPE_LOWER)
	     && (flags & ONIGENC_CASE_UPCASE)) {
      flags |= ONIGENC_CASE_MODIFIED;
      if (code == 0xA8)
	code -= 2;
      else if (code == 0xB8)
	code -= 4;
      else if (code == 0xBD)
	code -= 1;
      else if (code == 0xFF)
	code -= 0x41;
      else
	code -= 0x20;
    }
    *to++ = code;
    if (flags & ONIGENC_CASE_TITLECASE)  /* switch from titlecase to lowercase for capitalize */
      flags ^= (ONIGENC_CASE_UPCASE | ONIGENC_CASE_DOWNCASE | ONIGENC_CASE_TITLECASE);
  }
  *flagP = flags;
  return (int )(to - to_start);
}

Project: ruby
File: re.c

rb_reg_prepare_re(VALUE re, VALUE str)
{
    onig_errmsg_buffer err = "";
    return rb_reg_prepare_re0(re, str, err);
}

Project: ruby
File: re.c

read_escaped_byte(const char **pp, const char *end, onig_errmsg_buffer err)
{
    const char *p = *pp;
    int code;
    int meta_prefix = 0, ctrl_prefix = 0;
    size_t len;

    if (p == end || *p++ != '\\') {
        errcpy(err, "too short escaped multibyte character");
        return -1;
    }

again:
    if (p == end) {
        errcpy(err, "too short escape sequence");
        return -1;
    }
    switch (*p++) {
      case '\\': code = '\\'; break;
      case 'n': code = '\n'; break;
      case 't': code = '\t'; break;
      case 'r': code = '\r'; break;
      case 'f': code = '\f'; break;
      case 'v': code = '\013'; break;
      case 'a': code = '\007'; break;
      case 'e': code = '\033'; break;

      /* \OOO */
      case '0': case '1': case '2': case '3':
      case '4': case '5': case '6': case '7':
        p--;
        code = scan_oct(p, end < p+3 ? end-p : 3, &len);
        p += len;
        break;

      case 'x': /* \xHH */
        code = scan_hex(p, end < p+2 ? end-p : 2, &len);
        if (len < 1) {
            errcpy(err, "invalid hex escape");
            return -1;
        }
        p += len;
        break;

      case 'M': /* \M-X, \M-\C-X, \M-\cX */
        if (meta_prefix) {
            errcpy(err, "duplicate meta escape");
            return -1;
        }
        meta_prefix = 1;
        if (p+1 < end && *p++ == '-' && (*p & 0x80) == 0) {
            if (*p == '\\') {
                p++;
                goto again;
            }
            else {
                code = *p++;
                break;
            }
        }
        errcpy(err, "too short meta escape");
        return -1;

      case 'C': /* \C-X, \C-\M-X */
        if (p == end || *p++ != '-') {
            errcpy(err, "too short control escape");
            return -1;
        }
      case 'c': /* \cX, \c\M-X */
        if (ctrl_prefix) {
            errcpy(err, "duplicate control escape");
            return -1;
        }
        ctrl_prefix = 1;
        if (p < end && (*p & 0x80) == 0) {
            if (*p == '\\') {
                p++;
                goto again;
            }
            else {
                code = *p++;
                break;
            }
        }
        errcpy(err, "too short control escape");
        return -1;

      default:
        errcpy(err, "unexpected escape sequence");
        return -1;
    }
    if (code < 0 || 0xff < code) {
        errcpy(err, "invalid escape code");
        return -1;
    }

    if (ctrl_prefix)
        code &= 0x1f;
    if (meta_prefix)
        code |= 0x80;

    *pp = p;
    return code;
}

Project: ruby
File: iso_8859_1.c

apply_all_case_fold(OnigCaseFoldType flag,
			       OnigApplyAllCaseFoldFunc f, void* arg,
			       OnigEncoding enc ARG_UNUSED)
{
  return onigenc_apply_all_case_fold_with_map(
             numberof(CaseFoldMap), CaseFoldMap, 1,
             flag, f, arg);
}

Project: ruby
File: regcomp.c

unset_addr_list_fix(UnsetAddrList* uslist, regex_t* reg)
{
  int i, offset;
  EncloseNode* en;
  AbsAddrType addr;

  for (i = 0; i < uslist->num; i++) {
    en = NENCLOSE(uslist->us[i].target);
    if (! IS_ENCLOSE_ADDR_FIXED(en)) return ONIGERR_PARSER_BUG;
    addr = en->call_addr;
    offset = uslist->us[i].offset;

    BBUF_WRITE(reg, offset, &addr, SIZE_ABSADDR);
  }
  return 0;
}

Project: ruby
File: regparse.c

onig_strcpy(UChar* dest, const UChar* src, const UChar* end)
{
  ptrdiff_t len = end - src;
  if (len > 0) {
    xmemcpy(dest, src, len);
    dest[len] = (UChar )0;
  }
}

Project: ruby
File: regparse.c

name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
{
  int alloc;
  NameEntry* e;
  NameTable* t = (NameTable* )reg->name_table;

  if (name_end - name <= 0)
    return ONIGERR_EMPTY_GROUP_NAME;

  e = name_find(reg, name, name_end);
  if (IS_NULL(e)) {
# ifdef USE_ST_LIBRARY
    if (IS_NULL(t)) {
      t = onig_st_init_strend_table_with_size(5);
      reg->name_table = (void* )t;
    }
    e = (NameEntry* )xmalloc(sizeof(NameEntry));
    CHECK_NULL_RETURN_MEMERR(e);

    e->name = strdup_with_null(reg->enc, name, name_end);
    if (IS_NULL(e->name)) {
      xfree(e);
      return ONIGERR_MEMORY;
    }
    onig_st_insert_strend(t, e->name, (e->name + (name_end - name)),
                          (HashDataType )e);

    e->name_len   = name_end - name;
    e->back_num   = 0;
    e->back_alloc = 0;
    e->back_refs  = (int* )NULL;

# else

    if (IS_NULL(t)) {
      alloc = INIT_NAMES_ALLOC_NUM;
      t = (NameTable* )xmalloc(sizeof(NameTable));
      CHECK_NULL_RETURN_MEMERR(t);
      t->e     = NULL;
      t->alloc = 0;
      t->num   = 0;

      t->e = (NameEntry* )xmalloc(sizeof(NameEntry) * alloc);
      if (IS_NULL(t->e)) {
	xfree(t);
	return ONIGERR_MEMORY;
      }
      t->alloc = alloc;
      reg->name_table = t;
      goto clear;
    }
    else if (t->num == t->alloc) {
      int i;
      NameEntry* p;

      alloc = t->alloc * 2;
      p = (NameEntry* )xrealloc(t->e, sizeof(NameEntry) * alloc);
      CHECK_NULL_RETURN_MEMERR(p);
      t->e = p;
      t->alloc = alloc;

    clear:
      for (i = t->num; i < t->alloc; i++) {
	t->e[i].name       = NULL;
	t->e[i].name_len   = 0;
	t->e[i].back_num   = 0;
	t->e[i].back_alloc = 0;
	t->e[i].back_refs  = (int* )NULL;
      }
    }
    e = &(t->e[t->num]);
    t->num++;
    e->name = strdup_with_null(reg->enc, name, name_end);
    if (IS_NULL(e->name)) return ONIGERR_MEMORY;
    e->name_len = name_end - name;
# endif
  }

  if (e->back_num >= 1 &&
      ! IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME)) {
    onig_scan_env_set_error_string(env, ONIGERR_MULTIPLEX_DEFINED_NAME,
				    name, name_end);
    return ONIGERR_MULTIPLEX_DEFINED_NAME;
  }

  e->back_num++;
  if (e->back_num == 1) {
    e->back_ref1 = backref;
  }
  else {
    if (e->back_num == 2) {
      alloc = INIT_NAME_BACKREFS_ALLOC_NUM;
      e->back_refs = (int* )xmalloc(sizeof(int) * alloc);
      CHECK_NULL_RETURN_MEMERR(e->back_refs);
      e->back_alloc = alloc;
      e->back_refs[0] = e->back_ref1;
      e->back_refs[1] = backref;
    }
    else {
      if (e->back_num > e->back_alloc) {
	int* p;
	alloc = e->back_alloc * 2;
	p = (int* )xrealloc(e->back_refs, sizeof(int) * alloc);
	CHECK_NULL_RETURN_MEMERR(p);
	e->back_refs = p;
	e->back_alloc = alloc;
      }
      e->back_refs[e->back_num - 1] = backref;
    }
  }

  return 0;
}

Project: ruby
File: regparse.c

is_onechar_cclass(CClassNode* cc, OnigCodePoint* code)
{
  const OnigCodePoint not_found = ONIG_LAST_CODE_POINT;
  OnigCodePoint c = not_found;
  int i;
  BBuf *bbuf = cc->mbuf;

  if (IS_NCCLASS_NOT(cc)) return 0;

  /* check bbuf */
  if (IS_NOT_NULL(bbuf)) {
    OnigCodePoint n, *data;
    GET_CODE_POINT(n, bbuf->p);
    data = (OnigCodePoint* )(bbuf->p) + 1;
    if ((n == 1) && (data[0] == data[1])) {
      /* only one char found in the bbuf, save the code point. */
      c = data[0];
      if (((c < SINGLE_BYTE_SIZE) && BITSET_AT(cc->bs, c))) {
	/* skip if c is included in the bitset */
	c = not_found;
      }
    }
    else {
      return 0;  /* the bbuf contains multiple chars */
    }
  }

  /* check bitset */
  for (i = 0; i < BITSET_SIZE; i++) {
    Bits b1 = cc->bs[i];
    if (b1 != 0) {
      if (((b1 & (b1 - 1)) == 0) && (c == not_found)) {
	c = BITS_IN_ROOM * i + countbits(b1 - 1);
      } else {
	return 0;  /* the character class contains multiple chars */
      }
    }
  }

  if (c != not_found) {
    *code = c;
    return 1;
  }

  /* the character class contains no char. */
  return 0;
}

Project: ruby
File: regexec.c

onig_scan(regex_t* reg, const UChar* str, const UChar* end,
	  OnigRegion* region, OnigOptionType option,
	  int (*scan_callback)(OnigPosition, OnigPosition, OnigRegion*, void*),
	  void* callback_arg)
{
  OnigPosition r;
  OnigPosition n;
  int rs;
  const UChar* start;

  n = 0;
  start = str;
  while (1) {
    r = onig_search(reg, str, end, start, end, region, option);
    if (r >= 0) {
      rs = scan_callback(n, r, region, callback_arg);
      n++;
      if (rs != 0)
	return rs;

      if (region->end[0] == start - str)
	start++;
      else
	start = str + region->end[0];

      if (start > end)
	break;
    }
    else if (r == ONIG_MISMATCH) {
      break;
    }
    else { /* error */
      return r;
    }
  }

  return n;
}

Project: ruby
File: regparse.c

CLOSE_BRACKET_WITHOUT_ESC_WARN(ScanEnv* env, UChar* c)
{
  if (onig_warn == onig_null_warn) return ;

  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_WARN_CC_OP_NOT_ESCAPED)) {
    onig_syntax_warn(env, "regular expression has '%s' without escape", c);
  }
}

Project: ruby
File: re.c

match_hash(VALUE match)
{
    const struct re_registers *regs;
    st_index_t hashval;

    match_check(match);
    hashval = rb_hash_start(rb_str_hash(RMATCH(match)->str));
    hashval = rb_hash_uint(hashval, reg_hash(RMATCH(match)->regexp));
    regs = RMATCH_REGS(match);
    hashval = rb_hash_uint(hashval, regs->num_regs);
    hashval = rb_hash_uint(hashval, rb_memhash(regs->beg, regs->num_regs * sizeof(*regs->beg)));
    hashval = rb_hash_uint(hashval, rb_memhash(regs->end, regs->num_regs * sizeof(*regs->end)));
    hashval = rb_hash_end(hashval);
    return ST2FIX(hashval);
}

Project: ruby
File: re.c

rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
{
    long result;
    VALUE match;
    struct re_registers regi, *regs = &regi;
    char *range = RSTRING_PTR(str);
    regex_t *reg;
    int tmpreg;
    onig_errmsg_buffer err = "";

    if (pos > RSTRING_LEN(str) || pos < 0) {
	rb_backref_set(Qnil);
	return -1;
    }

    reg = rb_reg_prepare_re0(re, str, err);
    tmpreg = reg != RREGEXP_PTR(re);
    if (!tmpreg) RREGEXP(re)->usecnt++;

    match = rb_backref_get();
    if (!NIL_P(match)) {
	if (FL_TEST(match, MATCH_BUSY)) {
	    match = Qnil;
	}
	else {
	    regs = RMATCH_REGS(match);
	}
    }
    if (NIL_P(match)) {
	MEMZERO(regs, struct re_registers, 1);
    }
    if (!reverse) {
	range += RSTRING_LEN(str);
    }
    result = onig_search(reg,
			 (UChar*)(RSTRING_PTR(str)),
			 ((UChar*)(RSTRING_PTR(str)) + RSTRING_LEN(str)),
			 ((UChar*)(RSTRING_PTR(str)) + pos),
			 ((UChar*)range),
			 regs, ONIG_OPTION_NONE);
    if (!tmpreg) RREGEXP(re)->usecnt--;
    if (tmpreg) {
	if (RREGEXP(re)->usecnt) {
	    onig_free(reg);
	}
	else {
	    onig_free(RREGEXP_PTR(re));
	    RREGEXP_PTR(re) = reg;
	}
    }
    if (result < 0) {
	if (regs == &regi)
	    onig_region_free(regs, 0);
	if (result == ONIG_MISMATCH) {
	    rb_backref_set(Qnil);
	    return result;
	}
	else {
	    onig_error_code_to_str((UChar*)err, (int)result);
	    rb_reg_raise(RREGEXP_SRC_PTR(re), RREGEXP_SRC_LEN(re), err, re);
	}
    }

    if (NIL_P(match)) {
	int err;
	match = match_alloc(rb_cMatch);
	err = rb_reg_region_copy(RMATCH_REGS(match), regs);
	onig_region_free(regs, 0);
	if (err) rb_memerror();
    }
    else {
	FL_UNSET(match, FL_TAINT);
    }

    if (set_backref_str) {
	RMATCH(match)->str = rb_str_new4(str);
	OBJ_INFECT(match, str);
    }

    RMATCH(match)->regexp = re;
    RMATCH(match)->rmatch->char_offset_updated = 0;
    rb_backref_set(match);

    OBJ_INFECT(match, re);

    return result;
}

Project: ruby
File: regcomp.c

compile_length_option_node(EncloseNode* node, regex_t* reg)
{
  int tlen;
  OnigOptionType prev = reg->options;

  reg->options = node->option;
  tlen = compile_length_tree(node->target, reg);
  reg->options = prev;

  if (tlen < 0) return tlen;

  if (IS_DYNAMIC_OPTION(prev ^ node->option)) {
    return SIZE_OP_SET_OPTION_PUSH + SIZE_OP_SET_OPTION + SIZE_OP_FAIL
           + tlen + SIZE_OP_SET_OPTION;
  }
  else
    return tlen;
}

Project: ruby
File: regenc.c

onigenc_strlen_null(OnigEncoding enc, const UChar* s)
{
  int n = 0;
  UChar* p = (UChar* )s;
  UChar* e;

  while (1) {
    if (*p == '\0') {
      UChar* q;
      int len = ONIGENC_MBC_MINLEN(enc);

      if (len == 1) return n;
      q = p + 1;
      while (len > 1) {
        if (*q != '\0') break;
        q++;
        len--;
      }
      if (len == 1) return n;
    }
    e = p + ONIGENC_MBC_MAXLEN(enc);
    p += ONIGENC_MBC_ENC_LEN(enc, p, e);
    n++;
  }
}

Project: ruby
File: regparse.c

scan_env_add_mem_entry(ScanEnv* env)
{
  int i, need, alloc;
  Node** p;

  need = env->num_mem + 1;
  if (need > ONIG_MAX_CAPTURE_GROUP_NUM)
    return ONIGERR_TOO_MANY_CAPTURE_GROUPS;
  if (need >= SCANENV_MEMNODES_SIZE) {
    if (env->mem_alloc <= need) {
      if (IS_NULL(env->mem_nodes_dynamic)) {
	alloc = INIT_SCANENV_MEMNODES_ALLOC_SIZE;
	p = (Node** )xmalloc(sizeof(Node*) * alloc);
	xmemcpy(p, env->mem_nodes_static,
		sizeof(Node*) * SCANENV_MEMNODES_SIZE);
      }
      else {
	alloc = env->mem_alloc * 2;
	p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc);
      }
      CHECK_NULL_RETURN_MEMERR(p);

      for (i = env->num_mem + 1; i < alloc; i++)
	p[i] = NULL_NODE;

      env->mem_nodes_dynamic = p;
      env->mem_alloc = alloc;
    }
  }

  env->num_mem++;
  return env->num_mem;
}

Project: ruby
File: regenc.c

onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc,
				   const UChar* start, const UChar* s, const UChar* end, const UChar** prev)
{
  UChar* p = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end);

  if (p < s) {
    if (prev) *prev = (const UChar* )p;
    p += enclen(enc, p, end);
  }
  else {
    if (prev) *prev = (const UChar* )NULL; /* Sorry */
  }
  return p;
}

Project: ruby
File: regcomp.c

concat_opt_exact_info(OptExactInfo* to, OptExactInfo* add, OnigEncoding enc)
{
  int i, j, len;
  UChar *p, *end;
  OptAncInfo tanc;

  if (to->ignore_case < 0)
    to->ignore_case = add->ignore_case;
  else if (to->ignore_case != add->ignore_case)
    return ;  /* avoid */

  p = add->s;
  end = p + add->len;
  for (i = to->len; p < end; ) {
    len = enclen(enc, p, end);
    if (i + len > OPT_EXACT_MAXLEN) break;
    for (j = 0; j < len && p < end; j++)
      to->s[i++] = *p++;
  }

  to->len = i;
  to->reach_end = (p == end ? add->reach_end : 0);

  concat_opt_anc_info(&tanc, &to->anc, &add->anc, 1, 1);
  if (! to->reach_end) tanc.right_anchor = 0;
  copy_opt_anc_info(&to->anc, &tanc);
}

Project: ruby
File: regexec.c

make_capture_history_tree(OnigCaptureTreeNode* node, OnigStackType** kp,
                          OnigStackType* stk_top, UChar* str, regex_t* reg)
{
  int n, r;
  OnigCaptureTreeNode* child;
  OnigStackType* k = *kp;

  while (k < stk_top) {
    if (k->type == STK_MEM_START) {
      n = k->u.mem.num;
      if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP &&
	  BIT_STATUS_AT(reg->capture_history, n) != 0) {
	child = history_node_new();
	CHECK_NULL_RETURN_MEMERR(child);
	child->group = n;
	child->beg = k->u.mem.pstr - str;
	r = history_tree_add_child(node, child);
	if (r != 0) {
	  history_tree_free(child);
	  return r;
	}
	*kp = (k + 1);
	r = make_capture_history_tree(child, kp, stk_top, str, reg);
	if (r != 0) return r;

	k = *kp;
	child->end = k->u.mem.pstr - str;
      }
    }
    else if (k->type == STK_MEM_END) {
      if (k->u.mem.num == node->group) {
	node->end = k->u.mem.pstr - str;
	*kp = k;
	return 0;
      }
    }
    k++;
  }

  return 1; /* 1: root node ending. */
}

Project: ruby
File: regparse.c

bitset_invert(BitSetRef bs)
{
  int i;
  for (i = 0; i < BITSET_SIZE; i++) { bs[i] = ~(bs[i]); }
}

Project: ruby
File: regcomp.c

clear_optimize_info(regex_t* reg)
{
  reg->optimize      = ONIG_OPTIMIZE_NONE;
  reg->anchor        = 0;
  reg->anchor_dmin   = 0;
  reg->anchor_dmax   = 0;
  reg->sub_anchor    = 0;
  reg->exact_end     = (UChar* )NULL;
  reg->threshold_len = 0;
  if (IS_NOT_NULL(reg->exact)) {
    xfree(reg->exact);
    reg->exact = (UChar* )NULL;
  }
}

Project: ruby
File: iso_8859_1.c

is_mbc_ambiguous(OnigCaseFoldType flag,
		 const UChar** pp, const UChar* end)
{
  int v;
  const UChar* p = *pp;

  if (*p == SHARP_s && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
    (*pp)++;
    return TRUE;
  }

  (*pp)++;
  v = (EncISO_8859_1_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
  if ((v | BIT_CTYPE_LOWER) != 0) {
    /* 0xdf, 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
    if (*p >= 0xaa && *p <= 0xba)
      return FALSE;
    else
      return TRUE;
  }

  return (v != 0 ? TRUE : FALSE);
}

Project: ruby
File: re.c

prematch_getter(void)
{
    return rb_reg_match_pre(rb_backref_get());
}

Project: ruby
File: regcomp.c

subexp_recursive_check(Node* node)
{
  int r = 0;

  switch (NTYPE(node)) {
  case NT_LIST:
  case NT_ALT:
    do {
      r |= subexp_recursive_check(NCAR(node));
    } while (IS_NOT_NULL(node = NCDR(node)));
    break;

  case NT_QTFR:
    r = subexp_recursive_check(NQTFR(node)->target);
    break;

  case NT_ANCHOR:
    {
      AnchorNode* an = NANCHOR(node);
      switch (an->type) {
      case ANCHOR_PREC_READ:
      case ANCHOR_PREC_READ_NOT:
      case ANCHOR_LOOK_BEHIND:
      case ANCHOR_LOOK_BEHIND_NOT:
	r = subexp_recursive_check(an->target);
	break;
      }
    }
    break;

  case NT_CALL:
    r = subexp_recursive_check(NCALL(node)->target);
    if (r != 0) SET_CALL_RECURSION(node);
    break;

  case NT_ENCLOSE:
    if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
      return 0;
    else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
      return 1; /* recursion */
    else {
      SET_ENCLOSE_STATUS(node, NST_MARK2);
      r = subexp_recursive_check(NENCLOSE(node)->target);
      CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
    }
    break;

  default:
    break;
  }

  return r;
}

Project: ruby
File: regcomp.c

setup_look_behind(Node* node, regex_t* reg, ScanEnv* env)
{
  int r, len;
  AnchorNode* an = NANCHOR(node);

  r = get_char_length_tree(an->target, reg, &len);
  if (r == 0)
    an->char_len = len;
  else if (r == GET_CHAR_LEN_VARLEN)
    r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
  else if (r == GET_CHAR_LEN_TOP_ALT_VARLEN) {
    if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND))
      r = divide_look_behind_alternatives(node);
    else
      r = ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
  }

  return r;
}

Project: ruby
File: regcomp.c

compile_tree_n_times(Node* node, int n, regex_t* reg)
{
  int i, r;

  for (i = 0; i < n; i++) {
    r = compile_tree(node, reg);
    if (r) return r;
  }
  return 0;
}

Project: ruby
File: re.c

rb_reg_match(VALUE re, VALUE str)
{
    long pos = reg_match_pos(re, &str, 0);
    if (pos < 0) return Qnil;
    pos = rb_str_sublen(str, pos);
    return LONG2FIX(pos);
}

Project: ruby
File: regparse.c

node_str_cat_codepoint(Node* node, OnigEncoding enc, OnigCodePoint c)
{
  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
  int num = ONIGENC_CODE_TO_MBC(enc, c, buf);
  if (num < 0) return num;
  return onig_node_str_cat(node, buf, buf + num);
}

Project: ruby
File: re.c

rb_reg_raise_str(VALUE str, int options, const char *err)
{
    rb_exc_raise(rb_reg_error_desc(str, options, err));
}

Project: ruby
File: regcomp.c

compile_cclass_node(CClassNode* cc, regex_t* reg)
{
  int r;

  if (IS_NULL(cc->mbuf)) {
    if (IS_NCCLASS_NOT(cc))
      add_opcode(reg, OP_CCLASS_NOT);
    else
      add_opcode(reg, OP_CCLASS);

    r = add_bitset(reg, cc->bs);
  }
  else {
    if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
      if (IS_NCCLASS_NOT(cc))
	add_opcode(reg, OP_CCLASS_MB_NOT);
      else
	add_opcode(reg, OP_CCLASS_MB);

      r = add_multi_byte_cclass(cc->mbuf, reg);
    }
    else {
      if (IS_NCCLASS_NOT(cc))
	add_opcode(reg, OP_CCLASS_MIX_NOT);
      else
	add_opcode(reg, OP_CCLASS_MIX);

      r = add_bitset(reg, cc->bs);
      if (r) return r;
      r = add_multi_byte_cclass(cc->mbuf, reg);
    }
  }

  return r;
}

Project: ruby
File: re.c

rb_reg_to_s(VALUE re)
{
    int options, opt;
    const int embeddable = ONIG_OPTION_MULTILINE|ONIG_OPTION_IGNORECASE|ONIG_OPTION_EXTEND;
    long len;
    const UChar* ptr;
    VALUE str = rb_str_buf_new2("(?");
    char optbuf[5];
    rb_encoding *enc = rb_enc_get(re);

    rb_reg_check(re);

    rb_enc_copy(str, re);
    options = RREGEXP_PTR(re)->options;
    ptr = (UChar*)RREGEXP_SRC_PTR(re);
    len = RREGEXP_SRC_LEN(re);
  again:
    if (len >= 4 && ptr[0] == '(' && ptr[1] == '?') {
	int err = 1;
	ptr += 2;
	if ((len -= 2) > 0) {
	    do {
                opt = char_to_option((int )*ptr);
                if (opt != 0) {
                    options |= opt;
                }
                else {
                    break;
                }
		++ptr;
	    } while (--len > 0);
	}
	if (len > 1 && *ptr == '-') {
	    ++ptr;
	    --len;
	    do {
                opt = char_to_option((int )*ptr);
                if (opt != 0) {
                    options &= ~opt;
                }
                else {
                    break;
                }
		++ptr;
	    } while (--len > 0);
	}
	if (*ptr == ')') {
	    --len;
	    ++ptr;
	    goto again;
	}
	if (*ptr == ':' && ptr[len-1] == ')') {
	    Regexp *rp;
	    VALUE verbose = ruby_verbose;
	    ruby_verbose = Qfalse;

	    ++ptr;
	    len -= 2;
            err = onig_new(&rp, ptr, ptr + len, ONIG_OPTION_DEFAULT,
			   enc, OnigDefaultSyntax, NULL);
	    onig_free(rp);
	    ruby_verbose = verbose;
	}
	if (err) {
	    options = RREGEXP_PTR(re)->options;
	    ptr = (UChar*)RREGEXP_SRC_PTR(re);
	    len = RREGEXP_SRC_LEN(re);
	}
    }

    if (*option_to_str(optbuf, options)) rb_str_buf_cat2(str, optbuf);

    if ((options & embeddable) != embeddable) {
	optbuf[0] = '-';
	option_to_str(optbuf + 1, ~options);
	rb_str_buf_cat2(str, optbuf);
    }

    rb_str_buf_cat2(str, ":");
    if (rb_enc_asciicompat(enc)) {
	rb_reg_expr_str(str, (char*)ptr, len, enc, NULL);
	rb_str_buf_cat2(str, ")");
    }
    else {
	const char *s, *e;
	char *paren;
	ptrdiff_t n;
	rb_str_buf_cat2(str, ")");
	rb_enc_associate(str, rb_usascii_encoding());
	str = rb_str_encode(str, rb_enc_from_encoding(enc), 0, Qnil);

	/* backup encoded ")" to paren */
	s = RSTRING_PTR(str);
	e = RSTRING_END(str);
	s = rb_enc_left_char_head(s, e-1, e, enc);
	n = e - s;
	paren = ALLOCA_N(char, n);
	memcpy(paren, s, n);
	rb_str_resize(str, RSTRING_LEN(str) - n);

	rb_reg_expr_str(str, (char*)ptr, len, enc, NULL);
	rb_str_buf_cat(str, paren, n);
    }
    rb_enc_copy(str, re);

    OBJ_INFECT(str, re);
    return str;
}

Project: ruby
File: regparse.c

parse_char_property(Node** np, OnigToken* tok, UChar** src, UChar* end,
		    ScanEnv* env)
{
  int r, ctype;
  CClassNode* cc;

  ctype = fetch_char_property_to_ctype(src, end, env);
  if (ctype < 0) return ctype;

  *np = node_new_cclass();
  CHECK_NULL_RETURN_MEMERR(*np);
  cc = NCCLASS(*np);
  r = add_ctype_to_cc(cc, ctype, 0, 0, env);
  if (r != 0) return r;
  if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);

  if (IS_IGNORECASE(env->option)) {
    if (ctype != ONIGENC_CTYPE_ASCII)
      r = cclass_case_fold(np, cc, cc, env);
  }
  return r;
}

Project: ruby
File: re.c

kcode_setter(VALUE val, ID id)
{
    rb_warn("variable $KCODE is no longer effective; ignored");
}

Project: ruby
File: iso_8859_5.c

apply_all_case_fold(OnigCaseFoldType flag,
		    OnigApplyAllCaseFoldFunc f, void* arg,
		    OnigEncoding enc ARG_UNUSED)
{
  return onigenc_apply_all_case_fold_with_map(
             numberof(CaseFoldMap), CaseFoldMap, 0,
             flag, f, arg);
}

Project: ruby
File: regenc.c

onigenc_mb4_code_to_mbclen(OnigCodePoint code, OnigEncoding enc ARG_UNUSED)
{
       if ((code & 0xff000000) != 0) return 4;
  else if ((code & 0xff0000) != 0) return 3;
  else if ((code & 0xff00) != 0) return 2;
  else return 1;
}

Project: ruby
File: re.c

match_named_captures(VALUE match)
{
    VALUE hash;
    struct MEMO *memo;

    match_check(match);

    hash = rb_hash_new();
    memo = MEMO_NEW(hash, match, 0);

    onig_foreach_name(RREGEXP(RMATCH(match)->regexp)->ptr, match_named_captures_iter, (void*)memo);

    return hash;
}

Project: ruby
File: regenc.c

onigenc_str_bytelen_null(OnigEncoding enc, const UChar* s)
{
  UChar* start = (UChar* )s;
  UChar* p = (UChar* )s;
  UChar* e;

  while (1) {
    if (*p == '\0') {
      UChar* q;
      int len = ONIGENC_MBC_MINLEN(enc);

      if (len == 1) return (int )(p - start);
      q = p + 1;
      while (len > 1) {
        if (*q != '\0') break;
        q++;
        len--;
      }
      if (len == 1) return (int )(p - start);
    }
    e = p + ONIGENC_MBC_MAXLEN(enc);
    p += ONIGENC_MBC_ENC_LEN(enc, p, e);
  }
}

Project: ruby
File: regenc.c

onigenc_ascii_is_code_ctype(OnigCodePoint code, unsigned int ctype,
                            OnigEncoding enc ARG_UNUSED)
{
  if (code < 128)
    return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
  else
    return FALSE;
}

Project: ruby
File: regparse.c

propname2ctype(ScanEnv* env, const char* propname)
{
  UChar* name = (UChar* )propname;
  int ctype = env->enc->property_name_to_ctype(ONIG_ENCODING_ASCII,
      name, name + strlen(propname));
  return ctype;
}

Project: ruby
File: regcomp.c

set_optimize_exact_info(regex_t* reg, OptExactInfo* e)
{
  int r;
  int allow_reverse;

  if (e->len == 0) return 0;

  reg->exact = (UChar* )xmalloc(e->len);
  CHECK_NULL_RETURN_MEMERR(reg->exact);
  xmemcpy(reg->exact, e->s, e->len);
  reg->exact_end = reg->exact + e->len;

  allow_reverse =
	ONIGENC_IS_ALLOWED_REVERSE_MATCH(reg->enc, reg->exact, reg->exact_end);

  if (e->ignore_case > 0) {
    if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
      r = set_bm_skip(reg->exact, reg->exact_end, reg,
		      reg->map, &(reg->int_map), 1);
      if (r == 0) {
	reg->optimize = (allow_reverse != 0
			 ? ONIG_OPTIMIZE_EXACT_BM_IC : ONIG_OPTIMIZE_EXACT_BM_NOT_REV_IC);
      }
      else {
	reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
      }
    }
    else {
      reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
    }
  }
  else {
    if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
      r = set_bm_skip(reg->exact, reg->exact_end, reg,
		      reg->map, &(reg->int_map), 0);
      if (r == 0) {
	reg->optimize = (allow_reverse != 0
		       ? ONIG_OPTIMIZE_EXACT_BM : ONIG_OPTIMIZE_EXACT_BM_NOT_REV);
      }
      else {
	reg->optimize = ONIG_OPTIMIZE_EXACT;
      }
    }
    else {
      reg->optimize = ONIG_OPTIMIZE_EXACT;
    }
  }

  reg->dmin = e->mmd.min;
  reg->dmax = e->mmd.max;

  if (reg->dmin != ONIG_INFINITE_DISTANCE) {
    reg->threshold_len = (int )(reg->dmin + (reg->exact_end - reg->exact));
  }

  return 0;
}

Project: ruby
File: re.c

match_to_s(VALUE match)
{
    VALUE str = rb_reg_last_match(match);

    match_check(match);
    if (NIL_P(str)) str = rb_str_new(0,0);
    if (OBJ_TAINTED(match)) OBJ_TAINT(str);
    if (OBJ_TAINTED(RMATCH(match)->str)) OBJ_TAINT(str);
    return str;
}

Project: ruby
File: re.c

rb_reg_s_last_match(int argc, VALUE *argv)
{
    VALUE nth;

    if (argc > 0 && rb_scan_args(argc, argv, "01", &nth) == 1) {
        VALUE match = rb_backref_get();
        int n;
        if (NIL_P(match)) return Qnil;
        n = match_backref_number(match, nth);
	return rb_reg_nth_match(n, match);
    }
    return match_getter();
}

Project: ruby
File: regerror.c

onig_snprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
                           UChar* pat, UChar* pat_end, const UChar *fmt, ...)
{
  va_list args;
  va_start(args, fmt);
  onig_vsnprintf_with_pattern(buf, bufsize, enc,
	  pat, pat_end, fmt, args);
  va_end(args);
}

Project: ruby
File: iso_8859_4.c

is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
  int v;
  const UChar* p = *pp;

  if (*p == SHARP_s && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
    (*pp)++;
    return TRUE;
  }

  (*pp)++;
  v = (EncISO_8859_4_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
  if ((v | BIT_CTYPE_LOWER) != 0) {
    if (*p == 0xa2)
      return FALSE;
    else
      return TRUE;
  }

  return (v != 0 ? TRUE : FALSE);
}

Project: ruby
File: re.c

rb_memsearch_qs_utf8(const unsigned char *xs, long m, const unsigned char *ys, long n)
{
    const unsigned char *x = xs, *xe = xs + m;
    const unsigned char *y = ys;
    VALUE i, qstable[512];

    /* Preprocessing */
    for (i = 0; i < 512; ++i) {
	qstable[i] = m + 1;
    }
    for (; x < xe; ++x) {
	qstable[rb_memsearch_qs_utf8_hash(x)] = xe - x;
    }
    /* Searching */
    for (; y + m <= ys + n; y += qstable[rb_memsearch_qs_utf8_hash(y+m)]) {
	if (*xs == *y && memcmp(xs, y, m) == 0)
	    return y - ys;
    }
    return -1;
}

Project: ruby
File: regexec.c

onig_number_of_captures(const regex_t* reg)
{
  return reg->num_mem;
}

Project: ruby
File: unicode.c

onigenc_unicode_get_case_fold_codes_by_str(OnigEncoding enc,
    OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end,
    OnigCaseFoldCodeItem items[])
{
  int n, i, j, k, len;
  OnigCodePoint code, codes[3];
  const CodePointList3 *to, *z3;
  const CodePointList2 *z2;

  n = 0;

  code = ONIGENC_MBC_TO_CODE(enc, p, end);
  len = enclen(enc, p, end);

#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
  if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
    switch (code) {
    case 'I':
      items[0].byte_len = len;
      items[0].code_len = 1;
      items[0].code[0]  = DOTLESS_i;
      return 1;
    case I_WITH_DOT_ABOVE:
      items[0].byte_len = len;
      items[0].code_len = 1;
      items[0].code[0]  = 'i';
      return 1;
    case DOTLESS_i:
      items[0].byte_len = len;
      items[0].code_len = 1;
      items[0].code[0]  = 'I';
      return 1;
    case 'i':
      items[0].byte_len = len;
      items[0].code_len = 1;
      items[0].code[0]  = I_WITH_DOT_ABOVE;
      return 1;
    }
  }
#endif

  if ((to = onigenc_unicode_fold_lookup(code)) != 0) {
    if (OnigCodePointCount(to->n) == 1) {
      OnigCodePoint orig_code = code;

      items[0].byte_len = len;
      items[0].code_len = 1;
      items[0].code[0]  = to->code[0];
      n++;

      code = to->code[0];
      if ((to = onigenc_unicode_unfold1_lookup(code)) != 0 &&
	  CodePointListValidP(to)) {
	for (i = 0; i < OnigCodePointCount(to->n); i++) {
	  if (to->code[i] != orig_code) {
	    items[n].byte_len = len;
	    items[n].code_len = 1;
	    items[n].code[0]  = to->code[i];
	    n++;
	  }
	}
      }
    }
    else if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
      OnigCodePoint cs[3][4];
      int fn, ncs[3];

      for (fn = 0; fn < OnigCodePointCount(to->n); fn++) {
	cs[fn][0] = to->code[fn];
	if ((z3 = onigenc_unicode_unfold1_lookup(cs[fn][0])) != 0) {
	  for (i = 0; i < OnigCodePointCount(z3->n); i++) {
	    cs[fn][i+1] = z3->code[i];
	  }
	  ncs[fn] = OnigCodePointCount(z3->n) + 1;
	}
	else
	  ncs[fn] = 1;
      }

      if (fn == 2) {
	for (i = 0; i < ncs[0]; i++) {
	  for (j = 0; j < ncs[1]; j++) {
	    items[n].byte_len = len;
	    items[n].code_len = 2;
	    items[n].code[0]  = cs[0][i];
	    items[n].code[1]  = cs[1][j];
	    n++;
	  }
	}

	if ((z2 = onigenc_unicode_unfold2_lookup(to->code)) != 0 &&
	    CodePointListValidP(z2)) {
	  for (i = 0; i < OnigCodePointCount(z2->n); i++) {
	    if (z2->code[i] == code) continue;

	    items[n].byte_len = len;
	    items[n].code_len = 1;
	    items[n].code[0]  = z2->code[i];
	    n++;
	  }
	}
      }
      else {
	for (i = 0; i < ncs[0]; i++) {
	  for (j = 0; j < ncs[1]; j++) {
	    for (k = 0; k < ncs[2]; k++) {
	      items[n].byte_len = len;
	      items[n].code_len = 3;
	      items[n].code[0]  = cs[0][i];
	      items[n].code[1]  = cs[1][j];
	      items[n].code[2]  = cs[2][k];
	      n++;
	    }
	  }
	}

	if ((z2 = onigenc_unicode_unfold3_lookup(to->code)) != 0 &&
	    CodePointListValidP(z2)) {
	  for (i = 0; i < OnigCodePointCount(z2->n); i++) {
	    if (z2->code[i] == code) continue;

	    items[n].byte_len = len;
	    items[n].code_len = 1;
	    items[n].code[0]  = z2->code[i];
	    n++;
	  }
	}
      }

      /* multi char folded code is not head of another folded multi char */
      flag = 0; /* DISABLE_CASE_FOLD_MULTI_CHAR(flag); */
    }
  }
  else {
    if ((to = onigenc_unicode_unfold1_lookup(code)) != 0 &&
	CodePointListValidP(to)) {
      for (i = 0; i < OnigCodePointCount(to->n); i++) {
	items[n].byte_len = len;
	items[n].code_len = 1;
	items[n].code[0]  = to->code[i];
	n++;
      }
    }
  }


  if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
    p += len;
    if (p < end) {
      int clen;

      codes[0] = code;
      code = ONIGENC_MBC_TO_CODE(enc, p, end);
      if ((to = onigenc_unicode_fold_lookup(code)) != 0
	  && OnigCodePointCount(to->n) == 1) {
	codes[1] = to->code[0];
      }
      else
	codes[1] = code;

      clen = enclen(enc, p, end);
      len += clen;
      if ((z2 = onigenc_unicode_unfold2_lookup(codes)) != 0 &&
	  CodePointListValidP(z2)) {
	for (i = 0; i < OnigCodePointCount(z2->n); i++) {
	  items[n].byte_len = len;
	  items[n].code_len = 1;
	  items[n].code[0]  = z2->code[i];
	  n++;
	}
      }

      p += clen;
      if (p < end) {
	code = ONIGENC_MBC_TO_CODE(enc, p, end);
	if ((to = onigenc_unicode_fold_lookup(code)) != 0
	    && OnigCodePointCount(to->n) == 1) {
	  codes[2] = to->code[0];
	}
	else
	  codes[2] = code;

	clen = enclen(enc, p, end);
	len += clen;
	if ((z2 = onigenc_unicode_unfold3_lookup(codes)) != 0 &&
	    CodePointListValidP(z2)) {
	  for (i = 0; i < OnigCodePointCount(z2->n); i++) {
	    items[n].byte_len = len;
	    items[n].code_len = 1;
	    items[n].code[0]  = z2->code[i];
	    n++;
	  }
	}
      }
    }
  }

  return n;
}

Project: ruby
File: re.c

rb_reg_eqq(VALUE re, VALUE str)
{
    long start;

    str = reg_operand(str, FALSE);
    if (NIL_P(str)) {
	rb_backref_set(Qnil);
	return Qfalse;
    }
    start = rb_reg_search(re, str, 0, 0);
    if (start < 0) {
	return Qfalse;
    }
    return Qtrue;
}

Project: ruby
File: regparse.c

countbits(unsigned int bits)
{
  bits = (bits & 0x55555555) + ((bits >> 1) & 0x55555555);
  bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
  bits = (bits & 0x0f0f0f0f) + ((bits >> 4) & 0x0f0f0f0f);
  bits = (bits & 0x00ff00ff) + ((bits >> 8) & 0x00ff00ff);
  return (bits & 0x0000ffff) + ((bits >>16) & 0x0000ffff);
}

Project: ruby
File: regcomp.c

add_rel_addr(regex_t* reg, int addr)
{
  RelAddrType ra = (RelAddrType )addr;

  BBUF_ADD(reg, &ra, SIZE_RELADDR);
  return 0;
}

Project: ruby
File: re.c

match_getter(void)
{
    VALUE match = rb_backref_get();

    if (NIL_P(match)) return Qnil;
    rb_match_busy(match);
    return match;
}

Project: ruby
File: regcomp.c

comp_distance_value(MinMaxLen* d1, MinMaxLen* d2, int v1, int v2)
{
  if (v2 <= 0) return -1;
  if (v1 <= 0) return  1;

  v1 *= distance_value(d1);
  v2 *= distance_value(d2);

  if (v2 > v1) return  1;
  if (v2 < v1) return -1;

  if (d2->min < d1->min) return  1;
  if (d2->min > d1->min) return -1;
  return 0;
}

Project: ruby
File: regparse.c

fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
{
  int num;
  OnigCodePoint c, c2;
  const OnigSyntaxType* syn = env->syntax;
  OnigEncoding enc = env->enc;
  UChar* prev;
  UChar* p = *src;
  PFETCH_READY;

  if (PEND) {
    tok->type = TK_EOT;
    return tok->type;
  }

  PFETCH(c);
  tok->type = TK_CHAR;
  tok->base = 0;
  tok->u.c  = c;
  tok->escaped = 0;

  if (c == ']') {
    tok->type = TK_CC_CLOSE;
  }
  else if (c == '-') {
    tok->type = TK_CC_RANGE;
  }
  else if (c == MC_ESC(syn)) {
    if (! IS_SYNTAX_BV(syn, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC))
      goto end;

    if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;

    PFETCH(c);
    tok->escaped = 1;
    tok->u.c = c;
    switch (c) {
    case 'w':
      tok->type = TK_CHAR_TYPE;
      tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
      tok->u.prop.not   = 0;
      break;
    case 'W':
      tok->type = TK_CHAR_TYPE;
      tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
      tok->u.prop.not   = 1;
      break;
    case 'd':
      tok->type = TK_CHAR_TYPE;
      tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
      tok->u.prop.not   = 0;
      break;
    case 'D':
      tok->type = TK_CHAR_TYPE;
      tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
      tok->u.prop.not   = 1;
      break;
    case 's':
      tok->type = TK_CHAR_TYPE;
      tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
      tok->u.prop.not   = 0;
      break;
    case 'S':
      tok->type = TK_CHAR_TYPE;
      tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
      tok->u.prop.not   = 1;
      break;
    case 'h':
      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
      tok->type = TK_CHAR_TYPE;
      tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
      tok->u.prop.not   = 0;
      break;
    case 'H':
      if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
      tok->type = TK_CHAR_TYPE;
      tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
      tok->u.prop.not   = 1;
      break;

    case 'p':
    case 'P':
      if (PEND) break;

      c2 = PPEEK;
      if (c2 == '{' &&
	  IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY)) {
	PINC;
	tok->type = TK_CHAR_PROPERTY;
	tok->u.prop.not = (c == 'P' ? 1 : 0);

	if (!PEND && IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
	  PFETCH(c2);
	  if (c2 == '^') {
	    tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
	  }
	  else
	    PUNFETCH;
	}
      }
      else {
	onig_syntax_warn(env, "invalid Unicode Property \\%c", c);
      }
      break;

    case 'x':
      if (PEND) break;

      prev = p;
      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_BRACE_HEX8)) {
	PINC;
	num = scan_unsigned_hexadecimal_number(&p, end, 0, 8, enc);
	if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
	if (!PEND) {
	  c2 = PPEEK;
	  if (ONIGENC_IS_CODE_XDIGIT(enc, c2))
	    return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
	}

	if (p > prev + enclen(enc, prev, end) && !PEND && (PPEEK_IS('}'))) {
	  PINC;
	  tok->type   = TK_CODE_POINT;
	  tok->base   = 16;
	  tok->u.code = (OnigCodePoint )num;
	}
	else {
	  /* can't read nothing or invalid format */
	  p = prev;
	}
      }
      else if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_X_HEX2)) {
	num = scan_unsigned_hexadecimal_number(&p, end, 0, 2, enc);
	if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
	if (p == prev) {  /* can't read nothing. */
	  num = 0; /* but, it's not error */
	}
	tok->type = TK_RAW_BYTE;
	tok->base = 16;
	tok->u.c  = num;
      }
      break;

    case 'u':
      if (PEND) break;

      prev = p;
      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_U_HEX4)) {
	num = scan_unsigned_hexadecimal_number(&p, end, 4, 4, enc);
	if (num < -1) return ONIGERR_TOO_SHORT_DIGITS;
	else if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
	if (p == prev) {  /* can't read nothing. */
	  num = 0; /* but, it's not error */
	}
	tok->type   = TK_CODE_POINT;
	tok->base   = 16;
	tok->u.code = (OnigCodePoint )num;
      }
      break;

    case 'o':
      if (PEND) break;

      prev = p;
      if (PPEEK_IS('{') && IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_O_BRACE_OCTAL)) {
	PINC;
	num = scan_unsigned_octal_number(&p, end, 11, enc);
	if (num < 0) return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
	if (!PEND) {
	  c2 = PPEEK;
	  if (ONIGENC_IS_CODE_DIGIT(enc, c2) && c2 < '8')
	    return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
	}

	if (p > prev + enclen(enc, prev, end) && !PEND && (PPEEK_IS('}'))) {
	  PINC;
	  tok->type   = TK_CODE_POINT;
	  tok->base   = 8;
	  tok->u.code = (OnigCodePoint )num;
	}
	else {
	  /* can't read nothing or invalid format */
	  p = prev;
	}
      }
      break;

    case '0':
    case '1': case '2': case '3': case '4': case '5': case '6': case '7':
      if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_OCTAL3)) {
	PUNFETCH;
	prev = p;
	num = scan_unsigned_octal_number(&p, end, 3, enc);
	if (num < 0 || 0xff < num) return ONIGERR_TOO_BIG_NUMBER;
	if (p == prev) {  /* can't read nothing. */
	  num = 0; /* but, it's not error */
	}
	tok->type = TK_RAW_BYTE;
	tok->base = 8;
	tok->u.c  = num;
      }
      break;

    default:
      PUNFETCH;
      num = fetch_escaped_value(&p, end, env, &c2);
      if (num < 0) return num;
      if ((OnigCodePoint)tok->u.c != c2) {
	tok->u.code = (OnigCodePoint )c2;
	tok->type   = TK_CODE_POINT;
      }
      break;
    }
  }
  else if (c == '[') {
    if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_POSIX_BRACKET) && (PPEEK_IS(':'))) {
      OnigCodePoint send[] = { (OnigCodePoint )':', (OnigCodePoint )']' };
      tok->backp = p; /* point at '[' is read */
      PINC;
      if (str_exist_check_with_esc(send, 2, p, end,
                                   (OnigCodePoint )']', enc, syn)) {
	tok->type = TK_POSIX_BRACKET_OPEN;
      }
      else {
	PUNFETCH;
	goto cc_in_cc;
      }
    }
    else {
    cc_in_cc:
      if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP)) {
	tok->type = TK_CC_CC_OPEN;
      }
      else {
	CC_ESC_WARN(env, (UChar* )"[");
      }
    }
  }
  else if (c == '&') {
    if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_CCLASS_SET_OP) &&
	!PEND && (PPEEK_IS('&'))) {
      PINC;
      tok->type = TK_CC_AND;
    }
  }

 end:
  *src = p;
  return tok->type;
}

Project: ruby
File: regcomp.c

set_sub_anchor(regex_t* reg, OptAncInfo* anc)
{
  reg->sub_anchor |= anc->left_anchor  & ANCHOR_BEGIN_LINE;
  reg->sub_anchor |= anc->right_anchor & ANCHOR_END_LINE;
}

Project: ruby
File: regexec.c

history_tree_clear(OnigCaptureTreeNode* node)
{
  int i;

  if (IS_NOT_NULL(node)) {
    for (i = 0; i < node->num_childs; i++) {
      if (IS_NOT_NULL(node->childs[i])) {
	history_tree_free(node->childs[i]);
      }
    }
    for (i = 0; i < node->allocated; i++) {
      node->childs[i] = (OnigCaptureTreeNode* )0;
    }
    node->num_childs = 0;
    node->beg = ONIG_REGION_NOTPOS;
    node->end = ONIG_REGION_NOTPOS;
    node->group = -1;
    xfree(node->childs);
    node->childs = (OnigCaptureTreeNode** )0;
  }
}

Project: ruby
File: regparse.c

onig_number_of_names(const regex_t* reg)
{
  NameTable* t = (NameTable* )reg->name_table;

  if (IS_NOT_NULL(t))
    return t->num;
  else
    return 0;
}

Project: ruby
File: regcomp.c

compile_length_cclass_node(CClassNode* cc, regex_t* reg)
{
  int len;

  if (IS_NULL(cc->mbuf)) {
    len = SIZE_OPCODE + SIZE_BITSET;
  }
  else {
    if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
      len = SIZE_OPCODE;
    }
    else {
      len = SIZE_OPCODE + SIZE_BITSET;
    }
#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
    len += SIZE_LENGTH + cc->mbuf->used;
#else
    len += SIZE_LENGTH + cc->mbuf->used + (WORD_ALIGNMENT_SIZE - 1);
#endif
  }

  return len;
}

Project: ruby
File: windows_1253.c

is_mbc_ambiguous(OnigCaseFoldType flag,
		 const UChar** pp, const UChar* end)
{
  int v;
  const UChar* p = *pp;

  (*pp)++;
  v = (EncCP1253_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
  if ((v | BIT_CTYPE_LOWER) != 0) {
    if (*p == 0xc0 || *p == 0xe0)
      return FALSE;
    else
      return TRUE;
  }

  return (v != 0 ? TRUE : FALSE);
}

Project: ruby
File: re.c

rb_reg_names(VALUE re)
{
    VALUE ary;
    rb_reg_check(re);
    ary = rb_ary_new_capa(onig_number_of_names(RREGEXP_PTR(re)));
    onig_foreach_name(RREGEXP_PTR(re), reg_names_iter, (void*)ary);
    return ary;
}

Project: ruby
File: regparse.c

parse_enclose(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
	      ScanEnv* env)
{
  int r = 0, num;
  Node *target, *work1 = NULL, *work2 = NULL;
  OnigOptionType option;
  OnigCodePoint c;
  OnigEncoding enc = env->enc;

#ifdef USE_NAMED_GROUP
  int list_capture;
#endif

  UChar* p = *src;
  PFETCH_READY;

  *np = NULL;
  if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;

  option = env->option;
  if (PPEEK_IS('?') &&
      IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_GROUP_EFFECT)) {
    PINC;
    if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;

    PFETCH(c);
    switch (c) {
    case ':':   /* (?:...) grouping only */
    group:
      r = fetch_token(tok, &p, end, env);
      if (r < 0) return r;
      r = parse_subexp(np, tok, term, &p, end, env);
      if (r < 0) return r;
      *src = p;
      return 1; /* group */
      break;

    case '=':
      *np = onig_node_new_anchor(ANCHOR_PREC_READ);
      break;
    case '!':   /* preceding read */
      *np = onig_node_new_anchor(ANCHOR_PREC_READ_NOT);
      break;
    case '>':   /* (?>...) stop backtrack */
      *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
      break;

#ifdef USE_NAMED_GROUP
    case '\'':
      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
	goto named_group1;
      }
      else
	return ONIGERR_UNDEFINED_GROUP_OPTION;
      break;

# ifdef USE_CAPITAL_P_NAMED_GROUP
    case 'P':   /* (?P<name>...) */
      if (!PEND &&
	  IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_CAPITAL_P_NAMED_GROUP)) {
	PFETCH(c);
	if (c == '<') goto named_group1;
      }
      return ONIGERR_UNDEFINED_GROUP_OPTION;
      break;
# endif
#endif

    case '<':   /* look behind (?<=...), (?<!...) */
      if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
      PFETCH(c);
      if (c == '=')
	*np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND);
      else if (c == '!')
	*np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND_NOT);
#ifdef USE_NAMED_GROUP
      else {    /* (?<name>...) */
	if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
	  UChar *name;
	  UChar *name_end;

	  PUNFETCH;
	  c = '<';

	named_group1:
	  list_capture = 0;

	named_group2:
	  name = p;
	  r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0);
	  if (r < 0) return r;

	  num = scan_env_add_mem_entry(env);
	  if (num < 0) return num;
	  if (list_capture != 0 && num >= (int )BIT_STATUS_BITS_NUM)
	    return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;

	  r = name_add(env->reg, name, name_end, num, env);
	  if (r != 0) return r;
	  *np = node_new_enclose_memory(env->option, 1);
	  CHECK_NULL_RETURN_MEMERR(*np);
	  NENCLOSE(*np)->regnum = num;
	  if (list_capture != 0)
	    BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
	  env->num_named++;
	}
	else {
	  return ONIGERR_UNDEFINED_GROUP_OPTION;
	}
      }
#else
      else {
	return ONIGERR_UNDEFINED_GROUP_OPTION;
      }
#endif
      break;

    case '@':
      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY)) {
#ifdef USE_NAMED_GROUP
	if (!PEND &&
	    IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
	  PFETCH(c);
	  if (c == '<' || c == '\'') {
	    list_capture = 1;
	    goto named_group2; /* (?@<name>...) */
	  }
	  PUNFETCH;
	}
#endif
	*np = node_new_enclose_memory(env->option, 0);
	CHECK_NULL_RETURN_MEMERR(*np);
	num = scan_env_add_mem_entry(env);
	if (num < 0) return num;
	if (num >= (int )BIT_STATUS_BITS_NUM)
	  return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;

	NENCLOSE(*np)->regnum = num;
	BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
      }
      else {
	return ONIGERR_UNDEFINED_GROUP_OPTION;
      }
      break;

    case '(':   /* conditional expression: (?(cond)yes), (?(cond)yes|no) */
      if (!PEND &&
	  IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LPAREN_CONDITION)) {
	UChar *name = NULL;
	UChar *name_end;
	PFETCH(c);
	if (ONIGENC_IS_CODE_DIGIT(enc, c)) {     /* (n) */
	  PUNFETCH;
	  r = fetch_name((OnigCodePoint )'(', &p, end, &name_end, env, &num, 1);
	  if (r < 0) return r;
#if 0
	  /* Relative number is not currently supported. (same as Perl) */
	  if (num < 0) {
	    num = BACKREF_REL_TO_ABS(num, env);
	    if (num <= 0)
	      return ONIGERR_INVALID_BACKREF;
	  }
#endif
	  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_STRICT_CHECK_BACKREF)) {
	    if (num > env->num_mem ||
		IS_NULL(SCANENV_MEM_NODES(env)[num]))
	    return ONIGERR_INVALID_BACKREF;
	  }
	}
#ifdef USE_NAMED_GROUP
	else if (c == '<' || c == '\'') {    /* (<name>), ('name') */
	  name = p;
	  r = fetch_named_backref_token(c, tok, &p, end, env);
	  if (r < 0) return r;
	  if (!PPEEK_IS(')')) return ONIGERR_UNDEFINED_GROUP_OPTION;
	  PINC;

	  if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_USE_LEFT_MOST_NAMED_GROUP)) {
	    num = tok->u.backref.ref1;
	  }
	  else {
	    /* FIXME:
	     * Use left most named group for now. This is the same as Perl.
	     * However this should use the same strategy as normal back-
	     * references on Ruby syntax; search right to left. */
	    int len = tok->u.backref.num;
	    num = len > 1 ? tok->u.backref.refs[0] : tok->u.backref.ref1;
	  }
	}
#endif
	else
	  return ONIGERR_INVALID_CONDITION_PATTERN;
	*np = node_new_enclose(ENCLOSE_CONDITION);
	CHECK_NULL_RETURN_MEMERR(*np);
	NENCLOSE(*np)->regnum = num;
	if (IS_NOT_NULL(name)) NENCLOSE(*np)->state |= NST_NAME_REF;
      }
      else
	return ONIGERR_UNDEFINED_GROUP_OPTION;
      break;

#if 0
    case '|':   /* branch reset: (?|...) */
      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_VBAR_BRANCH_RESET)) {
	/* TODO */
      }
      else
	return ONIGERR_UNDEFINED_GROUP_OPTION;
      break;
#endif

    case '^':   /* loads default options */
      if (!PEND && IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
	/* d-imsx */
	ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
	ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
	ONOFF(option, ONIG_OPTION_SINGLELINE, 0);
	ONOFF(option, ONIG_OPTION_MULTILINE,  1);
	ONOFF(option, ONIG_OPTION_EXTEND, 1);
	PFETCH(c);
      }
#if 0
      else if (!PEND && IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
	/* d-imx */
	ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
	ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 0);
	ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 0);
	ONOFF(option, ONIG_OPTION_IGNORECASE, 1);
	ONOFF(option, ONIG_OPTION_MULTILINE,  1);
	ONOFF(option, ONIG_OPTION_EXTEND, 1);
	PFETCH(c);
      }
#endif
      else {
	return ONIGERR_UNDEFINED_GROUP_OPTION;
      }
      /* fall through */
#ifdef USE_POSIXLINE_OPTION
    case 'p':
#endif
    case '-': case 'i': case 'm': case 's': case 'x':
    case 'a': case 'd': case 'l': case 'u':
      {
	int neg = 0;

	while (1) {
	  switch (c) {
	  case ':':
	  case ')':
	  break;

	  case '-':  neg = 1; break;
	  case 'x':  ONOFF(option, ONIG_OPTION_EXTEND,     neg); break;
	  case 'i':  ONOFF(option, ONIG_OPTION_IGNORECASE, neg); break;
	  case 's':
	    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
	      ONOFF(option, ONIG_OPTION_MULTILINE,  neg);
	    }
	    else
	      return ONIGERR_UNDEFINED_GROUP_OPTION;
	    break;

	  case 'm':
	    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL)) {
	      ONOFF(option, ONIG_OPTION_SINGLELINE, (neg == 0 ? 1 : 0));
	    }
	    else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) {
	      ONOFF(option, ONIG_OPTION_MULTILINE,  neg);
	    }
	    else
	      return ONIGERR_UNDEFINED_GROUP_OPTION;
	    break;
#ifdef USE_POSIXLINE_OPTION
	  case 'p':
	    ONOFF(option, ONIG_OPTION_MULTILINE|ONIG_OPTION_SINGLELINE, neg);
	    break;
#endif

	  case 'a':     /* limits \d, \s, \w and POSIX brackets to ASCII range */
	    if ((IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) ||
		 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
		(neg == 0)) {
	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
	      ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 1);
	      ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 1);
	    }
	    else
	      return ONIGERR_UNDEFINED_GROUP_OPTION;
	    break;

	  case 'u':
	    if ((IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) ||
		 IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY)) &&
		(neg == 0)) {
	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
	      ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 1);
	      ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 1);
	    }
	    else
	      return ONIGERR_UNDEFINED_GROUP_OPTION;
	    break;

	  case 'd':
	    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) &&
		(neg == 0)) {
	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
	    }
	    else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_RUBY) &&
		(neg == 0)) {
	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 0);
	      ONOFF(option, ONIG_OPTION_POSIX_BRACKET_ALL_RANGE, 0);
	      ONOFF(option, ONIG_OPTION_WORD_BOUND_ALL_RANGE, 0);
	    }
	    else
	      return ONIGERR_UNDEFINED_GROUP_OPTION;
	    break;

	  case 'l':
	    if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_OPTION_PERL) && (neg == 0)) {
	      ONOFF(option, ONIG_OPTION_ASCII_RANGE, 1);
	    }
	    else
	      return ONIGERR_UNDEFINED_GROUP_OPTION;
	    break;

	  default:
	    return ONIGERR_UNDEFINED_GROUP_OPTION;
	  }

	  if (c == ')') {
	    *np = node_new_option(option);
	    CHECK_NULL_RETURN_MEMERR(*np);
	    *src = p;
	    return 2; /* option only */
	  }
	  else if (c == ':') {
	    OnigOptionType prev = env->option;

	    env->option = option;
	    r = fetch_token(tok, &p, end, env);
	    if (r < 0) {
	      env->option = prev;
	      return r;
	    }
	    r = parse_subexp(&target, tok, term, &p, end, env);
	    env->option = prev;
	    if (r < 0) return r;
	    *np = node_new_option(option);
	    CHECK_NULL_RETURN_MEMERR(*np);
	    NENCLOSE(*np)->target = target;
	    *src = p;
	    return 0;
	  }

	  if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
	  PFETCH(c);
	}
      }
      break;

    default:
      return ONIGERR_UNDEFINED_GROUP_OPTION;
    }
  }
  else {
    if (ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_DONT_CAPTURE_GROUP))
      goto group;

    *np = node_new_enclose_memory(env->option, 0);
    CHECK_NULL_RETURN_MEMERR(*np);
    num = scan_env_add_mem_entry(env);
    if (num < 0) return num;
    NENCLOSE(*np)->regnum = num;
  }

  CHECK_NULL_RETURN_MEMERR(*np);
  r = fetch_token(tok, &p, end, env);
  if (r < 0) return r;
  r = parse_subexp(&target, tok, term, &p, end, env);
  if (r < 0) {
    onig_node_free(target);
    return r;
  }

  if (NTYPE(*np) == NT_ANCHOR)
    NANCHOR(*np)->target = target;
  else {
    NENCLOSE(*np)->target = target;
    if (NENCLOSE(*np)->type == ENCLOSE_MEMORY) {
      /* Don't move this to previous of parse_subexp() */
      r = scan_env_set_mem_node(env, NENCLOSE(*np)->regnum, *np);
      if (r != 0) return r;
    }
    else if (NENCLOSE(*np)->type == ENCLOSE_CONDITION) {
      if (NTYPE(target) != NT_ALT) {
	/* convert (?(cond)yes) to (?(cond)yes|empty) */
	work1 = node_new_empty();
	if (IS_NULL(work1)) goto err;
	work2 = onig_node_new_alt(work1, NULL_NODE);
	if (IS_NULL(work2)) goto err;
	work1 = onig_node_new_alt(target, work2);
	if (IS_NULL(work1)) goto err;
	NENCLOSE(*np)->target = work1;
      }
    }
  }

  *src = p;
  return 0;

 err:
  onig_node_free(work1);
  onig_node_free(work2);
  onig_node_free(*np);
  *np = NULL;
  return ONIGERR_MEMORY;
}

Project: ruby
File: regcomp.c

select_str_opcode(int mb_len, OnigDistance byte_len, int ignore_case)
{
  int op;
  OnigDistance str_len = (byte_len + mb_len - 1) / mb_len;

  if (ignore_case) {
    switch (str_len) {
    case 1:  op = OP_EXACT1_IC; break;
    default: op = OP_EXACTN_IC; break;
    }
  }
  else {
    switch (mb_len) {
    case 1:
      switch (str_len) {
      case 1:  op = OP_EXACT1; break;
      case 2:  op = OP_EXACT2; break;
      case 3:  op = OP_EXACT3; break;
      case 4:  op = OP_EXACT4; break;
      case 5:  op = OP_EXACT5; break;
      default: op = OP_EXACTN; break;
      }
      break;

    case 2:
      switch (str_len) {
      case 1:  op = OP_EXACTMB2N1; break;
      case 2:  op = OP_EXACTMB2N2; break;
      case 3:  op = OP_EXACTMB2N3; break;
      default: op = OP_EXACTMB2N;  break;
      }
      break;

    case 3:
      op = OP_EXACTMB3N;
      break;

    default:
      op = OP_EXACTMBN;
      break;
    }
  }
  return op;
}

Project: ruby
File: iso_8859_7.c

is_mbc_ambiguous(OnigCaseFoldType flag,
		 const UChar** pp, const UChar* end)
{
  int v;
  const UChar* p = *pp;

  (*pp)++;
  v = (EncISO_8859_7_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
  if ((v | BIT_CTYPE_LOWER) != 0) {
    if (*p == 0xc0 || *p == 0xe0)
      return FALSE;
    else
      return TRUE;
  }

  return (v != 0 ? TRUE : FALSE);
}

Project: ruby
File: regcomp.c

expand_case_fold_string_alt(int item_num, OnigCaseFoldCodeItem items[],
			    UChar *p, int slen, UChar *end,
			    regex_t* reg, Node **rnode)
{
  int r, i, j, len, varlen;
  Node *anode, *var_anode, *snode, *xnode, *an;
  UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];

  *rnode = var_anode = NULL_NODE;

  varlen = 0;
  for (i = 0; i < item_num; i++) {
    if (items[i].byte_len != slen) {
      varlen = 1;
      break;
    }
  }

  if (varlen != 0) {
    *rnode = var_anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
    if (IS_NULL(var_anode)) return ONIGERR_MEMORY;

    xnode = onig_node_new_list(NULL, NULL);
    if (IS_NULL(xnode)) goto mem_err;
    NCAR(var_anode) = xnode;

    anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
    if (IS_NULL(anode)) goto mem_err;
    NCAR(xnode) = anode;
  }
  else {
    *rnode = anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
    if (IS_NULL(anode)) return ONIGERR_MEMORY;
  }

  snode = onig_node_new_str(p, p + slen);
  if (IS_NULL(snode)) goto mem_err;

  NCAR(anode) = snode;

  for (i = 0; i < item_num; i++) {
    snode = onig_node_new_str(NULL, NULL);
    if (IS_NULL(snode)) goto mem_err;

    for (j = 0; j < items[i].code_len; j++) {
      len = ONIGENC_CODE_TO_MBC(reg->enc, items[i].code[j], buf);
      if (len < 0) {
	r = len;
	goto mem_err2;
      }

      r = onig_node_str_cat(snode, buf, buf + len);
      if (r != 0) goto mem_err2;
    }

    an = onig_node_new_alt(NULL_NODE, NULL_NODE);
    if (IS_NULL(an)) {
      goto mem_err2;
    }

    if (items[i].byte_len != slen) {
      Node *rem;
      UChar *q = p + items[i].byte_len;

      if (q < end) {
	r = expand_case_fold_make_rem_string(&rem, q, end, reg);
	if (r != 0) {
	  onig_node_free(an);
	  goto mem_err2;
	}

	xnode = onig_node_list_add(NULL_NODE, snode);
	if (IS_NULL(xnode)) {
	  onig_node_free(an);
	  onig_node_free(rem);
	  goto mem_err2;
	}
	if (IS_NULL(onig_node_list_add(xnode, rem))) {
	  onig_node_free(an);
	  onig_node_free(xnode);
	  onig_node_free(rem);
	  goto mem_err;
	}

	NCAR(an) = xnode;
      }
      else {
	NCAR(an) = snode;
      }

      NCDR(var_anode) = an;
      var_anode = an;
    }
    else {
      NCAR(an)     = snode;
      NCDR(anode) = an;
      anode = an;
    }
  }

  return varlen;

 mem_err2:
  onig_node_free(snode);

 mem_err:
  onig_node_free(*rnode);

  return ONIGERR_MEMORY;
}

Project: ruby
File: re.c

rb_memcicmp(const void *x, const void *y, long len)
{
    const unsigned char *p1 = x, *p2 = y;
    int tmp;

    while (len--) {
	if ((tmp = casetable[(unsigned)*p1++] - casetable[(unsigned)*p2++]))
	    return tmp;
    }
    return 0;
}

Project: ruby
File: re.c

match_setter(VALUE val)
{
    if (!NIL_P(val)) {
	Check_Type(val, T_MATCH);
    }
    rb_backref_set(val);
}

Project: ruby
File: re.c

rb_reg_initialize(VALUE obj, const char *s, long len, rb_encoding *enc,
		  int options, onig_errmsg_buffer err,
		  const char *sourcefile, int sourceline)
{
    struct RRegexp *re = RREGEXP(obj);
    VALUE unescaped;
    rb_encoding *fixed_enc = 0;
    rb_encoding *a_enc = rb_ascii8bit_encoding();

    rb_check_frozen(obj);
    if (FL_TEST(obj, REG_LITERAL))
	rb_raise(rb_eSecurityError, "can't modify literal regexp");
    if (re->ptr)
        rb_raise(rb_eTypeError, "already initialized regexp");
    re->ptr = 0;

    if (rb_enc_dummy_p(enc)) {
	errcpy(err, "can't make regexp with dummy encoding");
	return -1;
    }

    unescaped = rb_reg_preprocess(s, s+len, enc, &fixed_enc, err);
    if (unescaped == Qnil)
        return -1;

    if (fixed_enc) {
	if ((fixed_enc != enc && (options & ARG_ENCODING_FIXED)) ||
            (fixed_enc != a_enc && (options & ARG_ENCODING_NONE))) {
	    errcpy(err, "incompatible character encoding");
	    return -1;
	}
        if (fixed_enc != a_enc) {
	    options |= ARG_ENCODING_FIXED;
	    enc = fixed_enc;
	}
    }
    else if (!(options & ARG_ENCODING_FIXED)) {
       enc = rb_usascii_encoding();
    }

    rb_enc_associate((VALUE)re, enc);
    if ((options & ARG_ENCODING_FIXED) || fixed_enc) {
	re->basic.flags |= KCODE_FIXED;
    }
    if (options & ARG_ENCODING_NONE) {
        re->basic.flags |= REG_ENCODING_NONE;
    }

    re->ptr = make_regexp(RSTRING_PTR(unescaped), RSTRING_LEN(unescaped), enc,
			  options & ARG_REG_OPTION_MASK, err,
			  sourcefile, sourceline);
    if (!re->ptr) return -1;
    RB_GC_GUARD(unescaped);
    return 0;
}

Project: ruby
File: re.c

rb_reg_quote(VALUE str)
{
    rb_encoding *enc = rb_enc_get(str);
    char *s, *send, *t;
    VALUE tmp;
    int c, clen;
    int ascii_only = rb_enc_str_asciionly_p(str);

    s = RSTRING_PTR(str);
    send = s + RSTRING_LEN(str);
    while (s < send) {
        c = rb_enc_ascget(s, send, &clen, enc);
	if (c == -1) {
            s += mbclen(s, send, enc);
	    continue;
	}
	switch (c) {
	  case '[': case ']': case '{': case '}':
	  case '(': case ')': case '|': case '-':
	  case '*': case '.': case '\\':
	  case '?': case '+': case '^': case '$':
	  case ' ': case '#':
	  case '\t': case '\f': case '\v': case '\n': case '\r':
	    goto meta_found;
	}
        s += clen;
    }
    tmp = rb_str_new3(str);
    if (ascii_only) {
        rb_enc_associate(tmp, rb_usascii_encoding());
    }
    return tmp;

  meta_found:
    tmp = rb_str_new(0, RSTRING_LEN(str)*2);
    if (ascii_only) {
        rb_enc_associate(tmp, rb_usascii_encoding());
    }
    else {
        rb_enc_copy(tmp, str);
    }
    t = RSTRING_PTR(tmp);
    /* copy upto metacharacter */
    memcpy(t, RSTRING_PTR(str), s - RSTRING_PTR(str));
    t += s - RSTRING_PTR(str);

    while (s < send) {
        c = rb_enc_ascget(s, send, &clen, enc);
	if (c == -1) {
	    int n = mbclen(s, send, enc);

	    while (n--)
		*t++ = *s++;
	    continue;
	}
        s += clen;
	switch (c) {
	  case '[': case ']': case '{': case '}':
	  case '(': case ')': case '|': case '-':
	  case '*': case '.': case '\\':
	  case '?': case '+': case '^': case '$':
	  case '#':
            t += rb_enc_mbcput('\\', t, enc);
	    break;
	  case ' ':
            t += rb_enc_mbcput('\\', t, enc);
            t += rb_enc_mbcput(' ', t, enc);
	    continue;
	  case '\t':
            t += rb_enc_mbcput('\\', t, enc);
            t += rb_enc_mbcput('t', t, enc);
	    continue;
	  case '\n':
            t += rb_enc_mbcput('\\', t, enc);
            t += rb_enc_mbcput('n', t, enc);
	    continue;
	  case '\r':
            t += rb_enc_mbcput('\\', t, enc);
            t += rb_enc_mbcput('r', t, enc);
	    continue;
	  case '\f':
            t += rb_enc_mbcput('\\', t, enc);
            t += rb_enc_mbcput('f', t, enc);
	    continue;
	  case '\v':
            t += rb_enc_mbcput('\\', t, enc);
            t += rb_enc_mbcput('v', t, enc);
	    continue;
	}
        t += rb_enc_mbcput(c, t, enc);
    }
    rb_str_resize(tmp, t - RSTRING_PTR(tmp));
    OBJ_INFECT(tmp, str);
    return tmp;
}

Project: ruby
File: windows_1254.c

is_code_ctype(OnigCodePoint code, unsigned int ctype, OnigEncoding enc ARG_UNUSED)
{
  if (code < 256)
    return ENC_IS_CP1254_CTYPE(code, ctype);
  else
    return FALSE;
}

Project: ruby
File: regparse.c

str_node_split_last_char(StrNode* sn, OnigEncoding enc)
{
  const UChar *p;
  Node* n = NULL_NODE;

  if (sn->end > sn->s) {
    p = onigenc_get_prev_char_head(enc, sn->s, sn->end, sn->end);
    if (p && p > sn->s) { /* can be split. */
      n = node_new_str(p, sn->end);
      if (IS_NOT_NULL(n) && (sn->flag & NSTR_RAW) != 0)
	NSTRING_SET_RAW(n);
      sn->end = (UChar* )p;
    }
  }
  return n;
}

Project: ruby
File: regenc.c

onigenc_get_left_adjust_char_head(OnigEncoding enc, const UChar* start, const UChar* s, const UChar* end)
{
  return ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s, end);
}

Project: ruby
File: regparse.c

scan_unsigned_hexadecimal_number(UChar** src, UChar* end, int minlen,
				 int maxlen, OnigEncoding enc)
{
  OnigCodePoint c;
  unsigned int num, val;
  int restlen;
  UChar* p = *src;
  PFETCH_READY;

  restlen = maxlen - minlen;
  num = 0;
  while (!PEND && maxlen-- != 0) {
    PFETCH(c);
    if (ONIGENC_IS_CODE_XDIGIT(enc, c)) {
      val = (unsigned int )XDIGITVAL(enc,c);
      if ((INT_MAX_LIMIT - val) / 16UL < num)
	return -1;  /* overflow */

      num = (num << 4) + XDIGITVAL(enc,c);
    }
    else {
      PUNFETCH;
      maxlen++;
      break;
    }
  }
  if (maxlen > restlen)
    return -2;  /* not enough digits */
  *src = p;
  return num;
}