(Fread_file_name): Delete duplicates in
[bpt/emacs.git] / src / eval.c
index 1bb7cb8..879f916 100644 (file)
@@ -1,5 +1,5 @@
 /* Evaluator for GNU Emacs Lisp interpreter.
-   Copyright (C) 1985, 86, 87, 93, 94, 95, 99, 2000, 2001, 2002
+   Copyright (C) 1985, 86, 87, 93, 94, 95, 99, 2000, 2001, 02, 2004
      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -117,7 +117,7 @@ struct specbinding *specpdl;
 
 /* Pointer to first unused element in specpdl.  */
 
-struct specbinding *specpdl_ptr;
+volatile struct specbinding *specpdl_ptr;
 
 /* Maximum size allowed for specpdl allocation */
 
@@ -204,7 +204,7 @@ init_eval_once ()
   specpdl_size = 50;
   specpdl = (struct specbinding *) xmalloc (specpdl_size * sizeof (struct specbinding));
   specpdl_ptr = specpdl;
-  max_specpdl_size = 600;
+  max_specpdl_size = 1000;
   max_lisp_eval_depth = 300;
 
   Vrun_hooks = Qnil;
@@ -234,13 +234,13 @@ call_debugger (arg)
   int debug_while_redisplaying;
   int count = SPECPDL_INDEX ();
   Lisp_Object val;
-  
+
   if (lisp_eval_depth + 20 > max_lisp_eval_depth)
     max_lisp_eval_depth = lisp_eval_depth + 20;
-  
+
   if (specpdl_size + 40 > max_specpdl_size)
     max_specpdl_size = specpdl_size + 40;
-  
+
 #ifdef HAVE_X_WINDOWS
   if (display_hourglass_p)
     cancel_hourglass ();
@@ -261,7 +261,7 @@ call_debugger (arg)
         redisplay, which necessarily leads to display problems.  */
   specbind (Qinhibit_eval_during_redisplay, Qt);
 #endif
-  
+
   val = apply1 (Vdebugger, arg);
 
   /* Interrupting redisplay and resuming it later is not safe under
@@ -294,24 +294,18 @@ usage: (or CONDITIONS ...)  */)
      (args)
      Lisp_Object args;
 {
-  register Lisp_Object val;
-  Lisp_Object args_left;
+  register Lisp_Object val = Qnil;
   struct gcpro gcpro1;
 
-  if (NILP(args))
-    return Qnil;
-
-  args_left = args;
-  GCPRO1 (args_left);
+  GCPRO1 (args);
 
-  do
+  while (CONSP (args))
     {
-      val = Feval (Fcar (args_left));
+      val = Feval (XCAR (args));
       if (!NILP (val))
        break;
-      args_left = Fcdr (args_left);
+      args = XCDR (args);
     }
-  while (!NILP(args_left));
 
   UNGCPRO;
   return val;
@@ -325,24 +319,18 @@ usage: (and CONDITIONS ...)  */)
      (args)
      Lisp_Object args;
 {
-  register Lisp_Object val;
-  Lisp_Object args_left;
+  register Lisp_Object val = Qt;
   struct gcpro gcpro1;
 
-  if (NILP(args))
-    return Qt;
-
-  args_left = args;
-  GCPRO1 (args_left);
+  GCPRO1 (args);
 
-  do
+  while (CONSP (args))
     {
-      val = Feval (Fcar (args_left));
+      val = Feval (XCAR (args));
       if (NILP (val))
        break;
-      args_left = Fcdr (args_left);
+      args = XCDR (args);
     }
-  while (!NILP(args_left));
 
   UNGCPRO;
   return val;
@@ -410,22 +398,16 @@ usage: (progn BODY ...)  */)
      (args)
      Lisp_Object args;
 {
-  register Lisp_Object val;
-  Lisp_Object args_left;
+  register Lisp_Object val = Qnil;
   struct gcpro gcpro1;
 
-  if (NILP(args))
-    return Qnil;
-
-  args_left = args;
-  GCPRO1 (args_left);
+  GCPRO1 (args);
 
-  do
+  while (CONSP (args))
     {
-      val = Feval (Fcar (args_left));
-      args_left = Fcdr (args_left);
+      val = Feval (XCAR (args));
+      args = XCDR (args);
     }
-  while (!NILP(args_left));
 
   UNGCPRO;
   return val;
@@ -535,7 +517,7 @@ usage: (setq SYM VAL SYM VAL ...)  */)
   UNGCPRO;
   return val;
 }
