]> code.delx.au - gnu-emacs/blobdiff - src/fns.c
(struct redisplay_interface): Add active_p argument to
[gnu-emacs] / src / fns.c
index 621d19fbbcc6612b4c5d1e6d3abdc4d145207186..fe3e0f82a3f9b06ce32d10f0f8fd47ee6485a435 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -1,5 +1,5 @@
 /* Random utility Lisp functions.
 /* Random utility Lisp functions.
-   Copyright (C) 1985, 86, 87, 93, 94, 95, 97, 98, 99, 2000, 2001
+   Copyright (C) 1985, 86, 87, 93, 94, 95, 97, 98, 99, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -30,11 +30,10 @@ Boston, MA 02111-1307, USA.  */
    so make sure we don't use that name in this file.  */
 #undef vector
 #define vector *****
    so make sure we don't use that name in this file.  */
 #undef vector
 #define vector *****
-
 #include "lisp.h"
 #include "commands.h"
 #include "charset.h"
 #include "lisp.h"
 #include "commands.h"
 #include "charset.h"
-
+#include "coding.h"
 #include "buffer.h"
 #include "keyboard.h"
 #include "keymap.h"
 #include "buffer.h"
 #include "keyboard.h"
 #include "keymap.h"
@@ -47,7 +46,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #ifndef NULL
 #endif
 
 #ifndef NULL
-#define NULL (void *)0
+#define NULL ((POINTER_TYPE *)0)
 #endif
 
 /* Nonzero enables use of dialog boxes for questions
 #endif
 
 /* Nonzero enables use of dialog boxes for questions
@@ -56,11 +55,13 @@ int use_dialog_box;
 
 extern int minibuffer_auto_raise;
 extern Lisp_Object minibuf_window;
 
 extern int minibuffer_auto_raise;
 extern Lisp_Object minibuf_window;
+extern Lisp_Object Vlocale_coding_system;
 
 Lisp_Object Qstring_lessp, Qprovide, Qrequire;
 Lisp_Object Qyes_or_no_p_history;
 Lisp_Object Qcursor_in_echo_area;
 Lisp_Object Qwidget_type;
 
 Lisp_Object Qstring_lessp, Qprovide, Qrequire;
 Lisp_Object Qyes_or_no_p_history;
 Lisp_Object Qcursor_in_echo_area;
 Lisp_Object Qwidget_type;
+Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper;
 
 extern Lisp_Object Qinput_method_function;
 
 
 extern Lisp_Object Qinput_method_function;
 
@@ -74,7 +75,7 @@ extern long time ();
 #endif
 \f
 DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
 #endif
 \f
 DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
-       doc: /* Return the argument unchanged. */)
+       doc: /* Return the argument unchanged.  */)
      (arg)
      Lisp_Object arg;
 {
      (arg)
      Lisp_Object arg;
 {
@@ -121,7 +122,7 @@ With argument t, set the random number seed from the current time and pid. */)
 DEFUN ("length", Flength, Slength, 1, 1, 0,
        doc: /* Return the length of vector, list or string SEQUENCE.
 A byte-code function object is also allowed.
 DEFUN ("length", Flength, Slength, 1, 1, 0,
        doc: /* Return the length of vector, list or string SEQUENCE.
 A byte-code function object is also allowed.
-If the string contains multibyte characters, this is not the necessarily
+If the string contains multibyte characters, this is not necessarily
 the number of bytes in the string; it is the number of characters.
 To get the number of bytes, use `string-bytes'. */)
      (sequence)
 the number of bytes in the string; it is the number of characters.
 To get the number of bytes, use `string-bytes'. */)
      (sequence)
@@ -132,7 +133,7 @@ To get the number of bytes, use `string-bytes'. */)
 
  retry:
   if (STRINGP (sequence))
 
  retry:
   if (STRINGP (sequence))
-    XSETFASTINT (val, XSTRING (sequence)->size);
+    XSETFASTINT (val, SCHARS (sequence));
   else if (VECTORP (sequence))
     XSETFASTINT (val, XVECTOR (sequence)->size);
   else if (CHAR_TABLE_P (sequence))
   else if (VECTORP (sequence))
     XSETFASTINT (val, XVECTOR (sequence)->size);
   else if (CHAR_TABLE_P (sequence))
@@ -201,14 +202,14 @@ which is at least the number of distinct elements. */)
   return length;
 }
 
   return length;
 }
 
-DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0, 
+DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
        doc: /* Return the number of bytes in STRING.
 If STRING is a multibyte string, this is greater than the length of STRING. */)
      (string)
      Lisp_Object string;
 {
   CHECK_STRING (string);
        doc: /* Return the number of bytes in STRING.
 If STRING is a multibyte string, this is greater than the length of STRING. */)
      (string)
      Lisp_Object string;
 {
   CHECK_STRING (string);
-  return make_number (STRING_BYTES (XSTRING (string)));
+  return make_number (SBYTES (string));
 }
 
 DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
 }
 
 DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
@@ -219,15 +220,15 @@ Symbols are also allowed; their print names are used instead. */)
      register Lisp_Object s1, s2;
 {
   if (SYMBOLP (s1))
      register Lisp_Object s1, s2;
 {
   if (SYMBOLP (s1))
-    XSETSTRING (s1, XSYMBOL (s1)->name);
+    s1 = SYMBOL_NAME (s1);
   if (SYMBOLP (s2))
   if (SYMBOLP (s2))
-    XSETSTRING (s2, XSYMBOL (s2)->name);
+    s2 = SYMBOL_NAME (s2);
   CHECK_STRING (s1);
   CHECK_STRING (s2);
 
   CHECK_STRING (s1);
   CHECK_STRING (s2);
 
-  if (XSTRING (s1)->size != XSTRING (s2)->size
-      || STRING_BYTES (XSTRING (s1)) != STRING_BYTES (XSTRING (s2))
-      || bcmp (XSTRING (s1)->data, XSTRING (s2)->data, STRING_BYTES (XSTRING (s1))))
+  if (SCHARS (s1) != SCHARS (s2)
+      || SBYTES (s1) != SBYTES (s2)
+      || bcmp (SDATA (s1), SDATA (s2), SBYTES (s1)))
     return Qnil;
   return Qt;
 }
     return Qnil;
   return Qt;
 }
@@ -272,11 +273,11 @@ If string STR1 is greater, the value is a positive number N;
   i1_byte = string_char_to_byte (str1, i1);
   i2_byte = string_char_to_byte (str2, i2);
 
   i1_byte = string_char_to_byte (str1, i1);
   i2_byte = string_char_to_byte (str2, i2);
 
-  end1_char = XSTRING (str1)->size;
+  end1_char = SCHARS (str1);
   if (! NILP (end1) && end1_char > XINT (end1))
     end1_char = XINT (end1);
 
   if (! NILP (end1) && end1_char > XINT (end1))
     end1_char = XINT (end1);
 
-  end2_char = XSTRING (str2)->size;
+  end2_char = SCHARS (str2);
   if (! NILP (end2) && end2_char > XINT (end2))
     end2_char = XINT (end2);
 
   if (! NILP (end2) && end2_char > XINT (end2))
     end2_char = XINT (end2);
 
@@ -290,7 +291,7 @@ If string STR1 is greater, the value is a positive number N;
        FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c1, str1, i1, i1_byte);
       else
        {
        FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c1, str1, i1, i1_byte);
       else
        {
-         c1 = XSTRING (str1)->data[i1++];
+         c1 = SREF (str1, i1++);
          c1 = unibyte_char_to_multibyte (c1);
        }
 
          c1 = unibyte_char_to_multibyte (c1);
        }
 
@@ -298,7 +299,7 @@ If string STR1 is greater, the value is a positive number N;
        FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c2, str2, i2, i2_byte);
       else
        {
        FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c2, str2, i2, i2_byte);
       else
        {
-         c2 = XSTRING (str2)->data[i2++];
+         c2 = SREF (str2, i2++);
          c2 = unibyte_char_to_multibyte (c2);
        }
 
          c2 = unibyte_char_to_multibyte (c2);
        }
 
@@ -346,17 +347,17 @@ Symbols are also allowed; their print names are used instead. */)
   register int i1, i1_byte, i2, i2_byte;
 
   if (SYMBOLP (s1))
   register int i1, i1_byte, i2, i2_byte;
 
   if (SYMBOLP (s1))
-    XSETSTRING (s1, XSYMBOL (s1)->name);
+    s1 = SYMBOL_NAME (s1);
   if (SYMBOLP (s2))
   if (SYMBOLP (s2))
-    XSETSTRING (s2, XSYMBOL (s2)->name);
+    s2 = SYMBOL_NAME (s2);
   CHECK_STRING (s1);
   CHECK_STRING (s2);
 
   i1 = i1_byte = i2 = i2_byte = 0;
 
   CHECK_STRING (s1);
   CHECK_STRING (s2);
 
   i1 = i1_byte = i2 = i2_byte = 0;
 
