summaryrefslogtreecommitdiff
path: root/posix/regexec.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2002-11-03 00:59:09 +0000
committerRoland McGrath <roland@gnu.org>2002-11-03 00:59:09 +0000
commit05dab910b0032cab151f3c4507dc04100b1c2ce0 (patch)
treec2e532dc6b4876cd1950eef568f5be6477a57487 /posix/regexec.c
parent379c9e03af51b7b98aec1f9b04f8f22dec5d4711 (diff)
downloadglibc-05dab910b0032cab151f3c4507dc04100b1c2ce0.tar.gz
* manual/filesys.texi (Reading/Closing Directory): Rewrite readdir_r
description to be clearer and to say that *RESULT is set to ENTRY. 2002-10-30 Jakub Jelinek <jakub@redhat.com> * posix/regexec.c (build_trtable): Alloca or malloc dests_node and dests_ch arrays together. Alloca or malloc dest_states, dest_states_word and dest_states_nl arrays together. Free memory on error exit. 2002-10-29 Daniel Jacobowitz <drow@mvista.com> * crypt/crypt_util.c (__init_des_r): Initialize current_salt and current_saltbits. 2002-11-02 Roland McGrath <roland@redhat.com>
Diffstat (limited to 'posix/regexec.c')
-rw-r--r--posix/regexec.c95
1 files changed, 69 insertions, 26 deletions
diff --git a/posix/regexec.c b/posix/regexec.c
index 60518f731f..511b979f2a 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -2469,8 +2469,10 @@ build_trtable (preg, state, fl_search)
reg_errcode_t err;
re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
int i, j, k, ch;
+ int dests_node_malloced = 0, dest_states_malloced = 0;
int ndests; /* Number of the destination states from `state'. */
- re_dfastate_t **trtable, **dest_states, **dest_states_word, **dest_states_nl;
+ re_dfastate_t **trtable;
+ re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
re_node_set follows, *dests_node;
bitset *dests_ch;
bitset acceptable;
@@ -2479,34 +2481,76 @@ build_trtable (preg, state, fl_search)
from `state'. `dests_node[i]' represents the nodes which i-th
destination state contains, and `dests_ch[i]' represents the
characters which i-th destination state accepts. */
- dests_node = re_malloc (re_node_set, SBC_MAX);
- dests_ch = re_malloc (bitset, SBC_MAX);
+#ifdef _LIBC
+ if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX))
+ dests_node = (re_node_set *)
+ alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
+ else
+#endif
+ {
+ dests_node = (re_node_set *)
+ malloc ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX);
+ if (BE (dests_node == NULL, 0))
+ return NULL;
+ dests_node_malloced = 1;
+ }
+ dests_ch = (bitset *) (dests_node + SBC_MAX);
/* Initialize transiton table. */
trtable = (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
- if (BE (dests_node == NULL || dests_ch == NULL || trtable == NULL, 0))
- return NULL;
+ if (BE (trtable == NULL, 0))
+ {
+ if (dests_node_malloced)
+ free (dests_node);
+ return NULL;
+ }
/* At first, group all nodes belonging to `state' into several
destinations. */
ndests = group_nodes_into_DFAstates (preg, state, dests_node, dests_ch);
if (BE (ndests <= 0, 0))
{
- re_free (dests_node);
- re_free (dests_ch);
+ if (dests_node_malloced)
+ free (dests_node);
/* Return NULL in case of an error, trtable otherwise. */
- return (ndests < 0) ? NULL : trtable;
+ if (ndests == 0)
+ return trtable;
+ free (trtable);
+ return NULL;
}
- dest_states = re_malloc (re_dfastate_t *, ndests);
- dest_states_word = re_malloc (re_dfastate_t *, ndests);
- dest_states_nl = re_malloc (re_dfastate_t *, ndests);
- bitset_empty (acceptable);
-
err = re_node_set_alloc (&follows, ndests + 1);
- if (BE (dest_states == NULL || dest_states_word == NULL
- || dest_states_nl == NULL || err != REG_NOERROR, 0))
- return NULL;
+ if (BE (err != REG_NOERROR, 0))
+ goto out_free;
+
+#ifdef _LIBC
+ if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX
+ + ndests * 3 * sizeof (re_dfastate_t *)))
+ dest_states = (re_dfastate_t **)
+ alloca (ndests * 3 * sizeof (re_dfastate_t *));
+ else
+#endif
+ {
+ dest_states = (re_dfastate_t **)
+ malloc (ndests * 3 * sizeof (re_dfastate_t *));
+ if (BE (dest_states == NULL, 0))
+ {
+out_free:
+ if (dest_states_malloced)
+ free (dest_states);
+ re_node_set_free (&follows);
+ for (i = 0; i < ndests; ++i)
+ re_node_set_free (dests_node + i);
+ free (trtable);
+ if (dests_node_malloced)
+ free (dests_node);
+ return NULL;
+ }
+ dest_states_malloced = 1;
+ }
+ dest_states_word = dest_states + ndests;
+ dest_states_nl = dest_states_word + ndests;
+ bitset_empty (acceptable);
/* Then build the states for all destinations. */
for (i = 0; i < ndests; ++i)
@@ -2521,7 +2565,7 @@ build_trtable (preg, state, fl_search)
{
err = re_node_set_merge (&follows, dfa->eclosures + next_node);
if (BE (err != REG_NOERROR, 0))
- return NULL;
+ goto out_free;
}
}
/* If search flag is set, merge the initial state. */
@@ -2541,12 +2585,12 @@ build_trtable (preg, state, fl_search)
err = re_node_set_merge (&follows,
dfa->init_state->entrance_nodes);
if (BE (err != REG_NOERROR, 0))
- return NULL;
+ goto out_free;
}
}
dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
- return NULL;
+ goto out_free;
/* If the new state has context constraint,
build appropriate states for these contexts. */
if (dest_states[i]->has_constraint)
@@ -2554,11 +2598,11 @@ build_trtable (preg, state, fl_search)
dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
CONTEXT_WORD);
if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
- return NULL;
+ goto out_free;
dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
CONTEXT_NEWLINE);
if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
- return NULL;
+ goto out_free;
}
else
{
@@ -2615,16 +2659,15 @@ build_trtable (preg, state, fl_search)
}
}
- re_free (dest_states_nl);
- re_free (dest_states_word);
- re_free (dest_states);
+ if (dest_states_malloced)
+ free (dest_states);
re_node_set_free (&follows);
for (i = 0; i < ndests; ++i)
re_node_set_free (dests_node + i);
- re_free (dests_ch);
- re_free (dests_node);
+ if (dests_node_malloced)
+ free (dests_node);
return trtable;
}