New macro to iterate over all buffers, miscellaneous cleanups.
[bpt/emacs.git] / src / buffer.h
index 73628fe..8c59683 100644 (file)
@@ -1,6 +1,6 @@
 /* Header file for the buffer manipulation primitives.
 
-Copyright (C) 1985-1986, 1993-1995, 1997-2011
+Copyright (C) 1985-1986, 1993-1995, 1997-2012
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -19,6 +19,7 @@ You should have received a copy of the GNU General Public License
 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <sys/types.h> /* for off_t, time_t */
+#include "systime.h" /* for EMACS_TIME */
 
 /* Accessing the parameters of the current buffer.  */
 
@@ -245,12 +246,12 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define BUF_TEMP_SET_PT(buffer, position) \
   (temp_set_point ((buffer), (position)))
 
-extern void set_point (EMACS_INT);
-extern void temp_set_point (struct buffer *, EMACS_INT);
-extern void set_point_both (EMACS_INT, EMACS_INT);
+extern void set_point (ptrdiff_t);
+extern void temp_set_point (struct buffer *, ptrdiff_t);
+extern void set_point_both (ptrdiff_t, ptrdiff_t);
 extern void temp_set_point_both (struct buffer *,
-                                EMACS_INT, EMACS_INT);
-extern void enlarge_buffer_text (struct buffer *, EMACS_INT);
+                                ptrdiff_t, ptrdiff_t);
+extern void enlarge_buffer_text (struct buffer *, ptrdiff_t);
 
 \f
 /* Macros for setting the BEGV, ZV or PT of a given buffer.
@@ -343,7 +344,8 @@ while (0)
  - (ptr - (current_buffer)->text->beg <= GPT_BYTE - BEG_BYTE ? 0 : GAP_SIZE) \
  + BEG_BYTE)
 
-/* Return character at byte position POS.  */
+/* Return character at byte position POS.  See the caveat WARNING for
+   FETCH_MULTIBYTE_CHAR below.  */
 
 #define FETCH_CHAR(pos)                                        \
   (!NILP (BVAR (current_buffer, enable_multibyte_characters))  \
@@ -354,18 +356,6 @@ while (0)
 
 #define FETCH_BYTE(n) *(BYTE_POS_ADDR ((n)))
 
-/* Variables used locally in FETCH_MULTIBYTE_CHAR.  */
-extern unsigned char *_fetch_multibyte_char_p;
-
-/* Return character code of multi-byte form at byte position POS.  If POS
-   doesn't point the head of valid multi-byte form, only the byte at
-   POS is returned.  No range checking.  */
-
-#define FETCH_MULTIBYTE_CHAR(pos)                                      \
-  (_fetch_multibyte_char_p = (((pos) >= GPT_BYTE ? GAP_SIZE : 0)       \
-                              + (pos) + BEG_ADDR - BEG_BYTE),          \
-   STRING_CHAR (_fetch_multibyte_char_p))
-
 /* Return character at byte position POS.  If the current buffer is unibyte
    and the character is not ASCII, make the returning character
    multibyte.  */
@@ -414,16 +404,6 @@ extern unsigned char *_fetch_multibyte_char_p;
 
 #define BUF_FETCH_BYTE(buf, n) \
   *(BUF_BYTE_ADDRESS ((buf), (n)))
-
-/* Return character code of multi-byte form at byte position POS in BUF.
-   If POS doesn't point the head of valid multi-byte form, only the byte at
-   POS is returned.  No range checking.  */
-
-#define BUF_FETCH_MULTIBYTE_CHAR(buf, pos)                             \
-  (_fetch_multibyte_char_p                                             \
-     = (((pos) >= BUF_GPT_BYTE (buf) ? BUF_GAP_SIZE (buf) : 0)         \
-        + (pos) + BUF_BEG_ADDR (buf) - BEG_BYTE),                      \
-   STRING_CHAR (_fetch_multibyte_char_p))
 \f
 /* Define the actual buffer data structures.  */
 
@@ -438,38 +418,38 @@ struct buffer_text
        into a buffer's text to functions that malloc.  */
     unsigned char *beg;
 
-    EMACS_INT gpt;             /* Char pos of gap in buffer.  */
-    EMACS_INT z;               /* Char pos of end of buffer.  */
-    EMACS_INT gpt_byte;                /* Byte pos of gap in buffer.  */
-    EMACS_INT z_byte;          /* Byte pos of end of buffer.  */
-    EMACS_INT gap_size;                /* Size of buffer's gap.  */
-    int modiff;                        /* This counts buffer-modification events
+    ptrdiff_t gpt;             /* Char pos of gap in buffer.  */
+    ptrdiff_t z;               /* Char pos of end of buffer.  */
+    ptrdiff_t gpt_byte;                /* Byte pos of gap in buffer.  */
+    ptrdiff_t z_byte;          /* Byte pos of end of buffer.  */
+    ptrdiff_t gap_size;                /* Size of buffer's gap.  */
+    EMACS_INT modiff;          /* This counts buffer-modification events
                                   for this buffer.  It is incremented for
                                   each such event, and never otherwise
                                   changed.  */
-    int chars_modiff;           /* This is modified with character change
+    EMACS_INT chars_modiff;    /* This is modified with character change
                                   events for this buffer.  It is set to
                                   modiff for each such event, and never
                                   otherwise changed.  */
-    int save_modiff;           /* Previous value of modiff, as of last
+    EMACS_INT save_modiff;     /* Previous value of modiff, as of last
                                   time buffer visited or saved a file.  */
 
-    int overlay_modiff;                /* Counts modifications to overlays.  */
+    EMACS_INT overlay_modiff;  /* Counts modifications to overlays.  */
 
     /* Minimum value of GPT - BEG since last redisplay that finished.  */
-    EMACS_INT beg_unchanged;
+    ptrdiff_t beg_unchanged;
 
     /* Minimum value of Z - GPT since last redisplay that finished.  */
-    EMACS_INT end_unchanged;
+    ptrdiff_t end_unchanged;
 
     /* MODIFF as of last redisplay that finished; if it matches MODIFF,
        beg_unchanged and end_unchanged contain no useful information.  */
-    int unchanged_modified;
+    EMACS_INT unchanged_modified;
 
     /* BUF_OVERLAY_MODIFF of current buffer, as of last redisplay that
        finished; if it matches BUF_OVERLAY_MODIFF, beg_unchanged and
        end_unchanged contain no useful information.  */
-    int overlay_unchanged_modified;
+    EMACS_INT overlay_unchanged_modified;
 
     /* Properties of this buffer's text.  */
     INTERVAL intervals;
@@ -502,139 +482,26 @@ struct buffer_text
 
 struct buffer
 {
-  /* Everything before the `name' slot must be of a non-Lisp_Object type,
-     and every slot after `name' must be a Lisp_Object.
-
-     Check out mark_buffer (alloc.c) to see why.  */
-
-  /* HEADER.NEXT is the next buffer, in chain of all buffers,
-     including killed buffers.
-     This chain is used only for garbage collection, in order to
-     collect killed buffers properly.
-     Note that vectors and most pseudovectors are all on one chain,
-     but buffers are on a separate chain of their own.  */
+  /* HEADER.NEXT is the next buffer, in chain of all buffers, including killed
+     buffers.  This chain, starting from all_buffers, is used only for garbage
+     collection, in order to collect killed buffers properly.  Note that large
+     vectors and large pseudo-vector objects are all on another chain starting
+     from large_vectors.  */
   struct vectorlike_header header;
 
-  /* This structure holds the coordinates of the buffer contents
-     in ordinary buffers.  In indirect buffers, this is not used.  */
-  struct buffer_text own_text;
-
-  /* This points to the `struct buffer_text' that used for this buffer.
-     In an ordinary buffer, this is the own_text field above.
-     In an indirect buffer, this is the own_text field of another buffer.  */
-  struct buffer_text *text;
-
-  /* Char position of point in buffer.  */
-  EMACS_INT pt;
-  /* Byte position of point in buffer.  */
-  EMACS_INT pt_byte;
-  /* Char position of beginning of accessible range.  */
-  EMACS_INT begv;
-  /* Byte position of beginning of accessible range.  */
-  EMACS_INT begv_byte;
-  /* Char position of end of accessible range.  */
-  EMACS_INT zv;
-  /* Byte position of end of accessible range.  */
-  EMACS_INT zv_byte;
-
-  /* In an indirect buffer, this points to the base buffer.
-     In an ordinary buffer, it is 0.  */
-  struct buffer *base_buffer;
-
-  /* A non-zero value in slot IDX means that per-buffer variable
-     with index IDX has a local value in this buffer.  The index IDX
-     for a buffer-local variable is stored in that variable's slot
-     in buffer_local_flags as a Lisp integer.  If the index is -1,
-     this means the variable is always local in all buffers.  */
-#define MAX_PER_BUFFER_VARS 50
-  char local_flags[MAX_PER_BUFFER_VARS];
-
-  /* Set to the modtime of the visited file when read or written.
-     -1 means visited file was nonexistent.
-     0 means visited file modtime unknown; in no case complain
-     about any mismatch on next save attempt.  */
-  time_t modtime;
-  /* Size of the file when modtime was set.  This is used to detect the
-     case where the file grew while we were reading it, so the modtime
-     is still the same (since it's rounded up to seconds) but we're actually
-     not up-to-date.  -1 means the size is unknown.  Only meaningful if
-     modtime is actually set.  */
-  off_t modtime_size;
-  /* The value of text->modiff at the last auto-save.  */
-  int auto_save_modified;
-  /* The value of text->modiff at the last display error.
-     Redisplay of this buffer is inhibited until it changes again.  */
-  int display_error_modiff;
-  /* The time at which we detected a failure to auto-save,
-     Or -1 if we didn't have a failure.  */
-  int auto_save_failure_time;
-  /* Position in buffer at which display started
-     the last time this buffer was displayed.  */
-  EMACS_INT last_window_start;
-
-  /* Set nonzero whenever the narrowing is changed in this buffer.  */
-  int clip_changed;
-
-  /* If the long line scan cache is enabled (i.e. the buffer-local
-     variable cache-long-line-scans is non-nil), newline_cache
-     points to the newline cache, and width_run_cache points to the
-     width run cache.
-
-     The newline cache records which stretches of the buffer are
-     known *not* to contain newlines, so that they can be skipped
-     quickly when we search for newlines.
-
-     The width run cache records which stretches of the buffer are
-     known to contain characters whose widths are all the same.  If
-     the width run cache maps a character to a value > 0, that value is
-     the character's width; if it maps a character to zero, we don't
-     know what its width is.  This allows compute_motion to process
-     such regions very quickly, using algebra instead of inspecting
-     each character.   See also width_table, below.  */
-  struct region_cache *newline_cache;
-  struct region_cache *width_run_cache;
-
-  /* Non-zero means don't use redisplay optimizations for
-     displaying this buffer.  */
-  unsigned prevent_redisplay_optimizations_p : 1;
-
-  /* List of overlays that end at or before the current center,
-     in order of end-position.  */
-  struct Lisp_Overlay *overlays_before;
-
-  /* List of overlays that end after  the current center,
-     in order of start-position.  */
-  struct Lisp_Overlay *overlays_after;
-
-  /* Position where the overlay lists are centered.  */
-  EMACS_INT overlay_center;
-
-  /* Everything from here down must be a Lisp_Object.  */
-  /* buffer-local Lisp variables start at `undo_list',
-     tho only the ones from `name' on are GC'd normally.  */
-  #define FIRST_FIELD_PER_BUFFER undo_list
-
-  /* Changes in the buffer are recorded here for undo.
-     t means don't record anything.
-     This information belongs to the base buffer of an indirect buffer,
-     But we can't store it in the  struct buffer_text
-     because local variables have to be right in the  struct buffer.
-     So we copy it around in set_buffer_internal.
-     This comes before `name' because it is marked in a special way.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (undo_list);
-
   /* The name of this buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (name);
 
   /* The name of the file visited in this buffer, or nil.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (filename);
-  /* Dir for expanding relative file names.  */
+
+  /* Directory for expanding relative file names.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (directory);
-  /* True if this buffer has been backed up (if you write to the
-     visited file and it hasn't been backed up, then a backup will
-     be made).  */
-  /* This isn't really used by the C code, so could be deleted.  */
+
+  /* True if this buffer has been backed up (if you write to the visited
+     file and it hasn't been backed up, then a backup will be made).  */
   Lisp_Object BUFFER_INTERNAL_FIELD (backed_up);
+
   /* Length of file when last read or saved.
      -1 means auto saving turned off because buffer shrank a lot.
      -2 means don't turn off auto saving if buffer shrinks.
@@ -642,6 +509,7 @@ struct buffer
      This is not in the  struct buffer_text
      because it's not used in indirect buffers at all.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (save_length);
+
   /* File name used for auto-saving this buffer.
      This is not in the  struct buffer_text
      because it's not used in indirect buffers at all.  */
@@ -649,6 +517,7 @@ struct buffer
 
   /* Non-nil if buffer read-only.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (read_only);
+
   /* "The mark".  This is a marker which may
      point into this buffer or may point nowhere.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (mark);
@@ -658,10 +527,12 @@ struct buffer
      symbols, just the symbol appears as the element.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (local_var_alist);
 
-  /* Symbol naming major mode (eg, lisp-mode).  */
+  /* Symbol naming major mode (e.g., lisp-mode).  */
   Lisp_Object BUFFER_INTERNAL_FIELD (major_mode);
-  /* Pretty name of major mode (eg, "Lisp"). */
+
+  /* Pretty name of major mode (e.g., "Lisp"). */
   Lisp_Object BUFFER_INTERNAL_FIELD (mode_name);
+
   /* Mode line element that controls format of mode line.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (mode_line_format);
 
@@ -671,10 +542,13 @@ struct buffer
 
   /* Keys that are bound local to this buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (keymap);
+
   /* This buffer's local abbrev table.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (abbrev_table);
+
   /* This buffer's syntax table.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (syntax_table);
+
   /* This buffer's category table.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (category_table);
 
@@ -685,48 +559,61 @@ struct buffer
   Lisp_Object BUFFER_INTERNAL_FIELD (tab_width);
   Lisp_Object BUFFER_INTERNAL_FIELD (fill_column);
   Lisp_Object BUFFER_INTERNAL_FIELD (left_margin);
+
   /* Function to call when insert space past fill column.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (auto_fill_function);
 
   /* Case table for case-conversion in this buffer.
      This char-table maps each char into its lower-case version.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (downcase_table);
+
   /* Char-table mapping each char to its upper-case version.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (upcase_table);
+
   /* Char-table for conversion for case-folding search.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (case_canon_table);
+
   /* Char-table of equivalences for case-folding search.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (case_eqv_table);
 
   /* Non-nil means do not display continuation lines.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (truncate_lines);
+
   /* Non-nil means to use word wrapping when displaying continuation lines.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (word_wrap);
+
   /* Non-nil means display ctl chars with uparrow.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (ctl_arrow);
+
   /* Non-nil means reorder bidirectional text for display in the
      visual order.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (bidi_display_reordering);
+
   /* If non-nil, specifies which direction of text to force in all the
      paragraphs of the buffer.  Nil means determine paragraph
      direction dynamically for each paragraph.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (bidi_paragraph_direction);
+
   /* Non-nil means do selective display;
      see doc string in syms_of_buffer (buffer.c) for details.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (selective_display);
-#ifndef old
+
   /* Non-nil means show ... at end of line followed by invisible lines.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (selective_display_ellipses);
-#endif
+
   /* Alist of (FUNCTION . STRING) for each minor mode enabled in buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (minor_modes);
+
   /* t if "self-insertion" should overwrite; `binary' if it should also
      overwrite newlines and tabs - for editing executables and the like.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (overwrite_mode);
-  /* non-nil means abbrev mode is on.  Expand abbrevs automatically.  */
+
+  /* Non-nil means abbrev mode is on.  Expand abbrevs automatically.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (abbrev_mode);
+
   /* Display table to use for text in this buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (display_table);
+
   /* t means the mark and region are currently active.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (mark_active);
 
@@ -793,11 +680,13 @@ struct buffer
 
   /* Widths of left and right marginal areas for windows displaying
      this buffer.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (left_margin_cols), BUFFER_INTERNAL_FIELD (right_margin_cols);
+  Lisp_Object BUFFER_INTERNAL_FIELD (left_margin_cols);
+  Lisp_Object BUFFER_INTERNAL_FIELD (right_margin_cols);
 
   /* Widths of left and right fringe areas for windows displaying
      this buffer.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (left_fringe_width), BUFFER_INTERNAL_FIELD (right_fringe_width);
+  Lisp_Object BUFFER_INTERNAL_FIELD (left_fringe_width);
+  Lisp_Object BUFFER_INTERNAL_FIELD (right_fringe_width);
 
   /* Non-nil means fringes are drawn outside display margins;
      othersize draw them between margin areas and text.  */
@@ -805,7 +694,8 @@ struct buffer
 
   /* Width and type of scroll bar areas for windows displaying
      this buffer.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (scroll_bar_width), BUFFER_INTERNAL_FIELD (vertical_scroll_bar_type);
+  Lisp_Object BUFFER_INTERNAL_FIELD (scroll_bar_width);
+  Lisp_Object BUFFER_INTERNAL_FIELD (vertical_scroll_bar_type);
 
   /* Non-nil means indicate lines not displaying text (in a style
      like vi).  */
@@ -843,16 +733,139 @@ struct buffer
      in the display of this buffer.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (extra_line_spacing);
 
-  /* *Cursor type to display in non-selected windows.
+  /* Cursor type to display in non-selected windows.
      t means to use hollow box cursor.
      See `cursor-type' for other values.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (cursor_in_non_selected_windows);
 
-  /* This must be the last field in the above list.  */
-  #define LAST_FIELD_PER_BUFFER cursor_in_non_selected_windows
+  /* No more Lisp_Object beyond this point.  Except undo_list,
+     which is handled specially in Fgarbage_collect .  */
+
+  /* This structure holds the coordinates of the buffer contents
+     in ordinary buffers.  In indirect buffers, this is not used.  */
+  struct buffer_text own_text;
+
+  /* This points to the `struct buffer_text' that used for this buffer.
+     In an ordinary buffer, this is the own_text field above.
+     In an indirect buffer, this is the own_text field of another buffer.  */
+  struct buffer_text *text;
+
+  /* Char position of point in buffer.  */
+  ptrdiff_t pt;
+
+  /* Byte position of point in buffer.  */
+  ptrdiff_t pt_byte;
+
+  /* Char position of beginning of accessible range.  */
+  ptrdiff_t begv;
+
+  /* Byte position of beginning of accessible range.  */
+  ptrdiff_t begv_byte;
+
+  /* Char position of end of accessible range.  */
+  ptrdiff_t zv;
+
+  /* Byte position of end of accessible range.  */
+  ptrdiff_t zv_byte;
+
+  /* In an indirect buffer, this points to the base buffer.
+     In an ordinary buffer, it is 0.  */
+  struct buffer *base_buffer;
+
+  /* A non-zero value in slot IDX means that per-buffer variable
+     with index IDX has a local value in this buffer.  The index IDX
+     for a buffer-local variable is stored in that variable's slot
+     in buffer_local_flags as a Lisp integer.  If the index is -1,
+     this means the variable is always local in all buffers.  */
+#define MAX_PER_BUFFER_VARS 50
+  char local_flags[MAX_PER_BUFFER_VARS];
+
+  /* Set to the modtime of the visited file when read or written.
+     EMACS_NSECS (modtime) == NONEXISTENT_MODTIME_NSECS means
+     visited file was nonexistent.  EMACS_NSECS (modtime) ==
+     UNKNOWN_MODTIME_NSECS means visited file modtime unknown;
+     in no case complain about any mismatch on next save attempt.  */
+#define NONEXISTENT_MODTIME_NSECS (-1)
+#define UNKNOWN_MODTIME_NSECS (-2)
+  EMACS_TIME modtime;
+
+  /* Size of the file when modtime was set.  This is used to detect the
+     case where the file grew while we were reading it, so the modtime
+     is still the same (since it's rounded up to seconds) but we're actually
+     not up-to-date.  -1 means the size is unknown.  Only meaningful if
+     modtime is actually set.  */
+  off_t modtime_size;
+
+  /* The value of text->modiff at the last auto-save.  */
+  EMACS_INT auto_save_modified;
+
+  /* The value of text->modiff at the last display error.
+     Redisplay of this buffer is inhibited until it changes again.  */
+  EMACS_INT display_error_modiff;
+
+  /* The time at which we detected a failure to auto-save,
+     Or 0 if we didn't have a failure.  */
+  time_t auto_save_failure_time;
+
+  /* Position in buffer at which display started
+     the last time this buffer was displayed.  */
+  ptrdiff_t last_window_start;
+
+  /* If the long line scan cache is enabled (i.e. the buffer-local
+     variable cache-long-line-scans is non-nil), newline_cache
+     points to the newline cache, and width_run_cache points to the
+     width run cache.
+
+     The newline cache records which stretches of the buffer are
+     known *not* to contain newlines, so that they can be skipped
+     quickly when we search for newlines.
+
+     The width run cache records which stretches of the buffer are
+     known to contain characters whose widths are all the same.  If
+     the width run cache maps a character to a value > 0, that value is
+     the character's width; if it maps a character to zero, we don't
+     know what its width is.  This allows compute_motion to process
+     such regions very quickly, using algebra instead of inspecting
+     each character.   See also width_table, below.  */
+  struct region_cache *newline_cache;
+  struct region_cache *width_run_cache;
+
+  /* Non-zero means don't use redisplay optimizations for
+     displaying this buffer.  */
+  unsigned prevent_redisplay_optimizations_p : 1;
+
+  /* Non-zero whenever the narrowing is changed in this buffer.  */
+  unsigned clip_changed : 1;
+
+  /* List of overlays that end at or before the current center,
+     in order of end-position.  */
+  struct Lisp_Overlay *overlays_before;
+
+  /* List of overlays that end after  the current center,
+     in order of start-position.  */
+  struct Lisp_Overlay *overlays_after;
+
+  /* Position where the overlay lists are centered.  */
+  ptrdiff_t overlay_center;
+
+  /* Changes in the buffer are recorded here for undo, and t means
+     don't record anything.  This information belongs to the base
+     buffer of an indirect buffer.  But we can't store it in the
+     struct buffer_text because local variables have to be right in
+     the struct buffer. So we copy it around in set_buffer_internal.  */
+  Lisp_Object BUFFER_INTERNAL_FIELD (undo_list);
 };
 
 \f
+/* Chain of all buffers, including killed ones.  */
+
+extern struct buffer *all_buffers;
+
+/* Used to iterate over the chain above.  */
+
+#define for_each_buffer(b) \
+  for ((b) = all_buffers; (b); (b) = (b)->header.next.buffer)
+
 /* This points to the current buffer.  */
 
 extern struct buffer *current_buffer;
@@ -890,20 +903,21 @@ extern struct buffer buffer_local_symbols;
 \f
 extern void delete_all_overlays (struct buffer *);
 extern void reset_buffer (struct buffer *);
-extern void evaporate_overlays (EMACS_INT);
+extern void evaporate_overlays (ptrdiff_t);
 extern ptrdiff_t overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
-                             ptrdiff_t *len_ptr, EMACS_INT *next_ptr,
-                             EMACS_INT *prev_ptr, int change_req);
+                             ptrdiff_t *len_ptr, ptrdiff_t *next_ptr,
+                             ptrdiff_t *prev_ptr, int change_req);
 extern ptrdiff_t sort_overlays (Lisp_Object *, ptrdiff_t, struct window *);