-     
+
 DEFUN ("quote", Fquote, Squote, 1, UNEVALLED, 0,
        doc: /* Return the argument, without evaluating it.  `(quote x)' yields `x'.
 usage: (quote ARG)  */)
@@ -544,7 +526,7 @@ usage: (quote ARG)  */)
 {
   return Fcar (args);
 }
-     
+
 DEFUN ("function", Ffunction, Sfunction, 1, UNEVALLED, 0,
        doc: /* Like `quote', but preferred for objects which are functions.
 In byte compilation, `function' causes its argument to be compiled.
@@ -558,21 +540,45 @@ usage: (function ARG)  */)
 
 
 DEFUN ("interactive-p", Finteractive_p, Sinteractive_p, 0, 0, 0,
-       doc: /* Return t if function in which this appears was called interactively.
+       doc: /* Return t if the function was run directly by user input.
 This means that the function was called with call-interactively (which
 includes being called as the binding of a key)
-and input is currently coming from the keyboard (not in keyboard macro).  */)
+and input is currently coming from the keyboard (not in keyboard macro),
+and Emacs is not running in batch mode (`noninteractive' is nil).
+
+The only known proper use of `interactive-p' is in deciding whether to
+display a helpful message, or how to display it.  If you're thinking
+of using it for any other purpose, it is quite likely that you're
+making a mistake.  Think: what do you want to do when the command is
+called from a keyboard macro?
+
+If you want to test whether your function was called with
+`call-interactively', the way to do that is by adding an extra
+optional argument, and making the `interactive' spec specify non-nil
+unconditionally for that argument.  (`p' is a good way to do this.)  */)
+     ()
+{
+  return (INTERACTIVE && interactive_p (1)) ? Qt : Qnil;
+}
+
+
+DEFUN ("called-interactively-p", Fcalled_interactively_p, Scalled_interactively_p, 0, 0, 0,
+       doc: /* Return t if the function using this was called with call-interactively.
+This is used for implementing advice and other function-modifying
+features of Emacs.
+
+The cleanest way to test whether your function was called with
+`call-interactively', the way to do that is by adding an extra
+optional argument, and making the `interactive' spec specify non-nil
+unconditionally for that argument.  (`p' is a good way to do this.)  */)
      ()
 {
   return interactive_p (1) ? Qt : Qnil;
 }
 
 
-/*  Return 1 if function in which this appears was called
-    interactively.  This means that the function was called with
-    call-interactively (which includes being called as the binding of
-    a key) and input is currently coming from the keyboard (not in
-    keyboard macro).
+/*  Return 1 if function in which this appears was called using
+    call-interactively.
 
     EXCLUDE_SUBRS_P non-zero means always return 0 if the function
     called is a built-in.  */
@@ -584,15 +590,13 @@ interactive_p (exclude_subrs_p)
   struct backtrace *btp;
   Lisp_Object fun;
 
-  if (!INTERACTIVE)
-    return 0;
-
   btp = backtrace_list;
 
   /* If this isn't a byte-compiled function, there may be a frame at
      the top for Finteractive_p.  If so, skip it.  */
   fun = Findirect_function (*btp->function);
-  if (SUBRP (fun) && XSUBR (fun) == &Sinteractive_p)
+  if (SUBRP (fun) && (XSUBR (fun) == &Sinteractive_p
+                     || XSUBR (fun) == &Scalled_interactively_p))
     btp = btp->next;
 
   /* If we're running an Emacs 18-style byte-compiled function, there
@@ -614,7 +618,7 @@ interactive_p (exclude_subrs_p)
   fun = Findirect_function (*btp->function);
   if (exclude_subrs_p && SUBRP (fun))
     return 0;
-  
+
   /* btp points to the frame of a Lisp function that called interactive-p.
      Return t if that function was called interactively.  */
   if (btp && btp->next && EQ (*btp->next->function, Qcall_interactively))
@@ -635,6 +639,7 @@ usage: (defun NAME ARGLIST [DOCSTRING] BODY...)  */)
   register Lisp_Object defn;
 
   fn_name = Fcar (args);
+  CHECK_SYMBOL (fn_name);
   defn = Fcons (Qlambda, Fcdr (args));
   if (!NILP (Vpurify_flag))
     defn = Fpurecopy (defn);
@@ -662,9 +667,9 @@ The elements can look like this:
   (indent INDENT)
        Set NAME's `lisp-indent-function' property to INDENT.
 
-  (edebug DEBUG)
+  (debug DEBUG)
        Set NAME's `edebug-form-spec' property to DEBUG.  (This is
-       equivalent to writing a `def-edebug-spec' for the macro.
+       equivalent to writing a `def-edebug-spec' for the macro.)
 usage: (defmacro NAME ARGLIST [DOCSTRING] [DECL] BODY...)  */)
      (args)
      Lisp_Object args;
@@ -674,14 +679,15 @@ usage: (defmacro NAME ARGLIST [DOCSTRING] [DECL] BODY...)  */)
   Lisp_Object lambda_list, doc, tail;
 
   fn_name = Fcar (args);
