(Fccl_execute_on_string): Put \n\ at end-of-line of
[bpt/emacs.git] / src / fns.c
index 421879f..a724fa5 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -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,51 @@ 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))
+               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)));
-                     }
+                   int c;
+                   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;
+                   unsigned char c;
+                   XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
+                   if (some_multibyte && XINT (elt) >= 0200
+                       && XINT (elt) < 0400)
+                     {
+                       c = XINT (elt);
+
+                       if (! NILP (Vnonascii_translate_table))
+                         c = XINT (Faref (Vnonascii_translate_table,
+                                          make_number (c)));
+                       else if (nonascii_insert_offset > 0)
+                         c += nonascii_insert_offset;
+                       else
+                         c += DEFAULT_NONASCII_INSERT_OFFSET;
+
+                       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)
@@ -786,6 +806,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 +854,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 = 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 +1571,8 @@ internal_equal (o1, o2, depth)
              return 0;
            return 1;
          }
+       if (WINDOW_CONFIGURATIONP (o1))
+         return compare_window_configurations (o1, o2);
 
        /* Aside from them, only true vectors, char-tables, and compiled
           functions are sensible to compare, so eliminate the others now.  */
@@ -1681,9 +1744,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 +1758,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 +1790,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 +1803,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 +1852,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);
@@ -2473,6 +2555,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 +2564,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);