-extern void recenter_overlay_lists (struct buffer *, EMACS_INT);
-extern EMACS_INT overlay_strings (EMACS_INT, struct window *, unsigned char **);
+extern void recenter_overlay_lists (struct buffer *, ptrdiff_t);
+extern ptrdiff_t overlay_strings (ptrdiff_t, struct window *, unsigned char **);
 extern void validate_region (Lisp_Object *, Lisp_Object *);
 extern void set_buffer_internal (struct buffer *);
 extern void set_buffer_internal_1 (struct buffer *);
 extern void set_buffer_temp (struct buffer *);
+extern Lisp_Object buffer_local_value_1 (Lisp_Object, Lisp_Object);
 extern void record_buffer (Lisp_Object);
-extern void buffer_slot_type_mismatch (Lisp_Object, int) NO_RETURN;
-extern void fix_overlays_before (struct buffer *, EMACS_INT, EMACS_INT);
+extern _Noreturn void buffer_slot_type_mismatch (Lisp_Object, int);
+extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t);
 extern void mmap_set_vars (int);
 
 /* Get overlays at POSN into array OVERLAYS with NOVERLAYS elements.
@@ -912,34 +926,59 @@ extern void mmap_set_vars (int);
 
 #define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq)                \
   do {                                                                 \
-    ptrdiff_t maxlen = 40;                                                     \
-    overlays = (Lisp_Object *) alloca (maxlen * sizeof (Lisp_Object)); \
+    ptrdiff_t maxlen = 40;                                             \
+    overlays = alloca (maxlen * sizeof *overlays);                     \
     noverlays = overlays_at (posn, 0, &overlays, &maxlen,              \
-                            nextp, NULL, chrq);                                \
+                            nextp, NULL, chrq);                        \
     if (noverlays > maxlen)                                            \
       {                                                                        \
        maxlen = noverlays;                                             \
-       overlays = (Lisp_Object *) alloca (maxlen * sizeof (Lisp_Object)); \
+       overlays = alloca (maxlen * sizeof *overlays);                  \
        noverlays = overlays_at (posn, 0, &overlays, &maxlen,           \
                                 nextp, NULL, chrq);                    \
       }                                                                        \
   } while (0)
 
-EXFUN (Fbuffer_live_p, 1);
-EXFUN (Fbuffer_name, 1);
-EXFUN (Fnext_overlay_change, 1);
-EXFUN (Fbuffer_local_value, 2);
-
 extern Lisp_Object Qbefore_change_functions;
 extern Lisp_Object Qafter_change_functions;
 extern Lisp_Object Qfirst_change_hook;
-
 \f
-/* Overlays */
+/* Return character code of multi-byte form at byte position POS.  If POS
+   doesn't point the head of valid multi-byte form, only the byte at
+   POS is returned.  No range checking.
+
+   WARNING: The character returned by this macro could be "unified"
+   inside STRING_CHAR, if the original character in the buffer belongs
+   to one of the Private Use Areas (PUAs) of codepoints that Emacs
+   uses to support non-unified CJK characters.  If that happens,
+   CHAR_BYTES will return a value that is different from the length of
+   the original multibyte sequence stored in the buffer.  Therefore,
+   do _not_ use FETCH_MULTIBYTE_CHAR if you need to advance through
+   the buffer to the next character after fetching this one.  Instead,
+   use either FETCH_CHAR_ADVANCE or STRING_CHAR_AND_LENGTH.  */
 