+  CHECK_SYMBOL (fn_name);
   lambda_list = Fcar (Fcdr (args));
   tail = Fcdr (Fcdr (args));
 
   doc = Qnil;
   if (STRINGP (Fcar (tail)))
     {
-      doc = Fcar (tail);
-      tail = Fcdr (tail);
+      doc = XCAR (tail);
+      tail = XCDR (tail);
     }
 
   while (CONSP (Fcar (tail))
@@ -694,7 +700,7 @@ usage: (defmacro NAME ARGLIST [DOCSTRING] [DECL] BODY...)  */)
          call2 (Vmacro_declaration_function, fn_name, Fcar (tail));
          UNGCPRO;
        }
-      
+
       tail = Fcdr (tail);
     }
 
@@ -703,7 +709,7 @@ usage: (defmacro NAME ARGLIST [DOCSTRING] [DECL] BODY...)  */)
   else
     tail = Fcons (lambda_list, Fcons (doc, tail));
   defn = Fcons (Qmacro, Fcons (Qlambda, tail));
-  
+
   if (!NILP (Vpurify_flag))
     defn = Fpurecopy (defn);
   if (CONSP (XSYMBOL (fn_name)->function)
@@ -719,8 +725,8 @@ DEFUN ("defvaralias", Fdefvaralias, Sdefvaralias, 2, 3, 0,
        doc: /* Make SYMBOL a variable alias for symbol ALIASED.
 Setting the value of SYMBOL will subsequently set the value of ALIASED,
 and getting the value of SYMBOL will return the value ALIASED has.
-ALIASED nil means remove the alias; SYMBOL is unbound after that.
-Third arg DOCSTRING, if non-nil, is documentation for SYMBOL.  */)
+Third arg DOCSTRING, if non-nil, is documentation for SYMBOL.
+The return value is ALIASED.  */)
      (symbol, aliased, docstring)
      Lisp_Object symbol, aliased, docstring;
 {
@@ -758,6 +764,13 @@ If DOCSTRING starts with *, this variable is identified as a user option.
  This means that M-x set-variable recognizes it.
  See also `user-variable-p'.
 If INITVALUE is missing, SYMBOL's value is not set.
+
+If SYMBOL has a local binding, then this form affects the local
+binding.  This is usually not what you want.  Thus, if you need to
+load a file defining variables, with this form or with `defconst' or
+`defcustom', you should always load that file _outside_ any bindings
+for these variables.  \(`defconst' and `defcustom' behave similarly in
+this respect.)
 usage: (defvar SYMBOL &optional INITVALUE DOCSTRING)  */)
      (args)
      Lisp_Object args;