-  end = XSTRING (s1)->size;
-  if (end > XSTRING (s2)->size)
-    end = XSTRING (s2)->size;
+  end = SCHARS (s1);
+  if (end > SCHARS (s2))
+    end = SCHARS (s2);
 
   while (i1 < end)
     {
 
   while (i1 < end)
     {
@@ -370,7 +371,7 @@ Symbols are also allowed; their print names are used instead. */)
       if (c1 != c2)
        return c1 < c2 ? Qt : Qnil;
     }
       if (c1 != c2)
        return c1 < c2 ? Qt : Qnil;
     }
-  return i1 < XSTRING (s2)->size ? Qt : Qnil;
+  return i1 < SCHARS (s2) ? Qt : Qnil;
 }
 \f
 static Lisp_Object concat ();
 }
 \f
 static Lisp_Object concat ();
@@ -443,7 +444,7 @@ usage: (vconcat &rest SEQUENCES)   */)
   return concat (nargs, args, Lisp_Vectorlike, 0);
 }
 
   return concat (nargs, args, Lisp_Vectorlike, 0);
 }
 
-/* Retrun a copy of a sub char table ARG.  The elements except for a
+/* Return a copy of a sub char table ARG.  The elements except for a
    nested sub char table are not copied.  */
 static Lisp_Object
 copy_sub_char_table (arg)
    nested sub char table are not copied.  */
 static Lisp_Object
 copy_sub_char_table (arg)
@@ -466,7 +467,7 @@ copy_sub_char_table (arg)
 
 
 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
 
 
 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
-       doc: /* Return a copy of a list, vector or string.
+       doc: /* Return a copy of a list, vector, string or char-table.
 The elements of a list or vector are not copied; they are shared
 with the original. */)
      (arg)
 The elements of a list or vector are not copied; they are shared
 with the original. */)
      (arg)
@@ -641,11 +642,11 @@ concat (nargs, args, target_type, last_special)
              if (STRING_MULTIBYTE (this))
                {
                  some_multibyte = 1;
              if (STRING_MULTIBYTE (this))
                {
                  some_multibyte = 1;
-                 result_len_byte += STRING_BYTES (XSTRING (this));
+                 result_len_byte += SBYTES (this);
                }
              else
                }
              else
-               result_len_byte += count_size_as_multibyte (XSTRING (this)->data,
-                                                           XSTRING (this)->size);
+               result_len_byte += count_size_as_multibyte (SDATA (this),
+                                                           SCHARS (this));
            }
        }
 
            }
        }
 
@@ -695,17 +696,17 @@ concat (nargs, args, target_type, last_special)
       if (STRINGP (this) && STRINGP (val)
          && STRING_MULTIBYTE (this) == some_multibyte)
        {
       if (STRINGP (this) && STRINGP (val)
          && STRING_MULTIBYTE (this) == some_multibyte)
        {
-         int thislen_byte = STRING_BYTES (XSTRING (this));
+         int thislen_byte = SBYTES (this);
          int combined;
 
          int combined;
 
-         bcopy (XSTRING (this)->data, XSTRING (val)->data + toindex_byte,
-                STRING_BYTES (XSTRING (this)));
+         bcopy (SDATA (this), SDATA (val) + toindex_byte,
+                SBYTES (this));
          combined =  (some_multibyte && toindex_byte > 0
          combined =  (some_multibyte && toindex_byte > 0
-                      ? count_combining (XSTRING (val)->data,
+                      ? count_combining (SDATA (val),
                                          toindex_byte + thislen_byte,
                                          toindex_byte)
                       : 0);
                                          toindex_byte + thislen_byte,
                                          toindex_byte)
                       : 0);
-         if (! NULL_INTERVAL_P (XSTRING (this)->intervals))
+         if (! NULL_INTERVAL_P (STRING_INTERVALS (this)))
            {
              textprops[num_textprops].argnum = argnum;
              /* We ignore text properties on characters being combined.  */
            {
              textprops[num_textprops].argnum = argnum;
              /* We ignore text properties on characters being combined.  */
@@ -714,20 +715,20 @@ concat (nargs, args, target_type, last_special)
            }
          toindex_byte += thislen_byte;
          toindex += thisleni - combined;
            }
          toindex_byte += thislen_byte;
          toindex += thisleni - combined;
-         XSTRING (val)->size -= combined;
+         STRING_SET_CHARS (val, SCHARS (val) - combined);
        }
       /* Copy a single-byte string to a multibyte string.  */
       else if (STRINGP (this) && STRINGP (val))
        {
        }
       /* Copy a single-byte string to a multibyte string.  */
       else if (STRINGP (this) && STRINGP (val))
        {
-         if (! NULL_INTERVAL_P (XSTRING (this)->intervals))
+         if (! NULL_INTERVAL_P (STRING_INTERVALS (this)))
            {
              textprops[num_textprops].argnum = argnum;
              textprops[num_textprops].from = 0;
              textprops[num_textprops++].to = toindex;
            }
            {
              textprops[num_textprops].argnum = argnum;
              textprops[num_textprops].from = 0;
              textprops[num_textprops++].to = toindex;
            }
-         toindex_byte += copy_text (XSTRING (this)->data,
-                                    XSTRING (val)->data + toindex_byte,
-                                    XSTRING (this)->size, 0, 1);
+         toindex_byte += copy_text (SDATA (this),
+                                    SDATA (val) + toindex_byte,
+                                    SCHARS (this), 0, 1);
          toindex += thisleni;
        }
       else
          toindex += thisleni;
        }
       else
