diff options
| author | Stefan Monnier | 2000-04-19 21:39:18 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2000-04-19 21:39:18 +0000 |
| commit | 419d1c749d2b78cc18a50365cf976f4f276051f4 (patch) | |
| tree | 4f9490de603efe62c3355b6bf883096a60464a74 /src | |
| parent | 14583cb1e0905a2e3fdb88f9fef5ca20102c0c5a (diff) | |
| download | emacs-419d1c749d2b78cc18a50365cf976f4f276051f4.tar.gz emacs-419d1c749d2b78cc18a50365cf976f4f276051f4.zip | |
(re_match_2_internal): Don't shorten the strings anymore,
instead define end_match(1|2) more carefully.
Use GET_CHAR_BEFORE_2 for `begline'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/regex.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/src/regex.c b/src/regex.c index 9a56db728e5..3b4eb502596 100644 --- a/src/regex.c +++ b/src/regex.c | |||
| @@ -3933,7 +3933,9 @@ static int bcmp_translate _RE_ARGS((re_char *s1, re_char *s2, | |||
| 3933 | : ((regoff_t) ((ptr) - string2 + size1))) | 3933 | : ((regoff_t) ((ptr) - string2 + size1))) |
| 3934 | 3934 | ||
| 3935 | /* Call before fetching a character with *d. This switches over to | 3935 | /* Call before fetching a character with *d. This switches over to |
| 3936 | string2 if necessary. */ | 3936 | string2 if necessary. |
| 3937 | Check re_match_2_internal for a discussion of why end_match_2 might | ||
| 3938 | not be within string2 (but be equal to end_match_1 instead). */ | ||
| 3937 | #define PREFETCH() \ | 3939 | #define PREFETCH() \ |
| 3938 | while (d == dend) \ | 3940 | while (d == dend) \ |
| 3939 | { \ | 3941 | { \ |
| @@ -4463,15 +4465,6 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) | |||
| 4463 | for (mcnt = 1; mcnt < num_regs; mcnt++) | 4465 | for (mcnt = 1; mcnt < num_regs; mcnt++) |
| 4464 | regstart[mcnt] = regend[mcnt] = REG_UNSET_VALUE; | 4466 | regstart[mcnt] = regend[mcnt] = REG_UNSET_VALUE; |
| 4465 | 4467 | ||
| 4466 | /* Shorten strings to `stop'. */ | ||
| 4467 | if (stop <= size1) | ||
| 4468 | { | ||
| 4469 | size1 = stop; | ||
| 4470 | size2 = 0; | ||
| 4471 | } | ||
| 4472 | else if (stop <= size1 + size2) | ||
| 4473 | size2 = stop - size1; | ||
| 4474 | |||
| 4475 | /* We move `string1' into `string2' if the latter's empty -- but not if | 4468 | /* We move `string1' into `string2' if the latter's empty -- but not if |
| 4476 | `string1' is null. */ | 4469 | `string1' is null. */ |
| 4477 | if (size2 == 0 && string1 != NULL) | 4470 | if (size2 == 0 && string1 != NULL) |
| @@ -4484,25 +4477,42 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) | |||
| 4484 | end1 = string1 + size1; | 4477 | end1 = string1 + size1; |
| 4485 | end2 = string2 + size2; | 4478 | end2 = string2 + size2; |
| 4486 | 4479 | ||
| 4487 | /* Compute where to stop matching, within the two strings. */ | ||
| 4488 | end_match_1 = end1; | ||
| 4489 | end_match_2 = end2; | ||
| 4490 | |||
| 4491 | /* `p' scans through the pattern as `d' scans through the data. | 4480 | /* `p' scans through the pattern as `d' scans through the data. |
| 4492 | `dend' is the end of the input string that `d' points within. `d' | 4481 | `dend' is the end of the input string that `d' points within. `d' |
| 4493 | is advanced into the following input string whenever necessary, but | 4482 | is advanced into the following input string whenever necessary, but |
| 4494 | this happens before fetching; therefore, at the beginning of the | 4483 | this happens before fetching; therefore, at the beginning of the |
| 4495 | loop, `d' can be pointing at the end of a string, but it cannot | 4484 | loop, `d' can be pointing at the end of a string, but it cannot |
| 4496 | equal `string2'. */ | 4485 | equal `string2'. */ |
| 4497 | if (size1 > 0 && pos <= size1) | 4486 | if (pos >= size1) |
| 4498 | { | 4487 | { |
| 4499 | d = string1 + pos; | 4488 | /* Only match within string2. */ |
| 4500 | dend = end_match_1; | 4489 | d = string2 + pos - size1; |
| 4490 | dend = end_match_2 = string2 + stop - size1; | ||
| 4491 | end_match_1 = end1; /* Just to give it a value. */ | ||
| 4501 | } | 4492 | } |
| 4502 | else | 4493 | else |
| 4503 | { | 4494 | { |
| 4504 | d = string2 + pos - size1; | 4495 | if (stop <= size1) |
| 4505 | dend = end_match_2; | 4496 | { |
| 4497 | /* Only match within string1. */ | ||
| 4498 | end_match_1 = string1 + stop; | ||
| 4499 | /* BEWARE! | ||
| 4500 | When we reach end_match_1, PREFETCH normally switches to string2. | ||
| 4501 | But in the present case, this means that just doing a PREFETCH | ||
| 4502 | makes us jump from `stop' to `gap' within the string. | ||
| 4503 | What we really want here is for the search to stop as | ||
| 4504 | soon as we hit end_match_1. That's why we set end_match_2 | ||
| 4505 | to end_match_1 (since PREFETCH fails as soon as we hit | ||
| 4506 | end_match_2). */ | ||
| 4507 | end_match_2 = end_match_1; | ||
| 4508 | } | ||
| 4509 | else | ||
| 4510 | { | ||
| 4511 | end_match_1 = end1; | ||
| 4512 | end_match_2 = string2 + stop - size1; | ||
| 4513 | } | ||
| 4514 | d = string1 + pos; | ||
| 4515 | dend = end_match_1; | ||
| 4506 | } | 4516 | } |
| 4507 | 4517 | ||
| 4508 | DEBUG_PRINT1 ("The compiled pattern is: "); | 4518 | DEBUG_PRINT1 ("The compiled pattern is: "); |
| @@ -4980,9 +4990,12 @@ re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) | |||
| 4980 | { | 4990 | { |
| 4981 | if (!bufp->not_bol) break; | 4991 | if (!bufp->not_bol) break; |
| 4982 | } | 4992 | } |
| 4983 | else if (d[-1] == '\n' && bufp->newline_anchor) | 4993 | else |
| 4984 | { | 4994 | { |
| 4985 | break; | 4995 | unsigned char c; |
| 4996 | GET_CHAR_BEFORE_2 (c, d, string1, end1, string2, end2); | ||
| 4997 | if (c == '\n' && bufp->newline_anchor) | ||
| 4998 | break; | ||
| 4986 | } | 4999 | } |
| 4987 | /* In all other cases, we fail. */ | 5000 | /* In all other cases, we fail. */ |
| 4988 | goto fail; | 5001 | goto fail; |