@@ -774,10 +787,25 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING)  */)
     {
       if (NILP (tem))
        Fset_default (sym, Feval (Fcar (tail)));
+      else
+       { /* Check if there is really a global binding rather than just a let
+            binding that shadows the global unboundness of the var.  */
+         volatile struct specbinding *pdl = specpdl_ptr;
+         while (--pdl >= specpdl)
+           {
+             if (EQ (pdl->symbol, sym) && !pdl->func
+                 && EQ (pdl->old_value, Qunbound))
+               {
+                 message_with_string ("Warning: defvar ignored because %s is let-bound",
+                                      SYMBOL_NAME (sym), 1);
+                 break;
+               }
+           }
+       }
       tail = Fcdr (tail);
-      if (!NILP (Fcar (tail)))
+      tem = Fcar (tail);
+      if (!NILP (tem))
        {
-         tem = Fcar (tail);
          if (!NILP (Vpurify_flag))
            tem = Fpurecopy (tem);
          Fput (sym, Qvariable_documentation, tem);
@@ -800,6 +828,10 @@ Always sets the value of SYMBOL to the result of evalling INITVALUE.
 If SYMBOL is buffer-local, its default value is what is set;
  buffer-local values are not affected.
 DOCSTRING is optional.
+
+If SYMBOL has a local binding, then this form sets the local binding's
+value.  However, you should normally not make local bindings for
+variables defined with this form.
 usage: (defconst SYMBOL INITVALUE [DOCSTRING])  */)
      (args)
      Lisp_Object args;
@@ -830,13 +862,12 @@ DEFUN ("user-variable-p", Fuser_variable_p, Suser_variable_p, 1, 1, 0,
 \(The alternative is a variable used internally in a Lisp program.)
 Determined by whether the first character of the documentation
 for the variable is `*' or if the variable is customizable (has a non-nil
-value of any of `custom-type', `custom-loads' or `standard-value'
-on its property list).  */)
+value of `standard-value' or of `custom-autoload' on its property list).  */)
      (variable)
      Lisp_Object variable;
 {
   Lisp_Object documentation;
-  
+
   if (!SYMBOLP (variable))
       return Qnil;
 
@@ -852,13 +883,12 @@ on its property list).  */)
       && INTEGERP (XCDR (documentation))
       && XINT (XCDR (documentation)) < 0)
     return Qt;
-  /* Customizable?  */
-  if ((!NILP (Fget (variable, intern ("custom-type"))))
-      || (!NILP (Fget (variable, intern ("custom-loads"))))
-      || (!NILP (Fget (variable, intern ("standard-value")))))
+  /* Customizable?  See `custom-variable-p'. */
+  if ((!NILP (Fget (variable, intern ("standard-value"))))
+      || (!NILP (Fget (variable, intern ("custom-autoload")))))
     return Qt;
   return Qnil;
-}  
+}
 \f
 DEFUN ("let*", FletX, SletX, 1, UNEVALLED, 0,
        doc: /* Bind variables according to VARLIST then eval BODY.
@@ -1144,9 +1174,10 @@ unwind_to_catch (catch, value)
   /* Save the value in the tag.  */
   catch->val = value;
 
-  /* Restore the polling-suppression count.  */
+  /* Restore certain special C variables.  */
   set_poll_suppress_count (catch->poll_suppress_count);
   interrupt_input_blocked = catch->interrupt_input_blocked;
+  handling_signal = 0;
 
   do
     {
@@ -1170,7 +1201,7 @@ unwind_to_catch (catch, value)
 #endif
   backtrace_list = catch->backlist;
   lisp_eval_depth = catch->lisp_eval_depth;
-  
+
   _longjmp (catch->jmp, 1);
 }
 
@@ -1207,9 +1238,9 @@ usage: (unwind-protect BODYFORM UNWINDFORMS...)  */)
   Lisp_Object val;
   int count = SPECPDL_INDEX ();
 