@@ -755,7 +756,7 @@ concat (nargs, args, target_type, last_special)
                  }
                else
                  {
                  }
                else
                  {
-                   XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
+                   XSETFASTINT (elt, SREF (this, thisindex++));
                    if (some_multibyte
                        && (XINT (elt) >= 0240
                            || (XINT (elt) >= 0200
                    if (some_multibyte
                        && (XINT (elt) >= 0240
                            || (XINT (elt) >= 0200
@@ -797,14 +798,14 @@ concat (nargs, args, target_type, last_special)
                    if (some_multibyte)
                      toindex_byte
                        += CHAR_STRING (XINT (elt),
                    if (some_multibyte)
                      toindex_byte
                        += CHAR_STRING (XINT (elt),
-                                       XSTRING (val)->data + toindex_byte);
+                                       SDATA (val) + toindex_byte);
                    else
                    else
-                     XSTRING (val)->data[toindex_byte++] = XINT (elt);
+                     SSET (val, toindex_byte++, XINT (elt));
                    if (some_multibyte
                        && toindex_byte > 0
                    if (some_multibyte
                        && toindex_byte > 0
-                       && count_combining (XSTRING (val)->data,
+                       && count_combining (SDATA (val),
                                            toindex_byte, toindex_byte - 1))
                                            toindex_byte, toindex_byte - 1))
-                     XSTRING (val)->size--;
+                     STRING_SET_CHARS (val, SCHARS (val) - 1);
                    else
                      toindex++;
                  }
                    else
                      toindex++;
                  }
@@ -815,7 +816,7 @@ concat (nargs, args, target_type, last_special)
                    int c = XINT (elt);
                    /* P exists as a variable
                       to avoid a bug on the Masscomp C compiler.  */
                    int c = XINT (elt);
                    /* P exists as a variable
                       to avoid a bug on the Masscomp C compiler.  */
-                   unsigned char *p = & XSTRING (val)->data[toindex_byte];
+                   unsigned char *p = SDATA (val) + toindex_byte;
 
                    toindex_byte += CHAR_STRING (c, p);
                    toindex++;
 
                    toindex_byte += CHAR_STRING (c, p);
                    toindex++;
@@ -836,7 +837,7 @@ concat (nargs, args, target_type, last_special)
          this = args[textprops[argnum].argnum];
          props = text_property_list (this,
                                      make_number (0),
          this = args[textprops[argnum].argnum];
          props = text_property_list (this,
                                      make_number (0),
-                                     make_number (XSTRING (this)->size),
+                                     make_number (SCHARS (this)),
                                      Qnil);
          /* If successive arguments have properites, be sure that the
             value of `composition' property be the copy.  */
                                      Qnil);
          /* If successive arguments have properites, be sure that the
             value of `composition' property be the copy.  */
@@ -844,7 +845,7 @@ concat (nargs, args, target_type, last_special)
            make_composition_value_copy (props);
          add_text_properties_from_list (val, props,
                                         make_number (textprops[argnum].to));
            make_composition_value_copy (props);
          add_text_properties_from_list (val, props,
                                         make_number (textprops[argnum].to));
-         last_to_end = textprops[argnum].to + XSTRING (this)->size;
+         last_to_end = textprops[argnum].to + SCHARS (this);
        }
     }
   return val;
        }
     }
   return val;
@@ -875,8 +876,8 @@ string_char_to_byte (string, char_index)
     return char_index;
 
   best_below = best_below_byte = 0;
     return char_index;
 
   best_below = best_below_byte = 0;
-  best_above = XSTRING (string)->size;
-  best_above_byte = STRING_BYTES (XSTRING (string));
+  best_above = SCHARS (string);
+  best_above_byte = SBYTES (string);
 
   if (EQ (string, string_char_byte_cache_string))
     {
 
   if (EQ (string, string_char_byte_cache_string))
     {
@@ -907,7 +908,7 @@ string_char_to_byte (string, char_index)
     {
       while (best_above > char_index)
        {
     {
       while (best_above > char_index)
        {
-         unsigned char *pend = XSTRING (string)->data + best_above_byte;
+         unsigned char *pend = SDATA (string) + best_above_byte;
          unsigned char *pbeg = pend - best_above_byte;
          unsigned char *p = pend - 1;
          int bytes;
          unsigned char *pbeg = pend - best_above_byte;
          unsigned char *p = pend - 1;
          int bytes;
@@ -948,8 +949,8 @@ string_byte_to_char (string, byte_index)
     return byte_index;
 
   best_below = best_below_byte = 0;
     return byte_index;
 
   best_below = best_below_byte = 0;
-  best_above = XSTRING (string)->size;
-  best_above_byte = STRING_BYTES (XSTRING (string));
+  best_above = SCHARS (string);
+  best_above_byte = SBYTES (string);
 
   if (EQ (string, string_char_byte_cache_string))
     {
 
   if (EQ (string, string_char_byte_cache_string))
     {
@@ -980,7 +981,7 @@ string_byte_to_char (string, byte_index)
     {
       while (best_above_byte > byte_index)
        {
     {
       while (best_above_byte > byte_index)
        {
-         unsigned char *pend = XSTRING (string)->data + best_above_byte;
+         unsigned char *pend = SDATA (string) + best_above_byte;
          unsigned char *pbeg = pend - best_above_byte;
          unsigned char *p = pend - 1;
          int bytes;
          unsigned char *pbeg = pend - best_above_byte;
          unsigned char *p = pend - 1;
          int bytes;
@@ -1020,20 +1021,50 @@ string_make_multibyte (string)
   if (STRING_MULTIBYTE (string))
     return string;
 
   if (STRING_MULTIBYTE (string))
     return string;
 
-  nbytes = count_size_as_multibyte (XSTRING (string)->data,
-                                   XSTRING (string)->size);
+  nbytes = count_size_as_multibyte (SDATA (string),
+                                   SCHARS (string));
   /* If all the chars are ASCII, they won't need any more bytes
      once converted.  In that case, we can return STRING itself.  */
   /* If all the chars are ASCII, they won't need any more bytes
      once converted.  In that case, we can return STRING itself.  */
-  if (nbytes == STRING_BYTES (XSTRING (string)))
+  if (nbytes == SBYTES (string))
     return string;
 
   buf = (unsigned char *) alloca (nbytes);
     return string;
 
   buf = (unsigned char *) alloca (nbytes);
-  copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
+  copy_text (SDATA (string), buf, SBYTES (string),
             0, 1);
 
             0, 1);
 
-  return make_multibyte_string (buf, XSTRING (string)->size, nbytes);
+  return make_multibyte_string (buf, SCHARS (string), nbytes);
+}
+
+
+/* Convert STRING to a multibyte string without changing each
+   character codes.  Thus, characters 0200 trough 0237 are converted
+   to eight-bit-control characters, and characters 0240 through 0377
+   are converted eight-bit-graphic characters. */
+
+Lisp_Object
+string_to_multibyte (string)
+     Lisp_Object string;
+{
+  unsigned char *buf;
+  int nbytes;
+
+  if (STRING_MULTIBYTE (string))
+    return string;
+
+  nbytes = parse_str_to_multibyte (SDATA (string), SBYTES (string));
+  /* If all the chars are ASCII or eight-bit-graphic, they won't need
+     any more bytes once converted.  */
+  if (nbytes == SBYTES (string))
+    return make_multibyte_string (SDATA (string), nbytes, nbytes);
+
+  buf = (unsigned char *) alloca (nbytes);
+  bcopy (SDATA (string), buf, SBYTES (string));
+  str_to_multibyte (buf, nbytes, SBYTES (string));
+
+  return make_multibyte_string (buf, SCHARS (string), nbytes);
 }
 
 }
 
+
 /* Convert STRING to a single-byte string.  */
 
 Lisp_Object
 /* Convert STRING to a single-byte string.  */
 
 Lisp_Object
@@ -1045,12 +1076,12 @@ string_make_unibyte (string)
   if (! STRING_MULTIBYTE (string))
     return string;
 
   if (! STRING_MULTIBYTE (string))
     return string;
 
-  buf = (unsigned char *) alloca (XSTRING (string)->size);
+  buf = (unsigned char *) alloca (SCHARS (string));
 
 
-  copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
+  copy_text (SDATA (string), buf, SBYTES (string),
             1, 0);
 
             1, 0);
 
-  return make_unibyte_string (buf, XSTRING (string)->size);
+  return make_unibyte_string (buf, SCHARS (string));
 }
 
 DEFUN ("string-make-multibyte", Fstring_make_multibyte, Sstring_make_multibyte,
 }
 
 DEFUN ("string-make-multibyte", Fstring_make_multibyte, Sstring_make_multibyte,
@@ -1069,8 +1100,10 @@ each unibyte character to a multibyte character. */)
 DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte,
        1, 1, 0,
        doc: /* Return the unibyte equivalent of STRING.
 DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte,
        1, 1, 0,
        doc: /* Return the unibyte equivalent of STRING.
-Multibyte character codes are converted to unibyte
-by using just the low 8 bits. */)
+Multibyte character codes are converted to unibyte according to
+`nonascii-translation-table' or, if that is nil, `nonascii-insert-offset'.
+If the lookup in the translation table fails, this function takes just
+the low 8 bits of each character. */)
      (string)
      Lisp_Object string;
 {
      (string)
      Lisp_Object string;
 {
@@ -1094,10 +1127,10 @@ corresponding single byte.  */)
 
   if (STRING_MULTIBYTE (string))
     {
 
   if (STRING_MULTIBYTE (string))
     {
-      int bytes = STRING_BYTES (XSTRING (string));
+      int bytes = SBYTES (string);
       unsigned char *str = (unsigned char *) xmalloc (bytes);
 
       unsigned char *str = (unsigned char *) xmalloc (bytes);
 
-      bcopy (XSTRING (string)->data, str, bytes);
+      bcopy (SDATA (string), str, bytes);
       bytes = str_as_unibyte (str, bytes);
       string = make_unibyte_string (str, bytes);
       xfree (str);
       bytes = str_as_unibyte (str, bytes);
       string = make_unibyte_string (str, bytes);
       xfree (str);
@@ -1123,20 +1156,38 @@ multibyte character of charset `eight-bit-control' or `eight-bit-graphic'.  */)
       Lisp_Object new_string;
       int nchars, nbytes;
 
       Lisp_Object new_string;
       int nchars, nbytes;
 
-      parse_str_as_multibyte (XSTRING (string)->data,
-                             STRING_BYTES (XSTRING (string)),
+      parse_str_as_multibyte (SDATA (string),
+                             SBYTES (string),
                              &nchars, &nbytes);
       new_string = make_uninit_multibyte_string (nchars, nbytes);
                              &nchars, &nbytes);
       new_string = make_uninit_multibyte_string (nchars, nbytes);
-      bcopy (XSTRING (string)->data, XSTRING (new_string)->data,
-            STRING_BYTES (XSTRING (string)));
-      if (nbytes != STRING_BYTES (XSTRING (string)))
-       str_as_multibyte (XSTRING (new_string)->data, nbytes,
-                         STRING_BYTES (XSTRING (string)), NULL);
+      bcopy (SDATA (string), SDATA (new_string),
+            SBYTES (string));
+      if (nbytes != SBYTES (string))
+       str_as_multibyte (SDATA (new_string), nbytes,
+                         SBYTES (string), NULL);
       string = new_string;
       string = new_string;
-      XSTRING (string)->intervals = NULL_INTERVAL;
+      STRING_SET_INTERVALS (string, NULL_INTERVAL);
     }
   return string;
 }
     }
   return string;
 }
+
+DEFUN ("string-to-multibyte", Fstring_to_multibyte, Sstring_to_multibyte,
+       1, 1, 0,
+       doc: /* Return a multibyte string with the same individual chars as STRING.
+If STRING is multibyte, the result is STRING itself.
+Otherwise it is a newly created string, with no text properties.
+Characters 0200 through 0237 are converted to eight-bit-control
+characters of the same character code.  Characters 0240 through 0377
+are converted to eight-bit-control characters of the same character
+codes.  */)
+     (string)
+     Lisp_Object string;
+{
+  CHECK_STRING (string);
+
+  return string_to_multibyte (string);
+}
+
 \f
 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
        doc: /* Return a copy of ALIST.
 \f
 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
        doc: /* Return a copy of ALIST.
@@ -1166,10 +1217,9 @@ Elements of ALIST that are not conses are also shared.  */)
 }
 
 DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
 }
 
 DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
-       doc: /* 
-Return a substring of STRING, starting at index FROM and ending before TO.
+       doc: /* Return a substring of STRING, starting at index FROM and ending before TO.
 TO may be nil or omitted; then the substring runs to the end of STRING.
 TO may be nil or omitted; then the substring runs to the end of STRING.
-If FROM or TO is negative, it counts from the end.
+FROM and TO start at 0.  If either is negative, it counts from the end.
 
 This function allows vectors as well as strings.  */)
      (string, from, to)
 
 This function allows vectors as well as strings.  */)
      (string, from, to)
