diff --git a/7.3.1117 b/7.3.1117 new file mode 100644 index 0000000..524cafe --- /dev/null +++ b/7.3.1117 @@ -0,0 +1,337 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.3.1117 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.3.1117 +Problem: New regexp engine: \%[abc] not supported. +Solution: Implement \%[abc]. Add tests. +Files: src/regexp_nfa.c, src/testdir/test64.in, src/testdir/test64.ok + + +*** ../vim-7.3.1116/src/regexp_nfa.c 2013-06-05 11:01:59.000000000 +0200 +--- src/regexp_nfa.c 2013-06-05 11:03:19.000000000 +0200 +*************** +*** 61,66 **** +--- 61,67 ---- + NFA_COMPOSING, /* Next nodes in NFA are part of the + composing multibyte char */ + NFA_END_COMPOSING, /* End of a composing char in the NFA */ ++ NFA_OPT_CHARS, /* \%[abc] */ + + /* The following are used only in the postfix form, not in the NFA */ + NFA_PREV_ATOM_NO_WIDTH, /* Used for \@= */ +*************** +*** 972,979 **** + #endif + + case '[': +! /* TODO: \%[abc] not supported yet */ +! return FAIL; + + default: + { +--- 973,993 ---- + #endif + + case '[': +! { +! int n; +! +! /* \%[abc] */ +! for (n = 0; (c = getchr()) != ']'; ++n) +! { +! if (c == NUL) +! EMSG2_RET_FAIL(_(e_missing_sb), +! reg_magic == MAGIC_ALL); +! EMIT(c); +! } +! EMIT(NFA_OPT_CHARS); +! EMIT(n); +! break; +! } + + default: + { +*************** +*** 989,995 **** + } + if (c == 'l' || c == 'c' || c == 'v') + { +- EMIT(n); + if (c == 'l') + /* \%{n}l \%{n}l */ + EMIT(cmp == '<' ? NFA_LNUM_LT : +--- 1003,1008 ---- +*************** +*** 1002,1015 **** + /* \%{n}v \%{n}v */ + EMIT(cmp == '<' ? NFA_VCOL_LT : + cmp == '>' ? NFA_VCOL_GT : NFA_VCOL); + break; + } + else if (c == '\'' && n == 0) + { + /* \%'m \%<'m \%>'m */ +- EMIT(getchr()); + EMIT(cmp == '<' ? NFA_MARK_LT : + cmp == '>' ? NFA_MARK_GT : NFA_MARK); + break; + } + } +--- 1015,1029 ---- + /* \%{n}v \%{n}v */ + EMIT(cmp == '<' ? NFA_VCOL_LT : + cmp == '>' ? NFA_VCOL_GT : NFA_VCOL); ++ EMIT(n); + break; + } + else if (c == '\'' && n == 0) + { + /* \%'m \%<'m \%>'m */ + EMIT(cmp == '<' ? NFA_MARK_LT : + cmp == '>' ? NFA_MARK_GT : NFA_MARK); ++ EMIT(getchr()); + break; + } + } +*************** +*** 1885,1890 **** +--- 1899,1905 ---- + + case NFA_COMPOSING: STRCPY(code, "NFA_COMPOSING"); break; + case NFA_END_COMPOSING: STRCPY(code, "NFA_END_COMPOSING"); break; ++ case NFA_OPT_CHARS: STRCPY(code, "NFA_OPT_CHARS"); break; + + case NFA_MOPEN: + case NFA_MOPEN1: +*************** +*** 2558,2567 **** +--- 2573,2621 ---- + PUSH(frag(s, list1(&s->out))); + break; + ++ case NFA_OPT_CHARS: ++ { ++ int n; ++ ++ /* \%[abc] */ ++ n = *++p; /* get number of characters */ ++ if (nfa_calc_size == TRUE) ++ { ++ nstate += n; ++ break; ++ } ++ e1.out = NULL; /* stores list with out1's */ ++ s1 = NULL; /* previous NFA_SPLIT to connect to */ ++ while (n-- > 0) ++ { ++ e = POP(); /* get character */ ++ s = alloc_state(NFA_SPLIT, e.start, NULL); ++ if (s == NULL) ++ goto theend; ++ if (e1.out == NULL) ++ e1 = e; ++ patch(e.out, s1); ++ append(e1.out, list1(&s->out1)); ++ s1 = s; ++ } ++ PUSH(frag(s, e1.out)); ++ break; ++ } ++ + case NFA_PREV_ATOM_NO_WIDTH: + case NFA_PREV_ATOM_NO_WIDTH_NEG: + case NFA_PREV_ATOM_JUST_BEFORE: + case NFA_PREV_ATOM_JUST_BEFORE_NEG: ++ { ++ int neg = (*p == NFA_PREV_ATOM_NO_WIDTH_NEG ++ || *p == NFA_PREV_ATOM_JUST_BEFORE_NEG); ++ int before = (*p == NFA_PREV_ATOM_JUST_BEFORE ++ || *p == NFA_PREV_ATOM_JUST_BEFORE_NEG); ++ int n; ++ ++ if (before) ++ n = *++p; /* get the count */ ++ + /* The \@= operator: match the preceding atom with zero width. + * The \@! operator: no match for the preceding atom. + * The \@<= operator: match for the preceding atom. +*************** +*** 2583,2603 **** + s = alloc_state(NFA_START_INVISIBLE, e.start, s1); + if (s == NULL) + goto theend; +! if (*p == NFA_PREV_ATOM_NO_WIDTH_NEG +! || *p == NFA_PREV_ATOM_JUST_BEFORE_NEG) + { + s->negated = TRUE; + s1->negated = TRUE; + } +! if (*p == NFA_PREV_ATOM_JUST_BEFORE +! || *p == NFA_PREV_ATOM_JUST_BEFORE_NEG) + { +! s->val = *++p; /* get the count */ + ++s->c; /* NFA_START_INVISIBLE -> NFA_START_INVISIBLE_BEFORE */ + } + + PUSH(frag(s, list1(&s1->out))); + break; + + #ifdef FEAT_MBYTE + case NFA_COMPOSING: /* char with composing char */ +--- 2637,2656 ---- + s = alloc_state(NFA_START_INVISIBLE, e.start, s1); + if (s == NULL) + goto theend; +! if (neg) + { + s->negated = TRUE; + s1->negated = TRUE; + } +! if (before) + { +! s->val = n; /* store the count */ + ++s->c; /* NFA_START_INVISIBLE -> NFA_START_INVISIBLE_BEFORE */ + } + + PUSH(frag(s, list1(&s1->out))); + break; ++ } + + #ifdef FEAT_MBYTE + case NFA_COMPOSING: /* char with composing char */ +*************** +*** 2750,2767 **** + case NFA_MARK: + case NFA_MARK_GT: + case NFA_MARK_LT: + if (nfa_calc_size == TRUE) + { + nstate += 1; + break; + } +! e1 = POP(); +! s = alloc_state(*p, NULL, NULL); + if (s == NULL) + goto theend; +! s->val = e1.start->c; /* lnum, col or mark name */ + PUSH(frag(s, list1(&s->out))); + break; + + case NFA_ZSTART: + case NFA_ZEND: +--- 2803,2823 ---- + case NFA_MARK: + case NFA_MARK_GT: + case NFA_MARK_LT: ++ { ++ int n = *++p; /* lnum, col or mark name */ ++ + if (nfa_calc_size == TRUE) + { + nstate += 1; + break; + } +! s = alloc_state(p[-1], NULL, NULL); + if (s == NULL) + goto theend; +! s->val = n; + PUSH(frag(s, list1(&s->out))); + break; ++ } + + case NFA_ZSTART: + case NFA_ZEND: +*** ../vim-7.3.1116/src/testdir/test64.in 2013-06-04 21:27:33.000000000 +0200 +--- src/testdir/test64.in 2013-06-04 23:45:44.000000000 +0200 +*************** +*** 352,357 **** +--- 352,370 ---- + :call add(tl, [2, '\%u0020', 'yes no', ' ']) + :call add(tl, [2, '\%U00000020', 'yes no', ' ']) + :" ++ :""""" \%[abc] ++ :call add(tl, [2, 'foo\%[bar]', 'fobar']) ++ :call add(tl, [2, 'foo\%[bar]', 'foobar', 'foobar']) ++ :call add(tl, [2, 'foo\%[bar]', 'fooxx', 'foo']) ++ :call add(tl, [2, 'foo\%[bar]', 'foobxx', 'foob']) ++ :call add(tl, [2, 'foo\%[bar]', 'foobaxx', 'fooba']) ++ :call add(tl, [2, 'foo\%[bar]', 'foobarxx', 'foobar']) ++ :call add(tl, [2, 'foo\%[bar]x', 'foobxx', 'foobx']) ++ :call add(tl, [2, 'foo\%[bar]x', 'foobarxx', 'foobarx']) ++ :call add(tl, [2, '\%[bar]x', 'barxx', 'barx']) ++ :call add(tl, [2, '\%[bar]x', 'bxx', 'bx']) ++ :call add(tl, [2, '\%[bar]x', 'xxx', 'x']) ++ :" + :"""" Alternatives, must use first longest match + :call add(tl, [2, 'goo\|go', 'google', 'goo']) + :call add(tl, [2, '\