emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master d84b4f8 4/4: Prefer functions to macros in buffer.h


From: Paul Eggert
Subject: [Emacs-diffs] master d84b4f8 4/4: Prefer functions to macros in buffer.h
Date: Wed, 4 Sep 2019 01:46:22 -0400 (EDT)

branch: master
commit d84b4f83a55e3b1a12e399ad199cc36cd013dcb3
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Prefer functions to macros in buffer.h
    
    In buffer.h, prefer inline functions to function-like macros
    when either will do.  This helps avoid confusion about how
    many times an arg is evaluated.  On my platform, this patch
    improves performance of ‘make compile-always’ by 5.7%.
    Also, prefer enum constants to object-like macros
    when either will do.
    * src/buffer.h (BEG, BEG_BYTE, GAP_BYTES_DFL, GAP_BYTES_MIN)
    (MAX_PER_BUFFER_VARS, NONEXISTENT_MODTIME_NSECS)
    (UNKNOWN_MODTIME_NSECS, BUFFER_LISP_SIZE, BUFFER_REST_SIZE):
    Now enum constants, instead of macros.
    (BUFFER_CEILING_OF, BUFFER_FLOOR_OF, BUF_BEG, BUF_BEG_BYTE)
    (BUF_BEGV, BUF_BEGV_BYTE, BUF_PT, BUF_PT_BYTE, BUF_ZV)
    (BUF_ZV_BYTE, BUF_GPT_ADDR, BUF_Z_ADDR, BUF_GAP_END_ADDR)
    (BUF_COMPUTE_UNCHANGED, SET_PT, TEMP_SET_PT, SET_PT_BOTH)
    (TEMP_SET_PT_BOTH, BUF_TEMP_SET_PT, SET_BUF_BEGV, SET_BUF_ZV)
    (SET_BUF_BEGV_BOTH, SET_BUF_ZV_BOTH, SET_BUF_PT_BOTH)
    (BYTE_POS_ADDR, CHAR_POS_ADDR, CHAR_TO_BYTE, BYTE_TO_CHAR)
    (PTR_BYTE_POS, FETCH_CHAR, FETCH_CHAR_AS_MULTIBYTE)
    (BUF_BYTE_ADDRESS, BUF_CHAR_ADDRESS, BUF_PTR_BYTE_POS)
    (BUF_FETCH_CHAR, BUF_FETCH_CHAR_AS_MULTIBYTE, BUF_FETCH_BYTE)
    (BUFFER_PVEC_INIT, BUFFER_LIVE_P, BUFFER_HIDDEN_P)
    (BUFFER_CHECK_INDIRECTION, OVERLAY_POSITION, PER_BUFFER_VALUE_P)
    (SET_PER_BUFFER_VALUE_P, PER_BUFFER_IDX):
    Now inline functions instead of macros.
---
 src/buffer.h | 661 +++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 395 insertions(+), 266 deletions(-)

diff --git a/src/buffer.h b/src/buffer.h
index 14de70c..82d9350 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -31,12 +31,11 @@ INLINE_HEADER_BEGIN
 
 /* Accessing the parameters of the current buffer.  */
 
-/* These macros come in pairs, one for the char position
+/* These constants and macros come in pairs, one for the char position
    and one for the byte position.  */
 
 /* Position of beginning of buffer.  */
-#define BEG (1)
-#define BEG_BYTE (BEG)
+enum { BEG = 1, BEG_BYTE = BEG };
 
 /* Position of beginning of accessible range of buffer.  */
 #define BEGV (current_buffer->begv)
@@ -96,59 +95,7 @@ INLINE_HEADER_BEGIN
 
 /* Modification count as of last visit or save.  */
 #define SAVE_MODIFF (current_buffer->text->save_modiff)
-
-/* BUFFER_CEILING_OF (resp. BUFFER_FLOOR_OF), when applied to n, return
-   the max (resp. min) p such that
-
-   BYTE_POS_ADDR (p) - BYTE_POS_ADDR (n) == p - n       */
-
-#define BUFFER_CEILING_OF(BYTEPOS) \
-  (((BYTEPOS) < GPT_BYTE && GPT < ZV ? GPT_BYTE : ZV_BYTE) - 1)
-#define BUFFER_FLOOR_OF(BYTEPOS) \
-  (BEGV <= GPT && GPT_BYTE <= (BYTEPOS) ? GPT_BYTE : BEGV_BYTE)
 
