mirror of
https://github.com/vim/vim.git
synced 2025-07-25 10:54:51 -04:00
updated for version 7.3.1087
Problem: A leading star is not seen as a normal char when \{} follows. Solution: Save and restore the parse state properly.
This commit is contained in:
parent
75d7a06920
commit
3737fc1c30
53
src/regexp.c
53
src/regexp.c
@ -665,10 +665,25 @@ static int nextchr; /* used for ungetchr() */
|
|||||||
#define REG_ZPAREN 2 /* \z(\) */
|
#define REG_ZPAREN 2 /* \z(\) */
|
||||||
#define REG_NPAREN 3 /* \%(\) */
|
#define REG_NPAREN 3 /* \%(\) */
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char_u *regparse;
|
||||||
|
int prevchr_len;
|
||||||
|
int curchr;
|
||||||
|
int prevchr;
|
||||||
|
int prevprevchr;
|
||||||
|
int nextchr;
|
||||||
|
int at_start;
|
||||||
|
int prev_at_start;
|
||||||
|
int regnpar;
|
||||||
|
} parse_state_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Forward declarations for vim_regcomp()'s friends.
|
* Forward declarations for vim_regcomp()'s friends.
|
||||||
*/
|
*/
|
||||||
static void initchr __ARGS((char_u *));
|
static void initchr __ARGS((char_u *));
|
||||||
|
static void save_parse_state __ARGS((parse_state_T *ps));
|
||||||
|
static void restore_parse_state __ARGS((parse_state_T *ps));
|
||||||
static int getchr __ARGS((void));
|
static int getchr __ARGS((void));
|
||||||
static void skipchr_keepstart __ARGS((void));
|
static void skipchr_keepstart __ARGS((void));
|
||||||
static int peekchr __ARGS((void));
|
static int peekchr __ARGS((void));
|
||||||
@ -2950,6 +2965,44 @@ initchr(str)
|
|||||||
prev_at_start = FALSE;
|
prev_at_start = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save the current parse state, so that it can be restored and parsing
|
||||||
|
* starts in the same state again.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
save_parse_state(ps)
|
||||||
|
parse_state_T *ps;
|
||||||
|
{
|
||||||
|
ps->regparse = regparse;
|
||||||
|
ps->prevchr_len = prevchr_len;
|
||||||
|
ps->curchr = curchr;
|
||||||
|
ps->prevchr = prevchr;
|
||||||
|
ps->prevprevchr = prevprevchr;
|
||||||
|
ps->nextchr = nextchr;
|
||||||
|
ps->at_start = at_start;
|
||||||
|
ps->prev_at_start = prev_at_start;
|
||||||
|
ps->regnpar = regnpar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore a previously saved parse state.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
restore_parse_state(ps)
|
||||||
|
parse_state_T *ps;
|
||||||
|
{
|
||||||
|
regparse = ps->regparse;
|
||||||
|
prevchr_len = ps->prevchr_len;
|
||||||
|
curchr = ps->curchr;
|
||||||
|
prevchr = ps->prevchr;
|
||||||
|
prevprevchr = ps->prevprevchr;
|
||||||
|
nextchr = ps->nextchr;
|
||||||
|
at_start = ps->at_start;
|
||||||
|
prev_at_start = ps->prev_at_start;
|
||||||
|
regnpar = ps->regnpar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the next character without advancing.
|
* Get the next character without advancing.
|
||||||
*/
|
*/
|
||||||
|
@ -1318,19 +1318,17 @@ nfa_regpiece()
|
|||||||
int ret;
|
int ret;
|
||||||
long minval, maxval;
|
long minval, maxval;
|
||||||
int greedy = TRUE; /* Braces are prefixed with '-' ? */
|
int greedy = TRUE; /* Braces are prefixed with '-' ? */
|
||||||
char_u *old_regparse, *new_regparse;
|
parse_state_T old_state;
|
||||||
|
parse_state_T new_state;
|
||||||
int c2;
|
int c2;
|
||||||
int old_post_pos;
|
int old_post_pos;
|
||||||
int my_post_start;
|
int my_post_start;
|
||||||
int old_regnpar;
|
|
||||||
int quest;
|
int quest;
|
||||||
|
|
||||||
/* Save the current position in the regexp, so that we can use it if
|
/* Save the current parse state, so that we can use it if <atom>{m,n} is
|
||||||
* <atom>{m,n} is next. */
|
* next. */
|
||||||
old_regparse = regparse;
|
save_parse_state(&old_state);
|
||||||
/* Save current number of open parenthesis, so we can use it if
|
|
||||||
* <atom>{m,n} is next */
|
|
||||||
old_regnpar = regnpar;
|
|
||||||
/* store current pos in the postfix form, for \{m,n} involving 0s */
|
/* store current pos in the postfix form, for \{m,n} involving 0s */
|
||||||
my_post_start = (int)(post_ptr - post_start);
|
my_post_start = (int)(post_ptr - post_start);
|
||||||
|
|
||||||
@ -1361,8 +1359,7 @@ nfa_regpiece()
|
|||||||
* In order to be consistent with the old engine, we replace
|
* In order to be consistent with the old engine, we replace
|
||||||
* <atom>+ with <atom><atom>*
|
* <atom>+ with <atom><atom>*
|
||||||
*/
|
*/
|
||||||
regnpar = old_regnpar;
|
restore_parse_state(&old_state);
|
||||||
regparse = old_regparse;
|
|
||||||
curchr = -1;
|
curchr = -1;
|
||||||
if (nfa_regatom() == FAIL)
|
if (nfa_regatom() == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@ -1452,17 +1449,14 @@ nfa_regpiece()
|
|||||||
|
|
||||||
/* Ignore previous call to nfa_regatom() */
|
/* Ignore previous call to nfa_regatom() */
|
||||||
post_ptr = post_start + my_post_start;
|
post_ptr = post_start + my_post_start;
|
||||||
/* Save pos after the repeated atom and the \{} */
|
/* Save parse state after the repeated atom and the \{} */
|
||||||
new_regparse = regparse;
|
save_parse_state(&new_state);
|
||||||
|
|
||||||
quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY);
|
quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY);
|
||||||
for (i = 0; i < maxval; i++)
|
for (i = 0; i < maxval; i++)
|
||||||
{
|
{
|
||||||
/* Goto beginning of the repeated atom */
|
/* Goto beginning of the repeated atom */
|
||||||
regparse = old_regparse;
|
restore_parse_state(&old_state);
|
||||||
curchr = -1;
|
|
||||||
/* Restore count of parenthesis */
|
|
||||||
regnpar = old_regnpar;
|
|
||||||
old_post_pos = (int)(post_ptr - post_start);
|
old_post_pos = (int)(post_ptr - post_start);
|
||||||
if (nfa_regatom() == FAIL)
|
if (nfa_regatom() == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@ -1486,7 +1480,7 @@ nfa_regpiece()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Go to just after the repeated atom and the \{} */
|
/* Go to just after the repeated atom and the \{} */
|
||||||
regparse = new_regparse;
|
restore_parse_state(&new_state);
|
||||||
curchr = -1;
|
curchr = -1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -188,6 +188,10 @@ STARTTEST
|
|||||||
:call add(tl, [2, 'a\{,0}', 'oidfguih iuhi hiu aaaa', ''])
|
:call add(tl, [2, 'a\{,0}', 'oidfguih iuhi hiu aaaa', ''])
|
||||||
:call add(tl, [2, 'a\{,5}', 'abcd', 'a'])
|
:call add(tl, [2, 'a\{,5}', 'abcd', 'a'])
|
||||||
:call add(tl, [2, 'a\{,5}', 'aaaaaaaaaa', 'aaaaa'])
|
:call add(tl, [2, 'a\{,5}', 'aaaaaaaaaa', 'aaaaa'])
|
||||||
|
:" leading star as normal char when \{} follows
|
||||||
|
:call add(tl, [2, '^*\{4,}$', '***'])
|
||||||
|
:call add(tl, [2, '^*\{4,}$', '****', '****'])
|
||||||
|
:call add(tl, [2, '^*\{4,}$', '*****', '*****'])
|
||||||
:" same thing as 'a*'
|
:" same thing as 'a*'
|
||||||
:call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', ''])
|
:call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', ''])
|
||||||
:call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa'])
|
:call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa'])
|
||||||
|
@ -407,6 +407,15 @@ OK 2 - a\{,5}
|
|||||||
OK 0 - a\{,5}
|
OK 0 - a\{,5}
|
||||||
OK 1 - a\{,5}
|
OK 1 - a\{,5}
|
||||||
OK 2 - a\{,5}
|
OK 2 - a\{,5}
|
||||||
|
OK 0 - ^*\{4,}$
|
||||||
|
OK 1 - ^*\{4,}$
|
||||||
|
OK 2 - ^*\{4,}$
|
||||||
|
OK 0 - ^*\{4,}$
|
||||||
|
OK 1 - ^*\{4,}$
|
||||||
|
OK 2 - ^*\{4,}$
|
||||||
|
OK 0 - ^*\{4,}$
|
||||||
|
OK 1 - ^*\{4,}$
|
||||||
|
OK 2 - ^*\{4,}$
|
||||||
OK 0 - a\{}
|
OK 0 - a\{}
|
||||||
OK 1 - a\{}
|
OK 1 - a\{}
|
||||||
OK 2 - a\{}
|
OK 2 - a\{}
|
||||||
|
@ -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 */
|
||||||
|
/**/
|
||||||
|
1087,
|
||||||
/**/
|
/**/
|
||||||
1086,
|
1086,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user