2002-09-30  Isamu Hasegawa  <isamu@yamato.ibm.com>

	* posix/regex_internal.h (re_match_context_t): Add a new member.
	(re_fail_stack_ent_t): New structure.
	(re_fail_stack_t): Likewise.
	* posix/regexec.c (re_search_internal): Use the new member of
	re_match_context_t.
	Use fail stack only if it has back references and there are plural
	matching candidates.
	(proceed_next_node): Use fail stack if it is indicated.
	(set_regs): Likewise.
	(push_fail_stack): New function.
	(pop_fail_stack): New function.
	(check_dst_limits): Likewise.
	(check_dst_limits_calc_pos): Likewise.
	(search_subexp): Check the limitations on the top of subexpressions.
	(sift_states_bkref): Check the limitations of the destination node.
	Reuse the array sctx->sifted_states.

2002-09-30  Ulrich Drepper  <drepper@redhat.com>

	* stdio-common/printf_fp.c: Shuffle a few lines around to help the
	compiler optimizing.  No semantical changes intended.
This commit is contained in:
Ulrich Drepper 2002-09-30 22:01:05 +00:00
parent fdb7f386dd
commit a3022b820f
4 changed files with 358 additions and 68 deletions

View File

@ -1,3 +1,27 @@
2002-09-30 Isamu Hasegawa <isamu@yamato.ibm.com>
* posix/regex_internal.h (re_match_context_t): Add a new member.
(re_fail_stack_ent_t): New structure.
(re_fail_stack_t): Likewise.
* posix/regexec.c (re_search_internal): Use the new member of
re_match_context_t.
Use fail stack only if it has back references and there are plural
matching candidates.
(proceed_next_node): Use fail stack if it is indicated.
(set_regs): Likewise.
(push_fail_stack): New function.
(pop_fail_stack): New function.
(check_dst_limits): Likewise.
(check_dst_limits_calc_pos): Likewise.
(search_subexp): Check the limitations on the top of subexpressions.
(sift_states_bkref): Check the limitations of the destination node.
Reuse the array sctx->sifted_states.
2002-09-30 Ulrich Drepper <drepper@redhat.com>
* stdio-common/printf_fp.c: Shuffle a few lines around to help the
compiler optimizing. No semantical changes intended.
2002-09-30 Jakub Jelinek <jakub@redhat.com>
* sysdeps/ia64/strncpy.S: Only segfault in .recovery2 if some bits

View File

