From e49e80c0bc76587e2299e1bc950986e436ed791b Mon Sep 17 00:00:00 2001 From: "K.Kosako" Date: Wed, 7 Feb 2018 16:49:18 +0900 Subject: [PATCH] add OP_CALLOUT_NAME --- src/regexec.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++--- src/regint.h | 5 ++ 2 files changed, 138 insertions(+), 6 deletions(-) diff --git a/src/regexec.c b/src/regexec.c index 6ff9811..754f02d 100644 --- a/src/regexec.c +++ b/src/regexec.c @@ -171,6 +171,7 @@ static OpInfoType OpInfo[] = { { OP_PUSH_SAVE_VAL, "push-save-val", ARG_SPECIAL }, { OP_UPDATE_VAR, "update-var", ARG_SPECIAL }, { OP_CALLOUT_CODE, "callout-code", ARG_SPECIAL }, + { OP_CALLOUT_NAME, "callout-name", ARG_SPECIAL }, { -1, "", ARG_NON } }; @@ -493,7 +494,7 @@ onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar** nextp, UChar* start, UChar* code_start; UChar* code_end; - GET_MEMNUM_INC(mem, bp); + GET_MEMNUM_INC(mem, bp); // number GET_MEMNUM_INC(dirs, bp); GET_POINTER_INC(code_start, bp); GET_POINTER_INC(code_end, bp); @@ -502,6 +503,23 @@ onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar** nextp, UChar* start, } break; + case OP_CALLOUT_NAME: + { + int dirs; + int id; + UChar* code_start; + UChar* code_end; + + GET_MEMNUM_INC(id, bp); // id + GET_MEMNUM_INC(mem, bp); // number + GET_MEMNUM_INC(dirs, bp); + GET_POINTER_INC(code_start, bp); + GET_POINTER_INC(code_end, bp); + + fprintf(f, ":%d:%d:%d:%p:%p", id, mem, dirs, code_start, code_end); + } + break; + default: fprintf(stderr, "onig_print_compiled_byte_code: undefined code %d\n", *--bp); } @@ -820,10 +838,31 @@ onig_region_copy(OnigRegion* to, OnigRegion* from) result = (func)((OnigCalloutArgs* )&args, user);\ } while (0) -#define RETRACTION_CALLOUT_CODE(func, anum, cstart, cend, user) do {\ +#define CALLOUT_BODY(func, ain, aof, aid, anum, cstart, cend, user, args, result) do { \ + args.in = (ain);\ + args.of = (aof);\ + args.id = (aid);\ + args.num = anum;\ + args.content = cstart;\ + args.content_end = cend;\ + args.regex = reg;\ + args.subject = str;\ + args.subject_end = end;\ + args.start = sstart;\ + args.right_range = right_range;\ + args.current = s;\ + args.try_in_match_counter = try_in_match_counter;\ + args.stk_base = stk_base;\ + args.stk = stk;\ + args.mem_start_stk = mem_start_stk;\ + args.mem_end_stk = mem_end_stk;\ + result = (func)((OnigCalloutArgs* )&args, user);\ +} while (0) + +#define RETRACTION_CALLOUT(func, aof, aid, anum, cstart, cend, user) do {\ int result;\ CalloutArgs args;\ - CALLOUT_CODE_BODY(func, ONIG_CALLOUT_IN_RETRACTION, anum, cstart, cend, user, args, result);\ + CALLOUT_BODY(func, ONIG_CALLOUT_IN_RETRACTION, aof, aid, anum, cstart, cend, user, args, result);\ switch (result) {\ case ONIG_CALLOUT_FAIL:\ goto fail;\ @@ -1412,9 +1451,20 @@ stack_double(int is_alloca, char** arg_alloc_base, }\ } while (0) -#define STACK_PUSH_CALLOUT_CODE(aid, anum, xcontent, xcontent_end) do {\ +#define STACK_PUSH_CALLOUT_CODE(anum, xcontent, xcontent_end) do {\ STACK_ENSURE(1);\ stk->type = STK_CALLOUT_CODE;\ + stk->zid = -1;\ + stk->u.callout_code.num = (anum);\ + stk->u.callout_code.content = (xcontent);\ + stk->u.callout_code.content_end = (xcontent_end);\ + STACK_INC;\ +} while(0) + +#define STACK_PUSH_CALLOUT_NAME(aid, anum, xcontent, xcontent_end) do {\ + STACK_ENSURE(1);\ + stk->type = STK_CALLOUT_CODE;\ + stk->zid = (aid);\ stk->u.callout_code.num = (anum);\ stk->u.callout_code.content = (xcontent);\ stk->u.callout_code.content_end = (xcontent_end);\ @@ -1475,7 +1525,17 @@ stack_double(int is_alloca, char** arg_alloc_base, mem_end_stk[stk->zid] = stk->u.mem.end;\ }\ else if (stk->type == STK_CALLOUT_CODE) {\ - RETRACTION_CALLOUT_CODE(msa->mp->retraction_callout_of_code, stk->u.callout_code.num, stk->u.callout_code.content, stk->u.callout_code.content_end, msa->mp->callout_user_data);\ + int aof;\ + OnigCalloutFunc func;\ + if (stk->zid < 0) {\ + aof = ONIG_CALLOUT_OF_CODE;\ + func = msa->mp->retraction_callout_of_code;\ + }\ + else {\ + aof = ONIG_CALLOUT_OF_NAME;\ + func = onig_get_retraction_callout_func_from_id(stk->zid);\ + }\ + RETRACTION_CALLOUT(func, aof, stk->zid, stk->u.callout_code.num, stk->u.callout_code.content, stk->u.callout_code.content_end, msa->mp->callout_user_data);\ }\ }\ }\ @@ -3580,7 +3640,74 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, retraction_callout: if ((dirs & CALLOUT_IN_RETRACTION) != 0 && IS_NOT_NULL(msa->mp->retraction_callout_of_code)) { - STACK_PUSH_CALLOUT_CODE(-1, num, content_start, content_end); + STACK_PUSH_CALLOUT_CODE(num, content_start, content_end); + } + } + } + SOP_OUT; + continue; + break; + + case OP_CALLOUT_NAME: SOP_IN(OP_CALLOUT_NAME); + { + int id; + int of; + OnigCalloutFunc func; + + UChar* content_start; + UChar* content_end; + int call_result; + int num; + int dirs; + CalloutArgs args; + + of = ONIG_CALLOUT_OF_NAME; + GET_MEMNUM_INC(id, p); + func = onig_get_callout_func_from_id(id); + + callout_common_entry: + GET_MEMNUM_INC(num, p); + GET_MEMNUM_INC(dirs, p); + GET_POINTER_INC(content_start, p); + GET_POINTER_INC(content_end, p); + + if (IS_NOT_NULL(func) && (dirs & CALLOUT_IN_PROGRESS) != 0) { + CALLOUT_BODY(func, ONIG_CALLOUT_IN_PROGRESS, of, id, + num, content_start, content_end, + msa->mp->callout_user_data, args, call_result); + switch (call_result) { + case ONIG_CALLOUT_FAIL: + goto fail; + break; + case ONIG_CALLOUT_SUCCESS: + goto retraction_callout2; + break; + case ONIG_CALLOUT_ABORT: /* == ONIG_ABORT */ + /* fall */ + default: /* error code */ + if (call_result > 0) { + call_result = ONIGERR_INVALID_ARGUMENT; + } + best_len = call_result; + goto finish; + break; + } + } + else { + retraction_callout2: + if ((dirs & CALLOUT_IN_RETRACTION) != 0) { + if (of == ONIG_CALLOUT_OF_NAME) { + func = onig_get_retraction_callout_func_from_id(id); + if (IS_NOT_NULL(func)) { + STACK_PUSH_CALLOUT_NAME(id, num, content_start, content_end); + } + } + else { + func = msa->mp->retraction_callout_of_code; + if (IS_NOT_NULL(func)) { + STACK_PUSH_CALLOUT_CODE(num, content_start, content_end); + } + } } } } diff --git a/src/regint.h b/src/regint.h index d37cbec..4dd4ee5 100644 --- a/src/regint.h +++ b/src/regint.h @@ -594,6 +594,7 @@ enum OpCode { OP_PUSH_SAVE_VAL, OP_UPDATE_VAR, OP_CALLOUT_CODE, /* (?{...}) (?{{...}}) */ + OP_CALLOUT_NAME, /* (*NAME) (*NAME:...) */ /* no need: IS_DYNAMIC_OPTION() == 0 */ OP_SET_OPTION_PUSH, /* set option and push recover option */ @@ -699,6 +700,7 @@ typedef int ModeType; #define SIZE_OP_PUSH_SAVE_VAL (SIZE_OPCODE + SIZE_SAVE_TYPE + SIZE_MEMNUM) #define SIZE_OP_UPDATE_VAR (SIZE_OPCODE + SIZE_UPDATE_VAR_TYPE + SIZE_MEMNUM) #define SIZE_OP_CALLOUT_CODE (SIZE_OPCODE + SIZE_MEMNUM + SIZE_MEMNUM + SIZE_POINTER + SIZE_POINTER) +#define SIZE_OP_CALLOUT_NAME (SIZE_OPCODE + SIZE_MEMNUM + SIZE_MEMNUM + SIZE_MEMNUM + SIZE_POINTER + SIZE_POINTER) #define MC_ESC(syn) (syn)->meta_char_table.esc #define MC_ANYCHAR(syn) (syn)->meta_char_table.anychar @@ -776,6 +778,9 @@ extern int onig_is_code_in_cc_len P_((int enclen, OnigCodePoint code, void* / 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 OnigCalloutFunc onig_get_callout_func_from_id(int id); +extern OnigCalloutFunc onig_get_retraction_callout_func_from_id(int id); + /* strend hash */ typedef void hash_table_type; -- 2.40.0