resynced with gnulib. Cleaned up wrapping layer

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-03-28 21:43:42 +02:00
parent bbdb72a1f4
commit a64b15feed
20 changed files with 620 additions and 305 deletions

View file

@ -1,6 +1,6 @@
/* Extended regular expression matching and search library.
Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009
Free Software Foundation, Inc.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@ -383,7 +383,7 @@ re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
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
&& (cset->nchar_classes || cset->non_match || cset->nranges
# ifdef _LIBC
|| cset->nequiv_classes
# endif /* _LIBC */
@ -636,7 +636,7 @@ free_dfa_content (re_dfa_t *dfa)
re_dfastate_t *state = entry->array[j];
free_state (state);
}
re_free (entry->array);
re_free (entry->array);
}
re_free (dfa->state_table);
#ifdef RE_ENABLE_I18N
@ -850,6 +850,9 @@ static reg_errcode_t
init_dfa (re_dfa_t *dfa, size_t pat_len)
{
__re_size_t table_size;
#ifndef _LIBC
char *codeset_name;
#endif
#ifdef RE_ENABLE_I18N
size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t));
#else
@ -893,7 +896,9 @@ init_dfa (re_dfa_t *dfa, size_t pat_len)
dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
!= 0);
#else
if (strcmp (locale_charset (), "UTF-8") == 0)
codeset_name = nl_langinfo (CODESET);
if (strcasecmp (codeset_name, "UTF-8") == 0
|| strcasecmp (codeset_name, "UTF8") == 0)
dfa->is_utf8 = 1;
/* We check exhaustively in the loop below if this charset is a
@ -1016,7 +1021,10 @@ create_initial_state (re_dfa_t *dfa)
Idx dest_idx = dfa->edests[node_idx].elems[0];
if (!re_node_set_contains (&init_nodes, dest_idx))
{
re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
reg_errcode_t merge_err
= re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
if (merge_err != REG_NOERROR)
return merge_err;
i = 0;
}
}
@ -1085,8 +1093,8 @@ optimize_utf8 (re_dfa_t *dfa)
}
break;
case OP_PERIOD:
has_period = true;
break;
has_period = true;
break;
case OP_BACK_REF:
case OP_ALT:
case END_OF_RE:
@ -1187,7 +1195,7 @@ analyze (regex_t *preg)
{
dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
if (BE (dfa->inveclosures == NULL, 0))
return REG_ESPACE;
return REG_ESPACE;
ret = calc_inveclosure (dfa);
}
@ -1209,16 +1217,16 @@ postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
if that's the only child). */
while (node->left || node->right)
if (node->left)
node = node->left;
else
node = node->right;
node = node->left;
else
node = node->right;
do
{
reg_errcode_t err = fn (extra, node);
if (BE (err != REG_NOERROR, 0))
return err;
if (node->parent == NULL)
if (node->parent == NULL)
return REG_NOERROR;
prev = node;
node = node->parent;
@ -1252,7 +1260,7 @@ preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
prev = node;
node = node->parent;
if (!node)
return REG_NOERROR;
return REG_NOERROR;
}
node = node->right;
}
@ -1275,13 +1283,13 @@ optimize_subexps (void *extra, bin_tree_t *node)
}
else if (node->token.type == SUBEXP
&& node->left && node->left->token.type == SUBEXP)
&& node->left && node->left->token.type == SUBEXP)
{
Idx other_idx = node->left->token.opr.idx;
node->left = node->left->left;
if (node->left)
node->left->parent = node;
node->left->parent = node;
dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];
if (other_idx < BITSET_WORD_BITS)
@ -1366,9 +1374,9 @@ calc_first (void *extra, bin_tree_t *node)
node->first = node;
node->node_idx = re_dfa_add_node (dfa, node->token);
if (BE (node->node_idx == REG_MISSING, 0))
return REG_ESPACE;
return REG_ESPACE;
if (node->token.type == ANCHOR)
dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
}
return REG_NOERROR;
}
@ -1390,7 +1398,7 @@ calc_next (void *extra, bin_tree_t *node)
if (node->left)
node->left->next = node->next;
if (node->right)
node->right->next = node->next;
node->right->next = node->next;
break;
}
return REG_NOERROR;
@ -1441,7 +1449,7 @@ link_nfa_nodes (void *extra, bin_tree_t *node)
case OP_BACK_REF:
dfa->nexts[idx] = node->next->node_idx;
if (node->token.type == OP_BACK_REF)
re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
break;
default:
@ -1498,7 +1506,6 @@ 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);
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)
@ -1542,7 +1549,7 @@ duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
}
else
{
/* There is a duplicated node which satisfy the constraint,
/* There is a duplicated node which satisfies the constraint,
use it to avoid infinite loop. */
ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
if (BE (! ok, 0))
@ -1674,10 +1681,9 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
{
reg_errcode_t err;
Idx i;
bool incomplete;
bool ok;
re_node_set eclosure;
incomplete = false;
bool ok;
bool incomplete = false;
err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
if (BE (err != REG_NOERROR, 0))
return err;
@ -1722,7 +1728,9 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
else
eclosure_elem = dfa->eclosures[edest];
/* Merge the epsilon closure of `edest'. */
re_node_set_merge (&eclosure, &eclosure_elem);
err = re_node_set_merge (&eclosure, &eclosure_elem);
if (BE (err != REG_NOERROR, 0))
return err;
/* If the epsilon closure of `edest' is incomplete,
the epsilon closure of this node is also incomplete. */
if (dfa->eclosures[edest].nelem == 0)
@ -1732,7 +1740,7 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
}
}
/* Epsilon closures include itself. */
/* An epsilon closure includes itself. */
ok = re_node_set_insert (&eclosure, node);
if (BE (! ok, 0))
return REG_ESPACE;
@ -2319,7 +2327,7 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
&& dfa->word_ops_used == 0)
init_word_char (dfa);
if (token->opr.ctx_type == WORD_DELIM
|| token->opr.ctx_type == NOT_WORD_DELIM)
|| token->opr.ctx_type == NOT_WORD_DELIM)
{
bin_tree_t *tree_first, *tree_last;
if (token->opr.ctx_type == WORD_DELIM)
@ -2327,13 +2335,13 @@ parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
token->opr.ctx_type = WORD_FIRST;
tree_first = create_token_tree (dfa, NULL, NULL, token);
token->opr.ctx_type = WORD_LAST;
}
else
{
}
else
{
token->opr.ctx_type = INSIDE_WORD;
tree_first = create_token_tree (dfa, NULL, NULL, token);
token->opr.ctx_type = INSIDE_NOTWORD;
}
}
tree_last = create_token_tree (dfa, NULL, NULL, token);
tree = create_tree (dfa, tree_first, tree_last, OP_ALT);
if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0))
@ -2444,7 +2452,7 @@ parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
{
tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
*err = REG_EPAREN;
*err = REG_EPAREN;
if (BE (*err != REG_NOERROR, 0))
return NULL;
}
@ -2515,7 +2523,8 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
return elem;
}
if (BE (end != REG_MISSING && start > end, 0))
if (BE ((end != REG_MISSING && start > end)
|| token->type != OP_CLOSE_DUP_NUM, 0))
{
/* First number greater than second. */
*err = REG_BADBR;
@ -2568,10 +2577,14 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
if (BE (tree == NULL, 0))
goto parse_dup_op_espace;
/* From gnulib's "intprops.h":
True if the arithmetic type T is signed. */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
/* This loop is actually executed only when end != REG_MISSING,
to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?... We have
already created the start+1-th copy. */
if ((Idx) -1 < 0 || end != REG_MISSING)
if (TYPE_SIGNED (Idx) || end != REG_MISSING)
for (i = start + 2; i <= end; ++i)
{
elem = duplicate_tree (elem, dfa);
@ -2609,11 +2622,17 @@ parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
static reg_errcode_t
internal_function
# ifdef RE_ENABLE_I18N
build_range_exp (bitset_t sbcset, re_charset_t *mbcset, Idx *range_alloc,
bracket_elem_t *start_elem, bracket_elem_t *end_elem)
build_range_exp (const reg_syntax_t syntax,
bitset_t sbcset,
re_charset_t *mbcset,
Idx *range_alloc,
const bracket_elem_t *start_elem,
const bracket_elem_t *end_elem)
# else /* not RE_ENABLE_I18N */
build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
bracket_elem_t *end_elem)
build_range_exp (const reg_syntax_t syntax,
bitset_t sbcset,
const bracket_elem_t *start_elem,
const bracket_elem_t *end_elem)
# endif /* not RE_ENABLE_I18N */
{
unsigned int start_ch, end_ch;
@ -2652,7 +2671,9 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
return REG_ECOLLATE;
cmp_buf[0] = start_wc;
cmp_buf[4] = end_wc;
if (wcscoll (cmp_buf, cmp_buf + 4) > 0)
if (BE ((syntax & RE_NO_EMPTY_RANGES)
&& wcscoll (cmp_buf, cmp_buf + 4) > 0, 0))
return REG_ERANGE;
/* Got valid collation sequence values, add them as a new entry.
@ -2662,9 +2683,9 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
no MBCSET if dfa->mb_cur_max == 1. */
if (mbcset)
{
/* Check the space of the arrays. */
if (BE (*range_alloc == mbcset->nranges, 0))
{
/* Check the space of the arrays. */
if (BE (*range_alloc == mbcset->nranges, 0))
{
/* There is not enough space, need realloc. */
wchar_t *new_array_start, *new_array_end;
Idx new_nranges;
@ -2674,9 +2695,9 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
/* Use realloc since mbcset->range_starts and mbcset->range_ends
are NULL if *range_alloc == 0. */
new_array_start = re_realloc (mbcset->range_starts, wchar_t,
new_nranges);
new_nranges);
new_array_end = re_realloc (mbcset->range_ends, wchar_t,
new_nranges);
new_nranges);
if (BE (new_array_start == NULL || new_array_end == NULL, 0))
return REG_ESPACE;
@ -2684,10 +2705,10 @@ build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem,
mbcset->range_starts = new_array_start;
mbcset->range_ends = new_array_end;
*range_alloc = new_nranges;
}
}
mbcset->range_starts[mbcset->nranges] = start_wc;
mbcset->range_ends[mbcset->nranges++] = end_wc;
mbcset->range_starts[mbcset->nranges] = start_wc;
mbcset->range_ends[mbcset->nranges++] = end_wc;
}
/* Build the table for single byte characters. */
@ -2799,7 +2820,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
return elem;
}
/* Local function for parse_bracket_exp used in _LIBC environement.
/* Local function for parse_bracket_exp used in _LIBC environment.
Look up the collation sequence value of BR_ELEM.
Return the value if succeeded, UINT_MAX otherwise. */
@ -2823,7 +2844,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
}
else if (br_elem->type == MB_CHAR)
{
return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
if (nrules != 0)
return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
}
else if (br_elem->type == COLL_SYM)
{
@ -2904,8 +2926,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
build below suffices. */
if (nrules > 0 || dfa->mb_cur_max > 1)
{
/* Check the space of the arrays. */
if (BE (*range_alloc == mbcset->nranges, 0))
/* Check the space of the arrays. */
if (BE (*range_alloc == mbcset->nranges, 0))
{
/* There is not enough space, need realloc. */
uint32_t *new_array_start;
@ -2917,18 +2939,18 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
new_array_start = re_realloc (mbcset->range_starts, uint32_t,
new_nranges);
new_array_end = re_realloc (mbcset->range_ends, uint32_t,
new_nranges);
new_nranges);
if (BE (new_array_start == NULL || new_array_end == NULL, 0))
return REG_ESPACE;
return REG_ESPACE;
mbcset->range_starts = new_array_start;
mbcset->range_ends = new_array_end;
*range_alloc = new_nranges;
}
mbcset->range_starts[mbcset->nranges] = start_collseq;
mbcset->range_ends[mbcset->nranges++] = end_collseq;
mbcset->range_starts[mbcset->nranges] = start_collseq;
mbcset->range_ends[mbcset->nranges++] = end_collseq;
}
/* Build the table for single byte characters. */
@ -3154,11 +3176,11 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
&start_elem, &end_elem);
#else
# ifdef RE_ENABLE_I18N
*err = build_range_exp (sbcset,
*err = build_range_exp (syntax, sbcset,
dfa->mb_cur_max > 1 ? mbcset : NULL,
&range_alloc, &start_elem, &end_elem);
# else
*err = build_range_exp (sbcset, &start_elem, &end_elem);
*err = build_range_exp (syntax, sbcset, &start_elem, &end_elem);
# endif
#endif /* RE_ENABLE_I18N */
if (BE (*err != REG_NOERROR, 0))
@ -3262,17 +3284,17 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
of having both SIMPLE_BRACKET and COMPLEX_BRACKET. */
if (sbc_idx < BITSET_WORDS)
{
/* Build a tree for simple bracket. */
br_token.type = SIMPLE_BRACKET;
br_token.opr.sbcset = sbcset;
work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
if (BE (work_tree == NULL, 0))
goto parse_bracket_exp_espace;
/* Build a tree for simple bracket. */
br_token.type = SIMPLE_BRACKET;
br_token.opr.sbcset = sbcset;
work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
if (BE (work_tree == NULL, 0))
goto parse_bracket_exp_espace;
/* Then join them by ALT node. */
work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);
if (BE (work_tree == NULL, 0))
goto parse_bracket_exp_espace;
/* Then join them by ALT node. */
work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);
if (BE (work_tree == NULL, 0))
goto parse_bracket_exp_espace;
}
else
{
@ -3291,7 +3313,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
br_token.opr.sbcset = sbcset;
work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
if (BE (work_tree == NULL, 0))
goto parse_bracket_exp_espace;
goto parse_bracket_exp_espace;
}
return work_tree;
@ -3430,7 +3452,7 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
/* Build single byte matcing table for this equivalence class. */
char_buf[1] = (unsigned char) '\0';
len = weights[idx1];
len = weights[idx1 & 0xffffff];
for (ch = 0; ch < SBC_MAX; ++ch)
{
char_buf[0] = ch;
@ -3442,11 +3464,15 @@ build_equiv_class (bitset_t sbcset, const unsigned char *name)
if (idx2 == 0)
/* This isn't a valid character. */
continue;
if (len == weights[idx2])
/* Compare only if the length matches and the collation rule
index is the same. */
if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24))
{
int cnt = 0;
while (cnt <= len &&
weights[idx1 + 1 + cnt] == weights[idx2 + 1 + cnt])
weights[(idx1 & 0xffffff) + 1 + cnt]
== weights[(idx2 & 0xffffff) + 1 + cnt])
++cnt;
if (cnt > len)
@ -3842,7 +3868,7 @@ duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa)
node = node->parent;
dup_node = dup_node->parent;
if (!node)
return dup_root;
return dup_root;
}
node = node->right;
p_new = &dup_node->right;