-  record_unwind_protect (0, Fcdr (args));
+  record_unwind_protect (Fprogn, Fcdr (args));
   val = Feval (Fcar (args));
-  return unbind_to (count, val);  
+  return unbind_to (count, val);
 }
 \f
 /* Chain of condition handlers currently in effect.
@@ -1240,7 +1271,7 @@ VAR may be nil; then you do not get access to the signal information.
 
 The value of the last BODY form is returned from the condition-case.
 See also the function `signal' for more info.
-usage: (condition-case VAR BODYFORM HANDLERS...)  */)
+usage: (condition-case VAR BODYFORM &rest HANDLERS)  */)
      (args)
      Lisp_Object args;
 {
@@ -1255,10 +1286,10 @@ usage: (condition-case VAR BODYFORM HANDLERS...)  */)
   handlers = Fcdr (Fcdr (args));
   CHECK_SYMBOL (var);
 
-  for (val = handlers; ! NILP (val); val = Fcdr (val))
+  for (val = handlers; CONSP (val); val = XCDR (val))
     {
       Lisp_Object tem;
-      tem = Fcar (val);
+      tem = XCAR (val);
       if (! (NILP (tem)
             || (CONSP (tem)
                 && (SYMBOLP (XCAR (tem))
@@ -1290,7 +1321,7 @@ usage: (condition-case VAR BODYFORM HANDLERS...)  */)
     }
   c.next = catchlist;
   catchlist = &c;
-  
+
   h.var = var;
   h.handler = handlers;
   h.next = handlerlist;
@@ -1456,6 +1487,8 @@ A handler for any of those names will get to handle this signal.
 The symbol `error' should normally be one of them.
 
 DATA should be a list.  Its elements are printed as part of the error message.
+See Info anchor `(elisp)Definition of signal' for some details on how this
+error message is constructed.
 If the signal is handled, DATA is made available to the handler.
 See also the function `condition-case'.  */)
      (error_symbol, data)
@@ -1474,6 +1507,7 @@ See also the function `condition-case'.  */)
   struct backtrace *bp;
 
   immediate_quit = handling_signal = 0;
+  abort_on_gc = 0;
   if (gc_in_progress || waiting_for_input)
     abort ();
 
@@ -1488,7 +1522,7 @@ See also the function `condition-case'.  */)
   if (display_hourglass_p)
     cancel_hourglass ();
 #endif
-#endif 
+#endif
 
   /* This hook is used by edebug.  */
   if (! NILP (Vsignal_hook_function)
@@ -1514,13 +1548,13 @@ See also the function `condition-case'.  */)
   for (; handlerlist; handlerlist = handlerlist->next)
     {
       register Lisp_Object clause;
-      
+
       if (lisp_eval_depth + 20 > max_lisp_eval_depth)
        max_lisp_eval_depth = lisp_eval_depth + 20;
-  
+
       if (specpdl_size + 40 > max_specpdl_size)
        max_specpdl_size = specpdl_size + 40;
-  
+
       clause = find_handler_clause (handlerlist->handler, conditions,
                                    error_symbol, data, &debugger_value);
 
@@ -1610,7 +1644,7 @@ skip_debugger (conditions, data)
              error_message = Ferror_message_string (data);
              first_string = 0;
            }
-         
+
          if (fast_string_match (XCAR (tail), error_message) >= 0)
            return 1;
        }
@@ -1829,13 +1863,11 @@ then strings and vectors are not accepted.  */)
   /* Lists may represent commands.  */
   if (!CONSP (fun))
     return Qnil;
-  funcar = Fcar (fun);
-  if (!SYMBOLP (funcar))
-    return Fsignal (Qinvalid_function, Fcons (fun, Qnil));
+  funcar = XCAR (fun);
   if (EQ (funcar, Qlambda))
-    return Fassq (Qinteractive, Fcdr (Fcdr (fun)));
+    return Fassq (Qinteractive, Fcdr (XCDR (fun)));
   if (EQ (funcar, Qautoload))
-    return Fcar (Fcdr (Fcdr (Fcdr (fun))));
+    return Fcar (Fcdr (Fcdr (XCDR (fun))));
   else
     return Qnil;
 }
