diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2016-10-23 02:50:48 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2016-10-23 02:50:48 -0700 |
commit | 394bdb8f2317e312d39e071b588581802dd3027a (patch) | |
tree | 159fc5496fbecff8760a3c434e82f95f67e99e61 /src/regex.c | |
parent | 46288dd6321e2ff4028781383660786050933304 (diff) | |
parent | 50fa7d64d36c3f2d6ab11e7136575fbca7012cae (diff) | |
download | emacs-394bdb8f2317e312d39e071b588581802dd3027a.tar.gz |
Merge from origin/emacs-25
50fa7d6 ;* src/w32heap.c: Fix typo and wording of the comments.
6f1325e electric-quote mode no longer worries about coding
c2a1792 * src/regex.c (re_search_2): Make new code safe for -Wjump-mi...
f6134bb Port to GCC 6.2.1 + --enable-gcc-warnings
b2ba630 Explain how to debug emacsclient lisp errors
9da53e2 Let describe-function work for lambda again
5c2da93 Fix kill-line's docstring
ad66b3f Fix handling of allocation in regex matching
5a26c9b * lisp/electric.el (electric-quote-mode): Improve doc (Bug#24...
3877c91 vc-region-history: Search just on lines intersecting the region
8988327 Fix documentation of 'alist-get'
b6998ea * src/regex.h (re_match_object): Improve commentary.
# Conflicts:
# etc/NEWS
# lisp/help-fns.el
Diffstat (limited to 'src/regex.c')
-rw-r--r-- | src/regex.c | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/src/regex.c b/src/regex.c index 1917a8480ae..8bc830356d0 100644 --- a/src/regex.c +++ b/src/regex.c @@ -153,6 +153,8 @@ /* Converts the pointer to the char to BEG-based offset from the start. */ # define PTR_TO_OFFSET(d) POS_AS_IN_BUFFER (POINTER_TO_OFFSET (d)) +/* Strings are 0-indexed, buffers are 1-indexed; we pun on the boolean + result to get the right base index. */ # define POS_AS_IN_BUFFER(p) ((p) + (NILP (re_match_object) || BUFFERP (re_match_object))) # define RE_MULTIBYTE_P(bufp) ((bufp)->multibyte) @@ -1363,11 +1365,62 @@ typedef struct #define NEXT_FAILURE_HANDLE(h) fail_stack.stack[(h) - 3].integer #define TOP_FAILURE_HANDLE() fail_stack.frame +#ifdef emacs +# define STR_BASE_PTR(obj) \ + (NILP (obj) ? current_buffer->text->beg \ + : STRINGP (obj) ? SDATA (obj) \ + : NULL) +#else +# define STR_BASE_PTR(obj) NULL +#endif #define ENSURE_FAIL_STACK(space) \ while (REMAINING_AVAIL_SLOTS <= space) { \ + re_char *orig_base = STR_BASE_PTR (re_match_object); \ + bool might_relocate = orig_base != NULL; \ + ptrdiff_t string1_off, end1_off, end_match_1_off; \ + ptrdiff_t string2_off, end2_off, end_match_2_off; \ + ptrdiff_t d_off, dend_off, dfail_off; \ + if (might_relocate) \ + { \ + if (string1) \ + { \ + string1_off = string1 - orig_base; \ + end1_off = end1 - orig_base; \ + end_match_1_off = end_match_1 - orig_base; \ + } \ + if (string2) \ + { \ + string2_off = string2 - orig_base; \ + end2_off = end2 - orig_base; \ + end_match_2_off = end_match_2 - orig_base; \ + } \ + d_off = d - orig_base; \ + dend_off = dend - orig_base; \ + dfail_off = dfail - orig_base; \ + } \ if (!GROW_FAIL_STACK (fail_stack)) \ return -2; \ + /* In Emacs, GROW_FAIL_STACK might relocate string pointers. */ \ + if (might_relocate) \ + { \ + re_char *new_base = STR_BASE_PTR (re_match_object); \ + if (string1) \ + { \ + string1 = new_base + string1_off; \ + end1 = new_base + end1_off; \ + end_match_1 = new_base + end_match_1_off; \ + } \ + if (string2) \ + { \ + string2 = new_base + string2_off; \ + end2 = new_base + end2_off; \ + end_match_2 = new_base + end_match_2_off; \ + } \ + d = new_base + d_off; \ + dend = new_base + dend_off; \ + dfail = new_base + dfail_off; \ + } \ DEBUG_PRINT ("\n Doubled stack; size now: %zd\n", (fail_stack).size);\ DEBUG_PRINT (" slots available: %zd\n", REMAINING_AVAIL_SLOTS);\ } @@ -4293,6 +4346,10 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, /* Loop through the string, looking for a place to start matching. */ for (;;) { + ptrdiff_t offset1, offset2; + re_char *orig_base; + bool might_relocate; + /* If the pattern is anchored, skip quickly past places we cannot match. We don't bother to treat startpos == 0 specially @@ -4409,6 +4466,17 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, && !bufp->can_be_null) return -1; + /* re_match_2_internal may allocate, relocating the Lisp text + object that we're searching. */ + IF_LINT (offset2 = 0); /* Work around GCC bug 78081. */ + orig_base = STR_BASE_PTR (re_match_object); + might_relocate = orig_base != NULL; + if (might_relocate) + { + if (string1) offset1 = string1 - orig_base; + if (string2) offset2 = string2 - orig_base; + } + val = re_match_2_internal (bufp, string1, size1, string2, size2, startpos, regs, stop); @@ -4418,6 +4486,13 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, if (val == -2) return -2; + if (might_relocate) + { + re_char *new_base = STR_BASE_PTR (re_match_object); + if (string1) string1 = offset1 + new_base; + if (string2) string2 = offset2 + new_base; + } + advance: if (!range) break; @@ -4905,8 +4980,8 @@ WEAK_ALIAS (__re_match, re_match) #endif /* not emacs */ #ifdef emacs -/* In Emacs, this is the string or buffer in which we - are matching. It is used for looking up syntax properties. */ +/* In Emacs, this is the string or buffer in which we are matching. + See the declaration in regex.h for details. */ Lisp_Object re_match_object; #endif |