@@ -1189,8 +1239,8 @@ This function allows vectors as well as strings.  */)
 
   if (STRINGP (string))
     {
 
   if (STRINGP (string))
     {
-      size = XSTRING (string)->size;
-      size_byte = STRING_BYTES (XSTRING (string));
+      size = SCHARS (string);
+      size_byte = SBYTES (string);
     }
   else
     size = XVECTOR (string)->size;
     }
   else
     size = XVECTOR (string)->size;
@@ -1224,7 +1274,7 @@ This function allows vectors as well as strings.  */)
 
   if (STRINGP (string))
     {
 
   if (STRINGP (string))
     {
-      res = make_specified_string (XSTRING (string)->data + from_byte,
+      res = make_specified_string (SDATA (string) + from_byte,
                                   to_char - from_char, to_byte - from_byte,
                                   STRING_MULTIBYTE (string));
       copy_text_properties (make_number (from_char), make_number (to_char),
                                   to_char - from_char, to_byte - from_byte,
                                   STRING_MULTIBYTE (string));
       copy_text_properties (make_number (from_char), make_number (to_char),
@@ -1237,6 +1287,65 @@ This function allows vectors as well as strings.  */)
   return res;
 }
 
   return res;
 }
 
+
+DEFUN ("substring-no-properties", Fsubstring_no_properties, Ssubstring_no_properties, 1, 3, 0,
+       doc: /* Return a substring of STRING, without text properties.
+It starts at index FROM and ending before TO.
+TO may be nil or omitted; then the substring runs to the end of STRING.
+If FROM is nil or omitted, the substring starts at the beginning of STRING.
+If FROM or TO is negative, it counts from the end.
+
+With one argument, just copy STRING without its properties.  */)
+     (string, from, to)
+     Lisp_Object string;
+     register Lisp_Object from, to;
+{
+  int size, size_byte;
+  int from_char, to_char;
+  int from_byte, to_byte;
+
+  CHECK_STRING (string);
+
+  size = SCHARS (string);
+  size_byte = SBYTES (string);
+
+  if (NILP (from))
+    from_char = from_byte = 0;
+  else
+    {
+      CHECK_NUMBER (from);
+      from_char = XINT (from);
+      if (from_char < 0)
+       from_char += size;
+
+      from_byte = string_char_to_byte (string, from_char);
+    }
+
+  if (NILP (to))
+    {
+      to_char = size;
+      to_byte = size_byte;
+    }
+  else
+    {
+      CHECK_NUMBER (to);
+
+      to_char = XINT (to);
+      if (to_char < 0)
+       to_char += size;
+
+      to_byte = string_char_to_byte (string, to_char);
+    }
+
+  if (!(0 <= from_char && from_char <= to_char && to_char <= size))
+    args_out_of_range_3 (string, make_number (from_char),
+                        make_number (to_char));
+
+  return make_specified_string (SDATA (string) + from_byte,
+                               to_char - from_char, to_byte - from_byte,
+                               STRING_MULTIBYTE (string));
+}
+
 /* Extract a substring of STRING, giving start and end positions
    both in characters and in bytes.  */
 
 /* Extract a substring of STRING, giving start and end positions
    both in characters and in bytes.  */
 
@@ -1254,8 +1363,8 @@ substring_both (string, from, from_byte, to, to_byte)
 
   if (STRINGP (string))
     {
 
   if (STRINGP (string))
     {
-      size = XSTRING (string)->size;
-      size_byte = STRING_BYTES (XSTRING (string));
+      size = SCHARS (string);
+      size_byte = SBYTES (string);
     }
   else
     size = XVECTOR (string)->size;
     }
   else
     size = XVECTOR (string)->size;
@@ -1265,7 +1374,7 @@ substring_both (string, from, from_byte, to, to_byte)
 
   if (STRINGP (string))
     {
 
   if (STRINGP (string))
     {
-      res = make_specified_string (XSTRING (string)->data + from_byte,
+      res = make_specified_string (SDATA (string) + from_byte,
                                   to - from, to_byte - from_byte,
                                   STRING_MULTIBYTE (string));
       copy_text_properties (make_number (from), make_number (to),
                                   to - from, to_byte - from_byte,
                                   STRING_MULTIBYTE (string));
       copy_text_properties (make_number (from), make_number (to),
@@ -1633,18 +1742,18 @@ to be sure of changing the value of `foo'.  */)
       int c;
 
       for (i = nchars = nbytes = ibyte = 0;
       int c;
 
       for (i = nchars = nbytes = ibyte = 0;
-          i < XSTRING (seq)->size;
+          i < SCHARS (seq);
           ++i, ibyte += cbytes)
        {
          if (STRING_MULTIBYTE (seq))
            {
           ++i, ibyte += cbytes)
        {
          if (STRING_MULTIBYTE (seq))
            {
-             c = STRING_CHAR (&XSTRING (seq)->data[ibyte],
-                              STRING_BYTES (XSTRING (seq)) - ibyte);
+             c = STRING_CHAR (SDATA (seq) + ibyte,
+                              SBYTES (seq) - ibyte);
              cbytes = CHAR_BYTES (c);
            }
          else
            {
              cbytes = CHAR_BYTES (c);
            }
          else
            {
-             c = XSTRING (seq)->data[i];
+             c = SREF (seq, i);
              cbytes = 1;
            }
 
              cbytes = 1;
            }
 
@@ -1655,34 +1764,34 @@ to be sure of changing the value of `foo'.  */)
            }
        }
 
            }
        }
 
-      if (nchars != XSTRING (seq)->size)
+      if (nchars != SCHARS (seq))
        {
          Lisp_Object tem;
 
          tem = make_uninit_multibyte_string (nchars, nbytes);
          if (!STRING_MULTIBYTE (seq))
        {
          Lisp_Object tem;
 
          tem = make_uninit_multibyte_string (nchars, nbytes);
          if (!STRING_MULTIBYTE (seq))
-           SET_STRING_BYTES (XSTRING (tem), -1);
+           STRING_SET_UNIBYTE (tem);
 
          for (i = nchars = nbytes = ibyte = 0;
 
          for (i = nchars = nbytes = ibyte = 0;
-              i < XSTRING (seq)->size;
+              i < SCHARS (seq);
               ++i, ibyte += cbytes)
            {
              if (STRING_MULTIBYTE (seq))
                {
               ++i, ibyte += cbytes)
            {
              if (STRING_MULTIBYTE (seq))
                {
-                 c = STRING_CHAR (&XSTRING (seq)->data[ibyte],
-                                  STRING_BYTES (XSTRING (seq)) - ibyte);
+                 c = STRING_CHAR (SDATA (seq) + ibyte,
+                                  SBYTES (seq) - ibyte);
                  cbytes = CHAR_BYTES (c);
                }
              else
                {
                  cbytes = CHAR_BYTES (c);
                }
              else
                {
-                 c = XSTRING (seq)->data[i];
+                 c = SREF (seq, i);
                  cbytes = 1;
                }
 
              if (!INTEGERP (elt) || c != XINT (elt))
                {
                  cbytes = 1;
                }
 
              if (!INTEGERP (elt) || c != XINT (elt))
                {
-                 unsigned char *from = &XSTRING (seq)->data[ibyte];
-                 unsigned char *to   = &XSTRING (tem)->data[nbytes];
+                 unsigned char *from = SDATA (seq) + ibyte;
+                 unsigned char *to   = SDATA (tem) + nbytes;
                  EMACS_INT n;
 
                  ++nchars;
                  EMACS_INT n;
 
                  ++nchars;
@@ -1746,7 +1855,7 @@ Returns the beginning of the reversed list.  */)
 }
 
 DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
 }
 
 DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
-    doc: /* Reverse LIST, copying.  Returns the beginning of the reversed list.
+       doc: /* Reverse LIST, copying.  Returns the beginning of the reversed list.
 See also the function `nreverse', which is used more often.  */)
      (list)
      Lisp_Object list;
 See also the function `nreverse', which is used more often.  */)
      (list)
      Lisp_Object list;
@@ -1754,7 +1863,10 @@ See also the function `nreverse', which is used more often.  */)
   Lisp_Object new;
 
   for (new = Qnil; CONSP (list); list = XCDR (list))
   Lisp_Object new;
 
   for (new = Qnil; CONSP (list); list = XCDR (list))
-    new = Fcons (XCAR (list), new);
+    {
+      QUIT;
+      new = Fcons (XCAR (list), new);
+    }
   if (!NILP (list))
     wrong_type_argument (Qconsp, list);
   return new;
   if (!NILP (list))
     wrong_type_argument (Qconsp, list);
   return new;
@@ -1865,7 +1977,7 @@ one of the properties on the list.  */)
      Lisp_Object prop;
 {
   Lisp_Object tail;
      Lisp_Object prop;
 {
   Lisp_Object tail;
-  
+
   for (tail = plist;
        CONSP (tail) && CONSP (XCDR (tail));
        tail = XCDR (XCDR (tail)))
   for (tail = plist;
        CONSP (tail) && CONSP (XCDR (tail));
        tail = XCDR (XCDR (tail)))
@@ -1881,7 +1993,7 @@ one of the properties on the list.  */)
 
   if (!NILP (tail))
     wrong_type_argument (Qlistp, prop);
 
   if (!NILP (tail))
     wrong_type_argument (Qlistp, prop);
-  
+
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -1919,7 +2031,7 @@ The PLIST is modified by side effects.  */)
          Fsetcar (XCDR (tail), val);
          return plist;
        }
          Fsetcar (XCDR (tail), val);
          return plist;
        }
