]> code.delx.au - gnu-emacs/blobdiff - src/fns.c
Remove leftover table unibyte_to_multibyte_table.
[gnu-emacs] / src / fns.c
index 82f9501f7aae87a92285f7114b177d0dc416ec8c..e1431251e2494edc296a1d0860417a52e51d4aef 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -1,14 +1,14 @@
 /* Random utility Lisp functions.
    Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997,
                  1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006, 2007 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
-GNU Emacs is free software; you can redistribute it and/or modify
+GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -16,9 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
@@ -27,16 +25,11 @@ Boston, MA 02110-1301, USA.  */
 #endif
 #include <time.h>
 
-#ifndef MAC_OS
-/* On Mac OS, defining this conflicts with precompiled headers.  */
-
 /* Note on some machines this defines `vector' as a typedef,
    so make sure we don't use that name in this file.  */
 #undef vector
 #define vector *****
 
-#endif  /* ! MAC_OSX */
-
 #include "lisp.h"
 #include "commands.h"
 #include "character.h"
@@ -102,18 +95,19 @@ DEFUN ("random", Frandom, Srandom, 0, 1, 0,
        doc: /* Return a pseudo-random number.
 All integers representable in Lisp are equally likely.
   On most systems, this is 29 bits' worth.
-With positive integer argument N, return random number in interval [0,N).
-With argument t, set the random number seed from the current time and pid.  */)
-     (n)
-     Lisp_Object n;
+With positive integer LIMIT, return random number in interval [0,LIMIT).
+With argument t, set the random number seed from the current time and pid.
+Other values of LIMIT are ignored.  */)
+     (limit)
+     Lisp_Object limit;
 {
   EMACS_INT val;
   Lisp_Object lispy_val;
   unsigned long denominator;
 
-  if (EQ (n, Qt))
+  if (EQ (limit, Qt))
     seed_random (getpid () + time (NULL));
-  if (NATNUMP (n) && XFASTINT (n) != 0)
+  if (NATNUMP (limit) && XFASTINT (limit) != 0)
     {
       /* Try to take our random number from the higher bits of VAL,
         not the lower, since (says Gentzel) the low bits of `random'
@@ -122,10 +116,10 @@ With argument t, set the random number seed from the current time and pid.  */)
         it's possible to get a quotient larger than n; discarding
         these values eliminates the bias that would otherwise appear
         when using a large n.  */
-      denominator = ((unsigned long)1 << VALBITS) / XFASTINT (n);
+      denominator = ((unsigned long)1 << VALBITS) / XFASTINT (limit);
       do
        val = get_random () / denominator;
-      while (val >= XFASTINT (n));
+      while (val >= XFASTINT (limit));
     }
   else
     val = get_random ();
@@ -303,7 +297,7 @@ If string STR1 is greater, the value is a positive number N;
       else
        {
          c1 = SREF (str1, i1++);
-         c1 = unibyte_char_to_multibyte (c1);
+         MAKE_CHAR_MULTIBYTE (c1);
        }
 
       if (STRING_MULTIBYTE (str2))
@@ -311,7 +305,7 @@ If string STR1 is greater, the value is a positive number N;
       else
        {
          c2 = SREF (str2, i2++);
-         c2 = unibyte_char_to_multibyte (c2);
+         MAKE_CHAR_MULTIBYTE (c2);
        }
 
       if (c1 == c2)
@@ -609,6 +603,8 @@ concat (nargs, args, target_type, last_special)
        }
 
       result_len += len;
+      if (result_len < 0)
+       error ("String overflow");
     }
 
   if (! some_multibyte)
@@ -665,7 +661,6 @@ concat (nargs, args, target_type, last_special)
            }
          toindex_byte += thislen_byte;
          toindex += thisleni;
-         STRING_SET_CHARS (val, SCHARS (val));
        }
       /* Copy a single-byte string to a multibyte string.  */
       else if (STRINGP (this) && STRINGP (val))