@@ -1899,14 +1931,14 @@ un_autoload (oldqueue)
   Vautoload_queue = oldqueue;
   while (CONSP (queue))
     {
-      first = Fcar (queue);
+      first = XCAR (queue);
       second = Fcdr (first);
       first = Fcar (first);
       if (EQ (second, Qnil))
        Vfeatures = first;
       else
        Ffset (first, second);
-      queue = Fcdr (queue);
+      queue = XCDR (queue);
     }
   return Qnil;
 }
@@ -1935,7 +1967,7 @@ do_autoload (fundef, funname)
 
   /* Preserve the match data.  */
   record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
-  
+
   /* Value saved here is to be restored into Vautoload_queue.  */
   record_unwind_protect (un_autoload, Vautoload_queue);
   Vautoload_queue = Qt;
@@ -1945,7 +1977,7 @@ do_autoload (fundef, funname)
   queue = Vautoload_queue;
   while (CONSP (queue))
     {
-      first = Fcar (queue);
+      first = XCAR (queue);
       second = Fcdr (first);
       first = Fcar (first);
 
@@ -1953,9 +1985,9 @@ do_autoload (fundef, funname)
         may be an atom if the autoload entry was generated by a defalias
         or fset.  */
       if (CONSP (second))
-       Fput (first, Qautoload, (Fcdr (second)));
+       Fput (first, Qautoload, (XCDR (second)));
 
-      queue = Fcdr (queue);
+      queue = XCDR (queue);
     }
 
   /* Once loading finishes, don't undo it.  */
@@ -1983,7 +2015,7 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0,
 
   if (handling_signal)
     abort ();
-  
+
   if (SYMBOLP (form))
     return Fsymbol_value (form);
   if (!CONSP (form))
@@ -2162,9 +2194,6 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0,
     val = call_debugger (Fcons (Qexit, Fcons (val, Qnil)));
   backtrace_list = backtrace.next;
 
-#ifdef HAVE_CARBON
-  mac_check_for_quit_char();
-#endif  
   return val;
 }
 \f
@@ -2187,7 +2216,7 @@ usage: (apply FUNCTION &rest ARGUMENTS)  */)
   funcall_args = 0;
   spread_arg = args [nargs - 1];
   CHECK_LIST (spread_arg);
-  
+
   numargs = XINT (Flength (spread_arg));
 
   if (numargs == 0)
@@ -2246,6 +2275,7 @@ usage: (apply FUNCTION &rest ARGUMENTS)  */)
       spread_arg = XCDR (spread_arg);
     }
 
+  /* By convention, the caller needs to gcpro Ffuncall's args.  */
   RETURN_UNGCPRO (Ffuncall (gcpro1.nvars, funcall_args));
 }
 \f
@@ -2282,7 +2312,7 @@ usage: (run-hooks &rest HOOKS)  */)
 
   return Qnil;
 }
