| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.1117 |
| 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.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 |
| |
| |
| |
| |
| |
| *** 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 \%{n}>l */ |
| EMIT(cmp == '<' ? NFA_LNUM_LT : |
| --- 1003,1008 ---- |
| |
| *** 1002,1015 **** |
| /* \%{n}v \%{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 \%{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: |
| |
| |
| |
| *** 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, '\<goo\|\<go', 'google', 'goo']) |
| |
| |
| |
| *** 797,802 **** |
| --- 797,835 ---- |
| OK 0 - \%U00000020 |
| OK 1 - \%U00000020 |
| OK 2 - \%U00000020 |
| + OK 0 - foo\%[bar] |
| + OK 1 - foo\%[bar] |
| + OK 2 - foo\%[bar] |
| + OK 0 - foo\%[bar] |
| + OK 1 - foo\%[bar] |
| + OK 2 - foo\%[bar] |
| + OK 0 - foo\%[bar] |
| + OK 1 - foo\%[bar] |
| + OK 2 - foo\%[bar] |
| + OK 0 - foo\%[bar] |
| + OK 1 - foo\%[bar] |
| + OK 2 - foo\%[bar] |
| + OK 0 - foo\%[bar] |
| + OK 1 - foo\%[bar] |
| + OK 2 - foo\%[bar] |
| + OK 0 - foo\%[bar] |
| + OK 1 - foo\%[bar] |
| + OK 2 - foo\%[bar] |
| + OK 0 - foo\%[bar]x |
| + OK 1 - foo\%[bar]x |
| + OK 2 - foo\%[bar]x |
| + OK 0 - foo\%[bar]x |
| + OK 1 - foo\%[bar]x |
| + OK 2 - foo\%[bar]x |
| + OK 0 - \%[bar]x |
| + OK 1 - \%[bar]x |
| + OK 2 - \%[bar]x |
| + OK 0 - \%[bar]x |
| + OK 1 - \%[bar]x |
| + OK 2 - \%[bar]x |
| + OK 0 - \%[bar]x |
| + OK 1 - \%[bar]x |
| + OK 2 - \%[bar]x |
| OK 0 - goo\|go |
| OK 1 - goo\|go |
| OK 2 - goo\|go |
| |
| |
| |
| *** 730,731 **** |
| --- 730,733 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 1117, |
| /**/ |
| |
| -- |
| From "know your smileys": |
| :-) Funny |
| |-) Funny Oriental |
| (-: Funny Australian |
| |
| /// 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 /// |