-      
+
       prev = tail;
       QUIT;
     }
       prev = tail;
       QUIT;
     }
@@ -1942,7 +2054,71 @@ It can be retrieved with `(get SYMBOL PROPNAME)'.  */)
     = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
   return value;
 }
     = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
   return value;
 }
+\f
+DEFUN ("lax-plist-get", Flax_plist_get, Slax_plist_get, 2, 2, 0,
+       doc: /* Extract a value from a property list, comparing with `equal'.
+PLIST is a property list, which is a list of the form
+\(PROP1 VALUE1 PROP2 VALUE2...).  This function returns the value
+corresponding to the given PROP, or nil if PROP is not
+one of the properties on the list.  */)
+     (plist, prop)
+     Lisp_Object plist;
+     Lisp_Object prop;
+{
+  Lisp_Object tail;
 
 
+  for (tail = plist;
+       CONSP (tail) && CONSP (XCDR (tail));
+       tail = XCDR (XCDR (tail)))
+    {
+      if (! NILP (Fequal (prop, XCAR (tail))))
+       return XCAR (XCDR (tail));
+
+      QUIT;
+    }
+
+  if (!NILP (tail))
+    wrong_type_argument (Qlistp, prop);
+
+  return Qnil;
+}
+
+DEFUN ("lax-plist-put", Flax_plist_put, Slax_plist_put, 3, 3, 0,
+       doc: /* Change value in PLIST of PROP to VAL, comparing with `equal'.
+PLIST is a property list, which is a list of the form
+\(PROP1 VALUE1 PROP2 VALUE2 ...).  PROP and VAL are any objects.
+If PROP is already a property on the list, its value is set to VAL,
+otherwise the new PROP VAL pair is added.  The new plist is returned;
+use `(setq x (lax-plist-put x prop val))' to be sure to use the new value.
+The PLIST is modified by side effects.  */)
+     (plist, prop, val)
+     Lisp_Object plist;
+     register Lisp_Object prop;
+     Lisp_Object val;
+{
+  register Lisp_Object tail, prev;
+  Lisp_Object newcell;
+  prev = Qnil;
+  for (tail = plist; CONSP (tail) && CONSP (XCDR (tail));
+       tail = XCDR (XCDR (tail)))
+    {
+      if (! NILP (Fequal (prop, XCAR (tail))))
+       {
+         Fsetcar (XCDR (tail), val);
+         return plist;
+       }
+
+      prev = tail;
+      QUIT;
+    }
+  newcell = Fcons (prop, Fcons (val, Qnil));
+  if (NILP (prev))
+    return newcell;
+  else
+    Fsetcdr (XCDR (prev), newcell);
+  return plist;
+}
+\f
 DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
        doc: /* Return t if two Lisp objects have similar structure and contents.
 They must have the same data type.
 DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
        doc: /* Return t if two Lisp objects have similar structure and contents.
 They must have the same data type.
@@ -2052,12 +2228,12 @@ internal_equal (o1, o2, depth)
       break;
 
     case Lisp_String:
       break;
 
     case Lisp_String:
-      if (XSTRING (o1)->size != XSTRING (o2)->size)
+      if (SCHARS (o1) != SCHARS (o2))
        return 0;
        return 0;
-      if (STRING_BYTES (XSTRING (o1)) != STRING_BYTES (XSTRING (o2)))
+      if (SBYTES (o1) != SBYTES (o2))
        return 0;
        return 0;
-      if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data,
-               STRING_BYTES (XSTRING (o1))))
+      if (bcmp (SDATA (o1), SDATA (o2),
+               SBYTES (o1)))
        return 0;
       return 1;
 
        return 0;
       return 1;
 
@@ -2066,7 +2242,7 @@ internal_equal (o1, o2, depth)
     case Lisp_Type_Limit:
       break;
     }
     case Lisp_Type_Limit:
       break;
     }
-  
+
   return 0;
 }
 \f
   return 0;
 }
 \f
@@ -2097,15 +2273,15 @@ ARRAY is a vector, string, char-table, or bool-vector.  */)
     }
   else if (STRINGP (array))
     {
     }
   else if (STRINGP (array))
     {
-      register unsigned char *p = XSTRING (array)->data;
+      register unsigned char *p = SDATA (array);
       CHECK_NUMBER (item);
       charval = XINT (item);
       CHECK_NUMBER (item);
       charval = XINT (item);
-      size = XSTRING (array)->size;
+      size = SCHARS (array);
       if (STRING_MULTIBYTE (array))
        {
          unsigned char str[MAX_MULTIBYTE_LENGTH];
          int len = CHAR_STRING (charval, str);
       if (STRING_MULTIBYTE (array))
        {
          unsigned char str[MAX_MULTIBYTE_LENGTH];
          int len = CHAR_STRING (charval, str);
-         int size_byte = STRING_BYTES (XSTRING (array));
+         int size_byte = SBYTES (array);
          unsigned char *p1 = p, *endp = p + size_byte;
          int i;
 
          unsigned char *p1 = p, *endp = p + size_byte;
          int i;
 
@@ -2522,6 +2698,14 @@ map_char_table (c_function, function, subtable, arg, depth, indices)
     }
 }
 
     }
 }
 
+static void void_call2 P_ ((Lisp_Object a, Lisp_Object b, Lisp_Object c));
+static void
+void_call2 (a, b, c)
+     Lisp_Object a, b, c;
+{
+  call2 (a, b, c);
+}
+
 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
        2, 2, 0,
        doc: /* Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.
 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
        2, 2, 0,
        doc: /* Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.
@@ -2535,7 +2719,11 @@ The key is always a possible IDX argument to `aref'.  */)
 
   CHECK_CHAR_TABLE (char_table);
 
 
   CHECK_CHAR_TABLE (char_table);
 
-  map_char_table (NULL, function, char_table, char_table, 0, indices);
+  /* When Lisp_Object is represented as a union, `call2' cannot directly
+     be passed to map_char_table because it returns a Lisp_Object rather
+     than returning nothing.
+     Casting leads to crashes on some architectures.  -stef  */
+  map_char_table (void_call2, Qnil, char_table, function, 0, indices);
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -2618,7 +2806,7 @@ usage: (nconc &rest LISTS)  */)
       while (CONSP (tem))
        {
          tail = tem;
       while (CONSP (tem))
        {
          tail = tem;
-         tem = Fcdr (tail);
+         tem = XCDR (tail);
          QUIT;
        }
 
          QUIT;
        }
 
@@ -2811,7 +2999,7 @@ is nil and `use-dialog-box' is non-nil.  */)
   Lisp_Object xprompt;
   Lisp_Object args[2];
   struct gcpro gcpro1, gcpro2;
   Lisp_Object xprompt;
   Lisp_Object args[2];
   struct gcpro gcpro1, gcpro2;
-  int count = specpdl_ptr - specpdl;
+  int count = SPECPDL_INDEX ();
 
   specbind (Qcursor_in_echo_area, Qt);
 
 
   specbind (Qcursor_in_echo_area, Qt);
 
@@ -2847,7 +3035,18 @@ is nil and `use-dialog-box' is non-nil.  */)
 #endif /* HAVE_MENUS */
       cursor_in_echo_area = 1;
       choose_minibuf_frame ();
 #endif /* HAVE_MENUS */
       cursor_in_echo_area = 1;
       choose_minibuf_frame ();