-      
+
 DEFUN ("run-hook-with-args", Frun_hook_with_args,
        Srun_hook_with_args, 1, MANY, 0,
        doc: /* Run HOOK with the specified arguments ARGS.
@@ -2525,7 +2555,7 @@ call1 (fn, arg1)
 {
   struct gcpro gcpro1;
 #ifdef NO_ARG_ARRAY
-  Lisp_Object args[2];  
+  Lisp_Object args[2];
 
   args[0] = fn;
   args[1] = arg1;
@@ -2659,6 +2689,8 @@ call6 (fn, arg1, arg2, arg3, arg4, arg5, arg6)
 #endif /* not NO_ARG_ARRAY */
 }
 
+/* The caller should GCPRO all the elements of ARGS.  */
+
 DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0,
        doc: /* Call first argument as a function, passing remaining arguments to it.
 Return the value that function returns.
@@ -2781,7 +2813,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS)  */)
        default:
 
          /* If a subr takes more than 8 arguments without using MANY
-            or UNEVALLED, we need to extend this function to support it. 
+            or UNEVALLED, we need to extend this function to support it.
             Until this is done, there is no way to call the function.  */
          abort ();
        }
@@ -2889,11 +2921,11 @@ funcall_lambda (fun, nargs, arg_vector)
   for (; CONSP (syms_left); syms_left = XCDR (syms_left))
     {
       QUIT;
-      
+
       next = XCAR (syms_left);
       while (!SYMBOLP (next))
        next = Fsignal (Qinvalid_function, Fcons (fun, Qnil));
-      
+
       if (EQ (next, Qand_rest))
        rest = 1;
       else if (EQ (next, Qand_optional))
@@ -2930,7 +2962,7 @@ funcall_lambda (fun, nargs, arg_vector)
                        AREF (fun, COMPILED_CONSTANTS),
                        AREF (fun, COMPILED_STACK_DEPTH));
     }
-  
+
   return unbind_to (count, val);
 }
 
@@ -3008,7 +3040,7 @@ specbind (symbol, value)
   else
     {
       Lisp_Object valcontents;
-      
+
       ovalue = find_symbol_value (symbol);
       specpdl_ptr->func = 0;
       specpdl_ptr->old_value = ovalue;
@@ -3022,7 +3054,7 @@ specbind (symbol, value)
          Lisp_Object where, current_buffer;
 
          current_buffer = Fcurrent_buffer ();
-         
+
          /* For a local variable, record both the symbol and which
             buffer's or frame's value we are saving.  */
          if (!NILP (Flocal_variable_p (symbol, Qnil)))
@@ -3088,14 +3120,17 @@ unbind_to (count, value)
 
   while (specpdl_ptr != specpdl + count)
     {
-      --specpdl_ptr;
-
-      if (specpdl_ptr->func != 0)
-       (*specpdl_ptr->func) (specpdl_ptr->old_value);
-      /* Note that a "binding" of nil is really an unwind protect,
-        so in that case the "old value" is a list of forms to evaluate.  */
-      else if (NILP (specpdl_ptr->symbol))
-       Fprogn (specpdl_ptr->old_value);
+      /* Copy the binding, and decrement specpdl_ptr, before we do
+        the work to unbind it.  We decrement first
+        so that an error in unbinding won't try to unbind
+        the same entry again, and we copy the binding first
+        in case more bindings are made during some of the code we run.  */
+
+      struct specbinding this_binding;
+      this_binding = *--specpdl_ptr;
+
+      if (this_binding.func != 0)
+       (*this_binding.func) (this_binding.old_value);
       /* If the symbol is a list, it is really (SYMBOL WHERE
         . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
         frame.  If WHERE is a buffer or frame, this indicates we
@@ -3103,32 +3138,32 @@ unbind_to (count, value)
         binding.  WHERE nil means that the variable had the default
         value when it was bound.  CURRENT-BUFFER is the buffer that
          was current when the variable was bound.  */
-      else if (CONSP (specpdl_ptr->symbol))
+      else if (CONSP (this_binding.symbol))
        {
          Lisp_Object symbol, where;
 
-         symbol = XCAR (specpdl_ptr->symbol);
-         where = XCAR (XCDR (specpdl_ptr->symbol));
+         symbol = XCAR (this_binding.symbol);
+         where = XCAR (XCDR (this_binding.symbol));
 
          if (NILP (where))
-           Fset_default (symbol, specpdl_ptr->old_value);
+           Fset_default (symbol, this_binding.old_value);
          else if (BUFFERP (where))
-           set_internal (symbol, specpdl_ptr->old_value, XBUFFER (where), 1);
-         else 
-           set_internal (symbol, specpdl_ptr->old_value, NULL, 1);
+           set_internal (symbol, this_binding.old_value, XBUFFER (where), 1);
+         else
+           set_internal (symbol, this_binding.old_value, NULL, 1);
        }
       else
        {
          /* If variable has a trivial value (no forwarding), we can
             just set it.  No need to check for constant symbols here,
             since that was already done by specbind.  */
-         if (!MISCP (SYMBOL_VALUE (specpdl_ptr->symbol)))
-           SET_SYMBOL_VALUE (specpdl_ptr->symbol, specpdl_ptr->old_value);
+         if (!MISCP (SYMBOL_VALUE (this_binding.symbol)))
+           SET_SYMBOL_VALUE (this_binding.symbol, this_binding.old_value);
          else
-           set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1);
+           set_internal (this_binding.symbol, this_binding.old_value, 0, 1);
        }
     }