-/* Similar macros to operate on a specified buffer.
-   Note that many of these evaluate the buffer argument more than once.  */
-
-/* Position of beginning of buffer.  */
-#define BUF_BEG(buf) (BEG)
-#define BUF_BEG_BYTE(buf) (BEG_BYTE)
-
-/* 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 == 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 == 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)
@@ -161,15 +108,6 @@ INLINE_HEADER_BEGIN
 /* Address of beginning of buffer.  */
 #define BUF_BEG_ADDR(buf) ((buf)->text->beg)
 
-/* Address of beginning of gap of buffer.  */
-#define BUF_GPT_ADDR(buf) ((buf)->text->beg + (buf)->text->gpt_byte - BEG_BYTE)
-
-/* Address of end of buffer.  */
-#define BUF_Z_ADDR(buf) ((buf)->text->beg + (buf)->text->gap_size + 
(buf)->text->z_byte - BEG_BYTE)
-
-/* Address of end of gap in buffer.  */
-#define BUF_GAP_END_ADDR(buf) ((buf)->text->beg + (buf)->text->gpt_byte + 
(buf)->text->gap_size - BEG_BYTE)
-
 /* Size of gap.  */
 #define BUF_GAP_SIZE(buf) ((buf)->text->gap_size)
 
@@ -209,43 +147,8 @@ INLINE_HEADER_BEGIN
   BUF_OVERLAY_UNCHANGED_MODIFIED (current_buffer)
 #define BEG_UNCHANGED BUF_BEG_UNCHANGED (current_buffer)
 #define END_UNCHANGED BUF_END_UNCHANGED (current_buffer)
-
-/* Compute how many characters at the top and bottom of BUF are
-   unchanged when the range START..END is modified.  This computation
-   must be done each time BUF is modified.  */
-
-#define BUF_COMPUTE_UNCHANGED(buf, start, end)                         \
-  do                                                                   \
-    {                                                                  \
-      if (BUF_UNCHANGED_MODIFIED (buf) == BUF_MODIFF (buf)             \
-         && (BUF_OVERLAY_UNCHANGED_MODIFIED (buf)                      \
-             == BUF_OVERLAY_MODIFF (buf)))                             \
-       {                                                               \
-         BUF_BEG_UNCHANGED (buf) = (start) - BUF_BEG (buf);            \
-         BUF_END_UNCHANGED (buf) = BUF_Z (buf) - (end);                \
-       }                                                               \
-      else                                                             \
-       {                                                               \
-         if (BUF_Z (buf) - (end) < BUF_END_UNCHANGED (buf))            \
-           BUF_END_UNCHANGED (buf) = BUF_Z (buf) - (end);              \
-         if ((start) - BUF_BEG (buf) < BUF_BEG_UNCHANGED (buf))        \
-           BUF_BEG_UNCHANGED (buf) = (start) - BUF_BEG (buf);          \
-       }                                                               \
-    }                                                                  \
-  while (false)
-
 
-/* Macros to set PT in the current buffer, or another buffer.  */
-
-#define SET_PT(position) (set_point (position))
-#define TEMP_SET_PT(position) (temp_set_point (current_buffer, (position)))
-
-#define SET_PT_BOTH(position, byte) (set_point_both (position, byte))
-#define TEMP_SET_PT_BOTH(position, byte) \
-  (temp_set_point_both (current_buffer, (position), (byte)))
-
-#define BUF_TEMP_SET_PT(buffer, position) \
-  (temp_set_point ((buffer), (position)))
+/* Functions to set PT in the current buffer, or another buffer.  */
 
 extern void set_point (ptrdiff_t);
 extern void temp_set_point (struct buffer *, ptrdiff_t);
@@ -255,39 +158,32 @@ extern void temp_set_point_both (struct buffer *,
 extern void set_point_from_marker (Lisp_Object);
 extern void enlarge_buffer_text (struct buffer *, ptrdiff_t);
 
+INLINE void
+SET_PT (ptrdiff_t position)
+{
+  set_point (position);
+}
+INLINE void
+TEMP_SET_PT (ptrdiff_t position)
+{
+  temp_set_point (current_buffer, position);
+}
+INLINE void
+SET_PT_BOTH (ptrdiff_t position, ptrdiff_t byte)
+{
+  set_point_both (position, byte);
+}
+INLINE void
+TEMP_SET_PT_BOTH (ptrdiff_t position, ptrdiff_t byte)
+{
+  temp_set_point_both (current_buffer, position, byte);
+}
+INLINE void
+BUF_TEMP_SET_PT (struct buffer *buffer, ptrdiff_t position)
+{
+  temp_set_point (buffer, position);
+}
 
-/* Macros for setting the BEGV, ZV or PT of a given buffer.
-
-   The ..._BOTH macros take both a charpos and a bytepos,
-   which must correspond to each other.
-
-   The macros without ..._BOTH take just a charpos,
-   and compute the bytepos from it.  */
-
-#define SET_BUF_BEGV(buf, charpos)                              \
-  ((buf)->begv_byte = buf_charpos_to_bytepos ((buf), (charpos)), \
-   (buf)->begv = (charpos))
-
-#define SET_BUF_ZV(buf, charpos)                               \
-  ((buf)->zv_byte = buf_charpos_to_bytepos ((buf), (charpos)), \
-   (buf)->zv = (charpos))
-
-#define SET_BUF_BEGV_BOTH(buf, charpos, byte)          \
-  ((buf)->begv = (charpos),                            \
-   (buf)->begv_byte = (byte))
-
-#define SET_BUF_ZV_BOTH(buf, charpos, byte)            \
-  ((buf)->zv = (charpos),                              \
-   (buf)->zv_byte = (byte))
-
-#define SET_BUF_PT_BOTH(buf, charpos, byte)            \
-  ((buf)->pt = (charpos),                              \
-   (buf)->pt_byte = (byte))
-
-/* Macros to access a character or byte in the current buffer,
-   or convert between a byte position and an address.
-   These macros do not check that the position is in range.  */
-
 /* Maximum number of bytes in a buffer.
    A buffer cannot contain more bytes than a 1-origin fixnum can represent,
    nor can it be so large that C pointer arithmetic stops working.
@@ -298,115 +194,21 @@ extern void enlarge_buffer_text (struct buffer *, 
ptrdiff_t);
 /* Maximum gap size after compact_buffer, in bytes.  Also
    used in make_gap_larger to get some extra reserved space.  */
 
-#define GAP_BYTES_DFL 2000
+enum { GAP_BYTES_DFL = 2000 };
 
 /* Minimum gap size after compact_buffer, in bytes.  Also
    used in make_gap_smaller to avoid too small gap size.  */
 
-#define GAP_BYTES_MIN 20
-
-/* Return the address of byte position N in current buffer.  */
-
-#define BYTE_POS_ADDR(n) \
-  (((n) >= GPT_BYTE ? GAP_SIZE : 0) + (n) + BEG_ADDR - BEG_BYTE)
-
-/* Return the address of char position N.  */
-
-#define CHAR_POS_ADDR(n)                       \
-  (((n) >= GPT ? GAP_SIZE : 0)                 \
-   + buf_charpos_to_bytepos (current_buffer, n)        \
-   + BEG_ADDR - BEG_BYTE)
-
-/* Convert a character position to a byte position.  */
-
-#define CHAR_TO_BYTE(charpos)                  \
-  (buf_charpos_to_bytepos (current_buffer, charpos))
-
-/* Convert a byte position to a character position.  */
-
-#define BYTE_TO_CHAR(bytepos)                  \
-  (buf_bytepos_to_charpos (current_buffer, bytepos))
+enum { GAP_BYTES_MIN = 20 };
 
 /* For those very rare cases where you may have a "random" pointer into
    the middle of a multibyte char, this moves to the next boundary.  */
 extern ptrdiff_t advance_to_char_boundary (ptrdiff_t byte_pos);
 
-/* Convert PTR, the address of a byte in the buffer, into a byte position.  */
-
-#define PTR_BYTE_POS(ptr) \
-  ((ptr) - (current_buffer)->text->beg                                     \
-   - (ptr - (current_buffer)->text->beg <= GPT_BYTE - BEG_BYTE ? 0 : GAP_SIZE) 
\
-   + BEG_BYTE)
-
-/* 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))  \
-   ? FETCH_MULTIBYTE_CHAR ((pos))                      \
-   : FETCH_BYTE ((pos)))
-
-/* Return the byte at byte position N.  */
+/* Return the byte at byte position N.
+   Do not check that the position is in range.  */
 
 #define FETCH_BYTE(n) *(BYTE_POS_ADDR ((n)))
-
-/* Return character at byte position POS.  If the current buffer is unibyte
-   and the character is not ASCII, make the returning character
-   multibyte.  */
-
-#define FETCH_CHAR_AS_MULTIBYTE(pos)                   \
-  (!NILP (BVAR (current_buffer, enable_multibyte_characters))  \
-   ? FETCH_MULTIBYTE_CHAR ((pos))                      \
-   : UNIBYTE_TO_CHAR (FETCH_BYTE ((pos))))
-
-
-/* Macros for accessing a character or byte,
-   or converting between byte positions and addresses,
-   in a specified buffer.  */
-
-/* Return the address of character at byte position POS in buffer BUF.
-   Note that both arguments can be computed more than once.  */
-
-#define BUF_BYTE_ADDRESS(buf, pos) \
-  ((buf)->text->beg + (pos) - BEG_BYTE \
-   + ((pos) >= (buf)->text->gpt_byte ? (buf)->text->gap_size : 0))
-
-/* Return the address of character at char position POS in buffer BUF.
-   Note that both arguments can be computed more than once.  */
-
-#define BUF_CHAR_ADDRESS(buf, pos) \
-  ((buf)->text->beg + buf_charpos_to_bytepos ((buf), (pos)) - BEG_BYTE \
-   + ((pos) >= (buf)->text->gpt ? (buf)->text->gap_size : 0))
-
-/* Convert PTR, the address of a char in buffer BUF,
-   into a character position.  */
-
-#define BUF_PTR_BYTE_POS(buf, ptr)                             \
-  ((ptr) - (buf)->text->beg                                    \
-   - (ptr - (buf)->text->beg <= BUF_GPT_BYTE (buf) - BEG_BYTE  \
-      ? 0 : BUF_GAP_SIZE ((buf)))                              \
-   + BEG_BYTE)
-
-/* Return the character at byte position POS in buffer BUF.   */
-
-#define BUF_FETCH_CHAR(buf, pos)               \
-  (!NILP (buf->enable_multibyte_characters)    \
-   ? BUF_FETCH_MULTIBYTE_CHAR ((buf), (pos))    \
-   : BUF_FETCH_BYTE ((buf), (pos)))
-
-/* Return character at byte position POS in buffer BUF.  If BUF is
-   unibyte and the character is not ASCII, make the returning
-   character multibyte.  */
-
-#define BUF_FETCH_CHAR_AS_MULTIBYTE(buf, pos)           \
-  (! NILP (BVAR ((buf), enable_multibyte_characters))   \
-   ? BUF_FETCH_MULTIBYTE_CHAR ((buf), (pos))            \
-   : UNIBYTE_TO_CHAR (BUF_FETCH_BYTE ((buf), (pos))))
-
-/* Return the byte at byte position N in buffer BUF.   */
-
-#define BUF_FETCH_BYTE(buf, n) \
-  *(BUF_BYTE_ADDRESS ((buf), (n)))
 
 /* Define the actual buffer data structures.  */
 
@@ -482,6 +284,13 @@ struct buffer_text
 
 #define BVAR(buf, field) ((buf)->field ## _)
 
+/* Max number of builtin per-buffer variables.  */
+enum { MAX_PER_BUFFER_VARS = 50 };
+
+/* Special values for struct buffer.modtime.  */
+enum { NONEXISTENT_MODTIME_NSECS = -1 };
+enum { UNKNOWN_MODTIME_NSECS = -2 };
+
 /* This is the structure that the buffer Lisp object points to.  */
 
 struct buffer
@@ -796,7 +605,6 @@ struct buffer
      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.
@@ -804,8 +612,6 @@ struct buffer
      visited file was nonexistent.  modtime.tv_nsec ==
      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)
   struct timespec modtime;
 
   /* Size of the file when modtime was set.  This is used to detect the
@@ -1018,49 +824,281 @@ bset_width_table (struct buffer *b, Lisp_Object val)
   b->width_table_ = val;
 }
 
+/* BUFFER_CEILING_OF (resp. BUFFER_FLOOR_OF), when applied to n, return
+   the max (resp. min) p such that
+
+   BYTE_POS_ADDR (p) - BYTE_POS_ADDR (n) == p - n       */
+
+INLINE ptrdiff_t
+BUFFER_CEILING_OF (ptrdiff_t bytepos)
+{
+  return (bytepos < GPT_BYTE && GPT < ZV ? GPT_BYTE : ZV_BYTE) - 1;
+}
+
+INLINE ptrdiff_t
+BUFFER_FLOOR_OF (ptrdiff_t bytepos)
+{
+  return BEGV <= GPT && GPT_BYTE <= bytepos ? GPT_BYTE : BEGV_BYTE;
+}
+
+/* The BUF_BEGV[_BYTE], BUF_ZV[_BYTE], and BUF_PT[_BYTE] functions cannot
+   be used for assignment; use SET_BUF_* functions below for that.  */
+
+/* Position of beginning of accessible range of buffer.  */
+INLINE ptrdiff_t
+BUF_BEGV (struct buffer *buf)
+{
+  return (buf == current_buffer ? BEGV
+         : NILP (BVAR (buf, begv_marker)) ? buf->begv
+         : marker_position (BVAR (buf, begv_marker)));
+}
+
+INLINE ptrdiff_t
+BUF_BEGV_BYTE (struct buffer *buf)
+{
+  return (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.  */
+INLINE ptrdiff_t
+BUF_PT (struct buffer *buf)
+{
+  return (buf == current_buffer ? PT
+         : NILP (BVAR (buf, pt_marker)) ? buf->pt
+         : marker_position (BVAR (buf, pt_marker)));
+}
+
+INLINE ptrdiff_t
+BUF_PT_BYTE (struct buffer *buf)
+{
+  return (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.  */
+INLINE ptrdiff_t
+BUF_ZV (struct buffer *buf)
+{
+  return (buf == current_buffer ? ZV
+         : NILP (BVAR (buf, zv_marker)) ? buf->zv
+         : marker_position (BVAR (buf, zv_marker)));
+}
+
+INLINE ptrdiff_t
+BUF_ZV_BYTE (struct buffer *buf)
+{
+  return (buf == current_buffer ? ZV_BYTE
+         : NILP (BVAR (buf, zv_marker)) ? buf->zv_byte
+         : marker_byte_position (BVAR (buf, zv_marker)));
+}
+
+/* Similar functions to operate on a specified buffer.  */
+
+/* Position of beginning of buffer.  */
+INLINE ptrdiff_t
+BUF_BEG (struct buffer *buf)
+{
+  return BEG;
+}
+
+INLINE ptrdiff_t
+BUF_BEG_BYTE (struct buffer *buf)
+{
+  return BEG_BYTE;
+}
+
+/* Address of beginning of gap of buffer.  */
+INLINE unsigned char *
+BUF_GPT_ADDR (struct buffer *buf)
+{
+  return buf->text->beg + buf->text->gpt_byte - BEG_BYTE;
+}
+
+/* Address of end of buffer.  */
+INLINE unsigned char *
+BUF_Z_ADDR (struct buffer *buf)
+{
+  return buf->text->beg + buf->text->gap_size + buf->text->z_byte - BEG_BYTE;
+}
+
+/* Address of end of gap in buffer.  */
+INLINE unsigned char *
+BUF_GAP_END_ADDR (struct buffer *buf)
+{
+  return buf->text->beg + buf->text->gpt_byte + buf->text->gap_size - BEG_BYTE;
+}
+
+/* Compute how many characters at the top and bottom of BUF are
+   unchanged when the range START..END is modified.  This computation
+   must be done each time BUF is modified.  */
+
+INLINE void
+BUF_COMPUTE_UNCHANGED (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
+{
+  if (BUF_UNCHANGED_MODIFIED (buf) == BUF_MODIFF (buf)
+      && (BUF_OVERLAY_UNCHANGED_MODIFIED (buf)
+         == BUF_OVERLAY_MODIFF (buf)))
+    {
+      buf->text->beg_unchanged = start - BUF_BEG (buf);
+      buf->text->end_unchanged = BUF_Z (buf) - (end);
+    }
+  else
+    {
+      if (BUF_Z (buf) - end < BUF_END_UNCHANGED (buf))
+       buf->text->end_unchanged = BUF_Z (buf) - end;
+      if (start - BUF_BEG (buf) < BUF_BEG_UNCHANGED (buf))
+       buf->text->beg_unchanged = start - BUF_BEG (buf);
+    }
+}
+
+/* Functions for setting the BEGV, ZV or PT of a given buffer.
+
+   The ..._BOTH functions take both a charpos and a bytepos,
+   which must correspond to each other.
+
+   The functions without ..._BOTH take just a charpos,
+   and compute the bytepos from it.  */
+
+INLINE void
+SET_BUF_BEGV (struct buffer *buf, ptrdiff_t charpos)
+{
+  buf->begv_byte = buf_charpos_to_bytepos (buf, charpos);
+  buf->begv = charpos;
+}
+
+INLINE void
+SET_BUF_ZV (struct buffer *buf, ptrdiff_t charpos)
+{
+  buf->zv_byte = buf_charpos_to_bytepos (buf, charpos);
+  buf->zv = charpos;
+}
+
+INLINE void
+SET_BUF_BEGV_BOTH (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t byte)
+{
+  buf->begv = charpos;
+  buf->begv_byte = byte;
+}
+
+INLINE void
+SET_BUF_ZV_BOTH (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t byte)
+{
+  buf->zv = charpos;
+  buf->zv_byte = byte;
+}
+
+INLINE void
+SET_BUF_PT_BOTH (struct buffer *buf, ptrdiff_t charpos, ptrdiff_t byte)
+{
+  buf->pt = charpos;
+  buf->pt_byte = byte;
+}
+
+/* Functions to access a character or byte in the current buffer,
+   or convert between a byte position and an address.
+   These functions do not check that the position is in range.  */
+
+/* Return the address of byte position N in current buffer.  */
+
+INLINE unsigned char *
+BYTE_POS_ADDR (ptrdiff_t n)
+{
+  return (n < GPT_BYTE ? 0 : GAP_SIZE) + n + BEG_ADDR - BEG_BYTE;
+}
+
+/* Return the address of char position N.  */
+
+INLINE unsigned char *
+CHAR_POS_ADDR (ptrdiff_t n)
+{
+  return ((n < GPT ? 0 : GAP_SIZE)
+         + buf_charpos_to_bytepos (current_buffer, n)
+         + BEG_ADDR - BEG_BYTE);
+}
+
+/* Convert a character position to a byte position.  */
+
+INLINE ptrdiff_t
+CHAR_TO_BYTE (ptrdiff_t charpos)
+{
+  return buf_charpos_to_bytepos (current_buffer, charpos);
+}
+
+/* Convert a byte position to a character position.  */
+
+INLINE ptrdiff_t
+BYTE_TO_CHAR (ptrdiff_t bytepos)
+{
+  return buf_bytepos_to_charpos (current_buffer, bytepos);
+}
+
+/* Convert PTR, the address of a byte in the buffer, into a byte position.  */
+
+INLINE ptrdiff_t
+PTR_BYTE_POS (unsigned char const *ptr)
+{
+  ptrdiff_t byte = ptr - current_buffer->text->beg;
+  return byte - (byte <= GPT_BYTE - BEG_BYTE ? 0 : GAP_SIZE) + BEG_BYTE;
+}
+
 /* Number of Lisp_Objects at the beginning of struct buffer.
    If you add, remove, or reorder Lisp_Objects within buffer
    structure, make sure that this is still correct.  */
 
-#define BUFFER_LISP_SIZE                                               \
-  PSEUDOVECSIZE (struct buffer, cursor_in_non_selected_windows_)
+enum { BUFFER_LISP_SIZE = PSEUDOVECSIZE (struct buffer,
+                                        cursor_in_non_selected_windows_) };
 
 /* Allocated size of the struct buffer part beyond leading
    Lisp_Objects, in word_size units.  */
 
-#define BUFFER_REST_SIZE (VECSIZE (struct buffer) - BUFFER_LISP_SIZE)
+enum { BUFFER_REST_SIZE = VECSIZE (struct buffer) - BUFFER_LISP_SIZE };
 
 /* Initialize the pseudovector header of buffer object.  BUFFER_LISP_SIZE
    is required for GC, but BUFFER_REST_SIZE is set up just to be consistent
    with other pseudovectors.  */
 
-#define BUFFER_PVEC_INIT(b)                                    \
-  XSETPVECTYPESIZE (b, PVEC_BUFFER, BUFFER_LISP_SIZE, BUFFER_REST_SIZE)
+INLINE void
+BUFFER_PVEC_INIT (struct buffer *b)
+{
+  XSETPVECTYPESIZE (b, PVEC_BUFFER, BUFFER_LISP_SIZE, BUFFER_REST_SIZE);
+}
 
 /* Convenient check whether buffer B is live.  */
 
-#define BUFFER_LIVE_P(b) (!NILP (BVAR (b, name)))
+INLINE bool
+BUFFER_LIVE_P (struct buffer *b)
+{
+  return !NILP (BVAR (b, name));
+}
 
 /* Convenient check whether buffer B is hidden (i.e. its name
    starts with a space).  Caller must ensure that B is live.  */
 
-#define BUFFER_HIDDEN_P(b) (SREF (BVAR (b, name), 0) == ' ')
+INLINE bool
+BUFFER_HIDDEN_P (struct buffer *b)
+{
+  return SREF (BVAR (b, name), 0) == ' ';
+}
 
 /* Verify indirection counters.  */
 
-#define BUFFER_CHECK_INDIRECTION(b)                    \
-  do {                                                 \
-    if (BUFFER_LIVE_P (b))                             \
-      {                                                        \
-       if (b->base_buffer)                             \
-         {                                             \
-           eassert (b->indirections == -1);            \
-           eassert (b->base_buffer->indirections > 0); \
-         }                                             \
-       else                                            \
-         eassert (b->indirections >= 0);               \
-      }                                                        \
-  } while (false)
+INLINE void
+BUFFER_CHECK_INDIRECTION (struct buffer *b)
+{
+  if (BUFFER_LIVE_P (b))
+    {
+      if (b->base_buffer)
+       {
+         eassert (b->indirections == -1);
+         eassert (b->base_buffer->indirections > 0);
+       }
+      else
+       eassert (b->indirections >= 0);
+    }
+}
 
 /* Chain of all buffers, including killed ones.  */
 
@@ -1157,7 +1195,9 @@ record_unwind_current_buffer (void)
 
 /* Get overlays at POSN into array OVERLAYS with NOVERLAYS elements.
    If NEXTP is non-NULL, return next overlay there.
-   See overlay_at arg CHANGE_REQ for meaning of CHRQ arg.  */
+   See overlay_at arg CHANGE_REQ for meaning of CHRQ arg.
+   This macro might evaluate its args multiple times,
+   and it treat some args as lvalues.  */
 
 #define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq)                
\
   do {                                                                 \
@@ -1207,6 +1247,10 @@ buffer_has_overlays (void)
 {
   return current_buffer->overlays_before || current_buffer->overlays_after;
 }
+
+/* Functions for accessing a character or byte,
+   or converting between byte positions and addresses,
+   in a specified buffer.  */
 
 /* 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
@@ -1232,6 +1276,80 @@ BUF_FETCH_MULTIBYTE_CHAR (struct buffer *buf, ptrdiff_t 
pos)
   return STRING_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.  */
+
+INLINE int
+FETCH_CHAR_AS_MULTIBYTE (ptrdiff_t pos)
+{
+  return (!NILP (BVAR (current_buffer, enable_multibyte_characters))
+         ? FETCH_MULTIBYTE_CHAR (pos)
+         : UNIBYTE_TO_CHAR (FETCH_BYTE (pos)));
+}
+
+/* Return character at byte position POS.
+   See the caveat WARNING for FETCH_MULTIBYTE_CHAR above.  */
+
+INLINE int
+FETCH_CHAR (ptrdiff_t pos)
+{
+  return (!NILP (BVAR (current_buffer, enable_multibyte_characters))
+         ? FETCH_MULTIBYTE_CHAR (pos)
+         : FETCH_BYTE (pos));
+}
+
+/* Return the address of character at byte position POS in buffer BUF.
+   Note that both arguments can be computed more than once.  */
+
+INLINE unsigned char *
+BUF_BYTE_ADDRESS (struct buffer *buf, ptrdiff_t pos)
+{
+  return (buf->text->beg + pos - BEG_BYTE
+         + (pos < buf->text->gpt_byte ? 0 : buf->text->gap_size));
+}
+
+/* Return the address of character at char position POS in buffer BUF.
+   Note that both arguments can be computed more than once.  */
+
+INLINE unsigned char *
+BUF_CHAR_ADDRESS (struct buffer *buf, ptrdiff_t pos)
+{
+  return (buf->text->beg + buf_charpos_to_bytepos (buf, pos) - BEG_BYTE
+         + (pos < buf->text->gpt ? 0 : buf->text->gap_size));
+}
+
+/* Convert PTR, the address of a char in buffer BUF,
+   into a character position.  */
+
+INLINE ptrdiff_t
+BUF_PTR_BYTE_POS (struct buffer *buf, unsigned char *ptr)
+{
+  ptrdiff_t byte = ptr - buf->text->beg;
+  return (byte - (byte <= BUF_GPT_BYTE (buf) - BEG_BYTE ? 0 : BUF_GAP_SIZE 
(buf))
+         + BEG_BYTE);
+}
+
+/* Return the byte at byte position N in buffer BUF.   */
+
+INLINE unsigned char
+BUF_FETCH_BYTE (struct buffer *buf, ptrdiff_t n)
+{
+  return *BUF_BYTE_ADDRESS (buf, n);
+}
+
+/* Return character at byte position POS in buffer BUF.  If BUF is
+   unibyte and the character is not ASCII, make the returning
+   character multibyte.  */
+
+INLINE int
+BUF_FETCH_CHAR_AS_MULTIBYTE (struct buffer *buf, ptrdiff_t pos)
+{
+  return (! NILP (BVAR (buf, enable_multibyte_characters))
+         ? BUF_FETCH_MULTIBYTE_CHAR (buf, pos)
+         : UNIBYTE_TO_CHAR (BUF_FETCH_BYTE (buf, pos)));
+}
+
 /* Return number of windows showing B.  */
 
 INLINE int
@@ -1260,8 +1378,11 @@ buffer_window_count (struct buffer *b)
 /* Return the actual buffer position for the marker P.
    We assume you know which buffer it's pointing into.  */
 
-#define OVERLAY_POSITION(P) \
- (MARKERP (P) ? marker_position (P) : (emacs_abort (), 0))
+INLINE ptrdiff_t
+OVERLAY_POSITION (Lisp_Object p)
+{
+  return marker_position (p);
+}
 
 
 /***********************************************************************
@@ -1297,16 +1418,22 @@ extern bool valid_per_buffer_idx (int);
 /* Value is true if the variable with index IDX has a local value
    in buffer B.  */
 
-#define PER_BUFFER_VALUE_P(B, IDX)             \
-  (eassert (valid_per_buffer_idx (IDX)),       \
-   (B)->local_flags[IDX])
+INLINE bool
+PER_BUFFER_VALUE_P (struct buffer *b, int idx)
+{
+  eassert (valid_per_buffer_idx (idx));
+  return b->local_flags[idx];
+}
 
 /* Set whether per-buffer variable with index IDX has a buffer-local
    value in buffer B.  VAL zero means it hasn't.  */
 
-#define SET_PER_BUFFER_VALUE_P(B, IDX, VAL)    \
-  (eassert (valid_per_buffer_idx (IDX)),       \
-   (B)->local_flags[IDX] = (VAL))
+INLINE void
+SET_PER_BUFFER_VALUE_P (struct buffer *b, int idx, bool val)
+{
+  eassert (valid_per_buffer_idx (idx));
+  b->local_flags[idx] = val;
+}
 
 /* Return the index value of the per-buffer variable at offset OFFSET
    in the buffer structure.
@@ -1326,11 +1453,13 @@ extern bool valid_per_buffer_idx (int);
    new buffer.
 
    If a slot in this structure corresponding to a DEFVAR_PER_BUFFER is
-   zero, that is a bug */
+   zero, that is a bug.  */
 
-
-#define PER_BUFFER_IDX(OFFSET) \
-      XFIXNUM (*(Lisp_Object *)((OFFSET) + (char *) &buffer_local_flags))
+INLINE int
+PER_BUFFER_IDX (ptrdiff_t offset)
+{
+  return XFIXNUM (*(Lisp_Object *) (offset + (char *) &buffer_local_flags));
+}
 
 /* Functions to get and set default value of the per-buffer
    variable at offset OFFSET in the buffer structure.  */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]