]> granicus.if.org Git - onig/commitdiff
parse callout tag part
authorK.Kosako <kosako@sofnec.co.jp>
Wed, 14 Feb 2018 07:36:39 +0000 (16:36 +0900)
committerK.Kosako <kosako@sofnec.co.jp>
Wed, 14 Feb 2018 07:36:39 +0000 (16:36 +0900)
src/regcomp.c
src/regparse.c
src/regparse.h

index 3c2b920ba2c414a764aa5f84a3be0502f245ec92..8c228e294eea62cd1df961bb78c569093ee21346 100644 (file)
@@ -1562,10 +1562,18 @@ compile_gimmick_node(GimmickNode* node, regex_t* reg)
         if (r != 0) return r;
         r = add_mem_num(reg, node->dirs);
         if (r != 0) return r;
-        r = add_pointer(reg, pattern + node->code_start);
-        if (r != 0) return r;
-        r = add_pointer(reg, pattern + node->code_end);
-        if (r != 0) return r;
+        if (node->code_start >= 0) {
+          r = add_pointer(reg, pattern + node->code_start);
+          if (r != 0) return r;
+          r = add_pointer(reg, pattern + node->code_end);
+          if (r != 0) return r;
+        }
+        else {
+          r = add_pointer(reg, 0);
+          if (r != 0) return r;
+          r = add_pointer(reg, 0);
+          if (r != 0) return r;
+        }
       }
       break;
 
index 2b94b9188bfbd75c0bfae8fe0e25db98e173cf65..e868f57e0e39bc39de30710391a7e738d3f06afc 100644 (file)
@@ -2168,6 +2168,8 @@ node_new_callout(Node** node, enum OnigCalloutOf callout_of, int id, int dirs,
   GIMMICK_(*node)->dirs        = dirs;
   GIMMICK_(*node)->code_start  = -1;
   GIMMICK_(*node)->code_end    = -1;
+  GIMMICK_(*node)->tag_start   = -1;
+  GIMMICK_(*node)->tag_end     = -1;
 
   return ONIG_NORMAL;
 }
@@ -6054,7 +6056,8 @@ static int parse_subexp(Node** top, OnigToken* tok, int term,
                         UChar** src, UChar* end, ScanEnv* env);
 
 #ifdef USE_CALLOUT
-/* (?{...}) (?{{...}}) */
+
+/* (?{...}[+-]) (?{{...}}[+-]) */
 static int
 parse_callout_of_code(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* env)
 {
@@ -6117,14 +6120,16 @@ parse_callout_of_code(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* en
   r = node_new_callout(np, ONIG_CALLOUT_OF_CODE, -1, dirs, env);
   if (r != 0) return r;
 
-  GIMMICK_(*np)->code_start = (int )(code_start - env->pattern);
-  GIMMICK_(*np)->code_end   = (int )(code_end   - env->pattern);
+  if (code_start != code_end) {
+    GIMMICK_(*np)->code_start = (int )(code_start - env->pattern);
+    GIMMICK_(*np)->code_end   = (int )(code_end   - env->pattern);
+  }
 
   *src = p;
   return 0;
 }
 
-/* (*NAME[+-]) (*NAME[+-]:...) */
+/* (*NAME[+-][TAG]) (*NAME[+-][TAG]{...}) */
 static int
 parse_callout_of_name(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* env)
 {
@@ -6136,6 +6141,8 @@ parse_callout_of_name(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* en
   UChar* name_end;
   UChar* code_start;
   UChar* code_end;
+  UChar* tag_start;
+  UChar* tag_end;
   OnigEncoding enc = env->enc;
   UChar* p = *src;
 
@@ -6153,11 +6160,11 @@ parse_callout_of_name(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* en
 
       if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
       PFETCH_S(c);
-      if (c == cterm || c == ':') break;
+      if (c == cterm || c == '[' || c == '{') break;
       else
         return ONIGERR_INVALID_CALLOUT_PATTERN;
     }
-    else if (c == cterm || c == ':') break;
+    else if (c == cterm || c == '[' || c == '{') break;
     else if (c > 255)
       return ONIGERR_INVALID_CALLOUT_NAME;
     else {
@@ -6166,15 +6173,39 @@ parse_callout_of_name(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* en
     }
   }
 
-  if (c == ':') {
-    if (PEND) return ONIGERR_INVALID_CALLOUT_PATTERN;
+  if (c == '[') {
+    if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+    tag_start = p;
+    while (! PEND) {
+      tag_end = p;
+      PFETCH_S(c);
+      if (c == ']') break;
+      if (c > 255) return ONIGERR_INVALID_CALLOUT_TAG_NAME;
+      if (! ONIGENC_IS_CODE_ALNUM(enc, c) && c != '_')
+        return ONIGERR_INVALID_CALLOUT_TAG_NAME;
+    }
+    if (c != ']') return ONIGERR_END_PATTERN_IN_GROUP;
+
+    if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+    PFETCH_S(c);
+  }
+  else {
+    tag_start = tag_end = 0;
+  }
+
+  if (c == '{') {
+    if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+    
     code_start = p;
     while (! PEND) {
       code_end = p;
       PFETCH_S(c);
-      if (c == cterm) break;
+      if (c == '}') break;
     }
-    if (c != cterm) return ONIGERR_END_PATTERN_IN_GROUP;
+    if (c != '}') return ONIGERR_END_PATTERN_IN_GROUP;
+
+    if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
+    PFETCH_S(c);
   }
   else {
     code_start = code_end = 0;
@@ -6189,8 +6220,15 @@ parse_callout_of_name(Node** np, int cterm, UChar** src, UChar* end, ScanEnv* en
   r = node_new_callout(np, ONIG_CALLOUT_OF_NAME, id, dirs, env);
   if (r != ONIG_NORMAL) return r;
 
-  GIMMICK_(*np)->code_start = (int )(code_start - env->pattern);
-  GIMMICK_(*np)->code_end   = (int )(code_end   - env->pattern);
+  if (code_start != code_end) {
+    GIMMICK_(*np)->code_start = (int )(code_start - env->pattern);
+    GIMMICK_(*np)->code_end   = (int )(code_end   - env->pattern);
+  }
+
+  if (tag_start != tag_end) {
+    GIMMICK_(*np)->tag_start = (int )(tag_start - env->pattern);
+    GIMMICK_(*np)->tag_end   = (int )(tag_end   - env->pattern);
+  }
 
   *src = p;
   return 0;
index 49712b45053811f2c0b45e0caba842362d5d3412..6eb6ca55e8d965bd88c261b475e5d63180b61928 100644 (file)
@@ -338,6 +338,8 @@ typedef struct {
   int  id;
   int  code_start;  /* code start position index */
   int  code_end;    /* code end   position index */
+  int  tag_start;   /* -1: NO tag */
+  int  tag_end;
 } GimmickNode;
 
 typedef struct _Node {