XEmacs 21.4.12 "Portable Code".
[chise/xemacs-chise.git.1] / src / buffer.h
index b56d8a5..590219e 100644 (file)
@@ -36,6 +36,9 @@ Boston, MA 02111-1307, USA.  */
 #include "mule-charset.h"
 #endif
 
+#include "casetab.h"
+#include "chartab.h"
+
 /************************************************************************/
 /*                                                                      */
 /*                    definition of Lisp buffer object                  */
@@ -134,6 +137,9 @@ struct buffer
   int face_change;     /* This is set when a change in how the text should
                           be displayed (e.g., font, color) is made. */
 
+  /* Whether buffer specific face is specified. */
+  int buffer_local_face_property;
+
   /* change data indicating what portion of the text has changed
      since the last time this was reset.  Used by redisplay.
      Logically we should keep this with the text structure, but
@@ -198,7 +204,7 @@ struct buffer
   int modtime;
 
   /* the value of text->modiff at the last auto-save.  */
-  int auto_save_modified;
+  long auto_save_modified;
 
   /* The time at which we detected a failure to auto-save,
      Or -1 if we didn't have a failure.  */
@@ -408,7 +414,7 @@ for (mps_bufcons = Qunbound,                                                        \
 #define REAL_INC_CHARPTR(ptr) \
   ((void) ((ptr) += REP_BYTES_BY_FIRST_BYTE (* (unsigned char *) (ptr))))
 
-#define REAL_INC_CHARBYTIND(ptr,pos) \
+#define REAL_INC_CHARBYTIND(ptr, pos) \
   (pos += REP_BYTES_BY_FIRST_BYTE (* (unsigned char *) (ptr)))
 
 #define REAL_DEC_CHARPTR(ptr) do {     \
@@ -421,9 +427,9 @@ for (mps_bufcons = Qunbound,                                                        \
   REAL_INC_CHARPTR (ptr);              \
 } while (0)
 
-#define INC_CHARBYTIND(ptr,pos) do {           \
-  ASSERT_VALID_CHARPTR (ptr);          \
-  REAL_INC_CHARBYTIND (ptr,pos);               \
+#define INC_CHARBYTIND(ptr, pos) do {          \
+  ASSERT_VALID_CHARPTR (ptr);                  \
+  REAL_INC_CHARBYTIND (ptr, pos);              \
 } while (0)
 
 #define DEC_CHARPTR(ptr) do {                  \
@@ -432,11 +438,11 @@ for (mps_bufcons = Qunbound,                                                      \
   REAL_DEC_CHARPTR (dc_ptr2);                  \
   assert (dc_ptr1 - dc_ptr2 ==                 \
          REP_BYTES_BY_FIRST_BYTE (*dc_ptr2));  \
-  (ptr) = dc_ptr2;                             \
+  (ptr) = (Bufbyte *) dc_ptr2;                 \
 } while (0)
 
 #else /* ! ERROR_CHECK_BUFPOS */
-#define INC_CHARBYTIND(ptr,pos) REAL_INC_CHARBYTIND (ptr,pos)
+#define INC_CHARBYTIND(ptr, pos) REAL_INC_CHARBYTIND (ptr, pos)
 #define INC_CHARPTR(ptr) REAL_INC_CHARPTR (ptr)
 #define DEC_CHARPTR(ptr) REAL_DEC_CHARPTR (ptr)
 #endif /* ! ERROR_CHECK_BUFPOS */
