]> code.delx.au - gnu-emacs/blobdiff - src/buffer.c
Tiny adjustment around the previous redisplay change.
[gnu-emacs] / src / buffer.c
index 0e2e50d9f51630aab2e21fb125f43e74c3b3a903..619a729a859bfa1a8f748d9adb40b03f094f7115 100644 (file)
@@ -26,7 +26,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <sys/param.h>
 #include <errno.h>
 #include <stdio.h>
-#include <setjmp.h>
 #include <unistd.h>
 
 #include <verify.h>
@@ -44,7 +43,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "keymap.h"
 #include "frame.h"
 
-struct buffer *current_buffer;         /* the current buffer */
+struct buffer *current_buffer;         /* The current buffer.  */
 
 /* First buffer in chain of all buffers (in reverse order of creation).
    Threaded through ->header.next.buffer.  */
@@ -60,10 +59,6 @@ struct buffer *all_buffers;
 
 struct buffer alignas (GCALIGNMENT) buffer_defaults;
 
-/* A Lisp_Object pointer to the above, used for staticpro */
-
-static Lisp_Object Vbuffer_defaults;
-
 /* This structure marks which slots in a buffer have corresponding
    default values in buffer_defaults.
    Each such slot has a nonzero value in this structure.
@@ -78,18 +73,15 @@ static Lisp_Object Vbuffer_defaults;
    and the corresponding slot in buffer_defaults is not used.
 
    If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
-   zero, that is a bug */
+   zero, that is a bug */
 
 struct buffer buffer_local_flags;
 
 /* This structure holds the names of symbols whose values may be
-   buffer-local.  It is indexed and accessed in the same way as the above. */
+   buffer-local.  It is indexed and accessed in the same way as the above.  */
 
 struct buffer alignas (GCALIGNMENT) buffer_local_symbols;
 
-/* A Lisp_Object pointer to the above, used for staticpro */
-static Lisp_Object Vbuffer_local_symbols;
-
 /* Return the symbol of the per-buffer variable at offset OFFSET in
    the buffer structure.  */
 
@@ -115,7 +107,7 @@ static void call_overlay_mod_hooks (Lisp_Object list, Lisp_Object overlay,
 static void swap_out_buffer_local_variables (struct buffer *b);
 static void reset_buffer_local_variables (struct buffer *, bool);
 
-/* Alist of all buffer names vs the buffers. */
+/* Alist of all buffer names vs the buffers.  */
 /* This used to be a variable, but is no longer,
  to prevent lossage due to user rplac'ing this alist or its elements.  */
 Lisp_Object Vbuffer_alist;
@@ -134,7 +126,7 @@ static Lisp_Object Qpermanent_local_hook;
 
 static Lisp_Object Qprotected_field;
 
-static Lisp_Object QSFundamental;      /* A string "Fundamental" */
+static Lisp_Object QSFundamental;      /* A string "Fundamental" */
 
 static Lisp_Object Qkill_buffer_hook;
 static Lisp_Object Qbuffer_list_update_hook;
@@ -158,222 +150,222 @@ static void modify_overlay (struct buffer *, ptrdiff_t, ptrdiff_t);
 static Lisp_Object buffer_lisp_local_variables (struct buffer *, bool);
 
 /* These setters are used only in this file, so they can be private.  */
-static inline void
+static void
 bset_abbrev_mode (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (abbrev_mode) = val;
 }
-static inline void
+static void
 bset_abbrev_table (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (abbrev_table) = val;
 }
-static inline void
+static void
 bset_auto_fill_function (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (auto_fill_function) = val;
 }
-static inline void
+static void
 bset_auto_save_file_format (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (auto_save_file_format) = val;
 }
-static inline void
+static void
 bset_auto_save_file_name (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (auto_save_file_name) = val;
 }
-static inline void
+static void
 bset_backed_up (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (backed_up) = val;
 }
-static inline void
+static void
 bset_begv_marker (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (begv_marker) = val;
 }
-static inline void
+static void
 bset_bidi_display_reordering (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (bidi_display_reordering) = val;
 }
-static inline void
+static void
 bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (buffer_file_coding_system) = val;
 }
