From b6998eab37962357fda49a6a3b013c73228af187 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 19 Oct 2016 17:31:47 +0300 Subject: [PATCH 01/12] * src/regex.h (re_match_object): Improve commentary. --- src/regex.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/regex.h b/src/regex.h index 817167a07ca..51f4424ce94 100644 --- a/src/regex.h +++ b/src/regex.h @@ -168,8 +168,12 @@ extern reg_syntax_t re_syntax_options; #ifdef emacs # include "lisp.h" -/* 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. + It is used for looking up syntax properties. + + If the value is a Lisp string object, we are matching text in that + string; if it's nil, we are matching text in the current buffer; if + it's t, we are matching text in a C string. */ extern Lisp_Object re_match_object; #endif From 8988327d548db7b69f30ea15496ccb0726fa4502 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 19 Oct 2016 21:10:31 +0300 Subject: [PATCH 02/12] Fix documentation of 'alist-get' * doc/lispref/lists.texi (Association Lists): Fix the signature of 'alist-get'. Fix the markup, the wording, and the punctuation in the description. (Bug#24740) --- doc/lispref/lists.texi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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: @end smallexample @end defun -@defun alist-get key value &optional default remove +@defun alist-get key alist &optional default remove This function is like @code{assq}, but instead of returning the entire -association for @var{key}, @code{(@var{key} . @var{value})}, it -returns just the @var{value}. If @var{key} is not found in -@var{alist} it returns @var{default}. +association for @var{key} in @var{alist}, +@w{@code{(@var{key} . @var{value})}}, it returns just the @var{value}. +If @var{key} is not found in @var{alist}, it returns @var{default}. This is a generalized variable (@pxref{Generalized Variables}) that can be used to change a value with @code{setf}. When using it to set -a value, optional argument @var{remove} non-nil means to remove +a value, optional argument @var{remove} non-@code{nil} means to remove @var{key} from @var{alist} if the new value is @code{eql} to @var{default}. @end defun From 3877c911b7bd4ca7def18932615b10dc7b1fc6d3 Mon Sep 17 00:00:00 2001 From: Tino Calancha Date: Thu, 20 Oct 2016 19:39:59 +0900 Subject: [PATCH 03/12] vc-region-history: Search just on lines intersecting the region * lisp/vc/vc.el (vc-region-history): If region ends in the beginning of a line, then exclude that line from the search (Bug#24725). --- lisp/vc/vc.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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." "Show the history of the region FROM..TO." (interactive "r") (let* ((lfrom (line-number-at-pos from)) - (lto (line-number-at-pos to)) + (lto (line-number-at-pos (1- to))) (file buffer-file-name) (backend (vc-backend file)) (buf (get-buffer-create "*VC-history*"))) From 5a26c9b0e1b0d9a2de35e0a8b0a803017e70def0 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 21 Oct 2016 14:00:09 -0700 Subject: [PATCH 04/12] * lisp/electric.el (electric-quote-mode): Improve doc (Bug#24759). --- lisp/electric.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/electric.el b/lisp/electric.el index e2896010405..b6697e0736a 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -497,6 +497,9 @@ and text paragraphs, and these are selectively controlled with `electric-quote-comment', `electric-quote-string', and `electric-quote-paragraph'. +Electric quoting is suppressed in a buffer whose coding system +cannot represent the replacement characters. + This is a global minor mode. To toggle the mode in a single buffer, use `electric-quote-local-mode'." :global t :group 'electricity From ad66b3fadb7ae22a4cbb82bb1507c39ceadf3897 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Wed, 19 Oct 2016 20:23:50 -0400 Subject: [PATCH 05/12] Fix handling of allocation in regex matching `re_match_2_internal' uses pointers to the lisp objects that it searches. Since it may call malloc when growing the "fail stack", these pointers may be invalidated while searching, resulting in memory curruption (Bug #24358). To fix this, we check the pointer that the lisp object (as specified by re_match_object) points to before and after growing the stack, and update existing pointers accordingly. * src/regex.c (STR_BASE_PTR): New macro. (ENSURE_FAIL_STACK, re_search_2): Use it to convert pointers into offsets before possible malloc call, and back into pointers again afterwards. (POS_AS_IN_BUFFER): Add explanatory comment about punning trick. * src/search.c (search_buffer): Instead of storing search location as pointers, store them as pointers and recompute the corresponding address for each call to `re_search_2'. (string_match_1, fast_string_match_internal, fast_looking_at): * src/dired.c (directory_files_internal): Set `re_match_object' to Qnil after calling `re_search' or `re_match_2'. * src/regex.h (re_match_object): Mention new usage in commentary. --- src/dired.c | 4 ++- src/regex.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++--- src/regex.h | 4 ++- src/search.c | 36 ++++++++++++++++--------- 4 files changed, 103 insertions(+), 17 deletions(-) diff --git a/src/dired.c b/src/dired.c index dba575ce4c2..006f74c834d 100644 --- a/src/dired.c +++ b/src/dired.c @@ -259,9 +259,11 @@ directory_files_internal (Lisp_Object directory, Lisp_Object full, QUIT; bool wanted = (NILP (match) - || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0); + || (re_match_object = name, + re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0)); immediate_quit = 0; + re_match_object = Qnil; /* Stop protecting name from GC. */ if (wanted) { diff --git a/src/regex.c b/src/regex.c index 164eb4612ae..1346ef401cb 100644 --- a/src/regex.c +++ b/src/regex.c @@ -152,6 +152,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) @@ -1436,11 +1438,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); \ + 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 (orig_base) \ + { \ + 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; \ + return -2; \ + /* GROW_FAIL_STACK may call malloc and relocate the string */ \ + /* pointers. */ \ + re_char* new_base = STR_BASE_PTR (re_match_object); \ + if (new_base && new_base != orig_base) \ + { \ + 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);\ } @@ -4443,6 +4496,16 @@ 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, causing a relocation of the + lisp text object that we're searching. */ + ptrdiff_t offset1, offset2; + re_char *orig_base = STR_BASE_PTR (re_match_object); + if (orig_base) + { + 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); @@ -4452,6 +4515,13 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, if (val == -2) return -2; + re_char *new_base = STR_BASE_PTR (re_match_object); + if (new_base && new_base != orig_base) + { + if (string1) string1 = offset1 + new_base; + if (string2) string2 = offset2 + new_base; + } + advance: if (!range) break; @@ -4887,8 +4957,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 diff --git a/src/regex.h b/src/regex.h index 51f4424ce94..61c771c045f 100644 --- a/src/regex.h +++ b/src/regex.h @@ -169,7 +169,9 @@ extern reg_syntax_t re_syntax_options; #ifdef emacs # include "lisp.h" /* In Emacs, this is the string or buffer in which we are matching. - It is used for looking up syntax properties. + It is used for looking up syntax properties, and also to recompute + pointers in case the object is relocated as a side effect of + calling malloc (if it calls r_alloc_sbrk in ralloc.c). If the value is a Lisp string object, we are matching text in that string; if it's nil, we are matching text in the current buffer; if diff --git a/src/search.c b/src/search.c index dc7e2d88603..ec5a1d7733f 100644 --- a/src/search.c +++ b/src/search.c @@ -287,8 +287,10 @@ looking_at_1 (Lisp_Object string, bool posix) immediate_quit = 1; QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ - /* Get pointers and sizes of the two strings - that make up the visible portion of the buffer. */ + /* Get pointers and sizes of the two strings that make up the + visible portion of the buffer. Note that we can use pointers + here, unlike in search_buffer, because we only call re_match_2 + once, after which we never use the pointers again. */ p1 = BEGV_ADDR; s1 = GPT_BYTE - BEGV_BYTE; @@ -407,6 +409,7 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, (NILP (Vinhibit_changing_match_data) ? &search_regs : NULL)); immediate_quit = 0; + re_match_object = Qnil; /* Stop protecting string from GC. */ /* Set last_thing_searched only when match data is changed. */ if (NILP (Vinhibit_changing_match_data)) @@ -477,6 +480,7 @@ fast_string_match_internal (Lisp_Object regexp, Lisp_Object string, SBYTES (string), 0, SBYTES (string), 0); immediate_quit = 0; + re_match_object = Qnil; /* Stop protecting string from GC. */ return val; } @@ -564,6 +568,7 @@ fast_looking_at (Lisp_Object regexp, ptrdiff_t pos, ptrdiff_t pos_byte, len = re_match_2 (buf, (char *) p1, s1, (char *) p2, s2, pos_byte, NULL, limit_byte); immediate_quit = 0; + re_match_object = Qnil; /* Stop protecting string from GC. */ return len; } @@ -1178,8 +1183,8 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, if (RE && !(trivial_regexp_p (string) && NILP (Vsearch_spaces_regexp))) { - unsigned char *p1, *p2; - ptrdiff_t s1, s2; + unsigned char *base; + ptrdiff_t off1, off2, s1, s2; struct re_pattern_buffer *bufp; bufp = compile_pattern (string, @@ -1193,16 +1198,19 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, can take too long. */ QUIT; /* Do a pending quit right away, to avoid paradoxical behavior */ - /* Get pointers and sizes of the two strings - that make up the visible portion of the buffer. */ + /* Get offsets and sizes of the two strings that make up the + visible portion of the buffer. We compute offsets instead of + pointers because re_search_2 may call malloc and therefore + change the buffer text address. */ - p1 = BEGV_ADDR; + base = current_buffer->text->beg; + off1 = BEGV_ADDR - base; s1 = GPT_BYTE - BEGV_BYTE; - p2 = GAP_END_ADDR; + off2 = GAP_END_ADDR - base; s2 = ZV_BYTE - GPT_BYTE; if (s1 < 0) { - p2 = p1; + off2 = off1; s2 = ZV_BYTE - BEGV_BYTE; s1 = 0; } @@ -1217,7 +1225,9 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, { ptrdiff_t val; - val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, + val = re_search_2 (bufp, + (char*) (base + off1), s1, + (char*) (base + off2), s2, pos_byte - BEGV_BYTE, lim_byte - pos_byte, (NILP (Vinhibit_changing_match_data) ? &search_regs : &search_regs_1), @@ -1262,8 +1272,10 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, { ptrdiff_t val; - val = re_search_2 (bufp, (char *) p1, s1, (char *) p2, s2, - pos_byte - BEGV_BYTE, lim_byte - pos_byte, + val = re_search_2 (bufp, + (char*) (base + off1), s1, + (char*) (base + off2), s2, + pos_byte - BEGV_BYTE, lim_byte - pos_byte, (NILP (Vinhibit_changing_match_data) ? &search_regs : &search_regs_1), lim_byte - BEGV_BYTE); From 5c2da93015abb2e6746d54e5946dfaa5ede4e685 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 17 Sep 2016 13:30:24 -0400 Subject: [PATCH 06/12] Fix kill-line's docstring * lisp/simple.el (kill-line): The effect of show-trailing-whitespace is important lines with *no* nonblanks (Bug #16654). --- lisp/simple.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/simple.el b/lisp/simple.el index 67c02665ea1..6d36a88892f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -4846,8 +4846,8 @@ To kill a whole line, when point is not at the beginning, type \ \\[move-beginning-of-line] \\[kill-line] \\[kill-line]. If `show-trailing-whitespace' is non-nil, this command will just -kill the rest of the current line, even if there are only -nonblanks there. +kill the rest of the current line, even if there are no nonblanks +there. If option `kill-whole-line' is non-nil, then this command kills the whole line including its terminating newline, when used at the beginning of a line From 9da53e2d353c97ab955fe8c35482b5eb335316c1 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Mon, 3 Oct 2016 18:49:56 -0400 Subject: [PATCH 07/12] Let describe-function work for lambda again Since commit "* lisp/help-fns.el (describe-function): More type checking[...]", `describe-function' throws a user-error when given a non-symbol. This prevents the [back] button in a *Help* buffer from working when the page it goes back to describes an anonymous function (e.g., the result of `describe-key' on a key which is bound to a lambda form). * lisp/help-fns.el (describe-function): Move the checks on FUNCTION being an fbound symbol into the `interactive' form. This allows non-interactive calls to pass an anonymous function (Bug #24221). Note that passing a non-bound symbol non-interactively will still trigger a `void-function' error from `describe-function-1'. --- lisp/help-fns.el | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 26d8839f7cb..7dfa6700b29 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -50,23 +50,24 @@ to get buffer-local values.") ;;;###autoload (defun describe-function (function) - "Display the full documentation of FUNCTION (a symbol)." + "Display the full documentation of FUNCTION (a symbol). +When called from lisp, FUNCTION may also be a function object." (interactive - (let ((fn (function-called-at-point)) - (enable-recursive-minibuffers t) - val) - (setq val (completing-read (if fn - (format "Describe function (default %s): " fn) - "Describe function: ") - obarray 'fboundp t nil nil - (and fn (symbol-name fn)))) - (list (if (equal val "") - fn (intern val))))) - (or (and function (symbolp function)) - (user-error "You didn't specify a function symbol")) - (or (fboundp function) - (user-error "Symbol's function definition is void: %s" function)) - + (let* ((fn (function-called-at-point)) + (enable-recursive-minibuffers t) + (val (completing-read + (if fn + (format "Describe function (default %s): " fn) + "Describe function: ") + obarray 'fboundp t nil nil + (and fn (symbol-name fn))))) + (unless (equal val "") + (setq fn (intern val))) + (unless (and fn (symbolp fn)) + (user-error "You didn't specify a function symbol")) + (unless (fboundp fn) + (user-error "Symbol's function definition is void: %s" fn)) + (list fn))) ;; We save describe-function-orig-buffer on the help xref stack, so ;; it is restored by the back/forward buttons. 'help-buffer' ;; expects (current-buffer) to be a help buffer when processing From b2ba630739cf12db939cdcfe9cd19b6a7fdfbf97 Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Sat, 22 Oct 2016 11:52:14 -0400 Subject: [PATCH 08/12] Explain how to debug emacsclient lisp errors * doc/lispref/debugging.texi (Error Debugging): Mention that debug-on-signal is useful for getting backtraces from emacsclient (Bug#24616). --- doc/lispref/debugging.texi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi index c88a2fa60e0..371934377a8 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 must still fulfill the criteria specified by @code{debug-on-error} and @code{debug-ignored-errors}.) +@cindex emacsclient, getting a backtrace +@cindex backtrace from emacsclient's @option{--eval} +For example, setting this variable is useful to get a backtrace from +code evaluated by emacsclient's @option{--eval} option. If Lisp code +evaluated by emacsclient signals an error while this variable is +non-@code{nil}, the backtrace will popup in the running Emacs. + @strong{Warning:} Setting this variable to non-@code{nil} may have annoying effects. Various parts of Emacs catch errors in the normal course of affairs, and you may not even realize that errors happen From f6134bbda259c115c06d4a9a3ab5c39340a15949 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 22 Oct 2016 21:12:54 -0700 Subject: [PATCH 09/12] Port to GCC 6.2.1 + --enable-gcc-warnings * src/regex.c (ENSURE_FAIL_STACK, re_search_2): Redo recent regex changes to avoid complaints from GCC 6.2.1 when Emacs is configured with --enable-gcc-warnings. Also, work around GCC bug 78081, which was uncovered by this new code. --- src/regex.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/regex.c b/src/regex.c index 1346ef401cb..daa15ec5a8d 100644 --- a/src/regex.c +++ b/src/regex.c @@ -1439,21 +1439,22 @@ typedef struct #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) +# define STR_BASE_PTR(obj) \ + (NILP (obj) ? current_buffer->text->beg \ + : STRINGP (obj) ? SDATA (obj) \ + : NULL) #else -#define STR_BASE_PTR(obj) NULL +# 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); \ + 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 (orig_base) \ + if (might_relocate) \ { \ if (string1) \ { \ @@ -1472,12 +1473,11 @@ while (REMAINING_AVAIL_SLOTS <= space) { \ dfail_off = dfail - orig_base; \ } \ if (!GROW_FAIL_STACK (fail_stack)) \ - return -2; \ - /* GROW_FAIL_STACK may call malloc and relocate the string */ \ - /* pointers. */ \ - re_char* new_base = STR_BASE_PTR (re_match_object); \ - if (new_base && new_base != orig_base) \ + 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; \ @@ -4496,11 +4496,13 @@ 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, causing a relocation of the - lisp text object that we're searching. */ + /* re_match_2_internal may allocate, relocating the Lisp text + object that we're searching. */ ptrdiff_t offset1, offset2; + IF_LINT (offset2 = 0); /* Work around GCC bug 78081. */ re_char *orig_base = STR_BASE_PTR (re_match_object); - if (orig_base) + bool might_relocate = orig_base != NULL; + if (might_relocate) { if (string1) offset1 = string1 - orig_base; if (string2) offset2 = string2 - orig_base; @@ -4515,9 +4517,9 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, if (val == -2) return -2; - re_char *new_base = STR_BASE_PTR (re_match_object); - if (new_base && new_base != orig_base) + 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; } From c2a17924a57483d14692c8913edbe8ad24b5ffbb Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 23 Oct 2016 01:00:27 -0700 Subject: [PATCH 10/12] * src/regex.c (re_search_2): Make new code safe for -Wjump-misses-init. --- src/regex.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/regex.c b/src/regex.c index daa15ec5a8d..b12e95b38c0 100644 --- a/src/regex.c +++ b/src/regex.c @@ -4380,6 +4380,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 @@ -4498,10 +4502,9 @@ re_search_2 (struct re_pattern_buffer *bufp, const char *str1, size_t size1, /* re_match_2_internal may allocate, relocating the Lisp text object that we're searching. */ - ptrdiff_t offset1, offset2; IF_LINT (offset2 = 0); /* Work around GCC bug 78081. */ - re_char *orig_base = STR_BASE_PTR (re_match_object); - bool might_relocate = orig_base != NULL; + orig_base = STR_BASE_PTR (re_match_object); + might_relocate = orig_base != NULL; if (might_relocate) { if (string1) offset1 = string1 - orig_base; From 6f1325ed926ed455398021377a10160ac695c0d6 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sun, 23 Oct 2016 01:14:23 -0700 Subject: [PATCH 11/12] electric-quote mode no longer worries about coding * doc/emacs/text.texi (Quotation Marks), etc/NEWS: Document this. * lisp/electric.el (electric--insertable-p): Remove. All uses removed (Bug#24759). --- doc/emacs/text.texi | 4 +--- etc/NEWS | 6 ++++++ lisp/electric.el | 21 ++++----------------- 3 files changed, 11 insertions(+), 20 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. Electric Quote mode makes it easier to type curved quotes. As you type characters it optionally converts @t{`} to @t{‘}, @t{'} to @t{’}, -@t{``} to @t{“}, and @t{''} to @t{”}. These conversions are -suppressed in buffers whose coding systems cannot represent curved -quote characters. +@t{``} to @t{“}, and @t{''} to @t{”}. @vindex electric-quote-paragraph @vindex electric-quote-comment diff --git a/etc/NEWS b/etc/NEWS index 5b89639440d..a5bcb8dabdc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -38,6 +38,12 @@ fontsets if the default font supports these characters. Set this variable to nil to disable the new behavior and get back the old behavior. ++++ +** 'electric-quote-mode' is no longer suppressed in a buffer whose +whose coding system cannot represent curved quote characters. +Instead, users can deal with the unrepresentable characters in the +usual way when they save the buffer. + --- ** New variable 'inhibit-compacting-font-caches'. Set this variable to a non-nil value to speed up display of characters diff --git a/lisp/electric.el b/lisp/electric.el index b6697e0736a..ab9770b0bbb 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." :version "25.1" :type 'boolean :safe 'booleanp :group 'electricity) -(defun electric--insertable-p (string) - (or (not buffer-file-coding-system) - (eq (coding-system-base buffer-file-coding-system) 'undecided) - (not (unencodable-char-position nil nil buffer-file-coding-system - nil string)))) - (defun electric-quote-post-self-insert-function () "Function that `electric-quote-mode' adds to `post-self-insert-hook'. This requotes when a quoting key is typed." @@ -460,8 +454,7 @@ This requotes when a quoting key is typed." (when start (save-excursion (if (eq last-command-event ?\`) - (cond ((and (electric--insertable-p "“") - (search-backward "‘`" (- (point) 2) t)) + (cond ((search-backward "‘`" (- (point) 2) t) (replace-match "“") (when (and electric-pair-mode (eq (cdr-safe @@ -469,16 +462,13 @@ This requotes when a quoting key is typed." (char-after))) (delete-char 1)) (setq last-command-event ?“)) - ((and (electric--insertable-p "‘") - (search-backward "`" (1- (point)) t)) + ((search-backward "`" (1- (point)) t) (replace-match "‘") (setq last-command-event ?‘))) - (cond ((and (electric--insertable-p "”") - (search-backward "’'" (- (point) 2) t)) + (cond ((search-backward "’'" (- (point) 2) t) (replace-match "”") (setq last-command-event ?”)) - ((and (electric--insertable-p "’") - (search-backward "'" (1- (point)) t)) + ((search-backward "'" (1- (point)) t) (replace-match "’") (setq last-command-event ?’))))))))) @@ -497,9 +487,6 @@ and text paragraphs, and these are selectively controlled with `electric-quote-comment', `electric-quote-string', and `electric-quote-paragraph'. -Electric quoting is suppressed in a buffer whose coding system -cannot represent the replacement characters. - This is a global minor mode. To toggle the mode in a single buffer, use `electric-quote-local-mode'." :global t :group 'electricity From 50fa7d64d36c3f2d6ab11e7136575fbca7012cae Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 23 Oct 2016 12:14:05 +0300 Subject: [PATCH 12/12] ;* src/w32heap.c: Fix typo and wording of the comments. --- src/w32heap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/w32heap.c b/src/w32heap.c index 6643b439a26..3e628d54c42 100644 --- a/src/w32heap.c +++ b/src/w32heap.c @@ -129,18 +129,18 @@ static DWORD_PTR committed = 0; /* The maximum block size that can be handled by a non-growable w32 heap is limited by the MaxBlockSize value below. - This point deserves and explanation. + This point deserves an explanation. - The W32 heap allocator can be used for a growable - heap or a non-growable one. + The W32 heap allocator can be used for a growable heap or a + non-growable one. A growable heap is not compatible with a fixed base address for the heap. Only a non-growable one is. One drawback of non-growable heaps is that they can hold only objects smaller than a certain - size (the one defined below). Most of the largest blocks are GC'ed - before dumping. In any case and to be safe, we implement a simple + size (the one defined below). Most of the larger blocks are GC'ed + before dumping. In any case, and to be safe, we implement a simple first-fit allocation algorithm starting at the end of the - dumped_data[] array like depicted below: + dumped_data[] array as depicted below: ---------------------------------------------- | | | | @@ -273,7 +273,7 @@ init_heap (void) else { /* Find the RtlCreateHeap function. Headers for this function - are provided with the w32 ddk, but the function is available + are provided with the w32 DDK, but the function is available in ntdll.dll since XP. */ HMODULE hm_ntdll = LoadLibrary ("ntdll.dll"); RtlCreateHeap_Proc s_pfn_Rtl_Create_Heap