-/* 1 if the OV is an overlay object.  */
+static inline int
+FETCH_MULTIBYTE_CHAR (ptrdiff_t pos)
+{
+  unsigned char *p = ((pos >= GPT_BYTE ? GAP_SIZE : 0)
+                     + pos + BEG_ADDR - BEG_BYTE);
+  return STRING_CHAR (p);
+}
+
+/* Return character code of multi-byte form at byte position POS in BUF.
+   If POS doesn't point the head of valid multi-byte form, only the byte at
+   POS is returned.  No range checking.  */
 
-#define OVERLAY_VALID(OV) (OVERLAYP (OV))
+static inline int
+BUF_FETCH_MULTIBYTE_CHAR (struct buffer *buf, ptrdiff_t pos)
+{
+  unsigned char *p
+    = ((pos >= BUF_GPT_BYTE (buf) ? BUF_GAP_SIZE (buf) : 0)
+       + pos + BUF_BEG_ADDR (buf) - BEG_BYTE);
+  return STRING_CHAR (p);
+}
+\f
+/* Overlays */
 
 /* Return the marker that stands for where OV starts in the buffer.  */
 
@@ -974,11 +1013,20 @@ extern int last_per_buffer_idx;
 #define PER_BUFFER_VAR_OFFSET(VAR) \
   offsetof (struct buffer, BUFFER_INTERNAL_FIELD (VAR))
 
+/* Used to iterate over normal Lisp_Object fields of struct buffer (all
+   Lisp_Objects except undo_list).  If you add, remove, or reorder
+   Lisp_Objects in a struct buffer, make sure that this is still correct.  */
+
+#define for_each_per_buffer_object_at(offset)                           \
+  for (offset = PER_BUFFER_VAR_OFFSET (name);                           \
+       offset <= PER_BUFFER_VAR_OFFSET (cursor_in_non_selected_windows); \
+       offset += sizeof (Lisp_Object))
+
 /* Return the index of buffer-local variable VAR.  Each per-buffer
    variable has an index > 0 associated with it, except when it always
    has buffer-local values, in which case the index is -1.  If this is
    0, this is a bug and means that the slot of VAR in
-   buffer_local_flags wasn't intiialized.  */
+   buffer_local_flags wasn't initialized.  */
 
 #define PER_BUFFER_VAR_IDX(VAR) \
     PER_BUFFER_IDX (PER_BUFFER_VAR_OFFSET (VAR))