-      message_with_string ("%s(y or n) ", xprompt, 0);
+
+      {
+       Lisp_Object pargs[3];
+
+       /* Colorize prompt according to `minibuffer-prompt' face.  */
+       pargs[0] = build_string ("%s(y or n) ");
+       pargs[1] = intern ("face");
+       pargs[2] = intern ("minibuffer-prompt");
+       args[0] = Fpropertize (3, pargs);
+       args[1] = xprompt;
+       Fmessage (2, args);
+      }
 
       if (minibuffer_auto_raise)
        {
 
       if (minibuffer_auto_raise)
        {
@@ -2978,12 +3177,12 @@ is nil, and `use-dialog-box' is non-nil.  */)
       ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
                                              Qyes_or_no_p_history, Qnil,
                                              Qnil));
       ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
                                              Qyes_or_no_p_history, Qnil,
                                              Qnil));
-      if (XSTRING (ans)->size == 3 && !strcmp (XSTRING (ans)->data, "yes"))
+      if (SCHARS (ans) == 3 && !strcmp (SDATA (ans), "yes"))
        {
          UNGCPRO;
          return Qt;
        }
        {
          UNGCPRO;
          return Qt;
        }
-      if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
+      if (SCHARS (ans) == 2 && !strcmp (SDATA (ans), "no"))
        {
          UNGCPRO;
          return Qnil;
        {
          UNGCPRO;
          return Qnil;
@@ -2998,7 +3197,7 @@ is nil, and `use-dialog-box' is non-nil.  */)
 \f
 DEFUN ("load-average", Fload_average, Sload_average, 0, 1, 0,
        doc: /* Return list of 1 minute, 5 minute and 15 minute load averages.
 \f
 DEFUN ("load-average", Fload_average, Sload_average, 0, 1, 0,
        doc: /* Return list of 1 minute, 5 minute and 15 minute load averages.
-     
+
 Each of the three load averages is multiplied by 100, then converted
 to integer.
 
 Each of the three load averages is multiplied by 100, then converted
 to integer.
 
@@ -3033,7 +3232,7 @@ extern Lisp_Object Vafter_load_alist;
 
 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 2, 0,
        doc: /* Returns t if FEATURE is present in this Emacs.
 
 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 2, 0,
        doc: /* Returns t if FEATURE is present in this Emacs.
-     
+
 Use this to conditionalize execution of lisp code based on the
 presence or absence of emacs or environment extensions.
 Use `provide' to declare that a feature is available.  This function
 Use this to conditionalize execution of lisp code based on the
 presence or absence of emacs or environment extensions.
 Use `provide' to declare that a feature is available.  This function
@@ -3046,7 +3245,7 @@ SUBFEATURE can be used to check a specific subfeature of FEATURE.  */)
   CHECK_SYMBOL (feature);
   tem = Fmemq (feature, Vfeatures);
   if (!NILP (tem) && !NILP (subfeature))
   CHECK_SYMBOL (feature);
   tem = Fmemq (feature, Vfeatures);
   if (!NILP (tem) && !NILP (subfeature))
-    tem = Fmemq (subfeature, Fget (feature, Qsubfeatures));
+    tem = Fmember (subfeature, Fget (feature, Qsubfeatures));
   return (NILP (tem)) ? Qnil : Qt;
 }
 
   return (NILP (tem)) ? Qnil : Qt;
 }
 
@@ -3059,6 +3258,7 @@ particular subfeatures supported in this version of FEATURE.  */)
 {
   register Lisp_Object tem;
   CHECK_SYMBOL (feature);
 {
   register Lisp_Object tem;
   CHECK_SYMBOL (feature);
+  CHECK_LIST (subfeatures);
   if (!NILP (Vautoload_queue))
     Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
   tem = Fmemq (feature, Vfeatures);
   if (!NILP (Vautoload_queue))
     Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
   tem = Fmemq (feature, Vfeatures);
@@ -3070,8 +3270,8 @@ particular subfeatures supported in this version of FEATURE.  */)
 
   /* Run any load-hooks for this file.  */
   tem = Fassq (feature, Vafter_load_alist);
 
   /* Run any load-hooks for this file.  */
   tem = Fassq (feature, Vafter_load_alist);
-  if (!NILP (tem))
-    Fprogn (Fcdr (tem));
+  if (CONSP (tem))
+    Fprogn (XCDR (tem));
 
   return feature;
 }
 
   return feature;
 }
@@ -3110,13 +3310,19 @@ The normal messages at start and end of loading FILENAME are suppressed.  */)
 
   tem = Fmemq (feature, Vfeatures);
 
 
   tem = Fmemq (feature, Vfeatures);
 
-  LOADHIST_ATTACH (Fcons (Qrequire, feature));
-  
   if (NILP (tem))
     {
   if (NILP (tem))
     {
-      int count = specpdl_ptr - specpdl;
+      int count = SPECPDL_INDEX ();
       int nesting = 0;
       int nesting = 0;
-      
+
+      LOADHIST_ATTACH (Fcons (Qrequire, feature));
+
+      /* This is to make sure that loadup.el gives a clear picture
+        of what files are preloaded and when.  */
+      if (! NILP (Vpurify_flag))
+       error ("(require %s) while preparing to dump",
+              SDATA (SYMBOL_NAME (feature)));
+
       /* A certain amount of recursive `require' is legitimate,
         but if we require the same feature recursively 3 times,
         signal an error.  */
       /* A certain amount of recursive `require' is legitimate,
         but if we require the same feature recursively 3 times,
         signal an error.  */
@@ -3127,9 +3333,9 @@ The normal messages at start and end of loading FILENAME are suppressed.  */)
            nesting++;
          tem = XCDR (tem);
        }
            nesting++;
          tem = XCDR (tem);
        }
-      if (nesting > 2)
+      if (nesting > 3)
        error ("Recursive `require' for feature `%s'",
        error ("Recursive `require' for feature `%s'",
-              XSYMBOL (feature)->name->data);
+              SDATA (SYMBOL_NAME (feature)));
 
       /* Update the list for any nested `require's that occur.  */
       record_unwind_protect (require_unwind, require_nesting_list);
 
       /* Update the list for any nested `require's that occur.  */
       record_unwind_protect (require_unwind, require_nesting_list);
@@ -3152,7 +3358,7 @@ The normal messages at start and end of loading FILENAME are suppressed.  */)
       tem = Fmemq (feature, Vfeatures);
       if (NILP (tem))
        error ("Required feature `%s' was not provided",
       tem = Fmemq (feature, Vfeatures);
       if (NILP (tem))
        error ("Required feature `%s' was not provided",
-              XSYMBOL (feature)->name->data);
+              SDATA (SYMBOL_NAME (feature)));
 
       /* Once loading finishes, don't undo it.  */
       Vautoload_queue = Qt;
 
       /* Once loading finishes, don't undo it.  */
       Vautoload_queue = Qt;
@@ -3247,6 +3453,90 @@ usage: (widget-apply WIDGET PROPERTY &rest ARGS)  */)
   UNGCPRO;
   return result;
 }
   UNGCPRO;
   return result;
 }
+
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
+DEFUN ("langinfo", Flanginfo, Slanginfo, 1, 1, 0,
+       doc: /* Access locale data ITEM, if available.
+
+ITEM may be one of the following:
+`codeset', returning the character set as a string (locale item CODESET);
+`days', returning a 7-element vector of day names (locale items DAY_n);
+`months', returning a 12-element vector of month names (locale items MON_n);
+`paper', returning a list (WIDTH, HEIGHT) for the default paper size,
+  where the width and height are in mm (locale items PAPER_WIDTH,
+  PAPER_HEIGHT).
+
+If the system can't provide such information through a call to
+nl_langinfo(3), return nil.
+
+See also Info node `(libc)Locales'.
+
+The data read from the system are decoded using `locale-coding-system'.  */)
+     (item)
+     Lisp_Object item;
+{
+  char *str = NULL;
+#ifdef HAVE_LANGINFO_CODESET
+  Lisp_Object val;
+  if (EQ (item, Qcodeset))
+    {
+      str = nl_langinfo (CODESET);
+      return build_string (str);
+    }
+#ifdef DAY_1
+  else if (EQ (item, Qdays))   /* e.g. for calendar-day-name-array */
+    {
+      Lisp_Object v = Fmake_vector (make_number (7), Qnil);
+      int days[7] = {DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7};
+      int i;
+      synchronize_system_time_locale ();
+      for (i = 0; i < 7; i++)
+       {
+         str = nl_langinfo (days[i]);
+         val = make_unibyte_string (str, strlen (str));
+         /* Fixme: Is this coding system necessarily right, even if
+            it is consistent with CODESET?  If not, what to do?  */
+         Faset (v, make_number (i),
+                code_convert_string_norecord (val, Vlocale_coding_system,
+                                              0));
+       }
+      return v;
+    }
+#endif /* DAY_1 */
+#ifdef MON_1
+  else if (EQ (item, Qmonths)) /* e.g. for calendar-month-name-array */
+    {
+      struct Lisp_Vector *p = allocate_vector (12);
+      int months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7,
+                       MON_8, MON_9, MON_10, MON_11, MON_12};
+      int i;
+      synchronize_system_time_locale ();
+      for (i = 0; i < 12; i++)
+       {
+         str = nl_langinfo (months[i]);
+         val = make_unibyte_string (str, strlen (str));
+         p->contents[i] =
+           code_convert_string_norecord (val, Vlocale_coding_system, 0);
+       }
+      XSETVECTOR (val, p);
+      return val;
+    }
+#endif /* MON_1 */
+/* LC_PAPER stuff isn't defined as accessible in glibc as of 2.3.1,
+   but is in the locale files.  This could be used by ps-print.  */
+#ifdef PAPER_WIDTH
+  else if (EQ (item, Qpaper))
+    {
+      return list2 (make_number (nl_langinfo (PAPER_WIDTH)),
+                   make_number (nl_langinfo (PAPER_HEIGHT)));
+    }
+#endif /* PAPER_WIDTH */
+#endif /* HAVE_LANGINFO_CODESET*/
+    return Qnil;
+}
 \f
 /* base64 encode/decode functions (RFC 2045).
    Based on code from GNU recode. */
 \f
 /* base64 encode/decode functions (RFC 2045).
    Based on code from GNU recode. */
@@ -3415,7 +3705,7 @@ into shorter lines.  */)
   /* We need to allocate enough room for encoding the text.
      We need 33 1/3% more space, plus a newline every 76
      characters, and then we round up. */
   /* We need to allocate enough room for encoding the text.
      We need 33 1/3% more space, plus a newline every 76
      characters, and then we round up. */