-static inline void
+static void
 bset_cache_long_line_scans (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (cache_long_line_scans) = val;
 }
-static inline void
+static void
 bset_case_fold_search (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (case_fold_search) = val;
 }
-static inline void
+static void
 bset_ctl_arrow (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (ctl_arrow) = val;
 }
-static inline void
+static void
 bset_cursor_in_non_selected_windows (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (cursor_in_non_selected_windows) = val;
 }
-static inline void
+static void
 bset_cursor_type (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (cursor_type) = val;
 }
-static inline void
+static void
 bset_display_table (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (display_table) = val;
 }
-static inline void
+static void
 bset_extra_line_spacing (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (extra_line_spacing) = val;
 }
-static inline void
+static void
 bset_file_format (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (file_format) = val;
 }
-static inline void
+static void
 bset_file_truename (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (file_truename) = val;
 }
-static inline void
+static void
 bset_fringe_cursor_alist (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (fringe_cursor_alist) = val;
 }
-static inline void
+static void
 bset_fringe_indicator_alist (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (fringe_indicator_alist) = val;
 }
-static inline void
+static void
 bset_fringes_outside_margins (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (fringes_outside_margins) = val;
 }
-static inline void
+static void
 bset_header_line_format (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (header_line_format) = val;
 }
-static inline void
+static void
 bset_indicate_buffer_boundaries (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (indicate_buffer_boundaries) = val;
 }
-static inline void
+static void
 bset_indicate_empty_lines (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (indicate_empty_lines) = val;
 }
-static inline void
+static void
 bset_invisibility_spec (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (invisibility_spec) = val;
 }
-static inline void
+static void
 bset_left_fringe_width (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (left_fringe_width) = val;
 }
-static inline void
+static void
 bset_major_mode (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (major_mode) = val;
 }
-static inline void
+static void
 bset_mark (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (mark) = val;
 }
-static inline void
+static void
 bset_minor_modes (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (minor_modes) = val;
 }
-static inline void
+static void
 bset_mode_line_format (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (mode_line_format) = val;
 }
-static inline void
+static void
 bset_mode_name (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (mode_name) = val;
 }
-static inline void
+static void
 bset_name (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (name) = val;
 }
-static inline void
+static void
 bset_overwrite_mode (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (overwrite_mode) = val;
 }
-static inline void
+static void
 bset_pt_marker (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (pt_marker) = val;
 }
-static inline void
+static void
 bset_right_fringe_width (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (right_fringe_width) = val;
 }
-static inline void
+static void
 bset_save_length (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (save_length) = val;
 }
-static inline void
+static void
 bset_scroll_bar_width (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (scroll_bar_width) = val;
 }
-static inline void
+static void
 bset_scroll_down_aggressively (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (scroll_down_aggressively) = val;
 }
-static inline void
+static void
 bset_scroll_up_aggressively (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (scroll_up_aggressively) = val;
 }
-static inline void
+static void
 bset_selective_display (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (selective_display) = val;
 }
-static inline void
+static void
 bset_selective_display_ellipses (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (selective_display_ellipses) = val;
 }
-static inline void
+static void
 bset_vertical_scroll_bar_type (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (vertical_scroll_bar_type) = val;
 }
-static inline void
+static void
 bset_word_wrap (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (word_wrap) = val;
 }
