]> code.delx.au - gnu-emacs/blobdiff - src/fns.c
(Flength): Doc fix.
[gnu-emacs] / src / fns.c
index a723b3f1c7013cd34e72805024e09707de27e226..26a1e3ea48d7631d1a9511662b205f26b83981d5 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;
@@ -111,8 +109,8 @@ DEFUN ("length", Flength, Slength, 1, 1, 0,
   "Return the length of vector, list or string SEQUENCE.\n\
 A byte-code function object is also allowed.\n\
 If the string contains multibyte characters, this is not the necessarily\n\
-the number of characters in the string; it is the number of bytes.\n\
-To get the number of characters, use `chars-in-string'")
+the number of bytes in the string; it is the number of characters.\n\
+To get the number of bytes, use `string-bytes'")
   (sequence)
      register Lisp_Object sequence;
 {
@@ -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))
@@ -186,7 +186,7 @@ If STRING is a multibyte string, this is greater than the length of STRING.")
      Lisp_Object string;
 {
   CHECK_STRING (string, 1);
-  return make_number (XSTRING (string)->size_byte);
+  return make_number (STRING_BYTES (XSTRING (string)));
 }
 
 DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
@@ -204,8 +204,8 @@ Symbols are also allowed; their print names are used instead.")
   CHECK_STRING (s2, 1);
 
   if (XSTRING (s1)->size != XSTRING (s2)->size
-      || XSTRING (s1)->size_byte != XSTRING (s2)->size_byte
-      || bcmp (XSTRING (s1)->data, XSTRING (s2)->data, XSTRING (s1)->size_byte))
+      || STRING_BYTES (XSTRING (s1)) != STRING_BYTES (XSTRING (s2))
+      || bcmp (XSTRING (s1)->data, XSTRING (s2)->data, STRING_BYTES (XSTRING (s1))))
     return Qnil;
   return Qt;
 }
@@ -488,7 +488,7 @@ concat (nargs, args, target_type, last_special)
              if (STRING_MULTIBYTE (this))
                {
                  some_multibyte = 1;
-                 result_len_byte += XSTRING (this)->size_byte;
+                 result_len_byte += STRING_BYTES (XSTRING (this));
                }
              else
                result_len_byte += count_size_as_multibyte (XSTRING (this)->data,
@@ -507,8 +507,10 @@ concat (nargs, args, target_type, last_special)
     val = Fmake_list (make_number (result_len), Qnil);
   else if (target_type == Lisp_Vectorlike)
     val = Fmake_vector (make_number (result_len), Qnil);
-  else
+  else if (some_multibyte)
     val = make_uninit_multibyte_string (result_len, result_len_byte);
+  else
+    val = make_uninit_string (result_len);
 
   /* In `append', if all but last arg are nil, return last arg.  */
   if (target_type == Lisp_Cons && EQ (val, Qnil))
@@ -542,9 +544,9 @@ concat (nargs, args, target_type, last_special)
       if (STRINGP (this) && STRINGP (val)
          && STRING_MULTIBYTE (this) == some_multibyte)
        {
-         int thislen_byte = XSTRING (this)->size_byte;
+         int thislen_byte = STRING_BYTES (XSTRING (this));
          bcopy (XSTRING (this)->data, XSTRING (val)->data + toindex_byte,
-                XSTRING (this)->size_byte);
+                STRING_BYTES (XSTRING (this)));
          toindex_byte += thislen_byte;
          toindex += thisleni;
        }
@@ -571,9 +573,9 @@ concat (nargs, args, target_type, last_special)
              break;
            else if (STRINGP (this))
              {
+               int c;
                if (STRING_MULTIBYTE (this))
                  {
-                   int c;
                    FETCH_STRING_CHAR_ADVANCE (c, this,
                                               thisindex,
                                               thisindex_byte);
@@ -581,21 +583,11 @@ concat (nargs, args, target_type, last_special)
                  }
                else
                  {
-                   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;
-
+                       c = unibyte_char_to_multibyte (XINT (elt));
                        XSETINT (elt, c);
                      }
                  }
@@ -674,7 +666,7 @@ string_char_to_byte (string, char_index)
 
   best_below = best_below_byte = 0;
   best_above = XSTRING (string)->size;
