diff options
| author | Paul Eggert | 2016-10-23 02:50:48 -0700 |
|---|---|---|
| committer | Paul Eggert | 2016-10-23 02:50:48 -0700 |
| commit | 394bdb8f2317e312d39e071b588581802dd3027a (patch) | |
| tree | 159fc5496fbecff8760a3c434e82f95f67e99e61 | |
| parent | 46288dd6321e2ff4028781383660786050933304 (diff) | |
| parent | 50fa7d64d36c3f2d6ab11e7136575fbca7012cae (diff) | |
| download | emacs-394bdb8f2317e312d39e071b588581802dd3027a.tar.gz emacs-394bdb8f2317e312d39e071b588581802dd3027a.zip | |
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
| -rw-r--r-- | doc/emacs/text.texi | 4 | ||||
| -rw-r--r-- | doc/lispref/debugging.texi | 7 | ||||
| -rw-r--r-- | doc/lispref/lists.texi | 10 | ||||
| -rw-r--r-- | lisp/electric.el | 18 | ||||
| -rw-r--r-- | lisp/help-fns.el | 33 | ||||
| -rw-r--r-- | lisp/simple.el | 4 | ||||
| -rw-r--r-- | lisp/vc/vc.el | 2 | ||||
| -rw-r--r-- | src/dired.c | 4 | ||||
| -rw-r--r-- | src/regex.c | 79 | ||||
| -rw-r--r-- | src/regex.h | 10 | ||||
| -rw-r--r-- | src/search.c | 36 | ||||
| -rw-r--r-- | src/w32heap.c | 14 |
12 files changed, 156 insertions, 65 deletions
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi index 579f7880cfe..7fa0804d270 100644 --- a/doc/emacs/text.texi +++ b/doc/emacs/text.texi | |||
| @@ -422,9 +422,7 @@ portable; curved quotes are less ambiguous and typically look nicer. | |||
| 422 | 422 | ||
| 423 | Electric Quote mode makes it easier to type curved quotes. As you | 423 | Electric Quote mode makes it easier to type curved quotes. As you |
| 424 | type characters it optionally converts @t{`} to @t{‘}, @t{'} to @t{’}, | 424 | type characters it optionally converts @t{`} to @t{‘}, @t{'} to @t{’}, |
| 425 | @t{``} to @t{“}, and @t{''} to @t{”}. These conversions are | 425 | @t{``} to @t{“}, and @t{''} to @t{”}. |
| 426 | suppressed in buffers whose coding systems cannot represent curved | ||
| 427 | quote characters. | ||
| 428 | 426 | ||
| 429 | @vindex electric-quote-paragraph | 427 | @vindex electric-quote-paragraph |
| 430 | @vindex electric-quote-comment | 428 | @vindex electric-quote-comment |
diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi index 5ff95827d27..6c0908acccb 100644 --- a/doc/lispref/debugging.texi +++ b/doc/lispref/debugging.texi | |||
| @@ -152,6 +152,13 @@ presence of @code{condition-case}. (To invoke the debugger, the error | |||
| 152 | must still fulfill the criteria specified by @code{debug-on-error} and | 152 | must still fulfill the criteria specified by @code{debug-on-error} and |
| 153 | @code{debug-ignored-errors}.) | 153 | @code{debug-ignored-errors}.) |
| 154 | 154 | ||
| 155 | @cindex emacsclient, getting a backtrace | ||
| 156 | @cindex backtrace from emacsclient's @option{--eval} | ||
| 157 | For example, setting this variable is useful to get a backtrace from | ||
| 158 | code evaluated by emacsclient's @option{--eval} option. If Lisp code | ||
| 159 | evaluated by emacsclient signals an error while this variable is | ||
| 160 | non-@code{nil}, the backtrace will popup in the running Emacs. | ||
| 161 | |||
| 155 | @strong{Warning:} Setting this variable to non-@code{nil} may have | 162 | @strong{Warning:} Setting this variable to non-@code{nil} may have |
| 156 | annoying effects. Various parts of Emacs catch errors in the normal | 163 | annoying effects. Various parts of Emacs catch errors in the normal |
| 157 | course of affairs, and you may not even realize that errors happen | 164 | course of affairs, and you may not even realize that errors happen |
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi index e7a739f88f3..dc4075dbab4 100644 --- a/doc/lispref/lists.texi +++ b/doc/lispref/lists.texi | |||
| @@ -1556,15 +1556,15 @@ keys may not be symbols: | |||
| 1556 | @end smallexample | 1556 | @end smallexample |
| 1557 | @end defun | 1557 | @end defun |
| 1558 | 1558 | ||
| 1559 | @defun alist-get key value &optional default remove | 1559 | @defun alist-get key alist &optional default remove |
| 1560 | This function is like @code{assq}, but instead of returning the entire | 1560 | This function is like @code{assq}, but instead of returning the entire |
| 1561 | association for @var{key}, @code{(@var{key} . @var{value})}, it | 1561 | association for @var{key} in @var{alist}, |
| 1562 | returns just the @var{value}. If @var{key} is not found in | 1562 | @w{@code{(@var{key} . @var{value})}}, it returns just the @var{value}. |
| 1563 | @var{alist} it returns @var{default}. | 1563 | If @var{key} is not found in @var{alist}, it returns @var{default}. |
| 1564 | 1564 | ||
| 1565 | This is a generalized variable (@pxref{Generalized Variables}) that | 1565 | This is a generalized variable (@pxref{Generalized Variables}) that |
| 1566 | can be used to change a value with @code{setf}. When using it to set | 1566 | can be used to change a value with @code{setf}. When using it to set |
| 1567 | a value, optional argument @var{remove} non-nil means to remove | 1567 | a value, optional argument @var{remove} non-@code{nil} means to remove |
| 1568 | @var{key} from @var{alist} if the new value is @code{eql} to @var{default}. | 1568 | @var{key} from @var{alist} if the new value is @code{eql} to @var{default}. |
| 1569 | @end defun | 1569 | @end defun |
| 1570 | 1570 | ||
diff --git a/lisp/electric.el b/lisp/electric.el index 0ec0a1efba1..f35f8b99db3 100644 --- a/lisp/electric.el +++ b/lisp/electric.el | |||
| @@ -430,12 +430,6 @@ The variable `electric-layout-rules' says when and how to insert newlines." | |||
| 430 | :version "25.1" | 430 | :version "25.1" |
| 431 | :type 'boolean :safe 'booleanp :group 'electricity) | 431 | :type 'boolean :safe 'booleanp :group 'electricity) |
| 432 | 432 | ||
| 433 | (defun electric--insertable-p (string) | ||
| 434 | (or (not buffer-file-coding-system) | ||
| 435 | (eq (coding-system-base buffer-file-coding-system) 'undecided) | ||
| 436 | (not (unencodable-char-position nil nil buffer-file-coding-system | ||
| 437 | nil string)))) | ||
| 438 | |||
| 439 | (defun electric-quote-post-self-insert-function () | 433 | (defun electric-quote-post-self-insert-function () |
| 440 | "Function that `electric-quote-mode' adds to `post-self-insert-hook'. | 434 | "Function that `electric-quote-mode' adds to `post-self-insert-hook'. |
| 441 | This requotes when a quoting key is typed." | 435 | This requotes when a quoting key is typed." |
| @@ -460,8 +454,7 @@ This requotes when a quoting key is typed." | |||
| 460 | (when start | 454 | (when start |
| 461 | (save-excursion | 455 | (save-excursion |
| 462 | (if (eq last-command-event ?\`) | 456 | (if (eq last-command-event ?\`) |
| 463 | (cond ((and (electric--insertable-p "“") | 457 | (cond ((search-backward "‘`" (- (point) 2) t) |
| 464 | (search-backward "‘`" (- (point) 2) t)) | ||
| 465 | (replace-match "“") | 458 | (replace-match "“") |
| 466 | (when (and electric-pair-mode | 459 | (when (and electric-pair-mode |
| 467 | (eq (cdr-safe | 460 | (eq (cdr-safe |
| @@ -469,16 +462,13 @@ This requotes when a quoting key is typed." | |||
| 469 | (char-after))) | 462 | (char-after))) |
| 470 | (delete-char 1)) | 463 | (delete-char 1)) |
| 471 | (setq last-command-event ?“)) | 464 | (setq last-command-event ?“)) |
| 472 | ((and (electric--insertable-p "‘") | 465 | ((search-backward "`" (1- (point)) t) |
| 473 | (search-backward "`" (1- (point)) t)) | ||
| 474 | (replace-match "‘") | 466 | (replace-match "‘") |
| 475 | (setq last-command-event ?‘))) | 467 | (setq last-command-event ?‘))) |
| 476 | (cond ((and (electric--insertable-p "”") | 468 | (cond ((search-backward "’'" (- (point) 2) t) |
| 477 | (search-backward "’'" (- (point) 2) t)) | ||
| 478 | (replace-match "”") | 469 | (replace-match "”") |
| 479 | (setq last-command-event ?”)) | 470 | (setq last-command-event ?”)) |
| 480 | ((and (electric--insertable-p "’") | 471 | ((search-backward "'" (1- (point)) t) |
| 481 | (search-backward "'" (1- (point)) t)) | ||
| 482 | (replace-match "’") | 472 | (replace-match "’") |
| 483 | (setq last-command-event ?’))))))))) | 473 | (setq last-command-event ?’))))))))) |
| 484 | 474 | ||
diff --git a/lisp/help-fns.el b/lisp/help-fns.el index e4e23330e37..87e7d8f87bb 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el | |||
| @@ -106,23 +106,24 @@ to get buffer-local values.") | |||
| 106 | 106 | ||
| 107 | ;;;###autoload | 107 | ;;;###autoload |
| 108 | (defun describe-function (function) | 108 | (defun describe-function (function) |
| 109 | "Display the full documentation of FUNCTION (a symbol)." | 109 | "Display the full documentation of FUNCTION (a symbol). |
| 110 | When called from lisp, FUNCTION may also be a function object." | ||
| 110 | (interactive | 111 | (interactive |
| 111 | (let ((fn (function-called-at-point)) | 112 | (let* ((fn (function-called-at-point)) |
| 112 | (enable-recursive-minibuffers t) | 113 | (enable-recursive-minibuffers t) |
| 113 | val) | 114 | (val (completing-read |
| 114 | (setq val (completing-read (if fn | 115 | (if fn |
| 115 | (format "Describe function (default %s): " fn) | 116 | (format "Describe function (default %s): " fn) |
| 116 | "Describe function: ") | 117 | "Describe function: ") |
| 117 | #'help--symbol-completion-table | 118 | #'help--symbol-completion-table #'fboundp t nil nil |
| 118 | #'fboundp | 119 | (and fn (symbol-name fn))))) |
| 119 | t nil nil (and fn (symbol-name fn)))) | 120 | (unless (equal val "") |
| 120 | (list (if (equal val "") | 121 | (setq fn (intern val))) |
| 121 | fn (intern val))))) | 122 | (unless (and fn (symbolp fn)) |
| 122 | (or (and function (symbolp function)) | 123 | (user-error "You didn't specify a function symbol")) |
| 123 | (user-error "You didn't specify a function symbol")) | 124 | (unless (fboundp fn) |
| 124 | (or (fboundp function) | 125 | (user-error "Symbol's function definition is void: %s" fn)) |
| 125 | (user-error "Symbol's function definition is void: %s" function)) | 126 | (list fn))) |
| 126 | 127 | ||
| 127 | ;; We save describe-function-orig-buffer on the help xref stack, so | 128 | ;; We save describe-function-orig-buffer on the help xref stack, so |
| 128 | ;; it is restored by the back/forward buttons. 'help-buffer' | 129 | ;; it is restored by the back/forward buttons. 'help-buffer' |
diff --git a/lisp/simple.el b/lisp/simple.el index 70bd759edab..d915ee2eb63 100644 --- a/lisp/simple.el +++ b/lisp/simple.el | |||
| @@ -4957,8 +4957,8 @@ To kill a whole line, when point is not at the beginning, type \ | |||
| 4957 | \\[move-beginning-of-line] \\[kill-line] \\[kill-line]. | 4957 | \\[move-beginning-of-line] \\[kill-line] \\[kill-line]. |
| 4958 | 4958 | ||
| 4959 | If `show-trailing-whitespace' is non-nil, this command will just | 4959 | If `show-trailing-whitespace' is non-nil, this command will just |
| 4960 | kill the rest of the current line, even if there are only | 4960 | kill the rest of the current line, even if there are no nonblanks |
| 4961 | nonblanks there. | 4961 | there. |
| 4962 | 4962 | ||
| 4963 | If option `kill-whole-line' is non-nil, then this command kills the whole line | 4963 | If option `kill-whole-line' is non-nil, then this command kills the whole line |
| 4964 | including its terminating newline, when used at the beginning of a line | 4964 | including its terminating newline, when used at the beginning of a line |
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index af875e89907..ac020d09539 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el | |||
| @@ -2393,7 +2393,7 @@ When called interactively with a prefix argument, prompt for REMOTE-LOCATION." | |||
| 2393 | "Show the history of the region FROM..TO." | 2393 | "Show the history of the region FROM..TO." |
| 2394 | (interactive "r") | 2394 | (interactive "r") |
| 2395 | (let* ((lfrom (line-number-at-pos from)) | 2395 | (let* ((lfrom (line-number-at-pos from)) |
| 2396 | (lto (line-number-at-pos to)) | 2396 | (lto (line-number-at-pos (1- to))) |
| 2397 | (file buffer-file-name) | 2397 | (file buffer-file-name) |
| 2398 | (backend (vc-backend file)) | 2398 | (backend (vc-backend file)) |
| 2399 | (buf (get-buffer-create "*VC-history*"))) | 2399 | (buf (get-buffer-create "*VC-history*"))) |
diff --git a/src/dired.c b/src/dired.c index e468147e8b2..c69164b2a1f 100644 --- a/src/dired.c +++ b/src/dired.c | |||
| @@ -253,9 +253,11 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, | |||
| 253 | QUIT; | 253 | QUIT; |
| 254 | 254 | ||
| 255 | bool wanted = (NILP (match) | 255 | bool wanted = (NILP (match) |
| 256 | || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0); | 256 | || (re_match_object = name, |
| 257 | re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0)); | ||
| 257 | 258 | ||
| 258 | immediate_quit = 0; | 259 | immediate_quit = 0; |
| 260 | re_match_object = Qnil; /* Stop protecting name from GC. */ | ||
| 259 | 261 | ||
| 260 | if (wanted) | 262 | if (wanted) |
| 261 | { | 263 | { |
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 @@ | |||
| 153 | 153 | ||
| 154 | /* Converts the pointer to the char to BEG-based offset from the start. */ | 154 | /* Converts the pointer to the char to BEG-based offset from the start. */ |
| 155 | # define PTR_TO_OFFSET(d) POS_AS_IN_BUFFER (POINTER_TO_OFFSET (d)) | 155 | # define PTR_TO_OFFSET(d) POS_AS_IN_BUFFER (POINTER_TO_OFFSET (d)) |
| 156 | /* Strings are 0-indexed, buffers are 1-indexed; we pun on the boolean | ||
| 157 | result to get the right base index. */ | ||
| 156 | # define POS_AS_IN_BUFFER(p) ((p) + (NILP (re_match_object) || BUFFERP (re_match_object))) | 158 | # define POS_AS_IN_BUFFER(p) ((p) + (NILP (re_match_object) || BUFFERP (re_match_object))) |
| 157 | 159 | ||
| 158 | # define RE_MULTIBYTE_P(bufp) ((bufp)->multibyte) | 160 | # define RE_MULTIBYTE_P(bufp) ((bufp)->multibyte) |
| @@ -1363,11 +1365,62 @@ typedef struct | |||
| 1363 | #define NEXT_FAILURE_HANDLE(h) fail_stack.stack[(h) - 3].integer | 1365 | #define NEXT_FAILURE_HANDLE(h) fail_stack.stack[(h) - 3].integer |
| 1364 | #define TOP_FAILURE_HANDLE() fail_stack.frame | 1366 | #define TOP_FAILURE_HANDLE() fail_stack.frame |
| 1365 | 1367 | ||
| 1368 | #ifdef emacs | ||
| 1369 | # define STR_BASE_PTR(obj) \ | ||
| 1370 | (NILP (obj) ? current_buffer->text->beg \ | ||
| 1371 | : STRINGP (obj) ? SDATA (obj) \ | ||
| 1372 | : NULL) | ||
| 1373 | #else | ||
| 1374 | # define STR_BASE_PTR(obj) NULL | ||
| 1375 | #endif | ||
| 1366 | 1376 | ||
| 1367 | #define ENSURE_FAIL_STACK(space) \ | 1377 | #define ENSURE_FAIL_STACK(space) \ |
| 1368 | while (REMAINING_AVAIL_SLOTS <= space) { \ | 1378 | while (REMAINING_AVAIL_SLOTS <= space) { \ |
| 1379 | re_char *orig_base = STR_BASE_PTR (re_match_object); \ | ||
| 1380 | bool might_relocate = orig_base != NULL; \ | ||
| 1381 | ptrdiff_t string1_off, end1_off, end_match_1_off; \ | ||
| 1382 | ptrdiff_t string2_off, end2_off, end_match_2_off; \ | ||
| 1383 | ptrdiff_t d_off, dend_off, dfail_off; \ | ||
| 1384 | if (might_relocate) \ | ||
| 1385 | { \ | ||
| 1386 | if (string1) \ | ||
| 1387 | { \ | ||
| 1388 | string1_off = string1 - orig_base; \ | ||
| 1389 | end1_off = end1 - orig_base; \ | ||
| 1390 | end_match_1_off = end_match_1 - orig_base; \ | ||
| 1391 | } \ | ||
| 1392 | if (string2) \ | ||
| 1393 | { \ | ||
| 1394 | string2_off = string2 - orig_base; \ | ||
| 1395 | end2_off = end2 - orig_base; \ | ||
| 1396 | end_match_2_off = end_match_2 - orig_base; \ | ||
| 1397 | } \ | ||
| 1398 | d_off = d - orig_base; \ | ||
| 1399 | dend_off = dend - orig_base; \ | ||
| 1400 | dfail_off = dfail - orig_base; \ | ||
| 1401 | } \ | ||
| 1369 | if (!GROW_FAIL_STACK (fail_stack)) \ | 1402 | if (!GROW_FAIL_STACK (fail_stack)) \ |
| 1370 | return -2; \ | 1403 | return -2; \ |
| 1404 | /* In Emacs, GROW_FAIL_STACK might relocate string pointers. */ \ | ||
| 1405 | if (might_relocate) \ | ||
| 1406 | { \ | ||
| 1407 | re_char *new_base = STR_BASE_PTR (re_match_object); \ | ||
| 1408 | if (string1) \ | ||
| 1409 | { \ | ||
| 1410 | string1 = new_base + string1_off; \ | ||
| 1411 | end1 = new_base + end1_off; \ | ||
| 1412 | end_match_1 = new_base + end_match_1_off; \ | ||
| 1413 | } \ | ||
| 1414 | if (string2) \ | ||
| 1415 | { \ | ||
| 1416 | string2 = new_base + string2_off; \ | ||
| 1417 | end2 = new_base + end2_off; \ | ||
| 1418 | end_match_2 = new_base + end_match_2_off; \ | ||
| 1419 | } \ | ||
| 1420 | d = new_base + d_off; \ | ||
| 1421 | dend = new_base + dend_off; \ | ||
| 1422 | dfail = new_base + dfail_off; \ | ||
| 1423 | } \ | ||
| 1371 | DEBUG_PRINT ("\n Doubled stack; size now: %zd\n", (fail_stack).size);\ | 1424 | DEBUG_PRINT ("\n Doubled stack; size now: %zd\n", (fail_stack).size);\ |
| 1372 | DEBUG_PRINT (" slots available: %zd\n", REMAINING_AVAIL_SLOTS);\ | 1425 | DEBUG_PRINT (" slots available: %zd\n", REMAINING_AVAIL_SLOTS);\ |
| 1373 | } | 1426 | } |
| @@ -4293,6 +4346,10 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, | |||
| 4293 | /* Loop through the string, looking for a place to start matching. */ | 4346 | /* Loop through the string, looking for a place to start matching. */ |
| 4294 | for (;;) | 4347 | for (;;) |
| 4295 | { | 4348 | { |
| 4349 | ptrdiff_t offset1, offset2; | ||
| 4350 | re_char *orig_base; | ||
| 4351 | bool might_relocate; | ||
| 4352 | |||
| 4296 | /* If the pattern is anchored, | 4353 | /* If the pattern is anchored, |
| 4297 | skip quickly past places we cannot match. | 4354 | skip quickly past places we cannot match. |
| 4298 | We don't bother to treat startpos == 0 specially | 4355 | 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, | |||
| 4409 | && !bufp->can_be_null) | 4466 | && !bufp->can_be_null) |
| 4410 | return -1; | 4467 | return -1; |
| 4411 | 4468 | ||
| 4469 | /* re_match_2_internal may allocate, relocating the Lisp text | ||
| 4470 | object that we're searching. */ | ||
| 4471 | IF_LINT (offset2 = 0); /* Work around GCC bug 78081. */ | ||
| 4472 | orig_base = STR_BASE_PTR (re_match_object); | ||
| 4473 | might_relocate = orig_base != NULL; | ||
| 4474 | if (might_relocate) | ||
| 4475 | { | ||
| 4476 | if (string1) offset1 = string1 - orig_base; | ||
| 4477 | if (string2) offset2 = string2 - orig_base; | ||
| 4478 | } | ||
| 4479 | |||
| 4412 | val = re_match_2_internal (bufp, string1, size1, string2, size2, | 4480 | val = re_match_2_internal (bufp, string1, size1, string2, size2, |
| 4413 | startpos, regs, stop); | 4481 | startpos, regs, stop); |
| 4414 | 4482 | ||
| @@ -4418,6 +4486,13 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, | |||
| 4418 | if (val == -2) | 4486 | if (val == -2) |
| 4419 | return -2; | 4487 | return -2; |
| 4420 | 4488 | ||
| 4489 | if (might_relocate) | ||
| 4490 | { | ||
| 4491 | re_char *new_base = STR_BASE_PTR (re_match_object); | ||
| 4492 | if (string1) string1 = offset1 + new_base; | ||
| 4493 | if (string2) string2 = offset2 + new_base; | ||
| 4494 | } | ||
| 4495 | |||
| 4421 | advance: | 4496 | advance: |
| 4422 | if (!range) | 4497 | if (!range) |
| 4423 | break; | 4498 | break; |
| @@ -4905,8 +4980,8 @@ WEAK_ALIAS (__re_match, re_match) | |||
| 4905 | #endif /* not emacs */ | 4980 | #endif /* not emacs */ |
| 4906 | 4981 | ||
| 4907 | #ifdef emacs | 4982 | #ifdef emacs |
| 4908 | /* In Emacs, this is the string or buffer in which we | 4983 | /* In Emacs, this is the string or buffer in which we are matching. |
| 4909 | are matching. It is used for looking up syntax properties. */ | 4984 | See the declaration in regex.h for details. */ |
| 4910 | Lisp_Object re_match_object; | 4985 | Lisp_Object re_match_object; |
| 4911 | #endif | 4986 | #endif |
| 4912 | 4987 | ||
diff --git a/src/regex.h b/src/regex.h index b672d3fdef7..cb0796fe9cb 100644 --- a/src/regex.h +++ b/src/regex.h | |||
| @@ -175,8 +175,14 @@ extern reg_syntax_t re_syntax_options; | |||
| 175 | 175 | ||
| 176 | #ifdef emacs | 176 | #ifdef emacs |
| 177 | # include "lisp.h" | 177 | # include "lisp.h" |
| 178 | /* In Emacs, this is the string or buffer in which we | 178 | /* In Emacs, this is the string or buffer in which we are matching. |
| 179 | are matching. It is used for looking up syntax properties. */ | 179 | It is used for looking up syntax properties, and also to recompute |
| 180 | pointers in case the object is relocated as a side effect of | ||
| 181 | calling malloc (if it calls r_alloc_sbrk in ralloc.c). | ||
| 182 | |||
| 183 | If the value is a Lisp string object, we are matching text in that | ||
| 184 | string; if it's nil, we are matching text in the current buffer; if | ||
| 185 | it's t, we are matching text in a C string. */ | ||
| 180 | extern Lisp_Object re_match_object; | 186 | extern Lisp_Object re_match_object; |
| 181 | #endif | 187 | #endif |
| 182 | 188 | ||
diff --git a/src/search.c b/src/search.c index 9b8fc584120..bcb5ee95edb 100644 --- a/src/search.c +++ b/src/search.c | |||
| @@ -280,8 +280,10 @@ looking_at_1 (Lisp_Object string, bool posix) | |||
| 280 | immediate_quit = 1; | 280 | immediate_quit = 1; |
| 281 | QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ | 281 | QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ |
| 282 | 282 | ||
| 283 | /* Get pointers and sizes of the two strings | 283 | /* Get pointers and sizes of the two strings that make up the |
| 284 | that make up the visible portion of the buffer. */ | 284 | visible portion of the buffer. Note that we can use pointers |
| 285 | here, unlike in search_buffer, because we only call re_match_2 | ||
| 286 | once, after which we never use the pointers again. */ | ||
| 285 | 287 | ||
| 286 | p1 = BEGV_ADDR; | 288 | p1 = BEGV_ADDR; |
| 287 | s1 = GPT_BYTE - BEGV_BYTE; | 289 | s1 = GPT_BYTE - BEGV_BYTE; |
| @@ -400,6 +402,7 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, | |||
| 400 | (NILP (Vinhibit_changing_match_data) | 402 | (NILP (Vinhibit_changing_match_data) |
| 401 | ? &search_regs : NULL)); | 403 | ? &search_regs : NULL)); |
| 402 | immediate_quit = 0; | 404 | immediate_quit = 0; |
| 405 | re_match_object = Qnil; /* Stop protecting string from GC. */ | ||
| 403 | 406 | ||
| 404 | /* Set last_thing_searched only when match data is changed. */ | 407 | /* Set last_thing_searched only when match data is changed. */ |
| 405 | if (NILP (Vinhibit_changing_match_data)) | 408 | if (NILP (Vinhibit_changing_match_data)) |
| @@ -470,6 +473,7 @@ fast_string_match_internal (Lisp_Object regexp, Lisp_Object string, | |||
| 470 | SBYTES (string), 0, | 473 | SBYTES (string), 0, |
| 471 | SBYTES (string), 0); | 474 | SBYTES (string), 0); |
| 472 | immediate_quit = 0; | 475 | immediate_quit = 0; |
| 476 | re_match_object = Qnil; /* Stop protecting string from GC. */ | ||
| 473 | return val; | 477 | return val; |
| 474 | } | 478 | } |
| 475 | 479 | ||
| @@ -557,6 +561,7 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 557 | len = re_match_2 (buf, (char *) p1, s1, (char *) p2, s2, | 561 | len = re_match_2 (buf, (char *) p1, s1, (char *) p2, s2, |
| 558 | pos_byte, NULL, limit_byte); | 562 | pos_byte, NULL, limit_byte); |
| 559 | immediate_quit = 0; | 563 | immediate_quit = 0; |
| 564 | re_match_object = Qnil; /* Stop protecting string from GC. */ | ||
| 560 | 565 | ||
| 561 | return len; | 566 | return len; |
| 562 | } | 567 | } |
| @@ -1171,8 +1176,8 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1171 | 1176 | ||
| 1172 | if (RE && !(trivial_regexp_p (string) && NILP (Vsearch_spaces_regexp))) | 1177 | if (RE && !(trivial_regexp_p (string) && NILP (Vsearch_spaces_regexp))) |
| 1173 | { | 1178 | { |
| 1174 | unsigned char *p1, *p2; | 1179 | unsigned char *base; |
| 1175 | ptrdiff_t s1, s2; | 1180 | ptrdiff_t off1, off2, s1, s2; |
| 1176 | struct re_pattern_buffer *bufp; | 1181 | struct re_pattern_buffer *bufp; |
| 1177 | 1182 | ||
| 1178 | bufp = compile_pattern (string, | 1183 | bufp = compile_pattern (string, |
| @@ -1186,16 +1191,19 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1186 | can take too long. */ | 1191 | can take too long. */ |
| 1187 | QUIT; /* Do a pending quit right away, | 1192 | QUIT; /* Do a pending quit right away, |
| 1188 | to avoid paradoxical behavior */ | 1193 | to avoid paradoxical behavior */ |
| 1189 | /* Get pointers and sizes of the two strings | 1194 | /* Get offsets and sizes of the two strings that make up the |
| 1190 | that make up the visible portion of the buffer. */ | 1195 | visible portion of the buffer. We compute offsets instead of |
| 1196 | pointers because re_search_2 may call malloc and therefore | ||
| 1197 | change the buffer text address. */ | ||
| 1191 | 1198 | ||
| 1192 | p1 = BEGV_ADDR; | 1199 | base = current_buffer->text->beg; |
| 1200 | off1 = BEGV_ADDR - base; | ||
| 1193 | s1 = GPT_BYTE - BEGV_BYTE; | 1201 | s1 = GPT_BYTE - BEGV_BYTE; |
| 1194 | p2 = GAP_END_ADDR; | 1202 | off2 = GAP_END_ADDR - base; |
| 1195 | s2 = ZV_BYTE - GPT_BYTE; | 1203 | s2 = ZV_BYTE - GPT_BYTE; |
| 1196 | if (s1 < 0) | 1204 | if (s1 < 0) |
| 1197 | { | 1205 | { |
| 1198 | p2 = p1; | 1206 | off2 = off1; |
| 1199 | s2 = ZV_BYTE - BEGV_BYTE; | 1207 | s2 = ZV_BYTE - BEGV_BYTE; |
| 1200 | s1 = 0; | 1208 | s1 = 0; |
| 1201 | } | 1209 | } |
| @@ -1210,7 +1218,9 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1210 | { | 1218 | { |
| 1211 | ptrdiff_t val; | 1219 | ptrdiff_t val; |
| 1212 | 1220 | ||
| 1213 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, | 1221 | val = re_search_2 (bufp, |
| 1222 | (char*) (base + off1), s1, | ||
| 1223 | (char*) (base + off2), s2, | ||
| 1214 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | 1224 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, |
| 1215 | (NILP (Vinhibit_changing_match_data) | 1225 | (NILP (Vinhibit_changing_match_data) |
| 1216 | ? &search_regs : &search_regs_1), | 1226 | ? &search_regs : &search_regs_1), |
| @@ -1255,8 +1265,10 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, | |||
| 1255 | { | 1265 | { |
| 1256 | ptrdiff_t val; | 1266 | ptrdiff_t val; |
| 1257 | 1267 | ||
| 1258 | val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, | 1268 | val = re_search_2 (bufp, |
| 1259 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | 1269 | (char*) (base + off1), s1, |
| 1270 | (char*) (base + off2), s2, | ||
| 1271 | pos_byte - BEGV_BYTE, lim_byte - pos_byte, | ||
| 1260 | (NILP (Vinhibit_changing_match_data) | 1272 | (NILP (Vinhibit_changing_match_data) |
| 1261 | ? &search_regs : &search_regs_1), | 1273 | ? &search_regs : &search_regs_1), |
| 1262 | lim_byte - BEGV_BYTE); | 1274 | lim_byte - BEGV_BYTE); |
diff --git a/src/w32heap.c b/src/w32heap.c index 658a8a5d691..443472b4708 100644 --- a/src/w32heap.c +++ b/src/w32heap.c | |||
| @@ -129,18 +129,18 @@ static DWORD_PTR committed = 0; | |||
| 129 | /* The maximum block size that can be handled by a non-growable w32 | 129 | /* The maximum block size that can be handled by a non-growable w32 |
| 130 | heap is limited by the MaxBlockSize value below. | 130 | heap is limited by the MaxBlockSize value below. |
| 131 | 131 | ||
| 132 | This point deserves and explanation. | 132 | This point deserves an explanation. |
| 133 | 133 | ||
| 134 | The W32 heap allocator can be used for a growable | 134 | The W32 heap allocator can be used for a growable heap or a |
| 135 | heap or a non-growable one. | 135 | non-growable one. |
| 136 | 136 | ||
| 137 | A growable heap is not compatible with a fixed base address for the | 137 | A growable heap is not compatible with a fixed base address for the |
| 138 | heap. Only a non-growable one is. One drawback of non-growable | 138 | heap. Only a non-growable one is. One drawback of non-growable |
| 139 | heaps is that they can hold only objects smaller than a certain | 139 | heaps is that they can hold only objects smaller than a certain |
| 140 | size (the one defined below). Most of the largest blocks are GC'ed | 140 | size (the one defined below). Most of the larger blocks are GC'ed |
| 141 | before dumping. In any case and to be safe, we implement a simple | 141 | before dumping. In any case, and to be safe, we implement a simple |
| 142 | first-fit allocation algorithm starting at the end of the | 142 | first-fit allocation algorithm starting at the end of the |
| 143 | dumped_data[] array like depicted below: | 143 | dumped_data[] array as depicted below: |
| 144 | 144 | ||
| 145 | ---------------------------------------------- | 145 | ---------------------------------------------- |
| 146 | | | | | | 146 | | | | | |
| @@ -273,7 +273,7 @@ init_heap (void) | |||
| 273 | else | 273 | else |
| 274 | { | 274 | { |
| 275 | /* Find the RtlCreateHeap function. Headers for this function | 275 | /* Find the RtlCreateHeap function. Headers for this function |
| 276 | are provided with the w32 ddk, but the function is available | 276 | are provided with the w32 DDK, but the function is available |
| 277 | in ntdll.dll since XP. */ | 277 | in ntdll.dll since XP. */ |
| 278 | HMODULE hm_ntdll = LoadLibrary ("ntdll.dll"); | 278 | HMODULE hm_ntdll = LoadLibrary ("ntdll.dll"); |
| 279 | RtlCreateHeap_Proc s_pfn_Rtl_Create_Heap | 279 | RtlCreateHeap_Proc s_pfn_Rtl_Create_Heap |