-  
+
   if (NILP (Vquit_flag) && quitf)
     Vquit_flag = Qt;
 
@@ -3255,6 +3290,25 @@ If NFRAMES is more than the number of frames, the value is nil.  */)
 }
 
 \f
+void
+mark_backtrace ()
+{
+  register struct backtrace *backlist;
+  register int i;
+
+  for (backlist = backtrace_list; backlist; backlist = backlist->next)
+    {
+      mark_object (*backlist->function);
+
+      if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
+       i = 0;
+      else
+       i = backlist->nargs - 1;
+      for (; i >= 0; i--)
+       mark_object (backlist->args[i]);
+    }
+}
+
 void
 syms_of_eval ()
 {
@@ -3277,7 +3331,11 @@ Emacs could overflow the real C stack, and crash.  */);
 
   DEFVAR_LISP ("quit-flag", &Vquit_flag,
               doc: /* Non-nil causes `eval' to abort, unless `inhibit-quit' is non-nil.
-Typing C-g sets `quit-flag' non-nil, regardless of `inhibit-quit'.  */);
+If the value is t, that means do an ordinary quit.
+If the value equals `throw-on-input', that means quit by throwing
+to the tag specified in `throw-on-input'; it's for handling `while-no-input'.
+Typing C-g sets `quit-flag' to t, regardless of `inhibit-quit',
+but `inhibit-quit' non-nil prevents anything from taking notice of that.  */);
   Vquit_flag = Qnil;
 
   DEFVAR_LISP ("inhibit-quit", &Vinhibit_quit,
@@ -3302,7 +3360,7 @@ before making `inhibit-quit' nil.  */);
 
   Qdeclare = intern ("declare");
   staticpro (&Qdeclare);
-  
+
   /* Note that the process handling also uses Qexit, but we don't want
      to staticpro it twice, so we just do it here.  */
   Qexit = intern ("exit");
@@ -3433,6 +3491,7 @@ The value the function returns is not used.  */);
   defsubr (&Scondition_case);
   defsubr (&Ssignal);
   defsubr (&Sinteractive_p);
+  defsubr (&Scalled_interactively_p);
   defsubr (&Scommandp);
   defsubr (&Sautoload);
   defsubr (&Seval);
@@ -3447,3 +3506,6 @@ The value the function returns is not used.  */);
   defsubr (&Sbacktrace);
   defsubr (&Sbacktrace_frame);
 }
+
+/* arch-tag: 014a07aa-33ab-4a8f-a3d2-ee8a4a9ff7fb
+   (do not change this comment) */