-  best_above_byte = XSTRING (string)->size_byte;
+  best_above_byte = STRING_BYTES (XSTRING (string));
 
   if (EQ (string, string_char_byte_cache_string))
     {
@@ -740,7 +732,7 @@ string_byte_to_char (string, byte_index)
 
   best_below = best_below_byte = 0;
   best_above = XSTRING (string)->size;
-  best_above_byte = XSTRING (string)->size_byte;
+  best_above_byte = STRING_BYTES (XSTRING (string));
 
   if (EQ (string, string_char_byte_cache_string))
     {
@@ -791,7 +783,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
@@ -808,11 +800,11 @@ string_make_multibyte (string)
                                    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)
+  if (nbytes == STRING_BYTES (XSTRING (string)))
     return string;
 
   buf = (unsigned char *) alloca (nbytes);
-  copy_text (XSTRING (string)->data, buf, XSTRING (string)->size_byte,
+  copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
             0, 1);
 
   return make_multibyte_string (buf, XSTRING (string)->size, nbytes);
@@ -831,7 +823,7 @@ string_make_unibyte (string)
 
   buf = (unsigned char *) alloca (XSTRING (string)->size);
 
-  copy_text (XSTRING (string)->data, buf, XSTRING (string)->size_byte,
+  copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
             1, 0);
 
   return make_unibyte_string (buf, XSTRING (string)->size);
@@ -865,7 +857,8 @@ If STRING is unibyte, the result is STRING itself.")
   if (STRING_MULTIBYTE (string))
     {
       string = Fcopy_sequence (string);
-      XSTRING (string)->size = XSTRING (string)->size_byte;
+      XSTRING (string)->size = STRING_BYTES (XSTRING (string));
+      SET_STRING_BYTES (XSTRING (string), -1);
     }
   return string;
 }
@@ -879,14 +872,12 @@ If STRING is multibyte, the result is STRING itself.")
 {
   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;
-       }
+      int nbytes = STRING_BYTES (XSTRING (string));
+      int newlen = multibyte_chars_in_text (XSTRING (string)->data, nbytes);
+
+      string = Fcopy_sequence (string);
+      XSTRING (string)->size = newlen;
+      XSTRING (string)->size_byte = nbytes;
     }
   return string;
 }
@@ -942,7 +933,7 @@ This function allows vectors as well as strings.")
   if (STRINGP (string))
     {
       size = XSTRING (string)->size;
-      size_byte = XSTRING (string)->size_byte;
+      size_byte = STRING_BYTES (XSTRING (string));
     }
   else
     size = XVECTOR (string)->size;
@@ -976,8 +967,9 @@ This function allows vectors as well as strings.")
 
   if (STRINGP (string))
     {
-      res = make_multibyte_string (XSTRING (string)->data + from_byte,
-                                  to_char - from_char, to_byte - from_byte);
+      res = make_specified_string (XSTRING (string)->data + from_byte,
+                                  to_char - from_char, to_byte - from_byte,
+                                  STRING_MULTIBYTE (string));
       copy_text_properties (from_char, to_char, string,
                            make_number (0), res, Qnil);
     }
@@ -1006,7 +998,7 @@ substring_both (string, from, from_byte, to, to_byte)
   if (STRINGP (string))
     {
       size = XSTRING (string)->size;
-      size_byte = XSTRING (string)->size_byte;
+      size_byte = STRING_BYTES (XSTRING (string));
     }
   else
     size = XVECTOR (string)->size;
@@ -1016,8 +1008,9 @@ substring_both (string, from, from_byte, to, to_byte)
 
   if (STRINGP (string))
     {
-      res = make_multibyte_string (XSTRING (string)->data + from_byte,
-                                  to - from, to_byte - from_byte);
+      res = make_specified_string (XSTRING (string)->data + from_byte,
+                                  to - from, to_byte - from_byte,
+                                  STRING_MULTIBYTE (string));
       copy_text_properties (from, to, string, make_number (0), res, Qnil);
     }
   else
@@ -1572,7 +1565,7 @@ internal_equal (o1, o2, depth)
            return 1;
          }
        if (WINDOW_CONFIGURATIONP (o1))
-         return compare_window_configurations (o1, o2);
+         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.  */
@@ -1597,10 +1590,10 @@ internal_equal (o1, o2, depth)
     case Lisp_String:
       if (XSTRING (o1)->size != XSTRING (o2)->size)
        return 0;
-      if (XSTRING (o1)->size_byte != XSTRING (o2)->size_byte)
+      if (STRING_BYTES (XSTRING (o1)) != STRING_BYTES (XSTRING (o2)))
        return 0;
       if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data,
-               XSTRING (o1)->size_byte))
+               STRING_BYTES (XSTRING (o1))))
        return 0;
       return 1;
     }
@@ -1852,7 +1845,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);
@@ -1881,6 +1874,23 @@ See also the documentation of make-char.")
     XCHAR_TABLE (char_table)->contents[code1] = value;
   return value;
 }
+
+/* Look up the element in TABLE at index CH,
+   and return it as an integer.
+   If the element is nil, return CH itself.
+   (Actually we do that for any non-integer.)  */
+
+int
+char_table_translate (table, ch)
+     Lisp_Object table;
+     int ch;
+{
+  Lisp_Object value;
+  value = Faref (table, make_number (ch));
+  if (! INTEGERP (value))
+    return ch;
+  return XINT (value);
+}
 \f
 /* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
    character or group of characters that share a value.
@@ -2059,6 +2069,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.  */
@@ -2071,7 +2095,7 @@ mapcar1 (leni, vals, fn, seq)
   else if (STRINGP (seq))
     {
       /* Multi-byte string.  */
-      int len_byte = XSTRING (seq)->size_byte;
+      int len_byte = STRING_BYTES (XSTRING (seq));
       int i_byte;
 
       for (i = 0, i_byte = 0; i < leni;)
@@ -2100,7 +2124,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;
 {
@@ -2134,7 +2159,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;
 {