mirror of
https://github.com/vim/vim.git
synced 2025-07-04 23:07:33 -04:00
updated for version 7.3.1105
Problem: New regexp engine: too much code in one function. Dead code. Solution: Move the recursive nfa_regmatch call to a separate function. Remove the dead code.
This commit is contained in:
parent
f18fb7af75
commit
f46da70603
324
src/regexp_nfa.c
324
src/regexp_nfa.c
@ -3665,8 +3665,137 @@ nfa_re_num_cmp(val, op, pos)
|
|||||||
return val == pos;
|
return val == pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int recursive_regmatch __ARGS((nfa_state_T *state, nfa_regprog_T *prog, regsubs_T *submatch, regsubs_T *m, int **listids));
|
||||||
static int nfa_regmatch __ARGS((nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *submatch, regsubs_T *m));
|
static int nfa_regmatch __ARGS((nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *submatch, regsubs_T *m));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recursively call nfa_regmatch()
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
recursive_regmatch(state, prog, submatch, m, listids)
|
||||||
|
nfa_state_T *state;
|
||||||
|
nfa_regprog_T *prog;
|
||||||
|
regsubs_T *submatch;
|
||||||
|
regsubs_T *m;
|
||||||
|
int **listids;
|
||||||
|
{
|
||||||
|
char_u *save_reginput = reginput;
|
||||||
|
char_u *save_regline = regline;
|
||||||
|
int save_reglnum = reglnum;
|
||||||
|
int save_nfa_match = nfa_match;
|
||||||
|
save_se_T *save_nfa_endp = nfa_endp;
|
||||||
|
save_se_T endpos;
|
||||||
|
save_se_T *endposp = NULL;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (state->c == NFA_START_INVISIBLE_BEFORE)
|
||||||
|
{
|
||||||
|
/* The recursive match must end at the current position. */
|
||||||
|
endposp = &endpos;
|
||||||
|
if (REG_MULTI)
|
||||||
|
{
|
||||||
|
endpos.se_u.pos.col = (int)(reginput - regline);
|
||||||
|
endpos.se_u.pos.lnum = reglnum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
endpos.se_u.ptr = reginput;
|
||||||
|
|
||||||
|
/* Go back the specified number of bytes, or as far as the
|
||||||
|
* start of the previous line, to try matching "\@<=" or
|
||||||
|
* not matching "\@<!".
|
||||||
|
* TODO: This is very inefficient! Would be better to
|
||||||
|
* first check for a match with what follows. */
|
||||||
|
if (state->val <= 0)
|
||||||
|
{
|
||||||
|
if (REG_MULTI)
|
||||||
|
{
|
||||||
|
regline = reg_getline(--reglnum);
|
||||||
|
if (regline == NULL)
|
||||||
|
/* can't go before the first line */
|
||||||
|
regline = reg_getline(++reglnum);
|
||||||
|
}
|
||||||
|
reginput = regline;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (REG_MULTI && (int)(reginput - regline) < state->val)
|
||||||
|
{
|
||||||
|
/* Not enough bytes in this line, go to end of
|
||||||
|
* previous line. */
|
||||||
|
regline = reg_getline(--reglnum);
|
||||||
|
if (regline == NULL)
|
||||||
|
{
|
||||||
|
/* can't go before the first line */
|
||||||
|
regline = reg_getline(++reglnum);
|
||||||
|
reginput = regline;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
reginput = regline + STRLEN(regline);
|
||||||
|
}
|
||||||
|
if ((int)(reginput - regline) >= state->val)
|
||||||
|
{
|
||||||
|
reginput -= state->val;
|
||||||
|
#ifdef FEAT_MBYTE
|
||||||
|
if (has_mbyte)
|
||||||
|
reginput -= mb_head_off(regline, reginput);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
reginput = regline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call nfa_regmatch() to check if the current concat matches
|
||||||
|
* at this position. The concat ends with the node
|
||||||
|
* NFA_END_INVISIBLE */
|
||||||
|
if (*listids == NULL)
|
||||||
|
{
|
||||||
|
*listids = (int *)lalloc(sizeof(int) * nstate, TRUE);
|
||||||
|
if (*listids == NULL)
|
||||||
|
{
|
||||||
|
EMSG(_("E878: (NFA) Could not allocate memory for branch traversal!"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef ENABLE_LOG
|
||||||
|
if (log_fd != stderr)
|
||||||
|
fclose(log_fd);
|
||||||
|
log_fd = NULL;
|
||||||
|
#endif
|
||||||
|
/* Have to clear the listid field of the NFA nodes, so that
|
||||||
|
* nfa_regmatch() and addstate() can run properly after
|
||||||
|
* recursion. */
|
||||||
|
nfa_save_listids(prog, *listids);
|
||||||
|
nfa_endp = endposp;
|
||||||
|
result = nfa_regmatch(prog, state->out, submatch, m);
|
||||||
|
nfa_restore_listids(prog, *listids);
|
||||||
|
|
||||||
|
/* restore position in input text */
|
||||||
|
reginput = save_reginput;
|
||||||
|
regline = save_regline;
|
||||||
|
reglnum = save_reglnum;
|
||||||
|
nfa_match = save_nfa_match;
|
||||||
|
nfa_endp = save_nfa_endp;
|
||||||
|
|
||||||
|
#ifdef ENABLE_LOG
|
||||||
|
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
|
||||||
|
if (log_fd != NULL)
|
||||||
|
{
|
||||||
|
fprintf(log_fd, "****************************\n");
|
||||||
|
fprintf(log_fd, "FINISHED RUNNING nfa_regmatch() recursively\n");
|
||||||
|
fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : "FALSE");
|
||||||
|
fprintf(log_fd, "****************************\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EMSG(_("Could not open temporary log file for writing, displaying on stderr ... "));
|
||||||
|
log_fd = stderr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main matching routine.
|
* Main matching routine.
|
||||||
*
|
*
|
||||||
@ -3881,171 +4010,57 @@ nfa_regmatch(prog, start, submatch, m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case NFA_END_INVISIBLE:
|
case NFA_END_INVISIBLE:
|
||||||
/* This is only encountered after a NFA_START_INVISIBLE or
|
/*
|
||||||
|
* This is only encountered after a NFA_START_INVISIBLE or
|
||||||
* NFA_START_INVISIBLE_BEFORE node.
|
* NFA_START_INVISIBLE_BEFORE node.
|
||||||
* They surround a zero-width group, used with "\@=", "\&",
|
* They surround a zero-width group, used with "\@=", "\&",
|
||||||
* "\@!", "\@<=" and "\@<!".
|
* "\@!", "\@<=" and "\@<!".
|
||||||
* If we got here, it means that the current "invisible" group
|
* If we got here, it means that the current "invisible" group
|
||||||
* finished successfully, so return control to the parent
|
* finished successfully, so return control to the parent
|
||||||
* nfa_regmatch(). Submatches are stored in *m, and used in
|
* nfa_regmatch(). For a look-behind match only when it ends
|
||||||
* the parent call. */
|
* in the position in "nfa_endp".
|
||||||
if (start->c == NFA_MOPEN)
|
* Submatches are stored in *m, and used in the parent call.
|
||||||
/* TODO: do we ever get here? */
|
*/
|
||||||
addstate_here(thislist, t->state->out, &t->subs, &listidx);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_LOG
|
#ifdef ENABLE_LOG
|
||||||
if (nfa_endp != NULL)
|
if (nfa_endp != NULL)
|
||||||
{
|
{
|
||||||
if (REG_MULTI)
|
if (REG_MULTI)
|
||||||
fprintf(log_fd, "Current lnum: %d, endp lnum: %d; current col: %d, endp col: %d\n",
|
fprintf(log_fd, "Current lnum: %d, endp lnum: %d; current col: %d, endp col: %d\n",
|
||||||
(int)reglnum,
|
(int)reglnum,
|
||||||
(int)nfa_endp->se_u.pos.lnum,
|
(int)nfa_endp->se_u.pos.lnum,
|
||||||
(int)(reginput - regline),
|
(int)(reginput - regline),
|
||||||
nfa_endp->se_u.pos.col);
|
nfa_endp->se_u.pos.col);
|
||||||
else
|
else
|
||||||
fprintf(log_fd, "Current col: %d, endp col: %d\n",
|
fprintf(log_fd, "Current col: %d, endp col: %d\n",
|
||||||
(int)(reginput - regline),
|
(int)(reginput - regline),
|
||||||
(int)(nfa_endp->se_u.ptr - reginput));
|
(int)(nfa_endp->se_u.ptr - reginput));
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* It's only a match if it ends at "nfa_endp" */
|
|
||||||
if (nfa_endp != NULL && (REG_MULTI
|
|
||||||
? (reglnum != nfa_endp->se_u.pos.lnum
|
|
||||||
|| (int)(reginput - regline)
|
|
||||||
!= nfa_endp->se_u.pos.col)
|
|
||||||
: reginput != nfa_endp->se_u.ptr))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* do not set submatches for \@! */
|
|
||||||
if (!t->state->negated)
|
|
||||||
{
|
|
||||||
copy_sub(&m->norm, &t->subs.norm);
|
|
||||||
#ifdef FEAT_SYN_HL
|
|
||||||
if (nfa_has_zsubexpr)
|
|
||||||
copy_sub(&m->synt, &t->subs.synt);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
nfa_match = TRUE;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
/* It's only a match if it ends at "nfa_endp" */
|
||||||
|
if (nfa_endp != NULL && (REG_MULTI
|
||||||
|
? (reglnum != nfa_endp->se_u.pos.lnum
|
||||||
|
|| (int)(reginput - regline)
|
||||||
|
!= nfa_endp->se_u.pos.col)
|
||||||
|
: reginput != nfa_endp->se_u.ptr))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* do not set submatches for \@! */
|
||||||
|
if (!t->state->negated)
|
||||||
|
{
|
||||||
|
copy_sub(&m->norm, &t->subs.norm);
|
||||||
|
#ifdef FEAT_SYN_HL
|
||||||
|
if (nfa_has_zsubexpr)
|
||||||
|
copy_sub(&m->synt, &t->subs.synt);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
nfa_match = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NFA_START_INVISIBLE:
|
case NFA_START_INVISIBLE:
|
||||||
case NFA_START_INVISIBLE_BEFORE:
|
case NFA_START_INVISIBLE_BEFORE:
|
||||||
{
|
result = recursive_regmatch(t->state, prog, submatch, m,
|
||||||
char_u *save_reginput = reginput;
|
&listids);
|
||||||
char_u *save_regline = regline;
|
|
||||||
int save_reglnum = reglnum;
|
|
||||||
int save_nfa_match = nfa_match;
|
|
||||||
save_se_T *save_nfa_endp = nfa_endp;
|
|
||||||
save_se_T endpos;
|
|
||||||
save_se_T *endposp = NULL;
|
|
||||||
|
|
||||||
if (t->state->c == NFA_START_INVISIBLE_BEFORE)
|
|
||||||
{
|
|
||||||
/* The recursive match must end at the current position. */
|
|
||||||
endposp = &endpos;
|
|
||||||
if (REG_MULTI)
|
|
||||||
{
|
|
||||||
endpos.se_u.pos.col = (int)(reginput - regline);
|
|
||||||
endpos.se_u.pos.lnum = reglnum;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
endpos.se_u.ptr = reginput;
|
|
||||||
|
|
||||||
/* Go back the specified number of bytes, or as far as the
|
|
||||||
* start of the previous line, to try matching "\@<=" or
|
|
||||||
* not matching "\@<!".
|
|
||||||
* TODO: This is very inefficient! Would be better to
|
|
||||||
* first check for a match with what follows. */
|
|
||||||
if (t->state->val <= 0)
|
|
||||||
{
|
|
||||||
if (REG_MULTI)
|
|
||||||
{
|
|
||||||
regline = reg_getline(--reglnum);
|
|
||||||
if (regline == NULL)
|
|
||||||
/* can't go before the first line */
|
|
||||||
regline = reg_getline(++reglnum);
|
|
||||||
}
|
|
||||||
reginput = regline;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (REG_MULTI
|
|
||||||
&& (int)(reginput - regline) < t->state->val)
|
|
||||||
{
|
|
||||||
/* Not enough bytes in this line, go to end of
|
|
||||||
* previous line. */
|
|
||||||
regline = reg_getline(--reglnum);
|
|
||||||
if (regline == NULL)
|
|
||||||
{
|
|
||||||
/* can't go before the first line */
|
|
||||||
regline = reg_getline(++reglnum);
|
|
||||||
reginput = regline;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
reginput = regline + STRLEN(regline);
|
|
||||||
}
|
|
||||||
if ((int)(reginput - regline) >= t->state->val)
|
|
||||||
{
|
|
||||||
reginput -= t->state->val;
|
|
||||||
#ifdef FEAT_MBYTE
|
|
||||||
if (has_mbyte)
|
|
||||||
reginput -= mb_head_off(regline, reginput);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
reginput = regline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call nfa_regmatch() to check if the current concat matches
|
|
||||||
* at this position. The concat ends with the node
|
|
||||||
* NFA_END_INVISIBLE */
|
|
||||||
if (listids == NULL)
|
|
||||||
{
|
|
||||||
listids = (int *)lalloc(sizeof(int) * nstate, TRUE);
|
|
||||||
if (listids == NULL)
|
|
||||||
{
|
|
||||||
EMSG(_("E878: (NFA) Could not allocate memory for branch traversal!"));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef ENABLE_LOG
|
|
||||||
if (log_fd != stderr)
|
|
||||||
fclose(log_fd);
|
|
||||||
log_fd = NULL;
|
|
||||||
#endif
|
|
||||||
/* Have to clear the listid field of the NFA nodes, so that
|
|
||||||
* nfa_regmatch() and addstate() can run properly after
|
|
||||||
* recursion. */
|
|
||||||
nfa_save_listids(prog, listids);
|
|
||||||
nfa_endp = endposp;
|
|
||||||
result = nfa_regmatch(prog, t->state->out, submatch, m);
|
|
||||||
nfa_restore_listids(prog, listids);
|
|
||||||
|
|
||||||
/* restore position in input text */
|
|
||||||
reginput = save_reginput;
|
|
||||||
regline = save_regline;
|
|
||||||
reglnum = save_reglnum;
|
|
||||||
nfa_match = save_nfa_match;
|
|
||||||
nfa_endp = save_nfa_endp;
|
|
||||||
|
|
||||||
#ifdef ENABLE_LOG
|
|
||||||
log_fd = fopen(NFA_REGEXP_RUN_LOG, "a");
|
|
||||||
if (log_fd != NULL)
|
|
||||||
{
|
|
||||||
fprintf(log_fd, "****************************\n");
|
|
||||||
fprintf(log_fd, "FINISHED RUNNING nfa_regmatch() recursively\n");
|
|
||||||
fprintf(log_fd, "MATCH = %s\n", result == TRUE ? "OK" : "FALSE");
|
|
||||||
fprintf(log_fd, "****************************\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EMSG(_("Could not open temporary log file for writing, displaying on stderr ... "));
|
|
||||||
log_fd = stderr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* for \@! it is a match when result is FALSE */
|
/* for \@! it is a match when result is FALSE */
|
||||||
if (result != t->state->negated)
|
if (result != t->state->negated)
|
||||||
{
|
{
|
||||||
@ -4056,12 +4071,11 @@ nfa_regmatch(prog, start, submatch, m)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* t->state->out1 is the corresponding END_INVISIBLE node;
|
/* t->state->out1 is the corresponding END_INVISIBLE node;
|
||||||
* Add it to the current list (zero-width match). */
|
* Add its out to the current list (zero-width match). */
|
||||||
addstate_here(thislist, t->state->out1->out, &t->subs,
|
addstate_here(thislist, t->state->out1->out, &t->subs,
|
||||||
&listidx);
|
&listidx);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case NFA_BOL:
|
case NFA_BOL:
|
||||||
if (reginput == regline)
|
if (reginput == regline)
|
||||||
|
@ -728,6 +728,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1105,
|
||||||
/**/
|
/**/
|
||||||
1104,
|
1104,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user