mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Update.
2004-11-23 Paolo Bonzini <bonzini@gnu.org> * posix/regcomp.c (analyze_tree): Always call calc_epsdest. (calc_inveclosure): Use re_node_set_insert_last. (parse_dup_op): Lower X{1,5} to (X(X(X(XX?)?)?)?)? rather than X?X?X?X?X?. * posix/regex_internal.h (re_node_set_insert_last): New declaration. * posix/regex_internal.c (re_node_set_insert_last): New function. * posix/PCRE.tests: Add testcases.
This commit is contained in:
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
|||||||
|
2004-11-23 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
|
* posix/regcomp.c (analyze_tree): Always call calc_epsdest.
|
||||||
|
(calc_inveclosure): Use re_node_set_insert_last.
|
||||||
|
(parse_dup_op): Lower X{1,5} to (X(X(X(XX?)?)?)?)?
|
||||||
|
rather than X?X?X?X?X?.
|
||||||
|
* posix/regex_internal.h (re_node_set_insert_last): New declaration.
|
||||||
|
* posix/regex_internal.c (re_node_set_insert_last): New function.
|
||||||
|
* posix/PCRE.tests: Add testcases.
|
||||||
|
|
||||||
2004-11-25 Ulrich Drepper <drepper@redhat.com>
|
2004-11-25 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* dlfcn/dlfcn.h: Remove nonnull attribute from dlopen.
|
* dlfcn/dlfcn.h: Remove nonnull attribute from dlopen.
|
||||||
|
@ -2365,3 +2365,22 @@ No match
|
|||||||
0: bc123bc
|
0: bc123bc
|
||||||
1: bc
|
1: bc
|
||||||
2: bc
|
2: bc
|
||||||
|
|
||||||
|
/^a{2,5}$/
|
||||||
|
aa
|
||||||
|
0: aa
|
||||||
|
aaa
|
||||||
|
0: aaa
|
||||||
|
aaaa
|
||||||
|
0: aaaa
|
||||||
|
aaaaa
|
||||||
|
0: aaaaa
|
||||||
|
*** Failers
|
||||||
|
No match
|
||||||
|
a
|
||||||
|
No match
|
||||||
|
b
|
||||||
|
No match
|
||||||
|
aaaaab
|
||||||
|
No match
|
||||||
|
aaaaaa
|
||||||
|
@ -1269,8 +1269,8 @@ analyze_tree (dfa, node)
|
|||||||
calc_first (dfa, node);
|
calc_first (dfa, node);
|
||||||
if (node->next == -1)
|
if (node->next == -1)
|
||||||
calc_next (dfa, node);
|
calc_next (dfa, node);
|
||||||
if (node->eclosure.nelem == 0)
|
calc_epsdest (dfa, node);
|
||||||
calc_epsdest (dfa, node);
|
|
||||||
/* Calculate "first" etc. for the left child. */
|
/* Calculate "first" etc. for the left child. */
|
||||||
if (node->left != NULL)
|
if (node->left != NULL)
|
||||||
{
|
{
|
||||||
@ -1626,7 +1626,7 @@ calc_inveclosure (dfa)
|
|||||||
for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
|
for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
|
||||||
{
|
{
|
||||||
dest = dfa->eclosures[src].elems[idx];
|
dest = dfa->eclosures[src].elems[idx];
|
||||||
re_node_set_insert (dfa->inveclosures + dest, src);
|
re_node_set_insert_last (dfa->inveclosures + dest, src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2538,7 +2538,7 @@ parse_dup_op (elem, regexp, dfa, token, syntax, err)
|
|||||||
reg_errcode_t *err;
|
reg_errcode_t *err;
|
||||||
{
|
{
|
||||||
re_token_t dup_token;
|
re_token_t dup_token;
|
||||||
bin_tree_t *tree = NULL;
|
bin_tree_t *tree = NULL, *old_tree = NULL;
|
||||||
int i, start, end, start_idx = re_string_cur_idx (regexp);
|
int i, start, end, start_idx = re_string_cur_idx (regexp);
|
||||||
re_token_t start_token = *token;
|
re_token_t start_token = *token;
|
||||||
|
|
||||||
@ -2598,12 +2598,14 @@ parse_dup_op (elem, regexp, dfa, token, syntax, err)
|
|||||||
end = (token->type == OP_DUP_QUESTION) ? 1 : -1;
|
end = (token->type == OP_DUP_QUESTION) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fetch_token (token, regexp, syntax);
|
||||||
|
|
||||||
/* Treat "<re>{0}*" etc. as "<re>{0}". */
|
/* Treat "<re>{0}*" etc. as "<re>{0}". */
|
||||||
if (BE (elem == NULL, 0))
|
if (BE (elem == NULL || (start == 0 && end == 0), 0))
|
||||||
start = end = 0;
|
return NULL;
|
||||||
|
|
||||||
/* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}". */
|
/* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}". */
|
||||||
else if (BE (start > 0, 0))
|
if (BE (start > 0, 0))
|
||||||
{
|
{
|
||||||
tree = elem;
|
tree = elem;
|
||||||
for (i = 2; i <= start; ++i)
|
for (i = 2; i <= start; ++i)
|
||||||
@ -2613,52 +2615,41 @@ parse_dup_op (elem, regexp, dfa, token, syntax, err)
|
|||||||
if (BE (elem == NULL || tree == NULL, 0))
|
if (BE (elem == NULL || tree == NULL, 0))
|
||||||
goto parse_dup_op_espace;
|
goto parse_dup_op_espace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (start == end)
|
||||||
|
return tree;
|
||||||
|
|
||||||
|
/* Duplicate ELEM before it is marked optional. */
|
||||||
|
elem = duplicate_tree (elem, dfa);
|
||||||
|
old_tree = tree;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
old_tree = NULL;
|
||||||
|
|
||||||
if (BE (end != start, 1))
|
mark_opt_subexp (elem, dfa);
|
||||||
|
dup_token.type = (end == -1 ? OP_DUP_ASTERISK : OP_DUP_QUESTION);
|
||||||
|
tree = re_dfa_add_tree_node (dfa, elem, NULL, &dup_token);
|
||||||
|
if (BE (tree == NULL, 0))
|
||||||
|
goto parse_dup_op_espace;
|
||||||
|
|
||||||
|
/* This loop is actually executed only when end != -1,
|
||||||
|
to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?... We have
|
||||||
|
already created the start+1-th copy. */
|
||||||
|
for (i = start + 2; i <= end; ++i)
|
||||||
{
|
{
|
||||||
dup_token.type = (end == -1 ? OP_DUP_ASTERISK : OP_DUP_QUESTION);
|
elem = duplicate_tree (elem, dfa);
|
||||||
if (BE (start > 0, 0))
|
tree = create_tree (dfa, tree, elem, CONCAT, 0);
|
||||||
{
|
|
||||||
elem = duplicate_tree (elem, dfa);
|
|
||||||
if (BE (elem == NULL, 0))
|
|
||||||
goto parse_dup_op_espace;
|
|
||||||
|
|
||||||
/* This subexpression will be marked as optional, so that
|
|
||||||
empty matches do not touch the registers. */
|
|
||||||
mark_opt_subexp (elem, dfa);
|
|
||||||
|
|
||||||
/* Prepare the tree with the modifier. */
|
|
||||||
elem = re_dfa_add_tree_node (dfa, elem, NULL, &dup_token);
|
|
||||||
tree = create_tree (dfa, tree, elem, CONCAT, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* We do not need to duplicate the tree because we have not
|
|
||||||
created it yet. */
|
|
||||||
mark_opt_subexp (elem, dfa);
|
|
||||||
tree = elem = re_dfa_add_tree_node (dfa, elem, NULL, &dup_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BE (elem == NULL || tree == NULL, 0))
|
if (BE (elem == NULL || tree == NULL, 0))
|
||||||
goto parse_dup_op_espace;
|
goto parse_dup_op_espace;
|
||||||
|
|
||||||
/* This loop is actually executed only when end != -1,
|
tree = re_dfa_add_tree_node (dfa, tree, NULL, &dup_token);
|
||||||
to rewrite <re>{0,n} as <re>?<re>?<re>?... We have
|
if (BE (tree == NULL, 0))
|
||||||
already created the start+1-th copy. */
|
goto parse_dup_op_espace;
|
||||||
for (i = start + 2; i <= end; ++i)
|
|
||||||
{
|
|
||||||
elem = duplicate_tree (elem, dfa);
|
|
||||||
tree = create_tree (dfa, tree, elem, CONCAT, 0);
|
|
||||||
if (BE (elem == NULL || tree == NULL, 0))
|
|
||||||
{
|
|
||||||
*err = REG_ESPACE;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch_token (token, regexp, syntax);
|
if (old_tree)
|
||||||
|
tree = create_tree (dfa, old_tree, tree, CONCAT, 0);
|
||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
|
|
||||||
parse_dup_op_espace:
|
parse_dup_op_espace:
|
||||||
|
@ -1250,6 +1250,31 @@ re_node_set_insert (set, elem)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Insert the new element ELEM to the re_node_set* SET.
|
||||||
|
SET should not already have any element greater than or equal to ELEM.
|
||||||
|
Return -1 if an error is occured, return 1 otherwise. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
re_node_set_insert_last (set, elem)
|
||||||
|
re_node_set *set;
|
||||||
|
int elem;
|
||||||
|
{
|
||||||
|
/* Realloc if we need. */
|
||||||
|
if (set->alloc == set->nelem)
|
||||||
|
{
|
||||||
|
int *new_array;
|
||||||
|
set->alloc = (set->alloc + 1) * 2;
|
||||||
|
new_array = re_realloc (set->elems, int, set->alloc);
|
||||||
|
if (BE (new_array == NULL, 0))
|
||||||
|
return -1;
|
||||||
|
set->elems = new_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert the new element. */
|
||||||
|
set->elems[set->nelem++] = elem;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compare two node sets SET1 and SET2.
|
/* Compare two node sets SET1 and SET2.
|
||||||
return 1 if SET1 and SET2 are equivalent, return 0 otherwise. */
|
return 1 if SET1 and SET2 are equivalent, return 0 otherwise. */
|
||||||
|
|
||||||
|
@ -668,6 +668,8 @@ static reg_errcode_t re_node_set_init_union (re_node_set *dest,
|
|||||||
static reg_errcode_t re_node_set_merge (re_node_set *dest,
|
static reg_errcode_t re_node_set_merge (re_node_set *dest,
|
||||||
const re_node_set *src) internal_function;
|
const re_node_set *src) internal_function;
|
||||||
static int re_node_set_insert (re_node_set *set, int elem) internal_function;
|
static int re_node_set_insert (re_node_set *set, int elem) internal_function;
|
||||||
|
static int re_node_set_insert_last (re_node_set *set,
|
||||||
|
int elem) internal_function;
|
||||||
static int re_node_set_compare (const re_node_set *set1,
|
static int re_node_set_compare (const re_node_set *set1,
|
||||||
const re_node_set *set2) internal_function;
|
const re_node_set *set2) internal_function;
|
||||||
static int re_node_set_contains (const re_node_set *set, int elem) internal_function;
|
static int re_node_set_contains (const re_node_set *set, int elem) internal_function;
|
||||||
|
Reference in New Issue
Block a user