View file

@ -1,5 +1,6 @@
/* Extended regular expression matching and search library.
Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
Copyright (C) 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation,
Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@ -17,10 +18,55 @@
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#include <grub/regex.h>
#include <config.h>
/* Make sure noone compiles this code with a C++ compiler. */
#if defined __cplusplus && defined _LIBC
# error "This is C code, use a C compiler"
#endif
#ifdef _LIBC
/* We have to keep the namespace clean. */
# define regfree(preg) __regfree (preg)
# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
# define regerror(errcode, preg, errbuf, errbuf_size) \
__regerror(errcode, preg, errbuf, errbuf_size)
# define re_set_registers(bu, re, nu, st, en) \
__re_set_registers (bu, re, nu, st, en)
# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
# define re_match(bufp, string, size, pos, regs) \
__re_match (bufp, string, size, pos, regs)
# define re_search(bufp, string, size, startpos, range, regs) \
__re_search (bufp, string, size, startpos, range, regs)
# define re_compile_pattern(pattern, length, bufp) \
__re_compile_pattern (pattern, length, bufp)
# define re_set_syntax(syntax) __re_set_syntax (syntax)
# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
# include "../locale/localeinfo.h"
#endif
/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
GNU regex allows. Include it before <regex.h>, which correctly
#undefs RE_DUP_MAX and sets it to the right value. */
#include <limits.h>
#include <regex.h>
#include "regex_internal.h"
#include "regex_internal.c"
#include "regcomp.c"
#include "regexec.c"
/* Binary backward compatibility. */
#if _LIBC
# include <shlib-compat.h>
# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
int re_max_failures = 2000;
# endif
#endif

676
gnulib/regex.h Normal file
View file

@ -0,0 +1,676 @@
/* Definitions for data structures and routines for the regular
expression library.
Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1997, 1998,
2000, 2001, 2002, 2003, 2005, 2006, 2009, 2010 Free Software Foundation,
Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _REGEX_H
#define _REGEX_H 1
#include <sys/types.h>
/* Allow the use in C++ code. */
#ifdef __cplusplus
extern "C" {
#endif
/* Define __USE_GNU_REGEX to declare GNU extensions that violate the
POSIX name space rules. */
#undef __USE_GNU_REGEX
#if (defined _GNU_SOURCE \
|| (!defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE \
&& !defined _XOPEN_SOURCE))
# define __USE_GNU_REGEX 1
#endif
#ifdef _REGEX_LARGE_OFFSETS
/* Use types and values that are wide enough to represent signed and
unsigned byte offsets in memory. This currently works only when
the regex code is used outside of the GNU C library; it is not yet
supported within glibc itself, and glibc users should not define
_REGEX_LARGE_OFFSETS. */
/* The type of the offset of a byte within a string.
For historical reasons POSIX 1003.1-2004 requires that regoff_t be
at least as wide as off_t. However, many common POSIX platforms set
regoff_t to the more-sensible ssize_t and the Open Group has
signalled its intention to change the requirement to be that
regoff_t be at least as wide as ptrdiff_t and ssize_t; see XBD ERN
60 (2005-08-25). We don't know of any hosts where ssize_t or
ptrdiff_t is wider than ssize_t, so ssize_t is safe. */
typedef ssize_t regoff_t;
/* The type of nonnegative object indexes. Traditionally, GNU regex
uses 'int' for these. Code that uses __re_idx_t should work
regardless of whether the type is signed. */
typedef size_t __re_idx_t;
/* The type of object sizes. */
typedef size_t __re_size_t;
/* The type of object sizes, in places where the traditional code
uses unsigned long int. */
typedef size_t __re_long_size_t;
#else
/* Use types that are binary-compatible with the traditional GNU regex
implementation, which mishandles strings longer than INT_MAX. */
typedef int regoff_t;
typedef int __re_idx_t;
typedef unsigned int __re_size_t;
typedef unsigned long int __re_long_size_t;
#endif
/* The following two types have to be signed and unsigned integer type
wide enough to hold a value of a pointer. For most ANSI compilers
ptrdiff_t and size_t should be likely OK. Still size of these two
types is 2 for Microsoft C. Ugh... */
typedef long int s_reg_t;
typedef unsigned long int active_reg_t;
/* The following bits are used to determine the regexp syntax we
recognize. The set/not-set meanings are chosen so that Emacs syntax
remains the value 0. The bits are given in alphabetical order, and
the definitions shifted by one from the previous bit; thus, when we
add or remove a bit, only one other definition need change. */
typedef unsigned long int reg_syntax_t;
#ifdef __USE_GNU_REGEX
/* If this bit is not set, then \ inside a bracket expression is literal.
If set, then such a \ quotes the following character. */
# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
/* If this bit is not set, then + and ? are operators, and \+ and \? are
literals.
If set, then \+ and \? are operators and + and ? are literals. */
# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
/* If this bit is set, then character classes are supported. They are:
[:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
[:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
If not set, then character classes are not supported. */
# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
/* If this bit is set, then ^ and $ are always anchors (outside bracket
expressions, of course).
If this bit is not set, then it depends:
^ is an anchor if it is at the beginning of a regular
expression or after an open-group or an alternation operator;
$ is an anchor if it is at the end of a regular expression, or
before a close-group or an alternation operator.
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
POSIX draft 11.2 says that * etc. in leading positions is undefined.
We already implemented a previous draft which made those constructs
invalid, though, so we haven't changed the code back. */
# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
/* If this bit is set, then special characters are always special
regardless of where they are in the pattern.
If this bit is not set, then special characters are special only in
some contexts; otherwise they are ordinary. Specifically,
* + ? and intervals are only special when not after the beginning,
open-group, or alternation operator. */
# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
/* If this bit is set, then *, +, ?, and { cannot be first in an re or
immediately after an alternation or begin-group operator. */
# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
/* If this bit is set, then . matches newline.
If not set, then it doesn't. */
# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
/* If this bit is set, then . doesn't match NUL.
If not set, then it does. */
# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
/* If this bit is set, nonmatching lists [^...] do not match newline.
If not set, they do. */
# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
/* If this bit is set, either \{...\} or {...} defines an
interval, depending on RE_NO_BK_BRACES.
If not set, \{, \}, {, and } are literals. */
# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
/* If this bit is set, +, ? and | aren't recognized as operators.
If not set, they are. */
# define RE_LIMITED_OPS (RE_INTERVALS << 1)
/* If this bit is set, newline is an alternation operator.
If not set, newline is literal. */
# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
/* If this bit is set, then `{...}' defines an interval, and \{ and \}
are literals.
If not set, then `\{...\}' defines an interval. */
# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
/* If this bit is set, (...) defines a group, and \( and \) are literals.
If not set, \(...\) defines a group, and ( and ) are literals. */
# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
/* If this bit is set, then \<digit> matches <digit>.
If not set, then \<digit> is a back-reference. */
# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
/* If this bit is set, then | is an alternation operator, and \| is literal.
If not set, then \| is an alternation operator, and | is literal. */
# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
/* If this bit is set, then an ending range point collating higher
than the starting range point, as in [z-a], is invalid.
If not set, then when ending range point collates higher than the
starting range point, the range is ignored. */
# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
/* If this bit is set, then an unmatched ) is ordinary.
If not set, then an unmatched ) is invalid. */
# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
/* If this bit is set, succeed as soon as we match the whole pattern,
without further backtracking. */
# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
/* If this bit is set, do not process the GNU regex operators.
If not set, then the GNU regex operators are recognized. */
# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
/* If this bit is set, turn on internal regex debugging.
If not set, and debugging was on, turn it off.
This only works if regex.c is compiled -DDEBUG.
We define this bit always, so that all that's needed to turn on
debugging is to recompile regex.c; the calling code can always have
this bit set, and it won't affect anything in the normal case. */
# define RE_DEBUG (RE_NO_GNU_OPS << 1)
/* If this bit is set, a syntactically invalid interval is treated as
a string of ordinary characters. For example, the ERE 'a{1' is
treated as 'a\{1'. */
# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
/* If this bit is set, then ignore case when matching.
If not set, then case is significant. */
# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
for ^, because it is difficult to scan the regex backwards to find
whether ^ should be special. */
# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
/* If this bit is set, then \{ cannot be first in an bre or
immediately after an alternation or begin-group operator. */
# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
/* If this bit is set, then no_sub will be set to 1 during
re_compile_pattern. */
# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
#endif /* defined __USE_GNU_REGEX */
/* This global variable defines the particular regexp syntax to use (for
some interfaces). When a regexp is compiled, the syntax used is
stored in the pattern buffer, so changing this does not affect
already-compiled regexps. */
extern reg_syntax_t re_syntax_options;
#ifdef __USE_GNU_REGEX
/* Define combinations of the above bits for the standard possibilities.
(The [[[ comments delimit what gets put into the Texinfo file, so
don't delete them!) */
/* [[[begin syntaxes]]] */
# define RE_SYNTAX_EMACS 0
# define RE_SYNTAX_AWK \
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
| RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
| RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
# define RE_SYNTAX_GNU_AWK \
((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
& ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS \
| RE_CONTEXT_INVALID_OPS ))
# define RE_SYNTAX_POSIX_AWK \
(RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
| RE_INTERVALS | RE_NO_GNU_OPS)
# define RE_SYNTAX_GREP \
(RE_BK_PLUS_QM | RE_CHAR_CLASSES \
| RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
| RE_NEWLINE_ALT)
# define RE_SYNTAX_EGREP \
(RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
| RE_NEWLINE_ALT | RE_NO_BK_PARENS \
| RE_NO_BK_VBAR)
# define RE_SYNTAX_POSIX_EGREP \
(RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \
| RE_INVALID_INTERVAL_ORD)
/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
/* Syntax bits common to both basic and extended POSIX regex syntax. */
# define _RE_SYNTAX_POSIX_COMMON \
(RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
| RE_INTERVALS | RE_NO_EMPTY_RANGES)
# define RE_SYNTAX_POSIX_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
isn't minimal, since other operators, such as \`, aren't disabled. */
# define RE_SYNTAX_POSIX_MINIMAL_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
# define RE_SYNTAX_POSIX_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_VBAR \
| RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
removed and RE_NO_BK_REFS is added. */
# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* [[[end syntaxes]]] */
#endif /* defined __USE_GNU_REGEX */
#ifdef __USE_GNU_REGEX
/* Maximum number of duplicates an interval can allow. POSIX-conforming
systems might define this in <limits.h>, but we want our
value, so remove any previous define. */
# ifdef RE_DUP_MAX
# undef RE_DUP_MAX
# endif
/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored
the counter as a 2-byte signed integer. This is no longer true, so
RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to
((SIZE_MAX - 2) / 10 - 1) if _REGEX_LARGE_OFFSETS is defined.
However, there would be a huge performance problem if someone
actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains
its historical value. */
# define RE_DUP_MAX (0x7fff)
#endif /* defined __USE_GNU_REGEX */
/* POSIX `cflags' bits (i.e., information for `regcomp'). */
/* If this bit is set, then use extended regular expression syntax.
If not set, then use basic regular expression syntax. */
#define REG_EXTENDED 1
/* If this bit is set, then ignore case when matching.
If not set, then case is significant. */
#define REG_ICASE (1 << 1)
/* If this bit is set, then anchors do not match at newline
characters in the string.
If not set, then anchors do match at newlines. */
#define REG_NEWLINE (1 << 2)
/* If this bit is set, then report only success or fail in regexec.
If not set, then returns differ between not matching and errors. */
#define REG_NOSUB (1 << 3)
/* POSIX `eflags' bits (i.e., information for regexec). */
/* If this bit is set, then the beginning-of-line operator doesn't match
the beginning of the string (presumably because it's not the
beginning of a line).
If not set, then the beginning-of-line operator does match the
beginning of the string. */
#define REG_NOTBOL 1
/* Like REG_NOTBOL, except for the end-of-line. */
#define REG_NOTEOL (1 << 1)
/* Use PMATCH[0] to delimit the start and end of the search in the
buffer. */
#define REG_STARTEND (1 << 2)
/* If any error codes are removed, changed, or added, update the
`__re_error_msgid' table in regcomp.c. */
typedef enum
{
_REG_ENOSYS = -1, /* This will never happen for this implementation. */
_REG_NOERROR = 0, /* Success. */
_REG_NOMATCH, /* Didn't find a match (for regexec). */
/* POSIX regcomp return error codes. (In the order listed in the
standard.) */
_REG_BADPAT, /* Invalid pattern. */
_REG_ECOLLATE, /* Invalid collating element. */
_REG_ECTYPE, /* Invalid character class name. */
_REG_EESCAPE, /* Trailing backslash. */
_REG_ESUBREG, /* Invalid back reference. */
_REG_EBRACK, /* Unmatched left bracket. */
_REG_EPAREN, /* Parenthesis imbalance. */
_REG_EBRACE, /* Unmatched \{. */
_REG_BADBR, /* Invalid contents of \{\}. */
_REG_ERANGE, /* Invalid range end. */
_REG_ESPACE, /* Ran out of memory. */
_REG_BADRPT, /* No preceding re for repetition op. */
/* Error codes we've added. */
_REG_EEND, /* Premature end. */
_REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
_REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
} reg_errcode_t;
#ifdef _XOPEN_SOURCE
# define REG_ENOSYS _REG_ENOSYS
#endif
#define REG_NOERROR _REG_NOERROR
#define REG_NOMATCH _REG_NOMATCH
#define REG_BADPAT _REG_BADPAT
#define REG_ECOLLATE _REG_ECOLLATE
#define REG_ECTYPE _REG_ECTYPE
#define REG_EESCAPE _REG_EESCAPE
#define REG_ESUBREG _REG_ESUBREG
#define REG_EBRACK _REG_EBRACK
#define REG_EPAREN _REG_EPAREN
#define REG_EBRACE _REG_EBRACE
#define REG_BADBR _REG_BADBR
#define REG_ERANGE _REG_ERANGE
#define REG_ESPACE _REG_ESPACE
#define REG_BADRPT _REG_BADRPT
#define REG_EEND _REG_EEND
#define REG_ESIZE _REG_ESIZE
#define REG_ERPAREN _REG_ERPAREN
/* struct re_pattern_buffer normally uses member names like `buffer'
that POSIX does not allow. In POSIX mode these members have names
with leading `re_' (e.g., `re_buffer'). */
#ifdef __USE_GNU_REGEX
# define _REG_RE_NAME(id) id
# define _REG_RM_NAME(id) id
#else
# define _REG_RE_NAME(id) re_##id
# define _REG_RM_NAME(id) rm_##id
#endif
/* The user can specify the type of the re_translate member by
defining the macro RE_TRANSLATE_TYPE, which defaults to unsigned
char *. This pollutes the POSIX name space, so in POSIX mode just
use unsigned char *. */
#ifdef __USE_GNU_REGEX
# ifndef RE_TRANSLATE_TYPE
# define RE_TRANSLATE_TYPE unsigned char *
# endif
# define REG_TRANSLATE_TYPE RE_TRANSLATE_TYPE
#else
# define REG_TRANSLATE_TYPE unsigned char *
#endif
/* This data structure represents a compiled pattern. Before calling
the pattern compiler, the fields `buffer', `allocated', `fastmap',
`translate', and `no_sub' can be set. After the pattern has been
compiled, the `re_nsub' field is available. All other fields are
private to the regex routines. */
struct re_pattern_buffer
{
/* Space that holds the compiled pattern. It is declared as
`unsigned char *' because its elements are sometimes used as
array indexes. */
unsigned char *_REG_RE_NAME (buffer);
/* Number of bytes to which `buffer' points. */
__re_long_size_t _REG_RE_NAME (allocated);
/* Number of bytes actually used in `buffer'. */
__re_long_size_t _REG_RE_NAME (used);
/* Syntax setting with which the pattern was compiled. */
reg_syntax_t _REG_RE_NAME (syntax);
/* Pointer to a fastmap, if any, otherwise zero. re_search uses the
fastmap, if there is one, to skip over impossible starting points
for matches. */
char *_REG_RE_NAME (fastmap);
/* Either a translate table to apply to all characters before
comparing them, or zero for no translation. The translation is
applied to a pattern when it is compiled and to a string when it
is matched. */
REG_TRANSLATE_TYPE _REG_RE_NAME (translate);
/* Number of subexpressions found by the compiler. */
size_t re_nsub;
/* Zero if this pattern cannot match the empty string, one else.
Well, in truth it's used only in `re_search_2', to see whether or
not we should use the fastmap, so we don't set this absolutely
perfectly; see `re_compile_fastmap' (the `duplicate' case). */
unsigned int _REG_RE_NAME (can_be_null) : 1;
/* If REGS_UNALLOCATED, allocate space in the `regs' structure
for `max (RE_NREGS, re_nsub + 1)' groups.
If REGS_REALLOCATE, reallocate space if necessary.
If REGS_FIXED, use what's there. */
#ifdef __USE_GNU_REGEX
# define REGS_UNALLOCATED 0
# define REGS_REALLOCATE 1
# define REGS_FIXED 2
#endif
unsigned int _REG_RE_NAME (regs_allocated) : 2;
/* Set to zero when `regex_compile' compiles a pattern; set to one
by `re_compile_fastmap' if it updates the fastmap. */
unsigned int _REG_RE_NAME (fastmap_accurate) : 1;
/* If set, `re_match_2' does not return information about
subexpressions. */
unsigned int _REG_RE_NAME (no_sub) : 1;
/* If set, a beginning-of-line anchor doesn't match at the beginning
of the string. */
unsigned int _REG_RE_NAME (not_bol) : 1;
/* Similarly for an end-of-line anchor. */
unsigned int _REG_RE_NAME (not_eol) : 1;
/* If true, an anchor at a newline matches. */
unsigned int _REG_RE_NAME (newline_anchor) : 1;
/* [[[end pattern_buffer]]] */
};
typedef struct re_pattern_buffer regex_t;
/* This is the structure we store register match data in. See
regex.texinfo for a full description of what registers match. */
struct re_registers
{
__re_size_t _REG_RM_NAME (num_regs);
regoff_t *_REG_RM_NAME (start);
regoff_t *_REG_RM_NAME (end);
};
/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
`re_match_2' returns information about at least this many registers
the first time a `regs' structure is passed. */
#if !defined RE_NREGS && defined __USE_GNU_REGEX
# define RE_NREGS 30
#endif
/* POSIX specification for registers. Aside from the different names than
`re_registers', POSIX uses an array of structures, instead of a
structure of arrays. */
typedef struct
{
regoff_t rm_so; /* Byte offset from string's start to substring's start. */
regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
} regmatch_t;
/* Declarations for routines. */
/* Sets the current default syntax to SYNTAX, and return the old syntax.
You can also simply assign to the `re_syntax_options' variable. */
extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
/* Compile the regular expression PATTERN, with length LENGTH
and syntax given by the global `re_syntax_options', into the buffer
BUFFER. Return NULL if successful, and an error string if not. */
extern const char *re_compile_pattern (const char *__pattern, size_t __length,
struct re_pattern_buffer *__buffer);
/* Compile a fastmap for the compiled pattern in BUFFER; used to
accelerate searches. Return 0 if successful and -2 if was an
internal error. */
extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
/* Search in the string STRING (with length LENGTH) for the pattern
compiled into BUFFER. Start searching at position START, for RANGE
characters. Return the starting position of the match, -1 for no
match, or -2 for an internal error. Also return register
information in REGS (if REGS and BUFFER->no_sub are nonzero). */
extern regoff_t re_search (struct re_pattern_buffer *__buffer,
const char *__string, __re_idx_t __length,
__re_idx_t __start, regoff_t __range,
struct re_registers *__regs);
/* Like `re_search', but search in the concatenation of STRING1 and
STRING2. Also, stop searching at index START + STOP. */
extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
const char *__string1, __re_idx_t __length1,
const char *__string2, __re_idx_t __length2,
__re_idx_t __start, regoff_t __range,
struct re_registers *__regs,
__re_idx_t __stop);
/* Like `re_search', but return how many characters in STRING the regexp
in BUFFER matched, starting at position START. */
extern regoff_t re_match (struct re_pattern_buffer *__buffer,
const char *__string, __re_idx_t __length,
__re_idx_t __start, struct re_registers *__regs);
/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
const char *__string1, __re_idx_t __length1,
const char *__string2, __re_idx_t __length2,
__re_idx_t __start, struct re_registers *__regs,
__re_idx_t __stop);
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
ENDS. Subsequent matches using BUFFER and REGS will use this memory
for recording register information. STARTS and ENDS must be
allocated with malloc, and must each be at least `NUM_REGS * sizeof
(regoff_t)' bytes long.
If NUM_REGS == 0, then subsequent matches should allocate their own
register data.
Unless this function is called, the first search or match using
PATTERN_BUFFER will allocate its own register data, without
freeing the old data. */
extern void re_set_registers (struct re_pattern_buffer *__buffer,
struct re_registers *__regs,
__re_size_t __num_regs,
regoff_t *__starts, regoff_t *__ends);
#if defined _REGEX_RE_COMP || defined _LIBC
# ifndef _CRAY
/* 4.2 bsd compatibility. */
extern char *re_comp (const char *);
extern int re_exec (const char *);
# endif
#endif
/* GCC 2.95 and later have "__restrict"; C99 compilers have
"restrict", and "configure" may have defined "restrict".
Other compilers use __restrict, __restrict__, and _Restrict, and
'configure' might #define 'restrict' to those words, so pick a
different name. */
#ifndef _Restrict_
# if 199901L <= __STDC_VERSION__
# define _Restrict_ restrict
# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)
# define _Restrict_ __restrict
# else
# define _Restrict_
# endif
#endif
/* gcc 3.1 and up support the [restrict] syntax. Don't trust
sys/cdefs.h's definition of __restrict_arr, though, as it
mishandles gcc -ansi -pedantic. */
#ifndef _Restrict_arr_
# if ((199901L <= __STDC_VERSION__ \
|| ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__)) \
&& !__STRICT_ANSI__)) \
&& !defined __GNUG__)
# define _Restrict_arr_ _Restrict_
# else
# define _Restrict_arr_
# endif
#endif
/* POSIX compatibility. */
extern int regcomp (regex_t *_Restrict_ __preg,
const char *_Restrict_ __pattern,
int __cflags);
extern int regexec (const regex_t *_Restrict_ __preg,
const char *_Restrict_ __string, size_t __nmatch,
regmatch_t __pmatch[_Restrict_arr_],
int __eflags);
extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
char *_Restrict_ __errbuf, size_t __errbuf_size);
extern void regfree (regex_t *__preg);
#ifdef __cplusplus
}
#endif /* C++ */
#endif /* regex.h */

View file

@ -1,6 +1,6 @@
/* Extended regular expression matching and search library.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@ -36,7 +36,7 @@ static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
re_string_reconstruct before using the object. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
{
@ -64,7 +64,7 @@ re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
/* This function allocate the buffers, and initialize them. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_string_construct (re_string_t *pstr, const char *str, Idx len,
RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
{
@ -127,7 +127,7 @@ re_string_construct (re_string_t *pstr, const char *str, Idx len,
/* Helper functions for re_string_allocate, and re_string_construct. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
{
#ifdef RE_ENABLE_I18N
@ -267,7 +267,7 @@ build_wcs_buffer (re_string_t *pstr)
but for REG_ICASE. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
build_wcs_upper_buffer (re_string_t *pstr)
{
mbstate_t prev_st;
@ -430,8 +430,8 @@ build_wcs_upper_buffer (re_string_t *pstr)
src_idx += mbclen;
continue;
}
else
memcpy (pstr->mbs + byte_idx, p, mbclen);
else
memcpy (pstr->mbs + byte_idx, p, mbclen);
}
else
memcpy (pstr->mbs + byte_idx, p, mbclen);
@ -569,7 +569,7 @@ re_string_translate_buffer (re_string_t *pstr)
convert to upper case in case of REG_ICASE, apply translation. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
{
Idx offset;
@ -964,7 +964,7 @@ re_string_context_at (const re_string_t *input, Idx idx, int eflags)
/* Functions for set operation. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_alloc (re_node_set *set, Idx size)
{
set->alloc = size;
@ -976,7 +976,7 @@ re_node_set_alloc (re_node_set *set, Idx size)
}
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_init_1 (re_node_set *set, Idx elem)
{
set->alloc = 1;
@ -992,7 +992,7 @@ re_node_set_init_1 (re_node_set *set, Idx elem)
}
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
{
set->alloc = 2;
@ -1022,7 +1022,7 @@ re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
}
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
{
dest->nelem = src->nelem;
@ -1047,7 +1047,7 @@ re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
Note: We assume dest->elems is NULL, when dest->alloc is 0. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
const re_node_set *src2)
{
@ -1062,7 +1062,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
if (BE (new_elems == NULL, 0))
return REG_ESPACE;
return REG_ESPACE;
dest->elems = new_elems;
dest->alloc = new_alloc;
}
@ -1112,20 +1112,20 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
if (delta > 0 && REG_VALID_INDEX (id))
for (;;)
{
if (dest->elems[is] > dest->elems[id])
{
/* Copy from the top. */
dest->elems[id + delta--] = dest->elems[is--];
if (delta == 0)
break;
}
else
{
/* Slide from the bottom. */
dest->elems[id + delta] = dest->elems[id];
if (! REG_VALID_INDEX (--id))
break;
}
if (dest->elems[is] > dest->elems[id])
{
/* Copy from the top. */
dest->elems[id + delta--] = dest->elems[is--];
if (delta == 0)
break;
}
else
{
/* Slide from the bottom. */
dest->elems[id + delta] = dest->elems[id];
if (! REG_VALID_INDEX (--id))
break;
}
}
/* Copy remaining SRC elements. */
@ -1138,7 +1138,7 @@ re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
const re_node_set *src2)
{
@ -1191,7 +1191,7 @@ re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
DEST. Return value indicate the error code or REG_NOERROR if succeeded. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_merge (re_node_set *dest, const re_node_set *src)
{
Idx is, id, sbase, delta;
@ -1221,11 +1221,11 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
REG_VALID_INDEX (is) && REG_VALID_INDEX (id); )
{
if (dest->elems[id] == src->elems[is])
is--, id--;
is--, id--;
else if (dest->elems[id] < src->elems[is])
dest->elems[--sbase] = src->elems[is--];
dest->elems[--sbase] = src->elems[is--];
else /* if (dest->elems[id] > src->elems[is]) */
--id;
--id;
}
if (REG_VALID_INDEX (is))
@ -1247,21 +1247,21 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
for (;;)
{
if (dest->elems[is] > dest->elems[id])
{
{
/* Copy from the top. */
dest->elems[id + delta--] = dest->elems[is--];
dest->elems[id + delta--] = dest->elems[is--];
if (delta == 0)
break;
}
else
{
/* Slide from the bottom. */
dest->elems[id + delta] = dest->elems[id];
{
/* Slide from the bottom. */
dest->elems[id + delta] = dest->elems[id];
if (! REG_VALID_INDEX (--id))
{
/* Copy remaining SRC elements. */
memcpy (dest->elems, dest->elems + sbase,
delta * sizeof (Idx));
delta * sizeof (Idx));
break;
}
}
@ -1275,7 +1275,7 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src)
Return true if successful. */
static bool
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_insert (re_node_set *set, Idx elem)
{
Idx idx;
@ -1308,12 +1308,12 @@ re_node_set_insert (re_node_set *set, Idx elem)
{
idx = 0;
for (idx = set->nelem; idx > 0; idx--)
set->elems[idx] = set->elems[idx - 1];
set->elems[idx] = set->elems[idx - 1];
}
else
{
for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
set->elems[idx] = set->elems[idx - 1];
set->elems[idx] = set->elems[idx - 1];
}
/* Insert the new element. */
@ -1327,7 +1327,7 @@ re_node_set_insert (re_node_set *set, Idx elem)
Return true if successful. */
static bool
internal_function
internal_function __attribute_warn_unused_result__
re_node_set_insert_last (re_node_set *set, Idx elem)
{
/* Realloc if we need. */
@ -1473,7 +1473,7 @@ calc_state_hash (const re_node_set *nodes, unsigned int context)
optimization. */
static re_dfastate_t *
internal_function
internal_function __attribute_warn_unused_result__
re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
const re_node_set *nodes)
{
@ -1521,7 +1521,7 @@ re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
optimization. */
static re_dfastate_t *
internal_function
internal_function __attribute_warn_unused_result__
re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
const re_node_set *nodes, unsigned int context)
{
@ -1562,6 +1562,7 @@ re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
indicates the error code if failed. */
static reg_errcode_t
__attribute_warn_unused_result__
register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
re_hashval_t hash)
{
@ -1616,7 +1617,7 @@ free_state (re_dfastate_t *state)
Return the new state if succeeded, otherwise return NULL. */
static re_dfastate_t *
internal_function
internal_function __attribute_warn_unused_result__
create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
re_hashval_t hash)
{
@ -1666,7 +1667,7 @@ create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
Return the new state if succeeded, otherwise return NULL. */
static re_dfastate_t *
internal_function
internal_function __attribute_warn_unused_result__
create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
unsigned int context, re_hashval_t hash)
{
@ -1715,7 +1716,9 @@ create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
free_state (newstate);
return NULL;
}
re_node_set_init_copy (newstate->entrance_nodes, nodes);
if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
!= REG_NOERROR)
return NULL;
nctx_nodes = 0;
newstate->has_constraint = 1;
}

View file

@ -1,6 +1,6 @@
/* Extended regular expression matching and search library.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@ -21,6 +21,32 @@
#ifndef _REGEX_INTERNAL_H
#define _REGEX_INTERNAL_H 1
#include <assert.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <langinfo.h>
#ifndef _LIBC
# include "localcharset.h"
#endif
#if defined HAVE_LOCALE_H || defined _LIBC
# include <locale.h>
#endif
#include <wchar.h>
#include <wctype.h>
#include <stdint.h>
#if defined _LIBC
# include <bits/libc-lock.h>
#else
# define __libc_lock_init(NAME) do { } while (0)
# define __libc_lock_lock(NAME) do { } while (0)
# define __libc_lock_unlock(NAME) do { } while (0)
#endif
/* In case that the system doesn't have isblank(). */
#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
@ -58,7 +84,7 @@
# define SIZE_MAX ((size_t) -1)
#endif
#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || defined (_LIBC)
#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC
# define RE_ENABLE_I18N
#endif
@ -825,4 +851,21 @@ re_string_elem_size_at (const re_string_t *pstr, Idx idx)
}
#endif /* RE_ENABLE_I18N */
#ifndef __GNUC_PREREQ
# if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
# else
# define __GNUC_PREREQ(maj, min) 0
# endif
#endif
#if __GNUC_PREREQ (3,4)
# undef __attribute_warn_unused_result__
# define __attribute_warn_unused_result__ \
__attribute__ ((__warn_unused_result__))
#else
# define __attribute_warn_unused_result__ /* empty */
#endif
#endif /* _REGEX_INTERNAL_H */

View file

@ -1,6 +1,6 @@
/* Extended regular expression matching and search library.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
@ -637,7 +637,7 @@ re_exec (s)
(0 <= LAST_START && LAST_START <= LENGTH) */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
re_search_internal (const regex_t *preg,
const char *string, Idx length,
Idx start, Idx last_start, Idx stop,
@ -833,10 +833,10 @@ re_search_internal (const regex_t *preg,
break;
match_first += incr;
if (match_first < left_lim || match_first > right_lim)
{
err = REG_NOMATCH;
goto free_return;
}
{
err = REG_NOMATCH;
goto free_return;
}
}
break;
}
@ -953,14 +953,14 @@ re_search_internal (const regex_t *preg,
}
if (dfa->subexp_map)
for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
if (dfa->subexp_map[reg_idx] != reg_idx)
{
pmatch[reg_idx + 1].rm_so
= pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
pmatch[reg_idx + 1].rm_eo
= pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
}
for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
if (dfa->subexp_map[reg_idx] != reg_idx)
{
pmatch[reg_idx + 1].rm_so
= pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
pmatch[reg_idx + 1].rm_eo
= pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
}
}
free_return:
@ -972,7 +972,7 @@ re_search_internal (const regex_t *preg,
}
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
prune_impossible_nodes (re_match_context_t *mctx)
{
const re_dfa_t *const dfa = mctx->dfa;
@ -1110,7 +1110,7 @@ acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
index of the buffer. */
static Idx
internal_function
internal_function __attribute_warn_unused_result__
check_matching (re_match_context_t *mctx, bool fl_longest_match,
Idx *p_match_first)
{
@ -1149,7 +1149,7 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match,
{
err = transit_state_bkref (mctx, &cur_state->nodes);
if (BE (err != REG_NOERROR, 0))
return err;
return err;
}
}
}
@ -1176,16 +1176,16 @@ check_matching (re_match_context_t *mctx, bool fl_longest_match,
Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1;
if (BE (next_char_idx >= mctx->input.bufs_len, 0)
|| (BE (next_char_idx >= mctx->input.valid_len, 0)
&& mctx->input.valid_len < mctx->input.len))
{
err = extend_buffers (mctx);
if (BE (err != REG_NOERROR, 0))
|| (BE (next_char_idx >= mctx->input.valid_len, 0)
&& mctx->input.valid_len < mctx->input.len))
{
err = extend_buffers (mctx);
if (BE (err != REG_NOERROR, 0))
{
assert (err == REG_ESPACE);
return REG_ERROR;
}
}
}
cur_state = transit_state (&err, mctx, cur_state);
if (mctx->state_log != NULL)
@ -1309,17 +1309,17 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
if (dest_node == REG_MISSING)
dest_node = candidate;
else
else
{
/* In order to avoid infinite loop like "(a*)*", return the second
epsilon-transition if the first was already considered. */
epsilon-transition if the first was already considered. */
if (re_node_set_contains (eps_via_nodes, dest_node))
return candidate;
return candidate;
/* Otherwise, push the second epsilon-transition on the fail stack. */
else if (fs != NULL
&& push_fail_stack (fs, *pidx, candidate, nregs, regs,
eps_via_nodes))
eps_via_nodes))
return REG_ERROR;
/* We know we are going to exit. */
@ -1385,7 +1385,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
}
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
{
@ -1432,7 +1432,7 @@ pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
regmatch_t *pmatch, bool fl_backtrack)
{
@ -1667,7 +1667,7 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)
if (mctx->state_log[str_idx])
{
err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
if (BE (err != REG_NOERROR, 0))
if (BE (err != REG_NOERROR, 0))
goto free_return;
}
@ -1686,7 +1686,7 @@ sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)
}
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
Idx str_idx, re_node_set *cur_dest)
{
@ -1848,7 +1848,7 @@ update_cur_sifted_state (const re_match_context_t *mctx,
}
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
const re_node_set *candidates)
{
@ -1863,10 +1863,14 @@ add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
{
err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
if (BE (err != REG_NOERROR, 0))
return REG_ESPACE;
return REG_ESPACE;
for (i = 0; i < dest_nodes->nelem; i++)
re_node_set_merge (&state->inveclosure,
dfa->inveclosures + dest_nodes->elems[i]);
{
err = re_node_set_merge (&state->inveclosure,
dfa->inveclosures + dest_nodes->elems[i]);
if (BE (err != REG_NOERROR, 0))
return REG_ESPACE;
}
}
return re_node_set_add_intersect (dest_nodes, candidates,
&state->inveclosure);
@ -1978,7 +1982,7 @@ check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
{
struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
do
{
{
Idx dst;
int cpos;
@ -2000,9 +2004,9 @@ check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
if (dst == from_node)
{
if (boundaries & 1)
return -1;
return -1;
else /* if (boundaries & 2) */
return 0;
return 0;
}
cpos =
@ -2016,7 +2020,7 @@ check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
if (subexp_idx < BITSET_WORD_BITS)
ent->eps_reachable_subexps_map
&= ~((bitset_word_t) 1 << subexp_idx);
}
}
while (ent++->more);
}
break;
@ -2158,7 +2162,7 @@ check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,
}
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
Idx str_idx, const re_node_set *candidates)
{
@ -2241,7 +2245,7 @@ sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
re_node_set_remove (&local_sctx.limits, enabled_idx);
/* mctx->bkref_ents may have changed, reload the pointer. */
entry = mctx->bkref_ents + enabled_idx;
entry = mctx->bkref_ents + enabled_idx;
}
while (enabled_idx++, entry++->more);
}
@ -2288,7 +2292,7 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
update the destination of STATE_LOG. */
static re_dfastate_t *
internal_function
internal_function __attribute_warn_unused_result__
transit_state (reg_errcode_t *err, re_match_context_t *mctx,
re_dfastate_t *state)
{
@ -2322,7 +2326,7 @@ transit_state (reg_errcode_t *err, re_match_context_t *mctx,
trtable = state->word_trtable;
if (BE (trtable != NULL, 1))
{
{
unsigned int context;
context
= re_string_context_at (&mctx->input,
@ -2368,21 +2372,21 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,
unsigned int context;
re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
/* If (state_log[cur_idx] != 0), it implies that cur_idx is
the destination of a multibyte char/collating element/
back reference. Then the next state is the union set of
these destinations and the results of the transition table. */
the destination of a multibyte char/collating element/
back reference. Then the next state is the union set of
these destinations and the results of the transition table. */
pstate = mctx->state_log[cur_idx];
log_nodes = pstate->entrance_nodes;
if (next_state != NULL)
{
table_nodes = next_state->entrance_nodes;
*err = re_node_set_init_union (&next_nodes, table_nodes,
{
table_nodes = next_state->entrance_nodes;
*err = re_node_set_init_union (&next_nodes, table_nodes,
log_nodes);
if (BE (*err != REG_NOERROR, 0))
if (BE (*err != REG_NOERROR, 0))
return NULL;
}
}
else
next_nodes = *log_nodes;
next_nodes = *log_nodes;
/* Note: We already add the nodes of the initial state,
then we don't need to add them here. */
@ -2390,12 +2394,12 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,
re_string_cur_idx (&mctx->input) - 1,
mctx->eflags);
next_state = mctx->state_log[cur_idx]
= re_acquire_state_context (err, dfa, &next_nodes, context);
= re_acquire_state_context (err, dfa, &next_nodes, context);
/* We don't need to check errors here, since the return value of
this function is next_state and ERR is already set. */
this function is next_state and ERR is already set. */
if (table_nodes != NULL)
re_node_set_free (&next_nodes);
re_node_set_free (&next_nodes);
}
if (BE (dfa->nbackref, 0) && next_state != NULL)
@ -2436,9 +2440,9 @@ find_recover_state (reg_errcode_t *err, re_match_context_t *mctx)
do
{
if (++cur_str_idx > max)
return NULL;
re_string_skip_bytes (&mctx->input, 1);
if (++cur_str_idx > max)
return NULL;
re_string_skip_bytes (&mctx->input, 1);
}
while (mctx->state_log[cur_str_idx] == NULL);
@ -2546,7 +2550,7 @@ transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
re_dfastate_t *dest_state;
if (!dfa->nodes[cur_node_idx].accept_mb)
continue;
continue;
if (dfa->nodes[cur_node_idx].constraint)
{
@ -2714,7 +2718,7 @@ transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)
delay these checking for prune_impossible_nodes(). */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)
{
const re_dfa_t *const dfa = mctx->dfa;
@ -2727,7 +2731,7 @@ get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)
const struct re_backref_cache_entry *entry
= mctx->bkref_ents + cache_idx;
do
if (entry->node == bkref_node)
if (entry->node == bkref_node)
return REG_NOERROR; /* We already checked it. */
while (entry++->more);
}
@ -2915,7 +2919,7 @@ find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node,
Idx top_str, Idx last_node, Idx last_str, int type)
{
@ -3077,7 +3081,7 @@ check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node,
Can't we unify them? */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,
re_node_set *cur_nodes, re_node_set *next_nodes)
{
@ -3211,7 +3215,7 @@ check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes,
problematic append it to DST_NODES. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
Idx target, Idx ex_subexp, int type)
{
@ -3256,7 +3260,7 @@ check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
in MCTX->BKREF_ENTS. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
Idx cur_str, Idx subexp_num, int type)
{
@ -3622,7 +3626,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
}
#ifdef RE_ENABLE_I18N
else if (type == OP_UTF8_PERIOD)
{
{
if (ASCII_CHARS % BITSET_WORD_BITS == 0)
memset (accepts, -1, ASCII_CHARS / CHAR_BIT);
else
@ -3631,7 +3635,7 @@ group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
bitset_clear (accepts, '\n');
if (dfa->syntax & RE_DOT_NOT_NULL)
bitset_clear (accepts, '\0');
}
}
#endif
else
continue;
@ -3836,7 +3840,7 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
if (node->type == OP_PERIOD)
{
if (char_len <= 1)
return 0;
return 0;
/* FIXME: I don't think this if is needed, as both '\n'
and '\0' are char_len == 1. */
/* '.' accepts any one character except the following two cases. */
@ -3949,15 +3953,20 @@ check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
indirect = (const int32_t *)
_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
idx = findidx (&cp);
int32_t idx = findidx (&cp);
if (idx > 0)
for (i = 0; i < cset->nequiv_classes; ++i)
{
int32_t equiv_class_idx = cset->equiv_classes[i];
size_t weight_len = weights[idx];
if (weight_len == weights[equiv_class_idx])
size_t weight_len = weights[idx & 0xffffff];
if (weight_len == weights[equiv_class_idx & 0xffffff]
&& (idx >> 24) == (equiv_class_idx >> 24))
{
Idx cnt = 0;
idx &= 0xffffff;
equiv_class_idx &= 0xffffff;
while (cnt <= weight_len
&& (weights[equiv_class_idx + 1 + cnt]
== weights[idx + 1 + cnt]))
@ -4123,7 +4132,7 @@ check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
/* Extend the buffers, if the buffers have run out. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
extend_buffers (re_match_context_t *mctx)
{
reg_errcode_t ret;
@ -4186,7 +4195,7 @@ extend_buffers (re_match_context_t *mctx)
/* Initialize MCTX. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
match_ctx_init (re_match_context_t *mctx, int eflags, Idx n)
{
mctx->eflags = eflags;
@ -4266,7 +4275,7 @@ match_ctx_free (re_match_context_t *mctx)
*/
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from,
Idx to)
{
@ -4338,7 +4347,7 @@ search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
at STR_IDX. */
static reg_errcode_t
internal_function
internal_function __attribute_warn_unused_result__
match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)
{
#ifdef DEBUG