-static inline void
+static void
 bset_zv_marker (struct buffer *b, Lisp_Object val)
 {
   b->INTERNAL_FIELD (zv_marker) = val;
@@ -395,7 +387,7 @@ DEFUN ("buffer-live-p", Fbuffer_live_p, Sbuffer_live_p, 1, 1, 0,
 Value is nil if OBJECT is not a buffer or if it has been killed.  */)
   (Lisp_Object object)
 {
-  return ((BUFFERP (object) && ! NILP (BVAR (XBUFFER (object), name)))
+  return ((BUFFERP (object) && BUFFER_LIVE_P (XBUFFER (object)))
          ? Qt : Qnil);
 }
 
@@ -414,7 +406,6 @@ followed by the rest of the buffers.  */)
       Lisp_Object framelist, prevlist, tail;
       Lisp_Object args[3];
 
-      CHECK_FRAME (frame);
       framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
       prevlist = Fnreverse (Fcopy_sequence
                            (XFRAME (frame)->buried_buffer_list));
@@ -558,11 +549,11 @@ even if it is dead.  The return value is never nil.  */)
   b->indirections = 0;
 
   BUF_GAP_SIZE (b) = 20;
-  BLOCK_INPUT;
+  block_input ();
   /* We allocate extra 1-byte at the tail and keep it always '\0' for
      anchoring a search.  */
   alloc_buffer_text (b, BUF_GAP_SIZE (b) + 1);
-  UNBLOCK_INPUT;
+  unblock_input ();
   if (! BUF_BEG_ADDR (b))
     buffer_memory_full (BUF_GAP_SIZE (b) + 1);
 
@@ -595,10 +586,6 @@ even if it is dead.  The return value is never nil.  */)
   bset_width_table (b, Qnil);
   b->prevent_redisplay_optimizations_p = 1;
 
-  /* Put this on the chain of all buffers including killed ones.  */
-  b->header.next.buffer = all_buffers;
-  all_buffers = b;
-
   /* An ordinary buffer normally doesn't need markers
      to handle BEGV and ZV.  */
   bset_pt_marker (b, Qnil);
@@ -663,13 +650,13 @@ copy_overlays (struct buffer *b, struct Lisp_Overlay *list)
 
 /* Set an appropriate overlay of B.  */
 
-static inline void
+static void
 set_buffer_overlays_before (struct buffer *b, struct Lisp_Overlay *o)
 {
   b->overlays_before = o;
 }
 
-static inline void
+static void
 set_buffer_overlays_after (struct buffer *b, struct Lisp_Overlay *o)
 {
   b->overlays_after = o;
@@ -787,7 +774,7 @@ CLONE nil means the indirect buffer's state is reset to default values.  */)
   base_buffer = Fget_buffer (base_buffer);
   if (NILP (base_buffer))
     error ("No such buffer: `%s'", SDATA (tem));
-  if (NILP (BVAR (XBUFFER (base_buffer), name)))
+  if (!BUFFER_LIVE_P (XBUFFER (base_buffer)))
     error ("Base buffer has been killed");
 
   if (SCHARS (name) == 0)
@@ -819,10 +806,6 @@ CLONE nil means the indirect buffer's state is reset to default values.  */)
   b->width_run_cache = 0;
   bset_width_table (b, Qnil);
 
-  /* Put this on the chain of all buffers including killed ones.  */
-  b->header.next.buffer = all_buffers;
-  all_buffers = b;
-
   name = Fcopy_sequence (name);
   set_string_intervals (name, NULL);
   bset_name (b, name);
@@ -913,6 +896,8 @@ delete_all_overlays (struct buffer *b)
 {
   struct Lisp_Overlay *ov, *next;
 
+  /* FIXME: Since each drop_overlay will scan BUF_MARKERS to unlink its
+     markers, we have an unneeded O(N^2) behavior here.  */
   for (ov = b->overlays_before; ov; ov = next)
     {
       drop_overlay (b, ov);
@@ -1242,7 +1227,7 @@ buffer_local_value_1 (Lisp_Object variable, Lisp_Object buffer)
          result = Fdefault_value (variable);
        break;
       }
-    default: abort ();
+    default: emacs_abort ();
     }
 
   return result;
@@ -1357,9 +1342,13 @@ A non-nil FLAG means mark the buffer modified.  */)
   /* If buffer becoming modified, lock the file.
      If buffer becoming unmodified, unlock the file.  */
 
