lisp.h: Fix a problem with aliasing and vector headers.
[bpt/emacs.git] / src / buffer.h
index 19a7c0b..51b3182 100644 (file)
@@ -107,27 +107,46 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define BUF_BEG(buf) (BEG)
 #define BUF_BEG_BYTE(buf) (BEG_BYTE)
 
-/* !!!FIXME:  all the BUF_BEGV/BUF_ZV/BUF_PT macros are flawed:
-   on indirect (or base) buffers, that value is only correct if that buffer
-   is the current_buffer, or if the buffer's text hasn't been modified (via
-   an indirect buffer) since it was last current.  */
+/* The BUF_BEGV[_BYTE], BUF_ZV[_BYTE], and BUF_PT[_BYTE] macros cannot
+   be used for assignment; use SET_BUF_* macros below for that.  */
 
 /* Position of beginning of accessible range of buffer.  */
-#define BUF_BEGV(buf) ((buf)->begv)
-#define BUF_BEGV_BYTE(buf) ((buf)->begv_byte)
+#define BUF_BEGV(buf)                                  \
+   (buf == current_buffer ? BEGV                       \
+    : NILP (BVAR (buf, begv_marker)) ? buf->begv       \
+    : marker_position (BVAR (buf, begv_marker)))
+
+#define BUF_BEGV_BYTE(buf)                             \
+   (buf == current_buffer ? BEGV_BYTE                  \
+    : NILP (BVAR (buf, begv_marker)) ? buf->begv_byte  \
+    : marker_byte_position (BVAR (buf, begv_marker)))
 
 /* Position of point in buffer.  */
-#define BUF_PT(buf) ((buf)->pt)
-#define BUF_PT_BYTE(buf) ((buf)->pt_byte)
+#define BUF_PT(buf)                                    \
+   (buf == current_buffer ? PT                         \
+    : NILP (BVAR (buf, pt_marker)) ? buf->pt           \
+    : marker_position (BVAR (buf, pt_marker)))
+
+#define BUF_PT_BYTE(buf)                               \
+   (buf == current_buffer ? PT_BYTE                    \
+    : NILP (BVAR (buf, pt_marker)) ? buf->pt_byte      \
+    : marker_byte_position (BVAR (buf, pt_marker)))
+
+/* Position of end of accessible range of buffer.  */
+#define BUF_ZV(buf)                                    \
+   (buf == current_buffer ? ZV                         \
+    : NILP (BVAR (buf, zv_marker)) ? buf->zv           \
+    : marker_position (BVAR (buf, zv_marker)))
+
+#define BUF_ZV_BYTE(buf)                               \
+   (buf == current_buffer ? ZV_BYTE                    \
+    : NILP (BVAR (buf, zv_marker)) ? buf->zv_byte      \
+    : marker_byte_position (BVAR (buf, zv_marker)))
 
 /* Position of gap in buffer.  */
 #define BUF_GPT(buf) ((buf)->text->gpt)
 #define BUF_GPT_BYTE(buf) ((buf)->text->gpt_byte)
 
-/* Position of end of accessible range of buffer.  */
-#define BUF_ZV(buf) ((buf)->zv)
-#define BUF_ZV_BYTE(buf) ((buf)->zv_byte)
-
 /* Position of end of buffer.  */
 #define BUF_Z(buf) ((buf)->text->z)
 #define BUF_Z_BYTE(buf) ((buf)->text->z_byte)
@@ -235,8 +254,6 @@ extern void enlarge_buffer_text (struct buffer *, EMACS_INT);
 \f
 /* Macros for setting the BEGV, ZV or PT of a given buffer.
 
-   SET_BUF_PT* seet to be redundant.  Get rid of them?
-
    The ..._BOTH macros take both a charpos and a bytepos,
    which must correspond to each other.
 
@@ -482,14 +499,13 @@ struct buffer
 
      Check out mark_buffer (alloc.c) to see why.  */
 
-  EMACS_UINT size;
-
-  /* Next buffer, in chain of all buffers including killed buffers.
+  /* 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.  */
-  struct buffer *next;
+  struct vector_header header;
 
   /* This structure holds the coordinates of the buffer contents
      in ordinary buffers.  In indirect buffers, this is not used.  */
@@ -662,12 +678,6 @@ struct buffer
   Lisp_Object BUFFER_INTERNAL_FIELD (left_margin);
   /* Function to call when insert space past fill column.  */
   Lisp_Object BUFFER_INTERNAL_FIELD (auto_fill_function);
-  /* nil: text, t: binary.
-     This value is meaningful only on certain operating systems.  */
-  /* Actually, we don't need this flag any more because end-of-line
-     is handled correctly according to the buffer-file-coding-system
-     of the buffer.  Just keeping it for backward compatibility.  */
-  Lisp_Object BUFFER_INTERNAL_FIELD (buffer_file_type);
 
   /* Case table for case-conversion in this buffer.
      This char-table maps each char into its lower-case version.  */
@@ -906,7 +916,6 @@ extern void mmap_set_vars (int);
 EXFUN (Fbuffer_live_p, 1);
 EXFUN (Fbuffer_name, 1);
 EXFUN (Fnext_overlay_change, 1);
-EXFUN (Fdelete_overlay, 1);
 EXFUN (Fbuffer_local_value, 2);
 
 extern Lisp_Object Qbefore_change_functions;
@@ -1015,4 +1024,31 @@ extern int last_per_buffer_idx;
 
 #define PER_BUFFER_VALUE(BUFFER, OFFSET) \
       (*(Lisp_Object *)((OFFSET) + (char *) (BUFFER)))
+\f
+/* Downcase a character C, or make no change if that cannot be done.  */
+static inline int
+downcase (int c)
+{
+  Lisp_Object downcase_table = BVAR (current_buffer, downcase_table);
+  Lisp_Object down = CHAR_TABLE_REF (downcase_table, c);
+  return NATNUMP (down) ? XFASTINT (down) : c;
+}
+
+/* 1 if C is upper case.  */
+static inline int uppercasep (int c) { return downcase (c) != c; }
+
+/* Upcase a character C known to be not upper case.  */
+static inline int
+upcase1 (int c)
+{
+  Lisp_Object upcase_table = BVAR (current_buffer, upcase_table);
+  Lisp_Object up = CHAR_TABLE_REF (upcase_table, c);
+  return NATNUMP (up) ? XFASTINT (up) : c;
+}
+
+/* 1 if C is lower case.  */
+static inline int lowercasep (int c)
+{ return !uppercasep (c) && upcase1 (c) != c; }
 
+/* Upcase a character C, or make no change if that cannot be done.  */
+static inline int upcase (int c) { return uppercasep (c) ? c : upcase1 (c); }