summary refs log tree commit diff
path: root/posix/regcomp.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-01-27 19:08:10 +0000
committerUlrich Drepper <drepper@redhat.com>2005-01-27 19:08:10 +0000
commit963d8d782fc98fb6dc3a66f0068795f9920c269d (patch)
treef2f9455bff4b050e427bbeb11719eb1aceddf386 /posix/regcomp.c
parent717ecb1fe52cc726cb9521e8a93c90040fe2b255 (diff)
downloadglibc-963d8d782fc98fb6dc3a66f0068795f9920c269d.tar.gz
glibc-963d8d782fc98fb6dc3a66f0068795f9920c269d.tar.xz
glibc-963d8d782fc98fb6dc3a66f0068795f9920c269d.zip
[BZ #558]
Update.
2005-01-27  Paolo Bonzini  <bonzini@gnu.org>

	[BZ #558]
	* posix/regcomp.c (calc_inveclosure): Return reg_errcode_t.
	Initialize the node sets in dfa->inveclosures.
	(analyze): Initialize inveclosures only if it is needed.
	Check errors from calc_inveclosure.
	* posix/regex_internal.c (re_dfa_add_node): Do not initialize
	the inveclosure node set.
	* posix/regexec.c (re_search_internal): If nmatch includes unused
	subexpressions, reset them to { rm_so: -1, rm_eo: -1 } here.

	* posix/regcomp.c (parse_bracket_exp) [!RE_ENABLE_I18N]:
	Do build a SIMPLE_BRACKET token.

	* posix/regexec.c (transit_state_mb): Do not examine nodes
	where ACCEPT_MB is not set.
Diffstat (limited to 'posix/regcomp.c')
-rw-r--r--posix/regcomp.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/posix/regcomp.c b/posix/regcomp.c
index cf759690cf..1a5f7952c3 100644
--- a/posix/regcomp.c
+++ b/posix/regcomp.c
@@ -58,7 +58,7 @@ static int search_duplicated_node (re_dfa_t *dfa, int org_node,
 static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
 static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
 					 int node, int root);
-static void calc_inveclosure (re_dfa_t *dfa);
+static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);
 static int fetch_number (re_string_t *input, re_token_t *token,
 			 reg_syntax_t syntax);
 static void fetch_token (re_token_t *result, re_string_t *input,
@@ -1132,9 +1132,8 @@ analyze (preg)
   dfa->org_indices = re_malloc (int, dfa->nodes_alloc);
   dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
   dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
-  dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_alloc);
   if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
-	  || dfa->eclosures == NULL || dfa->inveclosures == NULL, 0))
+	  || dfa->eclosures == NULL, 0))
     return REG_ESPACE;
 
   dfa->subexp_map = re_malloc (int, preg->re_nsub);
@@ -1167,7 +1166,18 @@ analyze (preg)
   ret = calc_eclosure (dfa);
   if (BE (ret != REG_NOERROR, 0))
     return ret;
-  calc_inveclosure (dfa);
+
+  /* We only need this during the prune_impossible_nodes pass in regexec.c;
+     skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */
+  if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
+      || dfa->nbackref)
+    {
+      dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
+      if (BE (dfa->inveclosures == NULL, 0))
+        return REG_ESPACE;
+      ret = calc_inveclosure (dfa);
+    }
+
   return ret;
 }
 
@@ -1597,19 +1607,26 @@ duplicate_node (new_idx, dfa, org_idx, constraint)
   return REG_NOERROR;
 }
 
-static void
+static reg_errcode_t
 calc_inveclosure (dfa)
      re_dfa_t *dfa;
 {
-  int src, idx, dest;
+  int src, idx, ret;
+  for (idx = 0; idx < dfa->nodes_len; ++idx)
+    re_node_set_init_empty (dfa->inveclosures + idx);
+
   for (src = 0; src < dfa->nodes_len; ++src)
     {
+      int *elems = dfa->eclosures[src].elems;
       for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
 	{
-	  dest = dfa->eclosures[src].elems[idx];
-	  re_node_set_insert_last (dfa->inveclosures + dest, src);
+	  ret = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);
+	  if (BE (ret == -1, 0))
+	    return REG_ESPACE;
 	}
     }
+
+  return REG_NOERROR;
 }
 
 /* Calculate "eclosure" for all the node in DFA.  */
@@ -3304,17 +3321,18 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
 	}
     }
   else
+#endif /* not RE_ENABLE_I18N */
     {
+#ifdef RE_ENABLE_I18N
+      free_charset (mbcset);
+#endif
       /* Build a tree for simple bracket.  */
       br_token.type = SIMPLE_BRACKET;
       br_token.opr.sbcset = sbcset;
       work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
       if (BE (work_tree == NULL, 0))
         goto parse_bracket_exp_espace;
-
-      free_charset (mbcset);
     }
-#endif /* not RE_ENABLE_I18N */
   return work_tree;
 
  parse_bracket_exp_espace: