2002-04-26  Isamu Hasegawa  <isamu@yamato.ibm.com>

	* posix/regcomp.c (re_compile_fastmap_iter): Fix fastmap in case of
	not _LIBC and RE_ENABLE_I18N.
	(build_range_exp): Implement for not _LIBC.
	(build_collating_symbol): Likewise.
	(parse_bracket_exp): Unify redundant error handlings.
	Don't erase mbcset for non matching list in multibyte envs.
	(build_word_op): Add '_' to matching list for \w operator.
	* posix/regex_internal.c (re_string_construct): Invoke
	build_upper_buffer in case of not RE_ENABLE_I18N.
	(re_string_reconstruct): Don't touch cur_state in case of not
	RE_ENABLE_I18N.
	* posix/regex_internal.h (attribute_hidden): New macro in case of
	not _LIBC.
	(re_charset_t): Define range_starts/ends in case of not _LIBC.
	* posix/regexec.c (sift_states_iter_mb): Hide in case of not
	RE_ENABLE_I18N.
	(transit_state_mb): Likewise.
	(check_node_accept_bytes): Implement the code evaluating range
	expression in case of not _LIBC.
	(find_collation_sequence_value): Hide in case of not _LIBC.

2002-04-26  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c: Copied from
	i386/semctl.c.
	(__old_semctl, __new_semctl): Only use va_arg if the argument will
	be used.
This commit is contained in:
Ulrich Drepper 2002-04-26 20:52:02 +00:00
parent 58fe8d1096
commit 434d3784f1
6 changed files with 514 additions and 91 deletions

View File

@ -1,3 +1,33 @@
2002-04-26 Isamu Hasegawa <isamu@yamato.ibm.com>
* posix/regcomp.c (re_compile_fastmap_iter): Fix fastmap in case of
not _LIBC and RE_ENABLE_I18N.
(build_range_exp): Implement for not _LIBC.
(build_collating_symbol): Likewise.
(parse_bracket_exp): Unify redundant error handlings.
Don't erase mbcset for non matching list in multibyte envs.
(build_word_op): Add '_' to matching list for \w operator.
* posix/regex_internal.c (re_string_construct): Invoke
build_upper_buffer in case of not RE_ENABLE_I18N.
(re_string_reconstruct): Don't touch cur_state in case of not
RE_ENABLE_I18N.
* posix/regex_internal.h (attribute_hidden): New macro in case of
not _LIBC.
(re_charset_t): Define range_starts/ends in case of not _LIBC.
* posix/regexec.c (sift_states_iter_mb): Hide in case of not
RE_ENABLE_I18N.
(transit_state_mb): Likewise.
(check_node_accept_bytes): Implement the code evaluating range
expression in case of not _LIBC.
(find_collation_sequence_value): Hide in case of not _LIBC.
2002-04-26 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/sparc/sparc32/semctl.c: Copied from
i386/semctl.c.
(__old_semctl, __new_semctl): Only use va_arg if the argument will
be used.
2002-04-26 Ulrich Drepper <drepper@redhat.com> 2002-04-26 Ulrich Drepper <drepper@redhat.com>
* sysdeps/ia64/fpu/s_isinf.S: Fix definition of _internal names. * sysdeps/ia64/fpu/s_isinf.S: Fix definition of _internal names.

View File

@ -114,6 +114,16 @@ static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem, static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
re_string_t *regexp, re_string_t *regexp,
re_token_t *token); re_token_t *token);
#ifndef _LIBC
static reg_errcode_t build_range_exp (re_charset_t *mbcset,
re_bitset_ptr_t sbcset, int *range_alloc,
bracket_elem_t *start_elem,
bracket_elem_t *end_elem);
static reg_errcode_t build_collating_symbol (re_charset_t *mbcset,
re_bitset_ptr_t sbcset,
int *coll_sym_alloc,
unsigned char *name);
#endif /* not _LIBC */
static reg_errcode_t build_equiv_class (re_charset_t *mbcset, static reg_errcode_t build_equiv_class (re_charset_t *mbcset,
re_bitset_ptr_t sbcset, re_bitset_ptr_t sbcset,
int *equiv_class_alloc, int *equiv_class_alloc,
@ -354,7 +364,14 @@ re_compile_fastmap_iter (bufp, init_state, fastmap)
if (table[ch] < 0) if (table[ch] < 0)
fastmap[ch] = 1; fastmap[ch] = 1;
} }
#endif #else
# ifdef RE_ENABLE_I18N
if (MB_CUR_MAX > 1)
for (i = 0; i < SBC_MAX; ++i)
if (__btowc (i) == WEOF)
fastmap[i] = 1;
# endif /* RE_ENABLE_I18N */
#endif /* not _LIBC */
} }
for (i = 0; i < cset->nmbchars; ++i) for (i = 0; i < cset->nmbchars; ++i)
{ {
@ -2207,6 +2224,136 @@ parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)
I'm not sure, but maybe enough. */ I'm not sure, but maybe enough. */
#define BRACKET_NAME_BUF_SIZE 32 #define BRACKET_NAME_BUF_SIZE 32
#ifndef _LIBC
/* Local function for parse_bracket_exp only used in case of NOT _LIBC.
Build the range expression which starts from START_ELEM, and ends
at END_ELEM. The result are written to MBCSET and SBCSET.
RANGE_ALLOC is the allocated size of mbcset->range_starts, and
mbcset->range_ends, is a pointer argument sinse we may
update it. */
static reg_errcode_t
build_range_exp (mbcset, sbcset, range_alloc, start_elem, end_elem)
re_charset_t *mbcset;
re_bitset_ptr_t sbcset;
int *range_alloc;
bracket_elem_t *start_elem, *end_elem;
{
unsigned int start_ch, end_ch;
/* Equivalence Classes and Character Classes can't be a range start/end. */
if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
|| end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
0))
return REG_ERANGE;
/* We can handle no multi character collating elements without libc
support. */
if (BE ((start_elem->type == COLL_SYM && strlen (start_elem->opr.name) > 1)
|| (end_elem->type == COLL_SYM && strlen (end_elem->opr.name) > 1),
0))
return REG_ECOLLATE;
# ifdef RE_ENABLE_I18N
{
wchar_t wc, start_wc, end_wc;
wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
: 0));
end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
: ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
: 0));
start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
? __btowc (start_ch) : start_elem->opr.wch);
end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
? __btowc (end_ch) : end_elem->opr.wch);
cmp_buf[0] = start_wc;
cmp_buf[4] = end_wc;
if (wcscoll (cmp_buf, cmp_buf + 4) > 0)
return REG_ERANGE;
/* Check the space of the arrays. */
if (*range_alloc == mbcset->nranges)
{
/* There are not enough space, need realloc. */
wchar_t *new_array_start, *new_array_end;
int new_nranges;
/* +1 in case of mbcset->nranges is 0. */
new_nranges = 2 * mbcset->nranges + 1;
/* 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_array_end = re_realloc (mbcset->range_ends, wchar_t,
new_nranges);
if (BE (new_array_start == NULL || new_array_end == NULL, 0))
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_wc;
mbcset->range_ends[mbcset->nranges++] = end_wc;
/* Build the table for single byte characters. */
for (wc = 0; wc <= SBC_MAX; ++wc)
{
cmp_buf[2] = wc;
if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
&& wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
bitset_set (sbcset, wc);
}
}
# else /* not RE_ENABLE_I18N */
{
unsigned int ch;
start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch
: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
: 0));
end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch
: ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
: 0));
if (start_ch > end_ch)
return REG_ERANGE;
/* Build the table for single byte characters. */
for (ch = 0; ch <= SBC_MAX; ++ch)
if (start_ch <= ch && ch <= end_ch)
bitset_set (sbcset, ch);
}
# endif /* not RE_ENABLE_I18N */
return REG_NOERROR;
}
#endif /* not _LIBC */
#ifndef _LIBC
/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
Build the collating element which is represented by NAME.
The result are written to MBCSET and SBCSET.
COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
pointer argument since we may update it. */
static reg_errcode_t
build_collating_symbol (mbcset, sbcset, coll_sym_alloc, name)
re_charset_t *mbcset;
re_bitset_ptr_t sbcset;
int *coll_sym_alloc;
unsigned char *name;
{
if (BE (strlen (name) != 1, 0))
return REG_ECOLLATE;
else
{
bitset_set (sbcset, name[0]);
return REG_NOERROR;
}
}
#endif /* not _LIBC */
/* This function parse bracket expression like "[abc]", "[a-c]", /* This function parse bracket expression like "[abc]", "[a-c]",
"[[.a-a.]]" etc. */ "[[.a-a.]]" etc. */
@ -2225,7 +2372,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
const int32_t *symb_table; const int32_t *symb_table;
const unsigned char *extra; const unsigned char *extra;
/* Local function for parse_bracket_exp. /* Local function for parse_bracket_exp used in _LIBC environement.
Seek the collating symbol entry correspondings to NAME. Seek the collating symbol entry correspondings to NAME.
Return the index of the symbol in the SYMB_TABLE. */ Return the index of the symbol in the SYMB_TABLE. */
@ -2257,7 +2404,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
return elem; return elem;
} }
/* Local function for parse_bracket_exp. /* Local function for parse_bracket_exp used in _LIBC environement.
Look up the collation sequence value of BR_ELEM. Look up the collation sequence value of BR_ELEM.
Return the value if succeeded, UINT_MAX otherwise. */ Return the value if succeeded, UINT_MAX otherwise. */
@ -2321,7 +2468,7 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
return UINT_MAX; return UINT_MAX;
} }
/* Local function for parse_bracket_exp. /* Local function for parse_bracket_exp used in _LIBC environement.
Build the range expression which starts from START_ELEM, and ends Build the range expression which starts from START_ELEM, and ends
at END_ELEM. The result are written to MBCSET and SBCSET. at END_ELEM. The result are written to MBCSET and SBCSET.
RANGE_ALLOC is the allocated size of mbcset->range_starts, and RANGE_ALLOC is the allocated size of mbcset->range_starts, and
@ -2364,6 +2511,8 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
*range_alloc = new_nranges; *range_alloc = new_nranges;
} }
/* Equivalence Classes and Character Classes can't be a range
start/end. */
if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
|| end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
0)) 0))
@ -2397,9 +2546,8 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
} }
return REG_NOERROR; return REG_NOERROR;
} }
#endif
/* Local function for parse_bracket_exp. /* Local function for parse_bracket_exp used in _LIBC environement.
Build the collating element which is represented by NAME. Build the collating element which is represented by NAME.
The result are written to MBCSET and SBCSET. The result are written to MBCSET and SBCSET.
COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
@ -2412,7 +2560,6 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
int *coll_sym_alloc; int *coll_sym_alloc;
unsigned char *name; unsigned char *name;
{ {
#ifdef _LIBC
int32_t elem, idx; int32_t elem, idx;
if (nrules != 0) if (nrules != 0)
{ {
@ -2452,7 +2599,6 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
return REG_NOERROR; return REG_NOERROR;
} }
else else
#endif
{ {
if (BE (strlen (name) != 1, 0)) if (BE (strlen (name) != 1, 0))
return REG_ECOLLATE; return REG_ECOLLATE;
@ -2463,6 +2609,8 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
} }
} }
} }
#endif
re_token_t br_token; re_token_t br_token;
re_bitset_ptr_t sbcset; re_bitset_ptr_t sbcset;
re_charset_t *mbcset; re_charset_t *mbcset;
@ -2497,10 +2645,8 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
token_len = peek_token_bracket (token, regexp, syntax); token_len = peek_token_bracket (token, regexp, syntax);
if (BE (token->type == END_OF_RE, 0)) if (BE (token->type == END_OF_RE, 0))
{ {
re_free (sbcset);
free_charset (mbcset);
*err = REG_BADPAT; *err = REG_BADPAT;
return NULL; goto parse_bracket_exp_free_return;
} }
if (token->type == OP_NON_MATCH_LIST) if (token->type == OP_NON_MATCH_LIST)
{ {
@ -2512,10 +2658,8 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
token_len = peek_token_bracket (token, regexp, syntax); token_len = peek_token_bracket (token, regexp, syntax);
if (BE (token->type == END_OF_RE, 0)) if (BE (token->type == END_OF_RE, 0))
{ {
re_free (sbcset);
free_charset (mbcset);
*err = REG_BADPAT; *err = REG_BADPAT;
return NULL; goto parse_bracket_exp_free_return;
} }
if (MB_CUR_MAX > 1) if (MB_CUR_MAX > 1)
for (i = 0; i < SBC_MAX; ++i) for (i = 0; i < SBC_MAX; ++i)
@ -2541,19 +2685,15 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
syntax); syntax);
if (BE (ret != REG_NOERROR, 0)) if (BE (ret != REG_NOERROR, 0))
{ {
re_free (sbcset);
free_charset (mbcset);
*err = ret; *err = ret;
return NULL; goto parse_bracket_exp_free_return;
} }
token_len = peek_token_bracket (token, regexp, syntax); token_len = peek_token_bracket (token, regexp, syntax);
if (BE (token->type == END_OF_RE, 0)) if (BE (token->type == END_OF_RE, 0))
{ {
re_free (sbcset);
free_charset (mbcset);
*err = REG_BADPAT; *err = REG_BADPAT;
return NULL; goto parse_bracket_exp_free_return;
} }
if (token->type == OP_CHARSET_RANGE) if (token->type == OP_CHARSET_RANGE)
{ {
@ -2561,10 +2701,8 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
token_len2 = peek_token_bracket (&token2, regexp, syntax); token_len2 = peek_token_bracket (&token2, regexp, syntax);
if (BE (token->type == END_OF_RE, 0)) if (BE (token->type == END_OF_RE, 0))
{ {
re_free (sbcset);
free_charset (mbcset);
*err = REG_BADPAT; *err = REG_BADPAT;
return NULL; goto parse_bracket_exp_free_return;
} }
if (token2.type == OP_CLOSE_BRACKET) if (token2.type == OP_CLOSE_BRACKET)
{ {
@ -2583,28 +2721,20 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
dfa, syntax); dfa, syntax);
if (BE (ret != REG_NOERROR, 0)) if (BE (ret != REG_NOERROR, 0))
{ {
re_free (sbcset);
free_charset (mbcset);
*err = ret; *err = ret;
return NULL; goto parse_bracket_exp_free_return;
} }
token_len = peek_token_bracket (token, regexp, syntax); token_len = peek_token_bracket (token, regexp, syntax);
if (BE (token->type == END_OF_RE, 0)) if (BE (token->type == END_OF_RE, 0))
{ {
re_free (sbcset);
free_charset (mbcset);
*err = REG_BADPAT; *err = REG_BADPAT;
return NULL; goto parse_bracket_exp_free_return;
} }
*err = build_range_exp (mbcset, sbcset, &range_alloc, &start_elem, *err = build_range_exp (mbcset, sbcset, &range_alloc, &start_elem,
&end_elem); &end_elem);
if (BE (*err != REG_NOERROR, 0)) if (BE (*err != REG_NOERROR, 0))
{ goto parse_bracket_exp_free_return;
re_free (sbcset);
free_charset (mbcset);
return NULL;
}
} }
else else
{ {
@ -2632,21 +2762,13 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
*err = build_equiv_class (mbcset, sbcset, &equiv_class_alloc, *err = build_equiv_class (mbcset, sbcset, &equiv_class_alloc,
start_elem.opr.name); start_elem.opr.name);
if (BE (*err != REG_NOERROR, 0)) if (BE (*err != REG_NOERROR, 0))
{ goto parse_bracket_exp_free_return;
re_free (sbcset);
free_charset (mbcset);
return NULL;
}
break; break;
case COLL_SYM: case COLL_SYM:
*err = build_collating_symbol (mbcset, sbcset, &coll_sym_alloc, *err = build_collating_symbol (mbcset, sbcset, &coll_sym_alloc,
start_elem.opr.name); start_elem.opr.name);
if (BE (*err != REG_NOERROR, 0)) if (BE (*err != REG_NOERROR, 0))
{ goto parse_bracket_exp_free_return;
re_free (sbcset);
free_charset (mbcset);
return NULL;
}
break; break;
case CHAR_CLASS: case CHAR_CLASS:
ret = build_charclass (mbcset, sbcset, &char_class_alloc, ret = build_charclass (mbcset, sbcset, &char_class_alloc,
@ -2678,7 +2800,8 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
goto parse_bracket_exp_espace; goto parse_bracket_exp_espace;
if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
|| mbcset->nranges || (mbcset->nchar_classes && MB_CUR_MAX > 1)) || mbcset->nranges || (MB_CUR_MAX > 1 && (mbcset->nchar_classes
|| mbcset->non_match)))
{ {
re_token_t alt_token; re_token_t alt_token;
bin_tree_t *mbc_tree; bin_tree_t *mbc_tree;
@ -2704,11 +2827,15 @@ parse_bracket_exp (regexp, dfa, token, syntax, err)
} }
parse_bracket_exp_espace: parse_bracket_exp_espace:
free_charset (mbcset);
*err = REG_ESPACE; *err = REG_ESPACE;
parse_bracket_exp_free_return:
re_free (sbcset);
free_charset (mbcset);
return NULL; return NULL;
} }
/* Parse an element in the bracket expression. */
static reg_errcode_t static reg_errcode_t
parse_bracket_element (elem, regexp, token, token_len, dfa, syntax) parse_bracket_element (elem, regexp, token, token_len, dfa, syntax)
bracket_elem_t *elem; bracket_elem_t *elem;
@ -2738,6 +2865,10 @@ parse_bracket_element (elem, regexp, token, token_len, dfa, syntax)
return REG_NOERROR; return REG_NOERROR;
} }
/* Parse a bracket symbol in the bracket expression. Bracket symbols are
such as [:<character_class>:], [.<collating_element>.], and
[=<equivalent_class>=]. */
static reg_errcode_t static reg_errcode_t
parse_bracket_symbol (elem, regexp, token) parse_bracket_symbol (elem, regexp, token)
bracket_elem_t *elem; bracket_elem_t *elem;
@ -2968,10 +3099,12 @@ build_word_op (dfa, not, err)
if (syntax & RE_HAT_LISTS_NOT_NEWLINE) if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
bitset_set(cset->sbcset, '\0'); bitset_set(cset->sbcset, '\0');
*/ */
#ifdef RE_ENABLE_I18N
if (MB_CUR_MAX > 1) if (MB_CUR_MAX > 1)
for (i = 0; i < SBC_MAX; ++i) for (i = 0; i < SBC_MAX; ++i)
if (__btowc (i) == WEOF) if (__btowc (i) == WEOF)
bitset_set (sbcset, i); bitset_set (sbcset, i);
#endif /* RE_ENABLE_I18N */
} }
/* We don't care the syntax in this case. */ /* We don't care the syntax in this case. */
@ -2983,6 +3116,8 @@ build_word_op (dfa, not, err)
*err = REG_ESPACE; *err = REG_ESPACE;
return NULL; return NULL;
} }
/* \w match '_' also. */
bitset_set (sbcset, '_');
/* If it is non-matching list. */ /* If it is non-matching list. */
if (mbcset->non_match) if (mbcset->non_match)

View File

@ -60,7 +60,9 @@
static void re_string_construct_common (const unsigned char *str, static void re_string_construct_common (const unsigned char *str,
int len, re_string_t *pstr, int len, re_string_t *pstr,
RE_TRANSLATE_TYPE trans, int icase); RE_TRANSLATE_TYPE trans, int icase);
#ifdef RE_ENABLE_I18N
static int re_string_skip_chars (re_string_t *pstr, int new_raw_idx); 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, static re_dfastate_t *create_newstate_common (re_dfa_t *dfa,
const re_node_set *nodes, const re_node_set *nodes,
unsigned int hash); unsigned int hash);
@ -134,8 +136,8 @@ re_string_construct (pstr, str, len, trans, icase)
if (MB_CUR_MAX > 1) if (MB_CUR_MAX > 1)
build_wcs_upper_buffer (pstr); build_wcs_upper_buffer (pstr);
else else
build_upper_buffer (pstr);
#endif /* RE_ENABLE_I18N */ #endif /* RE_ENABLE_I18N */
build_upper_buffer (pstr);
} }
else else
{ {
@ -409,7 +411,10 @@ re_string_reconstruct (pstr, idx, eflags, newline)
if (offset < 0) if (offset < 0)
{ {
/* Reset buffer. */ /* Reset buffer. */
memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); #ifdef RE_ENABLE_I18N
if (MB_CUR_MAX > 1)
memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
#endif /* RE_ENABLE_I18N */
pstr->valid_len = pstr->raw_mbs_idx = 0; pstr->valid_len = pstr->raw_mbs_idx = 0;
pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
: CONTEXT_NEWLINE | CONTEXT_BEGBUF); : CONTEXT_NEWLINE | CONTEXT_BEGBUF);

View File

@ -37,7 +37,8 @@
# define __iswctype iswctype # define __iswctype iswctype
# define __btowc btowc # define __btowc btowc
# define __mempcpy memcpy # define __mempcpy memcpy
#endif # define attribute_hidden
#endif /* not _LIBC */
extern const char __re_error_msgid[] attribute_hidden; extern const char __re_error_msgid[] attribute_hidden;
extern const size_t __re_error_msgid_idx[] attribute_hidden; extern const size_t __re_error_msgid_idx[] attribute_hidden;
@ -161,7 +162,10 @@ typedef struct
#ifdef _LIBC #ifdef _LIBC
uint32_t *range_starts; uint32_t *range_starts;
uint32_t *range_ends; uint32_t *range_ends;
#endif #else /* not _LIBC */
wchar_t *range_starts;
wchar_t *range_ends;
#endif /* not _LIBC */
int nranges; int nranges;
/* Character classes. */ /* Character classes. */

View File

@ -64,9 +64,11 @@ static int proceed_next_node (const regex_t *preg,
static reg_errcode_t set_regs (const regex_t *preg, static reg_errcode_t set_regs (const regex_t *preg,
const re_match_context_t *mctx, const re_match_context_t *mctx,
size_t nmatch, regmatch_t *pmatch, int last); size_t nmatch, regmatch_t *pmatch, int last);
#ifdef RE_ENABLE_I18N
static int sift_states_iter_mb (const regex_t *preg, static int sift_states_iter_mb (const regex_t *preg,
const re_match_context_t *mctx, const re_match_context_t *mctx,
int node_idx, int str_idx, int max_str_idx); int node_idx, int str_idx, int max_str_idx);
#endif /* RE_ENABLE_I18N */
static int sift_states_iter_bkref (const re_dfa_t *dfa, static int sift_states_iter_bkref (const re_dfa_t *dfa,
re_dfastate_t **state_log, re_dfastate_t **state_log,
struct re_backref_cache_entry *mctx_entry, struct re_backref_cache_entry *mctx_entry,
@ -88,9 +90,11 @@ static re_dfastate_t *transit_state_sb (reg_errcode_t *err, const regex_t *preg,
re_dfastate_t *pstate, re_dfastate_t *pstate,
int fl_search, int fl_search,
re_match_context_t *mctx); re_match_context_t *mctx);
#ifdef RE_ENABLE_I18N
static reg_errcode_t transit_state_mb (const regex_t *preg, static reg_errcode_t transit_state_mb (const regex_t *preg,
re_dfastate_t *pstate, re_dfastate_t *pstate,
re_match_context_t *mctx); re_match_context_t *mctx);
#endif /* RE_ENABLE_I18N */
static reg_errcode_t transit_state_bkref (const regex_t *preg, static reg_errcode_t transit_state_bkref (const regex_t *preg,
re_dfastate_t *pstate, re_dfastate_t *pstate,
re_match_context_t *mctx); re_match_context_t *mctx);
@ -101,10 +105,14 @@ static reg_errcode_t transit_state_bkref_loop (const regex_t *preg,
static re_dfastate_t **build_trtable (const regex_t *dfa, static re_dfastate_t **build_trtable (const regex_t *dfa,
const re_dfastate_t *state, const re_dfastate_t *state,
int fl_search); int fl_search);
#ifdef RE_ENABLE_I18N
static int check_node_accept_bytes (const regex_t *preg, int node_idx, static int check_node_accept_bytes (const regex_t *preg, int node_idx,
const re_string_t *input, int idx); const re_string_t *input, int idx);
# ifdef _LIBC
static unsigned int find_collation_sequence_value (const unsigned char *mbs, static unsigned int find_collation_sequence_value (const unsigned char *mbs,
size_t name_len); size_t name_len);
# endif /* _LIBC */
#endif /* RE_ENABLE_I18N */
static int group_nodes_into_DFAstates (const regex_t *dfa, static int group_nodes_into_DFAstates (const regex_t *dfa,
const re_dfastate_t *state, const re_dfastate_t *state,
re_node_set *states_node, re_node_set *states_node,
@ -912,9 +920,12 @@ proceed_next_node (preg, mctx, pidx, node, eps_via_nodes)
type = dfa->nodes[entity].type; type = dfa->nodes[entity].type;
} }
#ifdef RE_ENABLE_I18N
if (ACCEPT_MB_NODE (type)) if (ACCEPT_MB_NODE (type))
naccepted = check_node_accept_bytes (preg, entity, mctx->input, *pidx); naccepted = check_node_accept_bytes (preg, entity, mctx->input, *pidx);
else if (type == OP_BACK_REF) else
#endif /* RE_ENABLE_I18N */
if (type == OP_BACK_REF)
{ {
for (i = 0; i < mctx->nbkref_ents; ++i) for (i = 0; i < mctx->nbkref_ents; ++i)
{ {
@ -1121,13 +1132,16 @@ sift_states_backward (preg, mctx, last_node)
type = dfa->nodes[entity].type; type = dfa->nodes[entity].type;
} }
#ifdef RE_ENABLE_I18N
/* If the node may accept `multi byte'. */ /* If the node may accept `multi byte'. */
if (ACCEPT_MB_NODE (type)) if (ACCEPT_MB_NODE (type))
naccepted = sift_states_iter_mb (preg, mctx, entity, str_idx, naccepted = sift_states_iter_mb (preg, mctx, entity, str_idx,
mctx->match_last); mctx->match_last);
/* If the node is a back reference. */ /* If the node is a back reference. */
else if (type == OP_BACK_REF) else
#endif /* RE_ENABLE_I18N */
if (type == OP_BACK_REF)
for (j = 0; j < mctx->nbkref_ents; ++j) for (j = 0; j < mctx->nbkref_ents; ++j)
{ {
naccepted = sift_states_iter_bkref (dfa, mctx->state_log, naccepted = sift_states_iter_bkref (dfa, mctx->state_log,
@ -1201,6 +1215,7 @@ clean_state_log_if_need (mctx, next_state_log_idx)
return REG_NOERROR; return REG_NOERROR;
} }
#ifdef RE_ENABLE_I18N
static int static int
sift_states_iter_mb (preg, mctx, node_idx, str_idx, max_str_idx) sift_states_iter_mb (preg, mctx, node_idx, str_idx, max_str_idx)
const regex_t *preg; const regex_t *preg;
@ -1222,6 +1237,7 @@ sift_states_iter_mb (preg, mctx, node_idx, str_idx, max_str_idx)
`naccepted' bytes input. */ `naccepted' bytes input. */
return naccepted; return naccepted;
} }
#endif /* RE_ENABLE_I18N */
static int static int
sift_states_iter_bkref (dfa, state_log, mctx_entry, node_idx, idx, match_last) sift_states_iter_bkref (dfa, state_log, mctx_entry, node_idx, idx, match_last)
@ -1317,6 +1333,7 @@ transit_state (err, preg, mctx, state, fl_search)
} }
else else
{ {
#ifdef RE_ENABLE_I18N
/* If the current state can accept multibyte. */ /* If the current state can accept multibyte. */
if (state->accept_mb) if (state->accept_mb)
{ {
@ -1324,6 +1341,7 @@ transit_state (err, preg, mctx, state, fl_search)
if (BE (*err != REG_NOERROR, 0)) if (BE (*err != REG_NOERROR, 0))
return NULL; return NULL;
} }
#endif /* RE_ENABLE_I18N */
/* Then decide the next state with the single byte. */ /* Then decide the next state with the single byte. */
if (1) if (1)
@ -1474,6 +1492,7 @@ transit_state_sb (err, preg, state, fl_search, mctx)
return next_state; return next_state;
} }
#ifdef RE_ENABLE_I18N
static reg_errcode_t static reg_errcode_t
transit_state_mb (preg, pstate, mctx) transit_state_mb (preg, pstate, mctx)
const regex_t *preg; const regex_t *preg;
@ -1543,6 +1562,7 @@ transit_state_mb (preg, pstate, mctx)
} }
return REG_NOERROR; return REG_NOERROR;
} }
#endif /* RE_ENABLE_I18N */
static reg_errcode_t static reg_errcode_t
transit_state_bkref (preg, pstate, mctx) transit_state_bkref (preg, pstate, mctx)
@ -1991,7 +2011,14 @@ group_nodes_into_DFAstates (preg, state, dests_node, dests_ch)
return ndests; return ndests;
} }
/* Check how many bytes the node `dfa->nodes[node_idx]' accepts. */ #ifdef RE_ENABLE_I18N
/* Check how many bytes the node `dfa->nodes[node_idx]' accepts.
Return the number of the bytes the node accepts.
STR_IDX is the current index of the input string.
This function handles the nodes which can accept one character, or
one collating element like '.', '[a-z]', opposite to the other nodes
can only accept one byte. */
static int static int
check_node_accept_bytes (preg, node_idx, input, str_idx) check_node_accept_bytes (preg, node_idx, input, str_idx)
@ -2003,14 +2030,16 @@ check_node_accept_bytes (preg, node_idx, input, str_idx)
const re_token_t *node = dfa->nodes + node_idx; const re_token_t *node = dfa->nodes + node_idx;
int elem_len = re_string_elem_size_at (input, str_idx); int elem_len = re_string_elem_size_at (input, str_idx);
int char_len = re_string_char_size_at (input, str_idx); int char_len = re_string_char_size_at (input, str_idx);
int i, j; int i;
#ifdef _LIBC # ifdef _LIBC
int j;
uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
#endif /* _LIBC */ # endif /* _LIBC */
if (elem_len <= 1 && char_len <= 1) if (elem_len <= 1 && char_len <= 1)
return 0; return 0;
if (node->type == OP_PERIOD) if (node->type == OP_PERIOD)
{ {
/* '.' accepts any one character except the following two cases. */
if ((!(preg->syntax & RE_DOT_NEWLINE) && if ((!(preg->syntax & RE_DOT_NEWLINE) &&
re_string_byte_at (input, str_idx) == '\n') || re_string_byte_at (input, str_idx) == '\n') ||
((preg->syntax & RE_DOT_NOT_NULL) && ((preg->syntax & RE_DOT_NOT_NULL) &&
@ -2021,18 +2050,40 @@ check_node_accept_bytes (preg, node_idx, input, str_idx)
else if (node->type == COMPLEX_BRACKET) else if (node->type == COMPLEX_BRACKET)
{ {
const re_charset_t *cset = node->opr.mbcset; const re_charset_t *cset = node->opr.mbcset;
# ifdef _LIBC
const unsigned char *pin = re_string_get_buffer (input) + str_idx; const unsigned char *pin = re_string_get_buffer (input) + str_idx;
#ifdef _LIBC # endif /* _LIBC */
int match_len = 0;
wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
? re_string_wchar_at (input, str_idx) : 0);
/* match with multibyte character? */
for (i = 0; i < cset->nmbchars; ++i)
if (wc == cset->mbchars[i])
{
match_len = char_len;
goto check_node_accept_bytes_match;
}
/* match with character_class? */
for (i = 0; i < cset->nchar_classes; ++i)
{
wctype_t wt = cset->char_classes[i];
if (__iswctype (wc, wt))
{
match_len = char_len;
goto check_node_accept_bytes_match;
}
}
# ifdef _LIBC
if (nrules != 0) if (nrules != 0)
{ {
int match_len = 0;
unsigned int in_collseq = 0; unsigned int in_collseq = 0;
const int32_t *table, *indirect; const int32_t *table, *indirect;
const unsigned char *weights, *extra, *collseqwc; const unsigned char *weights, *extra, *collseqwc;
int32_t idx; int32_t idx;
wchar_t wc = 0;
/* This #include defines a local function! */ /* This #include defines a local function! */
# include <locale/weight.h> # include <locale/weight.h>
/* match with collating_symbol? */ /* match with collating_symbol? */
if (cset->ncoll_syms) if (cset->ncoll_syms)
@ -2057,9 +2108,6 @@ check_node_accept_bytes (preg, node_idx, input, str_idx)
} }
} }
if (cset->nranges || cset->nchar_classes || cset->nmbchars)
wc = re_string_wchar_at (input, str_idx);
if (cset->nranges) if (cset->nranges)
{ {
if (elem_len <= char_len) if (elem_len <= char_len)
@ -2112,43 +2160,39 @@ check_node_accept_bytes (preg, node_idx, input, str_idx)
} }
} }
} }
}
/* match with multibyte character? */ else
for (i = 0; i < cset->nmbchars; ++i) # endif /* _LIBC */
if (wc == cset->mbchars[i]) {
{ /* match with range expression? */
match_len = char_len; wchar_t cmp_buf[6] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
goto check_node_accept_bytes_match; for (i = 0; i < cset->nranges; ++i)
}
/* match with character_class? */
for (i = 0; i < cset->nchar_classes; ++i)
{ {
wctype_t wt = cset->char_classes[i]; cmp_buf[0] = cset->range_starts[i];
if (__iswctype (wc, wt)) cmp_buf[4] = cset->range_ends[i];
if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
&& wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
{ {
match_len = char_len; match_len = char_len;
goto check_node_accept_bytes_match; goto check_node_accept_bytes_match;
} }
} }
check_node_accept_bytes_match:
if (!cset->non_match)
return match_len;
else
{
if (match_len > 0)
return 0;
else
return re_string_elem_size_at (input, str_idx);
}
} }
#endif check_node_accept_bytes_match:
if (!cset->non_match)
return match_len;
else
{
if (match_len > 0)
return 0;
else
return (elem_len > char_len) ? elem_len : char_len;
}
} }
return 0; return 0;
} }
#ifdef _LIBC # ifdef _LIBC
static unsigned int static unsigned int
find_collation_sequence_value (mbs, mbs_len) find_collation_sequence_value (mbs, mbs_len)
const unsigned char *mbs; const unsigned char *mbs;
@ -2204,7 +2248,8 @@ find_collation_sequence_value (mbs, mbs_len)
} }
} }
} }
#endif # endif /* _LIBC */
#endif /* RE_ENABLE_I18N */
/* Check whether the node accepts the byte which is IDX-th /* Check whether the node accepts the byte which is IDX-th
byte of the INPUT. */ byte of the INPUT. */