-  length = STRING_BYTES (XSTRING (string));
+  length = SBYTES (string);
   allength = length + length/3 + 1;
   allength += allength / MIME_LINE_LENGTH + 1 + 6;
 
   allength = length + length/3 + 1;
   allength += allength / MIME_LINE_LENGTH + 1 + 6;
 
@@ -3425,7 +3715,7 @@ into shorter lines.  */)
   else
     encoded = (char *) xmalloc (allength);
 
   else
     encoded = (char *) xmalloc (allength);
 
-  encoded_length = base64_encode_1 (XSTRING (string)->data,
+  encoded_length = base64_encode_1 (SDATA (string),
                                    encoded, length, NILP (no_line_break),
                                    STRING_MULTIBYTE (string));
   if (encoded_length > allength)
                                    encoded, length, NILP (no_line_break),
                                    STRING_MULTIBYTE (string));
   if (encoded_length > allength)
@@ -3618,7 +3908,7 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
 
   CHECK_STRING (string);
 
 
   CHECK_STRING (string);
 
-  length = STRING_BYTES (XSTRING (string));
+  length = SBYTES (string);
   /* We need to allocate enough room for decoding the text. */
   if (length <= MAX_ALLOCA)
     decoded = (char *) alloca (length);
   /* We need to allocate enough room for decoding the text. */
   if (length <= MAX_ALLOCA)
     decoded = (char *) alloca (length);
@@ -3626,7 +3916,7 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
     decoded = (char *) xmalloc (length);
 
   /* The decoded result should be unibyte. */
     decoded = (char *) xmalloc (length);
 
   /* The decoded result should be unibyte. */
-  decoded_length = base64_decode_1 (XSTRING (string)->data, decoded, length,
+  decoded_length = base64_decode_1 (SDATA (string), decoded, length,
                                    0, NULL);
   if (decoded_length > length)
     abort ();
                                    0, NULL);
   if (decoded_length > length)
     abort ();
@@ -3754,32 +4044,6 @@ base64_decode_1 (from, to, length, multibyte, nchars_return)
    if a `:linear-search t' argument is given to make-hash-table.  */
 
 
    if a `:linear-search t' argument is given to make-hash-table.  */
 
 
-/* Value is the key part of entry IDX in hash table H.  */
-
-#define HASH_KEY(H, IDX)   AREF ((H)->key_and_value, 2 * (IDX))
-
-/* Value is the value part of entry IDX in hash table H.  */
-
-#define HASH_VALUE(H, IDX) AREF ((H)->key_and_value, 2 * (IDX) + 1)
-
-/* Value is the index of the next entry following the one at IDX
-   in hash table H.  */
-
-#define HASH_NEXT(H, IDX)  AREF ((H)->next, (IDX))
-
-/* Value is the hash code computed for entry IDX in hash table H.  */
-
-#define HASH_HASH(H, IDX)  AREF ((H)->hash, (IDX))
-
-/* Value is the index of the element in hash table H that is the
-   start of the collision list at index IDX in the index vector of H.  */
-
-#define HASH_INDEX(H, IDX)  AREF ((H)->index, (IDX))
-
-/* Value is the size of hash table H.  */
-
-#define HASH_TABLE_SIZE(H) XVECTOR ((H)->next)->size
-
 /* The list of all weak hash tables.  Don't staticpro this one.  */
 
 Lisp_Object Vweak_hash_tables;
 /* The list of all weak hash tables.  Don't staticpro this one.  */
 
 Lisp_Object Vweak_hash_tables;
@@ -4510,7 +4774,7 @@ sweep_weak_hash_tables ()
     {
       h = XHASH_TABLE (table);
       next = h->next_weak;
     {
       h = XHASH_TABLE (table);
       next = h->next_weak;
-      
+
       if (h->size & ARRAY_MARK_FLAG)
        {
          /* TABLE is marked as used.  Sweep its contents.  */
       if (h->size & ARRAY_MARK_FLAG)
        {
          /* TABLE is marked as used.  Sweep its contents.  */
@@ -4656,8 +4920,8 @@ sxhash (obj, depth)
       break;
 
     case Lisp_Symbol:
       break;
 
     case Lisp_Symbol:
-      hash = sxhash_string (XSYMBOL (obj)->name->data,
-                           XSYMBOL (obj)->name->size);
+      hash = sxhash_string (SDATA (SYMBOL_NAME (obj)),
+                           SCHARS (SYMBOL_NAME (obj)));
       break;
 
     case Lisp_Misc:
       break;
 
     case Lisp_Misc:
@@ -4665,7 +4929,7 @@ sxhash (obj, depth)
       break;
 
     case Lisp_String:
       break;
 
     case Lisp_String:
-      hash = sxhash_string (XSTRING (obj)->data, XSTRING (obj)->size);
+      hash = sxhash_string (SDATA (obj), SCHARS (obj));
       break;
 
       /* This can be everything from a vector to an overlay.  */
       break;
 
       /* This can be everything from a vector to an overlay.  */
@@ -4723,7 +4987,7 @@ DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0,
 
 DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
        doc: /* Create and return a new hash table.
 
 DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
        doc: /* Create and return a new hash table.
-         
+
 Arguments are specified as keyword/argument pairs.  The following
 arguments are defined:
 
 Arguments are specified as keyword/argument pairs.  The following
 arguments are defined:
 
@@ -4787,8 +5051,10 @@ usage: (make-hash-table &rest KEYWORD-ARGS)  */)
 
   /* See if there's a `:size SIZE' argument.  */
   i = get_key_arg (QCsize, nargs, args, used);
 
   /* See if there's a `:size SIZE' argument.  */
   i = get_key_arg (QCsize, nargs, args, used);
-  size = i < 0 ? make_number (DEFAULT_HASH_SIZE) : args[i];
-  if (!INTEGERP (size) || XINT (size) < 0)
+  size = i < 0 ? Qnil : args[i];
+  if (NILP (size))
+    size = make_number (DEFAULT_HASH_SIZE);
+  else if (!INTEGERP (size) || XINT (size) < 0)
     Fsignal (Qerror,
             list2 (build_string ("Invalid hash table size"),
                    size));
     Fsignal (Qerror,
             list2 (build_string ("Invalid hash table size"),
                    size));
@@ -4846,22 +5112,6 @@ DEFUN ("copy-hash-table", Fcopy_hash_table, Scopy_hash_table, 1, 1, 0,
 }
 
 
 }
 
 
-DEFUN ("makehash", Fmakehash, Smakehash, 0, 1, 0,
-       doc: /* Create a new hash table.
-         
-Optional first argument TEST specifies how to compare keys in the
-table.  Predefined tests are `eq', `eql', and `equal'.  Default is
-`eql'.  New tests can be defined with `define-hash-table-test'.  */)
-     (test)
-     Lisp_Object test;
-{
-  Lisp_Object args[2];
-  args[0] = QCtest;
-  args[1] = NILP (test) ? Qeql : test;
-  return Fmake_hash_table (2, args);
-}
-
-
 DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0,
        doc: /* Return the number of elements in TABLE.  */)
      (table)
 DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0,
        doc: /* Return the number of elements in TABLE.  */)
      (table)
@@ -5012,7 +5262,7 @@ FUNCTION is called with 2 arguments KEY and VALUE.  */)
 DEFUN ("define-hash-table-test", Fdefine_hash_table_test,
        Sdefine_hash_table_test, 3, 3, 0,
        doc: /* Define a new hash table test with name NAME, a symbol.
 DEFUN ("define-hash-table-test", Fdefine_hash_table_test,
        Sdefine_hash_table_test, 3, 3, 0,
        doc: /* Define a new hash table test with name NAME, a symbol.
-         
+
 In hash tables created with NAME specified as test, use TEST to
 compare keys, and HASH for computing hash codes of keys.
 
 In hash tables created with NAME specified as test, use TEST to
 compare keys, and HASH for computing hash codes of keys.
 
@@ -5038,7 +5288,7 @@ including negative integers.  */)
 
 DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
        doc: /* Return MD5 message digest of OBJECT, a buffer or string.
 
 DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
        doc: /* Return MD5 message digest of OBJECT, a buffer or string.
-         
+
 A message digest is a cryptographic checksum of a document, and the
 algorithm to calculate it is defined in RFC 1321.
 
 A message digest is a cryptographic checksum of a document, and the
 algorithm to calculate it is defined in RFC 1321.
 
@@ -5086,14 +5336,14 @@ guesswork fails.  Normally, an error is signaled in such case.  */)
          if (STRING_MULTIBYTE (object))
            /* use default, we can't guess correct value */
            coding_system = SYMBOL_VALUE (XCAR (Vcoding_category_list));
          if (STRING_MULTIBYTE (object))
            /* use default, we can't guess correct value */
            coding_system = SYMBOL_VALUE (XCAR (Vcoding_category_list));
-         else 
+         else
            coding_system = Qraw_text;
        }
            coding_system = Qraw_text;
        }