-  fn = BVAR (current_buffer, file_truename);
+  struct buffer *b = current_buffer->base_buffer
+    ? current_buffer->base_buffer
+    : current_buffer;
+
+  fn = BVAR (b, file_truename);
   /* Test buffer-file-name so that binding it to nil is effective.  */
-  if (!NILP (fn) && ! NILP (BVAR (current_buffer, filename)))
+  if (!NILP (fn) && ! NILP (BVAR (b, filename)))
     {
       bool already = SAVE_MODIFF < MODIFF;
       if (!already && !NILP (flag))
@@ -1553,22 +1542,16 @@ list first, followed by the list of all buffers.  If no other buffer
 exists, return the buffer `*scratch*' (creating it if necessary).  */)
   (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
 {
-  Lisp_Object tail, buf, pred;
-  Lisp_Object notsogood = Qnil;
+  struct frame *f = decode_any_frame (frame);
+  Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate;
+  Lisp_Object buf, notsogood = Qnil;
 
-  if (NILP (frame))
-    frame = selected_frame;
-
-  CHECK_FRAME (frame);
-
-  pred = frame_buffer_predicate (frame);
   /* Consider buffers that have been seen in the frame first.  */
-  tail = XFRAME (frame)->buffer_list;
   for (; CONSP (tail); tail = XCDR (tail))
     {
       buf = XCAR (tail);
       if (BUFFERP (buf) && !EQ (buf, buffer)
-         && !NILP (BVAR (XBUFFER (buf), name))
+         && BUFFER_LIVE_P (XBUFFER (buf))
          && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
          /* If the frame has a buffer_predicate, disregard buffers that
             don't fit the predicate.  */
@@ -1588,7 +1571,7 @@ exists, return the buffer `*scratch*' (creating it if necessary).  */)
     {
       buf = Fcdr (XCAR (tail));
       if (BUFFERP (buf) && !EQ (buf, buffer)
-         && !NILP (BVAR (XBUFFER (buf), name))
+         && BUFFER_LIVE_P (XBUFFER (buf))
          && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
          /* If the frame has a buffer_predicate, disregard buffers that
             don't fit the predicate.  */
@@ -1630,7 +1613,7 @@ other_buffer_safely (Lisp_Object buffer)
     {
       buf = Fcdr (XCAR (tail));
       if (BUFFERP (buf) && !EQ (buf, buffer)
-         && !NILP (BVAR (XBUFFER (buf), name))
+         && BUFFER_LIVE_P (XBUFFER (buf))
          && (SREF (BVAR (XBUFFER (buf), name), 0) != ' '))
        return buf;
     }
@@ -1673,18 +1656,11 @@ No argument or nil as argument means do this for the current buffer.  */)
 void
 compact_buffer (struct buffer *buffer)
 {
-  /* Verify indirection counters.  */
-  if (buffer->base_buffer)
-    {
-      eassert (buffer->indirections == -1);
-      eassert (buffer->base_buffer->indirections > 0);
-    }
-  else
-    eassert (buffer->indirections >= 0);
+  BUFFER_CHECK_INDIRECTION (buffer);
 
   /* Skip dead buffers, indirect buffers and buffers
      which aren't changed since last compaction.  */
-  if (!NILP (buffer->INTERNAL_FIELD (name))
+  if (BUFFER_LIVE_P (buffer)
       && (buffer->base_buffer == NULL)
       && (buffer->text->compact != buffer->text->modiff))
     {
@@ -1749,7 +1725,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
   b = XBUFFER (buffer);
 
   /* Avoid trouble for buffer already dead.  */
-  if (NILP (BVAR (b, name)))
+  if (!BUFFER_LIVE_P (b))
     return Qnil;
 
   /* Query if the buffer is still modified.  */
@@ -1785,7 +1761,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
   }
 
   /* If the hooks have killed the buffer, exit now.  */
-  if (NILP (BVAR (b, name)))
+  if (!BUFFER_LIVE_P (b))
     return Qt;
 
   /* We have no more questions to ask.  Verify that it is valid
@@ -1817,7 +1793,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
       UNGCPRO;
 
       /* Exit if we now have killed the base buffer (Bug#11665).  */
-      if (NILP (BVAR (b, name)))
+      if (!BUFFER_LIVE_P (b))
        return Qt;
     }
 
@@ -1828,7 +1804,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
   replace_buffer_in_windows (buffer);
 
   /* Exit if replacing the buffer in windows has killed our buffer.  */
-  if (NILP (BVAR (b, name)))
+  if (!BUFFER_LIVE_P (b))
     return Qt;
 
   /* Make this buffer not be current.  Exit if it is the sole visible
@@ -1861,7 +1837,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
 
   /* Killing buffer processes may run sentinels which may have killed
      our buffer.  */
-  if (NILP (BVAR (b, name)))
+  if (!BUFFER_LIVE_P (b))
     return Qt;
 
   /* These may run Lisp code and into infinite loops (if someone
@@ -1893,7 +1869,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
     }
 
   /* Deleting an auto-save file could have killed our buffer.  */
-  if (NILP (BVAR (b, name)))
+  if (!BUFFER_LIVE_P (b))
     return Qt;
 
   if (b->base_buffer)
@@ -1901,12 +1877,16 @@ cleaning up all windows currently displaying the buffer to be killed. */)
       /* Unchain all markers that belong to this indirect buffer.
         Don't unchain the markers that belong to the base buffer
         or its other indirect buffers.  */
-      for (m = BUF_MARKERS (b); m; )
+      struct Lisp_Marker **mp = &BUF_MARKERS (b);
+      while ((m = *mp))
        {
-         struct Lisp_Marker *next = m->next;
          if (m->buffer == b)
-           unchain_marker (m);
-         m = next;
+           {
+             m->buffer = NULL;
+             *mp = m->next;
+           }
+         else
+           mp = &m->next;
        }
     }
   else
@@ -1923,8 +1903,12 @@ cleaning up all windows currently displaying the buffer to be killed. */)
       BUF_MARKERS (b) = NULL;
       set_buffer_intervals (b, NULL);
 
-      /* Perhaps we should explicitly free the interval tree here... */
+      /* Perhaps we should explicitly free the interval tree here...  */
     }
+  /* Since we've unlinked the markers, the overlays can't be here any more
+     either.  */
+  b->overlays_before = NULL;
+  b->overlays_after = NULL;
 
   /* Reset the local variables, so that this buffer's local values
      won't be protected from GC.  They would be protected
@@ -1935,7 +1919,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
 
   bset_name (b, Qnil);
 
-  BLOCK_INPUT;
+  block_input ();
   if (b->base_buffer)
     {
       /* Notify our base buffer that we don't share the text anymore.  */
@@ -1958,7 +1942,7 @@ cleaning up all windows currently displaying the buffer to be killed. */)
       b->width_run_cache = 0;
     }
   bset_width_table (b, Qnil);
-  UNBLOCK_INPUT;
+  unblock_input ();
   bset_undo_list (b, Qnil);
 
   /* Run buffer-list-update-hook.  */
@@ -2062,7 +2046,7 @@ the current buffer's major mode.  */)
 
   CHECK_BUFFER (buffer);
 
-  if (NILP (BVAR (XBUFFER (buffer), name)))
+  if (!BUFFER_LIVE_P (XBUFFER (buffer)))
     error ("Attempt to set major mode for a dead buffer");
 
   if (strcmp (SSDATA (BVAR (XBUFFER (buffer), name)), "*scratch*") == 0)
@@ -2117,6 +2101,8 @@ set_buffer_internal_1 (register struct buffer *b)
   if (current_buffer == b)
     return;
 
+  BUFFER_CHECK_INDIRECTION (b);
+
   old_buf = current_buffer;
   current_buffer = b;
   last_known_column_point = -1;   /* invalidate indentation cache */