@ -419,6 +419,7 @@ typedef struct
int eflags;
/* Where the matching ends. */
int match_last;
int last_node;
/* The string object corresponding to the input string. */
re_string_t *input;
/* The state log used by the matcher. */
@ -446,6 +447,21 @@ typedef struct
int check_subexp;
} re_sift_context_t;
struct re_fail_stack_ent_t
{
int idx;
int node;
regmatch_t *regs;
re_node_set eps_via_nodes;
};
struct re_fail_stack_t
{
int num;
int alloc;
struct re_fail_stack_ent_t *stack;
};
struct re_dfa_t
{
re_bitset_ptr_t word_char;

View File

@ -81,12 +81,20 @@ static int check_halt_state_context (const regex_t *preg,
const re_match_context_t *mctx, int idx);
static void update_regs (re_dfa_t *dfa, regmatch_t *pmatch, int cur_node,
int cur_idx, int nmatch);
static int proceed_next_node (const regex_t *preg, regmatch_t *regs,
static int proceed_next_node (const regex_t *preg, int nregs, regmatch_t *regs,
const re_match_context_t *mctx,
int *pidx, int node, re_node_set *eps_via_nodes);
int *pidx, int node, re_node_set *eps_via_nodes,
struct re_fail_stack_t *fs);
static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
int str_idx, int *dests, int nregs,
regmatch_t *regs,
re_node_set *eps_via_nodes);
static int pop_fail_stack (struct re_fail_stack_t *fs, int *pidx, int nregs,
regmatch_t *regs, re_node_set *eps_via_nodes);
static reg_errcode_t set_regs (const regex_t *preg,
const re_match_context_t *mctx,
size_t nmatch, regmatch_t *pmatch, int last);
size_t nmatch, regmatch_t *pmatch,
int fl_backtrack);
#ifdef RE_ENABLE_I18N
static int sift_states_iter_mb (const regex_t *preg,
const re_match_context_t *mctx,
@ -107,6 +115,12 @@ static reg_errcode_t add_epsilon_src_nodes (re_dfa_t *dfa,
static reg_errcode_t sub_epsilon_src_nodes (re_dfa_t *dfa, int node,
re_node_set *dest_nodes,
const re_node_set *and_nodes);
static int check_dst_limits (re_dfa_t *dfa, re_node_set *limits,
re_match_context_t *mctx, int dst_node,
int dst_idx, int src_node, int src_idx);
static int check_dst_limits_calc_pos (re_dfa_t *dfa, re_match_context_t *mctx,
int limit, re_node_set *eclosures,
int subexp_idx, int node, int str_idx);
static reg_errcode_t check_subexp_limits (re_dfa_t *dfa,
re_node_set *dest_nodes,
const re_node_set *candidates,
@ -729,7 +743,9 @@ re_search_internal (preg, string, length, start, range, stop, nmatch, pmatch,
re_free (mctx.state_log);
mctx.state_log = sifted_states;
}
err = set_regs (preg, &mctx, nmatch, pmatch, halt_node);
mctx.last_node = halt_node;
err = set_regs (preg, &mctx, nmatch, pmatch,
dfa->has_plural_match && dfa->nbackref > 0);
if (BE (err != REG_NOERROR, 0))
return err;
}
@ -981,12 +997,13 @@ check_halt_state_context (preg, state, mctx, idx)
of errors. */
static int
proceed_next_node (preg, regs, mctx, pidx, node, eps_via_nodes)
proceed_next_node (preg, nregs, regs, mctx, pidx, node, eps_via_nodes, fs)
const regex_t *preg;
regmatch_t *regs;
const re_match_context_t *mctx;
int *pidx, node;
int nregs, *pidx, node;
re_node_set *eps_via_nodes;
struct re_fail_stack_t *fs;
{
re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
int i, err, dest_node, cur_entity;
@ -995,37 +1012,39 @@ proceed_next_node (preg, regs, mctx, pidx, node, eps_via_nodes)
? dfa->nodes[node].opr.ctx_info->entity : node);
if (IS_EPSILON_NODE (dfa->nodes[node].type))
{
int dest_entity = INT_MAX;
int ndest, dest_nodes[2], dest_entities[2];
err = re_node_set_insert (eps_via_nodes, node);
if (BE (err < 0, 0))
return -1;
for (i = 0; i < mctx->state_log[*pidx]->nodes.nelem; ++i)
/* Pick up valid destinations. */
for (ndest = 0, i = 0; i < mctx->state_log[*pidx]->nodes.nelem; ++i)
{
int candidate, candidate_entity;
candidate = mctx->state_log[*pidx]->nodes.elems[i];
candidate_entity = ((dfa->nodes[candidate].type == OP_CONTEXT_NODE)
? dfa->nodes[candidate].opr.ctx_info->entity
: candidate);
if (!re_node_set_contains (dfa->edests + node, candidate))
if (candidate == candidate_entity
|| !re_node_set_contains (dfa->edests + node, candidate_entity))
continue;
/* In order to avoid infinite loop like "(a*)*". */
if (cur_entity > candidate_entity
&& re_node_set_contains (eps_via_nodes, candidate))
int candidate = mctx->state_log[*pidx]->nodes.elems[i];
int entity;
entity = ((dfa->nodes[candidate].type == OP_CONTEXT_NODE)
? dfa->nodes[candidate].opr.ctx_info->entity : candidate);
if (!re_node_set_contains (dfa->edests + node, entity))
continue;
if (dest_entity > candidate_entity)
{
dest_node = candidate;
dest_entity = candidate_entity;
}
dest_nodes[0] = (ndest == 0) ? candidate : dest_nodes[0];
dest_entities[0] = (ndest == 0) ? entity : dest_entities[0];
dest_nodes[1] = (ndest == 1) ? candidate : dest_nodes[1];
dest_entities[1] = (ndest == 1) ? entity : dest_entities[1];
++ndest;
}
#ifdef DEBUG
assert (dest_node != -1);
#endif
return dest_node;
if (ndest <= 1)
return ndest == 0 ? -1 : (ndest == 1 ? dest_nodes[0] : 0);
if (dest_entities[0] > dest_entities[1])
{
int swap_work = dest_nodes[0];
dest_nodes[0] = dest_nodes[1];
dest_nodes[1] = swap_work;
}
/* In order to avoid infinite loop like "(a*)*". */
if (re_node_set_contains (eps_via_nodes, dest_nodes[0]))
return dest_nodes[1];
if (fs != NULL)
push_fail_stack (fs, *pidx, dest_nodes, nregs, regs, eps_via_nodes);
return dest_nodes[0];
}
else
{
@ -1046,12 +1065,24 @@ proceed_next_node (preg, regs, mctx, pidx, node, eps_via_nodes)
{
int subexp_idx = dfa->nodes[entity].opr.idx;
naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
if (fs != NULL)
{
if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
return -1;
else if (naccepted)
{
char *buf = re_string_get_buffer (mctx->input);
if (strncmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
naccepted) != 0)
return -1;
}
}
if (naccepted == 0)
{
err = re_node_set_insert (eps_via_nodes, node);
if (BE (err < 0, 0))
return -1;
return -2;
dest_node = dfa->nexts[node];
if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
dest_node))
@ -1072,18 +1103,56 @@ proceed_next_node (preg, regs, mctx, pidx, node, eps_via_nodes)
{
dest_node = dfa->nexts[node];
*pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
#ifdef DEBUG
assert (mctx->state_log[*pidx] != NULL);
#endif
if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
|| !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
dest_node)))
return -1;
re_node_set_empty (eps_via_nodes);
return dest_node;
}
}
/* Must not reach here. */
#ifdef DEBUG
assert (0);
#endif
return 0;
return -1;
}
static reg_errcode_t
push_fail_stack (fs, str_idx, dests, nregs, regs, eps_via_nodes)
struct re_fail_stack_t *fs;
int str_idx, *dests, nregs;
regmatch_t *regs;
re_node_set *eps_via_nodes;
{
reg_errcode_t err;
int num = fs->num++;
if (fs->num == fs->alloc)
{
fs->alloc *= 2;
fs->stack = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
* fs->alloc));
if (fs->stack == NULL)
return REG_ESPACE;
}
fs->stack[num].idx = str_idx;
fs->stack[num].node = dests[1];
fs->stack[num].regs = re_malloc (regmatch_t, nregs);
memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
return err;
}
static int
pop_fail_stack (fs, pidx, nregs, regs, eps_via_nodes)
struct re_fail_stack_t *fs;
int *pidx, nregs;
regmatch_t *regs;
re_node_set *eps_via_nodes;
{
int num = --fs->num;
assert (num >= 0);
*pidx = fs->stack[num].idx;
memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
re_node_set_free (eps_via_nodes);
*eps_via_nodes = fs->stack[num].eps_via_nodes;
return fs->stack[num].node;
}
/* Set the positions where the subexpressions are starts/ends to registers
@ -1092,34 +1161,66 @@ proceed_next_node (preg, regs, mctx, pidx, node, eps_via_nodes)
pmatch[i].rm_so == pmatch[i].rm_eo == -1 (i > 1). */
static reg_errcode_t
set_regs (preg, mctx, nmatch, pmatch, last_node)
const regex_t *preg;
const re_match_context_t *mctx;
size_t nmatch;
regmatch_t *pmatch;
int last_node;
set_regs (preg, mctx, nmatch, pmatch, fl_backtrack)
const regex_t *preg;
const re_match_context_t *mctx;
size_t nmatch;
regmatch_t *pmatch;
int fl_backtrack;
{
re_dfa_t *dfa = (re_dfa_t *)preg->buffer;
int idx, cur_node, real_nmatch;
re_node_set eps_via_nodes;
struct re_fail_stack_t *fs;
struct re_fail_stack_t fs_body = {0, 2, NULL};
#ifdef DEBUG
assert (nmatch > 1);
assert (mctx->state_log != NULL);
#endif
if (fl_backtrack)
{
fs = &fs_body;
fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
}
else
fs = NULL;
cur_node = dfa->init_node;
real_nmatch = (nmatch <= preg->re_nsub) ? nmatch : preg->re_nsub + 1;
re_node_set_init_empty (&eps_via_nodes);
for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
{
update_regs (dfa, pmatch, cur_node, idx, real_nmatch);
if (idx == pmatch[0].rm_eo && cur_node == last_node)
break;
if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
{
int reg_idx;
if (fs)
{
for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
break;
if (reg_idx == nmatch)
return REG_NOERROR;
cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
&eps_via_nodes);
}
else
return REG_NOERROR;
}
/* Proceed to next node. */
cur_node = proceed_next_node (preg, pmatch, mctx, &idx, cur_node,
&eps_via_nodes);
cur_node = proceed_next_node (preg, nmatch, pmatch, mctx, &idx, cur_node,
&eps_via_nodes, fs);
if (BE (cur_node < 0, 0))
return REG_ESPACE;
{
if (cur_node == -2)
return REG_ESPACE;
if (fs)
cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
&eps_via_nodes);
else
return REG_NOMATCH;
}
}
re_node_set_free (&eps_via_nodes);
return REG_NOERROR;
@ -1258,6 +1359,14 @@ sift_states_backward (preg, mctx, sctx)
if (naccepted == 0)
continue;
if (sctx->limits.nelem)
{
int to_idx = str_idx + naccepted;
if (check_dst_limits (dfa, &sctx->limits, mctx,
dfa->nexts[prev_node], to_idx,
prev_node, str_idx))
continue;
}
ret = re_node_set_insert (&cur_dest, prev_node);
if (BE (ret == -1, 0))
return err;
@ -1458,6 +1567,105 @@ sub_epsilon_src_nodes (dfa, node, dest_nodes, candidates)
return REG_NOERROR;
}
static int
check_dst_limits (dfa, limits, mctx, dst_node, dst_idx, src_node, src_idx)
re_dfa_t *dfa;
re_node_set *limits;
re_match_context_t *mctx;
int dst_node, dst_idx, src_node, src_idx;
{
int lim_idx, src_pos, dst_pos;
for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
{
int bkref, subexp_idx/*, node_idx, cls_node*/;
struct re_backref_cache_entry *ent;
ent = mctx->bkref_ents + limits->elems[lim_idx];
bkref = (dfa->nodes[ent->node].type == OP_CONTEXT_NODE
? dfa->nodes[ent->node].opr.ctx_info->entity : ent->node);
subexp_idx = dfa->nodes[bkref].opr.idx - 1;
dst_pos = check_dst_limits_calc_pos (dfa, mctx, limits->elems[lim_idx],
dfa->eclosures + dst_node,
subexp_idx, dst_node, dst_idx);
src_pos = check_dst_limits_calc_pos (dfa, mctx, limits->elems[lim_idx],
dfa->eclosures + src_node,
subexp_idx, src_node, src_idx);
/* In case of:
<src> <dst> ( <subexp> )
( <subexp> ) <src> <dst>
( <subexp1> <src> <subexp2> <dst> <subexp3> ) */
if (src_pos == dst_pos)
continue; /* This is unrelated limitation. */
else
return 1;
}
return 0;
}
static int
check_dst_limits_calc_pos (dfa, mctx, limit, eclosures, subexp_idx, node,
str_idx)
re_dfa_t *dfa;
re_match_context_t *mctx;
re_node_set *eclosures;
int limit, subexp_idx, node, str_idx;
{
struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
int pos = (str_idx < lim->subexp_from ? -1
: (lim->subexp_to < str_idx ? 1 : 0));
if (pos == 0
&& (str_idx == lim->subexp_from || str_idx == lim->subexp_to))
{
int node_idx;
for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
{
int node = eclosures->elems[node_idx];
int entity = node;
re_token_type_t type= dfa->nodes[node].type;
if (type == OP_CONTEXT_NODE)
{
entity = dfa->nodes[node].opr.ctx_info->entity;
type = dfa->nodes[entity].type;
}
if (type == OP_BACK_REF)
{
int bi;
for (bi = 0; bi < mctx->nbkref_ents; ++bi)
{
struct re_backref_cache_entry *ent = mctx->bkref_ents + bi;
if (ent->node == node && ent->subexp_from == ent->subexp_to
&& ent->str_idx == str_idx)
{
int cpos, dst;
dst = dfa->nexts[node];
cpos = check_dst_limits_calc_pos (dfa, mctx, limit,
dfa->eclosures + dst,
subexp_idx, dst,
str_idx);
if ((str_idx == lim->subexp_from && cpos == -1)
|| (str_idx == lim->subexp_to && cpos == 0))
return cpos;
}
}
}
if (type == OP_OPEN_SUBEXP && subexp_idx == dfa->nodes[node].opr.idx
&& str_idx == lim->subexp_from)
{
pos = -1;
break;
}
if (type == OP_CLOSE_SUBEXP && subexp_idx == dfa->nodes[node].opr.idx
&& str_idx == lim->subexp_to)
break;
}
if (node_idx == eclosures->nelem && str_idx == lim->subexp_to)
pos = 1;
}
return pos;
}
/* Check the limitations of sub expressions LIMITS, and remove the nodes
which are against limitations from DEST_NODES. */
@ -1572,6 +1780,7 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
re_sift_context_t local_sctx;
int node_idx, node;
const re_node_set *candidates;
re_dfastate_t **lim_states = NULL;
candidates = ((mctx->state_log[str_idx] == NULL) ? &empty_set
: &mctx->state_log[str_idx]->nodes);
local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */
@ -1589,6 +1798,7 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
if (type == OP_CLOSE_SUBEXP
&& sctx->check_subexp == dfa->nodes[node].opr.idx + 1)
{
re_dfastate_t *cur_state;
/* Found the bottom of the subexpression, then search for the
top of it. */
if (local_sctx.sifted_states == NULL)
@ -1600,9 +1810,12 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
return err;
}
local_sctx.check_subexp = -sctx->check_subexp;
local_sctx.limited_states = sctx->limited_states;
local_sctx.last_node = node;
local_sctx.last_str_idx = local_sctx.cls_subexp_idx = str_idx;
cur_state = local_sctx.sifted_states[str_idx];
err = sift_states_backward (preg, mctx, &local_sctx);
local_sctx.sifted_states[str_idx] = cur_state;
if (BE (err != REG_NOERROR, 0))
return err;
/* There must not 2 same node in a node set. */
@ -1631,6 +1844,42 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
buf = (char *) re_string_get_buffer (mctx->input);
if (strncmp (buf + str_idx, buf + bkref_str_idx, subexp_len) != 0)
break;
if (sctx->limits.nelem && str_idx > 0)
{
re_dfastate_t *cur_state = sctx->sifted_states[str_idx];
if (lim_states == NULL)
{
lim_states = re_malloc (re_dfastate_t *, str_idx + 1);
}
if (local_sctx.sifted_states == NULL)
{
/* It hasn't been initialized yet, initialize it now. */
local_sctx = *sctx;
if (BE (lim_states == NULL, 0))
return REG_ESPACE;
err = re_node_set_init_copy (&local_sctx.limits,
&sctx->limits);
if (BE (err != REG_NOERROR, 0))
return err;
}
local_sctx.check_subexp = 0;
local_sctx.last_node = node;
local_sctx.last_str_idx = str_idx;
local_sctx.limited_states = lim_states;
memset (lim_states, '\0',
sizeof (re_dfastate_t*) * (str_idx + 1));
err = sift_states_backward (preg, mctx, &local_sctx);
if (BE (err != REG_NOERROR, 0))
return err;
if (local_sctx.sifted_states[0] == NULL
&& local_sctx.limited_states[0] == NULL)
{
sctx->sifted_states[str_idx] = cur_state;
break;
}
sctx->sifted_states[str_idx] = cur_state;
}
/* Successfully matched, add a new cache entry. */
dest_str_idx = bkref_str_idx + subexp_len;
err = match_ctx_add_entry (mctx, sctx->cur_bkref, bkref_str_idx,
@ -1658,6 +1907,8 @@ search_subexp (preg, mctx, sctx, str_idx, dest_nodes)
if (local_sctx.sifted_states != NULL)
re_node_set_free (&local_sctx.limits);
if (lim_states != NULL)
re_free (lim_states);
return REG_NOERROR;
}
@ -1725,6 +1976,9 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
continue;
}
if (check_dst_limits (dfa, &sctx->limits, mctx, node,
str_idx, dfa->nexts[node], to_idx))
continue;
if (sctx->check_subexp == dfa->nodes[entity].opr.idx)
{
char *buf;
@ -1744,12 +1998,13 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
}
else
{
re_dfastate_t *cur_state;
entry->flag = 0;
for (disabled_idx = enabled_idx + 1;
disabled_idx < mctx->nbkref_ents; ++disabled_idx)
{
struct re_backref_cache_entry *entry2;
entry2 = mctx->bkref_ents + enabled_idx;
entry2 = mctx->bkref_ents + disabled_idx;
if (entry2->node != node || entry2->str_idx != str_idx)
continue;
entry2->flag = 1;
@ -1758,10 +2013,6 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
if (local_sctx.sifted_states == NULL)
{
local_sctx = *sctx;
local_sctx.sifted_states = re_malloc (re_dfastate_t *,
str_idx + 1);
if (BE (local_sctx.sifted_states == NULL, 0))
return REG_ESPACE;
err = re_node_set_init_copy (&local_sctx.limits,
&sctx->limits);
if (BE (err != REG_NOERROR, 0))
@ -1772,6 +2023,7 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
err = re_node_set_insert (&local_sctx.limits, enabled_idx);
if (BE (err < 0, 0))
return REG_ESPACE;
cur_state = local_sctx.sifted_states[str_idx];
err = sift_states_backward (preg, mctx, &local_sctx);
if (BE (err != REG_NOERROR, 0))
return err;
@ -1783,6 +2035,7 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
if (BE (err != REG_NOERROR, 0))
return err;
}
local_sctx.sifted_states[str_idx] = cur_state;
re_node_set_remove_at (&local_sctx.limits,
local_sctx.limits.nelem - 1);
entry->flag = 1;
@ -1799,7 +2052,6 @@ sift_states_bkref (preg, mctx, sctx, str_idx, dest_nodes)
}
if (local_sctx.sifted_states != NULL)
{
free (local_sctx.sifted_states);
re_node_set_free (&local_sctx.limits);
}

View File

@ -212,8 +212,7 @@ __printf_fp (FILE *fp,
else if (scalesize == 0)
{
hi = frac[fracsize - 1];
cy = __mpn_mul_1 (frac, frac, fracsize - 1, 10);
frac[fracsize - 1] = cy;
frac[fracsize - 1] = __mpn_mul_1 (frac, frac, fracsize - 1, 10);
}
else
{
@ -237,9 +236,9 @@ __printf_fp (FILE *fp,
}
}
cy = __mpn_mul_1 (frac, frac, fracsize, 10);
if (cy != 0)
frac[fracsize++] = cy;
mp_limb_t _cy = __mpn_mul_1 (frac, frac, fracsize, 10);
if (_cy != 0)
frac[fracsize++] = _cy;
}
return L'0' + hi;
@ -364,6 +363,7 @@ __printf_fp (FILE *fp,
/* Check for special values: not a number or infinity. */
if (__isnan (fpnum.dbl))
{
is_neg = 0;
if (isupper (info->spec))
{
special = "NAN";
@ -374,10 +374,10 @@ __printf_fp (FILE *fp,
special = "nan";
wspecial = L"nan";
}
is_neg = 0;
}
else if (__isinf (fpnum.dbl))
{
is_neg = fpnum.dbl < 0;
if (isupper (info->spec))
{
special = "INF";
@ -388,7 +388,6 @@ __printf_fp (FILE *fp,
special = "inf";
wspecial = L"inf";
}
is_neg = fpnum.dbl < 0;
}
else
{
@ -814,6 +813,8 @@ __printf_fp (FILE *fp,
{
type = 'f';
fracdig_min = fracdig_max = info->prec < 0 ? 6 : info->prec;
dig_max = INT_MAX; /* Unlimited. */
significant = 1; /* Does not matter here. */
if (expsign == 0)
{
intdig_max = exponent + 1;
@ -825,8 +826,6 @@ __printf_fp (FILE *fp,
intdig_max = 1;
chars_needed = 1 + 1 + fracdig_max;
}
dig_max = INT_MAX; /* Unlimited. */
significant = 1; /* Does not matter here. */
}
else
{
@ -912,7 +911,7 @@ __printf_fp (FILE *fp,
{
++fracdig_no;
*wcp = hack_digit ();
if (*wcp != L'0')
if (*wcp++ != L'0')
significant = 1;
else if (significant == 0)
{
@ -920,7 +919,6 @@ __printf_fp (FILE *fp,
if (fracdig_min > 0)
++fracdig_min;
}
++wcp;
}
/* Do rounding. */