Imported Upstream version 1.4.13+git200906171200
This commit is contained in:
parent
4ab9f0d24c
commit
d0b8ab8112
362 changed files with 34110 additions and 10773 deletions
133
gl/regcomp.c
133
gl/regcomp.c
|
@ -1,5 +1,6 @@
|
|||
/* Extended regular expression matching and search library.
|
||||
Copyright (C) 2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
|
||||
|
||||
|
@ -333,8 +334,8 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
|
|||
&& dfa->nodes[node].mb_partial)
|
||||
*p++ = dfa->nodes[node].opr.c;
|
||||
memset (&state, '\0', sizeof (state));
|
||||
if (mbrtowc (&wc, (const char *) buf, p - buf,
|
||||
&state) == p - buf
|
||||
if (__mbrtowc (&wc, (const char *) buf, p - buf,
|
||||
&state) == p - buf
|
||||
&& (__wcrtomb ((char *) buf, towlower (wc), &state)
|
||||
!= (size_t) -1))
|
||||
re_set_fastmap (fastmap, false, buf[0]);
|
||||
|
@ -356,45 +357,65 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
|
|||
#ifdef RE_ENABLE_I18N
|
||||
else if (type == COMPLEX_BRACKET)
|
||||
{
|
||||
Idx i;
|
||||
re_charset_t *cset = dfa->nodes[node].opr.mbcset;
|
||||
if (cset->non_match || cset->ncoll_syms || cset->nequiv_classes
|
||||
|| cset->nranges || cset->nchar_classes)
|
||||
{
|
||||
Idx i;
|
||||
|
||||
# ifdef _LIBC
|
||||
if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0)
|
||||
/* See if we have to try all bytes which start multiple collation
|
||||
elements.
|
||||
e.g. In da_DK, we want to catch 'a' since "aa" is a valid
|
||||
collation element, and don't catch 'b' since 'b' is
|
||||
the only collation element which starts from 'b' (and
|
||||
it is caught by SIMPLE_BRACKET). */
|
||||
if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0
|
||||
&& (cset->ncoll_syms || cset->nranges))
|
||||
{
|
||||
/* In this case we want to catch the bytes which are
|
||||
the first byte of any collation elements.
|
||||
e.g. In da_DK, we want to catch 'a' since "aa"
|
||||
is a valid collation element, and don't catch
|
||||
'b' since 'b' is the only collation element
|
||||
which starts from 'b'. */
|
||||
const int32_t *table = (const int32_t *)
|
||||
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
|
||||
for (i = 0; i < SBC_MAX; ++i)
|
||||
if (table[i] < 0)
|
||||
re_set_fastmap (fastmap, icase, i);
|
||||
}
|
||||
# else
|
||||
if (dfa->mb_cur_max > 1)
|
||||
for (i = 0; i < SBC_MAX; ++i)
|
||||
if (__btowc (i) == WEOF)
|
||||
re_set_fastmap (fastmap, icase, i);
|
||||
# endif /* not _LIBC */
|
||||
}
|
||||
for (i = 0; i < cset->nmbchars; ++i)
|
||||
# endif /* _LIBC */
|
||||
|
||||
/* See if we have to start the match at all multibyte characters,
|
||||
i.e. where we would not find an invalid sequence. This only
|
||||
applies to multibyte character sets; for single byte character
|
||||
sets, the SIMPLE_BRACKET again suffices. */
|
||||
if (dfa->mb_cur_max > 1
|
||||
&& (cset->nchar_classes || cset->non_match
|
||||
# ifdef _LIBC
|
||||
|| cset->nequiv_classes
|
||||
# endif /* _LIBC */
|
||||
))
|
||||
{
|
||||
char buf[256];
|
||||
mbstate_t state;
|
||||
memset (&state, '\0', sizeof (state));
|
||||
if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
|
||||
re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
|
||||
if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
|
||||
unsigned char c = 0;
|
||||
do
|
||||
{
|
||||
if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
|
||||
!= (size_t) -1)
|
||||
re_set_fastmap (fastmap, false, *(unsigned char *) buf);
|
||||
mbstate_t mbs;
|
||||
memset (&mbs, 0, sizeof (mbs));
|
||||
if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2)
|
||||
re_set_fastmap (fastmap, false, (int) c);
|
||||
}
|
||||
while (++c != 0);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* ... Else catch all bytes which can start the mbchars. */
|
||||
for (i = 0; i < cset->nmbchars; ++i)
|
||||
{
|
||||
char buf[256];
|
||||
mbstate_t state;
|
||||
memset (&state, '\0', sizeof (state));
|
||||
if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
|
||||
re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
|
||||
if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
|
||||
{
|
||||
if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
|
||||
!= (size_t) -1)
|
||||
re_set_fastmap (fastmap, false, *(unsigned char *) buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -776,7 +797,7 @@ re_compile_internal (regex_t *preg, const char * pattern, size_t length,
|
|||
__libc_lock_init (dfa->lock);
|
||||
|
||||
err = re_string_construct (®exp, pattern, length, preg->translate,
|
||||
syntax & RE_ICASE, dfa);
|
||||
(syntax & RE_ICASE) != 0, dfa);
|
||||
if (BE (err != REG_NOERROR, 0))
|
||||
{
|
||||
re_compile_internal_free_return:
|
||||
|
@ -1057,7 +1078,9 @@ optimize_utf8 (re_dfa_t *dfa)
|
|||
case BUF_LAST:
|
||||
break;
|
||||
default:
|
||||
/* Word anchors etc. cannot be handled. */
|
||||
/* Word anchors etc. cannot be handled. It's okay to test
|
||||
opr.ctx_type since constraints (for all DFA nodes) are
|
||||
created by ORing one or more opr.ctx_type values. */
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
@ -1344,6 +1367,8 @@ calc_first (void *extra, bin_tree_t *node)
|
|||
node->node_idx = re_dfa_add_node (dfa, node->token);
|
||||
if (BE (node->node_idx == REG_MISSING, 0))
|
||||
return REG_ESPACE;
|
||||
if (node->token.type == ANCHOR)
|
||||
dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
|
||||
}
|
||||
return REG_NOERROR;
|
||||
}
|
||||
|
@ -1473,21 +1498,18 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
|
|||
destination. */
|
||||
org_dest = dfa->edests[org_node].elems[0];
|
||||
re_node_set_empty (dfa->edests + clone_node);
|
||||
if (dfa->nodes[org_node].type == ANCHOR)
|
||||
clone_dest = search_duplicated_node (dfa, org_dest, constraint);
|
||||
/* If the node is root_node itself, it means the epsilon closure
|
||||
has a loop. Then tie it to the destination of the root_node. */
|
||||
if (org_node == root_node && clone_node != org_node)
|
||||
{
|
||||
/* In case of the node has another constraint, append it. */
|
||||
if (org_node == root_node && clone_node != org_node)
|
||||
{
|
||||
/* ...but if the node is root_node itself, it means the
|
||||
epsilon closure have a loop, then tie it to the
|
||||
destination of the root_node. */
|
||||
ok = re_node_set_insert (dfa->edests + clone_node, org_dest);
|
||||
if (BE (! ok, 0))
|
||||
return REG_ESPACE;
|
||||
break;
|
||||
}
|
||||
constraint |= dfa->nodes[org_node].opr.ctx_type;
|
||||
ok = re_node_set_insert (dfa->edests + clone_node, org_dest);
|
||||
if (BE (! ok, 0))
|
||||
return REG_ESPACE;
|
||||
break;
|
||||
}
|
||||
/* In case the node has another constraint, append it. */
|
||||
constraint |= dfa->nodes[org_node].constraint;
|
||||
clone_dest = duplicate_node (dfa, org_dest, constraint);
|
||||
if (BE (clone_dest == REG_MISSING, 0))
|
||||
return REG_ESPACE;
|
||||
|
@ -1505,7 +1527,7 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
|
|||
clone_dest = search_duplicated_node (dfa, org_dest, constraint);
|
||||
if (clone_dest == REG_MISSING)
|
||||
{
|
||||
/* There are no such a duplicated node, create a new one. */
|
||||
/* There is no such duplicated node, create a new one. */
|
||||
reg_errcode_t err;
|
||||
clone_dest = duplicate_node (dfa, org_dest, constraint);
|
||||
if (BE (clone_dest == REG_MISSING, 0))
|
||||
|
@ -1520,7 +1542,7 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* There are a duplicated node which satisfy the constraint,
|
||||
/* There is a duplicated node which satisfy the constraint,
|
||||
use it to avoid infinite loop. */
|
||||
ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
|
||||
if (BE (! ok, 0))
|
||||
|
@ -1569,8 +1591,7 @@ duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint)
|
|||
if (BE (dup_idx != REG_MISSING, 1))
|
||||
{
|
||||
dfa->nodes[dup_idx].constraint = constraint;
|
||||
if (dfa->nodes[org_idx].type == ANCHOR)
|
||||
dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].opr.ctx_type;
|
||||
dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;
|
||||
dfa->nodes[dup_idx].duplicated = 1;
|
||||
|
||||
/* Store the index of the original node. */
|
||||
|
@ -1652,7 +1673,6 @@ static reg_errcode_t
|
|||
calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
|
||||
{
|
||||
reg_errcode_t err;
|
||||
unsigned int constraint;
|
||||
Idx i;
|
||||
bool incomplete;
|
||||
bool ok;
|
||||
|
@ -1666,15 +1686,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
|
|||
We reference this value to avoid infinite loop. */
|
||||
dfa->eclosures[node].nelem = REG_MISSING;
|
||||
|
||||
constraint = ((dfa->nodes[node].type == ANCHOR)
|
||||
? dfa->nodes[node].opr.ctx_type : 0);
|
||||
/* If the current node has constraints, duplicate all nodes.
|
||||
Since they must inherit the constraints. */
|
||||
if (constraint
|
||||
/* If the current node has constraints, duplicate all nodes
|
||||
since they must inherit the constraints. */
|
||||
if (dfa->nodes[node].constraint
|
||||
&& dfa->edests[node].nelem
|
||||
&& !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
|
||||
{
|
||||
err = duplicate_node_closure (dfa, node, node, node, constraint);
|
||||
err = duplicate_node_closure (dfa, node, node, node,
|
||||
dfa->nodes[node].constraint);
|
||||
if (BE (err != REG_NOERROR, 0))
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue