Mercurial > vim
comparison src/regexp_nfa.c @ 10170:4acacf4081ce v7.4.2355
commit https://github.com/vim/vim/commit/16b3578f355282846f2600ce77fb344950f0b9ce
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Sep 9 20:29:50 2016 +0200
patch 7.4.2355
Problem: Regexp fails to match when using "\>\)\?". (Ramel)
Solution: When a state is already in the list, but addstate_here() is used
and the existing state comes later, add the new state anyway.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Fri, 09 Sep 2016 20:30:07 +0200 |
parents | 3c37899baa8d |
children | d76ccdacb41e |
comparison
equal
deleted
inserted
replaced
10169:fbb82155b1e2 | 10170:4acacf4081ce |
---|---|
4338 return TRUE; | 4338 return TRUE; |
4339 } | 4339 } |
4340 return FALSE; | 4340 return FALSE; |
4341 } | 4341 } |
4342 | 4342 |
4343 /* Offset used for "off" by addstate_here(). */ | |
4344 #define ADDSTATE_HERE_OFFSET 10 | |
4345 | |
4343 /* | 4346 /* |
4344 * Add "state" and possibly what follows to state list ".". | 4347 * Add "state" and possibly what follows to state list ".". |
4345 * Returns "subs_arg", possibly copied into temp_subs. | 4348 * Returns "subs_arg", possibly copied into temp_subs. |
4346 */ | 4349 */ |
4347 static regsubs_T * | 4350 static regsubs_T * |
4348 addstate( | 4351 addstate( |
4349 nfa_list_T *l, /* runtime state list */ | 4352 nfa_list_T *l, /* runtime state list */ |
4350 nfa_state_T *state, /* state to update */ | 4353 nfa_state_T *state, /* state to update */ |
4351 regsubs_T *subs_arg, /* pointers to subexpressions */ | 4354 regsubs_T *subs_arg, /* pointers to subexpressions */ |
4352 nfa_pim_T *pim, /* postponed look-behind match */ | 4355 nfa_pim_T *pim, /* postponed look-behind match */ |
4353 int off) /* byte offset, when -1 go to next line */ | 4356 int off_arg) /* byte offset, when -1 go to next line */ |
4354 { | 4357 { |
4355 int subidx; | 4358 int subidx; |
4359 int off = off_arg; | |
4360 int add_here = FALSE; | |
4361 int listindex = 0; | |
4362 int k; | |
4363 int found = FALSE; | |
4356 nfa_thread_T *thread; | 4364 nfa_thread_T *thread; |
4357 struct multipos save_multipos; | 4365 struct multipos save_multipos; |
4358 int save_in_use; | 4366 int save_in_use; |
4359 char_u *save_ptr; | 4367 char_u *save_ptr; |
4360 int i; | 4368 int i; |
4362 regsubs_T *subs = subs_arg; | 4370 regsubs_T *subs = subs_arg; |
4363 static regsubs_T temp_subs; | 4371 static regsubs_T temp_subs; |
4364 #ifdef ENABLE_LOG | 4372 #ifdef ENABLE_LOG |
4365 int did_print = FALSE; | 4373 int did_print = FALSE; |
4366 #endif | 4374 #endif |
4375 | |
4376 if (off_arg <= -ADDSTATE_HERE_OFFSET) | |
4377 { | |
4378 add_here = TRUE; | |
4379 off = 0; | |
4380 listindex = -(off_arg + ADDSTATE_HERE_OFFSET); | |
4381 } | |
4367 | 4382 |
4368 switch (state->c) | 4383 switch (state->c) |
4369 { | 4384 { |
4370 case NFA_NCLOSE: | 4385 case NFA_NCLOSE: |
4371 case NFA_MCLOSE: | 4386 case NFA_MCLOSE: |
4446 * when there is a PIM. For NFA_MATCH check the position, | 4461 * when there is a PIM. For NFA_MATCH check the position, |
4447 * lower position is preferred. */ | 4462 * lower position is preferred. */ |
4448 if (!nfa_has_backref && pim == NULL && !l->has_pim | 4463 if (!nfa_has_backref && pim == NULL && !l->has_pim |
4449 && state->c != NFA_MATCH) | 4464 && state->c != NFA_MATCH) |
4450 { | 4465 { |
4466 /* When called from addstate_here() do insert before | |
4467 * existing states. */ | |
4468 if (add_here) | |
4469 { | |
4470 for (k = 0; k < l->n && k < listindex; ++k) | |
4471 if (l->t[k].state->id == state->id) | |
4472 { | |
4473 found = TRUE; | |
4474 break; | |
4475 } | |
4476 } | |
4477 if (!add_here || found) | |
4478 { | |
4451 skip_add: | 4479 skip_add: |
4452 #ifdef ENABLE_LOG | 4480 #ifdef ENABLE_LOG |
4453 nfa_set_code(state->c); | 4481 nfa_set_code(state->c); |
4454 fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s\n", | 4482 fprintf(log_fd, "> Not adding state %d to list %d. char %d: %s pim: %s has_pim: %d found: %d\n", |
4455 abs(state->id), l->id, state->c, code); | 4483 abs(state->id), l->id, state->c, code, |
4456 #endif | 4484 pim == NULL ? "NULL" : "yes", l->has_pim, found); |
4457 return subs; | 4485 #endif |
4486 return subs; | |
4487 } | |
4458 } | 4488 } |
4459 | 4489 |
4460 /* Do not add the state again when it exists with the same | 4490 /* Do not add the state again when it exists with the same |
4461 * positions. */ | 4491 * positions. */ |
4462 if (has_state_with_pos(l, state, subs, pim)) | 4492 if (has_state_with_pos(l, state, subs, pim)) |
4517 case NFA_MATCH: | 4547 case NFA_MATCH: |
4518 break; | 4548 break; |
4519 | 4549 |
4520 case NFA_SPLIT: | 4550 case NFA_SPLIT: |
4521 /* order matters here */ | 4551 /* order matters here */ |
4522 subs = addstate(l, state->out, subs, pim, off); | 4552 subs = addstate(l, state->out, subs, pim, off_arg); |
4523 subs = addstate(l, state->out1, subs, pim, off); | 4553 subs = addstate(l, state->out1, subs, pim, off_arg); |
4524 break; | 4554 break; |
4525 | 4555 |
4526 case NFA_EMPTY: | 4556 case NFA_EMPTY: |
4527 case NFA_NOPEN: | 4557 case NFA_NOPEN: |
4528 case NFA_NCLOSE: | 4558 case NFA_NCLOSE: |
4529 subs = addstate(l, state->out, subs, pim, off); | 4559 subs = addstate(l, state->out, subs, pim, off_arg); |
4530 break; | 4560 break; |
4531 | 4561 |
4532 case NFA_MOPEN: | 4562 case NFA_MOPEN: |
4533 case NFA_MOPEN1: | 4563 case NFA_MOPEN1: |
4534 case NFA_MOPEN2: | 4564 case NFA_MOPEN2: |
4624 sub->in_use = subidx + 1; | 4654 sub->in_use = subidx + 1; |
4625 } | 4655 } |
4626 sub->list.line[subidx].start = reginput + off; | 4656 sub->list.line[subidx].start = reginput + off; |
4627 } | 4657 } |
4628 | 4658 |
4629 subs = addstate(l, state->out, subs, pim, off); | 4659 subs = addstate(l, state->out, subs, pim, off_arg); |
4630 /* "subs" may have changed, need to set "sub" again */ | 4660 /* "subs" may have changed, need to set "sub" again */ |
4631 #ifdef FEAT_SYN_HL | 4661 #ifdef FEAT_SYN_HL |
4632 if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) | 4662 if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9) |
4633 sub = &subs->synt; | 4663 sub = &subs->synt; |
4634 else | 4664 else |
4650 if (nfa_has_zend && (REG_MULTI | 4680 if (nfa_has_zend && (REG_MULTI |
4651 ? subs->norm.list.multi[0].end_lnum >= 0 | 4681 ? subs->norm.list.multi[0].end_lnum >= 0 |
4652 : subs->norm.list.line[0].end != NULL)) | 4682 : subs->norm.list.line[0].end != NULL)) |
4653 { | 4683 { |
4654 /* Do not overwrite the position set by \ze. */ | 4684 /* Do not overwrite the position set by \ze. */ |
4655 subs = addstate(l, state->out, subs, pim, off); | 4685 subs = addstate(l, state->out, subs, pim, off_arg); |
4656 break; | 4686 break; |
4657 } | 4687 } |
4658 case NFA_MCLOSE1: | 4688 case NFA_MCLOSE1: |
4659 case NFA_MCLOSE2: | 4689 case NFA_MCLOSE2: |
4660 case NFA_MCLOSE3: | 4690 case NFA_MCLOSE3: |
4723 sub->list.line[subidx].end = reginput + off; | 4753 sub->list.line[subidx].end = reginput + off; |
4724 /* avoid compiler warnings */ | 4754 /* avoid compiler warnings */ |
4725 vim_memset(&save_multipos, 0, sizeof(save_multipos)); | 4755 vim_memset(&save_multipos, 0, sizeof(save_multipos)); |
4726 } | 4756 } |
4727 | 4757 |
4728 subs = addstate(l, state->out, subs, pim, off); | 4758 subs = addstate(l, state->out, subs, pim, off_arg); |
4729 /* "subs" may have changed, need to set "sub" again */ | 4759 /* "subs" may have changed, need to set "sub" again */ |
4730 #ifdef FEAT_SYN_HL | 4760 #ifdef FEAT_SYN_HL |
4731 if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) | 4761 if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) |
4732 sub = &subs->synt; | 4762 sub = &subs->synt; |
4733 else | 4763 else |
4760 { | 4790 { |
4761 int tlen = l->n; | 4791 int tlen = l->n; |
4762 int count; | 4792 int count; |
4763 int listidx = *ip; | 4793 int listidx = *ip; |
4764 | 4794 |
4765 /* first add the state(s) at the end, so that we know how many there are */ | 4795 /* First add the state(s) at the end, so that we know how many there are. |
4766 addstate(l, state, subs, pim, 0); | 4796 * Pass the listidx as offset (avoids adding another argument to |
4797 * addstate(). */ | |
4798 addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET); | |
4767 | 4799 |
4768 /* when "*ip" was at the end of the list, nothing to do */ | 4800 /* when "*ip" was at the end of the list, nothing to do */ |
4769 if (listidx + 1 == tlen) | 4801 if (listidx + 1 == tlen) |
4770 return; | 4802 return; |
4771 | 4803 |