aboutsummaryrefslogtreecommitdiff
path: root/posix/regexec.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-11-06 19:57:50 +0000
committerUlrich Drepper <drepper@redhat.com>2002-11-06 19:57:50 +0000
commit1b2c2628354003bd97af125a164e830c9d295e3a (patch)
tree32abaefed6d40cf6c559bcd6e0b47016419e7dc3 /posix/regexec.c
parentb14993a2356cd7b8c3f74ca2b8e743c056f9401d (diff)
downloadglibc-1b2c2628354003bd97af125a164e830c9d295e3a.tar
glibc-1b2c2628354003bd97af125a164e830c9d295e3a.tar.gz
glibc-1b2c2628354003bd97af125a164e830c9d295e3a.tar.bz2
glibc-1b2c2628354003bd97af125a164e830c9d295e3a.zip
Update.
2002-11-06 Jakub Jelinek <jakub@redhat.com> * posix/regcomp.c (re_compile_pattern): Don't set regs_allocated here. (regcomp): Don't set can_be_null here. (re_comp): Clear whole re_comp_buf with the exception of fastmap. (re_compile_internal): Clear can_be_null, set regs_allocated. * posix/regcomp.c (re_set_fastmap): New function. (re_compile_fastmap_iter): Use it. Remove redundant type == COMPLEX_BRACKET check. * posix/regexec.c (re_search_internal): Optimize searching with fastmap. Call re_string_reconstruct even if match_first is smaller than raw_mbs_idx. 2002-11-06 Isamu Hasegawa <isamu@yamato.ibm.com> * posix/regcomp (free_dfa_content): Use free_state. * posix/regex_internal.c (re_string_realloc_buffers): Don't edit pointers in case that realloc failed. (re_node_set_merge): Likewise. (register_state): Likewise. (create_newstate_common): Invoke memory release functions in case of error conditions. (create_ci_newstate): Likewise. (create_cd_newstate): Likewise. (free_state): New function. * posix/regexec.c (re_search_internal): Invoke memory release functions in case of error conditions. (sift_states_backward): Likewise. (merge_state_array): Likewise. (add_epsilon_src_nodes): Likewise. (sub_epsilon_src_nodes): Likewise. (search_subexp): Likewise. (sift_states_bkref): Likewise. (transit_state_sb): Likewise. (transit_state_mb): Likewise. (transit_state_bkref_loop): Likewise. (group_nodes_into_DFAstates): Likewise. (push_fail_stack): Don't edit pointers in case that realloc failed. (extend_buffers): Likewise. (match_ctx_add_entry): Likewise.
Diffstat (limited to 'posix/regexec.c')
-rw-r--r--posix/regexec.c362
1 files changed, 238 insertions, 124 deletions
diff --git a/posix/regexec.c b/posix/regexec.c
index 511b979f2a..17c469c47f 100644
--- a/posix/regexec.c
+++ b/posix/regexec.c
@@ -85,7 +85,7 @@ static int proceed_next_node (const regex_t *preg, int nregs, regmatch_t *regs,
const re_match_context_t *mctx,
int *pidx, int node, re_node_set *eps_via_nodes,
struct re_fail_stack_t *fs);
-static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
+static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
int str_idx, int *dests, int nregs,
regmatch_t *regs,
re_node_set *eps_via_nodes);
@@ -337,7 +337,7 @@ re_search_2_stub (bufp, string1, length1, string2, length2, start, range, regs,
rval = re_search_stub (bufp, str, len, start, range, stop, regs,
ret_len);
if (free_str)
- re_free ((char *) str);
+ re_free ((char *) str);
return rval;
}
@@ -575,9 +575,10 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
re_string_t input;
int left_lim, right_lim, incr;
int fl_longest_match, match_first, match_last = -1;
+ int fast_translate, sb;
re_match_context_t mctx;
- char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate)
- ? preg->fastmap : NULL);
+ char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate
+ && range && !preg->can_be_null) ? preg->fastmap : NULL);
/* Check if the DFA haven't been compiled. */
if (BE (preg->used == 0 || dfa->init_state == NULL
@@ -586,6 +587,7 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
return REG_NOMATCH;
re_node_set_init_empty (&empty_set);
+ memset (&mctx, '\0', sizeof (re_match_context_t));
/* We must check the longest matching, if nmatch > 0. */
fl_longest_match = (nmatch != 0);
@@ -593,12 +595,12 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
err = re_string_allocate (&input, string, length, dfa->nodes_len + 1,
preg->translate, preg->syntax & RE_ICASE);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
input.stop = stop;
err = match_ctx_init (&mctx, eflags, &input, dfa->nbackref * 2);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
/* We will log all the DFA states through which the dfa pass,
if nmatch > 1, or this dfa has "multibyte node", which is a
@@ -608,7 +610,10 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
{
mctx.state_log = re_malloc (re_dfastate_t *, dfa->nodes_len + 1);
if (BE (mctx.state_log == NULL, 0))
- return REG_ESPACE;
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
}
else
mctx.state_log = NULL;
@@ -626,65 +631,117 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
incr = (range < 0) ? -1 : 1;
left_lim = (range < 0) ? start + range : start;
right_lim = (range < 0) ? start : start + range;
+ sb = MB_CUR_MAX == 1;
+ fast_translate = sb || !(preg->syntax & RE_ICASE || preg->translate);
for (;;)
{
/* At first get the current byte from input string. */
- int ch;
- if (MB_CUR_MAX > 1 && (preg->syntax & RE_ICASE || preg->translate))
- {
- /* In this case, we can't determin easily the current byte,
- since it might be a component byte of a multibyte character.
- Then we use the constructed buffer instead. */
- /* If MATCH_FIRST is out of the valid range, reconstruct the
- buffers. */
- if (input.raw_mbs_idx + input.valid_len <= match_first)
- re_string_reconstruct (&input, match_first, eflags,
- preg->newline_anchor);
- /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
- Note that MATCH_FIRST must not be smaller than 0. */
- ch = ((match_first >= length) ? 0
- : re_string_byte_at (&input, match_first - input.raw_mbs_idx));
- }
- else
- {
- /* We apply translate/conversion manually, since it is trivial
- in this case. */
- /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
- Note that MATCH_FIRST must not be smaller than 0. */
- ch = (match_first < length) ? (unsigned char)string[match_first] : 0;
- /* Apply translation if we need. */
- ch = preg->translate ? preg->translate[ch] : ch;
- /* In case of case insensitive mode, convert to upper case. */
- ch = ((preg->syntax & RE_ICASE) && islower (ch)) ? toupper (ch) : ch;
- }
+ if (fastmap)
+ {
+ if (BE (fast_translate, 1))
+ {
+ unsigned RE_TRANSLATE_TYPE t
+ = (unsigned RE_TRANSLATE_TYPE) preg->translate;
+ if (BE (range >= 0, 1))
+ {
+ if (BE (t != NULL, 0))
+ {
+ while (BE (match_first < right_lim, 1)
+ && !fastmap[t[(unsigned char) string[match_first]]])
+ ++match_first;
+ }
+ else
+ {
+ while (BE (match_first < right_lim, 1)
+ && !fastmap[(unsigned char) string[match_first]])
+ ++match_first;
+ }
+ if (BE (match_first == right_lim, 0))
+ {
+ int ch = match_first >= length
+ ? 0 : (unsigned char) string[match_first];
+ if (!fastmap[t ? t[ch] : ch])
+ break;
+ }
+ }
+ else
+ {
+ while (match_first >= left_lim)
+ {
+ int ch = match_first >= length
+ ? 0 : (unsigned char) string[match_first];
+ if (fastmap[t ? t[ch] : ch])
+ break;
+ --match_first;
+ }
+ if (match_first < left_lim)
+ break;
+ }
+ }
+ else
+ {
+ int ch;
+
+ do
+ {
+ /* In this case, we can't determine easily the current byte,
+ since it might be a component byte of a multibyte
+ character. Then we use the constructed buffer
+ instead. */
+ /* If MATCH_FIRST is out of the valid range, reconstruct the
+ buffers. */
+ if (input.raw_mbs_idx + input.valid_len <= match_first
+ || match_first < input.raw_mbs_idx)
+ {
+ err = re_string_reconstruct (&input, match_first, eflags,
+ preg->newline_anchor);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
+ }
+ /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
+ Note that MATCH_FIRST must not be smaller than 0. */
+ ch = ((match_first >= length) ? 0
+ : re_string_byte_at (&input,
+ match_first - input.raw_mbs_idx));
+ if (fastmap[ch])
+ break;
+ match_first += incr;
+ }
+ while (match_first >= left_lim && match_first <= right_lim);
+ if (! fastmap[ch])
+ break;
+ }
+ }
- /* Eliminate inappropriate one by fastmap. */
- if (preg->can_be_null || fastmap == NULL || fastmap[ch])
- {
- /* Reconstruct the buffers so that the matcher can assume that
- the matching starts from the begining of the buffer. */
- re_string_reconstruct (&input, match_first, eflags,
- preg->newline_anchor);
+ /* Reconstruct the buffers so that the matcher can assume that
+ the matching starts from the begining of the buffer. */
+ err = re_string_reconstruct (&input, match_first, eflags,
+ preg->newline_anchor);
+ if (BE (err != REG_NOERROR, 0))
+ goto free_return;
#ifdef RE_ENABLE_I18N
- /* Eliminate it when it is a component of a multibyte character
- and isn't the head of a multibyte character. */
- if (MB_CUR_MAX == 1 || re_string_first_byte (&input, 0))
+ /* Eliminate it when it is a component of a multibyte character
+ and isn't the head of a multibyte character. */
+ if (sb || re_string_first_byte (&input, 0))
#endif
- {
- /* It seems to be appropriate one, then use the matcher. */
- /* We assume that the matching starts from 0. */
- mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
- match_last = check_matching (preg, &mctx, 0, fl_longest_match);
- if (match_last != -1)
- {
- if (BE (match_last == -2, 0))
- return REG_ESPACE;
- else
- break; /* We found a matching. */
- }
- }
- }
+ {
+ /* It seems to be appropriate one, then use the matcher. */
+ /* We assume that the matching starts from 0. */
+ mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
+ match_last = check_matching (preg, &mctx, 0, fl_longest_match);
+ if (match_last != -1)
+ {
+ if (BE (match_last == -2, 0))
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
+ else
+ break; /* We found a matching. */
+ }
+ }
+
/* Update counter. */
match_first += incr;
if (match_first < left_lim || right_lim < match_first)
@@ -722,28 +779,42 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
match_ctx_clear_flag (&mctx);
sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
if (BE (sifted_states == NULL, 0))
- return REG_ESPACE;
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
if (dfa->nbackref)
{
lim_states = calloc (sizeof (re_dfastate_t *),
match_last + 1);
if (BE (lim_states == NULL, 0))
- return REG_ESPACE;
+ {
+ re_free (sifted_states);
+ err = REG_ESPACE;
+ goto free_return;
+ }
}
sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
mctx.match_last, 0);
err = sift_states_backward (preg, &mctx, &sctx);
+ re_node_set_free (&sctx.limits);
if (BE (err != REG_NOERROR, 0))
- return err;
+ {
+ re_free (sifted_states);
+ re_free (lim_states);
+ goto free_return;
+ }
if (lim_states != NULL)
{
err = merge_state_array (dfa, sifted_states, lim_states,
match_last + 1);
- if (BE (err != REG_NOERROR, 0))
- return err;
re_free (lim_states);
+ if (BE (err != REG_NOERROR, 0))
+ {
+ re_free (sifted_states);
+ goto free_return;
+ }
}
- re_node_set_free (&sctx.limits);
re_free (mctx.state_log);
mctx.state_log = sifted_states;
}
@@ -751,7 +822,7 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
err = set_regs (preg, &mctx, nmatch, pmatch,
dfa->has_plural_match && dfa->nbackref > 0);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
/* At last, add the offset to the each registers, since we slided
@@ -763,13 +834,13 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
pmatch[reg_idx].rm_eo += match_first;
}
}
-
+ err = (match_last == -1) ? REG_NOMATCH : REG_NOERROR;
+ free_return:
re_free (mctx.state_log);
if (dfa->nbackref)
match_ctx_free (&mctx);
re_string_destruct (&input);
-
- return (match_last == -1) ? REG_NOMATCH : REG_NOERROR;
+ return err;
}
/* Acquire an initial state and return it.
@@ -1099,11 +1170,13 @@ push_fail_stack (fs, str_idx, dests, nregs, regs, eps_via_nodes)
int num = fs->num++;
if (fs->num == fs->alloc)
{
+ struct re_fail_stack_ent_t *new_array;
fs->alloc *= 2;
- fs->stack = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
+ new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
* fs->alloc));
- if (fs->stack == NULL)
+ if (new_array == NULL)
return REG_ESPACE;
+ fs->stack = new_array;
}
fs->stack[num].idx = str_idx;
fs->stack[num].node = dests[1];
@@ -1112,7 +1185,7 @@ push_fail_stack (fs, str_idx, dests, nregs, regs, eps_via_nodes)
err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
return err;
}
-
+
static int
pop_fail_stack (fs, pidx, nregs, regs, eps_via_nodes)
struct re_fail_stack_t *fs;
@@ -1301,7 +1374,7 @@ sift_states_backward (preg, mctx, sctx)
return err;
err = update_cur_sifted_state (preg, mctx, sctx, str_idx, &cur_dest);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
/* Then check each states in the state_log. */
while (str_idx > 0)
@@ -1365,7 +1438,10 @@ sift_states_backward (preg, mctx, sctx)
}
ret = re_node_set_insert (&cur_dest, prev_node);
if (BE (ret == -1, 0))
- return err;
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
}
/* Add all the nodes which satisfy the following conditions:
@@ -1374,11 +1450,12 @@ sift_states_backward (preg, mctx, sctx)
And update state_log. */
err = update_cur_sifted_state (preg, mctx, sctx, str_idx, &cur_dest);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
-
+ err = REG_NOERROR;
+ free_return:
re_node_set_free (&cur_dest);
- return REG_NOERROR;
+ return err;
}
/* Helper functions. */
@@ -1409,7 +1486,8 @@ clean_state_log_if_need (mctx, next_state_log_idx)
return REG_NOERROR;
}
-static reg_errcode_t merge_state_array (dfa, dst, src, num)
+static reg_errcode_t
+merge_state_array (dfa, dst, src, num)
re_dfa_t *dfa;
re_dfastate_t **dst;
re_dfastate_t **src;
@@ -1429,9 +1507,9 @@ static reg_errcode_t merge_state_array (dfa, dst, src, num)
if (BE (err != REG_NOERROR, 0))
return err;
dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
+ re_node_set_free (&merged_set);
if (BE (err != REG_NOERROR, 0))
return err;
- re_node_set_free (&merged_set);
}
}
return REG_NOERROR;
@@ -1512,7 +1590,10 @@ add_epsilon_src_nodes (dfa, dest_nodes, candidates)
dfa->inveclosures
+ src_copy.elems[src_idx]);
if (BE (err != REG_NOERROR, 0))
- return err;
+ {
+ re_node_set_free (&src_copy);
+ return err;
+ }
}
re_node_set_free (&src_copy);
return REG_NOERROR;
@@ -1549,7 +1630,10 @@ sub_epsilon_src_nodes (dfa, node, dest_nodes, candidates)
err = re_node_set_add_intersect (&except_nodes, candidates,
dfa->inveclosures + cur_node);
if (BE (err != REG_NOERROR, 0))
- return err;
+ {
+ re_node_set_free (&except_nodes);
+ return err;
+ }
}
}
}
@@ -1791,7 +1875,7 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
local_sctx = *sctx;
err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
local_sctx.check_subexp = -sctx->check_subexp;
local_sctx.limited_states = sctx->limited_states;
@@ -1801,7 +1885,7 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
err = sift_states_backward (preg, mctx, &local_sctx);
local_sctx.sifted_states[str_idx] = cur_state;
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
/* There must not 2 same node in a node set. */
break;
}
@@ -1823,7 +1907,7 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
reg_errcode_t err;
err = extend_buffers (mctx);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
buf = (char *) re_string_get_buffer (mctx->input);
if (strncmp (buf + str_idx, buf + bkref_str_idx, subexp_len) != 0)
@@ -1835,17 +1919,20 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
if (lim_states == NULL)
{
lim_states = re_malloc (re_dfastate_t *, str_idx + 1);
+ if (BE (lim_states == NULL, 0))
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
}
if (local_sctx.sifted_states == NULL)
{
/* It hasn't been initialized yet, initialize it now. */
local_sctx = *sctx;
- if (BE (lim_states == NULL, 0))
- return REG_ESPACE;
err = re_node_set_init_copy (&local_sctx.limits,
&sctx->limits);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
local_sctx.check_subexp = 0;
local_sctx.last_node = node;
@@ -1855,7 +1942,7 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
sizeof (re_dfastate_t*) * (str_idx + 1));
err = sift_states_backward (preg, mctx, &local_sctx);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
if (local_sctx.sifted_states[0] == NULL
&& local_sctx.limited_states[0] == NULL)
{
@@ -1869,10 +1956,10 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
err = match_ctx_add_entry (mctx, sctx->cur_bkref, bkref_str_idx,
str_idx, sctx->cls_subexp_idx);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
err = clean_state_log_if_need (mctx, dest_str_idx);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
break;
}
}
@@ -1882,18 +1969,19 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
{
err = sub_epsilon_src_nodes(dfa, node, dest_nodes, candidates);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
/* Update state_log. */
sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
-
+ err = REG_NOERROR;
+ free_return:
if (local_sctx.sifted_states != NULL)
re_node_set_free (&local_sctx.limits);
if (lim_states != NULL)
re_free (lim_states);
- return REG_NOERROR;
+ return err;
}
static reg_errcode_t
@@ -1958,11 +2046,11 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
cur_bkref_idx, entry->subexp_from,
entry->subexp_to);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
err = clean_state_log_if_need (mctx, cur_bkref_idx
+ subexp_len);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
else
{
@@ -1984,24 +2072,27 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
err = re_node_set_init_copy (&local_sctx.limits,
&sctx->limits);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
local_sctx.last_node = node;
local_sctx.last_str_idx = str_idx;
err = re_node_set_insert (&local_sctx.limits, enabled_idx);
if (BE (err < 0, 0))
- return REG_ESPACE;
+ {
+ err = REG_ESPACE;
+ goto free_return;
+ }
cur_state = local_sctx.sifted_states[str_idx];
err = sift_states_backward (preg, mctx, &local_sctx);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
if (sctx->limited_states != NULL)
{
err = merge_state_array (dfa, sctx->limited_states,
local_sctx.sifted_states,
str_idx + 1);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
local_sctx.sifted_states[str_idx] = cur_state;
re_node_set_remove (&local_sctx.limits, enabled_idx);
@@ -2019,12 +2110,14 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
}
}
}
+ err = REG_NOERROR;
+ free_return:
if (local_sctx.sifted_states != NULL)
{
re_node_set_free (&local_sctx.limits);
}
- return REG_NOERROR;
+ return err;
}
@@ -2215,7 +2308,10 @@ transit_state_sb (err, preg, state, fl_search, mctx)
*err = re_node_set_merge (&next_nodes,
dfa->eclosures + dfa->nexts[cur_node]);
if (BE (*err != REG_NOERROR, 0))
- return NULL;
+ {
+ re_node_set_free (&next_nodes);
+ return NULL;
+ }
}
}
if (fl_search)
@@ -2235,7 +2331,10 @@ transit_state_sb (err, preg, state, fl_search, mctx)
*err = re_node_set_merge (&next_nodes,
dfa->init_state->entrance_nodes);
if (BE (*err != REG_NOERROR, 0))
- return NULL;
+ {
+ re_node_set_free (&next_nodes);
+ return NULL;
+ }
}
}
context = re_string_context_at (mctx->input, cur_str_idx, mctx->eflags,
@@ -2313,10 +2412,10 @@ transit_state_mb (preg, pstate, mctx)
preg->newline_anchor);
mctx->state_log[dest_idx]
= re_acquire_state_context (&err, dfa, &dest_nodes, context);
- if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
- return err;
if (dest_state != NULL)
re_node_set_free (&dest_nodes);
+ if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
+ return err;
}
return REG_NOERROR;
}
@@ -2389,7 +2488,7 @@ transit_state_bkref_loop (preg, nodes, work_state_log, mctx)
match_ctx_clear_flag (mctx);
err = sift_states_backward (preg, mctx, &sctx);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
/* And add the epsilon closures (which is `new_dest_nodes') of
the backreference to appropriate state_log. */
@@ -2424,7 +2523,7 @@ transit_state_bkref_loop (preg, nodes, work_state_log, mctx)
context);
if (BE (mctx->state_log[dest_str_idx] == NULL
&& err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
else
{
@@ -2433,13 +2532,16 @@ transit_state_bkref_loop (preg, nodes, work_state_log, mctx)
dest_state->entrance_nodes,
new_dest_nodes);
if (BE (err != REG_NOERROR, 0))
- return err;
+ {
+ re_node_set_free (&dest_nodes);
+ goto free_return;
+ }
mctx->state_log[dest_str_idx]
= re_acquire_state_context (&err, dfa, &dest_nodes, context);
+ re_node_set_free (&dest_nodes);
if (BE (mctx->state_log[dest_str_idx] == NULL
&& err != REG_NOERROR, 0))
- return err;
- re_node_set_free (&dest_nodes);
+ goto free_return;
}
/* We need to check recursively if the backreference can epsilon
transit. */
@@ -2449,12 +2551,14 @@ transit_state_bkref_loop (preg, nodes, work_state_log, mctx)
err = transit_state_bkref_loop (preg, new_dest_nodes,
work_state_log, mctx);
if (BE (err != REG_NOERROR, 0))
- return err;
+ goto free_return;
}
}
}
+ err = REG_NOERROR;
+ free_return:
re_free (cur_regs);
- return REG_NOERROR;
+ return err;
}
/* Build transition table for the state.
@@ -2776,14 +2880,14 @@ group_nodes_into_DFAstates (preg, state, dests_node, dests_ch)
bitset_copy (dests_ch[j], intersec);
err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
if (BE (err != REG_NOERROR, 0))
- return -1;
+ goto error_return;
++ndests;
}
/* Put the position in the current group. */
err = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
if (BE (err < 0, 0))
- return -1;
+ goto error_return;
/* If all characters are consumed, go to next node. */
if (!not_consumed)
@@ -2795,12 +2899,16 @@ group_nodes_into_DFAstates (preg, state, dests_node, dests_ch)
bitset_copy (dests_ch[ndests], accepts);
err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
if (BE (err != REG_NOERROR, 0))
- return -1;
+ goto error_return;
++ndests;
bitset_empty (accepts);
}
}
return ndests;
+ error_return:
+ for (j = 0; j < ndests; ++j)
+ re_node_set_free (dests_node + j);
+ return -1;
}
#ifdef RE_ENABLE_I18N
@@ -3099,10 +3207,12 @@ extend_buffers (mctx)
if (mctx->state_log != NULL)
{
/* And double the length of state_log. */
- mctx->state_log = re_realloc (mctx->state_log, re_dfastate_t *,
- pstr->bufs_len * 2);
- if (BE (mctx->state_log == NULL, 0))
+ re_dfastate_t **new_array;
+ new_array = re_realloc (mctx->state_log, re_dfastate_t *,
+ pstr->bufs_len * 2);
+ if (BE (new_array == NULL, 0))
return REG_ESPACE;
+ mctx->state_log = new_array;
}
/* Then reconstruct the buffers. */
@@ -3174,13 +3284,17 @@ match_ctx_add_entry (mctx, node, str_idx, from, to)
{
if (mctx->nbkref_ents >= mctx->abkref_ents)
{
- mctx->bkref_ents = re_realloc (mctx->bkref_ents,
- struct re_backref_cache_entry,
- mctx->abkref_ents * 2);
- if (BE (mctx->bkref_ents == NULL, 0))
- return REG_ESPACE;
+ struct re_backref_cache_entry* new_entry;
+ new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
+ mctx->abkref_ents * 2);
+ if (BE (new_entry == NULL, 0))
+ {
+ re_free (mctx->bkref_ents);
+ return REG_ESPACE;
+ }
+ mctx->bkref_ents = new_entry;
memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
- sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
+ sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
mctx->abkref_ents *= 2;
}
mctx->bkref_ents[mctx->nbkref_ents].node = node;