зеркало из https://github.com/github/ruby.git
merge Oniguruma 4.2.2
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10684 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
7e10b0c4de
Коммит
d92db05a27
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
Sat Aug 5 22:53:41 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
|
||||
|
||||
* oniguruma.h: Version 4.2.2
|
||||
|
||||
* regint.h: ditto.
|
||||
|
||||
* regparse.h: ditto.
|
||||
|
||||
* regexec.c: ditto.
|
||||
|
||||
* regcomp.c ditto.
|
||||
|
||||
* regerror.c: ditto.
|
||||
|
||||
* regparse.c: ditto.
|
||||
|
||||
Sat Aug 5 13:49:43 2006 Tadayoshi Funaba <tadf@dotrb.org>
|
||||
|
||||
* lib/date/format.rb (str[fp]time): "%\n" means "\n".
|
||||
|
|
|
@ -35,8 +35,8 @@ extern "C" {
|
|||
|
||||
#define ONIGURUMA
|
||||
#define ONIGURUMA_VERSION_MAJOR 4
|
||||
#define ONIGURUMA_VERSION_MINOR 0
|
||||
#define ONIGURUMA_VERSION_TEENY 3
|
||||
#define ONIGURUMA_VERSION_MINOR 2
|
||||
#define ONIGURUMA_VERSION_TEENY 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
# ifndef HAVE_PROTOTYPES
|
||||
|
|
159
regcomp.c
159
regcomp.c
|
@ -1268,6 +1268,13 @@ compile_length_tree(Node* node, regex_t* reg)
|
|||
{
|
||||
BackrefNode* br = &(NBACKREF(node));
|
||||
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
if (IS_BACKREF_NEST_LEVEL(br)) {
|
||||
r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
|
||||
SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (br->back_num == 1) {
|
||||
r = ((!IS_IGNORECASE(reg->options) && br->back_static[0] <= 3)
|
||||
? SIZE_OPCODE : (SIZE_OPCODE + SIZE_MEMNUM));
|
||||
|
@ -1381,9 +1388,21 @@ compile_tree(Node* node, regex_t* reg)
|
|||
|
||||
case N_BACKREF:
|
||||
{
|
||||
int i;
|
||||
BackrefNode* br = &(NBACKREF(node));
|
||||
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
if (IS_BACKREF_NEST_LEVEL(br)) {
|
||||
r = add_opcode(reg, OP_BACKREF_AT_LEVEL);
|
||||
if (r) return r;
|
||||
r = add_option(reg, (reg->options & ONIG_OPTION_IGNORECASE));
|
||||
if (r) return r;
|
||||
r = add_length(reg, br->nest_level);
|
||||
if (r) return r;
|
||||
|
||||
goto add_bacref_mems;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (br->back_num == 1) {
|
||||
n = br->back_static[0];
|
||||
if (IS_IGNORECASE(reg->options)) {
|
||||
|
@ -1405,17 +1424,19 @@ compile_tree(Node* node, regex_t* reg)
|
|||
}
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
int* p;
|
||||
|
||||
if (IS_IGNORECASE(reg->options)) {
|
||||
add_opcode(reg, OP_BACKREF_MULTI_IC);
|
||||
r = add_opcode(reg, OP_BACKREF_MULTI_IC);
|
||||
}
|
||||
else {
|
||||
add_opcode(reg, OP_BACKREF_MULTI);
|
||||
r = add_opcode(reg, OP_BACKREF_MULTI);
|
||||
}
|
||||
|
||||
if (r) return r;
|
||||
add_length(reg, br->back_num);
|
||||
|
||||
add_bacref_mems:
|
||||
r = add_length(reg, br->back_num);
|
||||
if (r) return r;
|
||||
p = BACKREFS_P(br);
|
||||
for (i = br->back_num - 1; i >= 0; i--) {
|
||||
|
@ -3088,6 +3109,11 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
|
|||
if (p[i] > env->num_mem) return ONIGERR_INVALID_BACKREF;
|
||||
BIT_STATUS_ON_AT(env->backrefed_mem, p[i]);
|
||||
BIT_STATUS_ON_AT(env->bt_mem_start, p[i]);
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
if (IS_BACKREF_NEST_LEVEL(br)) {
|
||||
BIT_STATUS_ON_AT(env->bt_mem_end, p[i]);
|
||||
}
|
||||
#endif
|
||||
SET_EFFECT_STATUS(nodes[p[i]], NST_MEM_BACKREFED);
|
||||
}
|
||||
}
|
||||
|
@ -3235,11 +3261,9 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
|
|||
#define ALLOWED_EFFECT_IN_LB_NOT 0
|
||||
|
||||
#define ALLOWED_ANCHOR_IN_LB \
|
||||
( ANCHOR_LOOK_BEHIND | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF )
|
||||
( ANCHOR_LOOK_BEHIND | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION )
|
||||
#define ALLOWED_ANCHOR_IN_LB_NOT \
|
||||
( ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF )
|
||||
/* can't allow all anchors, because \G in look-behind through Search().
|
||||
ex. /(?<=\G)zz/.match("azz") => success. */
|
||||
( ANCHOR_LOOK_BEHIND_NOT | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION )
|
||||
|
||||
case ANCHOR_LOOK_BEHIND:
|
||||
{
|
||||
|
@ -3576,9 +3600,10 @@ copy_opt_exact_info(OptExactInfo* to, OptExactInfo* from)
|
|||
}
|
||||
|
||||
static void
|
||||
concat_opt_exact_info(OptExactInfo* to, OptExactInfo* add)
|
||||
concat_opt_exact_info(OptExactInfo* to, OptExactInfo* add, OnigEncoding enc)
|
||||
{
|
||||
int i, n;
|
||||
int i, j, len;
|
||||
UChar *p, *end;
|
||||
OptAncInfo tanc;
|
||||
|
||||
if (! to->ignore_case && add->ignore_case) {
|
||||
|
@ -3587,11 +3612,17 @@ concat_opt_exact_info(OptExactInfo* to, OptExactInfo* add)
|
|||
to->ignore_case = 1;
|
||||
}
|
||||
|
||||
for (i = to->len, n = 0; n < add->len && i < OPT_EXACT_MAXLEN; i++, n++)
|
||||
to->s[i] = add->s[n];
|
||||
p = add->s;
|
||||
end = p + add->len;
|
||||
for (i = to->len; p < end; ) {
|
||||
len = enc_len(enc, p);
|
||||
if (i + len > OPT_EXACT_MAXLEN) break;
|
||||
for (j = 0; j < len && p < end; j++)
|
||||
to->s[i++] = *p++;
|
||||
}
|
||||
|
||||
to->len = i;
|
||||
to->reach_end = (n == add->len ? add->reach_end : 0);
|
||||
to->reach_end = (p == end ? add->reach_end : 0);
|
||||
|
||||
concat_opt_anc_info(&tanc, &to->anc, &add->anc, 1, 1);
|
||||
if (! to->reach_end) tanc.right_anchor = 0;
|
||||
|
@ -3606,15 +3637,10 @@ concat_opt_exact_info_str(OptExactInfo* to,
|
|||
UChar *p;
|
||||
|
||||
for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
|
||||
if (raw) {
|
||||
len = enc_len(enc, p);
|
||||
if (i + len > OPT_EXACT_MAXLEN) break;
|
||||
for (j = 0; j < len && p < end; j++)
|
||||
to->s[i++] = *p++;
|
||||
}
|
||||
else {
|
||||
len = enc_len(enc, p);
|
||||
if (i + len > OPT_EXACT_MAXLEN) break;
|
||||
for (j = 0; j < len; j++)
|
||||
to->s[i++] = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
to->len = i;
|
||||
|
@ -3879,11 +3905,11 @@ concat_left_node_opt_info(OnigEncoding enc, NodeOptInfo* to, NodeOptInfo* add)
|
|||
|
||||
if (add->exb.len > 0) {
|
||||
if (exb_reach) {
|
||||
concat_opt_exact_info(&to->exb, &add->exb);
|
||||
concat_opt_exact_info(&to->exb, &add->exb, enc);
|
||||
clear_opt_exact_info(&add->exb);
|
||||
}
|
||||
else if (exm_reach) {
|
||||
concat_opt_exact_info(&to->exm, &add->exb);
|
||||
concat_opt_exact_info(&to->exm, &add->exb, enc);
|
||||
clear_opt_exact_info(&add->exb);
|
||||
}
|
||||
}
|
||||
|
@ -4182,7 +4208,7 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
|
|||
if (nopt.exb.reach_end) {
|
||||
for (i = 2; i < qn->lower &&
|
||||
! is_full_opt_exact_info(&opt->exb); i++) {
|
||||
concat_opt_exact_info(&opt->exb, &nopt.exb);
|
||||
concat_opt_exact_info(&opt->exb, &nopt.exb, env->enc);
|
||||
}
|
||||
if (i < qn->lower) {
|
||||
opt->exb.reach_end = 0;
|
||||
|
@ -4593,7 +4619,6 @@ onig_chain_reduce(regex_t* reg)
|
|||
{
|
||||
regex_t *head, *prev;
|
||||
|
||||
THREAD_ATOMIC_START;
|
||||
prev = reg;
|
||||
head = prev->chain;
|
||||
if (IS_NOT_NULL(head)) {
|
||||
|
@ -4605,7 +4630,6 @@ onig_chain_reduce(regex_t* reg)
|
|||
prev->chain = (regex_t* )NULL;
|
||||
REGEX_TRANSFER(reg, head);
|
||||
}
|
||||
THREAD_ATOMIC_END;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -4844,6 +4868,7 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
|
|||
return r;
|
||||
}
|
||||
|
||||
#ifdef USE_RECOMPILE_API
|
||||
extern int
|
||||
onig_recompile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
|
||||
OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax,
|
||||
|
@ -4862,6 +4887,7 @@ onig_recompile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int onig_inited = 0;
|
||||
|
||||
|
@ -4965,14 +4991,14 @@ onig_end()
|
|||
onig_print_statistics(stderr);
|
||||
#endif
|
||||
|
||||
#ifdef USE_RECYCLE_NODE
|
||||
onig_free_node_list();
|
||||
#endif
|
||||
|
||||
#ifdef USE_SHARED_CCLASS_TABLE
|
||||
onig_free_shared_cclass_table();
|
||||
#endif
|
||||
|
||||
#ifdef USE_RECYCLE_NODE
|
||||
onig_free_node_list();
|
||||
#endif
|
||||
|
||||
onig_inited = 0;
|
||||
|
||||
THREAD_ATOMIC_END;
|
||||
|
@ -5026,35 +5052,36 @@ OnigOpInfoType OnigOpInfo[] = {
|
|||
{ OP_END_LINE, "end-line", ARG_NON },
|
||||
{ OP_SEMI_END_BUF, "semi-end-buf", ARG_NON },
|
||||
{ OP_BEGIN_POSITION, "begin-position", ARG_NON },
|
||||
{ OP_BACKREF1, "backref1", ARG_NON },
|
||||
{ OP_BACKREF2, "backref2", ARG_NON },
|
||||
{ OP_BACKREF3, "backref3", ARG_NON },
|
||||
{ OP_BACKREFN, "backrefn", ARG_MEMNUM },
|
||||
{ OP_BACKREFN_IC, "backrefn-ic", ARG_SPECIAL },
|
||||
{ OP_BACKREF_MULTI, "backref_multi", ARG_SPECIAL },
|
||||
{ OP_BACKREF_MULTI_IC, "backref_multi-ic",ARG_SPECIAL },
|
||||
{ OP_MEMORY_START_PUSH, "mem-start-push", ARG_MEMNUM },
|
||||
{ OP_MEMORY_START, "mem-start", ARG_MEMNUM },
|
||||
{ OP_BACKREF1, "backref1", ARG_NON },
|
||||
{ OP_BACKREF2, "backref2", ARG_NON },
|
||||
{ OP_BACKREF3, "backref3", ARG_NON },
|
||||
{ OP_BACKREFN, "backrefn", ARG_MEMNUM },
|
||||
{ OP_BACKREFN_IC, "backrefn-ic", ARG_SPECIAL },
|
||||
{ OP_BACKREF_MULTI, "backref_multi", ARG_SPECIAL },
|
||||
{ OP_BACKREF_MULTI_IC, "backref_multi-ic", ARG_SPECIAL },
|
||||
{ OP_BACKREF_AT_LEVEL, "backref_at_level", ARG_SPECIAL },
|
||||
{ OP_MEMORY_START_PUSH, "mem-start-push", ARG_MEMNUM },
|
||||
{ OP_MEMORY_START, "mem-start", ARG_MEMNUM },
|
||||
{ OP_MEMORY_END_PUSH, "mem-end-push", ARG_MEMNUM },
|
||||
{ OP_MEMORY_END_PUSH_REC, "mem-end-push-rec", ARG_MEMNUM },
|
||||
{ OP_MEMORY_END, "mem-end", ARG_MEMNUM },
|
||||
{ OP_MEMORY_END_REC, "mem-end-rec", ARG_MEMNUM },
|
||||
{ OP_SET_OPTION_PUSH, "set-option-push", ARG_OPTION },
|
||||
{ OP_SET_OPTION, "set-option", ARG_OPTION },
|
||||
{ OP_FAIL, "fail", ARG_NON },
|
||||
{ OP_JUMP, "jump", ARG_RELADDR },
|
||||
{ OP_PUSH, "push", ARG_RELADDR },
|
||||
{ OP_POP, "pop", ARG_NON },
|
||||
{ OP_PUSH_OR_JUMP_EXACT1, "push-or-jump-e1", ARG_SPECIAL },
|
||||
{ OP_PUSH_IF_PEEK_NEXT, "push-if-peek-next", ARG_SPECIAL },
|
||||
{ OP_REPEAT, "repeat", ARG_SPECIAL },
|
||||
{ OP_REPEAT_NG, "repeat-ng", ARG_SPECIAL },
|
||||
{ OP_REPEAT_INC, "repeat-inc", ARG_MEMNUM },
|
||||
{ OP_REPEAT_INC_NG, "repeat-inc-ng", ARG_MEMNUM },
|
||||
{ OP_REPEAT_INC_SG, "repeat-inc-sg", ARG_MEMNUM },
|
||||
{ OP_REPEAT_INC_NG_SG, "repeat-inc-ng-sg", ARG_MEMNUM },
|
||||
{ OP_NULL_CHECK_START, "null-check-start",ARG_MEMNUM },
|
||||
{ OP_NULL_CHECK_END, "null-check-end", ARG_MEMNUM },
|
||||
{ OP_SET_OPTION_PUSH, "set-option-push", ARG_OPTION },
|
||||
{ OP_SET_OPTION, "set-option", ARG_OPTION },
|
||||
{ OP_FAIL, "fail", ARG_NON },
|
||||
{ OP_JUMP, "jump", ARG_RELADDR },
|
||||
{ OP_PUSH, "push", ARG_RELADDR },
|
||||
{ OP_POP, "pop", ARG_NON },
|
||||
{ OP_PUSH_OR_JUMP_EXACT1, "push-or-jump-e1", ARG_SPECIAL },
|
||||
{ OP_PUSH_IF_PEEK_NEXT, "push-if-peek-next", ARG_SPECIAL },
|
||||
{ OP_REPEAT, "repeat", ARG_SPECIAL },
|
||||
{ OP_REPEAT_NG, "repeat-ng", ARG_SPECIAL },
|
||||
{ OP_REPEAT_INC, "repeat-inc", ARG_MEMNUM },
|
||||
{ OP_REPEAT_INC_NG, "repeat-inc-ng", ARG_MEMNUM },
|
||||
{ OP_REPEAT_INC_SG, "repeat-inc-sg", ARG_MEMNUM },
|
||||
{ OP_REPEAT_INC_NG_SG, "repeat-inc-ng-sg", ARG_MEMNUM },
|
||||
{ OP_NULL_CHECK_START, "null-check-start", ARG_MEMNUM },
|
||||
{ OP_NULL_CHECK_END, "null-check-end", ARG_MEMNUM },
|
||||
{ OP_NULL_CHECK_END_MEMST,"null-check-end-memst", ARG_MEMNUM },
|
||||
{ OP_NULL_CHECK_END_MEMST_PUSH,"null-check-end-memst-push", ARG_MEMNUM },
|
||||
{ OP_PUSH_POS, "push-pos", ARG_NON },
|
||||
|
@ -5286,6 +5313,26 @@ onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar** nextp,
|
|||
}
|
||||
break;
|
||||
|
||||
case OP_BACKREF_AT_LEVEL:
|
||||
{
|
||||
OnigOptionType option;
|
||||
LengthType level;
|
||||
|
||||
GET_OPTION_INC(option, bp);
|
||||
fprintf(f, ":%d", option);
|
||||
GET_LENGTH_INC(level, bp);
|
||||
fprintf(f, ":%d", level);
|
||||
|
||||
fputs(" ", f);
|
||||
GET_LENGTH_INC(len, bp);
|
||||
for (i = 0; i < len; i++) {
|
||||
GET_MEMNUM_INC(mem, bp);
|
||||
if (i > 0) fputs(", ", f);
|
||||
fprintf(f, "%d", mem);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_REPEAT:
|
||||
case OP_REPEAT_NG:
|
||||
{
|
||||
|
|
|
@ -276,7 +276,7 @@ onig_snprintf_with_pattern(buf, bufsize, enc, pat, pat_end, fmt, va_alist)
|
|||
UChar bs[6];
|
||||
va_list args;
|
||||
|
||||
va_init_list(args, (const char* )fmt);
|
||||
va_init_list(args, fmt);
|
||||
n = vsnprintf((char* )buf, bufsize, (const char* )fmt, args);
|
||||
va_end(args);
|
||||
|
||||
|
|
230
regexec.c
230
regexec.c
|
@ -610,15 +610,18 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
|
||||
|
||||
#ifdef ONIG_DEBUG
|
||||
#define STACK_BASE_CHECK(p) \
|
||||
if ((p) < stk_base) goto stack_error;
|
||||
#define STACK_BASE_CHECK(p, at) \
|
||||
if ((p) < stk_base) {\
|
||||
fprintf(stderr, "at %s\n", at);\
|
||||
goto stack_error;\
|
||||
}
|
||||
#else
|
||||
#define STACK_BASE_CHECK(p)
|
||||
#define STACK_BASE_CHECK(p, at)
|
||||
#endif
|
||||
|
||||
#define STACK_POP_ONE do {\
|
||||
stk--;\
|
||||
STACK_BASE_CHECK(stk); \
|
||||
STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \
|
||||
} while(0)
|
||||
|
||||
#define STACK_POP do {\
|
||||
|
@ -626,14 +629,14 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
case STACK_POP_LEVEL_FREE:\
|
||||
while (1) {\
|
||||
stk--;\
|
||||
STACK_BASE_CHECK(stk); \
|
||||
STACK_BASE_CHECK(stk, "STACK_POP"); \
|
||||
if ((stk->type & STK_MASK_POP_USED) != 0) break;\
|
||||
}\
|
||||
break;\
|
||||
case STACK_POP_LEVEL_MEM_START:\
|
||||
while (1) {\
|
||||
stk--;\
|
||||
STACK_BASE_CHECK(stk); \
|
||||
STACK_BASE_CHECK(stk, "STACK_POP 2"); \
|
||||
if ((stk->type & STK_MASK_POP_USED) != 0) break;\
|
||||
else if (stk->type == STK_MEM_START) {\
|
||||
mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
|
||||
|
@ -644,7 +647,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
default:\
|
||||
while (1) {\
|
||||
stk--;\
|
||||
STACK_BASE_CHECK(stk); \
|
||||
STACK_BASE_CHECK(stk, "STACK_POP 3"); \
|
||||
if ((stk->type & STK_MASK_POP_USED) != 0) break;\
|
||||
else if (stk->type == STK_MEM_START) {\
|
||||
mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
|
||||
|
@ -665,7 +668,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
#define STACK_POP_TIL_POS_NOT do {\
|
||||
while (1) {\
|
||||
stk--;\
|
||||
STACK_BASE_CHECK(stk); \
|
||||
STACK_BASE_CHECK(stk, "STACK_POP_TIL_POS_NOT"); \
|
||||
if (stk->type == STK_POS_NOT) break;\
|
||||
else if (stk->type == STK_MEM_START) {\
|
||||
mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
|
||||
|
@ -684,7 +687,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
#define STACK_POP_TIL_LOOK_BEHIND_NOT do {\
|
||||
while (1) {\
|
||||
stk--;\
|
||||
STACK_BASE_CHECK(stk); \
|
||||
STACK_BASE_CHECK(stk, "STACK_POP_TIL_LOOK_BEHIND_NOT"); \
|
||||
if (stk->type == STK_LOOK_BEHIND_NOT) break;\
|
||||
else if (stk->type == STK_MEM_START) {\
|
||||
mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
|
||||
|
@ -704,7 +707,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
k = stk;\
|
||||
while (1) {\
|
||||
k--;\
|
||||
STACK_BASE_CHECK(k); \
|
||||
STACK_BASE_CHECK(k, "STACK_POS_END"); \
|
||||
if (IS_TO_VOID_TARGET(k)) {\
|
||||
k->type = STK_VOID;\
|
||||
}\
|
||||
|
@ -719,7 +722,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
StackType *k = stk;\
|
||||
while (1) {\
|
||||
k--;\
|
||||
STACK_BASE_CHECK(k); \
|
||||
STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \
|
||||
if (IS_TO_VOID_TARGET(k)) {\
|
||||
k->type = STK_VOID;\
|
||||
}\
|
||||
|
@ -734,7 +737,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
StackType* k = stk;\
|
||||
while (1) {\
|
||||
k--;\
|
||||
STACK_BASE_CHECK(k); \
|
||||
STACK_BASE_CHECK(k, "STACK_NULL_CHECK"); \
|
||||
if (k->type == STK_NULL_CHECK_START) {\
|
||||
if (k->u.null_check.num == (id)) {\
|
||||
(isnull) = (k->u.null_check.pstr == (s));\
|
||||
|
@ -749,7 +752,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
StackType* k = stk;\
|
||||
while (1) {\
|
||||
k--;\
|
||||
STACK_BASE_CHECK(k); \
|
||||
STACK_BASE_CHECK(k, "STACK_NULL_CHECK_REC"); \
|
||||
if (k->type == STK_NULL_CHECK_START) {\
|
||||
if (k->u.null_check.num == (id)) {\
|
||||
if (level == 0) {\
|
||||
|
@ -769,7 +772,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
StackType* k = stk;\
|
||||
while (1) {\
|
||||
k--;\
|
||||
STACK_BASE_CHECK(k); \
|
||||
STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST"); \
|
||||
if (k->type == STK_NULL_CHECK_START) {\
|
||||
if (k->u.null_check.num == (id)) {\
|
||||
if (k->u.null_check.pstr != (s)) {\
|
||||
|
@ -809,7 +812,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
StackType* k = stk;\
|
||||
while (1) {\
|
||||
k--;\
|
||||
STACK_BASE_CHECK(k); \
|
||||
STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST_REC"); \
|
||||
if (k->type == STK_NULL_CHECK_START) {\
|
||||
if (k->u.null_check.num == (id)) {\
|
||||
if (level == 0) {\
|
||||
|
@ -857,7 +860,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
k = stk;\
|
||||
while (1) {\
|
||||
k--;\
|
||||
STACK_BASE_CHECK(k); \
|
||||
STACK_BASE_CHECK(k, "STACK_GET_REPEAT"); \
|
||||
if (k->type == STK_REPEAT) {\
|
||||
if (level == 0) {\
|
||||
if (k->u.repeat.num == (id)) {\
|
||||
|
@ -875,7 +878,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
|
|||
StackType* k = stk;\
|
||||
while (1) {\
|
||||
k--;\
|
||||
STACK_BASE_CHECK(k); \
|
||||
STACK_BASE_CHECK(k, "STACK_RETURN"); \
|
||||
if (k->type == STK_CALL_FRAME) {\
|
||||
if (level == 0) {\
|
||||
(addr) = k->u.call_frame.ret_addr;\
|
||||
|
@ -995,6 +998,77 @@ make_capture_history_tree(OnigCaptureTreeNode* node, StackType** kp,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
static int mem_is_in_memp(int mem, int num, UChar* memp)
|
||||
{
|
||||
int i;
|
||||
MemNumType m;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
GET_MEMNUM_INC(m, memp);
|
||||
if (mem == (int )m) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int backref_match_at_nested_level(regex_t* reg
|
||||
, StackType* top, StackType* stk_base
|
||||
, int ignore_case, int ambig_flag
|
||||
, int nest, int mem_num, UChar* memp, UChar** s, const UChar* send)
|
||||
{
|
||||
UChar *ss, *p, *pstart, *pend = NULL_UCHARP;
|
||||
int level;
|
||||
StackType* k;
|
||||
|
||||
level = 0;
|
||||
k = top;
|
||||
k--;
|
||||
while (k >= stk_base) {
|
||||
if (k->type == STK_CALL_FRAME) {
|
||||
level--;
|
||||
}
|
||||
else if (k->type == STK_RETURN) {
|
||||
level++;
|
||||
}
|
||||
else if (level == nest) {
|
||||
if (k->type == STK_MEM_START) {
|
||||
if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
|
||||
pstart = k->u.mem.pstr;
|
||||
if (pend != NULL_UCHARP) {
|
||||
if (pend - pstart > send - *s) return 0; /* or goto next_mem; */
|
||||
p = pstart;
|
||||
ss = *s;
|
||||
|
||||
if (ignore_case != 0) {
|
||||
if (string_cmp_ic(reg->enc, ambig_flag,
|
||||
pstart, &ss, (int )(pend - pstart)) == 0)
|
||||
return 0; /* or goto next_mem; */
|
||||
}
|
||||
else {
|
||||
while (p < pend) {
|
||||
if (*p++ != *ss++) return 0; /* or goto next_mem; */
|
||||
}
|
||||
}
|
||||
|
||||
*s = ss;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (k->type == STK_MEM_END) {
|
||||
if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
|
||||
pend = k->u.mem.pstr;
|
||||
}
|
||||
}
|
||||
}
|
||||
k--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_BACKREF_AT_LEVEL */
|
||||
|
||||
|
||||
#ifdef RUBY_PLATFORM
|
||||
|
||||
typedef struct {
|
||||
|
@ -1010,7 +1084,7 @@ trap_ensure(VALUE arg)
|
|||
TrapEnsureArg* ta = (TrapEnsureArg* )arg;
|
||||
|
||||
if (ta->state == 0) { /* trap_exec() is not normal return */
|
||||
ONIG_STATE_DEC(ta->reg);
|
||||
ONIG_STATE_DEC_THREAD(ta->reg);
|
||||
if (! IS_NULL(ta->msa->stack_p) && ta->stk_base != ta->msa->stack_p)
|
||||
xfree(ta->stk_base);
|
||||
|
||||
|
@ -2227,6 +2301,35 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
|
|||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
case OP_BACKREF_AT_LEVEL:
|
||||
{
|
||||
int len;
|
||||
OnigOptionType ic;
|
||||
LengthType level;
|
||||
|
||||
GET_OPTION_INC(ic, p);
|
||||
GET_LENGTH_INC(level, p);
|
||||
GET_LENGTH_INC(tlen, p);
|
||||
|
||||
sprev = s;
|
||||
if (backref_match_at_nested_level(reg, stk, stk_base, ic, ambig_flag
|
||||
, (int )level, (int )tlen, p, &s, end)) {
|
||||
while (sprev + (len = enc_len(encode, sprev)) < s)
|
||||
sprev += len;
|
||||
|
||||
p += (SIZE_MEMNUM * tlen);
|
||||
}
|
||||
else
|
||||
goto fail;
|
||||
|
||||
STAT_OP_OUT;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
case OP_SET_OPTION_PUSH: STAT_OP_IN(OP_SET_OPTION_PUSH);
|
||||
GET_OPTION_INC(option, p);
|
||||
|
@ -2766,66 +2869,56 @@ bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
|
|||
const UChar* text, const UChar* text_end,
|
||||
const UChar* text_range)
|
||||
{
|
||||
const UChar *s, *t, *p, *end;
|
||||
const UChar *s, *se, *t, *p, *end;
|
||||
const UChar *tail;
|
||||
int skip;
|
||||
int skip, tlen1;
|
||||
|
||||
#ifdef ONIG_DEBUG_SEARCH
|
||||
fprintf(stderr, "bm_search_notrev: text: %d, text_end: %d, text_range: %d\n",
|
||||
(int )text, (int )text_end, (int )text_range);
|
||||
#endif
|
||||
|
||||
end = text_range + (target_end - target) - 1;
|
||||
tlen1 = (target_end - target) - 1;
|
||||
end = text_range + tlen1;
|
||||
if (end > text_end)
|
||||
end = text_end;
|
||||
|
||||
tail = target_end - 1;
|
||||
s = text;
|
||||
while ((s - text) < target_end - target) {
|
||||
s += enc_len(reg->enc, s);
|
||||
}
|
||||
s--; /* set to text check tail position. */
|
||||
|
||||
if (IS_NULL(reg->int_map)) {
|
||||
while (s < end) {
|
||||
p = s;
|
||||
p = se = s + tlen1;
|
||||
t = tail;
|
||||
while (t >= target && *p == *t) {
|
||||
p--; t--;
|
||||
while (*p == *t && t >= target) {
|
||||
p--; t--;
|
||||
}
|
||||
if (t < target) return (UChar* )(p + 1);
|
||||
if (t < target) return (UChar* )s;
|
||||
|
||||
skip = reg->map[*s];
|
||||
p = s + 1;
|
||||
if (p >= text_end) return (UChar* )NULL;
|
||||
t = p;
|
||||
skip = reg->map[*se];
|
||||
t = s;
|
||||
do {
|
||||
p += enc_len(reg->enc, p);
|
||||
} while ((p - t) < skip && p < text_end);
|
||||
|
||||
s += (p - t);
|
||||
s += enc_len(reg->enc, s);
|
||||
} while ((s - t) < skip && s < end);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (s < end) {
|
||||
p = s;
|
||||
p = se = s + tlen1;
|
||||
t = tail;
|
||||
while (t >= target && *p == *t) {
|
||||
p--; t--;
|
||||
while (*p == *t && t >= target) {
|
||||
p--; t--;
|
||||
}
|
||||
if (t < target) return (UChar* )(p + 1);
|
||||
if (t < target) return (UChar* )s;
|
||||
|
||||
skip = reg->int_map[*s];
|
||||
p = s + 1;
|
||||
if (p >= text_end) return (UChar* )NULL;
|
||||
t = p;
|
||||
skip = reg->int_map[*se];
|
||||
t = s;
|
||||
do {
|
||||
p += enc_len(reg->enc, p);
|
||||
} while ((p - t) < skip && p < text_end);
|
||||
|
||||
s += (p - t);
|
||||
s += enc_len(reg->enc, s);
|
||||
} while ((s - t) < skip && s < end);
|
||||
}
|
||||
}
|
||||
|
||||
return (UChar* )NULL;
|
||||
}
|
||||
|
||||
|
@ -2954,7 +3047,9 @@ onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, On
|
|||
UChar *prev;
|
||||
MatchArg msa;
|
||||
|
||||
#ifdef USE_MULTI_THREAD_SYSTEM
|
||||
#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
|
||||
start:
|
||||
THREAD_ATOMIC_START;
|
||||
if (ONIG_STATE(reg) >= ONIG_STATE_NORMAL) {
|
||||
ONIG_STATE_INC(reg);
|
||||
if (IS_NOT_NULL(reg->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {
|
||||
|
@ -2963,15 +3058,19 @@ onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, On
|
|||
}
|
||||
}
|
||||
else {
|
||||
int n = 0;
|
||||
int n;
|
||||
|
||||
THREAD_ATOMIC_END;
|
||||
n = 0;
|
||||
while (ONIG_STATE(reg) < ONIG_STATE_NORMAL) {
|
||||
if (++n > THREAD_PASS_LIMIT_COUNT)
|
||||
return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;
|
||||
THREAD_PASS;
|
||||
}
|
||||
ONIG_STATE_INC(reg);
|
||||
goto start;
|
||||
}
|
||||
#endif /* USE_MULTI_THREAD_SYSTEM */
|
||||
THREAD_ATOMIC_END;
|
||||
#endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
|
||||
|
||||
MATCH_ARG_INIT(msa, option, region, at);
|
||||
|
||||
|
@ -2991,7 +3090,7 @@ onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, On
|
|||
}
|
||||
|
||||
MATCH_ARG_FREE(msa);
|
||||
ONIG_STATE_DEC(reg);
|
||||
ONIG_STATE_DEC_THREAD(reg);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -3234,8 +3333,11 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
|
|||
int r;
|
||||
UChar *s, *prev;
|
||||
MatchArg msa;
|
||||
const UChar *orig_start = start;
|
||||
|
||||
#ifdef USE_MULTI_THREAD_SYSTEM
|
||||
#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
|
||||
start:
|
||||
THREAD_ATOMIC_START;
|
||||
if (ONIG_STATE(reg) >= ONIG_STATE_NORMAL) {
|
||||
ONIG_STATE_INC(reg);
|
||||
if (IS_NOT_NULL(reg->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {
|
||||
|
@ -3244,15 +3346,19 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
|
|||
}
|
||||
}
|
||||
else {
|
||||
int n = 0;
|
||||
int n;
|
||||
|
||||
THREAD_ATOMIC_END;
|
||||
n = 0;
|
||||
while (ONIG_STATE(reg) < ONIG_STATE_NORMAL) {
|
||||
if (++n > THREAD_PASS_LIMIT_COUNT)
|
||||
return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;
|
||||
THREAD_PASS;
|
||||
}
|
||||
ONIG_STATE_INC(reg);
|
||||
goto start;
|
||||
}
|
||||
#endif /* USE_MULTI_THREAD_SYSTEM */
|
||||
THREAD_ATOMIC_END;
|
||||
#endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
|
||||
|
||||
#ifdef ONIG_DEBUG_SEARCH
|
||||
fprintf(stderr,
|
||||
|
@ -3380,7 +3486,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
|
|||
(int )(end - str), (int )(start - str), (int )(range - str));
|
||||
#endif
|
||||
|
||||
MATCH_ARG_INIT(msa, option, region, start);
|
||||
MATCH_ARG_INIT(msa, option, region, orig_start);
|
||||
|
||||
s = (UChar* )start;
|
||||
if (range > start) { /* forward search */
|
||||
|
@ -3512,7 +3618,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
|
|||
|
||||
finish:
|
||||
MATCH_ARG_FREE(msa);
|
||||
ONIG_STATE_DEC(reg);
|
||||
ONIG_STATE_DEC_THREAD(reg);
|
||||
|
||||
/* If result is mismatch and no FIND_NOT_EMPTY option,
|
||||
then the region is not setted in match_at(). */
|
||||
|
@ -3533,7 +3639,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
|
|||
mismatch_no_msa:
|
||||
r = ONIG_MISMATCH;
|
||||
finish_no_msa:
|
||||
ONIG_STATE_DEC(reg);
|
||||
ONIG_STATE_DEC_THREAD(reg);
|
||||
#ifdef ONIG_DEBUG
|
||||
if (r != ONIG_MISMATCH)
|
||||
fprintf(stderr, "onig_search: error %d\n", r);
|
||||
|
@ -3541,7 +3647,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
|
|||
return r;
|
||||
|
||||
match:
|
||||
ONIG_STATE_DEC(reg);
|
||||
ONIG_STATE_DEC_THREAD(reg);
|
||||
MATCH_ARG_FREE(msa);
|
||||
return s - str;
|
||||
}
|
||||
|
|
29
regint.h
29
regint.h
|
@ -59,9 +59,11 @@
|
|||
/* #define USE_UNICODE_FULL_RANGE_CTYPE */ /* --> move to regenc.h */
|
||||
#define USE_NAMED_GROUP
|
||||
#define USE_SUBEXP_CALL
|
||||
/* #define USE_BACKREF_AT_LEVEL */
|
||||
#define USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK /* /(?:()|())*\2/ */
|
||||
#define USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE /* /\n$/ =~ "\n" */
|
||||
#define USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
|
||||
/* #define USE_RECOMPILE_API */
|
||||
/* treat \r\n as line terminator.
|
||||
!!! NO SUPPORT !!!
|
||||
use this configuration on your own responsibility */
|
||||
|
@ -80,6 +82,7 @@
|
|||
/* interface to external system */
|
||||
#ifdef NOT_RUBY /* given from Makefile */
|
||||
#include "config.h"
|
||||
#define USE_BACKREF_AT_LEVEL
|
||||
#define USE_CAPTURE_HISTORY
|
||||
#define USE_VARIABLE_META_CHARS
|
||||
#define USE_WORD_BEGIN_END /* "\<": word-begin, "\>": word-end */
|
||||
|
@ -129,13 +132,26 @@
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef USE_MULTI_THREAD_SYSTEM
|
||||
#define ONIG_STATE_INC(reg) (reg)->state++
|
||||
#define ONIG_STATE_DEC(reg) (reg)->state--
|
||||
#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
|
||||
#define ONIG_STATE_INC(reg) (reg)->state++
|
||||
#define ONIG_STATE_DEC(reg) (reg)->state--
|
||||
|
||||
#define ONIG_STATE_INC_THREAD(reg) do {\
|
||||
THREAD_ATOMIC_START;\
|
||||
(reg)->state++;\
|
||||
THREAD_ATOMIC_END;\
|
||||
} while(0)
|
||||
#define ONIG_STATE_DEC_THREAD(reg) do {\
|
||||
THREAD_ATOMIC_START;\
|
||||
(reg)->state--;\
|
||||
THREAD_ATOMIC_END;\
|
||||
} while(0)
|
||||
#else
|
||||
#define ONIG_STATE_INC(reg) /* Nothing */
|
||||
#define ONIG_STATE_DEC(reg) /* Nothing */
|
||||
#endif /* USE_MULTI_THREAD_SYSTEM */
|
||||
#define ONIG_STATE_INC(reg) /* Nothing */
|
||||
#define ONIG_STATE_DEC(reg) /* Nothing */
|
||||
#define ONIG_STATE_INC_THREAD(reg) /* Nothing */
|
||||
#define ONIG_STATE_DEC_THREAD(reg) /* Nothing */
|
||||
#endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
|
||||
|
||||
|
||||
#define onig_st_is_member st_is_member
|
||||
|
@ -584,6 +600,7 @@ enum OpCode {
|
|||
OP_BACKREFN_IC,
|
||||
OP_BACKREF_MULTI,
|
||||
OP_BACKREF_MULTI_IC,
|
||||
OP_BACKREF_AT_LEVEL, /* \k<xxx+n>, \k<xxx-n> */
|
||||
|
||||
OP_MEMORY_START,
|
||||
OP_MEMORY_START_PUSH, /* push back-tracker to stack */
|
||||
|
|
125
regparse.c
125
regparse.c
|
@ -1085,13 +1085,13 @@ onig_free_node_list()
|
|||
{
|
||||
FreeNode* n;
|
||||
|
||||
THREAD_ATOMIC_START;
|
||||
/* THREAD_ATOMIC_START; */
|
||||
while (IS_NOT_NULL(FreeNodeList)) {
|
||||
n = FreeNodeList;
|
||||
FreeNodeList = FreeNodeList->next;
|
||||
xfree(n);
|
||||
}
|
||||
THREAD_ATOMIC_END;
|
||||
/* THREAD_ATOMIC_END; */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -1244,7 +1244,11 @@ onig_node_new_anchor(int type)
|
|||
}
|
||||
|
||||
static Node*
|
||||
node_new_backref(int back_num, int* backrefs, int by_name, ScanEnv* env)
|
||||
node_new_backref(int back_num, int* backrefs, int by_name,
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
int exist_level, int nest_level,
|
||||
#endif
|
||||
ScanEnv* env)
|
||||
{
|
||||
int i;
|
||||
Node* node = node_new();
|
||||
|
@ -1257,6 +1261,13 @@ node_new_backref(int back_num, int* backrefs, int by_name, ScanEnv* env)
|
|||
if (by_name != 0)
|
||||
NBACKREF(node).state |= NST_NAME_REF;
|
||||
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
if (exist_level != 0) {
|
||||
NBACKREF(node).state |= NST_NEST_LEVEL;
|
||||
NBACKREF(node).nest_level = nest_level;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < back_num; i++) {
|
||||
if (backrefs[i] <= env->num_mem &&
|
||||
IS_NULL(SCANENV_MEM_NODES(env)[backrefs[i]])) {
|
||||
|
@ -2241,6 +2252,10 @@ typedef struct {
|
|||
int ref1;
|
||||
int* refs;
|
||||
int by_name;
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
int exist_level;
|
||||
int level; /* \k<name+n> */
|
||||
#endif
|
||||
} backref;
|
||||
struct {
|
||||
UChar* name;
|
||||
|
@ -2420,6 +2435,89 @@ fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env)
|
|||
static int fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env);
|
||||
|
||||
#ifdef USE_NAMED_GROUP
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
/*
|
||||
\k<name+n>, \k<name-n>
|
||||
*/
|
||||
static int
|
||||
fetch_name_with_level(UChar** src, UChar* end, UChar** rname_end
|
||||
, ScanEnv* env, int* level)
|
||||
{
|
||||
int r, exist_level = 0;
|
||||
OnigCodePoint c = 0;
|
||||
OnigCodePoint first_code;
|
||||
OnigEncoding enc = env->enc;
|
||||
UChar *name_end;
|
||||
UChar *p = *src;
|
||||
PFETCH_READY;
|
||||
|
||||
name_end = end;
|
||||
r = 0;
|
||||
if (PEND) {
|
||||
return ONIGERR_EMPTY_GROUP_NAME;
|
||||
}
|
||||
else {
|
||||
PFETCH(c);
|
||||
first_code = c;
|
||||
if (c == '>')
|
||||
return ONIGERR_EMPTY_GROUP_NAME;
|
||||
|
||||
if (!ONIGENC_IS_CODE_WORD(enc, c)) {
|
||||
r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
while (!PEND) {
|
||||
name_end = p;
|
||||
PFETCH(c);
|
||||
if (c == '>' || c == ')' || c == '+' || c == '-') break;
|
||||
|
||||
if (!ONIGENC_IS_CODE_WORD(enc, c)) {
|
||||
r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
if (c != '>') {
|
||||
if (c == '+' || c == '-') {
|
||||
int num;
|
||||
int flag = (c == '-' ? -1 : 1);
|
||||
|
||||
PFETCH(c);
|
||||
if (! ONIGENC_IS_CODE_DIGIT(enc, c)) goto err;
|
||||
PUNFETCH;
|
||||
num = onig_scan_unsigned_number(&p, end, enc);
|
||||
if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
|
||||
*level = (num * flag);
|
||||
exist_level = 1;
|
||||
|
||||
PFETCH(c);
|
||||
if (c == '>')
|
||||
goto first_check;
|
||||
}
|
||||
|
||||
err:
|
||||
r = ONIGERR_INVALID_GROUP_NAME;
|
||||
name_end = end;
|
||||
}
|
||||
else {
|
||||
first_check:
|
||||
if (ONIGENC_IS_CODE_ASCII(first_code) &&
|
||||
ONIGENC_IS_CODE_UPPER(enc, first_code))
|
||||
r = ONIGERR_INVALID_GROUP_NAME;
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
*rname_end = name_end;
|
||||
*src = p;
|
||||
return (exist_level ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
onig_scan_env_set_error_string(env, r, *src, name_end);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
#endif /* USE_BACKREF_AT_LEVEL */
|
||||
|
||||
/*
|
||||
def: 0 -> define name (don't allow number name)
|
||||
1 -> reference name (allow number name)
|
||||
|
@ -3132,6 +3230,9 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
|
|||
tok->u.backref.num = 1;
|
||||
tok->u.backref.ref1 = num;
|
||||
tok->u.backref.by_name = 0;
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
tok->u.backref.exist_level = 0;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3170,8 +3271,17 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
|
|||
int* backs;
|
||||
|
||||
prev = p;
|
||||
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
name_end = NULL_UCHARP; /* no need. escape gcc warning. */
|
||||
r = fetch_name_with_level(&p, end, &name_end, env, &tok->u.backref.level);
|
||||
if (r == 1) tok->u.backref.exist_level = 1;
|
||||
else tok->u.backref.exist_level = 0;
|
||||
#else
|
||||
r = fetch_name(&p, end, &name_end, env, 1);
|
||||
#endif
|
||||
if (r < 0) return r;
|
||||
|
||||
num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs);
|
||||
if (num <= 0) {
|
||||
onig_scan_env_set_error_string(env,
|
||||
|
@ -5007,8 +5117,13 @@ parse_exp(Node** np, OnigToken* tok, int term,
|
|||
case TK_BACKREF:
|
||||
len = tok->u.backref.num;
|
||||
*np = node_new_backref(len,
|
||||
(len > 1 ? tok->u.backref.refs : &(tok->u.backref.ref1)),
|
||||
tok->u.backref.by_name, env);
|
||||
(len > 1 ? tok->u.backref.refs : &(tok->u.backref.ref1)),
|
||||
tok->u.backref.by_name,
|
||||
#ifdef USE_BACKREF_AT_LEVEL
|
||||
tok->u.backref.exist_level,
|
||||
tok->u.backref.level,
|
||||
#endif
|
||||
env);
|
||||
CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
|
||||
break;
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
|
||||
#define NODE_STR_MARGIN 16
|
||||
#define NODE_STR_BUF_SIZE 24 /* sizeof(CClassNode) - sizeof(int)*4 */
|
||||
#define NODE_BACKREFS_SIZE 7
|
||||
#define NODE_BACKREFS_SIZE 6
|
||||
|
||||
#define NSTR_RAW (1<<0) /* by backslashed number */
|
||||
#define NSTR_AMBIG (1<<1)
|
||||
|
@ -145,6 +145,7 @@ typedef struct {
|
|||
#define NST_NAMED_GROUP (1<<10)
|
||||
#define NST_NAME_REF (1<<11)
|
||||
#define NST_IN_REPEAT (1<<12) /* STK_REPEAT is nested in stack. */
|
||||
#define NST_NEST_LEVEL (1<<13)
|
||||
|
||||
#define SET_EFFECT_STATUS(node,f) (node)->u.effect.state |= (f)
|
||||
#define CLEAR_EFFECT_STATUS(node,f) (node)->u.effect.state &= ~(f)
|
||||
|
@ -165,6 +166,7 @@ typedef struct {
|
|||
#define IS_CALL_RECURSION(cn) (((cn)->state & NST_RECURSION) != 0)
|
||||
#define IS_CALL_NAME_REF(cn) (((cn)->state & NST_NAME_REF) != 0)
|
||||
#define IS_BACKREF_NAME_REF(bn) (((bn)->state & NST_NAME_REF) != 0)
|
||||
#define IS_BACKREF_NEST_LEVEL(bn) (((bn)->state & NST_NEST_LEVEL) != 0)
|
||||
#define IS_QUALIFIER_IN_REPEAT(qn) (((qn)->state & NST_IN_REPEAT) != 0)
|
||||
|
||||
typedef struct {
|
||||
|
@ -212,6 +214,7 @@ typedef struct {
|
|||
int back_num;
|
||||
int back_static[NODE_BACKREFS_SIZE];
|
||||
int* back_dynamic;
|
||||
int nest_level;
|
||||
} BackrefNode;
|
||||
|
||||
typedef struct {
|
||||
|
|
Загрузка…
Ссылка в новой задаче