-      
+
       if (NILP (Fcoding_system_p (coding_system)))
        {
          /* Invalid coding system.  */
       if (NILP (Fcoding_system_p (coding_system)))
        {
          /* Invalid coding system.  */
-         
+
          if (!NILP (noerror))
            coding_system = Qraw_text;
          else
          if (!NILP (noerror))
            coding_system = Qraw_text;
          else
@@ -5104,8 +5354,8 @@ guesswork fails.  Normally, an error is signaled in such case.  */)
       if (STRING_MULTIBYTE (object))
        object = code_convert_string1 (object, coding_system, Qnil, 1);
 
       if (STRING_MULTIBYTE (object))
        object = code_convert_string1 (object, coding_system, Qnil, 1);
 
-      size = XSTRING (object)->size;
-      size_byte = STRING_BYTES (XSTRING (object));
+      size = SCHARS (object);
+      size_byte = SBYTES (object);
 
       if (!NILP (start))
        {
 
       if (!NILP (start))
        {
@@ -5127,15 +5377,15 @@ guesswork fails.  Normally, an error is signaled in such case.  */)
       else
        {
          CHECK_NUMBER (end);
       else
        {
          CHECK_NUMBER (end);
-         
+
          end_char = XINT (end);
 
          if (end_char < 0)
            end_char += size;
          end_char = XINT (end);
 
          if (end_char < 0)
            end_char += size;
-         
+
          end_byte = string_char_to_byte (object, end_char);
        }
          end_byte = string_char_to_byte (object, end_char);
        }
-      
+
       if (!(0 <= start_char && start_char <= end_char && end_char <= size))
        args_out_of_range_3 (object, make_number (start_char),
                             make_number (end_char));
       if (!(0 <= start_char && start_char <= end_char && end_char <= size))
        args_out_of_range_3 (object, make_number (start_char),
                             make_number (end_char));
@@ -5145,7 +5395,7 @@ guesswork fails.  Normally, an error is signaled in such case.  */)
       CHECK_BUFFER (object);
 
       bp = XBUFFER (object);
       CHECK_BUFFER (object);
 
       bp = XBUFFER (object);
-         
+
       if (NILP (start))
        b = BUF_BEGV (bp);
       else
       if (NILP (start))
        b = BUF_BEGV (bp);
       else
@@ -5161,16 +5411,16 @@ guesswork fails.  Normally, an error is signaled in such case.  */)
          CHECK_NUMBER_COERCE_MARKER (end);
          e = XINT (end);
        }
          CHECK_NUMBER_COERCE_MARKER (end);
          e = XINT (end);
        }
-      
+
       if (b > e)
        temp = b, b = e, e = temp;
       if (b > e)
        temp = b, b = e, e = temp;
-      
+
       if (!(BUF_BEGV (bp) <= b && e <= BUF_ZV (bp)))
        args_out_of_range (start, end);
       if (!(BUF_BEGV (bp) <= b && e <= BUF_ZV (bp)))
        args_out_of_range (start, end);
-      
+
       if (NILP (coding_system))
        {
       if (NILP (coding_system))
        {
-         /* Decide the coding-system to encode the data with. 
+         /* Decide the coding-system to encode the data with.
             See fileio.c:Fwrite-region */
 
          if (!NILP (Vcoding_system_for_write))
             See fileio.c:Fwrite-region */
 
          if (!NILP (Vcoding_system_for_write))
@@ -5192,7 +5442,7 @@ guesswork fails.  Normally, an error is signaled in such case.  */)
                {
                  /* Check file-coding-system-alist.  */
                  Lisp_Object args[4], val;
                {
                  /* Check file-coding-system-alist.  */
                  Lisp_Object args[4], val;
-                 
+
                  args[0] = Qwrite_region; args[1] = start; args[2] = end;
                  args[3] = Fbuffer_file_name(object);
                  val = Ffind_operation_coding_system (4, args);
                  args[0] = Qwrite_region; args[1] = start; args[2] = end;
                  args[3] = Fbuffer_file_name(object);
                  val = Ffind_operation_coding_system (4, args);
@@ -5211,9 +5461,9 @@ guesswork fails.  Normally, an error is signaled in such case.  */)
              if (!force_raw_text
                  && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
                /* Confirm that VAL can surely encode the current region.  */
              if (!force_raw_text
                  && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
                /* Confirm that VAL can surely encode the current region.  */
-               coding_system = call3 (Vselect_safe_coding_system_function,
+               coding_system = call4 (Vselect_safe_coding_system_function,
                                       make_number (b), make_number (e),
                                       make_number (b), make_number (e),
-                                      coding_system);
+                                      coding_system, Qnil);
 
              if (force_raw_text)
                coding_system = Qraw_text;
 
              if (force_raw_text)
                coding_system = Qraw_text;
@@ -5237,8 +5487,8 @@ guesswork fails.  Normally, an error is signaled in such case.  */)
        object = code_convert_string1 (object, coding_system, Qnil, 1);
     }
 
        object = code_convert_string1 (object, coding_system, Qnil, 1);
     }
 
-  md5_buffer (XSTRING (object)->data + start_byte, 
-             STRING_BYTES(XSTRING (object)) - (size_byte - end_byte), 
+  md5_buffer (SDATA (object) + start_byte,
+             SBYTES (object) - (size_byte - end_byte),
              digest);
 
   for (i = 0; i < 16; i++)
              digest);
 
   for (i = 0; i < 16; i++)
@@ -5285,7 +5535,6 @@ syms_of_fns ()
   defsubr (&Ssxhash);
   defsubr (&Smake_hash_table);
   defsubr (&Scopy_hash_table);
   defsubr (&Ssxhash);
   defsubr (&Smake_hash_table);
   defsubr (&Scopy_hash_table);
-  defsubr (&Smakehash);
   defsubr (&Shash_table_count);
   defsubr (&Shash_table_rehash_size);
   defsubr (&Shash_table_rehash_threshold);
   defsubr (&Shash_table_count);
   defsubr (&Shash_table_rehash_size);
   defsubr (&Shash_table_rehash_threshold);
@@ -5328,9 +5577,20 @@ Used by `featurep' and `require', and altered by `provide'.  */);
   Qsubfeatures = intern ("subfeatures");
   staticpro (&Qsubfeatures);
 
   Qsubfeatures = intern ("subfeatures");
   staticpro (&Qsubfeatures);
 
+#ifdef HAVE_LANGINFO_CODESET
+  Qcodeset = intern ("codeset");
+  staticpro (&Qcodeset);
+  Qdays = intern ("days");
+  staticpro (&Qdays);
+  Qmonths = intern ("months");
+  staticpro (&Qmonths);
+  Qpaper = intern ("paper");
+  staticpro (&Qpaper);
+#endif /* HAVE_LANGINFO_CODESET */
+
   DEFVAR_BOOL ("use-dialog-box", &use_dialog_box,
     doc: /* *Non-nil means mouse commands use dialog boxes to ask questions.
   DEFVAR_BOOL ("use-dialog-box", &use_dialog_box,
     doc: /* *Non-nil means mouse commands use dialog boxes to ask questions.
-This applies to y-or-n and yes-or-no questions asked by commands
+This applies to `y-or-n-p' and `yes-or-no-p' questions asked by commands
 invoked by mouse clicks and mouse menu items.  */);
   use_dialog_box = 1;
 
 invoked by mouse clicks and mouse menu items.  */);
   use_dialog_box = 1;
 
@@ -5350,8 +5610,10 @@ invoked by mouse clicks and mouse menu items.  */);
   defsubr (&Sstring_make_unibyte);
   defsubr (&Sstring_as_multibyte);
   defsubr (&Sstring_as_unibyte);
   defsubr (&Sstring_make_unibyte);
   defsubr (&Sstring_as_multibyte);
   defsubr (&Sstring_as_unibyte);
+  defsubr (&Sstring_to_multibyte);
   defsubr (&Scopy_alist);
   defsubr (&Ssubstring);
   defsubr (&Scopy_alist);
   defsubr (&Ssubstring);
+  defsubr (&Ssubstring_no_properties);
   defsubr (&Snthcdr);
   defsubr (&Snth);
   defsubr (&Selt);
   defsubr (&Snthcdr);
   defsubr (&Snth);
   defsubr (&Selt);
@@ -5370,6 +5632,8 @@ invoked by mouse clicks and mouse menu items.  */);
   defsubr (&Sget);
   defsubr (&Splist_put);
   defsubr (&Sput);
   defsubr (&Sget);
   defsubr (&Splist_put);
   defsubr (&Sput);
+  defsubr (&Slax_plist_get);
+  defsubr (&Slax_plist_put);
   defsubr (&Sequal);
   defsubr (&Sfillarray);
   defsubr (&Schar_table_subtype);
   defsubr (&Sequal);
   defsubr (&Sfillarray);
   defsubr (&Schar_table_subtype);
@@ -5401,6 +5665,7 @@ invoked by mouse clicks and mouse menu items.  */);
   defsubr (&Sbase64_encode_string);
   defsubr (&Sbase64_decode_string);
   defsubr (&Smd5);
   defsubr (&Sbase64_encode_string);
   defsubr (&Sbase64_decode_string);
   defsubr (&Smd5);
+  defsubr (&Slanginfo);
 }
 
 
 }