This commit was generated by cvs2svn to compensate for changes in r5197,
[chise/xemacs-chise.git.1] / src / insdel.c
index 520507a..01484b7 100644 (file)
@@ -200,6 +200,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include <config.h>
 #include "lisp.h"
+#include <limits.h>
 
 #include "buffer.h"
 #include "device.h"
@@ -303,64 +304,65 @@ do                                                \
    the equivalent length in characters. */
 
 Charcount
-bytecount_to_charcount (const Bufbyte *ptr, Bytecount len)
+bytecount_to_charcount (CONST Bufbyte *ptr, Bytecount len)
 {
   Charcount count = 0;
-  const Bufbyte *end = ptr + len;
-
-#if SIZEOF_LONG == 8
-# define STRIDE_TYPE long
-# define HIGH_BIT_MASK 0x8080808080808080UL
-#elif SIZEOF_LONG_LONG == 8 && !(defined (i386) || defined (__i386__))
-# define STRIDE_TYPE long long
-# define HIGH_BIT_MASK 0x8080808080808080ULL
-#elif SIZEOF_LONG == 4
-# define STRIDE_TYPE long
-# define HIGH_BIT_MASK 0x80808080UL
-#else
-# error Add support for 128-bit systems here
-#endif
-
-#define ALIGN_BITS ((EMACS_UINT) (ALIGNOF (STRIDE_TYPE) - 1))
-#define ALIGN_MASK (~ ALIGN_BITS)
-#define ALIGNED(ptr) ((((EMACS_UINT) ptr) & ALIGN_BITS) == 0)
-#define STRIDE sizeof (STRIDE_TYPE)
-
-  while (ptr < end)
-    {
-      if (BYTE_ASCII_P (*ptr))
+  CONST Bufbyte *end = ptr + len;
+
+#if (LONGBITS == 32 || LONGBITS == 64)
+
+# if (LONGBITS == 32)
+#  define LONG_BYTES 4
+#  define ALIGN_MASK 0xFFFFFFFCU
+#  define HIGH_BIT_MASK 0x80808080U
+# else
+#  define LONG_BYTES 8
+#  define ALIGN_MASK 0xFFFFFFFFFFFFFFF8UL
+   /* I had a dream, I was being overrun with early Intel processors ... */
+#  define HIGH_BIT_MASK 0x8080808080808080UL
+# endif
+
+  /* When we have a large number of bytes to scan, we can be trickier
+     and significantly faster by scanning them in chunks of the CPU word
+     size (assuming that they're all ASCII -- we cut out as soon as
+     we find something non-ASCII). */
+  if (len >= 12)
+    {
+      /* Determine the section in the middle of the string that's
+        amenable to this treatment.  Everything has to be aligned
+        on CPU word boundaries. */
+      CONST Bufbyte *aligned_ptr =
+       (CONST Bufbyte *) (((unsigned long) (ptr + LONG_BYTES - 1)) &
+                          ALIGN_MASK);
+      CONST Bufbyte *aligned_end =
+       (CONST Bufbyte *) (((unsigned long) end) & ALIGN_MASK);
+
+      /* Handle unaligned stuff at the beginning. */
+      while (ptr < aligned_ptr)
        {
-         /* optimize for long stretches of ASCII */
-         if (! ALIGNED (ptr))
-           ptr++, count++;
-         else
-           {
-             const unsigned STRIDE_TYPE *ascii_end =
-               (const unsigned STRIDE_TYPE *) ptr;
-             /* This loop screams, because we can typically
-                detect ASCII characters 8 at a time. */
-             while ((const Bufbyte *) ascii_end + STRIDE <= end
-                    && !(*ascii_end & HIGH_BIT_MASK))
-               ascii_end++;
-             if ((Bufbyte *) ascii_end == ptr)
-               ptr++, count++;
-             else
-               {
-                 count += (Bufbyte *) ascii_end - ptr;
-                 ptr = (Bufbyte *) ascii_end;
-               }
-           }
+         if (!BYTE_ASCII_P (*ptr))
+           goto bail;
+         count++, ptr++;
        }
-      else
+      /* Now do it. */
+      while (ptr < aligned_end)
        {
-         /* optimize for successive characters from the same charset */
-         Bufbyte leading_byte = *ptr;
-         size_t bytes = REP_BYTES_BY_FIRST_BYTE (leading_byte);
-         while ((ptr < end) && (*ptr == leading_byte))
-           ptr += bytes, count++;
+
+         if ((* (unsigned long *) ptr) & HIGH_BIT_MASK)
+           goto bail;
+         ptr += LONG_BYTES;
+         count += LONG_BYTES;
        }
     }
 
+#endif /* LONGBITS == 32 || LONGBITS == 64 */
+
+ bail:
+  while (ptr < end)
+    {
+      count++;
+      INC_CHARPTR (ptr);
+    }
 #ifdef ERROR_CHECK_BUFPOS
   /* Bomb out if the specified substring ends in the middle
      of a character.  Note that we might have already gotten
@@ -376,9 +378,9 @@ bytecount_to_charcount (const Bufbyte *ptr, Bytecount len)
    the equivalent length in bytes. */
 
 Bytecount
-charcount_to_bytecount (const Bufbyte *ptr, Charcount len)
+charcount_to_bytecount (CONST Bufbyte *ptr, Charcount len)
 {
-  const Bufbyte *newptr = ptr;
+  CONST Bufbyte *newptr = ptr;
 
   while (len > 0)
     {
@@ -1194,7 +1196,6 @@ bytind_to_bufpos (struct buffer *buf, Bytind x)
 Bufpos
 get_buffer_pos_char (struct buffer *b, Lisp_Object pos, unsigned int flags)
 {
-  /* Does not GC */
   Bufpos ind;
   Bufpos min_allowed, max_allowed;
 
@@ -1244,7 +1245,6 @@ void
 get_buffer_range_char (struct buffer *b, Lisp_Object from, Lisp_Object to,
                       Bufpos *from_out, Bufpos *to_out, unsigned int flags)
 {
-  /* Does not GC */
   Bufpos min_allowed, max_allowed;
 
   min_allowed = (flags & GB_ALLOW_PAST_ACCESSIBLE) ?
@@ -1605,7 +1605,7 @@ static void
 adjust_markers (struct buffer *buf, Memind from, Memind to,
                Bytecount amount)
 {
-  Lisp_Marker *m;
+  struct Lisp_Marker *m;
 
   for (m = BUF_MARKERS (buf); m; m = marker_next (m))
     m->memind = do_marker_adjustment (m->memind, from, to, amount);
@@ -1617,7 +1617,7 @@ adjust_markers (struct buffer *buf, Memind from, Memind to,
 static void
 adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount)
 {
-  Lisp_Marker *m;
+  struct Lisp_Marker *m;
 
   for (m = BUF_MARKERS (buf); m; m = marker_next (m))
     {
@@ -1631,6 +1631,18 @@ adjust_markers_for_insert (struct buffer *buf, Memind ind, Bytecount amount)
 /*                  Routines for dealing with the gap                   */
 /************************************************************************/
 
+/* XEmacs requires an ANSI C compiler, and it damn well better have a
+   working memmove() */
+#define GAP_USE_BCOPY
+#ifdef BCOPY_UPWARD_SAFE
+# undef BCOPY_UPWARD_SAFE
+#endif
+#ifdef BCOPY_DOWNWARD_SAFE
+# undef BCOPY_DOWNWARD_SAFE
+#endif
+#define BCOPY_UPWARD_SAFE 1
+#define BCOPY_DOWNWARD_SAFE 1
+
 /* maximum amount of memory moved in a single chunk.  Increasing this
    value improves gap-motion efficiency but decreases QUIT responsiveness
    time.  Was 32000 but today's processors are faster and files are
@@ -1645,8 +1657,6 @@ gap_left (struct buffer *buf, Bytind pos)
   Bufbyte *to, *from;
   Bytecount i;
   Bytind new_s1;
-  struct buffer *mbuf;
-  Lisp_Object bufcons;
 
   from = BUF_GPT_ADDR (buf);
   to = from + BUF_GAP_SIZE (buf);
@@ -1671,15 +1681,23 @@ gap_left (struct buffer *buf, Bytind pos)
       /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
       if (i > GAP_MOVE_CHUNK)
        i = GAP_MOVE_CHUNK;
-
-      if (i >= 128)
+#ifdef GAP_USE_BCOPY
+      if (i >= 128
+         /* bcopy is safe if the two areas of memory do not overlap
+            or on systems where bcopy is always safe for moving upward.  */
+         && (BCOPY_UPWARD_SAFE
+             || to - from >= 128))
        {
+         /* If overlap is not safe, avoid it by not moving too many
+            characters at once.  */
+         if (!BCOPY_UPWARD_SAFE && i > to - from)
+           i = to - from;
          new_s1 -= i;
-         from   -= i;
-         to     -= i;
+         from -= i, to -= i;
          memmove (to, from, i);
        }
       else
+#endif
        {
          new_s1 -= i;
          while (--i >= 0)
@@ -1690,22 +1708,13 @@ gap_left (struct buffer *buf, Bytind pos)
   /* Adjust markers, and buffer data structure, to put the gap at POS.
      POS is where the loop above stopped, which may be what was specified
      or may be where a quit was detected.  */
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      adjust_markers (mbuf, pos, BI_BUF_GPT (mbuf), BUF_GAP_SIZE (mbuf));
-    }
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      adjust_extents (make_buffer (mbuf), pos, BI_BUF_GPT (mbuf),
-                     BUF_GAP_SIZE (mbuf));
-    }
+  adjust_markers (buf, pos, BI_BUF_GPT (buf), BUF_GAP_SIZE (buf));
+  adjust_extents (make_buffer (buf), pos, BI_BUF_GPT (buf),
+                 BUF_GAP_SIZE (buf));
   SET_BI_BUF_GPT (buf, pos);
   SET_GAP_SENTINEL (buf);
 #ifdef ERROR_CHECK_EXTENTS
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      sledgehammer_extent_check (make_buffer (mbuf));
-    }
+  sledgehammer_extent_check (make_buffer (buf));
 #endif
   QUIT;
 }
@@ -1716,8 +1725,6 @@ gap_right (struct buffer *buf, Bytind pos)
   Bufbyte *to, *from;
   Bytecount i;
   Bytind new_s1;
-  struct buffer *mbuf;
-  Lisp_Object bufcons;
 
   to = BUF_GPT_ADDR (buf);
   from = to + BUF_GAP_SIZE (buf);
@@ -1742,15 +1749,23 @@ gap_right (struct buffer *buf, Bytind pos)
       /* Move at most GAP_MOVE_CHUNK chars before checking again for a quit. */
       if (i > GAP_MOVE_CHUNK)
        i = GAP_MOVE_CHUNK;
-
-      if (i >= 128)
+#ifdef GAP_USE_BCOPY
+      if (i >= 128
+         /* bcopy is safe if the two areas of memory do not overlap
+            or on systems where bcopy is always safe for moving downward. */
+         && (BCOPY_DOWNWARD_SAFE
+             || from - to >= 128))
        {
+         /* If overlap is not safe, avoid it by not moving too many
+            characters at once.  */
+         if (!BCOPY_DOWNWARD_SAFE && i > from - to)
+           i = from - to;
          new_s1 += i;
          memmove (to, from, i);
-         from += i;
-         to   += i;
+         from += i, to += i;
        }
       else
+#endif
        {
          new_s1 += i;
          while (--i >= 0)
@@ -1760,22 +1775,13 @@ gap_right (struct buffer *buf, Bytind pos)
 
   {
     int gsize = BUF_GAP_SIZE (buf);
-    MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-      {
-       adjust_markers (mbuf, BI_BUF_GPT (mbuf) + gsize, pos + gsize, - gsize);
-      }
-    MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-      {
-       adjust_extents (make_buffer (mbuf), BI_BUF_GPT (mbuf) + gsize,
-                       pos + gsize, - gsize);
-      }
+    adjust_markers (buf, BI_BUF_GPT (buf) + gsize, pos + gsize, - gsize);
+    adjust_extents (make_buffer (buf), BI_BUF_GPT (buf) + gsize, pos + gsize,
+                   - gsize);
     SET_BI_BUF_GPT (buf, pos);
     SET_GAP_SENTINEL (buf);
 #ifdef ERROR_CHECK_EXTENTS
-    MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-      {
-       sledgehammer_extent_check (make_buffer (mbuf));
-      }
+    sledgehammer_extent_check (make_buffer (buf));
 #endif
   }
   if (pos == BI_BUF_Z (buf))
@@ -1858,7 +1864,7 @@ make_gap (struct buffer *buf, Bytecount increment)
   Bytecount old_gap_size;
 
   /* If we have to get more space, get enough to last a while.  We use
-     a geometric progression that saves on realloc space. */
+     a geometric progession that saves on realloc space. */
   increment += 2000 + ((BI_BUF_Z (buf) - BI_BUF_BEG (buf)) / 8);
 
   if (increment > BUF_END_GAP_SIZE (buf))
@@ -2029,12 +2035,7 @@ multiple_change_finish_up (Lisp_Object buffer)
    of the specified region, that will also be handled correctly.
 
    begin_multiple_change() returns a number (actually a specpdl depth)
-   that you must pass to end_multiple_change() when you are done.
-
-   FSF Emacs 20 implements a similar feature, accessible from Lisp
-   through a `combine-after-change-calls' special form, which is
-   essentially equivalent to this function.  We should consider
-   whether we want to introduce a similar Lisp form.  */
+   that you must pass to end_multiple_change() when you are done. */
 
 int
 begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end)
@@ -2079,11 +2080,8 @@ static int inside_change_hook;
 static Lisp_Object
 change_function_restore (Lisp_Object buffer)
 {
-  /* We should first reset the variable and then change the buffer,
-     because Fset_buffer() can throw.  */
+  Fset_buffer (buffer);
   inside_change_hook = 0;
-  if (XBUFFER (buffer) != current_buffer)
-    Fset_buffer (buffer);
   return Qnil;
 }
 
@@ -2092,8 +2090,8 @@ static int in_first_change;
 static Lisp_Object
 first_change_hook_restore (Lisp_Object buffer)
 {
-  in_first_change = 0;
   Fset_buffer (buffer);
+  in_first_change = 0;
   return Qnil;
 }
 
@@ -2108,7 +2106,8 @@ signal_first_change (struct buffer *buf)
 
   if (!in_first_change)
     {
-      if (!NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer)))
+      if (!preparing_for_armageddon &&
+         !NILP (symbol_value_in_buffer (Qfirst_change_hook, buffer)))
        {
          int speccount = specpdl_depth ();
          record_unwind_protect (first_change_hook_restore, buffer);
@@ -2127,14 +2126,11 @@ static void
 signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
 {
   /* This function can GC */
-  struct buffer *mbuf;
-  Lisp_Object bufcons;
+  Lisp_Object buffer;
+  XSETBUFFER (buffer, buf);
 
   if (!inside_change_hook)
     {
-      Lisp_Object buffer;
-      int speccount;
-
       /* Are we in a multiple-change session? */
       if (buf->text->changes->in_multiple_change &&
          buf->text->changes->mc_begin != 0)
@@ -2163,52 +2159,35 @@ signal_before_change (struct buffer *buf, Bufpos start, Bufpos end)
 
       /* If buffer is unmodified, run a special hook for that case.  */
       if (BUF_SAVE_MODIFF (buf) >= BUF_MODIFF (buf))
-       {
-         MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-           {
-             signal_first_change (mbuf);
-           }
-       }
+       signal_first_change (buf);
 
       /* Now in any case run the before-change-functions if any.  */
-      speccount = specpdl_depth ();
-      record_unwind_protect (change_function_restore, Fcurrent_buffer ());
-      inside_change_hook = 1;
 
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+      if (!preparing_for_armageddon &&
+         (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer)) ||
+          /* Obsolete, for compatibility */
+          !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))))
        {
-         XSETBUFFER (buffer, mbuf);
-         if (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer))
-             /* Obsolete, for compatibility */
-             || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer)))
-           {
-             set_buffer_internal (buf);
-             va_run_hook_with_args (Qbefore_change_functions, 2,
-                                    make_int (start), make_int (end));
-             /* Obsolete, for compatibility */
-             va_run_hook_with_args (Qbefore_change_function, 2,
-                                    make_int (start), make_int (end));
-           }
-       }
-
-      /* Make sure endpoints remain valid.  before-change-functions
-        might have modified the buffer. */
-      if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
-      if (start > BUF_ZV (buf))   start = BUF_ZV (buf);
-      if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf);
-      if (end > BUF_ZV (buf))   end = BUF_ZV (buf);
-
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         XSETBUFFER (buffer, mbuf);
-         report_extent_modification (buffer, start, end, 0);
+         int speccount = specpdl_depth ();
+         record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+         set_buffer_internal (buf);
+         inside_change_hook = 1;
+         va_run_hook_with_args (Qbefore_change_functions, 2,
+                                make_int (start), make_int (end));
+         /* Obsolete, for compatibility */
+         va_run_hook_with_args (Qbefore_change_function, 2,
+                                make_int (start), make_int (end));
+         unbind_to (speccount, Qnil);
        }
-      unbind_to (speccount, Qnil);
 
       /* Only now do we indicate that the before-change-functions have
         been called, in case some function throws out. */
       buf->text->changes->mc_begin_signaled = 1;
     }
+
+  /* #### At this point we should map over extents calling
+     modification-hooks, insert-before-hooks and insert-after-hooks
+     of relevant extents */
 }
 
 /* Signal a change immediately after it happens.
@@ -2222,26 +2201,15 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
                     Bufpos new_end)
 {
   /* This function can GC */
-  struct buffer *mbuf;
-  Lisp_Object bufcons;
+  Lisp_Object buffer;
+  XSETBUFFER (buffer, buf);
 
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      /* always do this. */
-      buffer_signal_changed_region (mbuf, start, new_end);
-    }
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      /* #### This seems inefficient.  Wouldn't it be better to just
-         keep one cache per base buffer?  */
-      font_lock_maybe_update_syntactic_caches (mbuf, start, orig_end, new_end);
-    }
+  /* always do this. */
+  buffer_signal_changed_region (buf, start, new_end);
+  font_lock_maybe_update_syntactic_caches (buf, start, orig_end, new_end);
 
   if (!inside_change_hook)
     {
-      Lisp_Object buffer;
-      int speccount;
-
       if (buf->text->changes->in_multiple_change &&
          buf->text->changes->mc_begin != 0)
        {
@@ -2253,46 +2221,30 @@ signal_after_change (struct buffer *buf, Bufpos start, Bufpos orig_end,
          return; /* after-change-functions signalled when all changes done */
        }
 
-      speccount = specpdl_depth ();
-      record_unwind_protect (change_function_restore, Fcurrent_buffer ());
-      inside_change_hook = 1;
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         XSETBUFFER (buffer, mbuf);
-
-         if (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer))
-             /* Obsolete, for compatibility */
-             || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer)))
-           {
-             set_buffer_internal (buf);
-             /* The actual after-change functions take slightly
-                different arguments than what we were passed. */
-             va_run_hook_with_args (Qafter_change_functions, 3,
-                                    make_int (start), make_int (new_end),
-                                    make_int (orig_end - start));
-             /* Obsolete, for compatibility */
-             va_run_hook_with_args (Qafter_change_function, 3,
-                                    make_int (start), make_int (new_end),
-                                    make_int (orig_end - start));
-           }
-       }
-
-      /* Make sure endpoints remain valid.  after-change-functions
-        might have modified the buffer. */
-      if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
-      if (start > BUF_ZV (buf))   start = BUF_ZV (buf);
-      if (new_end < BUF_BEGV (buf)) new_end = BUF_BEGV (buf);
-      if (new_end > BUF_ZV (buf))   new_end = BUF_ZV (buf);
-      if (orig_end < BUF_BEGV (buf)) orig_end = BUF_BEGV (buf);
-      if (orig_end > BUF_ZV (buf))   orig_end = BUF_ZV (buf);
-
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+      if (!preparing_for_armageddon &&
+         (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer)) ||
+          /* Obsolete, for compatibility */
+          !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))))
        {
-         XSETBUFFER (buffer, mbuf);
-         report_extent_modification (buffer, start, new_end, 1);
+         int speccount = specpdl_depth ();
+         record_unwind_protect (change_function_restore, Fcurrent_buffer ());
+         set_buffer_internal (buf);
+         inside_change_hook = 1;
+         /* The actual after-change functions take slightly
+            different arguments than what we were passed. */
+         va_run_hook_with_args (Qafter_change_functions, 3,
+                                make_int (start), make_int (new_end),
+                                make_int (orig_end - start));
+         /* Obsolete, for compatibility */
+         va_run_hook_with_args (Qafter_change_function, 3,
+                                make_int (start), make_int (new_end),
+                                make_int (orig_end - start));
+         unbind_to (speccount, Qnil);
        }
-      unbind_to (speccount, Qnil); /* sets inside_change_hook back to 0 */
     }
+
+  /* #### At this point we should map over extents calling
+     some sort of modification hooks of relevant extents */
 }
 
 /* Call this if you're about to change the region of BUFFER from START
@@ -2308,14 +2260,10 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end,
   /* dmoore - This function can also kill the buffer buf, the current
      buffer, and do anything it pleases.  So if you call it, be
      careful. */
-  struct buffer *mbuf;
-  Lisp_Object buffer, bufcons;
+  Lisp_Object buffer;
   struct gcpro gcpro1;
 
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      barf_if_buffer_read_only (mbuf, start, end);
-    }
+  barf_if_buffer_read_only (buf, start, end);
 
   /* if this is the first modification, see about locking the buffer's
      file */
@@ -2359,10 +2307,7 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end,
   Vdeactivate_mark = Qt;
 #endif
 
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      mbuf->point_before_scroll = Qnil;
-    }
+  buf->point_before_scroll = Qnil;
 }
 
 \f
@@ -2371,7 +2316,7 @@ prepare_to_modify_buffer (struct buffer *buf, Bufpos start, Bufpos end,
 /************************************************************************/
 
 void
-fixup_internal_substring (const Bufbyte *nonreloc, Lisp_Object reloc,
+fixup_internal_substring (CONST Bufbyte *nonreloc, Lisp_Object reloc,
                          Bytecount offset, Bytecount *len)
 {
   assert ((nonreloc && NILP (reloc)) || (!nonreloc && STRINGP (reloc)));
@@ -2379,7 +2324,7 @@ fixup_internal_substring (const Bufbyte *nonreloc, Lisp_Object reloc,
   if (*len < 0)
     {
       if (nonreloc)
-       *len = strlen ((const char *) nonreloc) - offset;
+       *len = strlen ((CONST char *) nonreloc) - offset;
       else
        *len = XSTRING_LENGTH (reloc) - offset;
     }
@@ -2413,7 +2358,7 @@ fixup_internal_substring (const Bufbyte *nonreloc, Lisp_Object reloc,
 
 Charcount
 buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
-                       const Bufbyte *nonreloc, Lisp_Object reloc,
+                       CONST Bufbyte *nonreloc, Lisp_Object reloc,
                        Bytecount offset, Bytecount length,
                        int flags)
 {
@@ -2422,8 +2367,6 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
   Bytind ind;
   Charcount cclen;
   int move_point = 0;
-  struct buffer *mbuf;
-  Lisp_Object bufcons;
 
   /* Defensive steps just in case a buffer gets deleted and a calling
      function doesn't notice it. */
@@ -2448,8 +2391,7 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
   if ((length + BUF_Z (buf)) > EMACS_INT_MAX)
     error ("Maximum buffer size exceeded");
 
-  /* theoretically not necessary -- caller should GCPRO.
-     #### buffer_insert_from_buffer_1() doesn't!  */
+  /* theoretically not necessary -- caller should GCPRO */
   GCPRO1 (reloc);
 
   prepare_to_modify_buffer (buf, pos, pos, !(flags & INSDEL_NO_LOCKING));
@@ -2491,11 +2433,7 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
 
   insert_invalidate_line_number_cache (buf, pos, nonreloc + offset, length);
 
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      record_insert (mbuf, pos, cclen);
-    }
-
+  record_insert (buf, pos, cclen);
   BUF_MODIFF (buf)++;
   MARK_BUFFERS_CHANGED;
 
@@ -2507,10 +2445,7 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
 
   SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) - length);
   SET_BI_BUF_GPT (buf, BI_BUF_GPT (buf) + length);
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) + cclen, BI_BUF_ZV (mbuf) + length);
-    }
+  SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) + cclen, BI_BUF_ZV (buf) + length);
   SET_BOTH_BUF_Z (buf, BUF_Z (buf) + cclen, BI_BUF_Z (buf) + length);
   SET_GAP_SENTINEL (buf);
 
@@ -2518,48 +2453,29 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
   buffer_mule_signal_inserted_region (buf, pos, length, cclen);
 #endif
 
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      process_extents_for_insertion (make_buffer (mbuf), ind, length);
-    }
-
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      /* We know the gap is at IND so the cast is OK. */
-      adjust_markers_for_insert (mbuf, (Memind) ind, length);
-    }
+  process_extents_for_insertion (make_buffer (buf), ind, length);
+  /* We know the gap is at IND so the cast is OK. */
+  adjust_markers_for_insert (buf, (Memind) ind, length);
 
   /* Point logically doesn't move, but may need to be adjusted because
      it's a byte index.  point-marker doesn't change because it's a
      memory index. */
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      if (BI_BUF_PT (mbuf) > ind)
-       JUST_SET_POINT (mbuf, BUF_PT (mbuf) + cclen,
-                       BI_BUF_PT (mbuf) + length);
-    }
+  if (BI_BUF_PT (buf) > ind)
+    JUST_SET_POINT (buf, BUF_PT (buf) + cclen, BI_BUF_PT (buf) + length);
 
   /* Well, point might move. */
   if (move_point)
     BI_BUF_SET_PT (buf, ind + length);
 
   if (STRINGP (reloc))
-    {
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         splice_in_string_extents (reloc, mbuf, ind, length, offset);
-       }
-    }
+    splice_in_string_extents (reloc, buf, ind, length, offset);
 
   if (flags & INSDEL_BEFORE_MARKERS)
     {
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         /* ind - 1 is correct because the FROM argument is exclusive.
-            I formerly used DEC_BYTIND() but that caused problems at the
-            beginning of the buffer. */
-         adjust_markers (mbuf, ind - 1, ind, length);
-       }
+      /* ind - 1 is correct because the FROM argument is exclusive.
+        I formerly used DEC_BYTIND() but that caused problems at the
+        beginning of the buffer. */
+      adjust_markers (buf, ind - 1, ind, length);
     }
 
   signal_after_change (buf, pos, pos, pos + cclen);
@@ -2578,7 +2494,7 @@ buffer_insert_string_1 (struct buffer *buf, Bufpos pos,
 
 Charcount
 buffer_insert_raw_string_1 (struct buffer *buf, Bufpos pos,
-                           const Bufbyte *nonreloc, Bytecount length,
+                           CONST Bufbyte *nonreloc, Bytecount length,
                            int flags)
 {
   /* This function can GC */
@@ -2591,9 +2507,7 @@ buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str,
                             int flags)
 {
   /* This function can GC */
-#ifdef ERROR_CHECK_TYPECHECK
   assert (STRINGP (str));
-#endif
   return buffer_insert_string_1 (buf, pos, 0, str, 0,
                                 XSTRING_LENGTH (str),
                                 flags);
@@ -2602,12 +2516,13 @@ buffer_insert_lisp_string_1 (struct buffer *buf, Bufpos pos, Lisp_Object str,
 /* Insert the null-terminated string S (in external format). */
 
 Charcount
-buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, const char *s,
+buffer_insert_c_string_1 (struct buffer *buf, Bufpos pos, CONST char *s,
                          int flags)
 {
   /* This function can GC */
-  const char *translated = GETTEXT (s);
-  return buffer_insert_string_1 (buf, pos, (const Bufbyte *) translated, Qnil,
+
+  CONST char *translated = GETTEXT (s);
+  return buffer_insert_string_1 (buf, pos, (CONST Bufbyte *) translated, Qnil,
                                 0, strlen (translated), flags);
 }
 
@@ -2617,7 +2532,9 @@ buffer_insert_emacs_char_1 (struct buffer *buf, Bufpos pos, Emchar ch,
 {
   /* This function can GC */
   Bufbyte str[MAX_EMCHAR_LEN];
-  Bytecount len = set_charptr_emchar (str, ch);
+  Bytecount len;
+
+  len = set_charptr_emchar (str, ch);
   return buffer_insert_string_1 (buf, pos, str, Qnil, 0, len, flags);
 }
 
@@ -2656,8 +2573,7 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
   Bytind bi_from, bi_to;
   Bytecount bc_numdel;
   EMACS_INT shortage;
-  struct buffer *mbuf;
-  Lisp_Object bufcons;
+  Lisp_Object bufobj;
 
   /* Defensive steps just in case a buffer gets deleted and a calling
      function doesn't notice it. */
@@ -2688,6 +2604,8 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
   if ((numdel = to - from) <= 0)
     return;
 
+  XSETBUFFER (bufobj, buf);
+
   /* Redisplay needs to know if a newline was in the deleted region.
      If we've already marked the changed region as having a deleted
      newline there is no use in performing the check. */
@@ -2695,12 +2613,7 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
     {
       scan_buffer (buf, '\n', from, to, 1, &shortage, 1);
       if (!shortage)
-       {
-         MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-           {
-             mbuf->changes->newline_was_deleted = 1;
-           }
-       }
+       buf->changes->newline_was_deleted = 1;
     }
 
   bi_from = bufpos_to_bytind (buf, from);
@@ -2714,70 +2627,49 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
     {
       /* avoid moving the gap just to delete from the bottom. */
 
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         record_delete (mbuf, from, numdel);
-       }
+      record_delete (buf, from, numdel);
       BUF_MODIFF (buf)++;
       MARK_BUFFERS_CHANGED;
 
-      /* #### Point used to be modified here, but this causes problems
-        with MULE, as point is used to calculate bytinds, and if the
-        offset in bc_numdel causes point to move to a non first-byte
-        location, causing some other function to throw an assertion
-        in ASSERT_VALID_BYTIND. I've moved the code to right after
-        the other movements and adjustments, but before the gap is
-        moved.  -- jh 970813 */
+      /* ### Point used to be modified here, but this causes problems with MULE,
+        as point is used to calculate bytinds, and if the offset in bc_numdel causes
+        point to move to a non first-byte location, causing some other function to
+        throw an assertion in ASSERT_VALID_BYTIND. I've moved the code to right after
+         the other movements and adjustments, but before the gap is moved.
+         -- jh 970813 */
 
       /* Detach any extents that are completely within the range [FROM, TO],
         if the extents are detachable.
 
-        This must come AFTER record_delete(), so that the appropriate
-        extents will be present to be recorded, and BEFORE the gap
-        size is increased, as otherwise we will be confused about
-        where the extents end. */
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0);
-       }
+        This must come AFTER record_delete(), so that the appropriate extents
+        will be present to be recorded, and BEFORE the gap size is increased,
+        as otherwise we will be confused about where the extents end. */
+      process_extents_for_deletion (bufobj, bi_from, bi_to, 0);
 
-      /* Relocate all markers pointing into the new, larger gap to
-        point at the end of the text before the gap.  */
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         adjust_markers (mbuf,
-                         (bi_to + BUF_GAP_SIZE (mbuf)),
-                         (bi_to + BUF_GAP_SIZE (mbuf)),
-                         (- bc_numdel));
-       }
+      /* Relocate all markers pointing into the new, larger gap
+        to point at the end of the text before the gap.  */
+      adjust_markers (buf,
+                     (bi_to + BUF_GAP_SIZE (buf)),
+                     (bi_to + BUF_GAP_SIZE (buf)),
+                     (- bc_numdel));
 
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         /* Relocate any extent endpoints just like markers. */
-         adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to,
-                                      BUF_GAP_SIZE (mbuf), bc_numdel, 0);
-       }
+      /* Relocate any extent endpoints just like markers. */
+      adjust_extents_for_deletion (bufobj, bi_from, bi_to,
+                                  BUF_GAP_SIZE (buf), bc_numdel, 0);
 
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+      /* Relocate point as if it were a marker.  */
+      if (bi_from < BI_BUF_PT (buf))
        {
-         /* Relocate point as if it were a marker.  */
-         if (bi_from < BI_BUF_PT (mbuf))
-           {
-             if (BI_BUF_PT (mbuf) < bi_to)
-               JUST_SET_POINT (mbuf, from, bi_from);
-             else
-               JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel,
-                               BI_BUF_PT (mbuf) - bc_numdel);
-           }
+         if (BI_BUF_PT (buf) < bi_to)
+           JUST_SET_POINT (buf, from, bi_from);
+         else
+           JUST_SET_POINT (buf, BUF_PT (buf) - numdel,
+                           BI_BUF_PT (buf) - bc_numdel);
        }
 
       SET_BUF_END_GAP_SIZE (buf, BUF_END_GAP_SIZE (buf) + bc_numdel);
 
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel,
-                          BI_BUF_ZV (mbuf) - bc_numdel);
-       }
+      SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) - numdel, BI_BUF_ZV (buf) - bc_numdel);
       SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel);
       SET_GAP_SENTINEL (buf);
     }
@@ -2789,20 +2681,16 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
       if (bi_from > BI_BUF_GPT (buf))
        gap_right (buf, bi_from);
 
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         record_delete (mbuf, from, numdel);
-       }
+      record_delete (buf, from, numdel);
       BUF_MODIFF (buf)++;
       MARK_BUFFERS_CHANGED;
 
-      /* #### Point used to be modified here, but this causes problems
-        with MULE, as point is used to calculate bytinds, and if the
-        offset in bc_numdel causes point to move to a non first-byte
-        location, causing some other function to throw an assertion
-        in ASSERT_VALID_BYTIND. I've moved the code to right after
-        the other movements and adjustments, but before the gap is
-        moved.  -- jh 970813 */
+      /* ### Point used to be modified here, but this causes problems with MULE,
+        as point is used to calculate bytinds, and if the offset in bc_numdel causes
+        point to move to a non first-byte location, causing some other function to
+        throw an assertion in ASSERT_VALID_BYTIND. I've moved the code to right after
+         the other movements and adjustments, but before the gap is moved.
+         -- jh 970813 */
 
       /* Detach any extents that are completely within the range [FROM, TO],
         if the extents are detachable.
@@ -2810,48 +2698,31 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
         This must come AFTER record_delete(), so that the appropriate extents
         will be present to be recorded, and BEFORE the gap size is increased,
         as otherwise we will be confused about where the extents end. */
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         process_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to, 0);
-       }
+      process_extents_for_deletion (bufobj, bi_from, bi_to, 0);
 
-      /* Relocate all markers pointing into the new, larger gap to
-        point at the end of the text before the gap.  */
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         adjust_markers (mbuf,
-                         (bi_to + BUF_GAP_SIZE (mbuf)),
-                         (bi_to + BUF_GAP_SIZE (mbuf)),
-                         (- bc_numdel - BUF_GAP_SIZE (mbuf)));
-       }
+      /* Relocate all markers pointing into the new, larger gap
+        to point at the end of the text before the gap.  */
+      adjust_markers (buf,
+                     (bi_to + BUF_GAP_SIZE (buf)),
+                     (bi_to + BUF_GAP_SIZE (buf)),
+                     (- bc_numdel - BUF_GAP_SIZE (buf)));
 
       /* Relocate any extent endpoints just like markers. */
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         adjust_extents_for_deletion (make_buffer (mbuf), bi_from, bi_to,
-                                      BUF_GAP_SIZE (mbuf),
-                                      bc_numdel, BUF_GAP_SIZE (mbuf));
-       }
+      adjust_extents_for_deletion (bufobj, bi_from, bi_to, BUF_GAP_SIZE (buf),
+                                  bc_numdel, BUF_GAP_SIZE (buf));
 
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
+      /* Relocate point as if it were a marker.  */
+      if (bi_from < BI_BUF_PT (buf))
        {
-         /* Relocate point as if it were a marker.  */
-         if (bi_from < BI_BUF_PT (mbuf))
-           {
-             if (BI_BUF_PT (mbuf) < bi_to)
-               JUST_SET_POINT (mbuf, from, bi_from);
-             else
-               JUST_SET_POINT (mbuf, BUF_PT (mbuf) - numdel,
-                               BI_BUF_PT (mbuf) - bc_numdel);
-           }
+         if (BI_BUF_PT (buf) < bi_to)
+           JUST_SET_POINT (buf, from, bi_from);
+         else
+           JUST_SET_POINT (buf, BUF_PT (buf) - numdel,
+                           BI_BUF_PT (buf) - bc_numdel);
        }
 
       SET_BUF_GAP_SIZE (buf, BUF_GAP_SIZE (buf) + bc_numdel);
-      MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-       {
-         SET_BOTH_BUF_ZV (mbuf, BUF_ZV (mbuf) - numdel,
-                          BI_BUF_ZV (mbuf) - bc_numdel);
-       }
+      SET_BOTH_BUF_ZV (buf, BUF_ZV (buf) - numdel, BI_BUF_ZV (buf) - bc_numdel);
       SET_BOTH_BUF_Z (buf, BUF_Z (buf) - numdel, BI_BUF_Z (buf) - bc_numdel);
       SET_BI_BUF_GPT (buf, bi_from);
       SET_GAP_SENTINEL (buf);
@@ -2862,10 +2733,7 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
 #endif
 
 #ifdef ERROR_CHECK_EXTENTS
-  MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-    {
-      sledgehammer_extent_check (make_buffer (mbuf));
-    }
+  sledgehammer_extent_check (bufobj);
 #endif
 
   signal_after_change (buf, from, to, from);
@@ -2879,7 +2747,7 @@ buffer_delete_range (struct buffer *buf, Bufpos from, Bufpos to, int flags)
 /* Replace the character at POS in buffer B with CH. */
 
 void
-buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch,
+buffer_replace_char (struct buffer *b, Bufpos pos, Emchar ch,
                     int not_real_change, int force_lock_check)
 {
   /* This function can GC */
@@ -2889,54 +2757,42 @@ buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch,
 
   /* Defensive steps just in case a buffer gets deleted and a calling
      function doesn't notice it. */
-  if (!BUFFER_LIVE_P (buf))
+  if (!BUFFER_LIVE_P (b))
     return;
 
-  curlen = BUF_CHARPTR_COPY_CHAR (buf, pos, curstr);
+  curlen = BUF_CHARPTR_COPY_CHAR (b, pos, curstr);
   newlen = set_charptr_emchar (newstr, ch);
 
   if (curlen == newlen)
     {
-      struct buffer *mbuf;
-      Lisp_Object bufcons;
-
       /* then we can just replace the text. */
-      prepare_to_modify_buffer (buf, pos, pos + 1,
+      prepare_to_modify_buffer (b, pos, pos + 1,
                                !not_real_change || force_lock_check);
       /* Defensive steps in case the before-change-functions fuck around */
-      if (!BUFFER_LIVE_P (buf))
+      if (!BUFFER_LIVE_P (b))
        /* Bad bad pre-change function. */
        return;
 
       /* Make args be valid again.  prepare_to_modify_buffer() might have
         modified the buffer. */
-      if (pos < BUF_BEGV (buf))
-       pos = BUF_BEGV (buf);
-      if (pos >= BUF_ZV (buf))
-       pos = BUF_ZV (buf) - 1;
-      if (pos < BUF_BEGV (buf))
+      if (pos < BUF_BEGV (b))
+       pos = BUF_BEGV (b);
+      if (pos >= BUF_ZV (b))
+       pos = BUF_ZV (b) - 1;
+      if (pos < BUF_BEGV (b))
        /* no more characters in buffer! */
        return;
 
-      if (BUF_FETCH_CHAR (buf, pos) == '\n')
-       {
-         MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-           {
-             mbuf->changes->newline_was_deleted = 1;
-           }
-       }
+      if (BUF_FETCH_CHAR (b, pos) == '\n')
+       b->changes->newline_was_deleted = 1;
       MARK_BUFFERS_CHANGED;
       if (!not_real_change)
        {
-         MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
-           {
-             record_change (mbuf, pos, 1);
-           }
-         BUF_MODIFF (buf)++;
+         record_change (b, pos, 1);
+         BUF_MODIFF (b)++;
        }
-      memcpy (BUF_BYTE_ADDRESS (buf, pos), newstr, newlen);
-
-      signal_after_change (buf, pos, pos + 1, pos + 1);
+      memcpy (BUF_BYTE_ADDRESS (b, pos), newstr, newlen);
+      signal_after_change (b, pos, pos + 1, pos + 1);
 
       /* We do not have to adjust the Mule data; we just replaced a
         character with another of the same number of bytes. */
@@ -2951,21 +2807,21 @@ buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch,
        * point.  Point will drift backward by one position and stay
        * there otherwise.
        */
-      int movepoint = (pos == BUF_PT (buf) - 1);
+      int movepoint = (pos == BUF_PT (b) - 1);
 
-      buffer_delete_range (buf, pos, pos + 1, 0);
+      buffer_delete_range (b, pos, pos + 1, 0);
       /* Defensive steps in case the before-change-functions fuck around */
-      if (!BUFFER_LIVE_P (buf))
+      if (!BUFFER_LIVE_P (b))
        /* Bad bad pre-change function. */
        return;
 
       /* Make args be valid again.  prepare_to_modify_buffer() might have
         modified the buffer. */
-      if (pos < BUF_BEGV (buf))
-       pos = BUF_BEGV (buf);
-      if (pos >= BUF_ZV (buf))
-       pos = BUF_ZV (buf) - 1;
-      if (pos < BUF_BEGV (buf))
+      if (pos < BUF_BEGV (b))
+       pos = BUF_BEGV (b);
+      if (pos >= BUF_ZV (b))
+       pos = BUF_ZV (b) - 1;
+      if (pos < BUF_BEGV (b))
        /* no more characters in buffer! */
        return;
       /*
@@ -2973,7 +2829,7 @@ buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch,
        * insertion, which we must do if the deletion moved point
        * backward so that it now equals the insertion point.
        */
-      buffer_insert_string_1 (buf, (movepoint ? -1 : pos),
+      buffer_insert_string_1 (b, (movepoint ? -1 : pos),
                              newstr, Qnil, 0, newlen, 0);
     }
 }
@@ -2986,20 +2842,22 @@ buffer_replace_char (struct buffer *buf, Bufpos pos, Emchar ch,
 /* Make a string from a buffer.  This needs to take into account the gap,
    and add any necessary extents from the buffer. */
 
-static Lisp_Object
-make_string_from_buffer_1 (struct buffer *buf, Bufpos pos, Charcount length,
-                          int no_extents)
+Lisp_Object
+make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
 {
   /* This function can GC */
-  Bytind    bi_ind = bufpos_to_bytind (buf, pos);
-  Bytecount bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind;
-  Lisp_Object  val = make_uninit_string (bi_len);
-
+  Lisp_Object val;
   struct gcpro gcpro1;
+  Bytind bi_ind;
+  Bytecount bi_len;
+
+  bi_ind = bufpos_to_bytind (buf, pos);
+  bi_len = bufpos_to_bytind (buf, pos + length) - bi_ind;
+
+  val = make_uninit_string (bi_len);
   GCPRO1 (val);
 
-  if (!no_extents)
-    add_string_extents (val, buf, bi_ind, bi_len);
+  add_string_extents (val, buf, bi_ind, bi_len);
 
   {
     Bytecount len1 = BI_BUF_GPT (buf) - bi_ind;
@@ -3031,19 +2889,6 @@ make_string_from_buffer_1 (struct buffer *buf, Bufpos pos, Charcount length,
   return val;
 }
 
-Lisp_Object
-make_string_from_buffer (struct buffer *buf, Bufpos pos, Charcount length)
-{
-  return make_string_from_buffer_1 (buf, pos, length, 0);
-}
-
-Lisp_Object
-make_string_from_buffer_no_extents (struct buffer *buf, Bufpos pos,
-                                   Charcount length)
-{
-  return make_string_from_buffer_1 (buf, pos, length, 1);
-}
-
 void
 barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to)
 {
@@ -3073,23 +2918,16 @@ barf_if_buffer_read_only (struct buffer *buf, Bufpos from, Bufpos to)
 }
 
 void
-find_charsets_in_bufbyte_string (unsigned char *charsets, const Bufbyte *str,
+find_charsets_in_bufbyte_string (unsigned char *charsets, CONST Bufbyte *str,
                                 Bytecount len)
 {
 #ifndef MULE
   /* Telescope this. */
   charsets[0] = 1;
 #else
-  const Bufbyte *strend = str + len;
+  CONST Bufbyte *strend = str + len;
   memset (charsets, 0, NUM_LEADING_BYTES);
 
-  /* #### SJT doesn't like this. */
-  if (len == 0)
-    {
-      charsets[XCHARSET_LEADING_BYTE (Vcharset_ascii) - 128] = 1;
-      return;
-    }
-
   while (str < strend)
     {
       charsets[CHAR_LEADING_BYTE (charptr_emchar (str)) - 128] = 1;
@@ -3099,7 +2937,7 @@ find_charsets_in_bufbyte_string (unsigned char *charsets, const Bufbyte *str,
 }
 
 void
-find_charsets_in_emchar_string (unsigned char *charsets, const Emchar *str,
+find_charsets_in_emchar_string (unsigned char *charsets, CONST Emchar *str,
                                Charcount len)
 {
 #ifndef MULE
@@ -3109,14 +2947,6 @@ find_charsets_in_emchar_string (unsigned char *charsets, const Emchar *str,
   int i;
 
   memset (charsets, 0, NUM_LEADING_BYTES);
-
-  /* #### SJT doesn't like this. */
-  if (len == 0)
-    {
-      charsets[XCHARSET_LEADING_BYTE (Vcharset_ascii) - 128] = 1;
-      return;
-    }
-
   for (i = 0; i < len; i++)
     {
       charsets[CHAR_LEADING_BYTE (str[i]) - 128] = 1;
@@ -3125,10 +2955,10 @@ find_charsets_in_emchar_string (unsigned char *charsets, const Emchar *str,
 }
 
 int
-bufbyte_string_displayed_columns (const Bufbyte *str, Bytecount len)
+bufbyte_string_displayed_columns (CONST Bufbyte *str, Bytecount len)
 {
   int cols = 0;
-  const Bufbyte *end = str + len;
+  CONST Bufbyte *end = str + len;
 
   while (str < end)
     {
@@ -3145,7 +2975,7 @@ bufbyte_string_displayed_columns (const Bufbyte *str, Bytecount len)
 }
 
 int
-emchar_string_displayed_columns (const Emchar *str, Charcount len)
+emchar_string_displayed_columns (CONST Emchar *str, Charcount len)
 {
 #ifdef MULE
   int cols = 0;
@@ -3163,10 +2993,10 @@ emchar_string_displayed_columns (const Emchar *str, Charcount len)
 /* NOTE: Does not reset the Dynarr. */
 
 void
-convert_bufbyte_string_into_emchar_dynarr (const Bufbyte *str, Bytecount len,
+convert_bufbyte_string_into_emchar_dynarr (CONST Bufbyte *str, Bytecount len,
                                           Emchar_dynarr *dyn)
 {
-  const Bufbyte *strend = str + len;
+  CONST Bufbyte *strend = str + len;
 
   while (str < strend)
     {
@@ -3176,11 +3006,11 @@ convert_bufbyte_string_into_emchar_dynarr (const Bufbyte *str, Bytecount len,
     }
 }
 
-Charcount
-convert_bufbyte_string_into_emchar_string (const Bufbyte *str, Bytecount len,
+int
+convert_bufbyte_string_into_emchar_string (CONST Bufbyte *str, Bytecount len,
                                           Emchar *arr)
 {
-  const Bufbyte *strend = str + len;
+  CONST Bufbyte *strend = str + len;
   Charcount newlen = 0;
   while (str < strend)
     {
@@ -3243,7 +3073,7 @@ convert_emchar_string_into_malloced_string (Emchar *arr, int nels,
 /************************************************************************/
 
 void
-reinit_vars_of_insdel (void)
+vars_of_insdel (void)
 {
   int i;
 
@@ -3255,15 +3085,9 @@ reinit_vars_of_insdel (void)
 }
 
 void
-vars_of_insdel (void)
-{
-  reinit_vars_of_insdel ();
-}
-
-void
-init_buffer_text (struct buffer *b)
+init_buffer_text (struct buffer *b, int indirect_p)
 {
-  if (!b->base_buffer)
+  if (!indirect_p)
     {
       SET_BUF_GAP_SIZE (b, 20);
       BUFFER_ALLOC (b->text->beg, BUF_GAP_SIZE (b) + BUF_END_SENTINEL_SIZE);
@@ -3291,7 +3115,6 @@ init_buffer_text (struct buffer *b)
          }
       }
 #endif /* MULE */
-      b->text->line_number_cache = Qnil;
 
       BUF_MODIFF (b) = 1;
       BUF_SAVE_MODIFF (b) = 1;
@@ -3322,9 +3145,9 @@ init_buffer_text (struct buffer *b)
 }
 
 void
-uninit_buffer_text (struct buffer *b)
+uninit_buffer_text (struct buffer *b, int indirect_p)
 {
-  if (!b->base_buffer)
+  if (!indirect_p)
     {
       BUFFER_FREE (b->text->beg);
       xfree (b->text->changes);