(fix_submap_inheritance, get_keyelt, store_in_keymap,
[bpt/emacs.git] / src / fns.c
index 421879f..34015c5 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -40,8 +40,6 @@ Boston, MA 02111-1307, USA.  */
 #define NULL (void *)0
 #endif
 
-#define DEFAULT_NONASCII_INSERT_OFFSET 0x800
-
 /* Nonzero enables use of dialog boxes for questions
    asked by mouse commands.  */
 int use_dialog_box;
@@ -125,7 +123,9 @@ To get the number of characters, use `chars-in-string'")
   else if (VECTORP (sequence))
     XSETFASTINT (val, XVECTOR (sequence)->size);
   else if (CHAR_TABLE_P (sequence))
-    XSETFASTINT (val, CHAR_TABLE_ORDINARY_SLOTS);
+    XSETFASTINT (val, (MIN_CHAR_COMPOSITION
+                      + (CHAR_FIELD2_MASK | CHAR_FIELD3_MASK)
+                      - 1));
   else if (BOOL_VECTOR_P (sequence))
     XSETFASTINT (val, XBOOL_VECTOR (sequence)->size);
   else if (COMPILEDP (sequence))
@@ -179,6 +179,16 @@ which is at least the number of distinct elements.")
   return length;
 }
 
+DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
+  "Return the number of bytes in STRING.\n\
+If STRING is a multibyte string, this is greater than the length of STRING.")
+  (string)
+     Lisp_Object string;
+{
+  CHECK_STRING (string, 1);
+  return make_number (XSTRING (string)->size_byte);
+}
+
 DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
   "Return t if two strings have identical contents.\n\
 Case is significant, but text properties are ignored.\n\
@@ -460,6 +470,8 @@ concat (nargs, args, target_type, last_special)
                if (this_len_byte > 1)
                  some_multibyte = 1;
              }
+         else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0)
+           wrong_type_argument (Qintegerp, Faref (this, make_number (0)));
          else if (CONSP (this))
            for (; CONSP (this); this = XCONS (this)->cdr)
              {
@@ -555,43 +567,41 @@ concat (nargs, args, target_type, last_special)
            if (NILP (this)) break;
            if (CONSP (this))
              elt = XCONS (this)->car, this = XCONS (this)->cdr;
-           else
+           else if (thisindex >= thisleni)
+             break;
+           else if (STRINGP (this))
              {
-               if (thisindex >= thisleni) break;
-               if (STRINGP (this))
+               int c;
+               if (STRING_MULTIBYTE (this))
                  {
-                   if (STRING_MULTIBYTE (this))
-                     {
-                       int c;
-                       FETCH_STRING_CHAR_ADVANCE (c, this,
-                                                  thisindex,
-                                                  thisindex_byte);
-                       XSETFASTINT (elt, c);
-                     }
-                   else
-                     {
-                       unsigned char c;
-                       XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
-                       if (some_multibyte)
-                         XSETINT (elt,
-                                  unibyte_char_to_multibyte (XINT (elt)));
-                     }
+                   FETCH_STRING_CHAR_ADVANCE (c, this,
+                                              thisindex,
+                                              thisindex_byte);
+                   XSETFASTINT (elt, c);
                  }
-               else if (BOOL_VECTOR_P (this))
+               else
                  {
-                   int size_in_chars
-                     = ((XBOOL_VECTOR (this)->size + BITS_PER_CHAR - 1)
-                        / BITS_PER_CHAR);
-                   int byte;
-                   byte = XBOOL_VECTOR (val)->data[thisindex / BITS_PER_CHAR];
-                   if (byte & (1 << (thisindex % BITS_PER_CHAR)))
-                     elt = Qt;
-                   else
-                     elt = Qnil;
+                   XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
+                   if (some_multibyte && XINT (elt) >= 0200
+                       && XINT (elt) < 0400)
+                     {
+                       c = unibyte_char_to_multibyte (XINT (elt));
+                       XSETINT (elt, c);
+                     }
                  }
+             }
+           else if (BOOL_VECTOR_P (this))
+             {
+               int byte;
+               byte = XBOOL_VECTOR (this)->data[thisindex / BITS_PER_CHAR];
+               if (byte & (1 << (thisindex % BITS_PER_CHAR)))
+                 elt = Qt;
                else
-                 elt = XVECTOR (this)->contents[thisindex++];
+                 elt = Qnil;
+               thisindex++;
              }
+           else
+             elt = XVECTOR (this)->contents[thisindex++];
 
            /* Store this element into the result.  */
            if (toindex < 0)
@@ -771,7 +781,7 @@ string_byte_to_char (string, byte_index)
 }
 \f
 /* Convert STRING to a multibyte string.
-   Single-byte characters 0200 through 0377 are converted
+   Single-byte characters 0240 through 0377 are converted
    by adding nonascii_insert_offset to each.  */
 
 Lisp_Object
@@ -786,6 +796,11 @@ string_make_multibyte (string)
 
   nbytes = count_size_as_multibyte (XSTRING (string)->data,
                                    XSTRING (string)->size);
+  /* 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 == XSTRING (string)->size_byte)
+    return string;
+
   buf = (unsigned char *) alloca (nbytes);
   copy_text (XSTRING (string)->data, buf, XSTRING (string)->size_byte,
             0, 1);
@@ -829,6 +844,42 @@ DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte,
 {
   return string_make_unibyte (string);
 }
+
+DEFUN ("string-as-unibyte", Fstring_as_unibyte, Sstring_as_unibyte,
+       1, 1, 0,
+  "Return a unibyte string with the same individual bytes as STRING.\n\
+If STRING is unibyte, the result is STRING itself.")
+  (string)
+     Lisp_Object string;
+{
+  if (STRING_MULTIBYTE (string))
+    {
+      string = Fcopy_sequence (string);
+      XSTRING (string)->size = XSTRING (string)->size_byte;
+    }
+  return string;
+}
+
+DEFUN ("string-as-multibyte", Fstring_as_multibyte, Sstring_as_multibyte,
+       1, 1, 0,
+  "Return a multibyte string with the same individual bytes as STRING.\n\
+If STRING is multibyte, the result is STRING itself.")
+  (string)
+     Lisp_Object string;
+{
+  if (! STRING_MULTIBYTE (string))
+    {
+      int newlen = multibyte_chars_in_text (XSTRING (string)->data,
+                                           XSTRING (string)->size_byte);
+      /* If all the chars are ASCII, STRING is already suitable.  */
+      if (newlen != XSTRING (string)->size_byte)
+       {
+         string = Fcopy_sequence (string);
+         XSTRING (string)->size = newlen;
+       }
+    }
+  return string;
+}
 \f
 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
   "Return a copy of ALIST.\n\
@@ -1510,6 +1561,8 @@ internal_equal (o1, o2, depth)
              return 0;
            return 1;
          }
+       if (WINDOW_CONFIGURATIONP (o1))
+         return compare_window_configurations (o1, o2, 0);
 
        /* Aside from them, only true vectors, char-tables, and compiled
           functions are sensible to compare, so eliminate the others now.  */
@@ -1681,9 +1734,9 @@ DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
 DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
        2, 2, 0,
   "Return the value in CHAR-TABLE for a range of characters RANGE.\n\
-RANGE should be t (for all characters), nil (for the default value)\n\
+RANGE should be nil (for the default value)\n\
 a vector which identifies a character set or a row of a character set,\n\
-or a character code.")
+a character set name, or a character code.")
   (char_table, range)
      Lisp_Object char_table, range;
 {
@@ -1695,10 +1748,19 @@ or a character code.")
     return XCHAR_TABLE (char_table)->defalt;
   else if (INTEGERP (range))
     return Faref (char_table, range);
+  else if (SYMBOLP (range))
+    {
+      Lisp_Object charset_info;
+
+      charset_info = Fget (range, Qcharset);
+      CHECK_VECTOR (charset_info, 0);
+
+      return Faref (char_table, XVECTOR (charset_info)->contents[0] + 128);
+    }
   else if (VECTORP (range))
     {
       if (XVECTOR (range)->size == 1)
-       return Faref (char_table, XVECTOR (range)->contents[0]);
+       return Faref (char_table, XVECTOR (range)->contents[0] + 128);
       else
        {
          int size = XVECTOR (range)->size;
@@ -1718,7 +1780,7 @@ DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
   "Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.\n\
 RANGE should be t (for all characters), nil (for the default value)\n\
 a vector which identifies a character set or a row of a character set,\n\
-or a character code.")
+a coding system, or a character code.")
   (char_table, range, value)
      Lisp_Object char_table, range, value;
 {
@@ -1731,12 +1793,22 @@ or a character code.")
       XCHAR_TABLE (char_table)->contents[i] = value;
   else if (EQ (range, Qnil))
     XCHAR_TABLE (char_table)->defalt = value;
+  else if (SYMBOLP (range))
+    {
+      Lisp_Object charset_info;
+
+      charset_info = Fget (range, Qcharset);
+      CHECK_VECTOR (charset_info, 0);
+
+      return Faset (char_table, XVECTOR (charset_info)->contents[0] + 128,
+                   value);
+    }
   else if (INTEGERP (range))
     Faset (char_table, range, value);
   else if (VECTORP (range))
     {
       if (XVECTOR (range)->size == 1)
-       return Faset (char_table, XVECTOR (range)->contents[0], value);
+       return Faset (char_table, XVECTOR (range)->contents[0] + 128, value);
       else
        {
          int size = XVECTOR (range)->size;
@@ -1770,7 +1842,7 @@ See also the documentation of make-char.")
   c = XINT (ch);
   SPLIT_NON_ASCII_CHAR (c, charset, code1, code2);
   if (! CHARSET_DEFINED_P (charset))
-    error ("Invalid character: %d", c);
+    invalid_character (c);
 
   if (charset == CHARSET_ASCII)
     return (XCHAR_TABLE (char_table)->defalt = value);
@@ -1977,6 +2049,20 @@ mapcar1 (leni, vals, fn, seq)
          vals[i] = call1 (fn, dummy);
        }
     }
+  else if (BOOL_VECTOR_P (seq))
+    {
+      for (i = 0; i < leni; i++)
+       {
+         int byte;
+         byte = XBOOL_VECTOR (seq)->data[i / BITS_PER_CHAR];
+         if (byte & (1 << (i % BITS_PER_CHAR)))
+           dummy = Qt;
+         else
+           dummy = Qnil;
+
+         vals[i] = call1 (fn, dummy);
+       }
+    }
   else if (STRINGP (seq) && ! STRING_MULTIBYTE (seq))
     {
       /* Single-byte string.  */
@@ -2018,7 +2104,8 @@ mapcar1 (leni, vals, fn, seq)
 DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
   "Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.\n\
 In between each pair of results, stick in SEPARATOR.  Thus, \" \" as\n\
-SEPARATOR results in spaces between the values returned by FUNCTION.")
+SEPARATOR results in spaces between the values returned by FUNCTION.\n\
+SEQUENCE may be a list, a vector, a bool-vector, or a string.")
   (function, sequence, separator)
      Lisp_Object function, sequence, separator;
 {
@@ -2052,7 +2139,7 @@ SEPARATOR results in spaces between the values returned by FUNCTION.")
 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
   "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
 The result is a list just as long as SEQUENCE.\n\
-SEQUENCE may be a list, a vector or a string.")
+SEQUENCE may be a list, a vector, a bool-vector, or a string.")
   (function, sequence)
      Lisp_Object function, sequence;
 {
@@ -2473,6 +2560,7 @@ invoked by mouse clicks and mouse menu items.");
   defsubr (&Srandom);
   defsubr (&Slength);
   defsubr (&Ssafe_length);
+  defsubr (&Sstring_bytes);
   defsubr (&Sstring_equal);
   defsubr (&Sstring_lessp);
   defsubr (&Sappend);
@@ -2481,6 +2569,8 @@ invoked by mouse clicks and mouse menu items.");
   defsubr (&Scopy_sequence);
   defsubr (&Sstring_make_multibyte);
   defsubr (&Sstring_make_unibyte);
+  defsubr (&Sstring_as_multibyte);
+  defsubr (&Sstring_as_unibyte);
   defsubr (&Scopy_alist);
   defsubr (&Ssubstring);
   defsubr (&Snthcdr);