| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.1076 |
| 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.1076 |
| Problem: New regexp engine: \@= and \& don't work. |
| Solution: Make these items work. Add column info to logging. |
| Files: src/regexp_nfa.c, src/testdir/test64.in, src/testdir/test64.ok |
| |
| |
| |
| |
| |
| *** 1740,1747 **** |
| STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH"); break; |
| case NFA_PREV_ATOM_NO_WIDTH_NEG: |
| STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH_NEG"); break; |
| ! case NFA_NOPEN: STRCPY(code, "NFA_MOPEN_INVISIBLE"); break; |
| ! case NFA_NCLOSE: STRCPY(code, "NFA_MCLOSE_INVISIBLE"); break; |
| case NFA_START_INVISIBLE: STRCPY(code, "NFA_START_INVISIBLE"); break; |
| case NFA_END_INVISIBLE: STRCPY(code, "NFA_END_INVISIBLE"); break; |
| |
| --- 1740,1747 ---- |
| STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH"); break; |
| case NFA_PREV_ATOM_NO_WIDTH_NEG: |
| STRCPY(code, "NFA_PREV_ATOM_NO_WIDTH_NEG"); break; |
| ! case NFA_NOPEN: STRCPY(code, "NFA_NOPEN"); break; |
| ! case NFA_NCLOSE: STRCPY(code, "NFA_NCLOSE"); break; |
| case NFA_START_INVISIBLE: STRCPY(code, "NFA_START_INVISIBLE"); break; |
| case NFA_END_INVISIBLE: STRCPY(code, "NFA_END_INVISIBLE"); break; |
| |
| |
| *** 2373,2384 **** |
| break; |
| |
| case NFA_PREV_ATOM_NO_WIDTH: |
| ! /* The \@= operator: match the preceding atom with 0 width. |
| * Surrounds the preceding atom with START_INVISIBLE and |
| ! * END_INVISIBLE, similarly to MOPEN. |
| ! */ |
| ! /* TODO: Maybe this drops the speed? */ |
| ! goto theend; |
| |
| if (nfa_calc_size == TRUE) |
| { |
| --- 2373,2381 ---- |
| break; |
| |
| case NFA_PREV_ATOM_NO_WIDTH: |
| ! /* The \@= operator: match the preceding atom with zero width. |
| * Surrounds the preceding atom with START_INVISIBLE and |
| ! * END_INVISIBLE, similarly to MOPEN. */ |
| |
| if (nfa_calc_size == TRUE) |
| { |
| |
| *** 2745,2750 **** |
| --- 2742,2750 ---- |
| int save_in_use; |
| char_u *save_ptr; |
| int i; |
| + #ifdef ENABLE_LOG |
| + int did_print = FALSE; |
| + #endif |
| |
| if (l == NULL || state == NULL) |
| return; |
| |
| *** 2782,2788 **** |
| /* These nodes do not need to be added, but we need to bail out |
| * when it was tried to be added to this list before. */ |
| if (state->lastlist == l->id) |
| ! return; |
| state->lastlist = l->id; |
| break; |
| |
| --- 2782,2788 ---- |
| /* These nodes do not need to be added, but we need to bail out |
| * when it was tried to be added to this list before. */ |
| if (state->lastlist == l->id) |
| ! goto skip_add; |
| state->lastlist = l->id; |
| break; |
| |
| |
| *** 2792,2798 **** |
| --- 2792,2806 ---- |
| /* This state is already in the list, don't add it again, |
| * unless it is an MOPEN that is used for a backreference. */ |
| if (!nfa_has_backref) |
| + { |
| + skip_add: |
| + #ifdef ENABLE_LOG |
| + nfa_set_code(state->c); |
| + fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n", |
| + abs(state->id), l->id, state->c, code); |
| + #endif |
| return; |
| + } |
| |
| /* See if the same state is already in the list with the same |
| * positions. */ |
| |
| *** 2801,2807 **** |
| thread = &l->t[i]; |
| if (thread->state->id == state->id |
| && sub_equal(&thread->sub, sub)) |
| ! return; |
| } |
| } |
| |
| --- 2809,2815 ---- |
| thread = &l->t[i]; |
| if (thread->state->id == state->id |
| && sub_equal(&thread->sub, sub)) |
| ! goto skip_add; |
| } |
| } |
| |
| |
| *** 2832,2843 **** |
| &sub->list.line[0], |
| sizeof(struct linepos) * sub->in_use); |
| } |
| } |
| |
| #ifdef ENABLE_LOG |
| ! nfa_set_code(state->c); |
| ! fprintf(log_fd, "> Adding state %d to list. Character %d: %s\n", |
| ! abs(state->id), state->c, code); |
| #endif |
| switch (state->c) |
| { |
| --- 2840,2878 ---- |
| &sub->list.line[0], |
| sizeof(struct linepos) * sub->in_use); |
| } |
| + #ifdef ENABLE_LOG |
| + { |
| + int col; |
| + |
| + if (thread->sub.in_use <= 0) |
| + col = -1; |
| + else if (REG_MULTI) |
| + col = thread->sub.list.multi[0].start.col; |
| + else |
| + col = (int)(thread->sub.list.line[0].start - regline); |
| + nfa_set_code(state->c); |
| + fprintf(log_fd, "> Adding state %d to list %d. char %d: %s (start col %d)\n", |
| + abs(state->id), l->id, state->c, code, col); |
| + did_print = TRUE; |
| + } |
| + #endif |
| } |
| |
| #ifdef ENABLE_LOG |
| ! if (!did_print) |
| ! { |
| ! int col; |
| ! |
| ! if (sub->in_use <= 0) |
| ! col = -1; |
| ! else if (REG_MULTI) |
| ! col = sub->list.multi[0].start.col; |
| ! else |
| ! col = (int)(sub->list.line[0].start - regline); |
| ! nfa_set_code(state->c); |
| ! fprintf(log_fd, "> Processing state %d for list %d. char %d: %s (start col %d)\n", |
| ! abs(state->id), l->id, state->c, code, col); |
| ! } |
| #endif |
| switch (state->c) |
| { |
| |
| *** 2873,2886 **** |
| addstate(l, state->out, sub, off); |
| break; |
| |
| - /* If this state is reached, then a recursive call of nfa_regmatch() |
| - * succeeded. the next call saves the found submatches in the |
| - * first state after the "invisible" branch. */ |
| - #if 0 |
| - case NFA_END_INVISIBLE: |
| - break; |
| - #endif |
| - |
| case NFA_MOPEN + 0: |
| case NFA_MOPEN + 1: |
| case NFA_MOPEN + 2: |
| --- 2908,2913 ---- |
| |
| *** 3450,3458 **** |
| fprintf(debug, "%s, ", code); |
| #endif |
| #ifdef ENABLE_LOG |
| ! nfa_set_code(t->state->c); |
| ! fprintf(log_fd, "(%d) %s, code %d ... \n", abs(t->state->id), |
| ! code, (int)t->state->c); |
| #endif |
| |
| /* |
| --- 3477,3495 ---- |
| fprintf(debug, "%s, ", code); |
| #endif |
| #ifdef ENABLE_LOG |
| ! { |
| ! int col; |
| ! |
| ! if (t->sub.in_use <= 0) |
| ! col = -1; |
| ! else if (REG_MULTI) |
| ! col = t->sub.list.multi[0].start.col; |
| ! else |
| ! col = (int)(t->sub.list.line[0].start - regline); |
| ! nfa_set_code(t->state->c); |
| ! fprintf(log_fd, "(%d) char %d %s (start col %d) ... \n", |
| ! abs(t->state->id), (int)t->state->c, code, col); |
| ! } |
| #endif |
| |
| /* |
| |
| *** 3504,3509 **** |
| --- 3541,3547 ---- |
| addstate_here(thislist, t->state->out, &t->sub, &listidx); |
| else |
| { |
| + /* TODO: only copy positions in use. */ |
| *m = t->sub; |
| nfa_match = TRUE; |
| } |
| |
| *** 3538,3543 **** |
| --- 3576,3582 ---- |
| result = nfa_regmatch(t->state->out, submatch, m); |
| nfa_set_neg_listids(start); |
| nfa_restore_listids(start, listids); |
| + nfa_match = FALSE; |
| |
| #ifdef ENABLE_LOG |
| log_fd = fopen(NFA_REGEXP_RUN_LOG, "a"); |
| |
| *** 3575,3583 **** |
| t->sub.list.line[j].start = m->list.line[j].start; |
| t->sub.list.line[j].end = m->list.line[j].end; |
| } |
| ! t->sub.in_use = m->in_use; |
| |
| ! /* t->state->out1 is the corresponding END_INVISIBLE node */ |
| addstate_here(thislist, t->state->out1->out, &t->sub, |
| &listidx); |
| } |
| --- 3614,3624 ---- |
| t->sub.list.line[j].start = m->list.line[j].start; |
| t->sub.list.line[j].end = m->list.line[j].end; |
| } |
| ! if (m->in_use > t->sub.in_use) |
| ! t->sub.in_use = m->in_use; |
| |
| ! /* t->state->out1 is the corresponding END_INVISIBLE node; |
| ! * Add it to the current list (zero-width match). */ |
| addstate_here(thislist, t->state->out1->out, &t->sub, |
| &listidx); |
| } |
| |
| *** 4146,4152 **** |
| fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr); |
| #endif |
| fprintf(f, "\tInput text is \"%s\" \n", reginput); |
| ! fprintf(f, " =======================================================\n\n\n\n\n\n\n"); |
| nfa_print_state(f, start); |
| fprintf(f, "\n\n"); |
| fclose(f); |
| --- 4187,4193 ---- |
| fprintf(f, "\tRegexp is \"%s\"\n", nfa_regengine.expr); |
| #endif |
| fprintf(f, "\tInput text is \"%s\" \n", reginput); |
| ! fprintf(f, " =======================================================\n\n"); |
| nfa_print_state(f, start); |
| fprintf(f, "\n\n"); |
| fclose(f); |
| |
| |
| |
| *** 294,315 **** |
| :call add(tl, [2, '\v(a \zsif .*){2}', 'a if then a if last', 'if last', 'a if last']) |
| :call add(tl, [2, '\>\zs.', 'aword. ', '.']) |
| :" |
| ! :"""" Tests for \@ features |
| ! :call add(tl, [0, 'abc\@=', 'abc', 'ab']) |
| ! :call add(tl, [0, 'abc\@=cd', 'abcd', 'abcd']) |
| ! :call add(tl, [0, 'abc\@=', 'ababc', 'ab']) |
| :" will never match, no matter the input text |
| :call add(tl, [2, 'abcd\@=e', 'abcd']) |
| :" will never match |
| :call add(tl, [2, 'abcd\@=e', 'any text in here ... ']) |
| ! :call add(tl, [0, '\v(abc)@=..', 'xabcd', 'ab', 'abc']) |
| :" no match |
| :call add(tl, [2, '\(.*John\)\@=.*Bob', 'here is John, and here is B']) |
| ! :call add(tl, [0, '\(John.*\)\@=.*Bob', 'John is Bobs friend', 'John is Bob', 'John is Bobs friend']) |
| :" no match |
| :call add(tl, [2, '.*John\&.*Bob', 'here is John, and here is B']) |
| ! :call add(tl, [0, '.*John\&.*Bob', 'John is Bobs friend', 'John is Bob']) |
| ! :call add(tl, [0, '\v(test1)@=.*yep', 'this is a test1, yep it is', 'test1, yep', 'test1']) |
| :" |
| :"""" Combining different tests and features |
| :call add(tl, [2, '[[:alpha:]]\{-2,6}', '787abcdiuhsasiuhb4', 'ab']) |
| --- 294,315 ---- |
| :call add(tl, [2, '\v(a \zsif .*){2}', 'a if then a if last', 'if last', 'a if last']) |
| :call add(tl, [2, '\>\zs.', 'aword. ', '.']) |
| :" |
| ! :"""" Tests for \@= and \& features |
| ! :call add(tl, [2, 'abc\@=', 'abc', 'ab']) |
| ! :call add(tl, [2, 'abc\@=cd', 'abcd', 'abcd']) |
| ! :call add(tl, [2, 'abc\@=', 'ababc', 'ab']) |
| :" will never match, no matter the input text |
| :call add(tl, [2, 'abcd\@=e', 'abcd']) |
| :" will never match |
| :call add(tl, [2, 'abcd\@=e', 'any text in here ... ']) |
| ! :call add(tl, [2, '\v(abc)@=..', 'xabcd', 'ab', 'abc']) |
| :" no match |
| :call add(tl, [2, '\(.*John\)\@=.*Bob', 'here is John, and here is B']) |
| ! :call add(tl, [2, '\(John.*\)\@=.*Bob', 'John is Bobs friend', 'John is Bob', 'John is Bobs friend']) |
| :" no match |
| :call add(tl, [2, '.*John\&.*Bob', 'here is John, and here is B']) |
| ! :call add(tl, [2, '.*John\&.*Bob', 'John is Bobs friend', 'John is Bob']) |
| ! :call add(tl, [2, '\v(test1)@=.*yep', 'this is a test1, yep it is', 'test1, yep', 'test1']) |
| :" |
| :"""" Combining different tests and features |
| :call add(tl, [2, '[[:alpha:]]\{-2,6}', '787abcdiuhsasiuhb4', 'ab']) |
| |
| |
| |
| *** 647,656 **** |
| --- 647,659 ---- |
| OK 2 - \>\zs. |
| OK 0 - abc\@= |
| OK 1 - abc\@= |
| + OK 2 - abc\@= |
| OK 0 - abc\@=cd |
| OK 1 - abc\@=cd |
| + OK 2 - abc\@=cd |
| OK 0 - abc\@= |
| OK 1 - abc\@= |
| + OK 2 - abc\@= |
| OK 0 - abcd\@=e |
| OK 1 - abcd\@=e |
| OK 2 - abcd\@=e |
| |
| *** 659,676 **** |
| --- 662,683 ---- |
| OK 2 - abcd\@=e |
| OK 0 - \v(abc)@=.. |
| OK 1 - \v(abc)@=.. |
| + OK 2 - \v(abc)@=.. |
| OK 0 - \(.*John\)\@=.*Bob |
| OK 1 - \(.*John\)\@=.*Bob |
| OK 2 - \(.*John\)\@=.*Bob |
| OK 0 - \(John.*\)\@=.*Bob |
| OK 1 - \(John.*\)\@=.*Bob |
| + OK 2 - \(John.*\)\@=.*Bob |
| OK 0 - .*John\&.*Bob |
| OK 1 - .*John\&.*Bob |
| OK 2 - .*John\&.*Bob |
| OK 0 - .*John\&.*Bob |
| OK 1 - .*John\&.*Bob |
| + OK 2 - .*John\&.*Bob |
| OK 0 - \v(test1)@=.*yep |
| OK 1 - \v(test1)@=.*yep |
| + OK 2 - \v(test1)@=.*yep |
| OK 0 - [[:alpha:]]\{-2,6} |
| OK 1 - [[:alpha:]]\{-2,6} |
| OK 2 - [[:alpha:]]\{-2,6} |
| |
| |
| |
| *** 730,731 **** |
| --- 730,733 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 1076, |
| /**/ |
| |
| -- |
| I'm not familiar with this proof, but I'm aware of a significant |
| following of toddlers who believe that peanut butter is the solution |
| to all of life's problems... -- Tim Hammerquist |
| |
| /// 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 /// |