History
+2018/12/11: Version 6.9.1
+
+2018/10/08: use ENC_FLAG_SKIP_OFFSET_XXX values
+2018/10/06: UTF-8 supports code range from 0x0000 to 0x10FFFF
+ (https://tools.ietf.org/html/rfc3629)
+2018/10/05: speed improvement
+2018/10/03: use OPTIMIZE_STR_CASE_FOLD_FAST
+2018/10/01: convert CRLF line endings to LF
+2018/09/27: set SIZEOF_SIZE_T for windows platforms
+2018/09/22: use Sunday quick search algorithm instead of Boyer-Moor-Horspool
+2018/09/20: introduce threaded code into match_at()
+2018/09/17: remove HAVE_STRINGS_H
+2018/09/16: remove HAVE_PROTOTYPES and HAVE_STDARG_PROTOTYPES
+2018/09/14: add a command line option '-gc' for make_unicode_property_data.py.
+2018/09/08: remove AC_HEADER_STDC
+2018/09/06: remove AC_OUTPUT macro call
+2018/09/06: remove AC_FUNC_MEMCMP, AC_HEADER_TIME, AC_C_CONST, HAVE__SETJMP and
+ HAVE_STRING_H
+2018/09/05: remove HAVE_LIMITS_H, HAVE_FLOAT_H and HAVE_STDLIB_H
+
2018/09/03: Version 6.9.0
2018/08/24: add Unicode Emoji properties
2006/11/07: [dist] remove test.rb, testconv.rb and testconvu.rb.
2006/11/07: [bug] get_case_fold_codes_by_str() should handle 'Ss' and 'sS'
combination for ess-tsett.
-2006/11/07: [impl] apply_all_case_fold() doesn't need to return all
+2006/11/07: [impl] apply_all_case_fold() doesn't need to return all
case character combination for multi-character folding.
(ONIGENC_CASE_FOLD_MULTI_CHAR)
2006/11/07: [bug] (thanks Byte)
add { 0xa3, 0xb3 } to CaseFoldMap[] for KOI8-R.
-2006/11/06: [spec] change ONIG_OPTION_FIND_LONGEST to search all of
+2006/11/06: [spec] change ONIG_OPTION_FIND_LONGEST to search all of
the string range.
add USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE.
2006/11/02: [impl] re-implement expand_case_fold_string() for
2006/05/11: [test] success in ruby 1.9.0 (2006-03-01) [i686-linux].
2006/05/11: [bug] (thanks Yuji Kaneda)
- dead-lock in onig_end().
+ dead-lock in onig_end().
2006/05/11: [dist] update index.html.
2006/05/08: Version 4.0.3
use GNU libtool/automake.
change configure.in and add Makefile.am, sample/Makefile.am.
add AUTHORS file.
-2006/01/24: [dist] test programs return exit code -1 when test fails.
+2006/01/24: [dist] test programs return exit code -1 when test fails.
2006/01/24: [bug] (thanks KIMURA Koichi)
invalid syntax definition in ONIG_SYNTAX_GREP.
ONIG_SYN_OP_BRACE_INTERVAL
2005/11/24: [test] success in ruby 1.9.0 (2005-08-09) [i686-linux].
2005/11/21: [test] success in ruby 1.9.0 (2005-11-20) [i386-cygwin].
2005/11/21: [bug] (thanks Allan Odgaard)
- utf-8 character comments in extended mode leads
+ utf-8 character comments in extended mode leads
invalid result.
ex. /(?x)(?<= # <any-utf-8 multibyte char>o\n~) /
fix onigenc_unicode_is_code_ctype() and
add new character encoding ONIG_ENCODING_GB18030.
2005/06/30: [bug] invalid ctype check for multibyte encodings.
("graph", "print")
- fix onigenc_mb2/4_is_code_ctype(),
+ fix onigenc_mb2/4_is_code_ctype(),
eucjp_is_code_ctype() and sjis_is_code_ctype().
2005/06/30: [bug] invalid conversion from code point to mbc in
onigenc_mb4_code_to_mbc().
remove oniggnu.h from make 19.
2005/03/01: [bug] (thanks matz) [ruby-dev:25778]
uninitialized member (OptEnv.backrefed_status)
- was used.
+ was used.
2005/02/19: Version 3.7.0
2005/01/19: [bug] (thanks Isao Sonobe)
callback function argument name_end of onig_foreach_name()
was wrong.
- name key of name table should be null terminated for
+ name key of name table should be null terminated for
character encoding length.
add strdup_with_null(), rename onig_strdup() to k_strdup().
use e->name_len in i_names().
RelAddrType, AbsAddrType and LengthType change
from short int to int type for the very long string match.
2004/06/14: [bug] (thanks Greg A. Woods)
- fix nmatch argument of regexec() is smaller than
+ fix nmatch argument of regexec() is smaller than
reg->num_mem + 1 case. (POSIX API)
2004/06/14: [spec] (thanks Greg A. Woods)
set pmatch to NULL if nmatch is 0 in regexec(). (POSIX API)
2004/02/23: [new] support ISO-8859-10. (ONIG_ENCODING_ISO_8859_10)
2004/02/20: [bug] fix iso_8859_4_mbc_is_case_ambig().
2004/02/20: [new] support ISO-8859-9. (ONIG_ENCODING_ISO_8859_9)
-2004/02/19: [bug] correct ctype tables for ISO-8859-3, ISO-8859-4,
+2004/02/19: [bug] correct ctype tables for ISO-8859-3, ISO-8859-4,
ISO-8859-6, ISO-8859-7, ISO-8859-8, KOI8_R.
2004/02/18: [bug] wrong replaced name OnigSyntaxGnuOnigex.
2004/02/17: [spec] check capture status for empty infinite loop.
2003/11/11: [spec] add syntax op. REG_SYN_OP_VARIABLE_META_CHARS.
2003/11/11: [spec] rename REG_SYN_OP_ESC_CAPITAL_Q_QUOTE to
REG_SYN_OP2_ESC_CAPITAL_Q_QUOTE,
- REG_SYN_OP_QMARK_GROUP_EFFECT to
+ REG_SYN_OP_QMARK_GROUP_EFFECT to
REG_SYN_OP2_QMARK_GROUP_EFFECT.
2003/11/06: [impl] define THREAD_PASS as rb_thread_schedule() in Ruby mode.
2003/11/05: [spec] add syntax behavior REG_SYN_WARN_REDUNDANT_NESTED_REPEAT.
2003/10/03: [bug] (thanks nobu) [ruby-dev:21472]
sub-anchor of optimization map info was wrong
in concat_left_node_opt_info().
- ex. /^(x?y)/ = "xy" fail.
+ ex. /^(x?y)/ = "xy" fail.
2003/09/17: Version 1.9.4
2003/09/01: [dist] update doc/RE and doc/RE.ja.
2003/08/26: [bug] (thanks Guy Decoux)
should not double free node at the case TK_CC_CC_OPEN
- in parse_char_class().
+ in parse_char_class().
2003/08/19: Version 1.9.3
REG_SYN_OP2_ATMARK_CAPTURE_HISTORY.
2003/08/18: [spec] (thanks nobu)
don't use IMPORT in oniguruma.h and onigposix.h.
-2003/08/18: [impl] (thanks nobu) change error output to stdout in testconv.rb.
-2003/08/18: [inst] (thanks nobu) lacked $(srcdir) in Makefile.in.
+2003/08/18: [impl] (thanks nobu) change error output to stdout in testconv.rb.
+2003/08/18: [inst] (thanks nobu) lacked $(srcdir) in Makefile.in.
2003/08/18: [bug] REG_MBLEN_TABLE[SJIS][0xFD-0xFF] should be 1.
2003/08/18: [bug] (thanks nobu) mbctab_sjis[0x80] should be 0.
2003/08/18: [bug] (thanks nobu)
2003/07/29: [new] add regex_get_encoding(), regex_get_options() and
regex_get_syntax().
2003/07/25: [spec] (thanks akr)
- change group(...) to shy-group(?:...) if named group is
+ change group(...) to shy-group(?:...) if named group is
used in the pattern.
add REG_SYN_CAPTURE_ONLY_NAMED_GROUP.
2003/07/24: [spec] rename REG_OPTION_CAPTURE_ONLY_NAMED_GROUP to
set option status to effect memory in optimize_node_left().
2003/07/07: [impl] add opcode OP_ANYCHAR_ML, OP_ANYCHAR_ML_STAR and
OP_ANYCHAR_ML_START_PEEK_NEXT.
-2003/07/07: [bug] (thanks nobu) REG_MBLEN_TABLE[SJIS][0x80] should be 1.
+2003/07/07: [bug] (thanks nobu) REG_MBLEN_TABLE[SJIS][0x80] should be 1.
2003/07/07: [spec] rename REG_SYN_OP_QUOTE to REG_SYN_OP_ESC_Q_QUOTE.
2003/07/04: Version 1.9.1
2003/06/12: [spec] add syntax behavior REG_SYN_WARN_FOR_CC_OP_NOT_ESCAPEED.
2003/06/12: [spec] invalid POSIX bracket should be error. ex. [[:upper :]]
2003/06/11: [new] char-class in char-class (as Java(TM)).
-2003/06/11: [spec] change AND operator in char-class from &&[..] to &&.
+2003/06/11: [spec] change AND operator in char-class from &&[..] to &&.
2003/06/04: [spec] {n,m}+ should not be possessive operator.
ex. a{3}+ should be (?:a{3})+
2003/06/03: [bug] should compare strings with min-length in is_not_included().
2003/02/26: [impl] add -win option to testconv.rb.
2003/02/25: [spec] allow to assign same name to different group.
add OP_BACKREF_MULTI.
-2003/02/24: [impl] reduce redundant repeat of empty target.
+2003/02/24: [impl] reduce redundant repeat of empty target.
ex. /()*/ ==> /()?/, /()+/ ==> /()/, /(?:)+/ ==> //
2003/02/24: [impl] change condition in regex_is_allow_reverse_match().
2003/02/24: [impl] convert i(/../, ...) functions in testconv.rb.
2003/02/04: [bug] typo miss in regex_region_copy().
2003/02/04: [impl] change THREAD_PASS macro. (regint.h)
2003/02/04: [dist] add API document file doc/API.
-2003/02/04: [tune] if sub_anchor has ANCHOR_BEGIN_LINE then
+2003/02/04: [tune] if sub_anchor has ANCHOR_BEGIN_LINE then
set REG_OPTIMIZE_EXACT_BM in set_optimize_exact_info().
2003/02/04: [spec] reimplement regex_clone() and it is obsoleted.
2003/02/04: [bug] add REGERR_OVER_THREAD_PASS_LIMIT_COUNT
2002/04/01: [dist] add COPYING.
2002/03/30: [spec] warn redundant nested repeat operator
in Ruby verbose mode. ex. (?:a*)?
-2002/03/30: [spec] nested repeat operator error check should be
+2002/03/30: [spec] nested repeat operator error check should be
same with GNU regex. (thanks Guy Decoux)
2002/03/30: [new] add \x{hexadecimal-wide-char}. (thanks matz)
2002/03/27: [bug] MBCTYPE_XXX symbol values should be same with GNU regex.
ex. /(?:abc){10}/
2002/03/06: [new] add a symbol REG_TRANSTABLE_USE_DEFAULT in regex.h.
2002/03/06: [impl] rename RegDefaultCharCode to RegDefaultCharEncoding.
-2002/03/06: [bug] if pattern has NULL(\000) char, infinite loop happens
+2002/03/06: [bug] if pattern has NULL(\000) char, infinite loop happens
in ScanMakeNode(). (beware of strchr(). thanks Nobu)
2002/03/06: [bug] range argument of ForwardSearchRange() is wrong.
ex. /\A.a/, /\G.a/ mismatched with "aa". (thanks Nobu)
See doc/API for Oniguruma API.
If you want to disable UChar type (== unsigned char) definition
- in oniguruma.h, define ONIG_ESCAPE_UCHAR_COLLISION and then
+ in oniguruma.h, define ONIG_ESCAPE_UCHAR_COLLISION and then
include oniguruma.h.
If you want to disable regex_t type definition in oniguruma.h,
[![Build Status](https://travis-ci.org/kkos/oniguruma.svg?branch=master)](https://travis-ci.org/kkos/oniguruma)
+[![Code Quality: Cpp](https://img.shields.io/lgtm/grade/cpp/g/kkos/oniguruma.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/kkos/oniguruma/context:cpp)
+[![Total Alerts](https://img.shields.io/lgtm/alerts/g/kkos/oniguruma.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/kkos/oniguruma/alerts)
Oniguruma
=========
* CP1251: contributed by Byte
+New feature of version 6.9.1
+--------------------------
+
+* Speed improvement (* especially UTF-8)
+
+
New feature of version 6.9.0
--------------------------
See doc/API for Oniguruma API.
If you want to disable UChar type (== unsigned char) definition
- in oniguruma.h, define ONIG_ESCAPE_UCHAR_COLLISION and then
+ in oniguruma.h, define ONIG_ESCAPE_UCHAR_COLLISION and then
include oniguruma.h.
If you want to disable regex_t type definition in oniguruma.h,
|utf32_le.c |UTF-32LE encoding |
|unicode.c |common codes of Unicode encoding |
|unicode_fold_data.c|Unicode folding data |
-|windows/testc.c |Test program for Windowns (VC++) |
+|windows/testc.c |Test program for Windows (VC++) |
ci->target_enc: target string character encoding.
ci->syntax: address of pattern syntax definition.
ci->option: compile time option.
- ci->case_fold_flag: character matching case fold bit flag for
+ ci->case_fold_flag: character matching case fold bit flag for
ONIG_OPTION_IGNORECASE mode.
ONIGENC_CASE_FOLD_MIN: minimum
\t, \n, \v, \f, \r, \x20
Unicodeの場合:
- U+0009, U+000A, U+000B, U+000C, U+000D, U+0085(NEL),
+ U+0009, U+000A, U+000B, U+000C, U+000D, U+0085(NEL),
General_Category -- Line_Separator
-- Paragraph_Separator
-- Space_Separator
<h1>Oniguruma</h1> (<a href="index_ja.html">Japanese</a>)
<p>
-(c) K.Kosako, updated at: 2018/08/31
+(c) K.Kosako, updated at: 2018/12/06
</p>
<dl>
<dt><b>What's new</b>
</font>
<ul>
+<li>2018/12/11: Version 6.9.1 released.</li>
<li>2018/09/03: Version 6.9.0 released.</li>
<li>2018/04/17: Version 6.8.2 released.</li>
<li>2018/03/19: Version 6.8.1 released.</li>
<h1>鬼車</h1>
<p>
-(c) K.Kosako, 最終更新: 2018/09/03
+(c) K.Kosako, 最終更新: 2018/12/06
</p>
<dl>
<dt><b>更新情報</b>
</font>
<ul>
+<li>2018/12/11: Version 6.9.1 リリース</li>
<li>2018/09/03: Version 6.9.0 リリース</li>
<li>2018/04/17: Version 6.8.2 リリース</li>
<li>2018/03/19: Version 6.8.1 リリース</li>
init,
0, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
p++;
break;
}
- }
+ }
}
len = enclen(ONIG_ENCODING_BIG5, p);
if (p + len > s) return (UChar* )p;
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
#if 1
if (enclen(ONIG_ENCODING_EUC_JP, buf) != (p - buf))
return ONIGERR_INVALID_CODE_POINT_VALUE;
-#endif
+#endif
return (int )(p - buf);
}
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1_OR_0,
0, 0
};
euckr_is_allowed_reverse_match,
NULL, /* init */
NULL, /* is_initialized */
- is_valid_mbc_string
+ is_valid_mbc_string,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1_OR_0,
+ 0, 0
};
/* Same with OnigEncodingEUC_KR except the name */
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1_OR_0,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
onigenc_always_true_is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
#define ONIGURUMA
#define ONIGURUMA_VERSION_MAJOR 6
#define ONIGURUMA_VERSION_MINOR 9
-#define ONIGURUMA_VERSION_TEENY 0
+#define ONIGURUMA_VERSION_TEENY 1
-#define ONIGURUMA_VERSION_INT 60900
+#define ONIGURUMA_VERSION_INT 60901
#ifndef P_
#if defined(__STDC__) || defined(_WIN32)
return 1;
}
+extern int
+onig_positive_int_multiply(int x, int y)
+{
+ if (x == 0 || y == 0) return 0;
+
+ if (x < INT_MAX / y)
+ return x * y;
+ else
+ return -1;
+}
+
#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
static unsigned char PadBuf[WORD_ALIGNMENT_SIZE];
if (NODE_TYPE(a) == NODE_STRING) {
StrNode* sn = STR_(a);
- if (sn->capa == 0) {
+ if (sn->capacity == 0) {
int len = (int )(sn->end - sn->s);
sn->s = sn->buf;
sn->end = sn->s + len;
if (NODE_TYPE(b) == NODE_STRING) {
StrNode* sn = STR_(b);
- if (sn->capa == 0) {
+ if (sn->capacity == 0) {
int len = (int )(sn->end - sn->s);
sn->s = sn->buf;
sn->end = sn->s + len;
if (r != 0) return r;
for (i = 0; i < n; i++) {
- r = add_opcode_rel_addr(reg, OP_PUSH,
- (n - i) * tlen + (n - i - 1) * SIZE_OP_PUSH);
+ int v = onig_positive_int_multiply(n - i, tlen);
+ if (v < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
+ r = add_opcode_rel_addr(reg, OP_PUSH, v + (n - i - 1) * SIZE_OP_PUSH);
if (r != 0) return r;
r = compile_tree(NODE_QUANT_BODY(qn), reg, env);
if (r != 0) return r;
}
static int
-compile_length_option_node(EnclosureNode* node, regex_t* reg)
+compile_length_option_node(BagNode* node, regex_t* reg)
{
int tlen;
OnigOptionType prev = reg->options;
reg->options = node->o.options;
- tlen = compile_length_tree(NODE_ENCLOSURE_BODY(node), reg);
+ tlen = compile_length_tree(NODE_BAG_BODY(node), reg);
reg->options = prev;
return tlen;
}
static int
-compile_option_node(EnclosureNode* node, regex_t* reg, ScanEnv* env)
+compile_option_node(BagNode* node, regex_t* reg, ScanEnv* env)
{
int r;
OnigOptionType prev = reg->options;
reg->options = node->o.options;
- r = compile_tree(NODE_ENCLOSURE_BODY(node), reg, env);
+ r = compile_tree(NODE_BAG_BODY(node), reg, env);
reg->options = prev;
return r;
}
static int
-compile_length_enclosure_node(EnclosureNode* node, regex_t* reg)
+compile_length_bag_node(BagNode* node, regex_t* reg)
{
int len;
int tlen;
- if (node->type == ENCLOSURE_OPTION)
+ if (node->type == BAG_OPTION)
return compile_length_option_node(node, reg);
- if (NODE_ENCLOSURE_BODY(node)) {
- tlen = compile_length_tree(NODE_ENCLOSURE_BODY(node), reg);
+ if (NODE_BAG_BODY(node)) {
+ tlen = compile_length_tree(NODE_BAG_BODY(node), reg);
if (tlen < 0) return tlen;
}
else
tlen = 0;
switch (node->type) {
- case ENCLOSURE_MEMORY:
+ case BAG_MEMORY:
#ifdef USE_CALL
if (node->m.regnum == 0 && NODE_IS_CALLED(node)) {
}
break;
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_STOP_BACKTRACK:
if (NODE_IS_STOP_BT_SIMPLE_REPEAT(node)) {
- QuantNode* qn = QUANT_(NODE_ENCLOSURE_BODY(node));
+ int v;
+ QuantNode* qn;
+
+ qn = QUANT_(NODE_BAG_BODY(node));
tlen = compile_length_tree(NODE_QUANT_BODY(qn), reg);
if (tlen < 0) return tlen;
- len = tlen * qn->lower
- + SIZE_OP_PUSH + tlen + SIZE_OP_POP_OUT + SIZE_OP_JUMP;
+ v = onig_positive_int_multiply(qn->lower, tlen);
+ if (v < 0) return ONIGERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE;
+ len = v + SIZE_OP_PUSH + tlen + SIZE_OP_POP_OUT + SIZE_OP_JUMP;
}
else {
len = SIZE_OP_ATOMIC_START + tlen + SIZE_OP_ATOMIC_END;
}
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
{
- Node* cond = NODE_ENCLOSURE_BODY(node);
+ Node* cond = NODE_BAG_BODY(node);
Node* Then = node->te.Then;
Node* Else = node->te.Else;
}
break;
- default:
- return ONIGERR_TYPE_BUG;
+ case BAG_OPTION:
+ len = tlen;
break;
}
return len;
}
-static int get_char_length_tree(Node* node, regex_t* reg, int* len);
+static int get_char_len_node(Node* node, regex_t* reg, int* len);
static int
-compile_enclosure_memory_node(EnclosureNode* node, regex_t* reg, ScanEnv* env)
+compile_bag_memory_node(BagNode* node, regex_t* reg, ScanEnv* env)
{
int r;
int len;
NODE_STATUS_ADD(node, ADDR_FIXED);
r = add_abs_addr(reg, (int )node->m.called_addr);
if (r != 0) return r;
- len = compile_length_tree(NODE_ENCLOSURE_BODY(node), reg);
+ len = compile_length_tree(NODE_BAG_BODY(node), reg);
len += SIZE_OP_RETURN;
r = add_opcode_rel_addr(reg, OP_JUMP, len);
if (r != 0) return r;
- r = compile_tree(NODE_ENCLOSURE_BODY(node), reg, env);
+ r = compile_tree(NODE_BAG_BODY(node), reg, env);
if (r != 0) return r;
r = add_opcode(reg, OP_RETURN);
return r;
NODE_STATUS_ADD(node, ADDR_FIXED);
r = add_abs_addr(reg, (int )node->m.called_addr);
if (r != 0) return r;
- len = compile_length_tree(NODE_ENCLOSURE_BODY(node), reg);
+ len = compile_length_tree(NODE_BAG_BODY(node), reg);
len += (SIZE_OP_MEMORY_START_PUSH + SIZE_OP_RETURN);
if (MEM_STATUS_AT0(reg->bt_mem_end, node->m.regnum))
len += (NODE_IS_RECURSION(node)
if (r != 0) return r;
r = add_mem_num(reg, node->m.regnum);
if (r != 0) return r;
- r = compile_tree(NODE_ENCLOSURE_BODY(node), reg, env);
+ r = compile_tree(NODE_BAG_BODY(node), reg, env);
if (r != 0) return r;
#ifdef USE_CALL
}
static int
-compile_enclosure_node(EnclosureNode* node, regex_t* reg, ScanEnv* env)
+compile_bag_node(BagNode* node, regex_t* reg, ScanEnv* env)
{
int r, len;
switch (node->type) {
- case ENCLOSURE_MEMORY:
- r = compile_enclosure_memory_node(node, reg, env);
+ case BAG_MEMORY:
+ r = compile_bag_memory_node(node, reg, env);
break;
- case ENCLOSURE_OPTION:
+ case BAG_OPTION:
r = compile_option_node(node, reg, env);
break;
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_STOP_BACKTRACK:
if (NODE_IS_STOP_BT_SIMPLE_REPEAT(node)) {
- QuantNode* qn = QUANT_(NODE_ENCLOSURE_BODY(node));
+ QuantNode* qn = QUANT_(NODE_BAG_BODY(node));
r = compile_tree_n_times(NODE_QUANT_BODY(qn), qn->lower, reg, env);
if (r != 0) return r;
else {
r = add_opcode(reg, OP_ATOMIC_START);
if (r != 0) return r;
- r = compile_tree(NODE_ENCLOSURE_BODY(node), reg, env);
+ r = compile_tree(NODE_BAG_BODY(node), reg, env);
if (r != 0) return r;
r = add_opcode(reg, OP_ATOMIC_END);
}
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
{
int cond_len, then_len, jump_len;
- Node* cond = NODE_ENCLOSURE_BODY(node);
+ Node* cond = NODE_BAG_BODY(node);
Node* Then = node->te.Then;
Node* Else = node->te.Else;
}
}
break;
-
- default:
- return ONIGERR_TYPE_BUG;
- break;
}
return r;
}
switch (node->type) {
- case ANCHOR_PREC_READ:
+ case ANCR_PREC_READ:
len = SIZE_OP_PREC_READ_START + tlen + SIZE_OP_PREC_READ_END;
break;
- case ANCHOR_PREC_READ_NOT:
+ case ANCR_PREC_READ_NOT:
len = SIZE_OP_PREC_READ_NOT_START + tlen + SIZE_OP_PREC_READ_NOT_END;
break;
- case ANCHOR_LOOK_BEHIND:
+ case ANCR_LOOK_BEHIND:
len = SIZE_OP_LOOK_BEHIND + tlen;
break;
- case ANCHOR_LOOK_BEHIND_NOT:
+ case ANCR_LOOK_BEHIND_NOT:
len = SIZE_OP_LOOK_BEHIND_NOT_START + tlen + SIZE_OP_LOOK_BEHIND_NOT_END;
break;
- case ANCHOR_WORD_BOUNDARY:
- case ANCHOR_NO_WORD_BOUNDARY:
+ case ANCR_WORD_BOUNDARY:
+ case ANCR_NO_WORD_BOUNDARY:
#ifdef USE_WORD_BEGIN_END
- case ANCHOR_WORD_BEGIN:
- case ANCHOR_WORD_END:
+ case ANCR_WORD_BEGIN:
+ case ANCR_WORD_END:
#endif
len = SIZE_OP_WORD_BOUNDARY;
break;
- case ANCHOR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
- case ANCHOR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
+ case ANCR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
+ case ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
len = SIZE_OPCODE;
break;
enum OpCode op;
switch (node->type) {
- case ANCHOR_BEGIN_BUF: r = add_opcode(reg, OP_BEGIN_BUF); break;
- case ANCHOR_END_BUF: r = add_opcode(reg, OP_END_BUF); break;
- case ANCHOR_BEGIN_LINE: r = add_opcode(reg, OP_BEGIN_LINE); break;
- case ANCHOR_END_LINE: r = add_opcode(reg, OP_END_LINE); break;
- case ANCHOR_SEMI_END_BUF: r = add_opcode(reg, OP_SEMI_END_BUF); break;
- case ANCHOR_BEGIN_POSITION: r = add_opcode(reg, OP_BEGIN_POSITION); break;
-
- case ANCHOR_WORD_BOUNDARY:
+ case ANCR_BEGIN_BUF: r = add_opcode(reg, OP_BEGIN_BUF); break;
+ case ANCR_END_BUF: r = add_opcode(reg, OP_END_BUF); break;
+ case ANCR_BEGIN_LINE: r = add_opcode(reg, OP_BEGIN_LINE); break;
+ case ANCR_END_LINE: r = add_opcode(reg, OP_END_LINE); break;
+ case ANCR_SEMI_END_BUF: r = add_opcode(reg, OP_SEMI_END_BUF); break;
+ case ANCR_BEGIN_POSITION: r = add_opcode(reg, OP_BEGIN_POSITION); break;
+
+ case ANCR_WORD_BOUNDARY:
op = OP_WORD_BOUNDARY;
word:
r = add_opcode(reg, op);
r = add_mode(reg, (ModeType )node->ascii_mode);
break;
- case ANCHOR_NO_WORD_BOUNDARY:
+ case ANCR_NO_WORD_BOUNDARY:
op = OP_NO_WORD_BOUNDARY; goto word;
break;
#ifdef USE_WORD_BEGIN_END
- case ANCHOR_WORD_BEGIN:
+ case ANCR_WORD_BEGIN:
op = OP_WORD_BEGIN; goto word;
break;
- case ANCHOR_WORD_END:
+ case ANCR_WORD_END:
op = OP_WORD_END; goto word;
break;
#endif
- case ANCHOR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
+ case ANCR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
r = add_opcode(reg, OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);
break;
- case ANCHOR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
+ case ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
r = add_opcode(reg, OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);
break;
- case ANCHOR_PREC_READ:
+ case ANCR_PREC_READ:
r = add_opcode(reg, OP_PREC_READ_START);
if (r != 0) return r;
r = compile_tree(NODE_ANCHOR_BODY(node), reg, env);
r = add_opcode(reg, OP_PREC_READ_END);
break;
- case ANCHOR_PREC_READ_NOT:
+ case ANCR_PREC_READ_NOT:
len = compile_length_tree(NODE_ANCHOR_BODY(node), reg);
if (len < 0) return len;
r = add_opcode_rel_addr(reg, OP_PREC_READ_NOT_START, len + SIZE_OP_PREC_READ_NOT_END);
r = add_opcode(reg, OP_PREC_READ_NOT_END);
break;
- case ANCHOR_LOOK_BEHIND:
+ case ANCR_LOOK_BEHIND:
{
int n;
r = add_opcode(reg, OP_LOOK_BEHIND);
if (r != 0) return r;
if (node->char_len < 0) {
- r = get_char_length_tree(NODE_ANCHOR_BODY(node), reg, &n);
+ r = get_char_len_node(NODE_ANCHOR_BODY(node), reg, &n);
if (r != 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
}
else
}
break;
- case ANCHOR_LOOK_BEHIND_NOT:
+ case ANCR_LOOK_BEHIND_NOT:
{
int n;
len + SIZE_OP_LOOK_BEHIND_NOT_END);
if (r != 0) return r;
if (node->char_len < 0) {
- r = get_char_length_tree(NODE_ANCHOR_BODY(node), reg, &n);
+ r = get_char_len_node(NODE_ANCHOR_BODY(node), reg, &n);
if (r != 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
}
else
r = compile_length_quantifier_node(QUANT_(node), reg);
break;
- case NODE_ENCLOSURE:
- r = compile_length_enclosure_node(ENCLOSURE_(node), reg);
+ case NODE_BAG:
+ r = compile_length_bag_node(BAG_(node), reg);
break;
case NODE_ANCHOR:
r = compile_quantifier_node(QUANT_(node), reg, env);
break;
- case NODE_ENCLOSURE:
- r = compile_enclosure_node(ENCLOSURE_(node), reg, env);
+ case NODE_BAG:
+ r = compile_bag_node(BAG_(node), reg, env);
break;
case NODE_ANCHOR:
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ BagNode* en = BAG_(node);
+ if (en->type == BAG_MEMORY) {
if (NODE_IS_NAMED_GROUP(node)) {
(*counter)++;
map[en->m.regnum].new_val = *counter;
r = noname_disable_map(plink, map, counter);
}
}
- else if (en->type == ENCLOSURE_IF_ELSE) {
- r = noname_disable_map(&(NODE_ENCLOSURE_BODY(en)), map, counter);
+ else if (en->type == BAG_IF_ELSE) {
+ r = noname_disable_map(&(NODE_BAG_BODY(en)), map, counter);
if (r != 0) return r;
if (IS_NOT_NULL(en->te.Then)) {
r = noname_disable_map(&(en->te.Then), map, counter);
r = renumber_by_map(NODE_BODY(node), map);
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
r = renumber_by_map(NODE_BODY(node), map);
if (r != 0) return r;
- if (en->type == ENCLOSURE_IF_ELSE) {
+ if (en->type == BAG_IF_ELSE) {
if (IS_NOT_NULL(en->te.Then)) {
r = renumber_by_map(en->te.Then, map);
if (r != 0) return r;
r = numbered_ref_check(NODE_BODY(node));
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
r = numbered_ref_check(NODE_BODY(node));
if (r != 0) return r;
- if (en->type == ENCLOSURE_IF_ELSE) {
+ if (en->type == BAG_IF_ELSE) {
if (IS_NOT_NULL(en->te.Then)) {
r = numbered_ref_check(en->te.Then);
if (r != 0) return r;
fix_unset_addr_list(UnsetAddrList* uslist, regex_t* reg)
{
int i, offset;
- EnclosureNode* en;
+ BagNode* en;
AbsAddrType addr;
for (i = 0; i < uslist->num; i++) {
if (! NODE_IS_ADDR_FIXED(uslist->us[i].target))
return ONIGERR_PARSER_BUG;
- en = ENCLOSURE_(uslist->us[i].target);
+ en = BAG_(uslist->us[i].target);
addr = en->m.called_addr;
offset = uslist->us[i].offset;
/* fixed size pattern node only */
static int
-get_char_length_tree1(Node* node, regex_t* reg, int* len, int level)
+get_char_len_node1(Node* node, regex_t* reg, int* len, int level)
{
int tlen;
int r = 0;
switch (NODE_TYPE(node)) {
case NODE_LIST:
do {
- r = get_char_length_tree1(NODE_CAR(node), reg, &tlen, level);
+ r = get_char_len_node1(NODE_CAR(node), reg, &tlen, level);
if (r == 0)
*len = distance_add(*len, tlen);
} while (r == 0 && IS_NOT_NULL(node = NODE_CDR(node)));
int tlen2;
int varlen = 0;
- r = get_char_length_tree1(NODE_CAR(node), reg, &tlen, level);
+ r = get_char_len_node1(NODE_CAR(node), reg, &tlen, level);
while (r == 0 && IS_NOT_NULL(node = NODE_CDR(node))) {
- r = get_char_length_tree1(NODE_CAR(node), reg, &tlen2, level);
+ r = get_char_len_node1(NODE_CAR(node), reg, &tlen2, level);
if (r == 0) {
if (tlen != tlen2)
varlen = 1;
*len = 0;
}
else {
- r = get_char_length_tree1(NODE_BODY(node), reg, &tlen, level);
+ r = get_char_len_node1(NODE_BODY(node), reg, &tlen, level);
if (r == 0)
*len = distance_multiply(tlen, qn->lower);
}
#ifdef USE_CALL
case NODE_CALL:
if (! NODE_IS_RECURSION(node))
- r = get_char_length_tree1(NODE_BODY(node), reg, len, level);
+ r = get_char_len_node1(NODE_BODY(node), reg, len, level);
else
r = GET_CHAR_LEN_VARLEN;
break;
*len = 1;
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
switch (en->type) {
- case ENCLOSURE_MEMORY:
+ case BAG_MEMORY:
#ifdef USE_CALL
if (NODE_IS_CLEN_FIXED(node))
*len = en->char_len;
else {
- r = get_char_length_tree1(NODE_BODY(node), reg, len, level);
+ r = get_char_len_node1(NODE_BODY(node), reg, len, level);
if (r == 0) {
en->char_len = *len;
NODE_STATUS_ADD(node, CLEN_FIXED);
}
break;
#endif
- case ENCLOSURE_OPTION:
- case ENCLOSURE_STOP_BACKTRACK:
- r = get_char_length_tree1(NODE_BODY(node), reg, len, level);
+ case BAG_OPTION:
+ case BAG_STOP_BACKTRACK:
+ r = get_char_len_node1(NODE_BODY(node), reg, len, level);
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
{
int clen, elen;
- r = get_char_length_tree1(NODE_BODY(node), reg, &clen, level);
+ r = get_char_len_node1(NODE_BODY(node), reg, &clen, level);
if (r == 0) {
if (IS_NOT_NULL(en->te.Then)) {
- r = get_char_length_tree1(en->te.Then, reg, &tlen, level);
+ r = get_char_len_node1(en->te.Then, reg, &tlen, level);
if (r != 0) break;
}
else tlen = 0;
if (IS_NOT_NULL(en->te.Else)) {
- r = get_char_length_tree1(en->te.Else, reg, &elen, level);
+ r = get_char_len_node1(en->te.Else, reg, &elen, level);
if (r != 0) break;
}
else elen = 0;
}
}
break;
-
- default:
- break;
}
}
break;
}
static int
-get_char_length_tree(Node* node, regex_t* reg, int* len)
+get_char_len_node(Node* node, regex_t* reg, int* len)
{
- return get_char_length_tree1(node, reg, len, 0);
+ return get_char_len_node1(node, reg, len, 0);
}
/* x is not included y ==> 1 : 0 */
code = ONIGENC_MBC_TO_CODE(reg->enc, xs->s,
xs->s + ONIGENC_MBC_MAXLEN(reg->enc));
- return (onig_is_code_in_cc(reg->enc, code, cc) != 0 ? 0 : 1);
+ return onig_is_code_in_cc(reg->enc, code, cc) == 0;
}
break;
if (sn->end <= sn->s)
break;
- if (exact != 0 &&
- !NODE_STRING_IS_RAW(node) && IS_IGNORECASE(reg->options)) {
- }
- else {
+ if (exact == 0 ||
+ ! IS_IGNORECASE(reg->options) || NODE_STRING_IS_RAW(node)) {
n = node;
}
}
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
switch (en->type) {
- case ENCLOSURE_OPTION:
+ case BAG_OPTION:
{
OnigOptionType options = reg->options;
- reg->options = ENCLOSURE_(node)->o.options;
+ reg->options = BAG_(node)->o.options;
n = get_head_value_node(NODE_BODY(node), exact, reg);
reg->options = options;
}
break;
- case ENCLOSURE_MEMORY:
- case ENCLOSURE_STOP_BACKTRACK:
- case ENCLOSURE_IF_ELSE:
+ case BAG_MEMORY:
+ case BAG_STOP_BACKTRACK:
+ case BAG_IF_ELSE:
n = get_head_value_node(NODE_BODY(node), exact, reg);
break;
}
break;
case NODE_ANCHOR:
- if (ANCHOR_(node)->type == ANCHOR_PREC_READ)
+ if (ANCHOR_(node)->type == ANCR_PREC_READ)
n = get_head_value_node(NODE_BODY(node), exact, reg);
break;
}
static int
-check_type_tree(Node* node, int type_mask, int enclosure_mask, int anchor_mask)
+check_type_tree(Node* node, int type_mask, int bag_mask, int anchor_mask)
{
NodeType type;
int r = 0;
case NODE_LIST:
case NODE_ALT:
do {
- r = check_type_tree(NODE_CAR(node), type_mask, enclosure_mask,
+ r = check_type_tree(NODE_CAR(node), type_mask, bag_mask,
anchor_mask);
} while (r == 0 && IS_NOT_NULL(node = NODE_CDR(node)));
break;
case NODE_QUANT:
- r = check_type_tree(NODE_BODY(node), type_mask, enclosure_mask, anchor_mask);
+ r = check_type_tree(NODE_BODY(node), type_mask, bag_mask, anchor_mask);
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
- if (((1<<en->type) & enclosure_mask) == 0)
+ BagNode* en = BAG_(node);
+ if (((1<<en->type) & bag_mask) == 0)
return 1;
- r = check_type_tree(NODE_BODY(node), type_mask, enclosure_mask, anchor_mask);
- if (r == 0 && en->type == ENCLOSURE_IF_ELSE) {
+ r = check_type_tree(NODE_BODY(node), type_mask, bag_mask, anchor_mask);
+ if (r == 0 && en->type == BAG_IF_ELSE) {
if (IS_NOT_NULL(en->te.Then)) {
- r = check_type_tree(en->te.Then, type_mask, enclosure_mask, anchor_mask);
+ r = check_type_tree(en->te.Then, type_mask, bag_mask, anchor_mask);
if (r != 0) break;
}
if (IS_NOT_NULL(en->te.Else)) {
- r = check_type_tree(en->te.Else, type_mask, enclosure_mask, anchor_mask);
+ r = check_type_tree(en->te.Else, type_mask, bag_mask, anchor_mask);
}
}
}
return 1;
if (IS_NOT_NULL(NODE_BODY(node)))
- r = check_type_tree(NODE_BODY(node), type_mask, enclosure_mask, anchor_mask);
+ r = check_type_tree(NODE_BODY(node), type_mask, bag_mask, anchor_mask);
break;
case NODE_GIMMICK:
Node* t = NODE_BODY(node);
if (NODE_IS_RECURSION(node)) {
if (NODE_IS_MIN_FIXED(t))
- len = ENCLOSURE_(t)->min_len;
+ len = BAG_(t)->min_len;
}
else
len = tree_min_len(t, env);
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
switch (en->type) {
- case ENCLOSURE_MEMORY:
+ case BAG_MEMORY:
if (NODE_IS_MIN_FIXED(node))
len = en->min_len;
else {
}
break;
- case ENCLOSURE_OPTION:
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_OPTION:
+ case BAG_STOP_BACKTRACK:
len = tree_min_len(NODE_BODY(node), env);
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
{
OnigLen elen;
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
switch (en->type) {
- case ENCLOSURE_MEMORY:
+ case BAG_MEMORY:
if (NODE_IS_MAX_FIXED(node))
len = en->max_len;
else {
}
break;
- case ENCLOSURE_OPTION:
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_OPTION:
+ case BAG_STOP_BACKTRACK:
len = tree_max_len(NODE_BODY(node), env);
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
{
OnigLen tlen, elen;
r = check_backrefs(NODE_BODY(node), env);
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
r = check_backrefs(NODE_BODY(node), env);
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
- if (en->type == ENCLOSURE_IF_ELSE) {
+ if (en->type == BAG_IF_ELSE) {
if (r != 0) return r;
if (IS_NOT_NULL(en->te.Then)) {
r = check_backrefs(en->te.Then, env);
r = infinite_recursive_call_check(NODE_BODY(node), env, head);
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ if (en->type == BAG_MEMORY) {
if (NODE_IS_MARK2(node))
return 0;
else if (NODE_IS_MARK1(node))
NODE_STATUS_REMOVE(node, MARK2);
}
}
- else if (en->type == ENCLOSURE_IF_ELSE) {
+ else if (en->type == BAG_IF_ELSE) {
int eret;
ret = infinite_recursive_call_check(NODE_BODY(node), env, head);
r = infinite_recursive_call_check_trav(NODE_BODY(node), env);
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ if (en->type == BAG_MEMORY) {
if (NODE_IS_RECURSION(node) && NODE_IS_CALLED(node)) {
int ret;
NODE_STATUS_REMOVE(node, MARK1);
}
}
- else if (en->type == ENCLOSURE_IF_ELSE) {
+ else if (en->type == BAG_IF_ELSE) {
if (IS_NOT_NULL(en->te.Then)) {
r = infinite_recursive_call_check_trav(en->te.Then, env);
if (r != 0) return r;
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ if (en->type == BAG_MEMORY) {
if (NODE_IS_MARK2(node))
return 0;
else if (NODE_IS_MARK1(node))
NODE_STATUS_REMOVE(node, MARK2);
}
}
- else if (en->type == ENCLOSURE_IF_ELSE) {
+ else if (en->type == BAG_IF_ELSE) {
r = 0;
if (IS_NOT_NULL(en->te.Then)) {
r |= recursive_call_check(en->te.Then);
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
int ret;
int state1;
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ if (en->type == BAG_MEMORY) {
if (NODE_IS_CALLED(node) || (state & IN_RECURSION) != 0) {
if (! NODE_IS_RECURSION(node)) {
NODE_STATUS_ADD(node, MARK1);
if (ret == FOUND_CALLED_NODE)
r = FOUND_CALLED_NODE;
- if (en->type == ENCLOSURE_IF_ELSE) {
+ if (en->type == BAG_IF_ELSE) {
if (IS_NOT_NULL(en->te.Then)) {
ret = recursive_call_check_trav(en->te.Then, env, state1);
if (ret == FOUND_CALLED_NODE)
#endif
+#define IN_ALT (1<<0)
+#define IN_NOT (1<<1)
+#define IN_REAL_REPEAT (1<<2)
+#define IN_VAR_REPEAT (1<<3)
+#define IN_ZERO_REPEAT (1<<4)
+#define IN_MULTI_ENTRY (1<<5)
+#define IN_LOOK_BEHIND (1<<6)
+
+
/* divide different length alternatives in look-behind.
(?<=A|B) ==> (?<=A)|(?<=B)
(?<!A|B) ==> (?<!A)(?<!B)
NODE_CAR(np) = insert_node;
}
- if (anc_type == ANCHOR_LOOK_BEHIND_NOT) {
+ if (anc_type == ANCR_LOOK_BEHIND_NOT) {
np = node;
do {
NODE_SET_TYPE(np, NODE_LIST); /* alt -> list */
int r, len;
AnchorNode* an = ANCHOR_(node);
- r = get_char_length_tree(NODE_ANCHOR_BODY(an), reg, &len);
+ r = get_char_len_node(NODE_ANCHOR_BODY(an), reg, &len);
if (r == 0)
an->char_len = len;
else if (r == GET_CHAR_LEN_VARLEN)
if (IS_NOT_NULL(x)) {
y = get_head_value_node(next_node, 0, reg);
if (IS_NOT_NULL(y) && is_exclusive(x, y, reg)) {
- Node* en = onig_node_new_enclosure(ENCLOSURE_STOP_BACKTRACK);
+ Node* en = onig_node_new_bag(BAG_STOP_BACKTRACK);
CHECK_NULL_RETURN_MEMERR(en);
NODE_STATUS_ADD(en, STOP_BT_SIMPLE_REPEAT);
swap_node(node, en);
}
}
}
- else if (type == NODE_ENCLOSURE) {
- EnclosureNode* en = ENCLOSURE_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ else if (type == NODE_BAG) {
+ BagNode* en = BAG_(node);
+ if (en->type == BAG_MEMORY) {
node = NODE_BODY(node);
goto retry;
}
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) {
goto mem_err2;
}
- if (items[i].byte_len != slen) {
+ if (items[i].byte_len != slen && IS_NOT_NULL(var_anode)) {
Node *rem;
UChar *q = p + items[i].byte_len;
}
static int
-expand_case_fold_string(Node* node, regex_t* reg)
+is_good_case_fold_items_for_search(OnigEncoding enc, int slen,
+ int n, OnigCaseFoldCodeItem items[])
{
+ int i, len;
+ UChar buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+
+ for (i = 0; i < n; i++) {
+ OnigCaseFoldCodeItem* item = items + i;
+
+ if (item->code_len != 1) return 0;
+ if (item->byte_len != slen) return 0;
+ len = ONIGENC_CODE_TO_MBC(enc, item->code[0], buf);
+ if (len != slen) return 0;
+ }
+
+ return 1;
+}
+
#define THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION 8
+static int
+expand_case_fold_string(Node* node, regex_t* reg, int state)
+{
int r, n, len, alt_num;
+ int fold_len;
+ int prev_is_ambig, prev_is_good, is_good, is_in_look_behind;
UChar *start, *end, *p;
+ UChar* foldp;
Node *top_root, *root, *snode, *prev_node;
OnigCaseFoldCodeItem items[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
- StrNode* sn = STR_(node);
+ UChar buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+ StrNode* sn;
if (NODE_STRING_IS_AMBIG(node)) return 0;
+ sn = STR_(node);
+
start = sn->s;
end = sn->end;
if (start >= end) return 0;
+ is_in_look_behind = (state & IN_LOOK_BEHIND) != 0;
+
r = 0;
top_root = root = prev_node = snode = NULL_NODE;
alt_num = 1;
p = start;
while (p < end) {
- n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(reg->enc, reg->case_fold_flag, p, end,
- items);
+ n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(reg->enc, reg->case_fold_flag,
+ p, end, items);
if (n < 0) {
r = n;
goto err;
}
- SAFE_ENC_LEN(reg->enc, p, end, len);
+ SAFE_ENC_LEN(reg->enc, p, end, len);
+ is_good = is_good_case_fold_items_for_search(reg->enc, len, n, items);
- if (n == 0) {
+ if (is_in_look_behind ||
+ (IS_NOT_NULL(snode) ||
+ (is_good
+ /* expand single char case: ex. /(?i:a)/ */
+ && !(p == start && p + len >= end)))) {
if (IS_NULL(snode)) {
if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
top_root = root = onig_node_list_add(NULL_NODE, prev_node);
goto mem_err;
}
}
+
+ prev_is_ambig = -1; /* -1: new */
+ prev_is_good = 0; /* escape compiler warning */
+ }
+ else {
+ prev_is_ambig = NODE_STRING_IS_AMBIG(snode);
+ prev_is_good = NODE_STRING_IS_GOOD_AMBIG(snode);
}
- r = onig_node_str_cat(snode, p, p + len);
- if (r != 0) goto err;
+ if (n != 0) {
+ foldp = p;
+ fold_len = ONIGENC_MBC_CASE_FOLD(reg->enc, reg->case_fold_flag,
+ &foldp, end, buf);
+ foldp = buf;
+ }
+ else {
+ foldp = p; fold_len = len;
+ }
+
+ if ((prev_is_ambig == 0 && n != 0) ||
+ (prev_is_ambig > 0 && (n == 0 || prev_is_good != is_good))) {
+ if (IS_NULL(root) /* && IS_NOT_NULL(prev_node) */) {
+ top_root = root = onig_node_list_add(NULL_NODE, prev_node);
+ if (IS_NULL(root)) {
+ onig_node_free(prev_node);
+ goto mem_err;
+ }
+ }
+
+ prev_node = snode = onig_node_new_str(foldp, foldp + fold_len);
+ if (IS_NULL(snode)) goto mem_err;
+ if (IS_NULL(onig_node_list_add(root, snode))) {
+ onig_node_free(snode);
+ goto mem_err;
+ }
+ }
+ else {
+ r = onig_node_str_cat(snode, foldp, foldp + fold_len);
+ if (r != 0) goto err;
+ }
+
+ if (n != 0) NODE_STRING_SET_AMBIG(snode);
+ if (is_good != 0) NODE_STRING_SET_GOOD_AMBIG(snode);
}
else {
alt_num *= (n + 1);
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
switch (en->type) {
- case ENCLOSURE_MEMORY:
+ case BAG_MEMORY:
if (NODE_IS_RECURSION(node)) {
return QUANT_BODY_IS_EMPTY_REC;
}
return QUANT_BODY_IS_EMPTY_MEM;
break;
- case ENCLOSURE_OPTION:
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_OPTION:
+ case BAG_STOP_BACKTRACK:
r = quantifiers_memory_node_info(NODE_BODY(node));
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
{
int v;
r = quantifiers_memory_node_info(NODE_BODY(node));
}
}
break;
- default:
- break;
}
}
break;
#endif /* USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT */
-#define IN_ALT (1<<0)
-#define IN_NOT (1<<1)
-#define IN_REAL_REPEAT (1<<2)
-#define IN_VAR_REPEAT (1<<3)
-#define IN_ZERO_REPEAT (1<<4)
-#define IN_MULTI_ENTRY (1<<5)
-
#ifdef USE_CALL
#ifdef __GNUC__
setup_call2_call(NODE_BODY(node));
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ if (en->type == BAG_MEMORY) {
if (! NODE_IS_MARK1(node)) {
NODE_STATUS_ADD(node, MARK1);
setup_call2_call(NODE_BODY(node));
NODE_STATUS_REMOVE(node, MARK1);
}
}
- else if (en->type == ENCLOSURE_IF_ELSE) {
+ else if (en->type == BAG_IF_ELSE) {
setup_call2_call(NODE_BODY(node));
if (IS_NOT_NULL(en->te.Then))
setup_call2_call(en->te.Then);
cn->entry_count++;
NODE_STATUS_ADD(called, CALLED);
- ENCLOSURE_(called)->m.entry_count++;
+ BAG_(called)->m.entry_count++;
setup_call2_call(called);
}
NODE_STATUS_REMOVE(node, MARK1);
r = 0;
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ if (en->type == BAG_MEMORY) {
if ((state & IN_ZERO_REPEAT) != 0) {
NODE_STATUS_ADD(node, IN_ZERO_REPEAT);
- ENCLOSURE_(node)->m.entry_count--;
+ BAG_(node)->m.entry_count--;
}
r = setup_call(NODE_BODY(node), env, state);
}
- else if (en->type == ENCLOSURE_IF_ELSE) {
+ else if (en->type == BAG_IF_ELSE) {
r = setup_call(NODE_BODY(node), env, state);
if (r != 0) return r;
if (IS_NOT_NULL(en->te.Then)) {
r = setup_call2(NODE_BODY(node));
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
if (! NODE_IS_IN_ZERO_REPEAT(node))
r = setup_call2(NODE_BODY(node));
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
if (r != 0) return r;
- if (en->type == ENCLOSURE_IF_ELSE) {
+ if (en->type == BAG_IF_ELSE) {
if (IS_NOT_NULL(en->te.Then)) {
r = setup_call2(en->te.Then);
if (r != 0) return r;
AnchorNode* an = ANCHOR_(node);
switch (an->type) {
- case ANCHOR_PREC_READ_NOT:
- case ANCHOR_LOOK_BEHIND_NOT:
+ case ANCR_PREC_READ_NOT:
+ case ANCR_LOOK_BEHIND_NOT:
state |= IN_NOT;
/* fall */
- case ANCHOR_PREC_READ:
- case ANCHOR_LOOK_BEHIND:
+ case ANCR_PREC_READ:
+ case ANCR_LOOK_BEHIND:
setup_called_state_call(NODE_ANCHOR_BODY(an), state);
break;
default:
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
- if (en->type == ENCLOSURE_MEMORY) {
+ if (en->type == BAG_MEMORY) {
if (NODE_IS_MARK1(node)) {
if ((~en->m.called_state & state) != 0) {
en->m.called_state |= state;
NODE_STATUS_REMOVE(node, MARK1);
}
}
- else if (en->type == ENCLOSURE_IF_ELSE) {
+ else if (en->type == BAG_IF_ELSE) {
if (IS_NOT_NULL(en->te.Then)) {
setup_called_state_call(en->te.Then, state);
}
break;
#endif
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
switch (en->type) {
- case ENCLOSURE_MEMORY:
+ case BAG_MEMORY:
if (en->m.entry_count > 1)
state |= IN_MULTI_ENTRY;
en->m.called_state |= state;
/* fall */
- case ENCLOSURE_OPTION:
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_OPTION:
+ case BAG_STOP_BACKTRACK:
setup_called_state(NODE_BODY(node), state);
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
setup_called_state(NODE_BODY(node), state);
if (IS_NOT_NULL(en->te.Then))
setup_called_state(en->te.Then, state);
AnchorNode* an = ANCHOR_(node);
switch (an->type) {
- case ANCHOR_PREC_READ_NOT:
- case ANCHOR_LOOK_BEHIND_NOT:
+ case ANCR_PREC_READ_NOT:
+ case ANCR_LOOK_BEHIND_NOT:
state |= IN_NOT;
/* fall */
- case ANCHOR_PREC_READ:
- case ANCHOR_LOOK_BEHIND:
+ case ANCR_PREC_READ:
+ case ANCR_LOOK_BEHIND:
setup_called_state(NODE_ANCHOR_BODY(an), state);
break;
default:
/* allowed node types in look-behind */
#define ALLOWED_TYPE_IN_LB \
( NODE_BIT_LIST | NODE_BIT_ALT | NODE_BIT_STRING | NODE_BIT_CCLASS \
- | NODE_BIT_CTYPE | NODE_BIT_ANCHOR | NODE_BIT_ENCLOSURE | NODE_BIT_QUANT \
+ | NODE_BIT_CTYPE | NODE_BIT_ANCHOR | NODE_BIT_BAG | NODE_BIT_QUANT \
| NODE_BIT_CALL | NODE_BIT_GIMMICK)
-#define ALLOWED_ENCLOSURE_IN_LB ( 1<<ENCLOSURE_MEMORY | 1<<ENCLOSURE_OPTION )
-#define ALLOWED_ENCLOSURE_IN_LB_NOT (1<<ENCLOSURE_OPTION)
+#define ALLOWED_BAG_IN_LB ( 1<<BAG_MEMORY | 1<<BAG_OPTION )
+#define ALLOWED_BAG_IN_LB_NOT (1<<BAG_OPTION)
#define ALLOWED_ANCHOR_IN_LB \
- ( ANCHOR_LOOK_BEHIND | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF \
- | ANCHOR_BEGIN_POSITION | ANCHOR_WORD_BOUNDARY | ANCHOR_NO_WORD_BOUNDARY \
- | ANCHOR_WORD_BEGIN | ANCHOR_WORD_END \
- | ANCHOR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY \
- | ANCHOR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY )
+ ( ANCR_LOOK_BEHIND | ANCR_BEGIN_LINE | ANCR_END_LINE | ANCR_BEGIN_BUF \
+ | ANCR_BEGIN_POSITION | ANCR_WORD_BOUNDARY | ANCR_NO_WORD_BOUNDARY \
+ | ANCR_WORD_BEGIN | ANCR_WORD_END \
+ | ANCR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY \
+ | ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY )
#define ALLOWED_ANCHOR_IN_LB_NOT \
- ( ANCHOR_LOOK_BEHIND | ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE \
- | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION | ANCHOR_WORD_BOUNDARY \
- | ANCHOR_NO_WORD_BOUNDARY | ANCHOR_WORD_BEGIN | ANCHOR_WORD_END \
- | ANCHOR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY \
- | ANCHOR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY )
+ ( ANCR_LOOK_BEHIND | ANCR_LOOK_BEHIND_NOT | ANCR_BEGIN_LINE \
+ | ANCR_END_LINE | ANCR_BEGIN_BUF | ANCR_BEGIN_POSITION | ANCR_WORD_BOUNDARY \
+ | ANCR_NO_WORD_BOUNDARY | ANCR_WORD_BEGIN | ANCR_WORD_END \
+ | ANCR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY \
+ | ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY )
int r;
AnchorNode* an = ANCHOR_(node);
switch (an->type) {
- case ANCHOR_PREC_READ:
+ case ANCR_PREC_READ:
r = setup_tree(NODE_ANCHOR_BODY(an), reg, state, env);
break;
- case ANCHOR_PREC_READ_NOT:
+ case ANCR_PREC_READ_NOT:
r = setup_tree(NODE_ANCHOR_BODY(an), reg, (state | IN_NOT), env);
break;
- case ANCHOR_LOOK_BEHIND:
+ case ANCR_LOOK_BEHIND:
{
r = check_type_tree(NODE_ANCHOR_BODY(an), ALLOWED_TYPE_IN_LB,
- ALLOWED_ENCLOSURE_IN_LB, ALLOWED_ANCHOR_IN_LB);
+ ALLOWED_BAG_IN_LB, ALLOWED_ANCHOR_IN_LB);
if (r < 0) return r;
if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
- r = setup_tree(NODE_ANCHOR_BODY(an), reg, state, env);
+ r = setup_tree(NODE_ANCHOR_BODY(an), reg, (state|IN_LOOK_BEHIND), env);
if (r != 0) return r;
r = setup_look_behind(node, reg, env);
}
break;
- case ANCHOR_LOOK_BEHIND_NOT:
+ case ANCR_LOOK_BEHIND_NOT:
{
r = check_type_tree(NODE_ANCHOR_BODY(an), ALLOWED_TYPE_IN_LB,
- ALLOWED_ENCLOSURE_IN_LB_NOT, ALLOWED_ANCHOR_IN_LB_NOT);
+ ALLOWED_BAG_IN_LB_NOT, ALLOWED_ANCHOR_IN_LB_NOT);
if (r < 0) return r;
if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
- r = setup_tree(NODE_ANCHOR_BODY(an), reg, (state | IN_NOT), env);
+ r = setup_tree(NODE_ANCHOR_BODY(an), reg, (state|IN_NOT|IN_LOOK_BEHIND),
+ env);
if (r != 0) return r;
r = setup_look_behind(node, reg, env);
}
#ifdef USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT
qn->body_empty_info = quantifiers_memory_node_info(body);
if (qn->body_empty_info == QUANT_BODY_IS_EMPTY_REC) {
- if (NODE_TYPE(body) == NODE_ENCLOSURE &&
- ENCLOSURE_(body)->type == ENCLOSURE_MEMORY) {
- MEM_STATUS_ON(env->bt_mem_end, ENCLOSURE_(body)->m.regnum);
+ if (NODE_TYPE(body) == NODE_BAG &&
+ BAG_(body)->type == BAG_MEMORY) {
+ MEM_STATUS_ON(env->bt_mem_end, BAG_(body)->m.regnum);
}
}
#else
case NODE_STRING:
if (IS_IGNORECASE(reg->options) && !NODE_STRING_IS_RAW(node)) {
- r = expand_case_fold_string(node, reg);
+ r = expand_case_fold_string(node, reg, state);
}
break;
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
switch (en->type) {
- case ENCLOSURE_OPTION:
+ case BAG_OPTION:
{
OnigOptionType options = reg->options;
- reg->options = ENCLOSURE_(node)->o.options;
+ reg->options = BAG_(node)->o.options;
r = setup_tree(NODE_BODY(node), reg, state, env);
reg->options = options;
}
break;
- case ENCLOSURE_MEMORY:
+ case BAG_MEMORY:
#ifdef USE_CALL
state |= en->m.called_state;
#endif
r = setup_tree(NODE_BODY(node), reg, state, env);
break;
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_STOP_BACKTRACK:
{
Node* target = NODE_BODY(node);
r = setup_tree(target, reg, state, env);
}
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
r = setup_tree(NODE_BODY(node), reg, (state | IN_ALT), env);
if (r != 0) return r;
if (IS_NOT_NULL(en->te.Then)) {
return r;
}
-/* set skip map for Boyer-Moore search */
static int
-set_bm_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED,
- UChar skip[], int** int_skip)
+set_sunday_quick_search_or_bmh_skip_table(regex_t* reg, int case_expand,
+ UChar* s, UChar* end,
+ UChar skip[], int* roffset)
{
- int i, len;
+ int i, j, k, len, offset;
+ int n, clen;
+ UChar* p;
+ OnigEncoding enc;
+ OnigCaseFoldCodeItem items[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
+ UChar buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+
+ enc = reg->enc;
+ offset = ENC_GET_SKIP_OFFSET(enc);
+ if (offset == ENC_SKIP_OFFSET_1_OR_0) {
+ UChar* p = s;
+ while (1) {
+ len = enclen(enc, p);
+ if (p + len >= end) {
+ if (len == 1) offset = 1;
+ else offset = 0;
+ break;
+ }
+ p += len;
+ }
+ }
len = (int )(end - s);
- if (len < ONIG_CHAR_TABLE_SIZE) {
- for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) skip[i] = len;
+ if (len + offset >= UCHAR_MAX)
+ return ONIGERR_PARSER_BUG;
+
+ *roffset = offset;
- for (i = 0; i < len - 1; i++)
- skip[s[i]] = len - 1 - i;
+ for (i = 0; i < CHAR_MAP_SIZE; i++) {
+ skip[i] = (UChar )(len + offset);
}
- else {
- if (IS_NULL(*int_skip)) {
- *int_skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
- if (IS_NULL(*int_skip)) return ONIGERR_MEMORY;
+
+ for (p = s; p < end; ) {
+ int z;
+
+ clen = enclen(enc, p);
+ if (p + clen > end) clen = (int )(end - p);
+
+ len = (int )(end - p);
+ for (j = 0; j < clen; j++) {
+ z = len - j + (offset - 1);
+ if (z <= 0) break;
+ skip[p[j]] = z;
+ }
+
+ if (case_expand != 0) {
+ n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
+ p, end, items);
+ for (k = 0; k < n; k++) {
+ ONIGENC_CODE_TO_MBC(enc, items[k].code[0], buf);
+ for (j = 0; j < clen; j++) {
+ z = len - j + (offset - 1);
+ if (z <= 0) break;
+ if (skip[buf[j]] > z)
+ skip[buf[j]] = z;
+ }
+ }
}
- for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) (*int_skip)[i] = len;
- for (i = 0; i < len - 1; i++)
- (*int_skip)[s[i]] = len - 1 - i;
+ p += clen;
}
+
return 0;
}
+
#define OPT_EXACT_MAXLEN 24
+#if OPT_EXACT_MAXLEN >= UCHAR_MAX
+#error Too big OPT_EXACT_MAXLEN
+#endif
+
typedef struct {
OnigLen min; /* min byte length */
OnigLen max; /* max byte length */
MinMax mmd; /* position */
OptAnc anc;
int reach_end;
- int ignore_case;
+ int case_fold;
+ int good_case_fold;
int len;
UChar s[OPT_EXACT_MAXLEN];
-} OptExact;
+} OptStr;
typedef struct {
MinMax mmd; /* position */
OptAnc anc;
int value; /* weighted value */
- UChar map[ONIG_CHAR_TABLE_SIZE];
+ UChar map[CHAR_MAP_SIZE];
} OptMap;
typedef struct {
- MinMax len;
- OptAnc anc;
- OptExact exb; /* boundary */
- OptExact exm; /* middle */
- OptExact expr; /* prec read (?=...) */
- OptMap map; /* boundary */
-} NodeOpt;
+ MinMax len;
+ OptAnc anc;
+ OptStr sb; /* boundary */
+ OptStr sm; /* middle */
+ OptStr spr; /* prec read (?=...) */
+ OptMap map; /* boundary */
+} OptNode;
static int
{
/* 1000 / (min-max-dist + 1) */
static const short int dist_vals[] = {
- 1000, 500, 333, 250, 200, 167, 143, 125, 111, 100,
- 91, 83, 77, 71, 67, 63, 59, 56, 53, 50,
- 48, 45, 43, 42, 40, 38, 37, 36, 34, 33,
- 32, 31, 30, 29, 29, 28, 27, 26, 26, 25,
- 24, 24, 23, 23, 22, 22, 21, 21, 20, 20,
- 20, 19, 19, 19, 18, 18, 18, 17, 17, 17,
- 16, 16, 16, 16, 15, 15, 15, 15, 14, 14,
- 14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
- 12, 12, 12, 12, 12, 12, 11, 11, 11, 11,
+ 1000, 500, 333, 250, 200, 167, 143, 125, 111, 100,
+ 91, 83, 77, 71, 67, 63, 59, 56, 53, 50,
+ 48, 45, 43, 42, 40, 38, 37, 36, 34, 33,
+ 32, 31, 30, 29, 29, 28, 27, 26, 26, 25,
+ 24, 24, 23, 23, 22, 22, 21, 21, 20, 20,
+ 20, 19, 19, 19, 18, 18, 18, 17, 17, 17,
+ 16, 16, 16, 16, 15, 15, 15, 15, 14, 14,
+ 14, 14, 14, 14, 13, 13, 13, 13, 13, 13,
+ 12, 12, 12, 12, 12, 12, 11, 11, 11, 11,
11, 11, 11, 11, 11, 10, 10, 10, 10, 10
};
static int
is_equal_mml(MinMax* a, MinMax* b)
{
- return (a->min == b->min && a->max == b->max) ? 1 : 0;
+ return a->min == b->min && a->max == b->max;
}
static void
to->right |= left->right;
}
else {
- to->right |= (left->right & ANCHOR_PREC_READ_NOT);
+ to->right |= (left->right & ANCR_PREC_READ_NOT);
}
}
static int
is_left(int a)
{
- if (a == ANCHOR_END_BUF || a == ANCHOR_SEMI_END_BUF ||
- a == ANCHOR_END_LINE || a == ANCHOR_PREC_READ || a == ANCHOR_PREC_READ_NOT)
+ if (a == ANCR_END_BUF || a == ANCR_SEMI_END_BUF ||
+ a == ANCR_END_LINE || a == ANCR_PREC_READ || a == ANCR_PREC_READ_NOT)
return 0;
return 1;
}
static int
-is_full_opt_exact(OptExact* e)
+is_full_opt_exact(OptStr* e)
{
- return (e->len >= OPT_EXACT_MAXLEN ? 1 : 0);
+ return e->len >= OPT_EXACT_MAXLEN;
}
static void
-clear_opt_exact(OptExact* e)
+clear_opt_exact(OptStr* e)
{
clear_mml(&e->mmd);
clear_opt_anc_info(&e->anc);
- e->reach_end = 0;
- e->ignore_case = 0;
- e->len = 0;
- e->s[0] = '\0';
+ e->reach_end = 0;
+ e->case_fold = 0;
+ e->good_case_fold = 0;
+ e->len = 0;
+ e->s[0] = '\0';
}
static void
-copy_opt_exact(OptExact* to, OptExact* from)
+copy_opt_exact(OptStr* to, OptStr* from)
{
*to = *from;
}
static int
-concat_opt_exact(OptExact* to, OptExact* add, OnigEncoding enc)
+concat_opt_exact(OptStr* to, OptStr* add, OnigEncoding enc)
{
int i, j, len, r;
UChar *p, *end;
OptAnc tanc;
- if (! to->ignore_case && add->ignore_case) {
- if (to->len >= add->len) return 0; /* avoid */
+ if (add->case_fold != 0) {
+ if (! to->case_fold) {
+ if (to->len > 1 || to->len >= add->len) return 0; /* avoid */
- to->ignore_case = 1;
+ to->case_fold = 1;
+ }
+ else {
+ if (to->good_case_fold != 0) {
+ if (add->good_case_fold == 0) return 0;
+ }
+ }
}
r = 0;
p = add->s;
end = p + add->len;
for (i = to->len; p < end; ) {
- len = enclen(enc, p);
+ SAFE_ENC_LEN(enc, p, end, len);
if (i + len > OPT_EXACT_MAXLEN) {
r = 1; /* 1:full */
break;
}
static void
-concat_opt_exact_str(OptExact* to, UChar* s, UChar* end, OnigEncoding enc)
+concat_opt_exact_str(OptStr* to, UChar* s, UChar* end, OnigEncoding enc)
{
int i, j, len;
UChar *p;
for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
- len = enclen(enc, p);
+ SAFE_ENC_LEN(enc, p, end, len);
if (i + len > OPT_EXACT_MAXLEN) break;
for (j = 0; j < len && p < end; j++)
to->s[i++] = *p++;
}
to->len = i;
+
+ if (p >= end && to->len == (int )(end - s))
+ to->reach_end = 1;
}
static void
-alt_merge_opt_exact(OptExact* to, OptExact* add, OptEnv* env)
+alt_merge_opt_exact(OptStr* to, OptStr* add, OptEnv* env)
{
int i, j, len;
to->reach_end = 0;
}
to->len = i;
- to->ignore_case |= add->ignore_case;
+ if (add->case_fold != 0)
+ to->case_fold = 1;
+ if (add->good_case_fold == 0)
+ to->good_case_fold = 0;
alt_merge_opt_anc_info(&to->anc, &add->anc);
if (! to->reach_end) to->anc.right = 0;
}
static void
-select_opt_exact(OnigEncoding enc, OptExact* now, OptExact* alt)
+select_opt_exact(OnigEncoding enc, OptStr* now, OptStr* alt)
{
int vn, va;
if (alt->len > 1) va += 5;
}
- if (now->ignore_case == 0) vn *= 2;
- if (alt->ignore_case == 0) va *= 2;
+ if (now->case_fold == 0) vn *= 2;
+ if (alt->case_fold == 0) va *= 2;
+
+ if (now->good_case_fold != 0) vn *= 4;
+ if (alt->good_case_fold != 0) va *= 4;
if (comp_distance_value(&now->mmd, &alt->mmd, vn, va) > 0)
copy_opt_exact(now, alt);
}
static int
-comp_opt_exact_or_map(OptExact* e, OptMap* m)
+comp_opt_exact_or_map(OptStr* e, OptMap* m)
{
#define COMP_EM_BASE 20
int ae, am;
+ int case_value;
if (m->value <= 0) return -1;
- ae = COMP_EM_BASE * e->len * (e->ignore_case ? 1 : 2);
+ if (e->case_fold != 0) {
+ if (e->good_case_fold != 0)
+ case_value = 2;
+ else
+ case_value = 1;
+ }
+ else
+ case_value = 3;
+
+ ae = COMP_EM_BASE * e->len * case_value;
am = COMP_EM_BASE * 5 * 2 / m->value;
return comp_distance_value(&e->mmd, &m->mmd, ae, am);
}
alt_merge_mml(&to->mmd, &add->mmd);
val = 0;
- for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
+ for (i = 0; i < CHAR_MAP_SIZE; i++) {
if (add->map[i])
to->map[i] = 1;
}
static void
-set_bound_node_opt_info(NodeOpt* opt, MinMax* plen)
+set_bound_node_opt_info(OptNode* opt, MinMax* plen)
{
- copy_mml(&(opt->exb.mmd), plen);
- copy_mml(&(opt->expr.mmd), plen);
- copy_mml(&(opt->map.mmd), plen);
+ copy_mml(&(opt->sb.mmd), plen);
+ copy_mml(&(opt->spr.mmd), plen);
+ copy_mml(&(opt->map.mmd), plen);
}
static void
-clear_node_opt_info(NodeOpt* opt)
+clear_node_opt_info(OptNode* opt)
{
clear_mml(&opt->len);
clear_opt_anc_info(&opt->anc);
- clear_opt_exact(&opt->exb);
- clear_opt_exact(&opt->exm);
- clear_opt_exact(&opt->expr);
+ clear_opt_exact(&opt->sb);
+ clear_opt_exact(&opt->sm);
+ clear_opt_exact(&opt->spr);
clear_opt_map(&opt->map);
}
static void
-copy_node_opt_info(NodeOpt* to, NodeOpt* from)
+copy_node_opt_info(OptNode* to, OptNode* from)
{
*to = *from;
}
static void
-concat_left_node_opt_info(OnigEncoding enc, NodeOpt* to, NodeOpt* add)
+concat_left_node_opt_info(OnigEncoding enc, OptNode* to, OptNode* add)
{
- int exb_reach, exm_reach;
+ int sb_reach, sm_reach;
OptAnc tanc;
concat_opt_anc_info(&tanc, &to->anc, &add->anc, to->len.max, add->len.max);
copy_opt_anc_info(&to->anc, &tanc);
- if (add->exb.len > 0 && to->len.max == 0) {
- concat_opt_anc_info(&tanc, &to->anc, &add->exb.anc, to->len.max, add->len.max);
- copy_opt_anc_info(&add->exb.anc, &tanc);
+ if (add->sb.len > 0 && to->len.max == 0) {
+ concat_opt_anc_info(&tanc, &to->anc, &add->sb.anc, to->len.max, add->len.max);
+ copy_opt_anc_info(&add->sb.anc, &tanc);
}
if (add->map.value > 0 && to->len.max == 0) {
add->map.anc.left |= to->anc.left;
}
- exb_reach = to->exb.reach_end;
- exm_reach = to->exm.reach_end;
+ sb_reach = to->sb.reach_end;
+ sm_reach = to->sm.reach_end;
if (add->len.max != 0)
- to->exb.reach_end = to->exm.reach_end = 0;
+ to->sb.reach_end = to->sm.reach_end = 0;
- if (add->exb.len > 0) {
- if (exb_reach) {
- concat_opt_exact(&to->exb, &add->exb, enc);
- clear_opt_exact(&add->exb);
+ if (add->sb.len > 0) {
+ if (sb_reach) {
+ concat_opt_exact(&to->sb, &add->sb, enc);
+ clear_opt_exact(&add->sb);
}
- else if (exm_reach) {
- concat_opt_exact(&to->exm, &add->exb, enc);
- clear_opt_exact(&add->exb);
+ else if (sm_reach) {
+ concat_opt_exact(&to->sm, &add->sb, enc);
+ clear_opt_exact(&add->sb);
}
}
- select_opt_exact(enc, &to->exm, &add->exb);
- select_opt_exact(enc, &to->exm, &add->exm);
+ select_opt_exact(enc, &to->sm, &add->sb);
+ select_opt_exact(enc, &to->sm, &add->sm);
- if (to->expr.len > 0) {
+ if (to->spr.len > 0) {
if (add->len.max > 0) {
- if (to->expr.len > (int )add->len.max)
- to->expr.len = add->len.max;
+ if (to->spr.len > (int )add->len.max)
+ to->spr.len = add->len.max;
- if (to->expr.mmd.max == 0)
- select_opt_exact(enc, &to->exb, &to->expr);
+ if (to->spr.mmd.max == 0)
+ select_opt_exact(enc, &to->sb, &to->spr);
else
- select_opt_exact(enc, &to->exm, &to->expr);
+ select_opt_exact(enc, &to->sm, &to->spr);
}
}
- else if (add->expr.len > 0) {
- copy_opt_exact(&to->expr, &add->expr);
+ else if (add->spr.len > 0) {
+ copy_opt_exact(&to->spr, &add->spr);
}
select_opt_map(&to->map, &add->map);
}
static void
-alt_merge_node_opt_info(NodeOpt* to, NodeOpt* add, OptEnv* env)
+alt_merge_node_opt_info(OptNode* to, OptNode* add, OptEnv* env)
{
alt_merge_opt_anc_info(&to->anc, &add->anc);
- alt_merge_opt_exact(&to->exb, &add->exb, env);
- alt_merge_opt_exact(&to->exm, &add->exm, env);
- alt_merge_opt_exact(&to->expr, &add->expr, env);
+ alt_merge_opt_exact(&to->sb, &add->sb, env);
+ alt_merge_opt_exact(&to->sm, &add->sm, env);
+ alt_merge_opt_exact(&to->spr, &add->spr, env);
alt_merge_opt_map(env->enc, &to->map, &add->map);
alt_merge_mml(&to->len, &add->len);
#define MAX_NODE_OPT_INFO_REF_COUNT 5
static int
-optimize_nodes(Node* node, NodeOpt* opt, OptEnv* env)
+optimize_nodes(Node* node, OptNode* opt, OptEnv* env)
{
int i;
int r;
- NodeOpt xo;
+ OptNode xo;
OnigEncoding enc;
r = 0;
/* int is_raw = NODE_STRING_IS_RAW(node); */
if (! NODE_STRING_IS_AMBIG(node)) {
- concat_opt_exact_str(&opt->exb, sn->s, sn->end, enc);
+ concat_opt_exact_str(&opt->sb, sn->s, sn->end, enc);
if (slen > 0) {
add_char_opt_map(&opt->map, *(sn->s), enc);
}
max = ONIGENC_MBC_MAXLEN_DIST(enc) * n;
}
else {
- concat_opt_exact_str(&opt->exb, sn->s, sn->end, enc);
- opt->exb.ignore_case = 1;
+ concat_opt_exact_str(&opt->sb, sn->s, sn->end, enc);
+ opt->sb.case_fold = 1;
+ if (NODE_STRING_IS_GOOD_AMBIG(node))
+ opt->sb.good_case_fold = 1;
if (slen > 0) {
r = add_char_amb_opt_map(&opt->map, sn->s, sn->end,
set_mml(&opt->len, slen, max);
}
-
- if (opt->exb.len == slen)
- opt->exb.reach_end = 1;
}
break;
case NODE_ANCHOR:
switch (ANCHOR_(node)->type) {
- case ANCHOR_BEGIN_BUF:
- case ANCHOR_BEGIN_POSITION:
- case ANCHOR_BEGIN_LINE:
- case ANCHOR_END_BUF:
- case ANCHOR_SEMI_END_BUF:
- case ANCHOR_END_LINE:
- case ANCHOR_PREC_READ_NOT:
- case ANCHOR_LOOK_BEHIND:
+ case ANCR_BEGIN_BUF:
+ case ANCR_BEGIN_POSITION:
+ case ANCR_BEGIN_LINE:
+ case ANCR_END_BUF:
+ case ANCR_SEMI_END_BUF:
+ case ANCR_END_LINE:
+ case ANCR_PREC_READ_NOT:
+ case ANCR_LOOK_BEHIND:
add_opt_anc_info(&opt->anc, ANCHOR_(node)->type);
break;
- case ANCHOR_PREC_READ:
+ case ANCR_PREC_READ:
{
r = optimize_nodes(NODE_BODY(node), &xo, env);
if (r == 0) {
- if (xo.exb.len > 0)
- copy_opt_exact(&opt->expr, &xo.exb);
- else if (xo.exm.len > 0)
- copy_opt_exact(&opt->expr, &xo.exm);
+ if (xo.sb.len > 0)
+ copy_opt_exact(&opt->spr, &xo.sb);
+ else if (xo.sm.len > 0)
+ copy_opt_exact(&opt->spr, &xo.sm);
- opt->expr.reach_end = 0;
+ opt->spr.reach_end = 0;
if (xo.map.value > 0)
copy_opt_map(&opt->map, &xo.map);
}
break;
- case ANCHOR_LOOK_BEHIND_NOT:
+ case ANCR_LOOK_BEHIND_NOT:
break;
}
break;
set_mml(&opt->len, 0, INFINITE_LEN);
else {
OnigOptionType save = env->options;
- env->options = ENCLOSURE_(NODE_BODY(node))->o.options;
+ env->options = BAG_(NODE_BODY(node))->o.options;
r = optimize_nodes(NODE_BODY(node), opt, env);
env->options = save;
}
if (qn->lower > 0) {
copy_node_opt_info(opt, &xo);
- if (xo.exb.len > 0) {
- if (xo.exb.reach_end) {
- for (i = 2; i <= qn->lower && ! is_full_opt_exact(&opt->exb); i++) {
- int rc = concat_opt_exact(&opt->exb, &xo.exb, enc);
+ if (xo.sb.len > 0) {
+ if (xo.sb.reach_end) {
+ for (i = 2; i <= qn->lower && ! is_full_opt_exact(&opt->sb); i++) {
+ int rc = concat_opt_exact(&opt->sb, &xo.sb, enc);
if (rc > 0) break;
}
- if (i < qn->lower) opt->exb.reach_end = 0;
+ if (i < qn->lower) opt->sb.reach_end = 0;
}
}
if (qn->lower != qn->upper) {
- opt->exb.reach_end = 0;
- opt->exm.reach_end = 0;
+ opt->sb.reach_end = 0;
+ opt->sm.reach_end = 0;
}
if (qn->lower > 1)
- opt->exm.reach_end = 0;
+ opt->sm.reach_end = 0;
}
if (IS_REPEAT_INFINITE(qn->upper)) {
if (env->mmd.max == 0 &&
NODE_IS_ANYCHAR(NODE_BODY(node)) && qn->greedy != 0) {
if (IS_MULTILINE(CTYPE_OPTION(NODE_QUANT_BODY(qn), env)))
- add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_INF_ML);
+ add_opt_anc_info(&opt->anc, ANCR_ANYCHAR_INF_ML);
else
- add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_INF);
+ add_opt_anc_info(&opt->anc, ANCR_ANYCHAR_INF);
}
max = (xo.len.max > 0 ? INFINITE_LEN : 0);
}
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
{
- EnclosureNode* en = ENCLOSURE_(node);
+ BagNode* en = BAG_(node);
switch (en->type) {
- case ENCLOSURE_OPTION:
+ case BAG_OPTION:
{
OnigOptionType save = env->options;
}
break;
- case ENCLOSURE_MEMORY:
+ case BAG_MEMORY:
#ifdef USE_CALL
en->opt_count++;
if (en->opt_count > MAX_NODE_OPT_INFO_REF_COUNT) {
#endif
{
r = optimize_nodes(NODE_BODY(node), opt, env);
- if (is_set_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_INF_MASK)) {
+ if (is_set_opt_anc_info(&opt->anc, ANCR_ANYCHAR_INF_MASK)) {
if (MEM_STATUS_AT0(env->scan_env->backrefed_mem, en->m.regnum))
- remove_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_INF_MASK);
+ remove_opt_anc_info(&opt->anc, ANCR_ANYCHAR_INF_MASK);
}
}
break;
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_STOP_BACKTRACK:
r = optimize_nodes(NODE_BODY(node), opt, env);
break;
- case ENCLOSURE_IF_ELSE:
+ case BAG_IF_ELSE:
{
OptEnv nenv;
copy_opt_env(&nenv, env);
- r = optimize_nodes(NODE_ENCLOSURE_BODY(en), &xo, &nenv);
+ r = optimize_nodes(NODE_BAG_BODY(en), &xo, &nenv);
if (r == 0) {
add_mml(&nenv.mmd, &xo.len);
concat_left_node_opt_info(enc, opt, &xo);
}
static int
-set_optimize_exact(regex_t* reg, OptExact* e)
+set_optimize_exact(regex_t* reg, OptStr* e)
{
int r;
if (e->len == 0) return 0;
- if (e->ignore_case) {
- 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;
- reg->optimize = OPTIMIZE_EXACT_IC;
+ 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;
+
+ if (e->case_fold) {
+ reg->optimize = OPTIMIZE_STR_CASE_FOLD;
+ if (e->good_case_fold != 0) {
+ if (e->len >= 2) {
+ r = set_sunday_quick_search_or_bmh_skip_table(reg, 1,
+ reg->exact, reg->exact_end,
+ reg->map, &(reg->map_offset));
+ if (r != 0) return r;
+ reg->optimize = OPTIMIZE_STR_CASE_FOLD_FAST;
+ }
+ }
}
else {
int allow_reverse;
- reg->exact = onigenc_strdup(reg->enc, e->s, e->s + e->len);
- CHECK_NULL_RETURN_MEMERR(reg->exact);
- reg->exact_end = reg->exact + e->len;
-
allow_reverse =
ONIGENC_IS_ALLOWED_REVERSE_MATCH(reg->enc, reg->exact, reg->exact_end);
- if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
- r = set_bm_skip(reg->exact, reg->exact_end, reg->enc,
- reg->map, &(reg->int_map));
+ if (e->len >= 2 || (e->len >= 1 && allow_reverse)) {
+ r = set_sunday_quick_search_or_bmh_skip_table(reg, 0,
+ reg->exact, reg->exact_end,
+ reg->map, &(reg->map_offset));
if (r != 0) return r;
reg->optimize = (allow_reverse != 0
- ? OPTIMIZE_EXACT_BM : OPTIMIZE_EXACT_BM_NO_REV);
+ ? OPTIMIZE_STR_FAST
+ : OPTIMIZE_STR_FAST_STEP_FORWARD);
}
else {
- reg->optimize = OPTIMIZE_EXACT;
+ reg->optimize = OPTIMIZE_STR;
}
}
{
int i;
- for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
+ for (i = 0; i < CHAR_MAP_SIZE; i++)
reg->map[i] = m->map[i];
reg->optimize = OPTIMIZE_MAP;
static void
set_sub_anchor(regex_t* reg, OptAnc* anc)
{
- reg->sub_anchor |= anc->left & ANCHOR_BEGIN_LINE;
- reg->sub_anchor |= anc->right & ANCHOR_END_LINE;
+ reg->sub_anchor |= anc->left & ANCR_BEGIN_LINE;
+ reg->sub_anchor |= anc->right & ANCR_END_LINE;
}
#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
set_optimize_info_from_tree(Node* node, regex_t* reg, ScanEnv* scan_env)
{
int r;
- NodeOpt opt;
+ OptNode opt;
OptEnv env;
env.enc = reg->enc;
r = optimize_nodes(node, &opt, &env);
if (r != 0) return r;
- reg->anchor = opt.anc.left & (ANCHOR_BEGIN_BUF |
- ANCHOR_BEGIN_POSITION | ANCHOR_ANYCHAR_INF | ANCHOR_ANYCHAR_INF_ML |
- ANCHOR_LOOK_BEHIND);
+ reg->anchor = opt.anc.left & (ANCR_BEGIN_BUF |
+ ANCR_BEGIN_POSITION | ANCR_ANYCHAR_INF | ANCR_ANYCHAR_INF_ML |
+ ANCR_LOOK_BEHIND);
- if ((opt.anc.left & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) != 0)
- reg->anchor &= ~ANCHOR_ANYCHAR_INF_ML;
+ if ((opt.anc.left & (ANCR_LOOK_BEHIND | ANCR_PREC_READ_NOT)) != 0)
+ reg->anchor &= ~ANCR_ANYCHAR_INF_ML;
- reg->anchor |= opt.anc.right & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF |
- ANCHOR_PREC_READ_NOT);
+ reg->anchor |= opt.anc.right & (ANCR_END_BUF | ANCR_SEMI_END_BUF |
+ ANCR_PREC_READ_NOT);
- if (reg->anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)) {
+ if (reg->anchor & (ANCR_END_BUF | ANCR_SEMI_END_BUF)) {
reg->anchor_dmin = opt.len.min;
reg->anchor_dmax = opt.len.max;
}
- if (opt.exb.len > 0 || opt.exm.len > 0) {
- select_opt_exact(reg->enc, &opt.exb, &opt.exm);
- if (opt.map.value > 0 && comp_opt_exact_or_map(&opt.exb, &opt.map) > 0) {
+ if (opt.sb.len > 0 || opt.sm.len > 0) {
+ select_opt_exact(reg->enc, &opt.sb, &opt.sm);
+ if (opt.map.value > 0 && comp_opt_exact_or_map(&opt.sb, &opt.map) > 0) {
goto set_map;
}
else {
- r = set_optimize_exact(reg, &opt.exb);
- set_sub_anchor(reg, &opt.exb.anc);
+ r = set_optimize_exact(reg, &opt.sb);
+ set_sub_anchor(reg, &opt.sb.anc);
}
}
else if (opt.map.value > 0) {
set_sub_anchor(reg, &opt.map.anc);
}
else {
- reg->sub_anchor |= opt.anc.left & ANCHOR_BEGIN_LINE;
+ reg->sub_anchor |= opt.anc.left & ANCR_BEGIN_LINE;
if (opt.len.max == 0)
- reg->sub_anchor |= opt.anc.right & ANCHOR_END_LINE;
+ reg->sub_anchor |= opt.anc.right & ANCR_END_LINE;
}
#if defined(ONIG_DEBUG_COMPILE) || defined(ONIG_DEBUG_MATCH)
reg->anchor_dmax = 0;
reg->sub_anchor = 0;
reg->exact_end = (UChar* )NULL;
+ reg->map_offset = 0;
reg->threshold_len = 0;
if (IS_NOT_NULL(reg->exact)) {
xfree(reg->exact);
fprintf(f, "[");
- if (anchor & ANCHOR_BEGIN_BUF) {
+ if (anchor & ANCR_BEGIN_BUF) {
fprintf(f, "begin-buf");
q = 1;
}
- if (anchor & ANCHOR_BEGIN_LINE) {
+ if (anchor & ANCR_BEGIN_LINE) {
if (q) fprintf(f, ", ");
q = 1;
fprintf(f, "begin-line");
}
- if (anchor & ANCHOR_BEGIN_POSITION) {
+ if (anchor & ANCR_BEGIN_POSITION) {
if (q) fprintf(f, ", ");
q = 1;
fprintf(f, "begin-pos");
}
- if (anchor & ANCHOR_END_BUF) {
+ if (anchor & ANCR_END_BUF) {
if (q) fprintf(f, ", ");
q = 1;
fprintf(f, "end-buf");
}
- if (anchor & ANCHOR_SEMI_END_BUF) {
+ if (anchor & ANCR_SEMI_END_BUF) {
if (q) fprintf(f, ", ");
q = 1;
fprintf(f, "semi-end-buf");
}
- if (anchor & ANCHOR_END_LINE) {
+ if (anchor & ANCR_END_LINE) {
if (q) fprintf(f, ", ");
q = 1;
fprintf(f, "end-line");
}
- if (anchor & ANCHOR_ANYCHAR_INF) {
+ if (anchor & ANCR_ANYCHAR_INF) {
if (q) fprintf(f, ", ");
q = 1;
fprintf(f, "anychar-inf");
}
- if (anchor & ANCHOR_ANYCHAR_INF_ML) {
+ if (anchor & ANCR_ANYCHAR_INF_ML) {
if (q) fprintf(f, ", ");
fprintf(f, "anychar-inf-ml");
}
static void
print_optimize_info(FILE* f, regex_t* reg)
{
- static const char* on[] = { "NONE", "EXACT", "EXACT_BM", "EXACT_BM_NOT_REV",
- "EXACT_IC", "MAP" };
+ static const char* on[] = { "NONE", "STR",
+ "STR_FAST", "STR_FAST_STEP_FORWARD",
+ "STR_CASE_FOLD_FAST", "STR_CASE_FOLD", "MAP" };
fprintf(f, "optimize: %s\n", on[reg->optimize]);
fprintf(f, " anchor: "); print_anchor(f, reg->anchor);
- if ((reg->anchor & ANCHOR_END_BUF_MASK) != 0)
+ if ((reg->anchor & ANCR_END_BUF_MASK) != 0)
print_distance_range(f, reg->anchor_dmin, reg->anchor_dmax);
fprintf(f, "\n");
else if (reg->optimize & OPTIMIZE_MAP) {
int c, i, n = 0;
- for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
+ for (i = 0; i < CHAR_MAP_SIZE; i++)
if (reg->map[i]) n++;
fprintf(f, "map: n=%d\n", n);
if (n > 0) {
c = 0;
fputc('[', f);
- for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
+ for (i = 0; i < CHAR_MAP_SIZE; i++) {
if (reg->map[i] != 0) {
if (c > 0) fputs(", ", f);
c++;
extern RegexExt*
onig_get_regex_ext(regex_t* reg)
{
- if (IS_NULL(REG_EXTP(reg))) {
+ if (IS_NULL(reg->extp)) {
RegexExt* ext = (RegexExt* )xmalloc(sizeof(*ext));
if (IS_NULL(ext)) return 0;
ext->callout_list = 0;
#endif
- REG_EXTPL(reg) = (void* )ext;
+ reg->extp = ext;
}
- return REG_EXTP(reg);
+ return reg->extp;
}
static void
if (IS_NOT_NULL(reg)) {
if (IS_NOT_NULL(reg->p)) xfree(reg->p);
if (IS_NOT_NULL(reg->exact)) xfree(reg->exact);
- if (IS_NOT_NULL(reg->int_map)) xfree(reg->int_map);
- if (IS_NOT_NULL(reg->int_map_backward)) xfree(reg->int_map_backward);
if (IS_NOT_NULL(reg->repeat_range)) xfree(reg->repeat_range);
- if (IS_NOT_NULL(REG_EXTP(reg))) {
- free_regex_ext(REG_EXTP(reg));
- REG_EXTPL(reg) = 0;
+ if (IS_NOT_NULL(reg->extp)) {
+ free_regex_ext(reg->extp);
+ reg->extp = 0;
}
onig_names_free(reg);
if ((reg->num_repeat != 0) || (reg->bt_mem_end != 0)
#ifdef USE_CALLOUT
- || (IS_NOT_NULL(REG_EXTP(reg)) && REG_EXTP(reg)->callout_num != 0)
+ || (IS_NOT_NULL(reg->extp) && reg->extp->callout_num != 0)
#endif
)
reg->stack_pop_level = STACK_POP_LEVEL_ALL;
(reg)->syntax = syntax;
(reg)->optimize = 0;
(reg)->exact = (UChar* )NULL;
- (reg)->int_map = (int* )NULL;
- (reg)->int_map_backward = (int* )NULL;
- REG_EXTPL(reg) = NULL;
+ (reg)->extp = (RegexExt* )NULL;
(reg)->p = (UChar* )NULL;
(reg)->alloc = 0;
found = 0;
}
else {
- found = (onig_is_in_code_range(cc->mbuf->p, code) != 0 ? 1 : 0);
+ found = onig_is_in_code_range(cc->mbuf->p, code) != 0;
}
}
else {
- found = (BITSET_AT(cc->bs, code) == 0 ? 0 : 1);
+ found = BITSET_AT(cc->bs, code) != 0;
}
if (IS_NCCLASS_NOT(cc))
break;
case NODE_STRING:
- fprintf(f, "<string%s:%p>", (NODE_STRING_IS_RAW(node) ? "-raw" : ""), node);
- for (p = STR_(node)->s; p < STR_(node)->end; p++) {
- if (*p >= 0x20 && *p < 0x7f)
- fputc(*p, f);
- else {
- fprintf(f, " 0x%02x", *p);
+ {
+ char* mode;
+ char* dont;
+ char* good;
+
+ if (NODE_STRING_IS_RAW(node))
+ mode = "-raw";
+ else if (NODE_STRING_IS_AMBIG(node))
+ mode = "-ambig";
+ else
+ mode = "";
+
+ if (NODE_STRING_IS_GOOD_AMBIG(node))
+ good = "-good";
+ else
+ good = "";
+
+ if (NODE_STRING_IS_DONT_GET_OPT_INFO(node))
+ dont = " (dont-opt)";
+ else
+ dont = "";
+
+ fprintf(f, "<string%s%s%s:%p>", mode, good, dont, node);
+ for (p = STR_(node)->s; p < STR_(node)->end; p++) {
+ if (*p >= 0x20 && *p < 0x7f)
+ fputc(*p, f);
+ else {
+ fprintf(f, " 0x%02x", *p);
+ }
}
}
break;
case NODE_ANCHOR:
fprintf(f, "<anchor:%p> ", node);
switch (ANCHOR_(node)->type) {
- case ANCHOR_BEGIN_BUF: fputs("begin buf", f); break;
- case ANCHOR_END_BUF: fputs("end buf", f); break;
- case ANCHOR_BEGIN_LINE: fputs("begin line", f); break;
- case ANCHOR_END_LINE: fputs("end line", f); break;
- case ANCHOR_SEMI_END_BUF: fputs("semi end buf", f); break;
- case ANCHOR_BEGIN_POSITION: fputs("begin position", f); break;
-
- case ANCHOR_WORD_BOUNDARY: fputs("word boundary", f); break;
- case ANCHOR_NO_WORD_BOUNDARY: fputs("not word boundary", f); break;
+ case ANCR_BEGIN_BUF: fputs("begin buf", f); break;
+ case ANCR_END_BUF: fputs("end buf", f); break;
+ case ANCR_BEGIN_LINE: fputs("begin line", f); break;
+ case ANCR_END_LINE: fputs("end line", f); break;
+ case ANCR_SEMI_END_BUF: fputs("semi end buf", f); break;
+ case ANCR_BEGIN_POSITION: fputs("begin position", f); break;
+
+ case ANCR_WORD_BOUNDARY: fputs("word boundary", f); break;
+ case ANCR_NO_WORD_BOUNDARY: fputs("not word boundary", f); break;
#ifdef USE_WORD_BEGIN_END
- case ANCHOR_WORD_BEGIN: fputs("word begin", f); break;
- case ANCHOR_WORD_END: fputs("word end", f); break;
+ case ANCR_WORD_BEGIN: fputs("word begin", f); break;
+ case ANCR_WORD_END: fputs("word end", f); break;
#endif
- case ANCHOR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
+ case ANCR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
fputs("extended-grapheme-cluster boundary", f); break;
- case ANCHOR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
+ case ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
fputs("no-extended-grapheme-cluster boundary", f); break;
- case ANCHOR_PREC_READ:
+ case ANCR_PREC_READ:
fprintf(f, "prec read\n");
print_indent_tree(f, NODE_BODY(node), indent + add);
break;
- case ANCHOR_PREC_READ_NOT:
+ case ANCR_PREC_READ_NOT:
fprintf(f, "prec read not\n");
print_indent_tree(f, NODE_BODY(node), indent + add);
break;
- case ANCHOR_LOOK_BEHIND:
+ case ANCR_LOOK_BEHIND:
fprintf(f, "look behind\n");
print_indent_tree(f, NODE_BODY(node), indent + add);
break;
- case ANCHOR_LOOK_BEHIND_NOT:
+ case ANCR_LOOK_BEHIND_NOT:
fprintf(f, "look behind not\n");
print_indent_tree(f, NODE_BODY(node), indent + add);
break;
print_indent_tree(f, NODE_BODY(node), indent + add);
break;
- case NODE_ENCLOSURE:
- fprintf(f, "<enclosure:%p> ", node);
- switch (ENCLOSURE_(node)->type) {
- case ENCLOSURE_OPTION:
- fprintf(f, "option:%d", ENCLOSURE_(node)->o.options);
+ case NODE_BAG:
+ fprintf(f, "<bag:%p> ", node);
+ switch (BAG_(node)->type) {
+ case BAG_OPTION:
+ fprintf(f, "option:%d", BAG_(node)->o.options);
break;
- case ENCLOSURE_MEMORY:
- fprintf(f, "memory:%d", ENCLOSURE_(node)->m.regnum);
+ case BAG_MEMORY:
+ fprintf(f, "memory:%d", BAG_(node)->m.regnum);
break;
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_STOP_BACKTRACK:
fprintf(f, "stop-bt");
break;
-
- default:
+ case BAG_IF_ELSE:
+ fprintf(f, "if-else");
break;
}
fprintf(f, "\n");
}
if (type != NODE_LIST && type != NODE_ALT && type != NODE_QUANT &&
- type != NODE_ENCLOSURE)
+ type != NODE_BAG)
fprintf(f, "\n");
fflush(f);
}
{
int n = 0;
UChar* q = (UChar* )p;
-
+
while (q < end) {
q += ONIGENC_MBC_ENC_LEN(enc, q);
n++;
{
int n = 0;
UChar* p = (UChar* )s;
-
+
while (1) {
if (*p == '\0') {
UChar* q;
#define ONIG_ENCODING_INIT_DEFAULT ONIG_ENCODING_ASCII
+#define ENC_SKIP_OFFSET_1_OR_0 7
+
#define ENC_FLAG_ASCII_COMPATIBLE (1<<0)
#define ENC_FLAG_UNICODE (1<<1)
+#define ENC_FLAG_SKIP_OFFSET_MASK (7<<2)
+#define ENC_FLAG_SKIP_OFFSET_0 0
+#define ENC_FLAG_SKIP_OFFSET_1 (1<<2)
+#define ENC_FLAG_SKIP_OFFSET_2 (2<<2)
+#define ENC_FLAG_SKIP_OFFSET_3 (3<<2)
+#define ENC_FLAG_SKIP_OFFSET_4 (4<<2)
+#define ENC_FLAG_SKIP_OFFSET_1_OR_0 (ENC_SKIP_OFFSET_1_OR_0<<2)
+
+#define ENC_GET_SKIP_OFFSET(enc) \
+ (((enc)->flag & ENC_FLAG_SKIP_OFFSET_MASK)>>2)
/* for encoding system implementation (internal) */
else if ((buk)->fold_len == 3)\
addr = OnigUnicodeFolds3 + (buk)->index;\
else\
- addr = 0;\
+ return ONIGERR_INVALID_CODE_POINT_VALUE;\
} while (0)
extern OnigCodePoint OnigUnicodeFolds1[];
#define ONIGENC_IS_ASCII_CODE_CASE_AMBIG(code) \
(ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_UPPER) ||\
ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_LOWER))
-
+
#define ONIGENC_IS_UNICODE_ENCODING(enc) \
(((enc)->flag & ENC_FLAG_UNICODE) != 0)
#include "regint.h"
#include <stdio.h> /* for vsnprintf() */
-#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
-#define va_init_list(a,b) va_start(a,b)
-#else
-#include <varargs.h>
-#define va_init_list(a,b) va_start(a)
-#endif
extern UChar*
onig_error_code_to_format(int code)
if (len >= buf_size) break;
}
- *is_over = ((p < end) ? 1 : 0);
+ *is_over = p < end;
}
else {
len = MIN((int )(end - s), buf_size);
/* for ONIG_MAX_ERROR_MESSAGE_LEN */
#define MAX_ERROR_PAR_LEN 30
-extern int
-#ifdef HAVE_STDARG_PROTOTYPES
-onig_error_code_to_str(UChar* s, int code, ...)
-#else
-onig_error_code_to_str(s, code, va_alist)
- UChar* s;
- int code;
- va_dcl
-#endif
+extern int onig_error_code_to_str(UChar* s, int code, ...)
{
UChar *p, *q;
OnigErrorInfo* einfo;
UChar parbuf[MAX_ERROR_PAR_LEN];
va_list vargs;
- va_init_list(vargs, code);
+ va_start(vargs, code);
switch (code) {
case ONIGERR_UNDEFINED_NAME_REFERENCE:
}
-void
-#ifdef HAVE_STDARG_PROTOTYPES
-onig_snprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
- UChar* pat, UChar* pat_end, const UChar *fmt, ...)
-#else
-onig_snprintf_with_pattern(buf, bufsize, enc, pat, pat_end, fmt, va_alist)
- UChar buf[];
- int bufsize;
- OnigEncoding enc;
- UChar* pat;
- UChar* pat_end;
- const UChar *fmt;
- va_dcl
-#endif
+void onig_snprintf_with_pattern(UChar buf[], int bufsize, OnigEncoding enc,
+ UChar* pat, UChar* pat_end, const UChar *fmt, ...)
{
int n, need, len;
UChar *p, *s, *bp;
UChar bs[6];
va_list args;
- va_init_list(args, fmt);
+ va_start(args, fmt);
n = xvsnprintf((char* )buf, bufsize, (const char* )fmt, args);
va_end(args);
onig_region_resize_clear(OnigRegion* region, int n)
{
int r;
-
+
r = onig_region_resize(region, n);
if (r != 0) return r;
onig_region_clear(region);
return 0;
}
-
+
extern int
onig_region_set(OnigRegion* region, int at, int beg, int end)
{
int r = onig_region_resize(region, at + 1);
if (r < 0) return r;
}
-
+
region->beg[at] = beg;
region->end[at] = end;
return 0;
static int
adjust_match_param(regex_t* reg, OnigMatchParam* mp)
{
- RegexExt* ext = REG_EXTP(reg);
+ RegexExt* ext = reg->extp;
mp->match_at_call_counter = 0;
regoff_t rm_eo;
} posix_regmatch_t;
+
+#ifdef __GNUC__
+#define USE_THREADED_CODE
+#endif
+
+#ifdef USE_THREADED_CODE
+
+#define BYTECODE_INTERPRETER_START JUMP_OP;
+#define BYTECODE_INTERPRETER_END
+#define CASE_OP(x) L_##x: SOP_IN(OP_##x); sbegin = s; MATCH_DEBUG_OUT(1)
+#define DEFAULT_OP /* L_DEFAULT: */
+#define NEXT_OP sprev = sbegin; JUMP_OP
+#define JUMP_OP goto *opcode_to_label[*p++]
+#define BREAK_OP /* Nothing */
+
+#else
+
+#define BYTECODE_INTERPRETER_START \
+ while (1) {\
+ MATCH_DEBUG_OUT(0)\
+ sbegin = s;\
+ switch (*p++) {
+#define BYTECODE_INTERPRETER_END } sprev = sbegin; }
+#define CASE_OP(x) case OP_##x: SOP_IN(OP_##x);
+#define DEFAULT_OP default:
+#define NEXT_OP break
+#define JUMP_OP continue; break
+#define BREAK_OP break
+
+#endif /* USE_THREADED_CODE */
+
+#define NEXT_OUT SOP_OUT; NEXT_OP
+#define JUMP_OUT SOP_OUT; JUMP_OP
+#define BREAK_OUT SOP_OUT; BREAK_OP
+#define CHECK_INTERRUPT_JUMP_OUT SOP_OUT; CHECK_INTERRUPT_IN_MATCH; JUMP_OP
+
+
+#ifdef ONIG_DEBUG_MATCH
+#define MATCH_DEBUG_OUT(offset) do {\
+ UChar *xp, *q, *bp, buf[50];\
+ int len, spos;\
+ spos = IS_NOT_NULL(s) ? (int )(s - str) : -1;\
+ xp = p - (offset);\
+ fprintf(stderr, "%7u: %7ld: %4d> \"",\
+ counter, GET_STACK_INDEX(stk), spos);\
+ counter++;\
+ bp = buf;\
+ if (IS_NOT_NULL(s)) {\
+ for (i = 0, q = s; i < 7 && q < end; i++) {\
+ len = enclen(encode, q);\
+ while (len-- > 0) *bp++ = *q++;\
+ }\
+ if (q < end) { xmemcpy(bp, "...\"", 4); bp += 4; }\
+ else { xmemcpy(bp, "\"", 1); bp += 1; }\
+ }\
+ else {\
+ xmemcpy(bp, "\"", 1); bp += 1;\
+ }\
+ *bp = 0;\
+ fputs((char* )buf, stderr);\
+ for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);\
+ if (xp == FinishCode)\
+ fprintf(stderr, "----: ");\
+ else\
+ fprintf(stderr, "%4d: ", (int )(xp - reg->p));\
+ onig_print_compiled_byte_code(stderr, xp, NULL, reg->p, encode);\
+ fprintf(stderr, "\n");\
+ } while(0);
+#else
+#define MATCH_DEBUG_OUT(offset)
+#endif
+
+
/* match data(str - end) from position (sstart). */
/* if sstart == str then set sprev to NULL. */
static int
{
static UChar FinishCode[] = { OP_FINISH };
+#ifdef USE_THREADED_CODE
+ static const void *opcode_to_label[] = {
+ &&L_FINISH,
+ &&L_END,
+ &&L_EXACT1,
+ &&L_EXACT2,
+ &&L_EXACT3,
+ &&L_EXACT4,
+ &&L_EXACT5,
+ &&L_EXACTN,
+ &&L_EXACTMB2N1,
+ &&L_EXACTMB2N2,
+ &&L_EXACTMB2N3,
+ &&L_EXACTMB2N,
+ &&L_EXACTMB3N,
+ &&L_EXACTMBN,
+ &&L_EXACT1_IC,
+ &&L_EXACTN_IC,
+ &&L_CCLASS,
+ &&L_CCLASS_MB,
+ &&L_CCLASS_MIX,
+ &&L_CCLASS_NOT,
+ &&L_CCLASS_MB_NOT,
+ &&L_CCLASS_MIX_NOT,
+#ifdef USE_OP_CCLASS_NODE
+ &&L_CCLASS_NODE,
+#endif
+ &&L_ANYCHAR,
+ &&L_ANYCHAR_ML,
+ &&L_ANYCHAR_STAR,
+ &&L_ANYCHAR_ML_STAR,
+ &&L_ANYCHAR_STAR_PEEK_NEXT,
+ &&L_ANYCHAR_ML_STAR_PEEK_NEXT,
+ &&L_WORD,
+ &&L_WORD_ASCII,
+ &&L_NO_WORD,
+ &&L_NO_WORD_ASCII,
+ &&L_WORD_BOUNDARY,
+ &&L_NO_WORD_BOUNDARY,
+ &&L_WORD_BEGIN,
+ &&L_WORD_END,
+ &&L_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY,
+ &&L_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY,
+ &&L_BEGIN_BUF,
+ &&L_END_BUF,
+ &&L_BEGIN_LINE,
+ &&L_END_LINE,
+ &&L_SEMI_END_BUF,
+ &&L_BEGIN_POSITION,
+ &&L_BACKREF1,
+ &&L_BACKREF2,
+ &&L_BACKREF_N,
+ &&L_BACKREF_N_IC,
+ &&L_BACKREF_MULTI,
+ &&L_BACKREF_MULTI_IC,
+ &&L_BACKREF_WITH_LEVEL,
+ &&L_BACKREF_CHECK,
+ &&L_BACKREF_CHECK_WITH_LEVEL,
+ &&L_MEMORY_START,
+ &&L_MEMORY_START_PUSH,
+ &&L_MEMORY_END_PUSH,
+ &&L_MEMORY_END_PUSH_REC,
+ &&L_MEMORY_END,
+ &&L_MEMORY_END_REC,
+ &&L_FAIL,
+ &&L_JUMP,
+ &&L_PUSH,
+ &&L_PUSH_SUPER,
+ &&L_POP_OUT,
+ &&L_PUSH_OR_JUMP_EXACT1,
+ &&L_PUSH_IF_PEEK_NEXT,
+ &&L_REPEAT,
+ &&L_REPEAT_NG,
+ &&L_REPEAT_INC,
+ &&L_REPEAT_INC_NG,
+ &&L_REPEAT_INC_SG,
+ &&L_REPEAT_INC_NG_SG,
+ &&L_EMPTY_CHECK_START,
+ &&L_EMPTY_CHECK_END,
+ &&L_EMPTY_CHECK_END_MEMST,
+ &&L_EMPTY_CHECK_END_MEMST_PUSH,
+ &&L_PREC_READ_START,
+ &&L_PREC_READ_END,
+ &&L_PREC_READ_NOT_START,
+ &&L_PREC_READ_NOT_END,
+ &&L_ATOMIC_START,
+ &&L_ATOMIC_END,
+ &&L_LOOK_BEHIND,
+ &&L_LOOK_BEHIND_NOT_START,
+ &&L_LOOK_BEHIND_NOT_END,
+ &&L_CALL,
+ &&L_RETURN,
+ &&L_PUSH_SAVE_VAL,
+ &&L_UPDATE_VAR,
+#ifdef USE_CALLOUT
+ &&L_CALLOUT_CONTENTS,
+ &&L_CALLOUT_NAME,
+#endif
+ };
+#endif
+
int i, n, num_mem, best_len, pop_level;
LengthType tlen, tlen2;
MemNumType mem;
OnigEncoding encode = reg->enc;
OnigCaseFoldType case_fold_flag = reg->case_fold_flag;
+#ifdef ONIG_DEBUG_MATCH
+ static unsigned int counter = 1;
+#endif
+
#ifdef USE_CALLOUT
msa->mp->match_at_call_counter++;
#endif
retry_in_match_counter = 0;
#endif
- while (1) {
-#ifdef ONIG_DEBUG_MATCH
- {
- static unsigned int counter = 1;
-
- UChar *q, *bp, buf[50];
- int len;
- fprintf(stderr, "%7u: %7ld: %4d> \"",
- counter, GET_STACK_INDEX(stk), (int )(s - str));
- counter++;
-
- bp = buf;
- for (i = 0, q = s; i < 7 && q < end; i++) {
- len = enclen(encode, q);
- while (len-- > 0) *bp++ = *q++;
- }
- if (q < end) { xmemcpy(bp, "...\"", 4); bp += 4; }
- else { xmemcpy(bp, "\"", 1); bp += 1; }
- *bp = 0;
- fputs((char* )buf, stderr);
-
- for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);
- if (p == FinishCode)
- fprintf(stderr, "----: ");
- else
- fprintf(stderr, "%4d: ", (int )(p - reg->p));
- onig_print_compiled_byte_code(stderr, p, NULL, reg->p, encode);
- fprintf(stderr, "\n");
- }
-#endif
-
- sbegin = s;
- switch (*p++) {
- case OP_END: SOP_IN(OP_END);
+ BYTECODE_INTERPRETER_START {
+ CASE_OP(END)
n = (int )(s - sstart);
if (n > best_len) {
OnigRegion* region;
/* default behavior: return first-matching result. */
goto finish;
- break;
- case OP_EXACT1: SOP_IN(OP_EXACT1);
+ CASE_OP(EXACT1)
DATA_ENSURE(1);
if (*p != *s) goto fail;
p++; s++;
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_EXACT1_IC: SOP_IN(OP_EXACT1_IC);
+ CASE_OP(EXACT1_IC)
{
int len;
UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
p++; q++;
}
}
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_EXACT2: SOP_IN(OP_EXACT2);
+ CASE_OP(EXACT2)
DATA_ENSURE(2);
if (*p != *s) goto fail;
p++; s++;
if (*p != *s) goto fail;
sprev = s;
p++; s++;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACT3: SOP_IN(OP_EXACT3);
+ CASE_OP(EXACT3)
DATA_ENSURE(3);
if (*p != *s) goto fail;
p++; s++;
if (*p != *s) goto fail;
sprev = s;
p++; s++;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACT4: SOP_IN(OP_EXACT4);
+ CASE_OP(EXACT4)
DATA_ENSURE(4);
if (*p != *s) goto fail;
p++; s++;
if (*p != *s) goto fail;
sprev = s;
p++; s++;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACT5: SOP_IN(OP_EXACT5);
+ CASE_OP(EXACT5)
DATA_ENSURE(5);
if (*p != *s) goto fail;
p++; s++;
if (*p != *s) goto fail;
sprev = s;
p++; s++;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACTN: SOP_IN(OP_EXACTN);
+ CASE_OP(EXACTN)
GET_LENGTH_INC(tlen, p);
DATA_ENSURE(tlen);
while (tlen-- > 0) {
if (*p++ != *s++) goto fail;
}
sprev = s - 1;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACTN_IC: SOP_IN(OP_EXACTN_IC);
+ CASE_OP(EXACTN_IC)
{
int len;
UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACTMB2N1: SOP_IN(OP_EXACTMB2N1);
+ CASE_OP(EXACTMB2N1)
DATA_ENSURE(2);
if (*p != *s) goto fail;
p++; s++;
if (*p != *s) goto fail;
p++; s++;
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_EXACTMB2N2: SOP_IN(OP_EXACTMB2N2);
+ CASE_OP(EXACTMB2N2)
DATA_ENSURE(4);
if (*p != *s) goto fail;
p++; s++;
p++; s++;
if (*p != *s) goto fail;
p++; s++;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACTMB2N3: SOP_IN(OP_EXACTMB2N3);
+ CASE_OP(EXACTMB2N3)
DATA_ENSURE(6);
if (*p != *s) goto fail;
p++; s++;
p++; s++;
if (*p != *s) goto fail;
p++; s++;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACTMB2N: SOP_IN(OP_EXACTMB2N);
+ CASE_OP(EXACTMB2N)
GET_LENGTH_INC(tlen, p);
DATA_ENSURE(tlen * 2);
while (tlen-- > 0) {
p++; s++;
}
sprev = s - 2;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACTMB3N: SOP_IN(OP_EXACTMB3N);
+ CASE_OP(EXACTMB3N)
GET_LENGTH_INC(tlen, p);
DATA_ENSURE(tlen * 3);
while (tlen-- > 0) {
p++; s++;
}
sprev = s - 3;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EXACTMBN: SOP_IN(OP_EXACTMBN);
+ CASE_OP(EXACTMBN)
GET_LENGTH_INC(tlen, p); /* mb-len */
GET_LENGTH_INC(tlen2, p); /* string len */
tlen2 *= tlen;
p++; s++;
}
sprev = s - tlen;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_CCLASS: SOP_IN(OP_CCLASS);
+ CASE_OP(CCLASS)
DATA_ENSURE(1);
if (BITSET_AT(((BitSetRef )p), *s) == 0) goto fail;
p += SIZE_BITSET;
s += enclen(encode, s); /* OP_CCLASS can match mb-code. \D, \S */
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_CCLASS_MB: SOP_IN(OP_CCLASS_MB);
+ CASE_OP(CCLASS_MB)
if (! ONIGENC_IS_MBC_HEAD(encode, s)) goto fail;
cclass_mb:
#endif
}
p += tlen;
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_CCLASS_MIX: SOP_IN(OP_CCLASS_MIX);
+ CASE_OP(CCLASS_MIX)
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_HEAD(encode, s)) {
p += SIZE_BITSET;
p += tlen;
s++;
}
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_CCLASS_NOT: SOP_IN(OP_CCLASS_NOT);
+ CASE_OP(CCLASS_NOT)
DATA_ENSURE(1);
if (BITSET_AT(((BitSetRef )p), *s) != 0) goto fail;
p += SIZE_BITSET;
s += enclen(encode, s);
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_CCLASS_MB_NOT: SOP_IN(OP_CCLASS_MB_NOT);
+ CASE_OP(CCLASS_MB_NOT)
DATA_ENSURE(1);
if (! ONIGENC_IS_MBC_HEAD(encode, s)) {
s++;
p += tlen;
cc_mb_not_success:
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_CCLASS_MIX_NOT: SOP_IN(OP_CCLASS_MIX_NOT);
+ CASE_OP(CCLASS_MIX_NOT)
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_HEAD(encode, s)) {
p += SIZE_BITSET;
p += tlen;
s++;
}
- SOP_OUT;
- break;
+ NEXT_OUT;
#ifdef USE_OP_CCLASS_NODE
- case OP_CCLASS_NODE: SOP_IN(OP_CCLASS_NODE);
+ CASE_OP(CCLASS_NODE)
{
OnigCodePoint code;
void *node;
code = ONIGENC_MBC_TO_CODE(encode, ss, s);
if (onig_is_code_in_cc_len(mb_len, code, node) == 0) goto fail;
}
- SOP_OUT;
- break;
+ NEXT_OUT;
#endif
- case OP_ANYCHAR: SOP_IN(OP_ANYCHAR);
+ CASE_OP(ANYCHAR)
DATA_ENSURE(1);
n = enclen(encode, s);
DATA_ENSURE(n);
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
s += n;
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_ANYCHAR_ML: SOP_IN(OP_ANYCHAR_ML);
+ CASE_OP(ANYCHAR_ML)
DATA_ENSURE(1);
n = enclen(encode, s);
DATA_ENSURE(n);
s += n;
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_ANYCHAR_STAR: SOP_IN(OP_ANYCHAR_STAR);
+ CASE_OP(ANYCHAR_STAR)
while (DATA_ENSURE_CHECK1) {
STACK_PUSH_ALT(p, s, sprev);
n = enclen(encode, s);
sprev = s;
s += n;
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_ANYCHAR_ML_STAR: SOP_IN(OP_ANYCHAR_ML_STAR);
+ CASE_OP(ANYCHAR_ML_STAR)
while (DATA_ENSURE_CHECK1) {
STACK_PUSH_ALT(p, s, sprev);
n = enclen(encode, s);
s++;
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_ANYCHAR_STAR_PEEK_NEXT: SOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
+ CASE_OP(ANYCHAR_STAR_PEEK_NEXT)
while (DATA_ENSURE_CHECK1) {
if (*p == *s) {
STACK_PUSH_ALT(p + 1, s, sprev);
s += n;
}
p++;
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_ANYCHAR_ML_STAR_PEEK_NEXT:SOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
+ CASE_OP(ANYCHAR_ML_STAR_PEEK_NEXT)
while (DATA_ENSURE_CHECK1) {
if (*p == *s) {
STACK_PUSH_ALT(p + 1, s, sprev);
}
}
p++;
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_WORD: SOP_IN(OP_WORD);
+ CASE_OP(WORD)
DATA_ENSURE(1);
if (! ONIGENC_IS_MBC_WORD(encode, s, end))
goto fail;
s += enclen(encode, s);
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_WORD_ASCII: SOP_IN(OP_WORD_ASCII);
+ CASE_OP(WORD_ASCII)
DATA_ENSURE(1);
if (! ONIGENC_IS_MBC_WORD_ASCII(encode, s, end))
goto fail;
s += enclen(encode, s);
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_NO_WORD: SOP_IN(OP_NO_WORD);
+ CASE_OP(NO_WORD)
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_WORD(encode, s, end))
goto fail;
s += enclen(encode, s);
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_NO_WORD_ASCII: SOP_IN(OP_NO_WORD_ASCII);
+ CASE_OP(NO_WORD_ASCII)
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_WORD_ASCII(encode, s, end))
goto fail;
s += enclen(encode, s);
- SOP_OUT;
- break;
+ NEXT_OUT;
- case OP_WORD_BOUNDARY: SOP_IN(OP_WORD_BOUNDARY);
+ CASE_OP(WORD_BOUNDARY)
{
ModeType mode;
GET_MODE_INC(mode, p); /* ascii_mode */
goto fail;
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_NO_WORD_BOUNDARY: SOP_IN(OP_NO_WORD_BOUNDARY);
+ CASE_OP(NO_WORD_BOUNDARY)
{
ModeType mode;
GET_MODE_INC(mode, p); /* ascii_mode */
goto fail;
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#ifdef USE_WORD_BEGIN_END
- case OP_WORD_BEGIN: SOP_IN(OP_WORD_BEGIN);
+ CASE_OP(WORD_BEGIN)
{
ModeType mode;
GET_MODE_INC(mode, p); /* ascii_mode */
if (DATA_ENSURE_CHECK1 && IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)) {
if (ON_STR_BEGIN(s) || !IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode)) {
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
}
}
goto fail;
- break;
- case OP_WORD_END: SOP_IN(OP_WORD_END);
+ CASE_OP(WORD_END)
{
ModeType mode;
GET_MODE_INC(mode, p); /* ascii_mode */
if (!ON_STR_BEGIN(s) && IS_MBC_WORD_ASCII_MODE(encode, sprev, end, mode)) {
if (ON_STR_END(s) || ! IS_MBC_WORD_ASCII_MODE(encode, s, end, mode)) {
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
}
}
goto fail;
- break;
#endif
- case OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
- SOP_IN(OP_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);
+ CASE_OP(EXTENDED_GRAPHEME_CLUSTER_BOUNDARY)
if (onigenc_egcb_is_break_position(encode, s, sprev, str, end)) {
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
goto fail;
- break;
- case OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY:
- SOP_IN(OP_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY);
+ CASE_OP(NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY)
if (onigenc_egcb_is_break_position(encode, s, sprev, str, end))
goto fail;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_BEGIN_BUF: SOP_IN(OP_BEGIN_BUF);
+ CASE_OP(BEGIN_BUF)
if (! ON_STR_BEGIN(s)) goto fail;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_END_BUF: SOP_IN(OP_END_BUF);
+ CASE_OP(END_BUF)
if (! ON_STR_END(s)) goto fail;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_BEGIN_LINE: SOP_IN(OP_BEGIN_LINE);
+ CASE_OP(BEGIN_LINE)
if (ON_STR_BEGIN(s)) {
if (IS_NOTBOL(msa->options)) goto fail;
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end) && !ON_STR_END(s)) {
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
goto fail;
- break;
- case OP_END_LINE: SOP_IN(OP_END_LINE);
+ CASE_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(encode, sprev, end)) {
#endif
if (IS_NOTEOL(msa->options)) goto fail;
- SOP_OUT;
- continue;
+ JUMP_OUT;
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
}
#endif
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) {
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
#ifdef USE_CRNL_AS_LINE_TERMINATOR
else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
#endif
goto fail;
- break;
- case OP_SEMI_END_BUF: SOP_IN(OP_SEMI_END_BUF);
+ CASE_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(encode, sprev, end)) {
#endif
if (IS_NOTEOL(msa->options)) goto fail;
- SOP_OUT;
- continue;
+ JUMP_OUT;
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
}
#endif
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end) &&
ON_STR_END(s + enclen(encode, s))) {
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
#ifdef USE_CRNL_AS_LINE_TERMINATOR
else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {
UChar* ss = s + enclen(encode, s);
ss += enclen(encode, ss);
if (ON_STR_END(ss)) {
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
}
#endif
goto fail;
- break;
- case OP_BEGIN_POSITION: SOP_IN(OP_BEGIN_POSITION);
+ CASE_OP(BEGIN_POSITION)
if (s != msa->start)
goto fail;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_MEMORY_START_PUSH: SOP_IN(OP_MEMORY_START_PUSH);
+ CASE_OP(MEMORY_START_PUSH)
GET_MEMNUM_INC(mem, p);
STACK_PUSH_MEM_START(mem, s);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_MEMORY_START: SOP_IN(OP_MEMORY_START);
+ CASE_OP(MEMORY_START)
GET_MEMNUM_INC(mem, p);
mem_start_stk[mem] = (StackIndex )((void* )s);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_MEMORY_END_PUSH: SOP_IN(OP_MEMORY_END_PUSH);
+ CASE_OP(MEMORY_END_PUSH)
GET_MEMNUM_INC(mem, p);
STACK_PUSH_MEM_END(mem, s);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_MEMORY_END: SOP_IN(OP_MEMORY_END);
+ CASE_OP(MEMORY_END)
GET_MEMNUM_INC(mem, p);
mem_end_stk[mem] = (StackIndex )((void* )s);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#ifdef USE_CALL
- case OP_MEMORY_END_PUSH_REC: SOP_IN(OP_MEMORY_END_PUSH_REC);
+ CASE_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);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_MEMORY_END_REC: SOP_IN(OP_MEMORY_END_REC);
+ CASE_OP(MEMORY_END_REC)
GET_MEMNUM_INC(mem, p);
mem_end_stk[mem] = (StackIndex )((void* )s);
STACK_GET_MEM_START(mem, stkp);
mem_start_stk[mem] = (StackIndex )((void* )stkp->u.mem.pstr);
STACK_PUSH_MEM_END_MARK(mem);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#endif
- case OP_BACKREF1: SOP_IN(OP_BACKREF1);
+ CASE_OP(BACKREF1)
mem = 1;
goto backref;
- break;
- case OP_BACKREF2: SOP_IN(OP_BACKREF2);
+ CASE_OP(BACKREF2)
mem = 2;
goto backref;
- break;
- case OP_BACKREF_N: SOP_IN(OP_BACKREF_N);
+ CASE_OP(BACKREF_N)
GET_MEMNUM_INC(mem, p);
backref:
{
STRING_CMP(pstart, s, n);
while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
-
- SOP_OUT;
- continue;
}
- break;
+ JUMP_OUT;
- case OP_BACKREF_N_IC: SOP_IN(OP_BACKREF_N_IC);
+ CASE_OP(BACKREF_N_IC)
GET_MEMNUM_INC(mem, p);
{
int len;
STRING_CMP_IC(case_fold_flag, pstart, &s, n);
while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
-
- SOP_OUT;
- continue;
}
- break;
+ JUMP_OUT;
- case OP_BACKREF_MULTI: SOP_IN(OP_BACKREF_MULTI);
+ CASE_OP(BACKREF_MULTI)
{
int len, is_fail;
UChar *pstart, *pend, *swork;
break; /* success */
}
if (i == tlen) goto fail;
- SOP_OUT;
- continue;
}
- break;
+ JUMP_OUT;
- case OP_BACKREF_MULTI_IC: SOP_IN(OP_BACKREF_MULTI_IC);
+ CASE_OP(BACKREF_MULTI_IC)
{
int len, is_fail;
UChar *pstart, *pend, *swork;
break; /* success */
}
if (i == tlen) goto fail;
- SOP_OUT;
- continue;
}
- break;
+ JUMP_OUT;
#ifdef USE_BACKREF_WITH_LEVEL
- case OP_BACKREF_WITH_LEVEL:
+ CASE_OP(BACKREF_WITH_LEVEL)
{
int len;
OnigOptionType ic;
}
else
goto fail;
-
- SOP_OUT;
- continue;
}
- break;
+ JUMP_OUT;
#endif
- case OP_BACKREF_CHECK: SOP_IN(OP_BACKREF_CHECK);
+ CASE_OP(BACKREF_CHECK)
{
GET_LENGTH_INC(tlen, p);
for (i = 0; i < tlen; i++) {
break; /* success */
}
if (i == tlen) goto fail;
- SOP_OUT;
- continue;
}
- break;
+ JUMP_OUT;
#ifdef USE_BACKREF_WITH_LEVEL
- case OP_BACKREF_CHECK_WITH_LEVEL:
+ CASE_OP(BACKREF_CHECK_WITH_LEVEL)
{
LengthType level;
}
else
goto fail;
-
- SOP_OUT;
- continue;
}
- break;
+ JUMP_OUT;
#endif
- case OP_EMPTY_CHECK_START: SOP_IN(OP_EMPTY_CHECK_START);
+ CASE_OP(EMPTY_CHECK_START)
GET_MEMNUM_INC(mem, p); /* mem: null check id */
STACK_PUSH_EMPTY_CHECK_START(mem, s);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_EMPTY_CHECK_END: SOP_IN(OP_EMPTY_CHECK_END);
+ CASE_OP(EMPTY_CHECK_END)
{
int is_empty;
}
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#ifdef USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT
- case OP_EMPTY_CHECK_END_MEMST: SOP_IN(OP_EMPTY_CHECK_END_MEMST);
+ CASE_OP(EMPTY_CHECK_END_MEMST)
{
int is_empty;
goto empty_check_found;
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#endif
#ifdef USE_CALL
- case OP_EMPTY_CHECK_END_MEMST_PUSH:
- SOP_IN(OP_EMPTY_CHECK_END_MEMST_PUSH);
+ CASE_OP(EMPTY_CHECK_END_MEMST_PUSH)
{
int is_empty;
STACK_PUSH_EMPTY_CHECK_END(mem);
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#endif
- case OP_JUMP: SOP_IN(OP_JUMP);
+ CASE_OP(JUMP)
GET_RELADDR_INC(addr, p);
p += addr;
- SOP_OUT;
- CHECK_INTERRUPT_IN_MATCH;
- continue;
- break;
+ CHECK_INTERRUPT_JUMP_OUT;
- case OP_PUSH: SOP_IN(OP_PUSH);
+ CASE_OP(PUSH)
GET_RELADDR_INC(addr, p);
STACK_PUSH_ALT(p + addr, s, sprev);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_PUSH_SUPER: SOP_IN(OP_PUSH_SUPER);
+ CASE_OP(PUSH_SUPER)
GET_RELADDR_INC(addr, p);
STACK_PUSH_SUPER_ALT(p + addr, s, sprev);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_POP_OUT: SOP_IN(OP_POP_OUT);
+ CASE_OP(POP_OUT)
STACK_POP_ONE;
/* for stop backtrack */
/* CHECK_RETRY_LIMIT_IN_MATCH; */
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_PUSH_OR_JUMP_EXACT1: SOP_IN(OP_PUSH_OR_JUMP_EXACT1);
+ CASE_OP(PUSH_OR_JUMP_EXACT1)
GET_RELADDR_INC(addr, p);
if (*p == *s && DATA_ENSURE_CHECK1) {
p++;
STACK_PUSH_ALT(p + addr, s, sprev);
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
p += (addr + 1);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_PUSH_IF_PEEK_NEXT: SOP_IN(OP_PUSH_IF_PEEK_NEXT);
+ CASE_OP(PUSH_IF_PEEK_NEXT)
GET_RELADDR_INC(addr, p);
if (*p == *s) {
p++;
STACK_PUSH_ALT(p + addr, s, sprev);
- SOP_OUT;
- continue;
+ JUMP_OUT;
}
p++;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_REPEAT: SOP_IN(OP_REPEAT);
+ CASE_OP(REPEAT)
{
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
GET_RELADDR_INC(addr, p);
STACK_PUSH_ALT(p + addr, s, sprev);
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_REPEAT_NG: SOP_IN(OP_REPEAT_NG);
+ CASE_OP(REPEAT_NG)
{
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
GET_RELADDR_INC(addr, p);
p += addr;
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_REPEAT_INC: SOP_IN(OP_REPEAT_INC);
+ CASE_OP(REPEAT_INC)
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
si = repeat_stk[mem];
stkp = STACK_AT(si);
p = stkp->u.repeat.pcode;
}
STACK_PUSH_REPEAT_INC(si);
- SOP_OUT;
- CHECK_INTERRUPT_IN_MATCH;
- continue;
- break;
+ CHECK_INTERRUPT_JUMP_OUT;
- case OP_REPEAT_INC_SG: SOP_IN(OP_REPEAT_INC_SG);
+ CASE_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;
- break;
- case OP_REPEAT_INC_NG: SOP_IN(OP_REPEAT_INC_NG);
+ CASE_OP(REPEAT_INC_NG)
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
si = repeat_stk[mem];
stkp = STACK_AT(si);
else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {
STACK_PUSH_REPEAT_INC(si);
}
- SOP_OUT;
- CHECK_INTERRUPT_IN_MATCH;
- continue;
- break;
+ CHECK_INTERRUPT_JUMP_OUT;
- case OP_REPEAT_INC_NG_SG: SOP_IN(OP_REPEAT_INC_NG_SG);
+ CASE_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;
- break;
- case OP_PREC_READ_START: SOP_IN(OP_PREC_READ_START);
+ CASE_OP(PREC_READ_START)
STACK_PUSH_POS(s, sprev);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_PREC_READ_END: SOP_IN(OP_PREC_READ_END);
+ CASE_OP(PREC_READ_END)
{
STACK_EXEC_TO_VOID(stkp);
s = stkp->u.state.pstr;
sprev = stkp->u.state.pstr_prev;
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_PREC_READ_NOT_START: SOP_IN(OP_PREC_READ_NOT_START);
+ CASE_OP(PREC_READ_NOT_START)
GET_RELADDR_INC(addr, p);
STACK_PUSH_ALT_PREC_READ_NOT(p + addr, s, sprev);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_PREC_READ_NOT_END: SOP_IN(OP_PREC_READ_NOT_END);
+ CASE_OP(PREC_READ_NOT_END)
STACK_POP_TIL_ALT_PREC_READ_NOT;
goto fail;
- break;
- case OP_ATOMIC_START: SOP_IN(OP_ATOMIC_START);
+ CASE_OP(ATOMIC_START)
STACK_PUSH_TO_VOID_START;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_ATOMIC_END: SOP_IN(OP_ATOMIC_END);
+ CASE_OP(ATOMIC_END)
STACK_EXEC_TO_VOID(stkp);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_LOOK_BEHIND: SOP_IN(OP_LOOK_BEHIND);
+ CASE_OP(LOOK_BEHIND)
GET_LENGTH_INC(tlen, p);
s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);
if (IS_NULL(s)) goto fail;
sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_LOOK_BEHIND_NOT_START: SOP_IN(OP_LOOK_BEHIND_NOT_START);
+ CASE_OP(LOOK_BEHIND_NOT_START)
GET_RELADDR_INC(addr, p);
GET_LENGTH_INC(tlen, p);
q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);
s = q;
sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_LOOK_BEHIND_NOT_END: SOP_IN(OP_LOOK_BEHIND_NOT_END);
+ CASE_OP(LOOK_BEHIND_NOT_END)
STACK_POP_TIL_ALT_LOOK_BEHIND_NOT;
goto fail;
- break;
#ifdef USE_CALL
- case OP_CALL: SOP_IN(OP_CALL);
+ CASE_OP(CALL)
GET_ABSADDR_INC(addr, p);
STACK_PUSH_CALL_FRAME(p);
p = reg->p + addr;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_RETURN: SOP_IN(OP_RETURN);
+ CASE_OP(RETURN)
STACK_RETURN(p);
STACK_PUSH_RETURN;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#endif
- case OP_PUSH_SAVE_VAL: SOP_IN(OP_PUSH_SAVE_VAL);
+ CASE_OP(PUSH_SAVE_VAL)
{
SaveType type;
GET_SAVE_TYPE_INC(type, p);
break;
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- case OP_UPDATE_VAR: SOP_IN(OP_UPDATE_VAR);
+ CASE_OP(UPDATE_VAR)
{
UpdateVarType type;
enum SaveType save_type;
break;
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#ifdef USE_CALLOUT
- case OP_CALLOUT_CONTENTS: SOP_IN(OP_CALLOUT_CONTENTS);
+ CASE_OP(CALLOUT_CONTENTS)
of = ONIG_CALLOUT_OF_CONTENTS;
goto callout_common_entry;
+ BREAK_OUT;
- SOP_OUT;
- continue;
- break;
-
- case OP_CALLOUT_NAME: SOP_IN(OP_CALLOUT_NAME);
+ CASE_OP(CALLOUT_NAME)
{
int call_result;
int name_id;
}
}
}
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
#endif
- case OP_FINISH:
+ CASE_OP(FINISH)
goto finish;
- break;
+#ifdef ONIG_DEBUG_STATISTICS
fail:
SOP_OUT;
- /* fall */
- case OP_FAIL: SOP_IN(OP_FAIL);
+ goto fail2;
+#endif
+ CASE_OP(FAIL)
+#ifdef ONIG_DEBUG_STATISTICS
+ fail2:
+#else
+ fail:
+#endif
STACK_POP;
p = stk->u.state.pcode;
s = stk->u.state.pstr;
sprev = stk->u.state.pstr_prev;
CHECK_RETRY_LIMIT_IN_MATCH;
- SOP_OUT;
- continue;
- break;
+ JUMP_OUT;
- default:
+ DEFAULT_OP
goto bytecode_error;
- } /* end of switch */
- sprev = sbegin;
- } /* end of while(1) */
+ } BYTECODE_INTERPRETER_END;
finish:
STACK_SAVE;
return (UChar* )NULL;
}
+
static UChar*
-bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
- const UChar* text, const UChar* text_end,
- const UChar* text_range)
+sunday_quick_search_step_forward(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;
int skip, tlen1;
+ int map_offset;
+ OnigEncoding enc;
#ifdef ONIG_DEBUG_SEARCH
- fprintf(stderr, "bm_search_notrev: text: %p, text_end: %p, text_range: %p\n",
- text, text_end, text_range);
+ fprintf(stderr,
+ "sunday_quick_search_step_forward: text: %p, text_end: %p, text_range: %p\n", text, text_end, text_range);
#endif
+ enc = reg->enc;
+
tail = target_end - 1;
tlen1 = (int )(tail - target);
end = text_range;
if (end + tlen1 > text_end)
end = text_end - tlen1;
+ map_offset = reg->map_offset;
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--;
- }
- skip = reg->map[*se];
- t = s;
- do {
- s += enclen(reg->enc, s);
- } while ((s - t) < skip && s < end);
- }
- }
- else {
- while (s < end) {
- p = se = s + tlen1;
- t = tail;
- while (*p == *t) {
- if (t == target) return (UChar* )s;
- p--; t--;
- }
- skip = reg->int_map[*se];
- t = s;
- do {
- s += enclen(reg->enc, s);
- } while ((s - t) < skip && s < end);
+ while (s < end) {
+ p = se = s + tlen1;
+ t = tail;
+ while (*p == *t) {
+ if (t == target) return (UChar* )s;
+ p--; t--;
}
+ if (se + map_offset >= text_end) break;
+ skip = reg->map[*(se + map_offset)];
+#if 0
+ t = s;
+ do {
+ s += enclen(enc, s);
+ } while ((s - t) < skip && s < end);
+#else
+ s += skip;
+ if (s < end)
+ s = onigenc_get_right_adjust_char_head(enc, text, s);
+#endif
}
return (UChar* )NULL;
}
static UChar*
-bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
- const UChar* text, const UChar* text_end, const UChar* text_range)
+sunday_quick_search(regex_t* reg, const UChar* target, const UChar* target_end,
+ const UChar* text, const UChar* text_end,
+ const UChar* text_range)
{
const UChar *s, *t, *p, *end;
const UChar *tail;
+ int map_offset;
- end = text_range + (target_end - target) - 1;
+ end = text_range + (target_end - target);
if (end > text_end)
end = text_end;
+ map_offset = reg->map_offset;
tail = target_end - 1;
- s = text + (target_end - target) - 1;
- if (IS_NULL(reg->int_map)) {
- while (s < end) {
- p = s;
- t = tail;
- while (*p == *t) {
- if (t == target) return (UChar* )p;
- p--; t--;
- }
- s += reg->map[*s];
- }
- }
- else { /* see int_map[] */
- while (s < end) {
- p = s;
- t = tail;
- while (*p == *t) {
- if (t == target) return (UChar* )p;
- p--; t--;
- }
- s += reg->int_map[*s];
+ s = text + (tail - target);
+
+ while (s < end) {
+ p = s;
+ t = tail;
+ while (*p == *t) {
+ if (t == target) return (UChar* )p;
+ p--; t--;
}
+ if (s + map_offset >= text_end) break;
+ s += reg->map[*(s + map_offset)];
}
+
return (UChar* )NULL;
}
-#ifdef USE_INT_MAP_BACKWARD
-static int
-set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED, int** skip)
+static UChar*
+sunday_quick_search_case_fold(regex_t* reg,
+ const UChar* target, const UChar* target_end,
+ const UChar* text, const UChar* text_end,
+ const UChar* text_range)
{
- int i, len;
-
- if (IS_NULL(*skip)) {
- *skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
- if (IS_NULL(*skip)) return ONIGERR_MEMORY;
- }
-
- len = end - s;
- for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
- (*skip)[i] = len;
+ const UChar *s, *se, *end;
+ const UChar *tail;
+ int skip, tlen1;
+ int map_offset;
+ int case_fold_flag;
+ OnigEncoding enc;
- for (i = len - 1; i > 0; i--)
- (*skip)[s[i]] = i;
+#ifdef ONIG_DEBUG_SEARCH
+ fprintf(stderr,
+ "sunday_quick_search_case_fold: text: %p, text_end: %p, text_range: %p\n", text, text_end, text_range);
+#endif
- return 0;
-}
+ enc = reg->enc;
+ case_fold_flag = reg->case_fold_flag;
-static UChar*
-bm_search_backward(regex_t* reg, const UChar* target, const UChar* target_end,
- const UChar* text, const UChar* adjust_text,
- const UChar* text_end, const UChar* text_start)
-{
- const UChar *s, *t, *p;
+ tail = target_end - 1;
+ tlen1 = (int )(tail - target);
+ end = text_range;
+ if (end + tlen1 > text_end)
+ end = text_end - tlen1;
- s = text_end - (target_end - target);
- if (text_start < s)
- s = text_start;
- else
- s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s);
+ map_offset = reg->map_offset;
+ s = text;
- while (s >= text) {
- p = s;
- t = target;
- while (t < target_end && *p == *t) {
- p++; t++;
- }
- if (t == target_end)
+ while (s < end) {
+ if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+ s, text_end))
return (UChar* )s;
- s -= reg->int_map_backward[*s];
- s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s);
+ se = s + tlen1;
+ if (se + map_offset >= text_end) break;
+ skip = reg->map[*(se + map_offset)];
+#if 0
+ p = s;
+ do {
+ s += enclen(enc, s);
+ } while ((s - p) < skip && s < end);
+#else
+ /* This is faster than prev code for long text. ex: /(?i)Twain/ */
+ s += skip;
+ if (s < end)
+ s = onigenc_get_right_adjust_char_head(enc, text, s);
+#endif
}
return (UChar* )NULL;
}
-#endif
static UChar*
map_search(OnigEncoding enc, UChar map[],
retry:
switch (reg->optimize) {
- case OPTIMIZE_EXACT:
+ case OPTIMIZE_STR:
p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);
break;
- case OPTIMIZE_EXACT_IC:
+ case OPTIMIZE_STR_CASE_FOLD:
p = slow_search_ic(reg->enc, reg->case_fold_flag,
reg->exact, reg->exact_end, p, end, range);
break;
- case OPTIMIZE_EXACT_BM:
- p = bm_search(reg, reg->exact, reg->exact_end, p, end, range);
+ case OPTIMIZE_STR_CASE_FOLD_FAST:
+ p = sunday_quick_search_case_fold(reg, reg->exact, reg->exact_end, p, end,
+ range);
+ break;
+
+ case OPTIMIZE_STR_FAST:
+ p = sunday_quick_search(reg, reg->exact, reg->exact_end, p, end, range);
break;
- case OPTIMIZE_EXACT_BM_NO_REV:
- p = bm_search_notrev(reg, reg->exact, reg->exact_end, p, end, range);
+ case OPTIMIZE_STR_FAST_STEP_FORWARD:
+ p = sunday_quick_search_step_forward(reg, reg->exact, reg->exact_end,
+ p, end, range);
break;
case OPTIMIZE_MAP:
UChar* prev;
switch (reg->sub_anchor) {
- case ANCHOR_BEGIN_LINE:
+ case ANCR_BEGIN_LINE:
if (!ON_STR_BEGIN(p)) {
prev = onigenc_get_prev_char_head(reg->enc,
(pprev ? pprev : str), p);
}
break;
- case ANCHOR_END_LINE:
+ case ANCR_END_LINE:
if (ON_STR_END(p)) {
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
prev = (UChar* )onigenc_get_prev_char_head(reg->enc,
}
-#define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD 100
-
static int
backward_search_range(regex_t* reg, const UChar* str, const UChar* end,
UChar* s, const UChar* range, UChar* adjrange,
{
UChar *p;
+ if (range == 0) goto fail;
+
range += reg->dmin;
p = s;
retry:
switch (reg->optimize) {
- case OPTIMIZE_EXACT:
+ case OPTIMIZE_STR:
exact_method:
p = slow_search_backward(reg->enc, reg->exact, reg->exact_end,
range, adjrange, end, p);
break;
- case OPTIMIZE_EXACT_IC:
+ case OPTIMIZE_STR_CASE_FOLD:
+ case OPTIMIZE_STR_CASE_FOLD_FAST:
p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,
reg->exact, reg->exact_end,
range, adjrange, end, p);
break;
- case OPTIMIZE_EXACT_BM:
- case OPTIMIZE_EXACT_BM_NO_REV:
-#ifdef USE_INT_MAP_BACKWARD
- if (IS_NULL(reg->int_map_backward)) {
- int r;
-
- if (s - range < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD)
- goto exact_method;
-
- r = set_bm_backward_skip(reg->exact, reg->exact_end, reg->enc,
- &(reg->int_map_backward));
- if (r != 0) return r;
- }
- p = bm_search_backward(reg, reg->exact, reg->exact_end, range, adjrange,
- end, p);
-#else
+ case OPTIMIZE_STR_FAST:
+ case OPTIMIZE_STR_FAST_STEP_FORWARD:
goto exact_method;
-#endif
break;
case OPTIMIZE_MAP:
UChar* prev;
switch (reg->sub_anchor) {
- case ANCHOR_BEGIN_LINE:
+ case ANCR_BEGIN_LINE:
if (!ON_STR_BEGIN(p)) {
prev = onigenc_get_prev_char_head(reg->enc, str, p);
- if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {
+ if (IS_NOT_NULL(prev) && !ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {
p = prev;
goto retry;
}
}
break;
- case ANCHOR_END_LINE:
+ case ANCR_END_LINE:
if (ON_STR_END(p)) {
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);
if (reg->anchor != 0 && str < end) {
UChar *min_semi_end, *max_semi_end;
- if (reg->anchor & ANCHOR_BEGIN_POSITION) {
+ if (reg->anchor & ANCR_BEGIN_POSITION) {
/* search start-position only */
begin_position:
if (range > start)
else
range = start;
}
- else if (reg->anchor & ANCHOR_BEGIN_BUF) {
+ else if (reg->anchor & ANCR_BEGIN_BUF) {
/* search str-position only */
if (range > start) {
if (start != str) goto mismatch_no_msa;
goto mismatch_no_msa;
}
}
- else if (reg->anchor & ANCHOR_END_BUF) {
+ else if (reg->anchor & ANCR_END_BUF) {
min_semi_end = max_semi_end = (UChar* )end;
end_buf:
if (range > start) goto mismatch_no_msa;
}
}
- else if (reg->anchor & ANCHOR_SEMI_END_BUF) {
+ else if (reg->anchor & ANCR_SEMI_END_BUF) {
UChar* pre_end = ONIGENC_STEP_BACK(reg->enc, str, end, 1);
max_semi_end = (UChar* )end;
goto end_buf;
}
}
- else if ((reg->anchor & ANCHOR_ANYCHAR_INF_ML)) {
+ else if ((reg->anchor & ANCR_ANYCHAR_INF_ML)) {
goto begin_position;
}
}
if (! forward_search_range(reg, str, end, s, sch_range,
&low, &high, (UChar** )NULL)) goto mismatch;
- if ((reg->anchor & ANCHOR_ANYCHAR_INF) != 0) {
+ if ((reg->anchor & ANCR_ANYCHAR_INF) != 0) {
do {
MATCH_AND_RETURN_CHECK(orig_range);
prev = s;
s += enclen(reg->enc, s);
- if ((reg->anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) == 0) {
+ if ((reg->anchor & (ANCR_LOOK_BEHIND | ANCR_PREC_READ_NOT)) == 0) {
while (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end) && s < range) {
prev = s;
s += enclen(reg->enc, s);
}
}
else { /* backward search */
+ if (range < str) goto mismatch;
+
if (orig_start < end)
orig_start += enclen(reg->enc, orig_start); /* is upper range */
if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
if (ci->pattern_enc != ci->target_enc) {
- r = conv_encoding(ci->pattern_enc, ci->target_enc, pattern, pattern_end,
- &cpat, &cpat_end);
- if (r != 0) return r;
+ return ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION;
}
else {
cpat = (UChar* )pattern;
#define USE_INSISTENT_CHECK_CAPTURES_IN_EMPTY_REPEAT /* /(?:()|())*\2/ */
#define USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE /* /\n$/ =~ "\n" */
#define USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
-
#define USE_RETRY_LIMIT_IN_MATCH
/* internal config */
#define USE_QUANT_PEEK_NEXT
#define USE_ST_LIBRARY
-#include "regenc.h"
-
-#ifdef __cplusplus
-# ifndef HAVE_STDARG_PROTOTYPES
-# define HAVE_STDARG_PROTOTYPES 1
-# endif
-#endif
-
-/* escape Mac OS X/Xcode 2.4/gcc 4.0.1 problem */
-#if defined(__APPLE__) && defined(__GNUC__) && __GNUC__ >= 4
-# ifndef HAVE_STDARG_PROTOTYPES
-# define HAVE_STDARG_PROTOTYPES 1
-# endif
-#endif
-
-#ifdef HAVE_STDARG_H
-# ifndef HAVE_STDARG_PROTOTYPES
-# define HAVE_STDARG_PROTOTYPES 1
-# endif
-#endif
+#define USE_WORD_BEGIN_END /* "\<", "\>" */
+#define USE_CAPTURE_HISTORY
+#define USE_VARIABLE_META_CHARS
+#define USE_POSIX_API_REGION_OPTION
+#define USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+#include "regenc.h"
#define INIT_MATCH_STACK_SIZE 160
#define DEFAULT_MATCH_STACK_LIMIT_SIZE 0 /* unlimited */
#undef ONIG_ESCAPE_UCHAR_COLLISION
#endif
-#define USE_WORD_BEGIN_END /* "\<", "\>" */
-#define USE_CAPTURE_HISTORY
-#define USE_VARIABLE_META_CHARS
-#define USE_POSIX_API_REGION_OPTION
-#define USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
-
#define xmalloc malloc
#define xrealloc realloc
#define xcalloc calloc
#include <stddef.h>
-
-#ifdef HAVE_LIMITS_H
#include <limits.h>
-#endif
-
-#ifdef HAVE_STDLIB_H
#include <stdlib.h>
-#endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#include <alloca.h>
#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#include <ctype.h>
#ifdef HAVE_SYS_TYPES_H
#define CHECK_NULL_RETURN_MEMERR(p) if (IS_NULL(p)) return ONIGERR_MEMORY
#define NULL_UCHARP ((UChar* )0)
+#define CHAR_MAP_SIZE 256
#define INFINITE_LEN ONIG_INFINITE_DISTANCE
#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
#endif
} RegexExt;
-#define REG_EXTP(reg) ((RegexExt* )((reg)->chain))
-#define REG_EXTPL(reg) ((reg)->chain)
-
struct re_pattern_buffer {
/* common members of BBuf(bytes-buffer) */
unsigned char* p; /* compiled pattern */
int num_mem; /* used memory(...) num counted from 1 */
int num_repeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */
int num_null_check; /* OP_EMPTY_CHECK_START/END id counter */
- int num_comb_exp_check; /* no longer used (combination explosion check) */
int num_call; /* number of subexp call */
unsigned int capture_history; /* (?@...) flag (1-31) */
unsigned int bt_mem_start; /* need backtrack flag */
int optimize; /* optimize flag */
int threshold_len; /* search str-length for apply optimize */
int anchor; /* BEGIN_BUF, BEGIN_POS, (SEMI_)END_BUF */
- OnigLen anchor_dmin; /* (SEMI_)END_BUF anchor distance */
- OnigLen anchor_dmax; /* (SEMI_)END_BUF anchor distance */
+ OnigLen anchor_dmin; /* (SEMI_)END_BUF anchor distance */
+ OnigLen anchor_dmax; /* (SEMI_)END_BUF anchor distance */
int sub_anchor; /* start-anchor for exact or map */
unsigned char *exact;
unsigned char *exact_end;
- unsigned char map[ONIG_CHAR_TABLE_SIZE]; /* used as BM skip or char-map */
- int *int_map; /* BM skip for exact_len > 255 */
- int *int_map_backward; /* BM skip for backward search */
- OnigLen dmin; /* min-distance of exact or map */
- OnigLen dmax; /* max-distance of exact or map */
-
- /* regex_t link chain */
- struct re_pattern_buffer* chain; /* escape compile-conflict */
+ unsigned char map[CHAR_MAP_SIZE]; /* used as BMH skip or char-map */
+ int map_offset;
+ OnigLen dmin; /* min-distance of exact or map */
+ OnigLen dmax; /* max-distance of exact or map */
+ RegexExt* extp;
};
/* optimize flags */
enum OptimizeType {
- OPTIMIZE_NONE = 0,
- OPTIMIZE_EXACT = 1, /* Slow Search */
- OPTIMIZE_EXACT_BM = 2, /* Boyer Moore Search */
- OPTIMIZE_EXACT_BM_NO_REV = 3, /* BM (but not simple match) */
- OPTIMIZE_EXACT_IC = 4, /* Slow Search (ignore case) */
- OPTIMIZE_MAP = 5 /* char map */
+ OPTIMIZE_NONE = 0,
+ OPTIMIZE_STR, /* Slow Search */
+ OPTIMIZE_STR_FAST, /* Sunday quick search / BMH */
+ OPTIMIZE_STR_FAST_STEP_FORWARD, /* Sunday quick search / BMH */
+ OPTIMIZE_STR_CASE_FOLD_FAST, /* Sunday quick search / BMH (ignore case) */
+ OPTIMIZE_STR_CASE_FOLD, /* Slow Search (ignore case) */
+ OPTIMIZE_MAP /* char map */
};
/* bit status */
/* has body */
-#define ANCHOR_PREC_READ (1<<0)
-#define ANCHOR_PREC_READ_NOT (1<<1)
-#define ANCHOR_LOOK_BEHIND (1<<2)
-#define ANCHOR_LOOK_BEHIND_NOT (1<<3)
+#define ANCR_PREC_READ (1<<0)
+#define ANCR_PREC_READ_NOT (1<<1)
+#define ANCR_LOOK_BEHIND (1<<2)
+#define ANCR_LOOK_BEHIND_NOT (1<<3)
/* no body */
-#define ANCHOR_BEGIN_BUF (1<<4)
-#define ANCHOR_BEGIN_LINE (1<<5)
-#define ANCHOR_BEGIN_POSITION (1<<6)
-#define ANCHOR_END_BUF (1<<7)
-#define ANCHOR_SEMI_END_BUF (1<<8)
-#define ANCHOR_END_LINE (1<<9)
-#define ANCHOR_WORD_BOUNDARY (1<<10)
-#define ANCHOR_NO_WORD_BOUNDARY (1<<11)
-#define ANCHOR_WORD_BEGIN (1<<12)
-#define ANCHOR_WORD_END (1<<13)
-#define ANCHOR_ANYCHAR_INF (1<<14)
-#define ANCHOR_ANYCHAR_INF_ML (1<<15)
-#define ANCHOR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY (1<<16)
-#define ANCHOR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY (1<<17)
-
-
-#define ANCHOR_HAS_BODY(a) ((a)->type < ANCHOR_BEGIN_BUF)
+#define ANCR_BEGIN_BUF (1<<4)
+#define ANCR_BEGIN_LINE (1<<5)
+#define ANCR_BEGIN_POSITION (1<<6)
+#define ANCR_END_BUF (1<<7)
+#define ANCR_SEMI_END_BUF (1<<8)
+#define ANCR_END_LINE (1<<9)
+#define ANCR_WORD_BOUNDARY (1<<10)
+#define ANCR_NO_WORD_BOUNDARY (1<<11)
+#define ANCR_WORD_BEGIN (1<<12)
+#define ANCR_WORD_END (1<<13)
+#define ANCR_ANYCHAR_INF (1<<14)
+#define ANCR_ANYCHAR_INF_ML (1<<15)
+#define ANCR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY (1<<16)
+#define ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY (1<<17)
+
+
+#define ANCHOR_HAS_BODY(a) ((a)->type < ANCR_BEGIN_BUF)
#define IS_WORD_ANCHOR_TYPE(type) \
- ((type) == ANCHOR_WORD_BOUNDARY || (type) == ANCHOR_NO_WORD_BOUNDARY || \
- (type) == ANCHOR_WORD_BEGIN || (type) == ANCHOR_WORD_END)
+ ((type) == ANCR_WORD_BOUNDARY || (type) == ANCR_NO_WORD_BOUNDARY || \
+ (type) == ANCR_WORD_BEGIN || (type) == ANCR_WORD_END)
/* operation code */
enum OpCode {
extern int onig_is_code_in_cc_len P_((int enclen, OnigCodePoint code, void* /* CClassNode* */ cc));
extern RegexExt* onig_get_regex_ext(regex_t* reg);
extern int onig_ext_set_pattern(regex_t* reg, const UChar* pattern, const UChar* pattern_end);
+extern int onig_positive_int_multiply(int x, int y);
#ifdef USE_CALLOUT
ONIG_SYN_OP2_CCLASS_SET_OP | ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL |
ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB |
ONIG_SYN_OP2_ESC_H_XDIGIT | ONIG_SYN_OP2_ESC_U_HEX4 )
- , ( SYN_GNU_REGEX_BV |
+ , ( SYN_GNU_REGEX_BV |
ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV |
ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND |
ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP |
ONIG_SYN_OP2_CCLASS_SET_OP | ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL |
ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB |
ONIG_SYN_OP2_ESC_H_XDIGIT | ONIG_SYN_OP2_ESC_U_HEX4 )
- , ( SYN_GNU_REGEX_BV |
+ , ( SYN_GNU_REGEX_BV |
ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV |
ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND |
ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP |
return 0;
}
-static int
-positive_int_multiply(int x, int y)
-{
- if (x == 0 || y == 0) return 0;
-
- if (x < INT_MAX / y)
- return x * y;
- else
- return -1;
-}
-
static void
bbuf_free(BBuf* bbuf)
{
#ifdef USE_ST_LIBRARY
if (IS_NULL(t)) {
t = onig_st_init_strend_table_with_size(INIT_NAMES_ALLOC_NUM);
+ CHECK_NULL_RETURN_MEMERR(t);
reg->name_table = (void* )t;
}
e = (NameEntry* )xmalloc(sizeof(NameEntry));
#ifdef USE_ST_LIBRARY
if (IS_NULL(t)) {
t = onig_st_init_callout_name_table_with_size(INIT_NAMES_ALLOC_NUM);
+ CHECK_NULL_RETURN_MEMERR(t);
GlobalCalloutNameTable = t;
}
e = (CalloutNameEntry* )xmalloc(sizeof(CalloutNameEntry));
}
for (i = arg_num - opt_arg_num, j = 0; i < arg_num; i++, j++) {
if (fe->arg_types[i] == ONIG_TYPE_STRING) {
+ if (IS_NULL(opt_defaults)) return ONIGERR_INVALID_ARGUMENT;
OnigValue* val = opt_defaults + j;
UChar* ds = onigenc_strdup(enc, val->s.start, val->s.end);
CHECK_NULL_RETURN_MEMERR(ds);
CalloutListEntry* e;
e = onig_reg_callout_list_at(reg, callout_num);
+ CHECK_NULL_RETURN(e);
return e->start_func;
}
onig_get_callout_tag_start(regex_t* reg, int callout_num)
{
CalloutListEntry* e = onig_reg_callout_list_at(reg, callout_num);
+ CHECK_NULL_RETURN(e);
return e->tag_start;
}
onig_get_callout_tag_end(regex_t* reg, int callout_num)
{
CalloutListEntry* e = onig_reg_callout_list_at(reg, callout_num);
+ CHECK_NULL_RETURN(e);
return e->tag_end;
}
int i, j;
RegexExt* ext;
- ext = REG_EXTP(reg);
+ ext = reg->extp;
if (IS_NOT_NULL(ext->tag_table)) {
onig_st_foreach((CalloutTagTable *)ext->tag_table, i_callout_callout_list_set,
(st_data_t )ext);
extern int
onig_callout_tag_is_exist_at_callout_num(regex_t* reg, int callout_num)
{
- RegexExt* ext = REG_EXTP(reg);
+ RegexExt* ext = reg->extp;
if (IS_NULL(ext) || IS_NULL(ext->callout_list)) return 0;
if (callout_num > ext->callout_num) return 0;
return (ext->callout_list[callout_num].flag &
- CALLOUT_TAG_LIST_FLAG_TAG_EXIST) != 0 ? 1 : 0;
+ CALLOUT_TAG_LIST_FLAG_TAG_EXIST) != 0;
}
static int
RegexExt* ext;
CalloutTagVal e;
- ext = REG_EXTP(reg);
+ ext = reg->extp;
if (IS_NULL(ext) || IS_NULL(ext->tag_table))
return ONIGERR_INVALID_CALLOUT_TAG_NAME;
if (r != ONIG_NORMAL) return r;
ext = onig_get_regex_ext(reg);
+ CHECK_NULL_RETURN_MEMERR(ext);
r = callout_tag_entry_raw(ext->tag_table, name, name_end, entry_val);
e = onig_reg_callout_list_at(reg, (int )entry_val);
+ CHECK_NULL_RETURN_MEMERR(e);
e->tag_start = name;
e->tag_end = name_end;
switch (NODE_TYPE(node)) {
case NODE_STRING:
- if (STR_(node)->capa != 0 &&
+ if (STR_(node)->capacity != 0 &&
IS_NOT_NULL(STR_(node)->s) && STR_(node)->s != STR_(node)->buf) {
xfree(STR_(node)->s);
}
xfree(BACKREF_(node)->back_dynamic);
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
if (NODE_BODY(node))
onig_node_free(NODE_BODY(node));
{
- EnclosureNode* en = ENCLOSURE_(node);
- if (en->type == ENCLOSURE_IF_ELSE) {
+ BagNode* en = BAG_(node);
+ if (en->type == BAG_IF_ELSE) {
onig_node_free(en->te.Then);
onig_node_free(en->te.Else);
}
Node* node;
node = (Node* )xmalloc(sizeof(Node));
+ CHECK_NULL_RETURN(node);
xmemset(node, 0, sizeof(*node));
#ifdef DEBUG_NODE_FREE
Node* node;
node = node_new_anychar();
+ CHECK_NULL_RETURN(node);
+
ct = CTYPE_(node);
ct->options = option;
NODE_STATUS_ADD(node, FIXED_OPTION);
}
static Node*
-node_new_enclosure(enum EnclosureType type)
+node_new_bag(enum BagType type)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- NODE_SET_TYPE(node, NODE_ENCLOSURE);
- ENCLOSURE_(node)->type = type;
+ NODE_SET_TYPE(node, NODE_BAG);
+ BAG_(node)->type = type;
switch (type) {
- case ENCLOSURE_MEMORY:
- ENCLOSURE_(node)->m.regnum = 0;
- ENCLOSURE_(node)->m.called_addr = -1;
- ENCLOSURE_(node)->m.entry_count = 1;
- ENCLOSURE_(node)->m.called_state = 0;
+ case BAG_MEMORY:
+ BAG_(node)->m.regnum = 0;
+ BAG_(node)->m.called_addr = -1;
+ BAG_(node)->m.entry_count = 1;
+ BAG_(node)->m.called_state = 0;
break;
- case ENCLOSURE_OPTION:
- ENCLOSURE_(node)->o.options = 0;
+ case BAG_OPTION:
+ BAG_(node)->o.options = 0;
break;
- case ENCLOSURE_STOP_BACKTRACK:
+ case BAG_STOP_BACKTRACK:
break;
- case ENCLOSURE_IF_ELSE:
- ENCLOSURE_(node)->te.Then = 0;
- ENCLOSURE_(node)->te.Else = 0;
+ case BAG_IF_ELSE:
+ BAG_(node)->te.Then = 0;
+ BAG_(node)->te.Else = 0;
break;
}
- ENCLOSURE_(node)->opt_count = 0;
+ BAG_(node)->opt_count = 0;
return node;
}
extern Node*
-onig_node_new_enclosure(int type)
+onig_node_new_bag(enum BagType type)
{
- return node_new_enclosure(type);
+ return node_new_bag(type);
}
static Node*
-node_new_enclosure_if_else(Node* cond, Node* Then, Node* Else)
+node_new_bag_if_else(Node* cond, Node* Then, Node* Else)
{
Node* n;
- n = node_new_enclosure(ENCLOSURE_IF_ELSE);
+ n = node_new_bag(BAG_IF_ELSE);
CHECK_NULL_RETURN(n);
NODE_BODY(n) = cond;
- ENCLOSURE_(n)->te.Then = Then;
- ENCLOSURE_(n)->te.Else = Else;
+ BAG_(n)->te.Then = Then;
+ BAG_(n)->te.Else = Else;
return n;
}
static Node*
node_new_memory(int is_named)
{
- Node* node = node_new_enclosure(ENCLOSURE_MEMORY);
+ Node* node = node_new_bag(BAG_MEMORY);
CHECK_NULL_RETURN(node);
if (is_named != 0)
NODE_STATUS_ADD(node, NAMED_GROUP);
static Node*
node_new_option(OnigOptionType option)
{
- Node* node = node_new_enclosure(ENCLOSURE_OPTION);
+ Node* node = node_new_bag(BAG_OPTION);
+ CHECK_NULL_RETURN(node);
+ BAG_(node)->o.options = option;
+ return node;
+}
+
+static Node*
+node_new_group(Node* content)
+{
+ Node* node;
+
+ node = node_new();
CHECK_NULL_RETURN(node);
- ENCLOSURE_(node)->o.options = option;
+ NODE_SET_TYPE(node, NODE_LIST);
+ NODE_CAR(node) = content;
+ NODE_CDR(node) = NULL_NODE;
+
return node;
}
+static Node*
+node_drop_group(Node* group)
+{
+ Node* content;
+
+ content = NODE_CAR(group);
+ NODE_CAR(group) = NULL_NODE;
+ onig_node_free(group);
+ return content;
+}
+
static int
node_new_fail(Node** node, ScanEnv* env)
{
extern CalloutListEntry*
onig_reg_callout_list_at(regex_t* reg, int num)
{
- RegexExt* ext = REG_EXTP(reg);
+ RegexExt* ext = reg->extp;
CHECK_NULL_RETURN(ext);
if (num <= 0 || num > ext->callout_num)
ns[1] = NULL_NODE;
r = ONIGERR_MEMORY;
- ns[0] = onig_node_new_anchor(ANCHOR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY, 0);
+ ns[0] = onig_node_new_anchor(ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY, 0);
if (IS_NULL(ns[0])) goto err;
r = node_new_true_anychar(&ns[1], env);
ns[0] = x;
ns[1] = NULL_NODE;
- x = node_new_enclosure(ENCLOSURE_STOP_BACKTRACK);
+ x = node_new_bag(BAG_STOP_BACKTRACK);
if (IS_NULL(x)) goto err;
NODE_BODY(x) = ns[0];
ns[0] = x;
if (possessive != 0) {
- x = node_new_enclosure(ENCLOSURE_STOP_BACKTRACK);
+ x = node_new_bag(BAG_STOP_BACKTRACK);
if (IS_NULL(x)) goto err0;
NODE_BODY(x) = ns[0];
quant = node;
}
else {
- if (NODE_TYPE(node) == NODE_ENCLOSURE) {
- EnclosureNode* en = ENCLOSURE_(node);
- if (en->type == ENCLOSURE_STOP_BACKTRACK) {
+ if (NODE_TYPE(node) == NODE_BAG) {
+ BagNode* en = BAG_(node);
+ if (en->type == BAG_STOP_BACKTRACK) {
*is_possessive = 1;
- quant = NODE_ENCLOSURE_BODY(en);
+ quant = NODE_BAG_BODY(en);
if (NODE_TYPE(quant) != NODE_QUANT)
return 0;
}
else {
r = make_absent_tail(&ns[5], &ns[6], id1, env);
if (r != 0) goto err;
-
+
x = make_list(7, ns);
if (IS_NULL(x)) goto err0;
}
r = ONIGERR_MEMORY;
err:
for (i = 0; i < 7; i++) onig_node_free(ns[i]);
- return r;
+ return r;
}
extern int
if (addlen > 0) {
int len = (int )(STR_(node)->end - STR_(node)->s);
- if (STR_(node)->capa > 0 || (len + addlen > NODE_STRING_BUF_SIZE - 1)) {
+ if (STR_(node)->capacity > 0 || (len + addlen > NODE_STRING_BUF_SIZE - 1)) {
UChar* p;
int capa = len + addlen + NODE_STRING_MARGIN;
- if (capa <= STR_(node)->capa) {
+ if (capa <= STR_(node)->capacity) {
onig_strcpy(STR_(node)->s + len, s, end);
}
else {
p = strcat_capa(STR_(node)->s, STR_(node)->end, s, end, capa);
CHECK_NULL_RETURN_MEMERR(p);
- STR_(node)->s = p;
- STR_(node)->capa = capa;
+ STR_(node)->s = p;
+ STR_(node)->capacity = capa;
}
}
else {
onig_node_conv_to_str_node(Node* node, int flag)
{
NODE_SET_TYPE(node, NODE_STRING);
- STR_(node)->flag = flag;
- STR_(node)->capa = 0;
- STR_(node)->s = STR_(node)->buf;
- STR_(node)->end = STR_(node)->buf;
+ STR_(node)->flag = flag;
+ STR_(node)->capacity = 0;
+ STR_(node)->s = STR_(node)->buf;
+ STR_(node)->end = STR_(node)->buf;
}
extern void
onig_node_str_clear(Node* node)
{
- if (STR_(node)->capa != 0 &&
+ if (STR_(node)->capacity != 0 &&
IS_NOT_NULL(STR_(node)->s) && STR_(node)->s != STR_(node)->buf) {
xfree(STR_(node)->s);
}
- STR_(node)->capa = 0;
- STR_(node)->flag = 0;
- STR_(node)->s = STR_(node)->buf;
- STR_(node)->end = STR_(node)->buf;
+ STR_(node)->capacity = 0;
+ STR_(node)->flag = 0;
+ STR_(node)->s = STR_(node)->buf;
+ STR_(node)->end = STR_(node)->buf;
}
static Node*
CHECK_NULL_RETURN(node);
NODE_SET_TYPE(node, NODE_STRING);
- STR_(node)->capa = 0;
- STR_(node)->flag = 0;
- STR_(node)->s = STR_(node)->buf;
- STR_(node)->end = STR_(node)->buf;
+ STR_(node)->capacity = 0;
+ STR_(node)->flag = 0;
+ STR_(node)->s = STR_(node)->buf;
+ STR_(node)->end = STR_(node)->buf;
if (onig_node_str_cat(node, s, end)) {
onig_node_free(node);
return NULL;
node_new_str_raw(UChar* s, UChar* end)
{
Node* node = node_new_str(s, end);
+ CHECK_NULL_RETURN(node);
NODE_STRING_SET_RAW(node);
return node;
}
p = onigenc_get_prev_char_head(enc, sn->s, sn->end);
if (p && p > sn->s) { /* can be split. */
rn = node_new_str(p, sn->end);
+ CHECK_NULL_RETURN(rn);
if (NODE_STRING_IS_RAW(node))
NODE_STRING_SET_RAW(rn);
return 1;
break;
- case NODE_ENCLOSURE:
+ case NODE_BAG:
/* allow enclosed elements */
/* return is_invalid_quantifier_target(NODE_BODY(node)); */
break;
if (pnum < 0 || cnum < 0) {
if ((p->lower == p->upper) && ! IS_REPEAT_INFINITE(p->upper)) {
if ((c->lower == c->upper) && ! IS_REPEAT_INFINITE(c->upper)) {
- int n = positive_int_multiply(p->lower, c->lower);
+ int n = onig_positive_int_multiply(p->lower, c->lower);
if (n >= 0) {
p->lower = p->upper = n;
NODE_BODY(pnode) = NODE_BODY(cnode);
if (r != 0) goto err1;
}
- x = node_new_enclosure_if_else(crnl, 0, ncc);
+ x = node_new_bag_if_else(crnl, 0, ncc);
if (IS_NULL(x)) goto err1;
*node = x;
OnigCodePoint x;
UChar *q;
UChar *p = from;
-
+
while (p < to) {
x = ONIGENC_MBC_TO_CODE(enc, p, to);
q = p + enclen(enc, p);
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);
+ tok->u.prop.not = c == 'P';
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);
+ tok->u.prop.not = tok->u.prop.not == 0;
}
else
PUNFETCH;
case 'b':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
tok->type = TK_ANCHOR;
- tok->u.anchor = ANCHOR_WORD_BOUNDARY;
+ tok->u.anchor = ANCR_WORD_BOUNDARY;
break;
case 'B':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_B_WORD_BOUND)) break;
tok->type = TK_ANCHOR;
- tok->u.anchor = ANCHOR_NO_WORD_BOUNDARY;
+ tok->u.anchor = ANCR_NO_WORD_BOUNDARY;
break;
case 'y':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP2_ESC_X_Y_GRAPHEME_CLUSTER)) break;
tok->type = TK_ANCHOR;
- tok->u.anchor = ANCHOR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY;
+ tok->u.anchor = ANCR_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY;
break;
case 'Y':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP2_ESC_X_Y_GRAPHEME_CLUSTER)) break;
tok->type = TK_ANCHOR;
- tok->u.anchor = ANCHOR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY;
+ tok->u.anchor = ANCR_NO_EXTENDED_GRAPHEME_CLUSTER_BOUNDARY;
break;
#ifdef USE_WORD_BEGIN_END
case '<':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
tok->type = TK_ANCHOR;
- tok->u.anchor = ANCHOR_WORD_BEGIN;
+ tok->u.anchor = ANCR_WORD_BEGIN;
break;
case '>':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_LTGT_WORD_BEGIN_END)) break;
tok->type = TK_ANCHOR;
- tok->u.anchor = ANCHOR_WORD_END;
+ tok->u.anchor = ANCR_WORD_END;
break;
#endif
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
begin_buf:
tok->type = TK_ANCHOR;
- tok->u.subtype = ANCHOR_BEGIN_BUF;
+ tok->u.subtype = ANCR_BEGIN_BUF;
break;
case 'Z':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
tok->type = TK_ANCHOR;
- tok->u.subtype = ANCHOR_SEMI_END_BUF;
+ tok->u.subtype = ANCR_SEMI_END_BUF;
break;
case 'z':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_AZ_BUF_ANCHOR)) break;
end_buf:
tok->type = TK_ANCHOR;
- tok->u.subtype = ANCHOR_END_BUF;
+ tok->u.subtype = ANCR_END_BUF;
break;
case 'G':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_CAPITAL_G_BEGIN_ANCHOR)) break;
tok->type = TK_ANCHOR;
- tok->u.subtype = ANCHOR_BEGIN_POSITION;
+ tok->u.subtype = ANCR_BEGIN_POSITION;
break;
case '`':
goto skip_backref;
}
- if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_DECIMAL_BACKREF) &&
+ if (IS_SYNTAX_OP(syn, ONIG_SYN_OP_DECIMAL_BACKREF) &&
(num <= env->num_mem || num <= 9)) { /* This spec. from GNU regex */
if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
if (num > env->num_mem || IS_NULL(SCANENV_MEMENV(env)[num].node))
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);
+ tok->u.prop.not = c == 'P';
if (!PEND &&
IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT)) {
PFETCH(c);
if (c == '^') {
- tok->u.prop.not = (tok->u.prop.not == 0 ? 1 : 0);
+ tok->u.prop.not = tok->u.prop.not == 0;
}
else
PUNFETCH;
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
tok->type = TK_ANCHOR;
tok->u.subtype = (IS_SINGLELINE(env->options)
- ? ANCHOR_BEGIN_BUF : ANCHOR_BEGIN_LINE);
+ ? ANCR_BEGIN_BUF : ANCR_BEGIN_LINE);
break;
case '$':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_LINE_ANCHOR)) break;
tok->type = TK_ANCHOR;
tok->u.subtype = (IS_SINGLELINE(env->options)
- ? ANCHOR_SEMI_END_BUF : ANCHOR_END_LINE);
+ ? ANCR_SEMI_END_BUF : ANCR_END_LINE);
break;
case '[':
}
static int parse_subexp(Node** top, OnigToken* tok, int term,
- UChar** src, UChar* end, ScanEnv* env);
+ UChar** src, UChar* end, ScanEnv* env, int group_head);
#ifdef USE_CALLOUT
if (r != 0) return r;
ext = onig_get_regex_ext(env->reg);
+ CHECK_NULL_RETURN_MEMERR(ext);
if (IS_NULL(ext->pattern)) {
r = onig_ext_set_pattern(env->reg, env->pattern, env->pattern_end);
if (r != ONIG_NORMAL) return r;
}
e = onig_reg_callout_list_at(env->reg, num);
+ if (IS_NULL(e)) {
+ xfree(contents);
+ return ONIGERR_MEMORY;
+ }
+
e->of = ONIG_CALLOUT_OF_CONTENTS;
e->in = in;
e->name_id = ONIG_NON_NAME_ID;
if (r != 0) return r;
ext = onig_get_regex_ext(env->reg);
+ CHECK_NULL_RETURN_MEMERR(ext);
if (IS_NULL(ext->pattern)) {
r = onig_ext_set_pattern(env->reg, env->pattern, env->pattern_end);
if (r != ONIG_NORMAL) return r;
if (r != ONIG_NORMAL) return r;
e = onig_reg_callout_list_at(env->reg, num);
+ CHECK_NULL_RETURN_MEMERR(e);
+
e->of = ONIG_CALLOUT_OF_NAME;
e->in = in;
e->name_id = name_id;
#endif
static int
-parse_enclosure(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
- ScanEnv* env)
+parse_bag(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
+ ScanEnv* env)
{
int r, num;
Node *target;
group:
r = fetch_token(tok, &p, end, env);
if (r < 0) return r;
- r = parse_subexp(np, tok, term, &p, end, env);
+ r = parse_subexp(np, tok, term, &p, end, env, 0);
if (r < 0) return r;
*src = p;
return 1; /* group */
break;
case '=':
- *np = onig_node_new_anchor(ANCHOR_PREC_READ, 0);
+ *np = onig_node_new_anchor(ANCR_PREC_READ, 0);
break;
case '!': /* preceding read */
- *np = onig_node_new_anchor(ANCHOR_PREC_READ_NOT, 0);
+ *np = onig_node_new_anchor(ANCR_PREC_READ_NOT, 0);
break;
case '>': /* (?>...) stop backtrack */
- *np = node_new_enclosure(ENCLOSURE_STOP_BACKTRACK);
+ *np = node_new_bag(BAG_STOP_BACKTRACK);
break;
case '\'':
if (PEND) return ONIGERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS;
PFETCH(c);
if (c == '=')
- *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND, 0);
+ *np = onig_node_new_anchor(ANCR_LOOK_BEHIND, 0);
else if (c == '!')
- *np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND_NOT, 0);
+ *np = onig_node_new_anchor(ANCR_LOOK_BEHIND_NOT, 0);
else {
if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
UChar *name;
if (r != 0) return r;
*np = node_new_memory(1);
CHECK_NULL_RETURN_MEMERR(*np);
- ENCLOSURE_(*np)->m.regnum = num;
+ BAG_(*np)->m.regnum = num;
if (list_capture != 0)
MEM_STATUS_ON_SIMPLE(env->capture_history, num);
env->num_named++;
r = fetch_token(tok, &p, end, env);
if (r < 0) return r;
- r = parse_subexp(&absent, tok, term, &p, end, env);
+ r = parse_subexp(&absent, tok, term, &p, end, env, 1);
if (r < 0) {
onig_node_free(absent);
return r;
condition_is_checker = 0;
r = fetch_token(tok, &p, end, env);
if (r < 0) return r;
- r = parse_subexp(&condition, tok, term, &p, end, env);
+ r = parse_subexp(&condition, tok, term, &p, end, env, 0);
if (r < 0) {
onig_node_free(condition);
return r;
onig_node_free(condition);
return r;
}
- r = parse_subexp(&target, tok, term, &p, end, env);
+ r = parse_subexp(&target, tok, term, &p, end, env, 1);
if (r < 0) {
onig_node_free(condition);
onig_node_free(target);
}
}
- *np = node_new_enclosure_if_else(condition, Then, Else);
+ *np = node_new_bag_if_else(condition, Then, Else);
if (IS_NULL(*np)) {
onig_node_free(condition);
onig_node_free(Then);
else if (num >= (int )MEM_STATUS_BITS_NUM) {
return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
}
- ENCLOSURE_(*np)->m.regnum = num;
+ BAG_(*np)->m.regnum = num;
MEM_STATUS_ON_SIMPLE(env->capture_history, num);
}
else {
env->options = option;
r = fetch_token(tok, &p, end, env);
if (r < 0) return r;
- r = parse_subexp(&target, tok, term, &p, end, env);
+ r = parse_subexp(&target, tok, term, &p, end, env, 0);
env->options = prev;
if (r < 0) {
onig_node_free(target);
CHECK_NULL_RETURN_MEMERR(*np);
num = scan_env_add_mem_entry(env);
if (num < 0) return num;
- ENCLOSURE_(*np)->m.regnum = num;
+ BAG_(*np)->m.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);
+ r = parse_subexp(&target, tok, term, &p, end, env, 0);
if (r < 0) {
onig_node_free(target);
return r;
NODE_BODY(*np) = target;
- if (NODE_TYPE(*np) == NODE_ENCLOSURE) {
- if (ENCLOSURE_(*np)->type == ENCLOSURE_MEMORY) {
+ if (NODE_TYPE(*np) == NODE_BAG) {
+ if (BAG_(*np)->type == BAG_MEMORY) {
/* Don't move this to previous of parse_subexp() */
- r = scan_env_set_mem_node(env, ENCLOSURE_(*np)->m.regnum, *np);
+ r = scan_env_set_mem_node(env, BAG_(*np)->m.regnum, *np);
if (r != 0) return r;
}
}
switch (NODE_TYPE(target)) {
case NODE_STRING:
- if (! group) {
+ if (group == 0) {
if (str_node_can_be_split(target, env->enc)) {
Node* n = str_node_split_last_char(target, env->enc);
if (IS_NOT_NULL(n)) {
static int
parse_exp(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
- ScanEnv* env)
+ ScanEnv* env, int group_head)
{
int r, len, group = 0;
Node* qn;
case TK_ALT:
case TK_EOT:
end_of_token:
- *np = node_new_empty();
- return tok->type;
+ *np = node_new_empty();
+ CHECK_NULL_RETURN_MEMERR(*np);
+ return tok->type;
break;
case TK_SUBEXP_OPEN:
- r = parse_enclosure(np, tok, TK_SUBEXP_CLOSE, src, end, env);
+ r = parse_bag(np, tok, TK_SUBEXP_CLOSE, src, end, env);
if (r < 0) return r;
- if (r == 1) group = 1;
+ if (r == 1) { /* group */
+ if (group_head == 0)
+ group = 1;
+ else {
+ Node* target = *np;
+ *np = node_new_group(target);
+ if (IS_NULL(*np)) {
+ onig_node_free(target);
+ return ONIGERR_MEMORY;
+ }
+ group = 2;
+ }
+ }
else if (r == 2) { /* option only */
Node* target;
OnigOptionType prev = env->options;
- env->options = ENCLOSURE_(*np)->o.options;
+ env->options = BAG_(*np)->o.options;
r = fetch_token(tok, src, end, env);
if (r < 0) return r;
- r = parse_subexp(&target, tok, term, src, end, env);
+ r = parse_subexp(&target, tok, term, src, end, env, 0);
env->options = prev;
if (r < 0) {
onig_node_free(target);
int ascii_mode =
IS_WORD_ASCII(env->options) && IS_WORD_ANCHOR_TYPE(tok->u.anchor) ? 1 : 0;
*np = onig_node_new_anchor(tok->u.anchor, ascii_mode);
+ CHECK_NULL_RETURN_MEMERR(*np);
}
break;
if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS)) {
if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS))
return ONIGERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED;
- else
+ else {
*np = node_new_empty();
+ CHECK_NULL_RETURN_MEMERR(*np);
+ }
}
else {
goto tk_byte;
repeat:
if (r == TK_OP_REPEAT || r == TK_INTERVAL) {
+ Node* target;
+
if (is_invalid_quantifier_target(*targetp))
return ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID;
qn = node_new_quantifier(tok->u.repeat.lower, tok->u.repeat.upper,
- (r == TK_INTERVAL ? 1 : 0));
+ r == TK_INTERVAL);
CHECK_NULL_RETURN_MEMERR(qn);
QUANT_(qn)->greedy = tok->u.repeat.greedy;
- r = set_quantifier(qn, *targetp, group, env);
+ if (group == 2) {
+ target = node_drop_group(*np);
+ *np = NULL_NODE;
+ }
+ else {
+ target = *targetp;
+ }
+ r = set_quantifier(qn, target, group, env);
if (r < 0) {
onig_node_free(qn);
return r;
if (tok->u.repeat.possessive != 0) {
Node* en;
- en = node_new_enclosure(ENCLOSURE_STOP_BACKTRACK);
+ en = node_new_bag(BAG_STOP_BACKTRACK);
if (IS_NULL(en)) {
onig_node_free(qn);
return ONIGERR_MEMORY;
static int
parse_branch(Node** top, OnigToken* tok, int term, UChar** src, UChar* end,
- ScanEnv* env)
+ ScanEnv* env, int group_head)
{
int r;
Node *node, **headp;
*top = NULL;
- r = parse_exp(&node, tok, term, src, end, env);
+ r = parse_exp(&node, tok, term, src, end, env, group_head);
if (r < 0) {
onig_node_free(node);
return r;
}
else {
*top = node_new_list(node, NULL);
+ if (IS_NULL(*top)) {
+ onig_node_free(node);
+ return ONIGERR_MEMORY;
+ }
+
headp = &(NODE_CDR(*top));
while (r != TK_EOT && r != term && r != TK_ALT) {
- r = parse_exp(&node, tok, term, src, end, env);
+ r = parse_exp(&node, tok, term, src, end, env, 0);
if (r < 0) {
onig_node_free(node);
return r;
/* term_tok: TK_EOT or TK_SUBEXP_CLOSE */
static int
parse_subexp(Node** top, OnigToken* tok, int term, UChar** src, UChar* end,
- ScanEnv* env)
+ ScanEnv* env, int group_head)
{
int r;
Node *node, **headp;
env->parse_depth++;
if (env->parse_depth > ParseDepthLimit)
return ONIGERR_PARSE_DEPTH_LIMIT_OVER;
- r = parse_branch(&node, tok, term, src, end, env);
+
+ r = parse_branch(&node, tok, term, src, end, env, group_head);
if (r < 0) {
onig_node_free(node);
return r;
}
else if (r == TK_ALT) {
*top = onig_node_new_alt(node, NULL);
+ if (IS_NULL(*top)) {
+ onig_node_free(node);
+ return ONIGERR_MEMORY;
+ }
+
headp = &(NODE_CDR(*top));
while (r == TK_ALT) {
r = fetch_token(tok, src, end, env);
if (r < 0) return r;
- r = parse_branch(&node, tok, term, src, end, env);
+ r = parse_branch(&node, tok, term, src, end, env, 0);
if (r < 0) {
onig_node_free(node);
return r;
}
*headp = onig_node_new_alt(node, NULL);
+ if (IS_NULL(*headp)) {
+ onig_node_free(node);
+ onig_node_free(*top);
+ return ONIGERR_MEMORY;
+ }
+
headp = &(NODE_CDR(*headp));
}
r = fetch_token(&tok, src, end, env);
if (r < 0) return r;
- r = parse_subexp(top, &tok, TK_EOT, src, end, env);
+ r = parse_subexp(top, &tok, TK_EOT, src, end, env, 0);
if (r < 0) return r;
return 0;
CHECK_NULL_RETURN_MEMERR(x);
NODE_BODY(x) = node;
- ENCLOSURE_(x)->m.regnum = 0;
+ BAG_(x)->m.regnum = 0;
r = scan_env_set_mem_node(env, 0, x);
if (r != 0) {
onig_node_free(x);
reg->num_mem = env->num_mem;
#ifdef USE_CALLOUT
- ext = REG_EXTP(reg);
+ ext = reg->extp;
if (IS_NOT_NULL(ext) && ext->callout_num > 0) {
r = setup_ext_callout_list_values(reg);
}
#include "regint.h"
+#define NODE_STRING_MARGIN 16
+#define NODE_STRING_BUF_SIZE 24 /* sizeof(CClassNode) - sizeof(int)*4 */
+#define NODE_BACKREFS_SIZE 6
+
/* node type */
typedef enum {
NODE_STRING = 0,
NODE_CTYPE = 2,
NODE_BACKREF = 3,
NODE_QUANT = 4,
- NODE_ENCLOSURE = 5,
+ NODE_BAG = 5,
NODE_ANCHOR = 6,
NODE_LIST = 7,
NODE_ALT = 8,
NODE_GIMMICK = 10
} NodeType;
+enum BagType {
+ BAG_MEMORY = 0,
+ BAG_OPTION = 1,
+ BAG_STOP_BACKTRACK = 2,
+ BAG_IF_ELSE = 3,
+};
+
enum GimmickType {
- GIMMICK_FAIL = 0,
- GIMMICK_KEEP = 1,
- GIMMICK_SAVE = 2,
+ GIMMICK_FAIL = 0,
+ GIMMICK_KEEP = 1,
+ GIMMICK_SAVE = 2,
GIMMICK_UPDATE_VAR = 3,
#ifdef USE_CALLOUT
- GIMMICK_CALLOUT = 4,
+ GIMMICK_CALLOUT = 4,
#endif
};
-
-/* node type bit */
-#define NODE_TYPE2BIT(type) (1<<(type))
-
-#define NODE_BIT_STRING NODE_TYPE2BIT(NODE_STRING)
-#define NODE_BIT_CCLASS NODE_TYPE2BIT(NODE_CCLASS)
-#define NODE_BIT_CTYPE NODE_TYPE2BIT(NODE_CTYPE)
-#define NODE_BIT_BACKREF NODE_TYPE2BIT(NODE_BACKREF)
-#define NODE_BIT_QUANT NODE_TYPE2BIT(NODE_QUANT)
-#define NODE_BIT_ENCLOSURE NODE_TYPE2BIT(NODE_ENCLOSURE)
-#define NODE_BIT_ANCHOR NODE_TYPE2BIT(NODE_ANCHOR)
-#define NODE_BIT_LIST NODE_TYPE2BIT(NODE_LIST)
-#define NODE_BIT_ALT NODE_TYPE2BIT(NODE_ALT)
-#define NODE_BIT_CALL NODE_TYPE2BIT(NODE_CALL)
-#define NODE_BIT_GIMMICK NODE_TYPE2BIT(NODE_GIMMICK)
-
-#define NODE_IS_SIMPLE_TYPE(node) \
- ((NODE_TYPE2BIT(NODE_TYPE(node)) & \
- (NODE_BIT_STRING | NODE_BIT_CCLASS | NODE_BIT_CTYPE | NODE_BIT_BACKREF)) != 0)
-
-#define NODE_TYPE(node) ((node)->u.base.node_type)
-#define NODE_SET_TYPE(node, ntype) (node)->u.base.node_type = (ntype)
-
-#define STR_(node) (&((node)->u.str))
-#define CCLASS_(node) (&((node)->u.cclass))
-#define CTYPE_(node) (&((node)->u.ctype))
-#define BACKREF_(node) (&((node)->u.backref))
-#define QUANT_(node) (&((node)->u.quant))
-#define ENCLOSURE_(node) (&((node)->u.enclosure))
-#define ANCHOR_(node) (&((node)->u.anchor))
-#define CONS_(node) (&((node)->u.cons))
-#define CALL_(node) (&((node)->u.call))
-#define GIMMICK_(node) (&((node)->u.gimmick))
-
-#define NODE_CAR(node) (CONS_(node)->car)
-#define NODE_CDR(node) (CONS_(node)->cdr)
-
-#define CTYPE_ANYCHAR -1
-#define NODE_IS_ANYCHAR(node) \
- (NODE_TYPE(node) == NODE_CTYPE && CTYPE_(node)->ctype == CTYPE_ANYCHAR)
-
-#define CTYPE_OPTION(node, reg) \
- (NODE_IS_FIXED_OPTION(node) ? CTYPE_(node)->options : reg->options)
-
-
-#define ANCHOR_ANYCHAR_INF_MASK (ANCHOR_ANYCHAR_INF | ANCHOR_ANYCHAR_INF_ML)
-#define ANCHOR_END_BUF_MASK (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)
-
-enum EnclosureType {
- ENCLOSURE_MEMORY = 0,
- ENCLOSURE_OPTION = 1,
- ENCLOSURE_STOP_BACKTRACK = 2,
- ENCLOSURE_IF_ELSE = 3,
-};
-
-#define NODE_STRING_MARGIN 16
-#define NODE_STRING_BUF_SIZE 24 /* sizeof(CClassNode) - sizeof(int)*4 */
-#define NODE_BACKREFS_SIZE 6
-
-#define NODE_STRING_RAW (1<<0) /* by backslashed number */
-#define NODE_STRING_AMBIG (1<<1)
-#define NODE_STRING_DONT_GET_OPT_INFO (1<<2)
-
-#define NODE_STRING_LEN(node) (int )((node)->u.str.end - (node)->u.str.s)
-#define NODE_STRING_SET_RAW(node) (node)->u.str.flag |= NODE_STRING_RAW
-#define NODE_STRING_CLEAR_RAW(node) (node)->u.str.flag &= ~NODE_STRING_RAW
-#define NODE_STRING_SET_AMBIG(node) (node)->u.str.flag |= NODE_STRING_AMBIG
-#define NODE_STRING_SET_DONT_GET_OPT_INFO(node) \
- (node)->u.str.flag |= NODE_STRING_DONT_GET_OPT_INFO
-#define NODE_STRING_IS_RAW(node) \
- (((node)->u.str.flag & NODE_STRING_RAW) != 0)
-#define NODE_STRING_IS_AMBIG(node) \
- (((node)->u.str.flag & NODE_STRING_AMBIG) != 0)
-#define NODE_STRING_IS_DONT_GET_OPT_INFO(node) \
- (((node)->u.str.flag & NODE_STRING_DONT_GET_OPT_INFO) != 0)
-
-#define BACKREFS_P(br) \
- (IS_NOT_NULL((br)->back_dynamic) ? (br)->back_dynamic : (br)->back_static)
-
enum QuantBodyEmpty {
QUANT_BODY_IS_NOT_EMPTY = 0,
QUANT_BODY_IS_EMPTY = 1,
QUANT_BODY_IS_EMPTY_REC = 3
};
-/* node status bits */
-#define NODE_ST_MIN_FIXED (1<<0)
-#define NODE_ST_MAX_FIXED (1<<1)
-#define NODE_ST_CLEN_FIXED (1<<2)
-#define NODE_ST_MARK1 (1<<3)
-#define NODE_ST_MARK2 (1<<4)
-#define NODE_ST_STOP_BT_SIMPLE_REPEAT (1<<5)
-#define NODE_ST_RECURSION (1<<6)
-#define NODE_ST_CALLED (1<<7)
-#define NODE_ST_ADDR_FIXED (1<<8)
-#define NODE_ST_NAMED_GROUP (1<<9)
-#define NODE_ST_IN_REAL_REPEAT (1<<10) /* STK_REPEAT is nested in stack. */
-#define NODE_ST_IN_ZERO_REPEAT (1<<11) /* (....){0} */
-#define NODE_ST_IN_MULTI_ENTRY (1<<12)
-#define NODE_ST_NEST_LEVEL (1<<13)
-#define NODE_ST_BY_NUMBER (1<<14) /* {n,m} */
-#define NODE_ST_BY_NAME (1<<15) /* backref by name */
-#define NODE_ST_BACKREF (1<<16)
-#define NODE_ST_CHECKER (1<<17)
-#define NODE_ST_FIXED_OPTION (1<<18)
-#define NODE_ST_PROHIBIT_RECURSION (1<<19)
-#define NODE_ST_SUPER (1<<20)
-
-
-#define NODE_STATUS(node) (((Node* )node)->u.base.status)
-#define NODE_STATUS_ADD(node,f) (NODE_STATUS(node) |= (NODE_ST_ ## f))
-#define NODE_STATUS_REMOVE(node,f) (NODE_STATUS(node) &= ~(NODE_ST_ ## f))
-
-#define NODE_IS_BY_NUMBER(node) ((NODE_STATUS(node) & NODE_ST_BY_NUMBER) != 0)
-#define NODE_IS_IN_REAL_REPEAT(node) ((NODE_STATUS(node) & NODE_ST_IN_REAL_REPEAT) != 0)
-#define NODE_IS_CALLED(node) ((NODE_STATUS(node) & NODE_ST_CALLED) != 0)
-#define NODE_IS_IN_MULTI_ENTRY(node) ((NODE_STATUS(node) & NODE_ST_IN_MULTI_ENTRY) != 0)
-#define NODE_IS_RECURSION(node) ((NODE_STATUS(node) & NODE_ST_RECURSION) != 0)
-#define NODE_IS_IN_ZERO_REPEAT(node) ((NODE_STATUS(node) & NODE_ST_IN_ZERO_REPEAT) != 0)
-#define NODE_IS_NAMED_GROUP(node) ((NODE_STATUS(node) & NODE_ST_NAMED_GROUP) != 0)
-#define NODE_IS_ADDR_FIXED(node) ((NODE_STATUS(node) & NODE_ST_ADDR_FIXED) != 0)
-#define NODE_IS_CLEN_FIXED(node) ((NODE_STATUS(node) & NODE_ST_CLEN_FIXED) != 0)
-#define NODE_IS_MIN_FIXED(node) ((NODE_STATUS(node) & NODE_ST_MIN_FIXED) != 0)
-#define NODE_IS_MAX_FIXED(node) ((NODE_STATUS(node) & NODE_ST_MAX_FIXED) != 0)
-#define NODE_IS_MARK1(node) ((NODE_STATUS(node) & NODE_ST_MARK1) != 0)
-#define NODE_IS_MARK2(node) ((NODE_STATUS(node) & NODE_ST_MARK2) != 0)
-#define NODE_IS_NEST_LEVEL(node) ((NODE_STATUS(node) & NODE_ST_NEST_LEVEL) != 0)
-#define NODE_IS_BY_NAME(node) ((NODE_STATUS(node) & NODE_ST_BY_NAME) != 0)
-#define NODE_IS_BACKREF(node) ((NODE_STATUS(node) & NODE_ST_BACKREF) != 0)
-#define NODE_IS_CHECKER(node) ((NODE_STATUS(node) & NODE_ST_CHECKER) != 0)
-#define NODE_IS_FIXED_OPTION(node) ((NODE_STATUS(node) & NODE_ST_FIXED_OPTION) != 0)
-#define NODE_IS_SUPER(node) ((NODE_STATUS(node) & NODE_ST_SUPER) != 0)
-#define NODE_IS_PROHIBIT_RECURSION(node) \
- ((NODE_STATUS(node) & NODE_ST_PROHIBIT_RECURSION) != 0)
-#define NODE_IS_STOP_BT_SIMPLE_REPEAT(node) \
- ((NODE_STATUS(node) & NODE_ST_STOP_BT_SIMPLE_REPEAT) != 0)
-
-#define NODE_BODY(node) ((node)->u.base.body)
-#define NODE_QUANT_BODY(node) ((node)->body)
-#define NODE_ENCLOSURE_BODY(node) ((node)->body)
-#define NODE_CALL_BODY(node) ((node)->body)
-#define NODE_ANCHOR_BODY(node) ((node)->body)
-
-
typedef struct {
NodeType node_type;
int status;
UChar* s;
UChar* end;
unsigned int flag;
- int capa; /* (allocated size - 1) or 0: use buf[] */
+ int capacity; /* (allocated size - 1) or 0: use buf[] */
UChar buf[NODE_STRING_BUF_SIZE];
} StrNode;
int status;
struct _Node* body;
- enum EnclosureType type;
+ enum BagType type;
union {
struct {
int regnum;
OnigLen max_len; /* max length (byte) */
int char_len; /* character length */
int opt_count; /* referenced count in optimize_nodes() */
-} EnclosureNode;
+} BagNode;
#ifdef USE_CALL
typedef struct {
NodeType node_type;
int status;
- struct _Node* body; /* to EnclosureNode : ENCLOSURE_MEMORY */
+ struct _Node* body; /* to BagNode : BAG_MEMORY */
int by_number;
int group_num;
StrNode str;
CClassNode cclass;
QuantNode quant;
- EnclosureNode enclosure;
+ BagNode bag;
BackRefNode backref;
AnchorNode anchor;
ConsAltNode cons;
} u;
} Node;
-
#define NULL_NODE ((Node* )0)
+
+/* node type bit */
+#define NODE_TYPE2BIT(type) (1<<(type))
+
+#define NODE_BIT_STRING NODE_TYPE2BIT(NODE_STRING)
+#define NODE_BIT_CCLASS NODE_TYPE2BIT(NODE_CCLASS)
+#define NODE_BIT_CTYPE NODE_TYPE2BIT(NODE_CTYPE)
+#define NODE_BIT_BACKREF NODE_TYPE2BIT(NODE_BACKREF)
+#define NODE_BIT_QUANT NODE_TYPE2BIT(NODE_QUANT)
+#define NODE_BIT_BAG NODE_TYPE2BIT(NODE_BAG)
+#define NODE_BIT_ANCHOR NODE_TYPE2BIT(NODE_ANCHOR)
+#define NODE_BIT_LIST NODE_TYPE2BIT(NODE_LIST)
+#define NODE_BIT_ALT NODE_TYPE2BIT(NODE_ALT)
+#define NODE_BIT_CALL NODE_TYPE2BIT(NODE_CALL)
+#define NODE_BIT_GIMMICK NODE_TYPE2BIT(NODE_GIMMICK)
+
+#define NODE_IS_SIMPLE_TYPE(node) \
+ ((NODE_TYPE2BIT(NODE_TYPE(node)) & \
+ (NODE_BIT_STRING | NODE_BIT_CCLASS | NODE_BIT_CTYPE | NODE_BIT_BACKREF)) != 0)
+
+#define NODE_TYPE(node) ((node)->u.base.node_type)
+#define NODE_SET_TYPE(node, ntype) (node)->u.base.node_type = (ntype)
+
+#define STR_(node) (&((node)->u.str))
+#define CCLASS_(node) (&((node)->u.cclass))
+#define CTYPE_(node) (&((node)->u.ctype))
+#define BACKREF_(node) (&((node)->u.backref))
+#define QUANT_(node) (&((node)->u.quant))
+#define BAG_(node) (&((node)->u.bag))
+#define ANCHOR_(node) (&((node)->u.anchor))
+#define CONS_(node) (&((node)->u.cons))
+#define CALL_(node) (&((node)->u.call))
+#define GIMMICK_(node) (&((node)->u.gimmick))
+
+#define NODE_CAR(node) (CONS_(node)->car)
+#define NODE_CDR(node) (CONS_(node)->cdr)
+
+#define CTYPE_ANYCHAR -1
+#define NODE_IS_ANYCHAR(node) \
+ (NODE_TYPE(node) == NODE_CTYPE && CTYPE_(node)->ctype == CTYPE_ANYCHAR)
+
+#define CTYPE_OPTION(node, reg) \
+ (NODE_IS_FIXED_OPTION(node) ? CTYPE_(node)->options : reg->options)
+
+
+#define ANCR_ANYCHAR_INF_MASK (ANCR_ANYCHAR_INF | ANCR_ANYCHAR_INF_ML)
+#define ANCR_END_BUF_MASK (ANCR_END_BUF | ANCR_SEMI_END_BUF)
+
+#define NODE_STRING_RAW (1<<0) /* by backslashed number */
+#define NODE_STRING_AMBIG (1<<1)
+#define NODE_STRING_GOOD_AMBIG (1<<2)
+#define NODE_STRING_DONT_GET_OPT_INFO (1<<3)
+
+#define NODE_STRING_LEN(node) (int )((node)->u.str.end - (node)->u.str.s)
+#define NODE_STRING_SET_RAW(node) (node)->u.str.flag |= NODE_STRING_RAW
+#define NODE_STRING_CLEAR_RAW(node) (node)->u.str.flag &= ~NODE_STRING_RAW
+#define NODE_STRING_SET_AMBIG(node) (node)->u.str.flag |= NODE_STRING_AMBIG
+#define NODE_STRING_SET_GOOD_AMBIG(node) (node)->u.str.flag |= NODE_STRING_GOOD_AMBIG
+#define NODE_STRING_SET_DONT_GET_OPT_INFO(node) \
+ (node)->u.str.flag |= NODE_STRING_DONT_GET_OPT_INFO
+#define NODE_STRING_IS_RAW(node) \
+ (((node)->u.str.flag & NODE_STRING_RAW) != 0)
+#define NODE_STRING_IS_AMBIG(node) \
+ (((node)->u.str.flag & NODE_STRING_AMBIG) != 0)
+#define NODE_STRING_IS_GOOD_AMBIG(node) \
+ (((node)->u.str.flag & NODE_STRING_GOOD_AMBIG) != 0)
+#define NODE_STRING_IS_DONT_GET_OPT_INFO(node) \
+ (((node)->u.str.flag & NODE_STRING_DONT_GET_OPT_INFO) != 0)
+
+#define BACKREFS_P(br) \
+ (IS_NOT_NULL((br)->back_dynamic) ? (br)->back_dynamic : (br)->back_static)
+
+/* node status bits */
+#define NODE_ST_MIN_FIXED (1<<0)
+#define NODE_ST_MAX_FIXED (1<<1)
+#define NODE_ST_CLEN_FIXED (1<<2)
+#define NODE_ST_MARK1 (1<<3)
+#define NODE_ST_MARK2 (1<<4)
+#define NODE_ST_STOP_BT_SIMPLE_REPEAT (1<<5)
+#define NODE_ST_RECURSION (1<<6)
+#define NODE_ST_CALLED (1<<7)
+#define NODE_ST_ADDR_FIXED (1<<8)
+#define NODE_ST_NAMED_GROUP (1<<9)
+#define NODE_ST_IN_REAL_REPEAT (1<<10) /* STK_REPEAT is nested in stack. */
+#define NODE_ST_IN_ZERO_REPEAT (1<<11) /* (....){0} */
+#define NODE_ST_IN_MULTI_ENTRY (1<<12)
+#define NODE_ST_NEST_LEVEL (1<<13)
+#define NODE_ST_BY_NUMBER (1<<14) /* {n,m} */
+#define NODE_ST_BY_NAME (1<<15) /* backref by name */
+#define NODE_ST_BACKREF (1<<16)
+#define NODE_ST_CHECKER (1<<17)
+#define NODE_ST_FIXED_OPTION (1<<18)
+#define NODE_ST_PROHIBIT_RECURSION (1<<19)
+#define NODE_ST_SUPER (1<<20)
+
+
+#define NODE_STATUS(node) (((Node* )node)->u.base.status)
+#define NODE_STATUS_ADD(node,f) (NODE_STATUS(node) |= (NODE_ST_ ## f))
+#define NODE_STATUS_REMOVE(node,f) (NODE_STATUS(node) &= ~(NODE_ST_ ## f))
+
+#define NODE_IS_BY_NUMBER(node) ((NODE_STATUS(node) & NODE_ST_BY_NUMBER) != 0)
+#define NODE_IS_IN_REAL_REPEAT(node) ((NODE_STATUS(node) & NODE_ST_IN_REAL_REPEAT) != 0)
+#define NODE_IS_CALLED(node) ((NODE_STATUS(node) & NODE_ST_CALLED) != 0)
+#define NODE_IS_IN_MULTI_ENTRY(node) ((NODE_STATUS(node) & NODE_ST_IN_MULTI_ENTRY) != 0)
+#define NODE_IS_RECURSION(node) ((NODE_STATUS(node) & NODE_ST_RECURSION) != 0)
+#define NODE_IS_IN_ZERO_REPEAT(node) ((NODE_STATUS(node) & NODE_ST_IN_ZERO_REPEAT) != 0)
+#define NODE_IS_NAMED_GROUP(node) ((NODE_STATUS(node) & NODE_ST_NAMED_GROUP) != 0)
+#define NODE_IS_ADDR_FIXED(node) ((NODE_STATUS(node) & NODE_ST_ADDR_FIXED) != 0)
+#define NODE_IS_CLEN_FIXED(node) ((NODE_STATUS(node) & NODE_ST_CLEN_FIXED) != 0)
+#define NODE_IS_MIN_FIXED(node) ((NODE_STATUS(node) & NODE_ST_MIN_FIXED) != 0)
+#define NODE_IS_MAX_FIXED(node) ((NODE_STATUS(node) & NODE_ST_MAX_FIXED) != 0)
+#define NODE_IS_MARK1(node) ((NODE_STATUS(node) & NODE_ST_MARK1) != 0)
+#define NODE_IS_MARK2(node) ((NODE_STATUS(node) & NODE_ST_MARK2) != 0)
+#define NODE_IS_NEST_LEVEL(node) ((NODE_STATUS(node) & NODE_ST_NEST_LEVEL) != 0)
+#define NODE_IS_BY_NAME(node) ((NODE_STATUS(node) & NODE_ST_BY_NAME) != 0)
+#define NODE_IS_BACKREF(node) ((NODE_STATUS(node) & NODE_ST_BACKREF) != 0)
+#define NODE_IS_CHECKER(node) ((NODE_STATUS(node) & NODE_ST_CHECKER) != 0)
+#define NODE_IS_FIXED_OPTION(node) ((NODE_STATUS(node) & NODE_ST_FIXED_OPTION) != 0)
+#define NODE_IS_SUPER(node) ((NODE_STATUS(node) & NODE_ST_SUPER) != 0)
+#define NODE_IS_PROHIBIT_RECURSION(node) \
+ ((NODE_STATUS(node) & NODE_ST_PROHIBIT_RECURSION) != 0)
+#define NODE_IS_STOP_BT_SIMPLE_REPEAT(node) \
+ ((NODE_STATUS(node) & NODE_ST_STOP_BT_SIMPLE_REPEAT) != 0)
+
+#define NODE_BODY(node) ((node)->u.base.body)
+#define NODE_QUANT_BODY(node) ((node)->body)
+#define NODE_BAG_BODY(node) ((node)->body)
+#define NODE_CALL_BODY(node) ((node)->body)
+#define NODE_ANCHOR_BODY(node) ((node)->body)
+
#define SCANENV_MEMENV_SIZE 8
#define SCANENV_MEMENV(senv) \
(IS_NOT_NULL((senv)->mem_env_dynamic) ? \
extern int onig_node_str_cat P_((Node* node, const UChar* s, const UChar* end));
extern int onig_node_str_set P_((Node* node, const UChar* s, const UChar* end));
extern void onig_node_free P_((Node* node));
-extern Node* onig_node_new_enclosure P_((int type));
+extern Node* onig_node_new_bag P_((enum BagType type));
extern Node* onig_node_new_anchor P_((int type, int ascii_mode));
extern Node* onig_node_new_str P_((const UChar* s, const UChar* end));
extern Node* onig_node_new_list P_((Node* left, Node* right));
#include "config.h"
#include "onigposix.h"
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#if defined(__GNUC__)
# define ARG_UNUSED __attribute__ ((unused))
ONIG_SYN_OP_BRACE_INTERVAL |
ONIG_SYN_OP_PLUS_ONE_INF | ONIG_SYN_OP_QMARK_ZERO_ONE | ONIG_SYN_OP_VBAR_ALT )
, 0
- , ( ONIG_SYN_CONTEXT_INDEP_ANCHORS |
- ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS | ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS |
+ , ( ONIG_SYN_CONTEXT_INDEP_ANCHORS |
+ ONIG_SYN_CONTEXT_INDEP_REPEAT_OPS | ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS |
ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP |
ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC )
, ( ONIG_OPTION_SINGLELINE | ONIG_OPTION_MULTILINE )
code_to_mbclen(OnigCodePoint code)
{
if (code < 256) {
- if (EncLen_SJIS[(int )code] == 1)
- return 1;
- else
- return 0;
+ return EncLen_SJIS[(int )code] == 1;
}
else if (code <= 0xffff) {
return 2;
const UChar** pp, const UChar* end)
{
return onigenc_mbn_is_mbc_ambiguous(ONIG_ENCODING_SJIS, flag, pp, end);
-
+
}
#endif
p++;
break;
}
- }
+ }
}
len = enclen(ONIG_ENCODING_SJIS, p);
if (p + len > s) return (UChar* )p;
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_SKIP_OFFSET_1_OR_0,
0, 0
};
#ifdef USE_UNICODE_EXTENDED_GRAPHEME_CLUSTER
if (! ONIGENC_IS_UNICODE_ENCODING(enc)) {
- if (from == 0x000d && to == 0x000a) return 0;
- else return 1;
+ return from != 0x000d || to != 0x000a;
}
btype = unicode_egcb_is_break_2code(from, to);
return 1;
#else
- if (from == 0x000d && to == 0x000a) return 0;
- else return 1;
+ return from != 0x000d || to != 0x000a;
#endif /* USE_UNICODE_EXTENDED_GRAPHEME_CLUSTER */
}
int len;
int c;
char* s;
+ UChar* uname;
if (UserDefinedPropertyNum >= USER_DEFINED_PROPERTY_MAX_NUM)
return ONIGERR_TOO_MANY_USER_DEFINED_OBJECTS;
if (s == 0)
return ONIGERR_MEMORY;
+ uname = (UChar* )name;
n = 0;
for (i = 0; i < len; i++) {
- c = name[i];
- if (c <= 0 || c >= 0x80) {
+ c = uname[i];
+ if (c < 0x20 || c >= 0x80) {
xfree(s);
return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
}
if (UserDefinedPropertyTable == 0) {
UserDefinedPropertyTable = onig_st_init_strend_table_with_size(10);
+ if (IS_NULL(UserDefinedPropertyTable)) {
+ xfree(s);
+ return ONIGERR_MEMORY;
+ }
}
e = UserDefinedPropertyRanges + UserDefinedPropertyNum;
/* ----- LOCALE ----- */
#define FOLDS3_END_INDEX 72
};
-
init,
0, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_UNICODE,
+ ENC_FLAG_UNICODE|ENC_FLAG_SKIP_OFFSET_2,
0, 0
};
init,
0, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_UNICODE,
+ ENC_FLAG_UNICODE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_UNICODE,
+ ENC_FLAG_UNICODE|ENC_FLAG_SKIP_OFFSET_4,
0, 0
};
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_UNICODE,
+ ENC_FLAG_UNICODE|ENC_FLAG_SKIP_OFFSET_1,
0, 0
};
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
+ 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
static int
OnigEncodingType OnigEncodingUTF8 = {
mbc_enc_len,
"UTF-8", /* name */
- 6, /* max enc length */
+ 4, /* max enc length */
1, /* min enc length */
onigenc_is_mbc_newline_0x0a,
mbc_to_code,
NULL, /* init */
NULL, /* is_initialized */
is_valid_mbc_string,
- ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_UNICODE,
+ ENC_FLAG_ASCII_COMPATIBLE|ENC_FLAG_UNICODE|ENC_FLAG_SKIP_OFFSET_1_OR_0,
0, 0
};
/* edit configure.ac to change version number */
#define PHP_MAJOR_VERSION 7
#define PHP_MINOR_VERSION 3
-#define PHP_RELEASE_VERSION 10
+#define PHP_RELEASE_VERSION 8
#define PHP_EXTRA_VERSION "-dev"
-#define PHP_VERSION "7.3.10-dev"
-#define PHP_VERSION_ID 70310
+#define PHP_VERSION "7.3.8-dev"
+#define PHP_VERSION_ID 70308