@@ -470,8 +476,9 @@ for (mps_bufcons = Qunbound,                                                        \
 /*     section of internally-formatted text                      */
 /* -------------------------------------------------------------- */
 
-INLINE const Bufbyte *charptr_n_addr (const Bufbyte *ptr, Charcount offset);
-INLINE const Bufbyte *
+INLINE_HEADER const Bufbyte *
+charptr_n_addr (const Bufbyte *ptr, Charcount offset);
+INLINE_HEADER const Bufbyte *
 charptr_n_addr (const Bufbyte *ptr, Charcount offset)
 {
   return ptr + charcount_to_bytecount (ptr, offset);
@@ -489,10 +496,10 @@ charptr_n_addr (const Bufbyte *ptr, Charcount offset)
 
 Emchar non_ascii_charptr_emchar (const Bufbyte *ptr);
 Bytecount non_ascii_set_charptr_emchar (Bufbyte *ptr, Emchar c);
-Bytecount non_ascii_charptr_copy_char (const Bufbyte *ptr, Bufbyte *ptr2);
+Bytecount non_ascii_charptr_copy_char (const Bufbyte *src, Bufbyte *dst);
 
-INLINE Emchar charptr_emchar (const Bufbyte *ptr);
-INLINE Emchar
+INLINE_HEADER Emchar charptr_emchar (const Bufbyte *ptr);
+INLINE_HEADER Emchar
 charptr_emchar (const Bufbyte *ptr)
 {
   return BYTE_ASCII_P (*ptr) ?
@@ -500,8 +507,8 @@ charptr_emchar (const Bufbyte *ptr)
     non_ascii_charptr_emchar (ptr);
 }
 
-INLINE Bytecount set_charptr_emchar (Bufbyte *ptr, Emchar x);
-INLINE Bytecount
+INLINE_HEADER Bytecount set_charptr_emchar (Bufbyte *ptr, Emchar x);
+INLINE_HEADER Bytecount
 set_charptr_emchar (Bufbyte *ptr, Emchar x)
 {
   return !CHAR_MULTIBYTE_P (x) ?
@@ -509,13 +516,16 @@ set_charptr_emchar (Bufbyte *ptr, Emchar x)
     non_ascii_set_charptr_emchar (ptr, x);
 }
 
-INLINE Bytecount charptr_copy_char (const Bufbyte *ptr, Bufbyte *ptr2);
-INLINE Bytecount
-charptr_copy_char (const Bufbyte *ptr, Bufbyte *ptr2)
+/* Copy the character pointed to by SRC into DST.
+   Return the number of bytes copied.  */
+INLINE_HEADER Bytecount
+charptr_copy_char (const Bufbyte *src, Bufbyte *dst);
+INLINE_HEADER Bytecount
+charptr_copy_char (const Bufbyte *src, Bufbyte *dst)
 {
-  return BYTE_ASCII_P (*ptr) ?
-    simple_charptr_copy_char (ptr, ptr2) :
-    non_ascii_charptr_copy_char (ptr, ptr2);
+  return BYTE_ASCII_P (*src) ?
+    simple_charptr_copy_char (src, dst) :
+    non_ascii_charptr_copy_char (src, dst);
 }
 
 #else /* not MULE */
@@ -538,8 +548,8 @@ charptr_copy_char (const Bufbyte *ptr, Bufbyte *ptr2)
 
 int non_ascii_valid_char_p (Emchar ch);
 
-INLINE int valid_char_p (Emchar ch);
-INLINE int
+INLINE_HEADER int valid_char_p (Emchar ch);
+INLINE_HEADER int
 valid_char_p (Emchar ch)
 {
   return ((unsigned int) (ch) <= 0xff) || non_ascii_valid_char_p (ch);
@@ -555,22 +565,13 @@ valid_char_p (Emchar ch)
 
 #define CHAR_OR_CHAR_INTP(x) (CHARP (x) || CHAR_INTP (x))
 
-#ifdef ERROR_CHECK_TYPECHECK
-
-INLINE Emchar XCHAR_OR_CHAR_INT (Lisp_Object obj);
-INLINE Emchar
+INLINE_HEADER Emchar XCHAR_OR_CHAR_INT (Lisp_Object obj);
+INLINE_HEADER Emchar
 XCHAR_OR_CHAR_INT (Lisp_Object obj)
 {
-  assert (CHAR_OR_CHAR_INTP (obj));
   return CHARP (obj) ? XCHAR (obj) : XINT (obj);
 }
 
-#else
-
-#define XCHAR_OR_CHAR_INT(obj) (CHARP (obj) ? XCHAR (obj) : XINT (obj))
-
-#endif
-
 #define CHECK_CHAR_COERCE_INT(x) do {          \
   if (CHARP (x))                               \
      ;                                         \
@@ -622,8 +623,8 @@ XCHAR_OR_CHAR_INT (Lisp_Object obj)
 /*----------------------------------------------------------------------*/
 
 /* Convert the address of a byte in the buffer into a position.  */
-INLINE Bytind BI_BUF_PTR_BYTE_POS (struct buffer *buf, Bufbyte *ptr);
-INLINE Bytind
+INLINE_HEADER Bytind BI_BUF_PTR_BYTE_POS (struct buffer *buf, Bufbyte *ptr);
+INLINE_HEADER Bytind
 BI_BUF_PTR_BYTE_POS (struct buffer *buf, Bufbyte *ptr)
 {
   return (ptr - buf->text->beg + 1
@@ -635,8 +636,8 @@ BI_BUF_PTR_BYTE_POS (struct buffer *buf, Bufbyte *ptr)
   bytind_to_bufpos (buf, BI_BUF_PTR_BYTE_POS (buf, ptr))
 
 /* Address of byte at position POS in buffer. */
-INLINE Bufbyte * BI_BUF_BYTE_ADDRESS (struct buffer *buf, Bytind pos);
-INLINE Bufbyte *
+INLINE_HEADER Bufbyte * BI_BUF_BYTE_ADDRESS (struct buffer *buf, Bytind pos);
+INLINE_HEADER Bufbyte *
 BI_BUF_BYTE_ADDRESS (struct buffer *buf, Bytind pos)
 {
   return (buf->text->beg +
@@ -648,8 +649,8 @@ BI_BUF_BYTE_ADDRESS (struct buffer *buf, Bytind pos)
   BI_BUF_BYTE_ADDRESS (buf, bufpos_to_bytind (buf, pos))
 
 /* Address of byte before position POS in buffer. */
-INLINE Bufbyte * BI_BUF_BYTE_ADDRESS_BEFORE (struct buffer *buf, Bytind pos);
-INLINE Bufbyte *
+INLINE_HEADER Bufbyte * BI_BUF_BYTE_ADDRESS_BEFORE (struct buffer *buf, Bytind pos);
+INLINE_HEADER Bufbyte *
 BI_BUF_BYTE_ADDRESS_BEFORE (struct buffer *buf, Bytind pos)
 {
   return (buf->text->beg +
@@ -664,8 +665,8 @@ BI_BUF_BYTE_ADDRESS_BEFORE (struct buffer *buf, Bytind pos)
 /*         Converting between byte indices and memory indices          */
 /*----------------------------------------------------------------------*/
 
-INLINE int valid_memind_p (struct buffer *buf, Memind x);
-INLINE int
+INLINE_HEADER int valid_memind_p (struct buffer *buf, Memind x);
+INLINE_HEADER int
 valid_memind_p (struct buffer *buf, Memind x)
 {
   return ((x >= 1 && x <= (Memind) buf->text->gpt) ||
@@ -673,16 +674,16 @@ valid_memind_p (struct buffer *buf, Memind x)
           x <= (Memind) (buf->text->z   + buf->text->gap_size)));
 }
 
-INLINE Memind bytind_to_memind (struct buffer *buf, Bytind x);
-INLINE Memind
+INLINE_HEADER Memind bytind_to_memind (struct buffer *buf, Bytind x);
+INLINE_HEADER Memind
 bytind_to_memind (struct buffer *buf, Bytind x)
 {
   return (Memind) ((x > buf->text->gpt) ? (x + buf->text->gap_size) : x);
 }
 
 
-INLINE Bytind memind_to_bytind (struct buffer *buf, Memind x);
-INLINE Bytind
+INLINE_HEADER Bytind memind_to_bytind (struct buffer *buf, Memind x);
+INLINE_HEADER Bytind
 memind_to_bytind (struct buffer *buf, Memind x)
 {
 #ifdef ERROR_CHECK_BUFPOS
@@ -902,16 +903,16 @@ memind_to_bytind (struct buffer *buf, Memind x)
   VALIDATE_BYTIND_BACKWARD (buf, x);                   \
 } while (0)
 
-INLINE Bytind prev_bytind (struct buffer *buf, Bytind x);
-INLINE Bytind
+INLINE_HEADER Bytind prev_bytind (struct buffer *buf, Bytind x);
+INLINE_HEADER Bytind
 prev_bytind (struct buffer *buf, Bytind x)
 {
   DEC_BYTIND (buf, x);
   return x;
 }
 
-INLINE Bytind next_bytind (struct buffer *buf, Bytind x);
-INLINE Bytind
+INLINE_HEADER Bytind next_bytind (struct buffer *buf, Bytind x);
+INLINE_HEADER Bytind
 next_bytind (struct buffer *buf, Bytind x)
 {
   INC_BYTIND (buf, x);
@@ -973,8 +974,8 @@ Bufpos bytind_to_bufpos_func (struct buffer *buf, Bytind x);
 
 extern short three_to_one_table[];
 
-INLINE int real_bufpos_to_bytind (struct buffer *buf, Bufpos x);
-INLINE int
+INLINE_HEADER int real_bufpos_to_bytind (struct buffer *buf, Bufpos x);
+INLINE_HEADER int
 real_bufpos_to_bytind (struct buffer *buf, Bufpos x)
 {
   if (x >= buf->text->mule_bufmin && x <= buf->text->mule_bufmax)
@@ -985,8 +986,8 @@ real_bufpos_to_bytind (struct buffer *buf, Bufpos x)
     return bufpos_to_bytind_func (buf, x);
 }
 
-INLINE int real_bytind_to_bufpos (struct buffer *buf, Bytind x);
-INLINE int
+INLINE_HEADER int real_bytind_to_bufpos (struct buffer *buf, Bytind x);
+INLINE_HEADER int
 real_bytind_to_bufpos (struct buffer *buf, Bytind x)
 {
   if (x >= buf->text->mule_bytmin && x <= buf->text->mule_bytmax)
@@ -1061,8 +1062,8 @@ Bufpos bytind_to_bufpos (struct buffer *buf, Bytind x);
   DATA,   (ptr, len),    // input data is a fixed buffer of size len
   ALLOCA, (ptr, len),    // output data is in a alloca()ed buffer of size len
   MALLOC, (ptr, len),    // output data is in a malloc()ed buffer of size len
-  C_STRING_ALLOCA, ptr,  // equivalent to ALLOCA (ptr, len_ignored) on output.
-  C_STRING_MALLOC, ptr,  // equivalent to MALLOC (ptr, len_ignored) on output.
+  C_STRING_ALLOCA, ptr,  // equivalent to ALLOCA (ptr, len_ignored) on output
+  C_STRING_MALLOC, ptr,  // equivalent to MALLOC (ptr, len_ignored) on output
   C_STRING,     ptr,     // equivalent to DATA, (ptr, strlen (ptr) + 1) on input
   LISP_STRING,  string,  // input or output is a Lisp_Object of type string
   LISP_BUFFER,  buffer,  // output is written to (point) in lisp buffer
@@ -1188,7 +1189,7 @@ typedef enum dfc_conversion_type dfc_conversion_type;
 
 /* WARNING: These use a static buffer.  This can lead to disaster if
    these functions are not used *very* carefully.  Another reason to only use
-   TO_EXTERNAL_FORMATf() and TO_INTERNAL_FORMAT(). */
+   TO_EXTERNAL_FORMAT() and TO_INTERNAL_FORMAT(). */
 void
 dfc_convert_to_external_format (dfc_conversion_type source_type,
                                dfc_conversion_data *source,
@@ -1267,16 +1268,17 @@ dfc_convert_to_internal_format (dfc_conversion_type source_type,
 } while (0)
 
 /* Assign to the `sink' lvalue(s) using the converted data. */
+typedef union { char c; void *p; } *dfc_aliasing_voidpp;
 #define DFC_ALLOCA_USE_CONVERTED_DATA(sink) do {                       \
   void * dfc_sink_ret = alloca (dfc_sink.data.len + 1);                        \
   memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1);     \
-  (DFC_CPP_CAR sink) = (unsigned char *) dfc_sink_ret;                 \
+  ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret;       \
   (DFC_CPP_CDR sink) = dfc_sink.data.len;                              \
 } while (0)
 #define DFC_MALLOC_USE_CONVERTED_DATA(sink) do {                       \
   void * dfc_sink_ret = xmalloc (dfc_sink.data.len + 1);               \
   memcpy (dfc_sink_ret, dfc_sink.data.ptr, dfc_sink.data.len + 1);     \
-  (DFC_CPP_CAR sink) = (unsigned char *) dfc_sink_ret;                 \
+  ((dfc_aliasing_voidpp) &(DFC_CPP_CAR sink))->p = dfc_sink_ret;       \
   (DFC_CPP_CDR sink) = dfc_sink.data.len;                              \
 } while (0)
 #define DFC_C_STRING_ALLOCA_USE_CONVERTED_DATA(sink) do {              \
@@ -1303,6 +1305,30 @@ dfc_convert_to_internal_format (dfc_conversion_type source_type,
    argument to TO_EXTERNAL_FORMAT() and TO_INTERNAL_FORMAT(). */
 #define Qnative Qfile_name
 
+#if defined (WIN32_NATIVE) || defined (CYGWIN)
+/* #### kludge!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+   Remove this as soon as my Mule code is integrated. */
+#define Qmswindows_tstr Qnative
+#endif
+
+/* More stand-ins */
+#define Qcommand_argument_encoding Qnative
+#define Qenvironment_variable_encoding Qnative
+
+/* Convenience macros for extremely common invocations */
+#define C_STRING_TO_EXTERNAL(in, out, coding_system) \
+  TO_EXTERNAL_FORMAT (C_STRING, in, C_STRING_ALLOCA, out, coding_system)
+#define C_STRING_TO_EXTERNAL_MALLOC(in, out, coding_system) \
+  TO_EXTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, coding_system)
+#define EXTERNAL_TO_C_STRING(in, out, coding_system) \
+  TO_INTERNAL_FORMAT (C_STRING, in, C_STRING_ALLOCA, out, coding_system)
+#define EXTERNAL_TO_C_STRING_MALLOC(in, out, coding_system) \
+  TO_INTERNAL_FORMAT (C_STRING, in, C_STRING_MALLOC, out, coding_system)
+#define LISP_STRING_TO_EXTERNAL(in, out, coding_system) \
+  TO_EXTERNAL_FORMAT (LISP_STRING, in, C_STRING_ALLOCA, out, coding_system)
+#define LISP_STRING_TO_EXTERNAL_MALLOC(in, out, coding_system) \
+  TO_EXTERNAL_FORMAT (LISP_STRING, in, C_STRING_MALLOC, out, coding_system)
+
 \f
 /************************************************************************/
 /*                                                                      */
@@ -1666,59 +1692,38 @@ int map_over_sharing_buffers (struct buffer *buf,
    already guaranteed that the character values are all in the range
    0 - 255.  Bad lossage will happen otherwise. */
 
-# define MAKE_TRT_TABLE() Fmake_string (make_int (256), make_char (0))
-# define TRT_TABLE_AS_STRING(table) XSTRING_DATA (table)
-# define TRT_TABLE_CHAR_1(table, ch) \
-  string_char (XSTRING (table), (Charcount) ch)
-# define SET_TRT_TABLE_CHAR_1(table, ch1, ch2) \
-  set_string_char (XSTRING (table), (Charcount) ch1, ch2)
-
-#ifdef MULE
-# define MAKE_MIRROR_TRT_TABLE() make_opaque (OPAQUE_CLEAR, 256)
-# define MIRROR_TRT_TABLE_AS_STRING(table) ((Bufbyte *) XOPAQUE_DATA (table))
-# define MIRROR_TRT_TABLE_CHAR_1(table, ch) \
-  ((Emchar) (MIRROR_TRT_TABLE_AS_STRING (table)[ch]))
-# define SET_MIRROR_TRT_TABLE_CHAR_1(table, ch1, ch2) \
-  (MIRROR_TRT_TABLE_AS_STRING (table)[ch1] = (Bufbyte) (ch2))
-#endif
-
-# define IN_TRT_TABLE_DOMAIN(c) (((EMACS_UINT) (c)) <= 255)
-
-#ifdef MULE
-#define MIRROR_DOWNCASE_TABLE_AS_STRING(buf) \
-  MIRROR_TRT_TABLE_AS_STRING (buf->mirror_downcase_table)
-#define MIRROR_UPCASE_TABLE_AS_STRING(buf) \
-  MIRROR_TRT_TABLE_AS_STRING (buf->mirror_upcase_table)
-#define MIRROR_CANON_TABLE_AS_STRING(buf) \
-  MIRROR_TRT_TABLE_AS_STRING (buf->mirror_case_canon_table)
-#define MIRROR_EQV_TABLE_AS_STRING(buf) \
-  MIRROR_TRT_TABLE_AS_STRING (buf->mirror_case_eqv_table)
-#else
-#define MIRROR_DOWNCASE_TABLE_AS_STRING(buf) \
-  TRT_TABLE_AS_STRING (buf->downcase_table)
-#define MIRROR_UPCASE_TABLE_AS_STRING(buf) \
-  TRT_TABLE_AS_STRING (buf->upcase_table)
-#define MIRROR_CANON_TABLE_AS_STRING(buf) \
-  TRT_TABLE_AS_STRING (buf->case_canon_table)
-#define MIRROR_EQV_TABLE_AS_STRING(buf) \
-  TRT_TABLE_AS_STRING (buf->case_eqv_table)
-#endif
+#define MAKE_TRT_TABLE() Fmake_char_table (Qgeneric)
+INLINE_HEADER Emchar TRT_TABLE_CHAR_1 (Lisp_Object table, Emchar c);
+INLINE_HEADER Emchar
+TRT_TABLE_CHAR_1 (Lisp_Object table, Emchar ch)
+{
+  Lisp_Object TRT_char;
+  TRT_char = get_char_table (ch, XCHAR_TABLE (table));
+  if (NILP (TRT_char))
+    return ch;
+  else
+    return XCHAR (TRT_char);
+}
+#define SET_TRT_TABLE_CHAR_1(table, ch1, ch2)  \
+  Fput_char_table (make_char (ch1), make_char (ch2), table);
 
-INLINE Emchar TRT_TABLE_OF (Lisp_Object trt, Emchar c);
-INLINE Emchar
+INLINE_HEADER Emchar TRT_TABLE_OF (Lisp_Object trt, Emchar c);
+INLINE_HEADER Emchar
 TRT_TABLE_OF (Lisp_Object trt, Emchar c)
 {
-  return IN_TRT_TABLE_DOMAIN (c) ? TRT_TABLE_CHAR_1 (trt, c) : c;
+  return TRT_TABLE_CHAR_1 (trt, c);
 }
 
 /* Macros used below. */
-#define DOWNCASE_TABLE_OF(buf, c) TRT_TABLE_OF (buf->downcase_table, c)
-#define UPCASE_TABLE_OF(buf, c) TRT_TABLE_OF (buf->upcase_table, c)
+#define DOWNCASE_TABLE_OF(buf, c)      \
+  TRT_TABLE_OF (XCASE_TABLE_DOWNCASE (buf->case_table), c)
+#define UPCASE_TABLE_OF(buf, c)                \
+  TRT_TABLE_OF (XCASE_TABLE_UPCASE (buf->case_table), c)
 
 /* 1 if CH is upper case.  */
 
-INLINE int UPPERCASEP (struct buffer *buf, Emchar ch);
-INLINE int
+INLINE_HEADER int UPPERCASEP (struct buffer *buf, Emchar ch);
+INLINE_HEADER int
 UPPERCASEP (struct buffer *buf, Emchar ch)
 {
   return DOWNCASE_TABLE_OF (buf, ch) != ch;
@@ -1726,8 +1731,8 @@ UPPERCASEP (struct buffer *buf, Emchar ch)
 
 /* 1 if CH is lower case.  */
 
-INLINE int LOWERCASEP (struct buffer *buf, Emchar ch);
-INLINE int
+INLINE_HEADER int LOWERCASEP (struct buffer *buf, Emchar ch);
+INLINE_HEADER int
 LOWERCASEP (struct buffer *buf, Emchar ch)
 {
   return (UPCASE_TABLE_OF   (buf, ch) != ch &&
@@ -1736,8 +1741,8 @@ LOWERCASEP (struct buffer *buf, Emchar ch)
 
 /* 1 if CH is neither upper nor lower case.  */
 
-INLINE int NOCASEP (struct buffer *buf, Emchar ch);
-INLINE int
+INLINE_HEADER int NOCASEP (struct buffer *buf, Emchar ch);
+INLINE_HEADER int
 NOCASEP (struct buffer *buf, Emchar ch)
 {
   return UPCASE_TABLE_OF (buf, ch) == ch;
@@ -1745,8 +1750,8 @@ NOCASEP (struct buffer *buf, Emchar ch)
 
 /* Upcase a character, or make no change if that cannot be done.  */
 
-INLINE Emchar UPCASE (struct buffer *buf, Emchar ch);
-INLINE Emchar
+INLINE_HEADER Emchar UPCASE (struct buffer *buf, Emchar ch);
+INLINE_HEADER Emchar
 UPCASE (struct buffer *buf, Emchar ch)
 {
   return (DOWNCASE_TABLE_OF (buf, ch) == ch) ? UPCASE_TABLE_OF (buf, ch) : ch;
@@ -1760,4 +1765,60 @@ UPCASE (struct buffer *buf, Emchar ch)
 
 #define DOWNCASE(buf, ch) DOWNCASE_TABLE_OF (buf, ch)
 
+/************************************************************************/
+/*             Lisp string representation convenience functions        */
+/************************************************************************/
+/* Because the representation of internally formatted data is subject to change,
+   It's bad style to do something like strcmp (XSTRING_DATA (s), "foo")
+   Instead, use the portable: bufbyte_strcmp (XSTRING_DATA (s), "foo")
+   or bufbyte_memcmp (XSTRING_DATA (s), "foo", 3) */
+
+/* Like strcmp, except first arg points at internally formatted data,
+   while the second points at a string of only ASCII chars. */
+INLINE_HEADER int
+bufbyte_strcmp (const Bufbyte *bp, const char *ascii_string);
+INLINE_HEADER int
+bufbyte_strcmp (const Bufbyte *bp, const char *ascii_string)
+{
+#ifdef MULE
+  while (1)
+    {
+      int diff;
+      type_checking_assert (BYTE_ASCII_P (*ascii_string));
+      if ((diff = charptr_emchar (bp) - *(Bufbyte *) ascii_string) != 0)
+       return diff;
+      if (*ascii_string == '\0')
+       return 0;
+      ascii_string++;
+      INC_CHARPTR (bp);
+    }
+#else
+  return strcmp ((char *)bp, ascii_string);
+#endif
+}
+
+
+/* Like memcmp, except first arg points at internally formatted data,
+   while the second points at a string of only ASCII chars. */
+INLINE_HEADER int
+bufbyte_memcmp (const Bufbyte *bp, const char *ascii_string, size_t len);
+INLINE_HEADER int
+bufbyte_memcmp (const Bufbyte *bp, const char *ascii_string, size_t len)
+{
+#ifdef MULE
+  while (len--)
+    {
+      int diff = charptr_emchar (bp) - *(Bufbyte *) ascii_string;
+      type_checking_assert (BYTE_ASCII_P (*ascii_string));
+      if (diff != 0)
+       return diff;
+      ascii_string++;
+      INC_CHARPTR (bp);
+    }
+  return 0;
+#else
+  return memcmp (bp, ascii_string, len);
+#endif
+}
+
 #endif /* INCLUDED_buffer_h_ */