View File

@ -1 +1,205 @@
#include <sysdeps/unix/sysv/linux/i386/semctl.c> /* Semctl for architectures where word sized unions are passed indirectly
Copyright (C) 1995, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <stdarg.h>
#include <sys/sem.h>
#include <ipc_priv.h>
#include <sysdep.h>
#include <string.h>
#include <sys/syscall.h>
#include "kernel-features.h"
#include <shlib-compat.h>
struct __old_semid_ds
{
struct __old_ipc_perm sem_perm; /* operation permission struct */
__time_t sem_otime; /* last semop() time */
__time_t sem_ctime; /* last time changed by semctl() */
struct sem *__sembase; /* ptr to first semaphore in array */
struct sem_queue *__sem_pending; /* pending operations */
struct sem_queue *__sem_pending_last; /* last pending operation */
struct sem_undo *__undo; /* ondo requests on this array */
unsigned short int sem_nsems; /* number of semaphores in set */
};
/* Define a `union semun' suitable for Linux here. */
union semun
{
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
unsigned short int *array; /* array for GETALL & SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
#include <bp-checks.h>
#include <bp-semctl.h> /* definition of CHECK_SEMCTL needs union semum */
#ifdef __NR_getuid32
# if __ASSUME_32BITUIDS == 0
/* This variable is shared with all files that need to check for 32bit
uids. */
extern int __libc_missing_32bit_uids;
# endif
#endif
/* Return identifier for array of NSEMS semaphores associated with
KEY. */
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
int __old_semctl (int semid, int semnum, int cmd, ...);
#endif
int __new_semctl (int semid, int semnum, int cmd, ...);
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
int
__old_semctl (int semid, int semnum, int cmd, ...)
{
union semun arg;
va_list ap;
/* Get the argument only if required. */
arg.buf = NULL;
switch (cmd)
{
case SETVAL: /* arg.val */
case GETALL: /* arg.array */
case SETALL:
case IPC_STAT: /* arg.buf */
case IPC_SET:
case SEM_STAT:
case IPC_INFO: /* arg.__buf */
case SEM_INFO:
va_start (ap, cmd);
arg = va_arg (ap, union semun);
va_end (ap);
break;
}
return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
CHECK_SEMCTL (&arg, semid, cmd));
}
compat_symbol (libc, __old_semctl, semctl, GLIBC_2_0);
#endif
int
__new_semctl (int semid, int semnum, int cmd, ...)
{
union semun arg;
va_list ap;
/* Get the argument only if required. */
arg.buf = NULL;
switch (cmd)
{
case SETVAL: /* arg.val */
case GETALL: /* arg.array */
case SETALL:
case IPC_STAT: /* arg.buf */
case IPC_SET:
case SEM_STAT:
case IPC_INFO: /* arg.__buf */
case SEM_INFO:
va_start (ap, cmd);
arg = va_arg (ap, union semun);
va_end (ap);
break;
}
#if __ASSUME_32BITUIDS > 0
return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
CHECK_SEMCTL (&arg, semid, cmd | __IPC_64));
#else
switch (cmd) {
case SEM_STAT:
case IPC_STAT:
case IPC_SET:
break;
default:
return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
CHECK_SEMCTL (&arg, semid, cmd));
}
{
int result;
struct __old_semid_ds old;
struct semid_ds *buf;
#ifdef __NR_getuid32
if (__libc_missing_32bit_uids <= 0)
{
if (__libc_missing_32bit_uids < 0)
{
int save_errno = errno;
/* Test presence of new IPC by testing for getuid32 syscall. */
result = INLINE_SYSCALL (getuid32, 0);
if (result == -1 && errno == ENOSYS)
__libc_missing_32bit_uids = 1;
else
__libc_missing_32bit_uids = 0;
__set_errno(save_errno);
}
if (__libc_missing_32bit_uids <= 0)
{
result = INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd | __IPC_64,
CHECK_SEMCTL (&arg, semid, cmd | __IPC_64));
return result;
}
}
#endif
buf = arg.buf;
arg.buf = (struct semid_ds *)&old;
if (cmd == IPC_SET)
{
old.sem_perm.uid = buf->sem_perm.uid;
old.sem_perm.gid = buf->sem_perm.gid;
old.sem_perm.mode = buf->sem_perm.mode;
if (old.sem_perm.uid != buf->sem_perm.uid ||
old.sem_perm.gid != buf->sem_perm.gid)
{
__set_errno (EINVAL);
return -1;
}
}
result = INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd,
CHECK_SEMCTL (&arg, semid, cmd));
if (result != -1 && cmd != IPC_SET)
{
memset(buf, 0, sizeof(*buf));
buf->sem_perm.__key = old.sem_perm.__key;
buf->sem_perm.uid = old.sem_perm.uid;
buf->sem_perm.gid = old.sem_perm.gid;
buf->sem_perm.cuid = old.sem_perm.cuid;
buf->sem_perm.cgid = old.sem_perm.cgid;
buf->sem_perm.mode = old.sem_perm.mode;
buf->sem_perm.__seq = old.sem_perm.__seq;
buf->sem_otime = old.sem_otime;
buf->sem_ctime = old.sem_ctime;
buf->sem_nsems = old.sem_nsems;
}
return result;
}
#endif
}
versioned_symbol (libc, __new_semctl, semctl, GLIBC_2_2);