]> code.delx.au - gnu-emacs/blobdiff - src/buffer.c
Fix bug #12242 with crashes in ralloc.c on OpenBSD.
[gnu-emacs] / src / buffer.c
index a6f61a1936afc2fb8ca588141d0ec376b3ca3015..88ef34070ea659628e0a8ec2fd1aadb3ef0b1be7 100644 (file)
@@ -1,6 +1,6 @@
 /* Buffer manipulation primitives for GNU Emacs.
 
-Copyright (C) 1985-1989, 1993-1995, 1997-2012  Free Software Foundation, Inc.
+Copyright (C) 1985-1989, 1993-1995, 1997-2012 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -156,7 +156,7 @@ static void alloc_buffer_text (struct buffer *, ptrdiff_t);
 static void free_buffer_text (struct buffer *b);
 static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *);
 static void modify_overlay (struct buffer *, EMACS_INT, EMACS_INT);
-static Lisp_Object buffer_lisp_local_variables (struct buffer *);
+static Lisp_Object buffer_lisp_local_variables (struct buffer *, int);
 
 /* For debugging; temporary.  See set_buffer_internal.  */
 /* Lisp_Object Qlisp_mode, Vcheck_symbol; */
@@ -272,7 +272,11 @@ See also `find-buffer-visiting'.  */)
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (filename, Qget_file_buffer);
   if (!NILP (handler))
-    return call2 (handler, Qget_file_buffer, filename);
+    {
+      Lisp_Object handled_buf = call2 (handler, Qget_file_buffer,
+                                      filename);
+      return BUFFERP (handled_buf) ? handled_buf : Qnil;
+    }
 
   for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
     {
@@ -501,7 +505,7 @@ clone_per_buffer_values (struct buffer *from, struct buffer *to)
 
   /* Get (a copy of) the alist of Lisp-level local variables of FROM
      and install that in TO.  */
-  BVAR (to, local_var_alist) = buffer_lisp_local_variables (from);
+  BVAR (to, local_var_alist) = buffer_lisp_local_variables (from, 1);
 }
 
 
@@ -999,10 +1003,12 @@ is the default binding of the variable. */)
 
 /* Return an alist of the Lisp-level buffer-local bindings of
    buffer BUF.  That is, don't include the variables maintained
-   in special slots in the buffer object.  */
+   in special slots in the buffer object.
+   If CLONE is zero elements of the form (VAR . unbound) are replaced
+   by VAR.  */
 
 static Lisp_Object
-buffer_lisp_local_variables (struct buffer *buf)
+buffer_lisp_local_variables (struct buffer *buf, int clone)
 {
   Lisp_Object result = Qnil;
   register Lisp_Object tail;
@@ -1022,7 +1028,7 @@ buffer_lisp_local_variables (struct buffer *buf)
       if (buf != current_buffer)
        val = XCDR (elt);
 
-      result = Fcons (EQ (val, Qunbound)
+      result = Fcons (!clone && EQ (val, Qunbound)
                      ? XCAR (elt)
                      : Fcons (XCAR (elt), val),
                      result);
@@ -1051,7 +1057,7 @@ No argument or nil as argument means use current buffer as BUFFER.  */)
       buf = XBUFFER (buffer);
     }
 
-  result = buffer_lisp_local_variables (buf);
+  result = buffer_lisp_local_variables (buf, 0);
 
   /* Add on all the variables stored in special slots.  */
   {
@@ -1713,7 +1719,7 @@ record_buffer (Lisp_Object buffer)
 /* Move BUFFER to the end of the buffer (a)lists.  Do nothing if the
    buffer is killed.  For the selected frame's buffer list this moves
    BUFFER to its end even if it was never shown in that frame.  If
-   this happens we have a feature, hence `unrecord-buffer' should be
+   this happens we have a feature, hence `bury-buffer-internal' should be
    called only when BUFFER was shown in the selected frame.  */
 
 DEFUN ("bury-buffer-internal", Fbury_buffer_internal, Sbury_buffer_internal,
@@ -2010,10 +2016,6 @@ advance_to_char_boundary (EMACS_INT byte_pos)
   return byte_pos;
 }
 
-#ifdef REL_ALLOC
-extern void r_alloc_reset_variable (POINTER_TYPE *, POINTER_TYPE *);
-#endif /* REL_ALLOC */
-
 DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
        1, 1, 0,
        doc: /* Swap the text between current buffer and BUFFER.  */)
@@ -2860,6 +2862,12 @@ compare_overlays (const void *v1, const void *v2)
     return s1->beg < s2->beg ? -1 : 1;
   if (s1->end != s2->end)
     return s2->end < s1->end ? -1 : 1;
+  /* Avoid the non-determinism of qsort by choosing an arbitrary ordering
+     between "equal" overlays.  The result can still change between
+     invocations of Emacs, but it won't change in the middle of
+     `find_field' (bug#6830).  */
+  if (XHASH (s1->overlay) != XHASH (s2->overlay))
+    return XHASH (s1->overlay) < XHASH (s2->overlay) ? -1 : 1;
   return 0;
 }
 
@@ -4769,13 +4777,6 @@ mmap_realloc (POINTER_TYPE **var, size_t nbytes)
                            Buffer-text Allocation
  ***********************************************************************/
 
-#ifdef REL_ALLOC
-extern POINTER_TYPE *r_alloc (POINTER_TYPE **, size_t);
-extern POINTER_TYPE *r_re_alloc (POINTER_TYPE **, size_t);
-extern void r_alloc_free (POINTER_TYPE **ptr);
-#endif /* REL_ALLOC */
-
-
 /* Allocate NBYTES bytes for buffer B's text buffer.  */
 
 static void
@@ -5992,7 +5993,7 @@ The function `kill-all-local-variables' runs this before doing anything else.  *
               doc: /* Hook run when the buffer list changes.
 Functions running this hook are `get-buffer-create',
 `make-indirect-buffer', `rename-buffer', `kill-buffer',
-`record-buffer' and `unrecord-buffer'.  */);
+and `bury-buffer-internal'.  */);
   Vbuffer_list_update_hook = Qnil;
   DEFSYM (Qbuffer_list_update_hook, "buffer-list-update-hook");