]> code.delx.au - gnu-emacs/blobdiff - src/fns.c
(XMenuActivate): Fix call to lookup_derived_face.
[gnu-emacs] / src / fns.c
index 6001d99fb49e4d583bf01b1115528823e2242406..9a3121a3391f7c75bcb4b315d61ca4d7ae6b65ed 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -26,8 +26,8 @@ Boston, MA 02111-1307, USA.  */
 #endif
 #include <time.h>
 
-#ifndef MAC_OSX
-/* On Mac OS X, defining this conflicts with precompiled headers.  */
+#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.  */
@@ -562,6 +562,7 @@ concat (nargs, args, target_type, last_special)
   struct textprop_rec  *textprops = NULL;
   /* Number of elments in textprops.  */
   int num_textprops = 0;
+  USE_SAFE_ALLOCA;
 
   tail = Qnil;
 
@@ -670,8 +671,7 @@ concat (nargs, args, target_type, last_special)
 
   prev = Qnil;
   if (STRINGP (val))
-    textprops
-      = (struct textprop_rec *) alloca (sizeof (struct textprop_rec) * nargs);
+    SAFE_ALLOCA (textprops, struct textprop_rec *, sizeof (struct textprop_rec) * nargs);
 
   for (argnum = 0; argnum < nargs; argnum++)
     {
@@ -741,7 +741,7 @@ concat (nargs, args, target_type, last_special)
                  }
                else
                  {
-                   XSETFASTINT (elt, SREF (this, thisindex++));
+                   XSETFASTINT (elt, SREF (this, thisindex)); thisindex++;
                    if (some_multibyte
                        && (XINT (elt) >= 0240
                            || (XINT (elt) >= 0200
@@ -827,6 +827,8 @@ concat (nargs, args, target_type, last_special)
          last_to_end = textprops[argnum].to + SCHARS (this);
        }
     }
+
+  SAFE_FREE ();
   return val;
 }
 \f
@@ -994,6 +996,8 @@ string_make_multibyte (string)
 {
   unsigned char *buf;
   int nbytes;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   if (STRING_MULTIBYTE (string))
     return string;
@@ -1005,11 +1009,14 @@ string_make_multibyte (string)
   if (nbytes == SBYTES (string))
     return string;
 
-  buf = (unsigned char *) alloca (nbytes);
+  SAFE_ALLOCA (buf, unsigned char *, nbytes);
   copy_text (SDATA (string), buf, SBYTES (string),
             0, 1);
 
-  return make_multibyte_string (buf, SCHARS (string), nbytes);
+  ret = make_multibyte_string (buf, SCHARS (string), nbytes);
+  SAFE_FREE ();
+
+  return ret;
 }
 
 
@@ -1024,6 +1031,8 @@ string_to_multibyte (string)
 {
   unsigned char *buf;
   int nbytes;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   if (STRING_MULTIBYTE (string))
     return string;
@@ -1034,11 +1043,14 @@ string_to_multibyte (string)
   if (nbytes == SBYTES (string))
     return make_multibyte_string (SDATA (string), nbytes, nbytes);
 
-  buf = (unsigned char *) alloca (nbytes);
+  SAFE_ALLOCA (buf, unsigned char *, nbytes);
   bcopy (SDATA (string), buf, SBYTES (string));
   str_to_multibyte (buf, nbytes, SBYTES (string));
 
-  return make_multibyte_string (buf, SCHARS (string), nbytes);
+  ret = make_multibyte_string (buf, SCHARS (string), nbytes);
+  SAFE_FREE ();
+
+  return ret;
 }
 
 
@@ -1048,17 +1060,24 @@ Lisp_Object
 string_make_unibyte (string)
      Lisp_Object string;
 {
+  int nchars;
   unsigned char *buf;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   if (! STRING_MULTIBYTE (string))
     return string;
 
-  buf = (unsigned char *) alloca (SCHARS (string));
+  nchars = SCHARS (string);
 
+  SAFE_ALLOCA (buf, unsigned char *, nchars);
   copy_text (SDATA (string), buf, SBYTES (string),
             1, 0);
 
-  return make_unibyte_string (buf, SCHARS (string));
+  ret = make_unibyte_string (buf, nchars);
+  SAFE_FREE ();
+
+  return ret;
 }
 
 DEFUN ("string-make-multibyte", Fstring_make_multibyte, Sstring_make_multibyte,
@@ -1980,6 +1999,35 @@ one of the properties on the list.  */)
   return Qnil;
 }
 
+DEFUN ("safe-plist-get", Fsafe_plist_get, Ssafe_plist_get, 2, 2, 0,
+       doc: /* Extract a value from a property list.
+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.
+This function never signals an error.  */)
+     (plist, prop)
+     Lisp_Object plist;
+     Lisp_Object prop;
+{
+  Lisp_Object tail, halftail;
+
+  /* halftail is used to detect circular lists.  */
+  tail = halftail = plist;
+  while (CONSP (tail) && CONSP (XCDR (tail)))
+    {
+      if (EQ (prop, XCAR (tail)))
+       return XCAR (XCDR (tail));
+
+      tail = XCDR (XCDR (tail));
+      halftail = XCDR (halftail);
+      if (EQ (tail, halftail))
+       break;
+    }
+
+  return Qnil;
+}
+
 DEFUN ("get", Fget, Sget, 2, 2, 0,
        doc: /* Return the value of SYMBOL's PROPNAME property.
 This is the last value stored with `(put SYMBOL PROPNAME VALUE)'.  */)
@@ -2353,7 +2401,9 @@ This makes STRING unibyte and may change its length.  */)
      (string)
      Lisp_Object string;
 {
-  int len = SBYTES (string);
+  int len;
+  CHECK_STRING (string);
+  len = SBYTES (string);
   bzero (SDATA (string), len);
   STRING_SET_CHARS (string, len);
   STRING_SET_UNIBYTE (string);
@@ -2686,6 +2736,9 @@ map_char_table (c_function, function, table, subtable, arg, depth, indices)
      int depth;
 {
   int i, to;
+  struct gcpro gcpro1, gcpro2,  gcpro3, gcpro4;
+
+  GCPRO4 (arg, table, subtable, function);
 
   if (depth == 0)
     {
@@ -2705,7 +2758,10 @@ map_char_table (c_function, function, table, subtable, arg, depth, indices)
 #if 0 /* If the char table has entries for higher characters,
         we should report them.  */
       if (NILP (current_buffer->enable_multibyte_characters))
-       return;
+       {
+         UNGCPRO;
+         return;
+       }
 #endif
       to = CHAR_TABLE_ORDINARY_SLOTS;
     }
@@ -2758,6 +2814,7 @@ map_char_table (c_function, function, table, subtable, arg, depth, indices)
            call2 (function, make_number (c), elt);
        }
     }
+  UNGCPRO;
 }
 
 static void void_call2 P_ ((Lisp_Object a, Lisp_Object b, Lisp_Object c));
@@ -2983,13 +3040,15 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string.  */)
   register Lisp_Object *args;
   register int i;
   struct gcpro gcpro1;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   len = Flength (sequence);
   leni = XINT (len);
   nargs = leni + leni - 1;
   if (nargs < 0) return build_string ("");
 
-  args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
+  SAFE_ALLOCA_LISP (args, nargs);
 
   GCPRO1 (separator);
   mapcar1 (leni, args, function, sequence);
@@ -3001,7 +3060,10 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string.  */)
   for (i = 1; i < nargs; i += 2)
     args[i] = separator;
 
-  return Fconcat (nargs, args);
+  ret = Fconcat (nargs, args);
+  SAFE_FREE ();
+
+  return ret;
 }
 
 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
@@ -3014,14 +3076,20 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string.  */)
   register Lisp_Object len;
   register int leni;
   register Lisp_Object *args;
+  Lisp_Object ret;
+  USE_SAFE_ALLOCA;
 
   len = Flength (sequence);
   leni = XFASTINT (len);
-  args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
+
+  SAFE_ALLOCA_LISP (args, leni);
 
   mapcar1 (leni, args, function, sequence);
 
