2004-01-01 Paolo Bonzini * posix/regcomp.c (init_dfa): initialize the word_char bitset. * posix/regex_internal.c (re_string_reconstruct, re_string_context_at): receive a REGEX_T instead of the NEWLINE_ANCHOR flag. Also use the word_char bitset. All callers adjusted. * posix/regex_internal.h: Adjust prototypes. * posix/regexec.c: Adjust callers to the above functions. (build_trtable): Use word_char bitset. diff -rup save/regcomp.c ./regcomp.c --- save/regcomp.c 2004-01-01 12:53:10.000000000 +0100 +++ ./regcomp.c 2004-01-01 12:57:33.000000000 +0100 @@ -1,5 +1,5 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . @@ -818,6 +818,7 @@ init_dfa (dfa, pat_len) int pat_len; { int table_size; + int i, j, ch; memset (dfa, '\0', sizeof (re_dfa_t)); @@ -852,8 +853,6 @@ init_dfa (dfa, pat_len) #ifdef RE_ENABLE_I18N if (dfa->mb_cur_max > 1) { - int i, j, ch; - dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1); if (BE (dfa->sb_char == NULL, 0)) return REG_ESPACE; @@ -869,6 +868,12 @@ init_dfa (dfa, pat_len) } #endif + dfa->word_char = (re_bitset_ptr_t) calloc (sizeof (bitset), 1); + for (i = 0, ch = 0; i < BITSET_UINTS; ++i) + for (j = 0; j < UINT_BITS; ++j, ++ch) + if (IS_WORD_CHAR (ch)) + dfa->word_char[i] |= 1 << j; + if (BE (dfa->nodes == NULL || dfa->state_table == NULL || dfa->subexps == NULL, 0)) return REG_ESPACE; diff -rup save/regex_internal.c ./regex_internal.c --- save/regex_internal.c 2004-01-01 12:53:10.000000000 +0100 +++ ./regex_internal.c 2004-01-01 13:05:38.000000000 +0100 @@ -572,9 +572,10 @@ re_string_translate_buffer (pstr) convert to upper case in case of REG_ICASE, apply translation. */ static reg_errcode_t -re_string_reconstruct (pstr, idx, eflags, newline) +re_string_reconstruct (pstr, idx, eflags, preg) re_string_t *pstr; - int idx, eflags, newline; + int idx, eflags; + const regex_t *preg; { int offset = idx - pstr->raw_mbs_idx; if (offset < 0) @@ -610,7 +611,7 @@ re_string_reconstruct (pstr, idx, eflags { /* Yes, move them to the front of the buffer. */ pstr->tip_context = re_string_context_at (pstr, offset - 1, eflags, - newline); + preg); #ifdef RE_ENABLE_I18N if (pstr->mb_cur_max > 1) memmove (pstr->wcs, pstr->wcs + offset, @@ -696,8 +697,8 @@ re_string_reconstruct (pstr, idx, eflags } pstr->valid_raw_len = pstr->valid_len; pstr->tip_context = (IS_WIDE_WORD_CHAR (wc) ? CONTEXT_WORD - : ((newline && IS_WIDE_NEWLINE (wc)) - ? CONTEXT_NEWLINE : 0)); + : ((IS_WIDE_NEWLINE (wc) && preg->newline_anchor) + ? CONTEXT_NEWLINE : 0)); } else #endif /* RE_ENABLE_I18N */ @@ -706,8 +707,8 @@ re_string_reconstruct (pstr, idx, eflags if (pstr->trans) c = pstr->trans[c]; pstr->tip_context = (IS_WORD_CHAR (c) ? CONTEXT_WORD - : ((newline && IS_NEWLINE (c)) - ? CONTEXT_NEWLINE : 0)); + : ((IS_NEWLINE (c) && preg->newline_anchor) + ? CONTEXT_NEWLINE : 0)); } } if (!pstr->mbs_allocated) @@ -843,11 +844,14 @@ re_string_destruct (pstr) /* Return the context at IDX in INPUT. */ static unsigned int -re_string_context_at (input, idx, eflags, newline_anchor) +re_string_context_at (input, idx, eflags, preg) const re_string_t *input; - int idx, eflags, newline_anchor; + int idx, eflags; + const regex_t *preg; { int c; + re_dfa_t *dfa = (re_dfa_t *)preg->buffer; + if (idx < 0 || idx == input->len) { if (idx < 0) @@ -876,15 +880,15 @@ re_string_context_at (input, idx, eflags wc = input->wcs[wc_idx]; if (IS_WIDE_WORD_CHAR (wc)) return CONTEXT_WORD; - return (newline_anchor && IS_WIDE_NEWLINE (wc)) ? CONTEXT_NEWLINE : 0; + return (IS_WIDE_NEWLINE (wc) && preg->newline_anchor) ? CONTEXT_NEWLINE : 0; } else #endif { c = re_string_byte_at (input, idx); - if (IS_WORD_CHAR (c)) + if (bitset_contain (dfa->word_char, c)) return CONTEXT_WORD; - return (newline_anchor && IS_NEWLINE (c)) ? CONTEXT_NEWLINE : 0; + return (IS_NEWLINE (c) && preg->newline_anchor) ? CONTEXT_NEWLINE : 0; } } diff -rup save/regex_internal.h ./regex_internal.h --- save/regex_internal.h 2004-01-01 12:53:10.000000000 +0100 +++ ./regex_internal.h 2004-01-01 13:05:27.000000000 +0100 @@ -368,7 +368,7 @@ static reg_errcode_t re_string_construct int len, RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa) internal_function; static reg_errcode_t re_string_reconstruct (re_string_t *pstr, int idx, - int eflags, int newline) internal_function; + int eflags, const regex_t *preg) internal_function; static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, int new_buf_len) internal_function; # ifdef RE_ENABLE_I18N @@ -384,7 +384,7 @@ static inline int re_string_char_size_at static inline wint_t re_string_wchar_at (const re_string_t *pstr, int idx) internal_function; # endif /* RE_ENABLE_I18N */ static unsigned int re_string_context_at (const re_string_t *input, int idx, - int eflags, int newline_anchor) internal_function; + int eflags, const regex_t *preg) internal_function; static unsigned char re_string_peek_byte_case (const re_string_t *pstr, int idx) internal_function; static unsigned char re_string_fetch_byte_case (re_string_t *pstr) internal_function; diff -rup save/regexec.c ./regexec.c --- save/regexec.c 2004-01-01 12:53:10.000000000 +0100 +++ ./regexec.c 2004-01-01 13:00:39.000000000 +0100 @@ -1,5 +1,5 @@ /* Extended regular expression matching and search library. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Isamu Hasegawa . @@ -721,7 +721,7 @@ re_search_internal (preg, string, length || match_first < input.raw_mbs_idx) { err = re_string_reconstruct (&input, match_first, eflags, - preg->newline_anchor); + preg); if (BE (err != REG_NOERROR, 0)) goto free_return; } @@ -743,7 +743,7 @@ re_search_internal (preg, string, length /* Reconstruct the buffers so that the matcher can assume that the matching starts from the beginning of the buffer. */ err = re_string_reconstruct (&input, match_first, eflags, - preg->newline_anchor); + preg); if (BE (err != REG_NOERROR, 0)) goto free_return; #ifdef RE_ENABLE_I18N @@ -952,7 +952,7 @@ acquire_init_state_context (err, preg, m { unsigned int context; context = re_string_context_at (mctx->input, idx - 1, mctx->eflags, - preg->newline_anchor); + preg); if (IS_WORD_CONTEXT (context)) return dfa->init_state_word; else if (IS_ORDINARY_CONTEXT (context)) @@ -1116,7 +1116,7 @@ check_halt_state_context (preg, state, m assert (state->halt); #endif context = re_string_context_at (mctx->input, idx, mctx->eflags, - preg->newline_anchor); + preg); for (i = 0; i < state->nodes.nelem; ++i) if (check_halt_node_context (dfa, state->nodes.elems[i], context)) return state->nodes.elems[i]; @@ -2179,7 +2179,7 @@ transit_state (err, preg, mctx, state) context = re_string_context_at (mctx->input, re_string_cur_idx (mctx->input) - 1, - mctx->eflags, preg->newline_anchor); + mctx->eflags, preg); if (IS_WORD_CONTEXT (context)) next_state = trtable[ch + SBC_MAX]; else @@ -2238,7 +2238,7 @@ transit_state (err, preg, mctx, state) context = re_string_context_at (mctx->input, re_string_cur_idx (mctx->input) - 1, - mctx->eflags, preg->newline_anchor); + mctx->eflags, preg); next_state = mctx->state_log[cur_idx] = re_acquire_state_context (err, dfa, &next_nodes, context); /* We don't need to check errors here, since the return value of @@ -2343,7 +2343,7 @@ transit_state_sb (err, preg, state, mctx } } context = re_string_context_at (mctx->input, cur_str_idx, mctx->eflags, - preg->newline_anchor); + preg); next_state = 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. */ @@ -2377,7 +2377,7 @@ transit_state_mb (preg, pstate, mctx) { context = re_string_context_at (mctx->input, re_string_cur_idx (mctx->input), - mctx->eflags, preg->newline_anchor); + mctx->eflags, preg); if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint, context)) continue; @@ -2415,7 +2415,7 @@ transit_state_mb (preg, pstate, mctx) return err; } context = re_string_context_at (mctx->input, dest_idx - 1, mctx->eflags, - preg->newline_anchor); + preg); mctx->state_log[dest_idx] = re_acquire_state_context (&err, dfa, &dest_nodes, context); if (dest_state != NULL) @@ -2453,7 +2453,7 @@ transit_state_bkref (preg, nodes, mctx) if (node->constraint) { context = re_string_context_at (mctx->input, cur_str_idx, - mctx->eflags, preg->newline_anchor); + mctx->eflags, preg); if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) continue; } @@ -2485,7 +2485,7 @@ transit_state_bkref (preg, nodes, mctx) dest_str_idx = (cur_str_idx + bkref_ent->subexp_to - bkref_ent->subexp_from); context = re_string_context_at (mctx->input, dest_str_idx - 1, - mctx->eflags, preg->newline_anchor); + mctx->eflags, preg); dest_state = mctx->state_log[dest_str_idx]; prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0 : mctx->state_log[cur_str_idx]->nodes.nelem); @@ -2759,7 +2759,7 @@ check_arrival (preg, mctx, path, top_nod /* Setup initial node set. */ context = re_string_context_at (mctx->input, str_idx - 1, mctx->eflags, - preg->newline_anchor); + preg); if (str_idx == top_str) { err = re_node_set_init_1 (&next_nodes, top_node); @@ -2846,7 +2846,7 @@ check_arrival (preg, mctx, path, top_nod } } context = re_string_context_at (mctx->input, str_idx - 1, mctx->eflags, - preg->newline_anchor); + preg); cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); if (BE (cur_state == NULL && err != REG_NOERROR, 0)) { @@ -3314,7 +3314,7 @@ out_free: ; /* j-th destination accepts the word character ch. */ - if (IS_WORD_CHAR (ch)) + if (dfa->word_char[i] & mask) trtable[ch] = dest_states_word[j]; else trtable[ch] = dest_states[j]; @@ -3891,7 +3891,7 @@ check_node_accept (preg, node, mctx, idx satisfies the constraints. */ unsigned int context = re_string_context_at (mctx->input, idx, mctx->eflags, - preg->newline_anchor); + preg); if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) return 0; }