]> code.delx.au - gnu-emacs/blobdiff - src/buffer.h
Switch from NO_RETURN to C11's _Noreturn.
[gnu-emacs] / src / buffer.h
index c75a09c55790144c285b239c70e104146232081d..b1ace4663cf679b8bbd0054094c0cc178d0b5e1c 100644 (file)
@@ -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.  */
 
@@ -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.  */
 
@@ -550,10 +530,13 @@ struct buffer
   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;
+     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
@@ -901,8 +884,9 @@ 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 _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);
 
@@ -933,7 +917,41 @@ EXFUN (Fbuffer_local_value, 2);
 extern Lisp_Object Qbefore_change_functions;
 extern Lisp_Object Qafter_change_functions;
 extern Lisp_Object Qfirst_change_hook;
+\f
+/* 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.  */
+
+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.  */
 
+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 */