-  return Flist (leni, args);
+  ret = Flist (leni, args);
+  SAFE_FREE ();
+
+  return ret;
 }
 
 DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0,
@@ -3238,7 +3306,7 @@ 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));
+                                             Qnil, Qnil));
       if (SCHARS (ans) == 3 && !strcmp (SDATA (ans), "yes"))
        {
          UNGCPRO;
@@ -3375,6 +3443,10 @@ The normal messages at start and end of loading FILENAME are suppressed.  */)
 
   CHECK_SYMBOL (feature);
 
+  /* Record the presence of `require' in this file
+     even if the feature specified is already loaded.  */
+  LOADHIST_ATTACH (Fcons (Qrequire, feature));
+
   tem = Fmemq (feature, Vfeatures);
 
   if (NILP (tem))
@@ -3382,8 +3454,6 @@ The normal messages at start and end of loading FILENAME are suppressed.  */)
       int count = SPECPDL_INDEX ();
       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))
@@ -3636,10 +3706,6 @@ The data read from the system are decoded using `locale-coding-system'.  */)
     }                                  \
   while (IS_BASE64_IGNORABLE (c))
 
-/* Don't use alloca for regions larger than this, lest we overflow
-   their stack.  */
-#define MAX_ALLOCA 16*1024
-
 /* Table of characters coding the 64 values.  */
 static char base64_value_to_char[64] =
 {
@@ -3705,6 +3771,7 @@ into shorter lines.  */)
   int allength, length;
   int ibeg, iend, encoded_length;
   int old_pos = PT;
+  USE_SAFE_ALLOCA;
 
   validate_region (&beg, &end);
 
@@ -3719,10 +3786,7 @@ into shorter lines.  */)
   allength = length + length/3 + 1;
   allength += allength / MIME_LINE_LENGTH + 1 + 6;
 
-  if (allength <= MAX_ALLOCA)
-    encoded = (char *) alloca (allength);
-  else
-    encoded = (char *) xmalloc (allength);
+  SAFE_ALLOCA (encoded, char *, allength);
   encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length,
                                    NILP (no_line_break),
                                    !NILP (current_buffer->enable_multibyte_characters));
@@ -3732,8 +3796,7 @@ into shorter lines.  */)
   if (encoded_length < 0)
     {
       /* The encoding wasn't possible. */
-      if (length > MAX_ALLOCA)
-       xfree (encoded);
+      SAFE_FREE ();
       error ("Multibyte character in data for base64 encoding");
     }
 
@@ -3741,8 +3804,7 @@ into shorter lines.  */)
      and delete the old.  (Insert first in order to preserve markers.)  */
   SET_PT_BOTH (XFASTINT (beg), ibeg);
   insert (encoded, encoded_length);
-  if (allength > MAX_ALLOCA)
-    xfree (encoded);
+  SAFE_FREE ();
   del_range_byte (ibeg + encoded_length, iend + encoded_length, 1);
 
   /* If point was outside of the region, restore it exactly; else just
@@ -3768,6 +3830,7 @@ into shorter lines.  */)
   int allength, length, encoded_length;
   char *encoded;
   Lisp_Object encoded_string;
+  USE_SAFE_ALLOCA;
 
   CHECK_STRING (string);
 
@@ -3779,10 +3842,7 @@ into shorter lines.  */)
   allength += allength / MIME_LINE_LENGTH + 1 + 6;
 
   /* We need to allocate enough room for decoding the text. */
-  if (allength <= MAX_ALLOCA)
-    encoded = (char *) alloca (allength);
-  else
-    encoded = (char *) xmalloc (allength);
+  SAFE_ALLOCA (encoded, char *, allength);
 
   encoded_length = base64_encode_1 (SDATA (string),
                                    encoded, length, NILP (no_line_break),
@@ -3793,14 +3853,12 @@ into shorter lines.  */)
   if (encoded_length < 0)
     {
       /* The encoding wasn't possible. */
-      if (length > MAX_ALLOCA)
-       xfree (encoded);
+      SAFE_FREE ();
       error ("Multibyte character in data for base64 encoding");
     }
 
   encoded_string = make_unibyte_string (encoded, encoded_length);
-  if (allength > MAX_ALLOCA)
-    xfree (encoded);
+  SAFE_FREE ();
 
   return encoded_string;
 }
@@ -3913,6 +3971,7 @@ If the region can't be decoded, signal an error and don't modify the buffer.  */
   int decoded_length;
   int inserted_chars;
   int multibyte = !NILP (current_buffer->enable_multibyte_characters);
+  USE_SAFE_ALLOCA;
 
   validate_region (&beg, &end);
 
@@ -3925,10 +3984,7 @@ If the region can't be decoded, signal an error and don't modify the buffer.  */
      working on a multibyte buffer, each decoded code may occupy at
      most two bytes.  */
   allength = multibyte ? length * 2 : length;
-  if (allength <= MAX_ALLOCA)
-    decoded = (char *) alloca (allength);
-  else
-    decoded = (char *) xmalloc (allength);
+  SAFE_ALLOCA (decoded, char *, allength);
 
   move_gap_both (XFASTINT (beg), ibeg);
   decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length,
@@ -3939,8 +3995,7 @@ If the region can't be decoded, signal an error and don't modify the buffer.  */
   if (decoded_length < 0)
     {
       /* The decoding wasn't possible. */
-      if (allength > MAX_ALLOCA)
-       xfree (decoded);
+      SAFE_FREE ();
       error ("Invalid base64 data");
     }
 
@@ -3948,8 +4003,8 @@ If the region can't be decoded, signal an error and don't modify the buffer.  */
      and delete the old.  (Insert first in order to preserve markers.)  */
   TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg);
   insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0);
-  if (allength > MAX_ALLOCA)
-    xfree (decoded);
+  SAFE_FREE ();
+
   /* Delete the original text.  */
   del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars,
                  iend + decoded_length, 1);
@@ -3974,15 +4029,13 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
   char *decoded;
   int length, decoded_length;
   Lisp_Object decoded_string;
+  USE_SAFE_ALLOCA;
 
   CHECK_STRING (string);
 
   length = SBYTES (string);
   /* We need to allocate enough room for decoding the text. */
-  if (length <= MAX_ALLOCA)
-    decoded = (char *) alloca (length);
-  else
-    decoded = (char *) xmalloc (length);
+  SAFE_ALLOCA (decoded, char *, length);
 
   /* The decoded result should be unibyte. */
   decoded_length = base64_decode_1 (SDATA (string), decoded, length,
@@ -3994,8 +4047,7 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
   else
     decoded_string = Qnil;
 
-  if (length > MAX_ALLOCA)
-    xfree (decoded);
+  SAFE_FREE ();
   if (!STRINGP (decoded_string))
     error ("Invalid base64 data");
 
@@ -4784,6 +4836,10 @@ sweep_weak_table (h, remove_entries_p)
 
                  h->count = make_number (XFASTINT (h->count) - 1);
                }
+             else
+               {
+                 prev = idx;
+               }
            }
          else
            {
@@ -4988,15 +5044,14 @@ sxhash (obj, depth)
       hash = XUINT (obj);
       break;
 
-    case Lisp_Symbol:
-      hash = sxhash_string (SDATA (SYMBOL_NAME (obj)),
-                           SCHARS (SYMBOL_NAME (obj)));
-      break;
-
     case Lisp_Misc:
       hash = XUINT (obj);
       break;
 
+    case Lisp_Symbol:
+      obj = SYMBOL_NAME (obj);
+      /* Fall through.  */
+
     case Lisp_String:
       hash = sxhash_string (SDATA (obj), SCHARS (obj));
       break;
@@ -5716,6 +5771,7 @@ used if both `use-dialog-box' and this variable are non-nil.  */);
   defsubr (&Sreverse);
   defsubr (&Ssort);
   defsubr (&Splist_get);
+  defsubr (&Ssafe_plist_get);
   defsubr (&Sget);
   defsubr (&Splist_put);
   defsubr (&Sput);