@@ -2188,7 +2174,7 @@ set_buffer_temp (struct buffer *b)
 DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
        doc: /* Make buffer BUFFER-OR-NAME current for editing operations.
 BUFFER-OR-NAME may be a buffer or the name of an existing buffer.  See
-also `save-excursion' when you want to make a buffer current
+also `with-current-buffer' when you want to make a buffer current
 temporarily.  This function does not display the buffer, so its effect
 ends when the current command terminates.  Use `switch-to-buffer' or
 `pop-to-buffer' to switch buffers permanently.  */)
@@ -2198,7 +2184,7 @@ ends when the current command terminates.  Use `switch-to-buffer' or
   buffer = Fget_buffer (buffer_or_name);
   if (NILP (buffer))
     nsberror (buffer_or_name);
-  if (NILP (BVAR (XBUFFER (buffer), name)))
+  if (!BUFFER_LIVE_P (XBUFFER (buffer)))
     error ("Selecting deleted buffer");
   set_buffer_internal (XBUFFER (buffer));
   return buffer;
@@ -2209,7 +2195,7 @@ ends when the current command terminates.  Use `switch-to-buffer' or
 Lisp_Object
 set_buffer_if_live (Lisp_Object buffer)
 {
-  if (! NILP (BVAR (XBUFFER (buffer), name)))
+  if (BUFFER_LIVE_P (XBUFFER (buffer)))
     set_buffer_internal (XBUFFER (buffer));
   return Qnil;
 }
@@ -2304,7 +2290,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
   CHECK_BUFFER (buffer);
   other_buffer = XBUFFER (buffer);
 
-  if (NILP (BVAR (other_buffer, name)))
+  if (!BUFFER_LIVE_P (other_buffer))
     error ("Cannot swap a dead buffer's text");
 
   /* Actually, it probably works just fine.
@@ -2476,7 +2462,7 @@ current buffer is cleared.  */)
     begv = BEGV, zv = ZV;
 
   if (narrowed)
-    Fwiden ();
+    error ("Changing multibyteness in a narrowed buffer");
 
   if (NILP (flag))
     {
@@ -2671,7 +2657,7 @@ current buffer is cleared.  */)
       /* Make sure no markers were put on the chain
         while the chain value was incorrect.  */
       if (BUF_MARKERS (current_buffer))
-       abort ();
+       emacs_abort ();
 
       BUF_MARKERS (current_buffer) = markers;
 
@@ -2700,7 +2686,7 @@ current buffer is cleared.  */)
   /* Copy this buffer's new multibyte status
      into all of its indirect buffers.  */
   FOR_EACH_BUFFER (other)
-    if (other->base_buffer == current_buffer && !NILP (BVAR (other, name)))
+    if (other->base_buffer == current_buffer && BUFFER_LIVE_P (other))
       {
        BVAR (other, enable_multibyte_characters)
          = BVAR (current_buffer, enable_multibyte_characters);
@@ -3146,8 +3132,8 @@ compare_overlays (const void *v1, const void *v2)
      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;
+  if (!EQ (s1->overlay, s2->overlay))
+    return XLI (s1->overlay) < XLI (s2->overlay) ? -1 : 1;
   return 0;
 }
 
@@ -3413,7 +3399,7 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr)
            }
        }
       if (p != overlay_str_buf + total)
-       abort ();
+       emacs_abort ();
       if (pstr)
        *pstr = overlay_str_buf;
       return total;
@@ -3701,7 +3687,6 @@ fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end)
       beforep->next = current_buffer->overlays_before;
       set_buffer_overlays_before (current_buffer, before_list);
     }
-  recenter_overlay_lists (current_buffer, current_buffer->overlay_center);
 
   if (afterp)
     {
@@ -3859,17 +3844,16 @@ for the rear of the overlay advance when text is inserted there
   end = OVERLAY_END (overlay);
   if (OVERLAY_POSITION (end) < b->overlay_center)
     {
-      if (b->overlays_after)
-       XOVERLAY (overlay)->next = b->overlays_after;
+      eassert (b->overlays_after || (XOVERLAY (overlay)->next == NULL));
+      XOVERLAY (overlay)->next = b->overlays_after;
       set_buffer_overlays_after (b, XOVERLAY (overlay));
     }
   else
     {
-      if (b->overlays_before)
-       XOVERLAY (overlay)->next = b->overlays_before;
+      eassert (b->overlays_before || (XOVERLAY (overlay)->next == NULL));
+      XOVERLAY (overlay)->next = b->overlays_before;
       set_buffer_overlays_before (b, XOVERLAY (overlay));
     }
-
   /* This puts it in the right list, and in the right order.  */
   recenter_overlay_lists (b, b->overlay_center);
 
@@ -4073,6 +4057,26 @@ DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
 
   return unbind_to (count, Qnil);
 }
+
+DEFUN ("delete-all-overlays", Fdelete_all_overlays, Sdelete_all_overlays, 0, 1, 0,
+       doc: /* Delete all overlays of BUFFER.
+BUFFER omitted or nil means delete all overlays of the current
+buffer.  */)
+  (Lisp_Object buffer)
+{
+  register struct buffer *buf;
+
+  if (NILP (buffer))
+    buf = current_buffer;
+  else
+    {
+      CHECK_BUFFER (buffer);
+      buf = XBUFFER (buffer);
+    }
+
+  delete_all_overlays (buf);
+  return Qnil;
+}
 \f
 /* Overlay dissection functions.  */
 
@@ -4133,7 +4137,7 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
   /* Put all the overlays we want in a vector in overlay_vec.
      Store the length in len.  */
   noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
-                          0, 0, 0);
+                          NULL, NULL, 0);
 
   /* Make a list of them all.  */
   result = Flist (noverlays, overlay_vec);
@@ -4576,7 +4580,7 @@ buffer_slot_type_mismatch (Lisp_Object newval, int type)
     case_Lisp_Int:    predicate = Qintegerp; break;
     case Lisp_String: predicate = Qstringp;  break;
     case Lisp_Symbol: predicate = Qsymbolp;  break;
-    default: abort ();
+    default: emacs_abort ();
     }
 
   wrong_type_argument (predicate, newval);
@@ -5024,7 +5028,7 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
 {
   void *p;
 
-  BLOCK_INPUT;
+  block_input ();
 #if defined USE_MMAP_FOR_BUFFERS
   p = mmap_alloc ((void **) &b->text->beg, nbytes);
 #elif defined REL_ALLOC
@@ -5035,12 +5039,12 @@ alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
 
   if (p == NULL)
     {
-      UNBLOCK_INPUT;
+      unblock_input ();
       memory_full (nbytes);
     }
 
   b->text->beg = (unsigned char *) p;
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 /* Enlarge buffer B's text buffer by DELTA bytes.  DELTA < 0 means
@@ -5052,7 +5056,7 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
   void *p;
   ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
                      + delta);
-  BLOCK_INPUT;
+  block_input ();
 #if defined USE_MMAP_FOR_BUFFERS
   p = mmap_realloc ((void **) &b->text->beg, nbytes);
 #elif defined REL_ALLOC
@@ -5063,12 +5067,12 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
 
   if (p == NULL)
     {
-      UNBLOCK_INPUT;
+      unblock_input ();
       memory_full (nbytes);
     }
 
   BUF_BEG_ADDR (b) = (unsigned char *) p;
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 
@@ -5077,7 +5081,7 @@ enlarge_buffer_text (struct buffer *b, ptrdiff_t delta)
 static void
 free_buffer_text (struct buffer *b)
 {
-  BLOCK_INPUT;
+  block_input ();
 
 #if defined USE_MMAP_FOR_BUFFERS
   mmap_free ((void **) &b->text->beg);
@@ -5088,7 +5092,7 @@ free_buffer_text (struct buffer *b)
 #endif
 
   BUF_BEG_ADDR (b) = NULL;
-  UNBLOCK_INPUT;
+  unblock_input ();
 }
 
 
@@ -5101,11 +5105,6 @@ void
 init_buffer_once (void)
 {
   int idx;
-  /* If you add, remove, or reorder Lisp_Objects in a struct buffer, make
-     sure that this is still correct.  Otherwise, mark_vectorlike may not
-     trace all Lisp_Objects in buffer_defaults and buffer_local_symbols.  */
-  const int pvecsize
-    = (offsetof (struct buffer, own_text) - header_size) / word_size;
 
   memset (buffer_permanent_local_flags, 0, sizeof buffer_permanent_local_flags);
 
@@ -5125,10 +5124,11 @@ init_buffer_once (void)
   buffer_local_symbols.indirections = 0;
   set_buffer_intervals (&buffer_defaults, NULL);
   set_buffer_intervals (&buffer_local_symbols, NULL);
-  XSETPVECTYPESIZE (&buffer_defaults, PVEC_BUFFER, pvecsize);
-  XSETBUFFER (Vbuffer_defaults, &buffer_defaults);
-  XSETPVECTYPESIZE (&buffer_local_symbols, PVEC_BUFFER, pvecsize);
-  XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols);
+  /* This is not strictly necessary, but let's make them initialized.  */
+  bset_name (&buffer_defaults, build_pure_c_string (" *buffer-defaults*"));
+  bset_name (&buffer_local_symbols, build_pure_c_string (" *buffer-local-symbols*"));
+  BUFFER_PVEC_INIT (&buffer_defaults);
+  BUFFER_PVEC_INIT (&buffer_local_symbols);
 
   /* Set up the default values of various buffer slots.  */
   /* Must do these before making the first buffer! */
@@ -5257,7 +5257,7 @@ init_buffer_once (void)
 
   /* Need more room? */
   if (idx >= MAX_PER_BUFFER_VARS)
-    abort ();
+    emacs_abort ();
   last_per_buffer_idx = idx;
 
   Vbuffer_alist = Qnil;
@@ -5398,7 +5398,7 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring,
   if (PER_BUFFER_IDX (offset) == 0)
     /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
        slot of buffer_local_flags */
-    abort ();
+    emacs_abort ();
 }
 
 
@@ -5410,8 +5410,6 @@ syms_of_buffer (void)
   last_overlay_modification_hooks
     = Fmake_vector (make_number (10), Qnil);
 
-  staticpro (&Vbuffer_defaults);
-  staticpro (&Vbuffer_local_symbols);
   staticpro (&Qfundamental_mode);
   staticpro (&Qmode_class);
   staticpro (&QSFundamental);
@@ -6200,15 +6198,15 @@ is a member of the list.  */);
                     doc: /* Cursor to use when this buffer is in the selected window.
 Values are interpreted as follows:
 
-  t              use the cursor specified for the frame
-  nil            don't display a cursor
-  box            display a filled box cursor
-  hollow         display a hollow box cursor
-  bar            display a vertical bar cursor with default width
-  (bar . WIDTH)          display a vertical bar cursor with width WIDTH
-  hbar           display a horizontal bar cursor with default height
+  t               use the cursor specified for the frame
+  nil             don't display a cursor
+  box             display a filled box cursor
+  hollow          display a hollow box cursor
+  bar             display a vertical bar cursor with default width
+  (bar . WIDTH)   display a vertical bar cursor with width WIDTH
+  hbar            display a horizontal bar cursor with default height
   (hbar . HEIGHT) display a horizontal bar cursor with height HEIGHT
-  ANYTHING ELSE          display a hollow box cursor
+  ANYTHING ELSE   display a hollow box cursor
 
 When the buffer is displayed in a non-selected window, the
 cursor's appearance is instead controlled by the variable
@@ -6286,6 +6284,7 @@ and `bury-buffer-internal'.  */);
   defsubr (&Soverlayp);
   defsubr (&Smake_overlay);
   defsubr (&Sdelete_overlay);
+  defsubr (&Sdelete_all_overlays);
   defsubr (&Smove_overlay);
   defsubr (&Soverlay_start);
   defsubr (&Soverlay_end);