| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.1087 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.3.1087 |
| Problem: A leading star is not seen as a normal char when \{} follows. |
| Solution: Save and restore the parse state properly. |
| Files: src/regexp.c, src/regexp_nfa.c, src/testdir/test64.in, |
| src/testdir/test64.ok |
| |
| |
| |
| |
| |
| *** 665,674 **** |
| --- 665,689 ---- |
| #define REG_ZPAREN 2 /* \z(\) */ |
| #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. |
| */ |
| 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 void skipchr_keepstart __ARGS((void)); |
| static int peekchr __ARGS((void)); |
| |
| *** 2951,2956 **** |
| --- 2966,3009 ---- |
| } |
| |
| /* |
| + * 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. |
| */ |
| static int |
| |
| |
| |
| *** 1318,1336 **** |
| int ret; |
| long minval, maxval; |
| int greedy = TRUE; /* Braces are prefixed with '-' ? */ |
| ! char_u *old_regparse, *new_regparse; |
| int c2; |
| int old_post_pos; |
| int my_post_start; |
| - int old_regnpar; |
| int quest; |
| |
| ! /* Save the current position in the regexp, so that we can use it if |
| ! * <atom>{m,n} is next. */ |
| ! old_regparse = regparse; |
| ! /* 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 */ |
| my_post_start = (int)(post_ptr - post_start); |
| |
| --- 1318,1334 ---- |
| int ret; |
| long minval, maxval; |
| int greedy = TRUE; /* Braces are prefixed with '-' ? */ |
| ! parse_state_T old_state; |
| ! parse_state_T new_state; |
| int c2; |
| int old_post_pos; |
| int my_post_start; |
| int quest; |
| |
| ! /* Save the current parse state, so that we can use it if <atom>{m,n} is |
| ! * next. */ |
| ! save_parse_state(&old_state); |
| ! |
| /* store current pos in the postfix form, for \{m,n} involving 0s */ |
| my_post_start = (int)(post_ptr - post_start); |
| |
| |
| *** 1361,1368 **** |
| * In order to be consistent with the old engine, we replace |
| * <atom>+ with <atom><atom>* |
| */ |
| ! regnpar = old_regnpar; |
| ! regparse = old_regparse; |
| curchr = -1; |
| if (nfa_regatom() == FAIL) |
| return FAIL; |
| --- 1359,1365 ---- |
| * In order to be consistent with the old engine, we replace |
| * <atom>+ with <atom><atom>* |
| */ |
| ! restore_parse_state(&old_state); |
| curchr = -1; |
| if (nfa_regatom() == FAIL) |
| return FAIL; |
| |
| *** 1452,1468 **** |
| |
| /* Ignore previous call to nfa_regatom() */ |
| post_ptr = post_start + my_post_start; |
| ! /* Save pos after the repeated atom and the \{} */ |
| ! new_regparse = regparse; |
| |
| quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY); |
| for (i = 0; i < maxval; i++) |
| { |
| /* Goto beginning of the repeated atom */ |
| ! regparse = old_regparse; |
| ! curchr = -1; |
| ! /* Restore count of parenthesis */ |
| ! regnpar = old_regnpar; |
| old_post_pos = (int)(post_ptr - post_start); |
| if (nfa_regatom() == FAIL) |
| return FAIL; |
| --- 1449,1462 ---- |
| |
| /* Ignore previous call to nfa_regatom() */ |
| post_ptr = post_start + my_post_start; |
| ! /* Save parse state after the repeated atom and the \{} */ |
| ! save_parse_state(&new_state); |
| |
| quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY); |
| for (i = 0; i < maxval; i++) |
| { |
| /* Goto beginning of the repeated atom */ |
| ! restore_parse_state(&old_state); |
| old_post_pos = (int)(post_ptr - post_start); |
| if (nfa_regatom() == FAIL) |
| return FAIL; |
| |
| *** 1486,1492 **** |
| } |
| |
| /* Go to just after the repeated atom and the \{} */ |
| ! regparse = new_regparse; |
| curchr = -1; |
| |
| break; |
| --- 1480,1486 ---- |
| } |
| |
| /* Go to just after the repeated atom and the \{} */ |
| ! restore_parse_state(&new_state); |
| curchr = -1; |
| |
| break; |
| |
| |
| |
| *** 188,193 **** |
| --- 188,197 ---- |
| :call add(tl, [2, 'a\{,0}', 'oidfguih iuhi hiu aaaa', '']) |
| :call add(tl, [2, 'a\{,5}', 'abcd', 'a']) |
| :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*' |
| :call add(tl, [2, 'a\{}', 'bbbcddiuhfcd', '']) |
| :call add(tl, [2, 'a\{}', 'aaaaioudfh coisf jda', 'aaaa']) |
| |
| |
| |
| *** 407,412 **** |
| --- 407,421 ---- |
| OK 0 - a\{,5} |
| OK 1 - 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 1 - a\{} |
| OK 2 - a\{} |
| |
| |
| |
| *** 730,731 **** |
| --- 730,733 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 1087, |
| /**/ |
| |
| -- |
| Change is inevitable, except from a vending machine. |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |