emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 394bdb8 7/8: Merge from origin/emacs-25


From: Paul Eggert
Subject: [Emacs-diffs] master 394bdb8 7/8: Merge from origin/emacs-25
Date: Sun, 23 Oct 2016 09:58:40 +0000 (UTC)

branch: master
commit 394bdb8f2317e312d39e071b588581802dd3027a
Merge: 46288dd 50fa7d6
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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
---
 doc/emacs/text.texi        |    4 +--
 doc/lispref/debugging.texi |    7 ++++
 doc/lispref/lists.texi     |   10 +++---
 lisp/electric.el           |   18 +++-------
 lisp/help-fns.el           |   33 +++++++++---------
 lisp/simple.el             |    4 +--
 lisp/vc/vc.el              |    2 +-
 src/dired.c                |    4 ++-
 src/regex.c                |   79 ++++++++++++++++++++++++++++++++++++++++++--
 src/regex.h                |   10 ++++--
 src/search.c               |   36 +++++++++++++-------
 src/w32heap.c              |   14 ++++----
 12 files changed, 156 insertions(+), 65 deletions(-)

diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index 579f788..7fa0804 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{’},
address@hidden to @t{“}, and @t{''} to @t{”}.  These conversions are
-suppressed in buffers whose coding systems cannot represent curved
-quote characters.
address@hidden to @t{“}, and @t{''} to @t{”}.
 
 @vindex electric-quote-paragraph
 @vindex electric-quote-comment
diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi
index 5ff9582..6c0908a 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}.)
 
address@hidden emacsclient, getting a backtrace
address@hidden 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
address@hidden, the backtrace will popup in the running Emacs.
+
 @strong{Warning:} Setting this variable to address@hidden 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
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index e7a739f..dc4075d 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -1556,15 +1556,15 @@ keys may not be symbols:
 @end smallexample
 @end defun
 
address@hidden alist-get key value &optional default remove
address@hidden 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
address@hidden it returns @var{default}.
+association for @var{key} in @var{alist},
address@hidden@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} address@hidden means to remove
 @var{key} from @var{alist} if the new value is @code{eql} to @var{default}.
 @end defun
 
diff --git a/lisp/electric.el b/lisp/electric.el
index 0ec0a1e..f35f8b9 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 ?’)))))))))
 
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index e4e2333..87e7d8f 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -106,23 +106,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: ")
-                               #'help--symbol-completion-table
-                                #'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: ")
+                #'help--symbol-completion-table #'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'
diff --git a/lisp/simple.el b/lisp/simple.el
index 70bd759..d915ee2 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 \
 \\[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
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index af875e8..ac020d0 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*")))
diff --git a/src/dired.c b/src/dired.c
index e468147..c69164b 100644
--- a/src/dired.c
+++ b/src/dired.c
@@ -253,9 +253,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 1917a84..8bc8303 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
 
diff --git a/src/regex.h b/src/regex.h
index b672d3f..cb0796f 100644
--- a/src/regex.h
+++ b/src/regex.h
@@ -175,8 +175,14 @@ 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, 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
+   it's t, we are matching text in a C string.  */
 extern Lisp_Object re_match_object;
 #endif
 
diff --git a/src/search.c b/src/search.c
index 9b8fc58..bcb5ee9 100644
--- a/src/search.c
+++ b/src/search.c
@@ -280,8 +280,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;
@@ -400,6 +402,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))
@@ -470,6 +473,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;
 }
 
@@ -557,6 +561,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;
 }
@@ -1171,8 +1176,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,
@@ -1186,16 +1191,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;
        }
@@ -1210,7 +1218,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),
@@ -1255,8 +1265,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);
diff --git a/src/w32heap.c b/src/w32heap.c
index 658a8a5..443472b 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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]