mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-05 21:00:05 +00:00
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.
This commit is contained in:
parent
b14993a235
commit
1b2c262835
43
ChangeLog
43
ChangeLog
@ -1,3 +1,46 @@
|
||||
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.
|
||||
|
||||
2002-11-06 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* configure.in: Add checks on as and ld for binutils 2.13 or later.
|
||||
|
@ -267,10 +267,6 @@ re_compile_pattern (pattern, length, bufp)
|
||||
{
|
||||
reg_errcode_t ret;
|
||||
|
||||
/* GNU code is written to assume at least RE_NREGS registers will be set
|
||||
(and at least one extra will be -1). */
|
||||
bufp->regs_allocated = REGS_UNALLOCATED;
|
||||
|
||||
/* And GNU code determines whether or not to get register information
|
||||
by passing null for the REGS argument to re_match, etc., not by
|
||||
setting no_sub. */
|
||||
@ -339,6 +335,14 @@ re_compile_fastmap (bufp)
|
||||
weak_alias (__re_compile_fastmap, re_compile_fastmap)
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
re_set_fastmap (char *fastmap, int icase, int ch)
|
||||
{
|
||||
fastmap[ch] = 1;
|
||||
if (icase)
|
||||
fastmap[tolower (ch)] = 1;
|
||||
}
|
||||
|
||||
/* Helper function for re_compile_fastmap.
|
||||
Compile fastmap for the initial_state INIT_STATE. */
|
||||
|
||||
@ -350,20 +354,21 @@ re_compile_fastmap_iter (bufp, init_state, fastmap)
|
||||
{
|
||||
re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
|
||||
int node_cnt;
|
||||
int icase = (MB_CUR_MAX == 1 && (bufp->syntax & RE_ICASE));
|
||||
for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
|
||||
{
|
||||
int node = init_state->nodes.elems[node_cnt];
|
||||
re_token_type_t type = dfa->nodes[node].type;
|
||||
|
||||
if (type == CHARACTER)
|
||||
fastmap[dfa->nodes[node].opr.c] = 1;
|
||||
re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
|
||||
else if (type == SIMPLE_BRACKET)
|
||||
{
|
||||
int i, j, ch;
|
||||
for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
|
||||
for (j = 0; j < UINT_BITS; ++j, ++ch)
|
||||
if (dfa->nodes[node].opr.sbcset[i] & (1 << j))
|
||||
fastmap[ch] = 1;
|
||||
re_set_fastmap (fastmap, icase, ch);
|
||||
}
|
||||
#ifdef RE_ENABLE_I18N
|
||||
else if (type == COMPLEX_BRACKET)
|
||||
@ -388,28 +393,24 @@ re_compile_fastmap_iter (bufp, init_state, fastmap)
|
||||
for (i = 0, ch = 0; i < BITSET_UINTS; ++i)
|
||||
for (j = 0; j < UINT_BITS; ++j, ++ch)
|
||||
if (table[ch] < 0)
|
||||
fastmap[ch] = 1;
|
||||
re_set_fastmap (fastmap, icase, ch);
|
||||
}
|
||||
# else
|
||||
if (MB_CUR_MAX > 1)
|
||||
for (i = 0; i < SBC_MAX; ++i)
|
||||
if (__btowc (i) == WEOF)
|
||||
fastmap[i] = 1;
|
||||
re_set_fastmap (fastmap, icase, i);
|
||||
# endif /* not _LIBC */
|
||||
}
|
||||
for (i = 0; i < cset->nmbchars; ++i)
|
||||
{
|
||||
char buf[256];
|
||||
wctomb (buf, cset->mbchars[i]);
|
||||
fastmap[*(unsigned char *) buf] = 1;
|
||||
re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
|
||||
}
|
||||
}
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
else if (type == END_OF_RE || type == OP_PERIOD
|
||||
#ifdef RE_ENABLE_I18N
|
||||
|| type == COMPLEX_BRACKET
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
)
|
||||
else if (type == END_OF_RE || type == OP_PERIOD)
|
||||
{
|
||||
memset (fastmap, '\1', sizeof (char) * SBC_MAX);
|
||||
if (type == END_OF_RE)
|
||||
@ -468,7 +469,6 @@ regcomp (preg, pattern, cflags)
|
||||
preg->buffer = NULL;
|
||||
preg->allocated = 0;
|
||||
preg->used = 0;
|
||||
preg->can_be_null = 0;
|
||||
|
||||
/* Try to allocate space for the fastmap. */
|
||||
preg->fastmap = re_malloc (char, SBC_MAX);
|
||||
@ -667,8 +667,7 @@ re_comp (s)
|
||||
fastmap = re_comp_buf.fastmap;
|
||||
re_comp_buf.fastmap = NULL;
|
||||
__regfree (&re_comp_buf);
|
||||
re_comp_buf.buffer = NULL;
|
||||
re_comp_buf.allocated = 0;
|
||||
memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
|
||||
re_comp_buf.fastmap = fastmap;
|
||||
}
|
||||
|
||||
@ -725,6 +724,8 @@ re_compile_internal (preg, pattern, length, syntax)
|
||||
preg->not_bol = preg->not_eol = 0;
|
||||
preg->used = 0;
|
||||
preg->re_nsub = 0;
|
||||
preg->can_be_null = 0;
|
||||
preg->regs_allocated = REGS_UNALLOCATED;
|
||||
|
||||
/* Initialize the dfa. */
|
||||
dfa = (re_dfa_t *) preg->buffer;
|
||||
|
@ -63,25 +63,25 @@
|
||||
#include "regex_internal.h"
|
||||
|
||||
static void re_string_construct_common (const char *str, int len,
|
||||
re_string_t *pstr,
|
||||
RE_TRANSLATE_TYPE trans, int icase);
|
||||
re_string_t *pstr,
|
||||
RE_TRANSLATE_TYPE trans, int icase);
|
||||
#ifdef RE_ENABLE_I18N
|
||||
static int re_string_skip_chars (re_string_t *pstr, int new_raw_idx);
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
static re_dfastate_t *create_newstate_common (re_dfa_t *dfa,
|
||||
const re_node_set *nodes,
|
||||
unsigned int hash);
|
||||
const re_node_set *nodes,
|
||||
unsigned int hash);
|
||||
static reg_errcode_t register_state (re_dfa_t *dfa, re_dfastate_t *newstate,
|
||||
unsigned int hash);
|
||||
unsigned int hash);
|
||||
static re_dfastate_t *create_ci_newstate (re_dfa_t *dfa,
|
||||
const re_node_set *nodes,
|
||||
unsigned int hash);
|
||||
const re_node_set *nodes,
|
||||
unsigned int hash);
|
||||
static re_dfastate_t *create_cd_newstate (re_dfa_t *dfa,
|
||||
const re_node_set *nodes,
|
||||
unsigned int context,
|
||||
unsigned int hash);
|
||||
const re_node_set *nodes,
|
||||
unsigned int context,
|
||||
unsigned int hash);
|
||||
static unsigned int inline calc_state_hash (const re_node_set *nodes,
|
||||
unsigned int context);
|
||||
unsigned int context);
|
||||
|
||||
/* Functions for string operation. */
|
||||
|
||||
@ -105,10 +105,10 @@ re_string_allocate (pstr, str, len, init_len, trans, icase)
|
||||
return ret;
|
||||
|
||||
pstr->mbs_case = (MBS_CASE_ALLOCATED (pstr) ? pstr->mbs_case
|
||||
: (unsigned char *) str);
|
||||
: (unsigned char *) str);
|
||||
pstr->mbs = MBS_ALLOCATED (pstr) ? pstr->mbs : pstr->mbs_case;
|
||||
pstr->valid_len = (MBS_CASE_ALLOCATED (pstr) || MBS_ALLOCATED (pstr)
|
||||
|| MB_CUR_MAX > 1) ? pstr->valid_len : len;
|
||||
|| MB_CUR_MAX > 1) ? pstr->valid_len : len;
|
||||
return REG_NOERROR;
|
||||
}
|
||||
|
||||
@ -131,34 +131,34 @@ re_string_construct (pstr, str, len, trans, icase)
|
||||
{
|
||||
ret = re_string_realloc_buffers (pstr, len + 1);
|
||||
if (BE (ret != REG_NOERROR, 0))
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
pstr->mbs_case = (MBS_CASE_ALLOCATED (pstr) ? pstr->mbs_case
|
||||
: (unsigned char *) str);
|
||||
: (unsigned char *) str);
|
||||
pstr->mbs = MBS_ALLOCATED (pstr) ? pstr->mbs : pstr->mbs_case;
|
||||
|
||||
if (icase)
|
||||
{
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (MB_CUR_MAX > 1)
|
||||
build_wcs_upper_buffer (pstr);
|
||||
build_wcs_upper_buffer (pstr);
|
||||
else
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
build_upper_buffer (pstr);
|
||||
build_upper_buffer (pstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (MB_CUR_MAX > 1)
|
||||
build_wcs_buffer (pstr);
|
||||
build_wcs_buffer (pstr);
|
||||
else
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
{
|
||||
if (trans != NULL)
|
||||
re_string_translate_buffer (pstr);
|
||||
else
|
||||
pstr->valid_len = len;
|
||||
}
|
||||
{
|
||||
if (trans != NULL)
|
||||
re_string_translate_buffer (pstr);
|
||||
else
|
||||
pstr->valid_len = len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialized whole buffers, then valid_len == bufs_len. */
|
||||
@ -176,24 +176,29 @@ re_string_realloc_buffers (pstr, new_buf_len)
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (MB_CUR_MAX > 1)
|
||||
{
|
||||
pstr->wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
|
||||
if (BE (pstr->wcs == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
wint_t *new_array = re_realloc (pstr->wcs, wint_t, new_buf_len);
|
||||
if (BE (new_array == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
pstr->wcs = new_array;
|
||||
}
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
if (MBS_ALLOCATED (pstr))
|
||||
{
|
||||
pstr->mbs = re_realloc (pstr->mbs, unsigned char, new_buf_len);
|
||||
if (BE (pstr->mbs == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
unsigned char *new_array = re_realloc (pstr->mbs, unsigned char,
|
||||
new_buf_len);
|
||||
if (BE (new_array == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
pstr->mbs = new_array;
|
||||
}
|
||||
if (MBS_CASE_ALLOCATED (pstr))
|
||||
{
|
||||
pstr->mbs_case = re_realloc (pstr->mbs_case, unsigned char, new_buf_len);
|
||||
if (BE (pstr->mbs_case == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
unsigned char *new_array = re_realloc (pstr->mbs_case, unsigned char,
|
||||
new_buf_len);
|
||||
if (BE (new_array == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
pstr->mbs_case = new_array;
|
||||
if (!MBS_ALLOCATED (pstr))
|
||||
pstr->mbs = pstr->mbs_case;
|
||||
pstr->mbs = pstr->mbs_case;
|
||||
}
|
||||
pstr->bufs_len = new_buf_len;
|
||||
return REG_NOERROR;
|
||||
@ -243,32 +248,32 @@ build_wcs_buffer (pstr)
|
||||
remain_len = end_idx - byte_idx;
|
||||
prev_st = pstr->cur_state;
|
||||
mbclen = mbrtowc (&wc, ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
|
||||
+ byte_idx), remain_len, &pstr->cur_state);
|
||||
+ byte_idx), remain_len, &pstr->cur_state);
|
||||
if (BE (mbclen == (size_t) -2, 0))
|
||||
{
|
||||
/* The buffer doesn't have enough space, finish to build. */
|
||||
pstr->cur_state = prev_st;
|
||||
break;
|
||||
}
|
||||
{
|
||||
/* The buffer doesn't have enough space, finish to build. */
|
||||
pstr->cur_state = prev_st;
|
||||
break;
|
||||
}
|
||||
else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
|
||||
{
|
||||
/* We treat these cases as a singlebyte character. */
|
||||
mbclen = 1;
|
||||
wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
|
||||
pstr->cur_state = prev_st;
|
||||
}
|
||||
{
|
||||
/* We treat these cases as a singlebyte character. */
|
||||
mbclen = 1;
|
||||
wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
|
||||
pstr->cur_state = prev_st;
|
||||
}
|
||||
|
||||
/* Apply the translateion if we need. */
|
||||
if (pstr->trans != NULL && mbclen == 1)
|
||||
{
|
||||
int ch = pstr->trans[pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]];
|
||||
pstr->mbs_case[byte_idx] = ch;
|
||||
}
|
||||
{
|
||||
int ch = pstr->trans[pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]];
|
||||
pstr->mbs_case[byte_idx] = ch;
|
||||
}
|
||||
/* Write wide character and padding. */
|
||||
pstr->wcs[byte_idx++] = wc;
|
||||
/* Write paddings. */
|
||||
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
|
||||
pstr->wcs[byte_idx++] = WEOF;
|
||||
pstr->wcs[byte_idx++] = WEOF;
|
||||
}
|
||||
pstr->valid_len = byte_idx;
|
||||
}
|
||||
@ -291,40 +296,40 @@ build_wcs_upper_buffer (pstr)
|
||||
remain_len = end_idx - byte_idx;
|
||||
prev_st = pstr->cur_state;
|
||||
mbclen = mbrtowc (&wc, ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
|
||||
+ byte_idx), remain_len, &pstr->cur_state);
|
||||
+ byte_idx), remain_len, &pstr->cur_state);
|
||||
if (BE (mbclen == (size_t) -2, 0))
|
||||
{
|
||||
/* The buffer doesn't have enough space, finish to build. */
|
||||
pstr->cur_state = prev_st;
|
||||
break;
|
||||
}
|
||||
{
|
||||
/* The buffer doesn't have enough space, finish to build. */
|
||||
pstr->cur_state = prev_st;
|
||||
break;
|
||||
}
|
||||
else if (mbclen == 1 || mbclen == (size_t) -1 || mbclen == 0)
|
||||
{
|
||||
/* In case of a singlebyte character. */
|
||||
int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
|
||||
/* Apply the translateion if we need. */
|
||||
if (pstr->trans != NULL && mbclen == 1)
|
||||
{
|
||||
ch = pstr->trans[ch];
|
||||
pstr->mbs_case[byte_idx] = ch;
|
||||
}
|
||||
pstr->wcs[byte_idx] = iswlower (wc) ? toupper (wc) : wc;
|
||||
pstr->mbs[byte_idx++] = islower (ch) ? toupper (ch) : ch;
|
||||
if (BE (mbclen == (size_t) -1, 0))
|
||||
pstr->cur_state = prev_st;
|
||||
}
|
||||
{
|
||||
/* In case of a singlebyte character. */
|
||||
int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
|
||||
/* Apply the translateion if we need. */
|
||||
if (pstr->trans != NULL && mbclen == 1)
|
||||
{
|
||||
ch = pstr->trans[ch];
|
||||
pstr->mbs_case[byte_idx] = ch;
|
||||
}
|
||||
pstr->wcs[byte_idx] = iswlower (wc) ? toupper (wc) : wc;
|
||||
pstr->mbs[byte_idx++] = islower (ch) ? toupper (ch) : ch;
|
||||
if (BE (mbclen == (size_t) -1, 0))
|
||||
pstr->cur_state = prev_st;
|
||||
}
|
||||
else /* mbclen > 1 */
|
||||
{
|
||||
if (iswlower (wc))
|
||||
wcrtomb ((char *) pstr->mbs + byte_idx, towupper (wc), &prev_st);
|
||||
else
|
||||
memcpy (pstr->mbs + byte_idx,
|
||||
pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
|
||||
pstr->wcs[byte_idx++] = iswlower (wc) ? toupper (wc) : wc;
|
||||
/* Write paddings. */
|
||||
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
|
||||
pstr->wcs[byte_idx++] = WEOF;
|
||||
}
|
||||
{
|
||||
if (iswlower (wc))
|
||||
wcrtomb ((char *) pstr->mbs + byte_idx, towupper (wc), &prev_st);
|
||||
else
|
||||
memcpy (pstr->mbs + byte_idx,
|
||||
pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
|
||||
pstr->wcs[byte_idx++] = iswlower (wc) ? toupper (wc) : wc;
|
||||
/* Write paddings. */
|
||||
for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
|
||||
pstr->wcs[byte_idx++] = WEOF;
|
||||
}
|
||||
}
|
||||
pstr->valid_len = byte_idx;
|
||||
}
|
||||
@ -347,13 +352,13 @@ re_string_skip_chars (pstr, new_raw_idx)
|
||||
int remain_len = pstr->len - rawbuf_idx;
|
||||
prev_st = pstr->cur_state;
|
||||
mbclen = mbrlen ((const char *) pstr->raw_mbs + rawbuf_idx, remain_len,
|
||||
&pstr->cur_state);
|
||||
&pstr->cur_state);
|
||||
if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
|
||||
{
|
||||
/* We treat these cases as a singlebyte character. */
|
||||
mbclen = 1;
|
||||
pstr->cur_state = prev_st;
|
||||
}
|
||||
{
|
||||
/* We treat these cases as a singlebyte character. */
|
||||
mbclen = 1;
|
||||
pstr->cur_state = prev_st;
|
||||
}
|
||||
/* Then proceed the next character. */
|
||||
rawbuf_idx += mbclen;
|
||||
}
|
||||
@ -361,7 +366,7 @@ re_string_skip_chars (pstr, new_raw_idx)
|
||||
}
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
|
||||
/* Build the buffer PSTR->MBS, and apply the translation if we need.
|
||||
/* Build the buffer PSTR->MBS, and apply the translation if we need.
|
||||
This function is used in case of REG_ICASE. */
|
||||
|
||||
static void
|
||||
@ -375,14 +380,14 @@ build_upper_buffer (pstr)
|
||||
{
|
||||
int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
|
||||
if (pstr->trans != NULL)
|
||||
{
|
||||
ch = pstr->trans[ch];
|
||||
pstr->mbs_case[char_idx] = ch;
|
||||
}
|
||||
{
|
||||
ch = pstr->trans[ch];
|
||||
pstr->mbs_case[char_idx] = ch;
|
||||
}
|
||||
if (islower (ch))
|
||||
pstr->mbs[char_idx] = toupper (ch);
|
||||
pstr->mbs[char_idx] = toupper (ch);
|
||||
else
|
||||
pstr->mbs[char_idx] = ch;
|
||||
pstr->mbs[char_idx] = ch;
|
||||
}
|
||||
pstr->valid_len = char_idx;
|
||||
}
|
||||
@ -420,65 +425,65 @@ re_string_reconstruct (pstr, idx, eflags, newline)
|
||||
/* Reset buffer. */
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (MB_CUR_MAX > 1)
|
||||
memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
|
||||
memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
pstr->len += pstr->raw_mbs_idx;
|
||||
pstr->stop += pstr->raw_mbs_idx;
|
||||
pstr->valid_len = pstr->raw_mbs_idx = 0;
|
||||
pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
|
||||
: CONTEXT_NEWLINE | CONTEXT_BEGBUF);
|
||||
: CONTEXT_NEWLINE | CONTEXT_BEGBUF);
|
||||
if (!MBS_CASE_ALLOCATED (pstr))
|
||||
pstr->mbs_case = (unsigned char *) pstr->raw_mbs;
|
||||
pstr->mbs_case = (unsigned char *) pstr->raw_mbs;
|
||||
if (!MBS_ALLOCATED (pstr) && !MBS_CASE_ALLOCATED (pstr))
|
||||
pstr->mbs = (unsigned char *) pstr->raw_mbs;
|
||||
pstr->mbs = (unsigned char *) pstr->raw_mbs;
|
||||
offset = idx;
|
||||
}
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
pstr->tip_context = re_string_context_at (pstr, offset - 1, eflags,
|
||||
newline);
|
||||
newline);
|
||||
/* Are the characters which are already checked remain? */
|
||||
if (offset < pstr->valid_len)
|
||||
{
|
||||
/* Yes, move them to the front of the buffer. */
|
||||
{
|
||||
/* Yes, move them to the front of the buffer. */
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (MB_CUR_MAX > 1)
|
||||
memmove (pstr->wcs, pstr->wcs + offset,
|
||||
(pstr->valid_len - offset) * sizeof (wint_t));
|
||||
if (MB_CUR_MAX > 1)
|
||||
memmove (pstr->wcs, pstr->wcs + offset,
|
||||
(pstr->valid_len - offset) * sizeof (wint_t));
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
if (MBS_ALLOCATED (pstr))
|
||||
memmove (pstr->mbs, pstr->mbs + offset,
|
||||
pstr->valid_len - offset);
|
||||
if (MBS_CASE_ALLOCATED (pstr))
|
||||
memmove (pstr->mbs_case, pstr->mbs_case + offset,
|
||||
pstr->valid_len - offset);
|
||||
pstr->valid_len -= offset;
|
||||
if (MBS_ALLOCATED (pstr))
|
||||
memmove (pstr->mbs, pstr->mbs + offset,
|
||||
pstr->valid_len - offset);
|
||||
if (MBS_CASE_ALLOCATED (pstr))
|
||||
memmove (pstr->mbs_case, pstr->mbs_case + offset,
|
||||
pstr->valid_len - offset);
|
||||
pstr->valid_len -= offset;
|
||||
#if DEBUG
|
||||
assert (pstr->valid_len > 0);
|
||||
assert (pstr->valid_len > 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No, skip all characters until IDX. */
|
||||
pstr->valid_len = 0;
|
||||
{
|
||||
/* No, skip all characters until IDX. */
|
||||
pstr->valid_len = 0;
|
||||
#ifdef RE_ENABLE_I18N
|
||||
if (MB_CUR_MAX > 1)
|
||||
{
|
||||
int wcs_idx;
|
||||
pstr->valid_len = re_string_skip_chars (pstr, idx) - idx;
|
||||
for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
|
||||
pstr->wcs[wcs_idx] = WEOF;
|
||||
}
|
||||
if (MB_CUR_MAX > 1)
|
||||
{
|
||||
int wcs_idx;
|
||||
pstr->valid_len = re_string_skip_chars (pstr, idx) - idx;
|
||||
for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
|
||||
pstr->wcs[wcs_idx] = WEOF;
|
||||
}
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
}
|
||||
}
|
||||
if (!MBS_CASE_ALLOCATED (pstr))
|
||||
{
|
||||
pstr->mbs_case += offset;
|
||||
/* In case of !MBS_ALLOCATED && !MBS_CASE_ALLOCATED. */
|
||||
if (!MBS_ALLOCATED (pstr))
|
||||
pstr->mbs += offset;
|
||||
}
|
||||
{
|
||||
pstr->mbs_case += offset;
|
||||
/* In case of !MBS_ALLOCATED && !MBS_CASE_ALLOCATED. */
|
||||
if (!MBS_ALLOCATED (pstr))
|
||||
pstr->mbs += offset;
|
||||
}
|
||||
}
|
||||
pstr->raw_mbs_idx = idx;
|
||||
pstr->len -= offset;
|
||||
@ -489,17 +494,17 @@ re_string_reconstruct (pstr, idx, eflags, newline)
|
||||
if (MB_CUR_MAX > 1)
|
||||
{
|
||||
if (pstr->icase)
|
||||
build_wcs_upper_buffer (pstr);
|
||||
build_wcs_upper_buffer (pstr);
|
||||
else
|
||||
build_wcs_buffer (pstr);
|
||||
build_wcs_buffer (pstr);
|
||||
}
|
||||
else
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
{
|
||||
if (pstr->icase)
|
||||
build_upper_buffer (pstr);
|
||||
build_upper_buffer (pstr);
|
||||
else if (pstr->trans != NULL)
|
||||
re_string_translate_buffer (pstr);
|
||||
re_string_translate_buffer (pstr);
|
||||
}
|
||||
pstr->cur_idx = 0;
|
||||
|
||||
@ -530,12 +535,12 @@ re_string_context_at (input, idx, eflags, newline_anchor)
|
||||
if (idx < 0 || idx == input->len)
|
||||
{
|
||||
if (idx < 0)
|
||||
/* In this case, we use the value stored in input->tip_context,
|
||||
since we can't know the character in input->mbs[-1] here. */
|
||||
return input->tip_context;
|
||||
/* In this case, we use the value stored in input->tip_context,
|
||||
since we can't know the character in input->mbs[-1] here. */
|
||||
return input->tip_context;
|
||||
else /* (idx == input->len) */
|
||||
return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
|
||||
: CONTEXT_NEWLINE | CONTEXT_ENDBUF);
|
||||
return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
|
||||
: CONTEXT_NEWLINE | CONTEXT_ENDBUF);
|
||||
}
|
||||
c = re_string_byte_at (input, idx);
|
||||
if (IS_WORD_CHAR (c))
|
||||
@ -590,15 +595,15 @@ re_node_set_init_2 (set, elem1, elem2)
|
||||
{
|
||||
set->nelem = 2;
|
||||
if (elem1 < elem2)
|
||||
{
|
||||
set->elems[0] = elem1;
|
||||
set->elems[1] = elem2;
|
||||
}
|
||||
{
|
||||
set->elems[0] = elem1;
|
||||
set->elems[1] = elem2;
|
||||
}
|
||||
else
|
||||
{
|
||||
set->elems[0] = elem2;
|
||||
set->elems[1] = elem1;
|
||||
}
|
||||
{
|
||||
set->elems[0] = elem2;
|
||||
set->elems[1] = elem1;
|
||||
}
|
||||
}
|
||||
return REG_NOERROR;
|
||||
}
|
||||
@ -614,7 +619,7 @@ re_node_set_init_copy (dest, src)
|
||||
dest->alloc = dest->nelem;
|
||||
dest->elems = re_malloc (int, dest->alloc);
|
||||
if (BE (dest->elems == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
return REG_ESPACE;
|
||||
memcpy (dest->elems, src->elems, src->nelem * sizeof (int));
|
||||
}
|
||||
else
|
||||
@ -635,12 +640,12 @@ re_node_set_add_intersect (dest, src1, src2)
|
||||
if (src1->nelem > 0 && src2->nelem > 0)
|
||||
{
|
||||
if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
|
||||
{
|
||||
dest->alloc = src1->nelem + src2->nelem + dest->nelem;
|
||||
dest->elems = re_realloc (dest->elems, int, dest->alloc);
|
||||
if (BE (dest->elems == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
}
|
||||
{
|
||||
dest->alloc = src1->nelem + src2->nelem + dest->nelem;
|
||||
dest->elems = re_realloc (dest->elems, int, dest->alloc);
|
||||
if (BE (dest->elems == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
}
|
||||
}
|
||||
else
|
||||
return REG_NOERROR;
|
||||
@ -648,24 +653,24 @@ re_node_set_add_intersect (dest, src1, src2)
|
||||
for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
|
||||
{
|
||||
if (src1->elems[i1] > src2->elems[i2])
|
||||
{
|
||||
++i2;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
++i2;
|
||||
continue;
|
||||
}
|
||||
if (src1->elems[i1] == src2->elems[i2])
|
||||
{
|
||||
while (id < dest->nelem && dest->elems[id] < src2->elems[i2])
|
||||
++id;
|
||||
if (id < dest->nelem && dest->elems[id] == src2->elems[i2])
|
||||
++id;
|
||||
else
|
||||
{
|
||||
memmove (dest->elems + id + 1, dest->elems + id,
|
||||
sizeof (int) * (dest->nelem - id));
|
||||
dest->elems[id++] = src2->elems[i2++];
|
||||
++dest->nelem;
|
||||
}
|
||||
}
|
||||
{
|
||||
while (id < dest->nelem && dest->elems[id] < src2->elems[i2])
|
||||
++id;
|
||||
if (id < dest->nelem && dest->elems[id] == src2->elems[i2])
|
||||
++id;
|
||||
else
|
||||
{
|
||||
memmove (dest->elems + id + 1, dest->elems + id,
|
||||
sizeof (int) * (dest->nelem - id));
|
||||
dest->elems[id++] = src2->elems[i2++];
|
||||
++dest->nelem;
|
||||
}
|
||||
}
|
||||
++i1;
|
||||
}
|
||||
return REG_NOERROR;
|
||||
@ -685,39 +690,39 @@ re_node_set_init_union (dest, src1, src2)
|
||||
dest->alloc = src1->nelem + src2->nelem;
|
||||
dest->elems = re_malloc (int, dest->alloc);
|
||||
if (BE (dest->elems == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
return REG_ESPACE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (src1 != NULL && src1->nelem > 0)
|
||||
return re_node_set_init_copy (dest, src1);
|
||||
return re_node_set_init_copy (dest, src1);
|
||||
else if (src2 != NULL && src2->nelem > 0)
|
||||
return re_node_set_init_copy (dest, src2);
|
||||
return re_node_set_init_copy (dest, src2);
|
||||
else
|
||||
re_node_set_init_empty (dest);
|
||||
re_node_set_init_empty (dest);
|
||||
return REG_NOERROR;
|
||||
}
|
||||
for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
|
||||
{
|
||||
if (src1->elems[i1] > src2->elems[i2])
|
||||
{
|
||||
dest->elems[id++] = src2->elems[i2++];
|
||||
continue;
|
||||
}
|
||||
{
|
||||
dest->elems[id++] = src2->elems[i2++];
|
||||
continue;
|
||||
}
|
||||
if (src1->elems[i1] == src2->elems[i2])
|
||||
++i2;
|
||||
++i2;
|
||||
dest->elems[id++] = src1->elems[i1++];
|
||||
}
|
||||
if (i1 < src1->nelem)
|
||||
{
|
||||
memcpy (dest->elems + id, src1->elems + i1,
|
||||
(src1->nelem - i1) * sizeof (int));
|
||||
(src1->nelem - i1) * sizeof (int));
|
||||
id += src1->nelem - i1;
|
||||
}
|
||||
else if (i2 < src2->nelem)
|
||||
{
|
||||
memcpy (dest->elems + id, src2->elems + i2,
|
||||
(src2->nelem - i2) * sizeof (int));
|
||||
(src2->nelem - i2) * sizeof (int));
|
||||
id += src2->nelem - i2;
|
||||
}
|
||||
dest->nelem = id;
|
||||
@ -737,10 +742,12 @@ re_node_set_merge (dest, src)
|
||||
return REG_NOERROR;
|
||||
if (dest->alloc < src->nelem + dest->nelem)
|
||||
{
|
||||
int *new_buffer;
|
||||
dest->alloc = 2 * (src->nelem + dest->alloc);
|
||||
dest->elems = re_realloc (dest->elems, int, dest->alloc);
|
||||
if (BE (dest->elems == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
new_buffer = re_realloc (dest->elems, int, dest->alloc);
|
||||
if (BE (new_buffer == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
dest->elems = new_buffer;
|
||||
}
|
||||
|
||||
for (si = 0, di = 0 ; si < src->nelem && di < dest->nelem ;)
|
||||
@ -749,34 +756,34 @@ re_node_set_merge (dest, src)
|
||||
/* Binary search the spot we will add the new element. */
|
||||
right = dest->nelem;
|
||||
while (di < right)
|
||||
{
|
||||
mid = (di + right) / 2;
|
||||
if (dest->elems[mid] < src_elem)
|
||||
di = mid + 1;
|
||||
else
|
||||
right = mid;
|
||||
}
|
||||
{
|
||||
mid = (di + right) / 2;
|
||||
if (dest->elems[mid] < src_elem)
|
||||
di = mid + 1;
|
||||
else
|
||||
right = mid;
|
||||
}
|
||||
if (di >= dest->nelem)
|
||||
break;
|
||||
break;
|
||||
|
||||
if (dest->elems[di] == src_elem)
|
||||
{
|
||||
/* Skip since, DEST already has the element. */
|
||||
++di;
|
||||
++si;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
/* Skip since, DEST already has the element. */
|
||||
++di;
|
||||
++si;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip the src elements which are less than dest->elems[di]. */
|
||||
cp_from = si;
|
||||
while (si < src->nelem && src->elems[si] < dest->elems[di])
|
||||
++si;
|
||||
++si;
|
||||
/* Copy these src elements. */
|
||||
ncp = si - cp_from;
|
||||
memmove (dest->elems + di + ncp, dest->elems + di,
|
||||
sizeof (int) * (dest->nelem - di));
|
||||
sizeof (int) * (dest->nelem - di));
|
||||
memcpy (dest->elems + di, src->elems + cp_from,
|
||||
sizeof (int) * ncp);
|
||||
sizeof (int) * ncp);
|
||||
/* Update counters. */
|
||||
di += ncp;
|
||||
dest->nelem += ncp;
|
||||
@ -786,7 +793,7 @@ re_node_set_merge (dest, src)
|
||||
if (si < src->nelem)
|
||||
{
|
||||
memcpy (dest->elems + di, src->elems + si,
|
||||
sizeof (int) * (src->nelem - si));
|
||||
sizeof (int) * (src->nelem - si));
|
||||
dest->nelem += src->nelem - si;
|
||||
}
|
||||
return REG_NOERROR;
|
||||
@ -806,9 +813,9 @@ re_node_set_insert (set, elem)
|
||||
if (set->elems == NULL || set->alloc == 0)
|
||||
{
|
||||
if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1))
|
||||
return 1;
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Binary search the spot we will add the new element. */
|
||||
@ -818,9 +825,9 @@ re_node_set_insert (set, elem)
|
||||
{
|
||||
mid = (idx + right) / 2;
|
||||
if (set->elems[mid] < elem)
|
||||
idx = mid + 1;
|
||||
idx = mid + 1;
|
||||
else
|
||||
right = mid;
|
||||
right = mid;
|
||||
}
|
||||
|
||||
/* Realloc if we need. */
|
||||
@ -830,13 +837,13 @@ re_node_set_insert (set, elem)
|
||||
set->alloc = set->alloc * 2;
|
||||
new_array = re_malloc (int, set->alloc);
|
||||
if (BE (new_array == NULL, 0))
|
||||
return -1;
|
||||
return -1;
|
||||
/* Copy the elements they are followed by the new element. */
|
||||
if (idx > 0)
|
||||
memcpy (new_array, set->elems, sizeof (int) * (idx));
|
||||
memcpy (new_array, set->elems, sizeof (int) * (idx));
|
||||
/* Copy the elements which follows the new element. */
|
||||
if (set->nelem - idx > 0)
|
||||
memcpy (new_array + idx + 1, set->elems + idx,
|
||||
memcpy (new_array + idx + 1, set->elems + idx,
|
||||
sizeof (int) * (set->nelem - idx));
|
||||
re_free (set->elems);
|
||||
set->elems = new_array;
|
||||
@ -845,8 +852,8 @@ re_node_set_insert (set, elem)
|
||||
{
|
||||
/* Move the elements which follows the new element. */
|
||||
if (set->nelem - idx > 0)
|
||||
memmove (set->elems + idx + 1, set->elems + idx,
|
||||
sizeof (int) * (set->nelem - idx));
|
||||
memmove (set->elems + idx + 1, set->elems + idx,
|
||||
sizeof (int) * (set->nelem - idx));
|
||||
}
|
||||
/* Insert the new element. */
|
||||
set->elems[idx] = elem;
|
||||
@ -888,9 +895,9 @@ re_node_set_contains (set, elem)
|
||||
{
|
||||
mid = (idx + right) / 2;
|
||||
if (set->elems[mid] < elem)
|
||||
idx = mid + 1;
|
||||
idx = mid + 1;
|
||||
else
|
||||
right = mid;
|
||||
right = mid;
|
||||
}
|
||||
return set->elems[idx] == elem ? idx + 1 : 0;
|
||||
}
|
||||
@ -904,7 +911,7 @@ re_node_set_remove_at (set, idx)
|
||||
return;
|
||||
if (idx < set->nelem - 1)
|
||||
memmove (set->elems + idx, set->elems + idx + 1,
|
||||
sizeof (int) * (set->nelem - idx - 1));
|
||||
sizeof (int) * (set->nelem - idx - 1));
|
||||
--set->nelem;
|
||||
}
|
||||
|
||||
@ -924,28 +931,28 @@ re_dfa_add_node (dfa, token, mode)
|
||||
dfa->nodes_alloc *= 2;
|
||||
new_array = re_realloc (dfa->nodes, re_token_t, dfa->nodes_alloc);
|
||||
if (BE (new_array == NULL, 0))
|
||||
return -1;
|
||||
return -1;
|
||||
else
|
||||
dfa->nodes = new_array;
|
||||
dfa->nodes = new_array;
|
||||
if (mode)
|
||||
{
|
||||
int *new_nexts;
|
||||
re_node_set *new_edests, *new_eclosures, *new_inveclosures;
|
||||
{
|
||||
int *new_nexts;
|
||||
re_node_set *new_edests, *new_eclosures, *new_inveclosures;
|
||||
|
||||
new_nexts = re_realloc (dfa->nexts, int, dfa->nodes_alloc);
|
||||
new_edests = re_realloc (dfa->edests, re_node_set, dfa->nodes_alloc);
|
||||
new_eclosures = re_realloc (dfa->eclosures, re_node_set,
|
||||
dfa->nodes_alloc);
|
||||
new_inveclosures = re_realloc (dfa->inveclosures, re_node_set,
|
||||
dfa->nodes_alloc);
|
||||
if (BE (new_nexts == NULL || new_edests == NULL
|
||||
|| new_eclosures == NULL || new_inveclosures == NULL, 0))
|
||||
return -1;
|
||||
dfa->nexts = new_nexts;
|
||||
dfa->edests = new_edests;
|
||||
dfa->eclosures = new_eclosures;
|
||||
dfa->inveclosures = new_inveclosures;
|
||||
}
|
||||
new_nexts = re_realloc (dfa->nexts, int, dfa->nodes_alloc);
|
||||
new_edests = re_realloc (dfa->edests, re_node_set, dfa->nodes_alloc);
|
||||
new_eclosures = re_realloc (dfa->eclosures, re_node_set,
|
||||
dfa->nodes_alloc);
|
||||
new_inveclosures = re_realloc (dfa->inveclosures, re_node_set,
|
||||
dfa->nodes_alloc);
|
||||
if (BE (new_nexts == NULL || new_edests == NULL
|
||||
|| new_eclosures == NULL || new_inveclosures == NULL, 0))
|
||||
return -1;
|
||||
dfa->nexts = new_nexts;
|
||||
dfa->edests = new_edests;
|
||||
dfa->eclosures = new_eclosures;
|
||||
dfa->inveclosures = new_inveclosures;
|
||||
}
|
||||
}
|
||||
dfa->nodes[dfa->nodes_len] = token;
|
||||
dfa->nodes[dfa->nodes_len].duplicated = 0;
|
||||
@ -970,9 +977,9 @@ calc_state_hash (nodes, context)
|
||||
Otherwise create the new one and return it. In case of an error
|
||||
return NULL and set the error code in ERR.
|
||||
Note: - We assume NULL as the invalid state, then it is possible that
|
||||
return value is NULL and ERR is REG_NOERROR.
|
||||
- We never return non-NULL value in case of any errors, it is for
|
||||
optimization. */
|
||||
return value is NULL and ERR is REG_NOERROR.
|
||||
- We never return non-NULL value in case of any errors, it is for
|
||||
optimization. */
|
||||
|
||||
static re_dfastate_t*
|
||||
re_acquire_state (err, dfa, nodes)
|
||||
@ -996,9 +1003,9 @@ re_acquire_state (err, dfa, nodes)
|
||||
{
|
||||
re_dfastate_t *state = spot->array[i];
|
||||
if (hash != state->hash)
|
||||
continue;
|
||||
continue;
|
||||
if (re_node_set_compare (&state->nodes, nodes))
|
||||
return state;
|
||||
return state;
|
||||
}
|
||||
|
||||
/* There are no appropriate state in the dfa, create the new one. */
|
||||
@ -1018,9 +1025,9 @@ re_acquire_state (err, dfa, nodes)
|
||||
Otherwise create the new one and return it. In case of an error
|
||||
return NULL and set the error code in ERR.
|
||||
Note: - We assume NULL as the invalid state, then it is possible that
|
||||
return value is NULL and ERR is REG_NOERROR.
|
||||
- We never return non-NULL value in case of any errors, it is for
|
||||
optimization. */
|
||||
return value is NULL and ERR is REG_NOERROR.
|
||||
- We never return non-NULL value in case of any errors, it is for
|
||||
optimization. */
|
||||
|
||||
static re_dfastate_t*
|
||||
re_acquire_state_context (err, dfa, nodes, context)
|
||||
@ -1045,10 +1052,10 @@ re_acquire_state_context (err, dfa, nodes, context)
|
||||
{
|
||||
re_dfastate_t *state = spot->array[i];
|
||||
if (hash != state->hash)
|
||||
continue;
|
||||
continue;
|
||||
if (re_node_set_compare (state->entrance_nodes, nodes)
|
||||
&& state->context == context)
|
||||
return state;
|
||||
&& state->context == context)
|
||||
return state;
|
||||
}
|
||||
/* There are no appropriate state in `dfa', create the new one. */
|
||||
new_state = create_cd_newstate (dfa, nodes, context, hash);
|
||||
@ -1071,10 +1078,16 @@ create_newstate_common (dfa, nodes, hash)
|
||||
unsigned int hash;
|
||||
{
|
||||
re_dfastate_t *newstate;
|
||||
reg_errcode_t err;
|
||||
newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
|
||||
if (BE (newstate == NULL, 0))
|
||||
return NULL;
|
||||
re_node_set_init_copy (&newstate->nodes, nodes);
|
||||
err = re_node_set_init_copy (&newstate->nodes, nodes);
|
||||
if (BE (err != REG_NOERROR, 0))
|
||||
{
|
||||
re_free (newstate);
|
||||
return NULL;
|
||||
}
|
||||
newstate->trtable = NULL;
|
||||
newstate->trtable_search = NULL;
|
||||
newstate->hash = hash;
|
||||
@ -1095,10 +1108,12 @@ register_state (dfa, newstate, hash)
|
||||
|
||||
if (spot->alloc <= spot->num)
|
||||
{
|
||||
re_dfastate_t **new_array;
|
||||
spot->alloc = 2 * spot->num + 2;
|
||||
spot->array = re_realloc (spot->array, re_dfastate_t *, spot->alloc);
|
||||
if (BE (spot->array == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
new_array = re_realloc (spot->array, re_dfastate_t *, spot->alloc);
|
||||
if (BE (new_array == NULL, 0))
|
||||
return REG_ESPACE;
|
||||
spot->array = new_array;
|
||||
}
|
||||
spot->array[spot->num++] = newstate;
|
||||
return REG_NOERROR;
|
||||
@ -1126,23 +1141,28 @@ create_ci_newstate (dfa, nodes, hash)
|
||||
re_token_t *node = dfa->nodes + nodes->elems[i];
|
||||
re_token_type_t type = node->type;
|
||||
if (type == CHARACTER && !node->constraint)
|
||||
continue;
|
||||
continue;
|
||||
|
||||
/* If the state has the halt node, the state is a halt state. */
|
||||
else if (type == END_OF_RE)
|
||||
newstate->halt = 1;
|
||||
newstate->halt = 1;
|
||||
#ifdef RE_ENABLE_I18N
|
||||
else if (type == COMPLEX_BRACKET
|
||||
|| (type == OP_PERIOD && MB_CUR_MAX > 1))
|
||||
newstate->accept_mb = 1;
|
||||
|| (type == OP_PERIOD && MB_CUR_MAX > 1))
|
||||
newstate->accept_mb = 1;
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
else if (type == OP_BACK_REF)
|
||||
newstate->has_backref = 1;
|
||||
newstate->has_backref = 1;
|
||||
else if (type == ANCHOR || node->constraint)
|
||||
newstate->has_constraint = 1;
|
||||
newstate->has_constraint = 1;
|
||||
}
|
||||
err = register_state (dfa, newstate, hash);
|
||||
return (err != REG_NOERROR) ? NULL : newstate;
|
||||
if (BE (err != REG_NOERROR, 0))
|
||||
{
|
||||
free_state (newstate);
|
||||
newstate = NULL;
|
||||
}
|
||||
return newstate;
|
||||
}
|
||||
|
||||
/* Create the new state which is depend on the context CONTEXT.
|
||||
@ -1170,42 +1190,65 @@ create_cd_newstate (dfa, nodes, context, hash)
|
||||
re_token_t *node = dfa->nodes + nodes->elems[i];
|
||||
re_token_type_t type = node->type;
|
||||
if (node->constraint)
|
||||
constraint = node->constraint;
|
||||
constraint = node->constraint;
|
||||
|
||||
if (type == CHARACTER && !constraint)
|
||||
continue;
|
||||
continue;
|
||||
/* If the state has the halt node, the state is a halt state. */
|
||||
else if (type == END_OF_RE)
|
||||
newstate->halt = 1;
|
||||
newstate->halt = 1;
|
||||
#ifdef RE_ENABLE_I18N
|
||||
else if (type == COMPLEX_BRACKET
|
||||
|| (type == OP_PERIOD && MB_CUR_MAX > 1))
|
||||
newstate->accept_mb = 1;
|
||||
|| (type == OP_PERIOD && MB_CUR_MAX > 1))
|
||||
newstate->accept_mb = 1;
|
||||
#endif /* RE_ENABLE_I18N */
|
||||
else if (type == OP_BACK_REF)
|
||||
newstate->has_backref = 1;
|
||||
newstate->has_backref = 1;
|
||||
else if (type == ANCHOR)
|
||||
constraint = node->opr.ctx_type;
|
||||
constraint = node->opr.ctx_type;
|
||||
|
||||
if (constraint)
|
||||
{
|
||||
if (newstate->entrance_nodes == &newstate->nodes)
|
||||
{
|
||||
newstate->entrance_nodes = re_malloc (re_node_set, 1);
|
||||
{
|
||||
if (newstate->entrance_nodes == &newstate->nodes)
|
||||
{
|
||||
newstate->entrance_nodes = re_malloc (re_node_set, 1);
|
||||
if (BE (newstate->entrance_nodes == NULL, 0))
|
||||
return NULL;
|
||||
re_node_set_init_copy (newstate->entrance_nodes, nodes);
|
||||
nctx_nodes = 0;
|
||||
newstate->has_constraint = 1;
|
||||
}
|
||||
{
|
||||
free_state (newstate);
|
||||
return NULL;
|
||||
}
|
||||
re_node_set_init_copy (newstate->entrance_nodes, nodes);
|
||||
nctx_nodes = 0;
|
||||
newstate->has_constraint = 1;
|
||||
}
|
||||
|
||||
if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
|
||||
{
|
||||
re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
|
||||
++nctx_nodes;
|
||||
}
|
||||
}
|
||||
if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
|
||||
{
|
||||
re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
|
||||
++nctx_nodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
err = register_state (dfa, newstate, hash);
|
||||
return (err != REG_NOERROR) ? NULL : newstate;
|
||||
if (BE (err != REG_NOERROR, 0))
|
||||
{
|
||||
free_state (newstate);
|
||||
newstate = NULL;
|
||||
}
|
||||
return newstate;
|
||||
}
|
||||
|
||||
static void
|
||||
free_state (state)
|
||||
re_dfastate_t *state;
|
||||
{
|
||||
if (state->entrance_nodes != &state->nodes)
|
||||
{
|
||||
re_node_set_free (state->entrance_nodes);
|
||||
re_free (state->entrance_nodes);
|
||||
}
|
||||
re_node_set_free (&state->nodes);
|
||||
re_free (state->trtable);
|
||||
re_free (state->trtable_search);
|
||||
re_free (state);
|
||||
}
|
||||
|
362
posix/regexec.c
362
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;
|
||||
|
||||
/* 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
Loading…
Reference in New Issue
Block a user