]> granicus.if.org Git - onig/commitdiff
add set_empty_status_check_trav()
authorK.Kosako <kkosako0@gmail.com>
Sat, 24 Aug 2019 13:03:54 +0000 (22:03 +0900)
committerK.Kosako <kkosako0@gmail.com>
Sat, 24 Aug 2019 13:03:54 +0000 (22:03 +0900)
src/regcomp.c

index d5d605839b97a99897c66e17f0a36040feb01009..8f8bd38ba8f44f630a4bc262cd0cb399ae5664f9 100644 (file)
@@ -3269,6 +3269,81 @@ set_empty_repeat_node_trav(Node* node, Node* empty, ScanEnv* env)
   return r;
 }
 
+static int
+is_ancestor_node(Node* node, Node* me)
+{
+  Node* parent;
+
+  while ((parent = NODE_PARENT(me)) != NULL_NODE) {
+    if (parent == node) return 1;
+    me = parent;
+  }
+  return 0;
+}
+
+static void
+set_empty_status_check_trav(Node* node, ScanEnv* env)
+{
+  switch (NODE_TYPE(node)) {
+  case NODE_LIST:
+  case NODE_ALT:
+    do {
+      set_empty_status_check_trav(NODE_CAR(node), env);
+    } while (IS_NOT_NULL(node = NODE_CDR(node)));
+    break;
+
+  case NODE_ANCHOR:
+    {
+      AnchorNode* an = ANCHOR_(node);
+
+      if (! ANCHOR_HAS_BODY(an)) break;
+      set_empty_status_check_trav(NODE_BODY(node), env);
+    }
+    break;
+
+  case NODE_QUANT:
+    set_empty_status_check_trav(NODE_BODY(node), env);
+    break;
+
+  case NODE_BAG:
+    if (IS_NOT_NULL(NODE_BODY(node)))
+      set_empty_status_check_trav(NODE_BODY(node), env);
+    {
+      BagNode* en = BAG_(node);
+
+      if (en->type == BAG_IF_ELSE) {
+        if (IS_NOT_NULL(en->te.Then)) {
+         set_empty_status_check_trav(en->te.Then, env);
+        }
+        if (IS_NOT_NULL(en->te.Else)) {
+         set_empty_status_check_trav(en->te.Else, env);
+        }
+      }
+    }
+    break;
+
+  case NODE_BACKREF:
+    {
+      int i;
+      int* backs;
+      MemEnv* mem_env = SCANENV_MEMENV(env);
+      BackRefNode* br = BACKREF_(node);
+      backs = BACKREFS_P(br);
+      for (i = 0; i < br->back_num; i++) {
+       Node* ernode = mem_env[backs[i]].empty_repeat_node;
+       if (IS_NOT_NULL(ernode)) {
+         if (is_ancestor_node(ernode, node))
+           NODE_STATUS_ADD(mem_env[backs[i]].mem_node, EMPTY_STATUS_CHECK);
+       }
+      }
+    }
+    break;
+
+  default:
+    break;
+  }
+}
+
 static void
 set_parent_node_trav(Node* node, Node* parent)
 {
@@ -6495,6 +6570,12 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
   r = setup_tree(root, reg, 0, &scan_env);
   if (r != 0) goto err_unset;
 
+  set_parent_node_trav(root, NULL_NODE);
+  r = set_empty_repeat_node_trav(root, NULL_NODE, &scan_env);
+  if (r != 0) goto err_unset;
+  set_empty_status_check_trav(root, &scan_env);
+
+
 #ifdef ONIG_DEBUG_PARSE
   print_tree(stderr, root);
 #endif