]> granicus.if.org Git - onig/commitdiff
add OP_CALLOUT_NAME
authorK.Kosako <kosako@sofnec.co.jp>
Wed, 7 Feb 2018 07:49:18 +0000 (16:49 +0900)
committerK.Kosako <kosako@sofnec.co.jp>
Wed, 7 Feb 2018 07:49:18 +0000 (16:49 +0900)
src/regexec.c
src/regint.h

index 6ff9811458e2c3268631ae7be21ec574b7b91e68..754f02dc63aa96061a7ebffb18db5fba8193b4b1 100644 (file)
@@ -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);
+              }
+            }
           }
         }
       }
index d37cbec608f2aec7ed6091ebb73d5818fadd850c..4dd4ee5519c7e065015919ca3ce829d7c509fc8d 100644 (file)
@@ -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;