@@ -708,10 +703,10 @@ concat (nargs, args, target_type, last_special)
                  {
                    XSETFASTINT (elt, SREF (this, thisindex)); thisindex++;
                    if (some_multibyte
-                       && XINT (elt) >= 0200
+                       && !ASCII_CHAR_P (XINT (elt))
                        && XINT (elt) < 0400)
                      {
-                       c = unibyte_char_to_multibyte (XINT (elt));
+                       c = BYTE8_TO_CHAR (XINT (elt));
                        XSETINT (elt, c);
                      }
                  }
@@ -727,7 +722,10 @@ concat (nargs, args, target_type, last_special)
                thisindex++;
              }
            else
-             elt = AREF (this, thisindex++);
+             {
+               elt = AREF (this, thisindex);
+               thisindex++;
+             }
 
            /* Store this element into the result.  */
            if (toindex < 0)
@@ -737,7 +735,10 @@ concat (nargs, args, target_type, last_special)
                tail = XCDR (tail);
              }
            else if (VECTORP (val))
-             AREF (val, toindex++) = elt;
+             {
+               ASET (val, toindex, elt);
+               toindex++;
+             }
            else
              {
                CHECK_NUMBER (elt);
@@ -780,8 +781,8 @@ concat (nargs, args, target_type, last_special)
 }
 \f
 static Lisp_Object string_char_byte_cache_string;
-static int string_char_byte_cache_charpos;
-static int string_char_byte_cache_bytepos;
+static EMACS_INT string_char_byte_cache_charpos;
+static EMACS_INT string_char_byte_cache_bytepos;
 
 void
 clear_string_char_byte_cache ()
@@ -789,16 +790,16 @@ clear_string_char_byte_cache ()
   string_char_byte_cache_string = Qnil;
 }
 
-/* Return the character index corresponding to CHAR_INDEX in STRING.  */
+/* Return the byte index corresponding to CHAR_INDEX in STRING.  */
 
-int
+EMACS_INT
 string_char_to_byte (string, char_index)
      Lisp_Object string;
-     int char_index;
+     EMACS_INT char_index;
 {
-  int i_byte;
-  int best_below, best_below_byte;
-  int best_above, best_above_byte;
+  EMACS_INT i_byte;
+  EMACS_INT best_below, best_below_byte;
+  EMACS_INT best_above, best_above_byte;
 
   best_below = best_below_byte = 0;
   best_above = SCHARS (string);
@@ -853,14 +854,14 @@ string_char_to_byte (string, char_index)
 \f
 /* Return the character index corresponding to BYTE_INDEX in STRING.  */
 
-int
+EMACS_INT
 string_byte_to_char (string, byte_index)
      Lisp_Object string;
-     int byte_index;
+     EMACS_INT byte_index;
 {
-  int i, i_byte;
-  int best_below, best_below_byte;
-  int best_above, best_above_byte;
+  EMACS_INT i, i_byte;
+  EMACS_INT best_below, best_below_byte;
+  EMACS_INT best_above, best_above_byte;
 
   best_below = best_below_byte = 0;
   best_above = SCHARS (string);
@@ -924,7 +925,7 @@ string_make_multibyte (string)
      Lisp_Object string;
 {
   unsigned char *buf;
-  int nbytes;
+  EMACS_INT nbytes;
   Lisp_Object ret;
   USE_SAFE_ALLOCA;
 
@@ -958,7 +959,7 @@ string_to_multibyte (string)
      Lisp_Object string;
 {
   unsigned char *buf;
-  int nbytes;
+  EMACS_INT nbytes;
   Lisp_Object ret;
   USE_SAFE_ALLOCA;
 
@@ -1127,6 +1128,33 @@ correct sequence.  */)
   return string_to_multibyte (string);
 }
 
+DEFUN ("string-to-unibyte", Fstring_to_unibyte, Sstring_to_unibyte,
+       1, 1, 0,
+       doc: /* Return a unibyte string with the same individual chars as STRING.
+If STRING is unibyte, the result is STRING itself.
+Otherwise it is a newly created string, with no text properties,
+where each `eight-bit' character is converted to the corresponding byte.
+If STRING contains a non-ASCII, non-`eight-bit' character,
+an error is signaled.  */)
+     (string)
+     Lisp_Object string;
+{
+  CHECK_STRING (string);
+
+  if (STRING_MULTIBYTE (string))
+    {
+      EMACS_INT chars = SCHARS (string);
+      unsigned char *str = (unsigned char *) xmalloc (chars);
+      EMACS_INT converted = str_to_unibyte (SDATA (string), str, chars, 0);
+
+      if (converted < chars)
+       error ("Can't convert the %dth character to unibyte", converted);
+      string = make_unibyte_string (str, chars);
+      xfree (str);
+    }
+  return string;
+}
+
 \f
 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
        doc: /* Return a copy of ALIST.
@@ -1156,11 +1184,16 @@ Elements of ALIST that are not conses are also shared.  */)
 }
 
 DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
-       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.
-FROM and TO start at 0.  If either is negative, it counts from the end.
-
-This function allows vectors as well as strings.  */)
+       doc: /* Return a new string whose contents are a substring of STRING.
+The returned string consists of the characters between index FROM
+\(inclusive) and index TO (exclusive) of STRING.  FROM and TO are
+zero-indexed: 0 means the first character of STRING.  Negative values
+are counted from the end of STRING.  If TO is nil, the substring runs
+to the end of STRING.
+
+The STRING argument may also be a vector.  In that case, the return
+value is a new vector that contains the elements between index FROM
+\(inclusive) and index TO (exclusive) of that vector argument.  */)
      (string, from, to)
      Lisp_Object string;
      register Lisp_Object from, to;
@@ -2201,12 +2234,13 @@ internal_equal (o1, o2, depth, props)
        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.  */
+       /* Aside from them, only true vectors, char-tables, compiled
+          functions, and fonts (font-spec, font-entity, font-ojbect)
+          are sensible to compare, so eliminate the others now.  */
        if (size & PSEUDOVECTOR_FLAG)
          {
            if (!(size & (PVEC_COMPILED
-                         | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE)))
+                         | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE | PVEC_FONT)))
              return 0;
            size &= PSEUDOVECTOR_SIZE_MASK;
          }
@@ -2594,7 +2628,7 @@ is nil and `use-dialog-box' is non-nil.  */)
   xprompt = prompt;
   GCPRO2 (prompt, xprompt);
 
-#ifdef HAVE_X_WINDOWS
+#ifdef HAVE_WINDOW_SYSTEM
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
@@ -3100,8 +3134,10 @@ The data read from the system are decoded using `locale-coding-system'.  */)
   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};
+      const int days[7] = {DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7};
       int i;
+      struct gcpro gcpro1;
+      GCPRO1 (v);
       synchronize_system_time_locale ();
       for (i = 0; i < 7; i++)
        {
@@ -3113,26 +3149,29 @@ The data read from the system are decoded using `locale-coding-system'.  */)
                 code_convert_string_norecord (val, Vlocale_coding_system,
                                               0));
        }
+      UNGCPRO;
       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};
+      Lisp_Object v = Fmake_vector (make_number (12), Qnil);
+      const 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;
+      struct gcpro gcpro1;
+      GCPRO1 (v);
       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);
+         Faset (v, make_number (i),
+                code_convert_string_norecord (val, Vlocale_coding_system, 0));
        }
-      XSETVECTOR (val, p);
-      return val;
+      UNGCPRO;
+      return v;
     }
 #endif /* MON_1 */
 /* LC_PAPER stuff isn't defined as accessible in glibc as of 2.3.1,
@@ -4172,8 +4211,8 @@ hash_put (h, key, value, hash)
 
 /* Remove the entry matching KEY from hash table H, if there is one.  */
 
-void
-hash_remove (h, key)
+static void
+hash_remove_from_table (h, key)
      struct Lisp_Hash_Table *h;
      Lisp_Object key;
 {
@@ -4239,7 +4278,7 @@ hash_clear (h)
        }
 
       for (i = 0; i < ASIZE (h->index); ++i)
-       AREF (h->index, i) = Qnil;
+       ASET (h->index, i, Qnil);
 
       h->next_free = make_number (0);
       h->count = 0;
@@ -4252,6 +4291,12 @@ hash_clear (h)
                           Weak Hash Tables
  ************************************************************************/
 
+void
+init_weak_hash_tables ()
+{
+  weak_hash_tables = NULL;
+}
+
 /* Sweep weak hash table H.  REMOVE_ENTRIES_P non-zero means remove
    entries from the table that don't survive the current GC.
    REMOVE_ENTRIES_P zero means mark entries that are in use.  Value is
@@ -4559,8 +4604,9 @@ sxhash (obj, depth)
 
     case Lisp_Float:
       {
-       unsigned char *p = (unsigned char *) &XFLOAT_DATA (obj);
-       unsigned char *e = p + sizeof XFLOAT_DATA (obj);
+       double val = XFLOAT_DATA (obj);
+       unsigned char *p = (unsigned char *) &val;
+       unsigned char *e = p + sizeof val;
        for (hash = 0; p < e; ++p)
          hash = SXHASH_COMBINE (hash, *p);
        break;
@@ -4779,12 +4825,13 @@ DEFUN ("hash-table-p", Fhash_table_p, Shash_table_p, 1, 1, 0,
 
 
 DEFUN ("clrhash", Fclrhash, Sclrhash, 1, 1, 0,
-       doc: /* Clear hash table TABLE.  */)
+       doc: /* Clear hash table TABLE and return it.  */)
      (table)
      Lisp_Object table;
 {
   hash_clear (check_hash_table (table));
-  return Qnil;
+  /* Be compatible with XEmacs.  */
+  return table;
 }
 
 
@@ -4827,7 +4874,7 @@ DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0,
      Lisp_Object key, table;
 {
   struct Lisp_Hash_Table *h = check_hash_table (table);
-  hash_remove (h, key);
+  hash_remove_from_table (h, key);
   return Qnil;
 }
 
@@ -5195,14 +5242,18 @@ Used by `featurep' and `require', and altered by `provide'.  */);
   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-p' and `yes-or-no-p' questions asked by commands
-invoked by mouse clicks and mouse menu items.  */);
+invoked by mouse clicks and mouse menu items.
+
+On some platforms, file selection dialogs are also enabled if this is
+non-nil.  */);
   use_dialog_box = 1;
 
   DEFVAR_BOOL ("use-file-dialog", &use_file_dialog,
     doc: /* *Non-nil means mouse commands use a file dialog to ask for files.
-This applies to commands from menus and tool bar buttons.  The value of
-`use-dialog-box' takes precedence over this variable, so a file dialog is only
-used if both `use-dialog-box' and this variable are non-nil.  */);
+This applies to commands from menus and tool bar buttons even when
+they are initiated from the keyboard.  If `use-dialog-box' is nil,
+that disables the use of a file dialog, regardless of the value of
+this variable.  */);
   use_file_dialog = 1;
 
   defsubr (&Sidentity);
@@ -5222,6 +5273,7 @@ used if both `use-dialog-box' and this variable are non-nil.  */);
   defsubr (&Sstring_as_multibyte);
   defsubr (&Sstring_as_unibyte);
   defsubr (&Sstring_to_multibyte);
+  defsubr (&Sstring_to_unibyte);
   defsubr (&Scopy_alist);
   defsubr (&Ssubstring);
   defsubr (&Ssubstring_no_properties);
@@ -5277,7 +5329,6 @@ used if both `use-dialog-box' and this variable are non-nil.  */);
 void
 init_fns ()
 {
-  weak_hash_tables = NULL;
 }
 
 /* arch-tag: 787f8219-5b74-46bd-8469-7e1cc475fa31