]> code.delx.au - gnu-emacs/blobdiff - src/eval.c
Merge from emacs--rel--22
[gnu-emacs] / src / eval.c
index 0993767b9e34f7cff7f51bf6a80ae0316a9b8179..b69eea44c75c2ecb7d23c9a4f2fa8f03a0be8be4 100644 (file)
@@ -202,6 +202,8 @@ Lisp_Object Vmacro_declaration_function;
 
 extern Lisp_Object Qrisky_local_variable;
 
+extern Lisp_Object Qfunction;
+
 static Lisp_Object funcall_lambda P_ ((Lisp_Object, int, Lisp_Object*));
 static void unwind_to_catch P_ ((struct catchtag *, Lisp_Object)) NO_RETURN;
 
@@ -221,7 +223,7 @@ init_eval_once ()
   specpdl_ptr = specpdl;
   /* Don't forget to update docs (lispref node "Local Variables").  */
   max_specpdl_size = 1000;
-  max_lisp_eval_depth = 300;
+  max_lisp_eval_depth = 400;
 
   Vrun_hooks = Qnil;
 }
@@ -539,7 +541,7 @@ usage: (setq [SYM VAL]...)  */)
   register Lisp_Object val, sym;
   struct gcpro gcpro1;
 
-  if (NILP(args))
+  if (NILP (args))
     return Qnil;
 
   args_left = args;
@@ -564,6 +566,8 @@ usage: (quote ARG)  */)
      (args)
      Lisp_Object args;
 {
+  if (!NILP (Fcdr (args)))
+    xsignal2 (Qwrong_number_of_arguments, Qquote, Flength (args));
   return Fcar (args);
 }
 
@@ -575,6 +579,8 @@ usage: (function ARG)  */)
      (args)
      Lisp_Object args;
 {
+  if (!NILP (Fcdr (args)))
+    xsignal2 (Qwrong_number_of_arguments, Qfunction, Flength (args));
   return Fcar (args);
 }
 
@@ -1274,7 +1280,11 @@ unwind_to_catch (catch, value)
 #if HAVE_X_WINDOWS
   /* If x_catch_errors was done, turn it off now.
      (First we give unbind_to a chance to do that.)  */
+#if 0 /* This would disable x_catch_errors after x_connection_closed.
+       * The catch must remain in effect during that delicate
+       * state. --lorentey  */
   x_fully_uncatch_errors ();
+#endif
 #endif
 
   byte_stack_list = catch->byte_stack;
@@ -1345,14 +1355,15 @@ if CONDITION-NAME is one of the error's condition names.
 If an error happens, the first applicable handler is run.
 
 The car of a handler may be a list of condition names
-instead of a single condition name.
+instead of a single condition name.  Then it handles all of them.
 
-When a handler handles an error,
-control returns to the condition-case and the handler BODY... is executed
-with VAR bound to (SIGNALED-CONDITIONS . SIGNAL-DATA).
-VAR may be nil; then you do not get access to the signal information.
+When a handler handles an error, control returns to the `condition-case'
+and it executes the handler's BODY...
+with VAR bound to (SIGNALED-CONDITIONS . SIGNAL-DATA) from the error.
+(If VAR is nil, the handler can't access that information.)
+Then the value of the last BODY form is returned from the `condition-case'
+expression.
 
-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 &rest HANDLERS)  */)
      (args)
@@ -1586,8 +1597,7 @@ internal_condition_case_2 (bfun, nargs, args, handlers, hfun)
 
 \f
 static Lisp_Object find_handler_clause P_ ((Lisp_Object, Lisp_Object,
-                                           Lisp_Object, Lisp_Object,
-                                           Lisp_Object *));
+                                           Lisp_Object, Lisp_Object));
 
 DEFUN ("signal", Fsignal, Ssignal, 2, 2, 0,
        doc: /* Signal an error.  Args are ERROR-SYMBOL and associated DATA.
@@ -1613,7 +1623,6 @@ See also the function `condition-case'.  */)
   Lisp_Object conditions;
   extern int gc_in_progress;
   extern int waiting_for_input;
-  Lisp_Object debugger_value;
   Lisp_Object string;
   Lisp_Object real_error_symbol;
   struct backtrace *bp;
@@ -1671,7 +1680,7 @@ See also the function `condition-case'.  */)
       register Lisp_Object clause;
 
       clause = find_handler_clause (handlerlist->handler, conditions,
-                                   error_symbol, data, &debugger_value);
+                                   error_symbol, data);
 
       if (EQ (clause, Qlambda))
        {
@@ -1702,7 +1711,7 @@ See also the function `condition-case'.  */)
   handlerlist = allhandlers;
   /* If no handler is present now, try to run the debugger,
      and if that fails, throw to top level.  */
-  find_handler_clause (Qerror, conditions, error_symbol, data, &debugger_value);
+  find_handler_clause (Qerror, conditions, error_symbol, data);
   if (catchlist != 0)
     Fthrow (Qtop_level, Qt);
 
@@ -1785,7 +1794,7 @@ signal_error (s, arg)
 }
 
 
-/* Return nonzero iff LIST is a non-nil atom or
+/* Return nonzero if LIST is a non-nil atom or
    a list containing one of CONDITIONS.  */
 
 static int
@@ -1854,75 +1863,54 @@ skip_debugger (conditions, data)
     = SIG is nil, and DATA is (SYMBOL . REST-OF-DATA).
        This is for memory-full errors only.
 
-   Store value returned from debugger into *DEBUGGER_VALUE_PTR.
-
    We need to increase max_specpdl_size temporarily around
    anything we do that can push on the specpdl, so as not to get
    a second error here in case we're handling specpdl overflow.  */
 
 static Lisp_Object
-find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
+find_handler_clause (handlers, conditions, sig, data)
      Lisp_Object handlers, conditions, sig, data;
-     Lisp_Object *debugger_value_ptr;
 {
   register Lisp_Object h;
   register Lisp_Object tem;
+  int debugger_called = 0;
+  int debugger_considered = 0;
 
-  if (EQ (handlers, Qt))  /* t is used by handlers for all conditions, set up by C code.  */
+  /* t is used by handlers for all conditions, set up by C code.  */
+  if (EQ (handlers, Qt))
     return Qt;
+
+  /* Don't run the debugger for a memory-full error.
+     (There is no room in memory to do that!)  */
+  if (NILP (sig))
+    debugger_considered = 1;
+
   /* error is used similarly, but means print an error message
      and run the debugger if that is enabled.  */
   if (EQ (handlers, Qerror)
       || !NILP (Vdebug_on_signal)) /* This says call debugger even if
                                      there is a handler.  */
     {
-      int debugger_called = 0;
-      Lisp_Object sig_symbol, combined_data;
-      /* This is set to 1 if we are handling a memory-full error,
-        because these must not run the debugger.
-        (There is no room in memory to do that!)  */
-      int no_debugger = 0;
-
-      if (NILP (sig))
-       {
-         combined_data = data;
-         sig_symbol = Fcar (data);
-         no_debugger = 1;
-       }
-      else
-       {
-         combined_data = Fcons (sig, data);
-         sig_symbol = sig;
-       }
-
-      if (wants_debugger (Vstack_trace_on_error, conditions))
+      if (!NILP (sig) && wants_debugger (Vstack_trace_on_error, conditions))
        {
          max_specpdl_size++;
-#ifdef PROTOTYPES
+    #ifdef PROTOTYPES
          internal_with_output_to_temp_buffer ("*Backtrace*",
                                               (Lisp_Object (*) (Lisp_Object)) Fbacktrace,
                                               Qnil);
-#else
+    #else
          internal_with_output_to_temp_buffer ("*Backtrace*",
                                               Fbacktrace, Qnil);
-#endif
+    #endif
          max_specpdl_size--;
        }
-      if (! no_debugger
-         /* Don't try to run the debugger with interrupts blocked.
-            The editing loop would return anyway.  */
-         && ! INPUT_BLOCKED_P
-         && (EQ (sig_symbol, Qquit)
-             ? debug_on_quit
-             : wants_debugger (Vdebug_on_error, conditions))
-         && ! skip_debugger (conditions, combined_data)
-         && when_entered_debugger < num_nonmacro_input_events)
+
+      if (!debugger_considered)
        {
-         *debugger_value_ptr
-           = call_debugger (Fcons (Qerror,
-                                   Fcons (combined_data, Qnil)));
-         debugger_called = 1;
+         debugger_considered = 1;
+         debugger_called = maybe_call_debugger (conditions, sig, data);
        }
+
       /* If there is no handler, return saying whether we ran the debugger.  */
       if (EQ (handlers, Qerror))
        {
@@ -1931,6 +1919,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
          return Qt;
        }
     }
+
   for (h = handlers; CONSP (h); h = Fcdr (h))
     {
       Lisp_Object handler, condit;
@@ -1949,18 +1938,55 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
       /* Handle a list of condition names in handler HANDLER.  */
       else if (CONSP (condit))
        {
-         while (CONSP (condit))
+         Lisp_Object tail;
+         for (tail = condit; CONSP (tail); tail = XCDR (tail))
            {
-             tem = Fmemq (Fcar (condit), conditions);
+             tem = Fmemq (Fcar (tail), conditions);
              if (!NILP (tem))
-               return handler;
-             condit = XCDR (condit);
+               {
+                 /* This handler is going to apply.
+                    Does it allow the debugger to run first?  */
+                 if (! debugger_considered && !NILP (Fmemq (Qdebug, condit)))
+                   maybe_call_debugger (conditions, sig, data);
+                 return handler;
+               }
            }
        }
     }
+
   return Qnil;
 }
 
+/* Call the debugger if calling it is currently enabled for CONDITIONS.
+   SIG and DATA describe the signal, as in find_handler_clause.  */
+
+int
+maybe_call_debugger (conditions, sig, data)
+     Lisp_Object conditions, sig, data;
+{
+  Lisp_Object combined_data;
+
+  combined_data = Fcons (sig, data);
+
+  if (
+      /* Don't try to run the debugger with interrupts blocked.
+        The editing loop would return anyway.  */
+      ! INPUT_BLOCKED_P
+      /* Does user wants to enter debugger for this kind of error?  */
+      && (EQ (sig, Qquit)
+         ? debug_on_quit
+         : wants_debugger (Vdebug_on_error, conditions))
+      && ! skip_debugger (conditions, combined_data)
+      /* rms: what's this for? */
+      && when_entered_debugger < num_nonmacro_input_events)
+    {
+      call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil)));
+      return 1;
+    }
+
+  return 0;
+}
+
 /* dump an error message; called like printf */
 
 /* VARARGS 1 */
@@ -2025,42 +2051,49 @@ then strings and vectors are not accepted.  */)
 {
   register Lisp_Object fun;
   register Lisp_Object funcar;
+  Lisp_Object if_prop = Qnil;
 
   fun = function;
 
-  fun = indirect_function (fun);
-  if (EQ (fun, Qunbound))
+  fun = indirect_function (fun); /* Check cycles. */
+  if (NILP (fun) || EQ (fun, Qunbound))
     return Qnil;
 
+  /* Check an `interactive-form' property if present, analogous to the
+     function-documentation property. */
+  fun = function;
+  while (SYMBOLP (fun))
+    {
+      Lisp_Object tmp = Fget (fun, intern ("interactive-form"));
+      if (!NILP (tmp))
+       if_prop = Qt;
+      fun = Fsymbol_function (fun);
+    }
+
   /* Emacs primitives are interactive if their DEFUN specifies an
      interactive spec.  */
   if (SUBRP (fun))
-    {
-      if (XSUBR (fun)->prompt)
-       return Qt;
-      else
-       return Qnil;
-    }
+    return XSUBR (fun)->intspec ? Qt : if_prop;
 
   /* Bytecode objects are interactive if they are long enough to
      have an element whose index is COMPILED_INTERACTIVE, which is
      where the interactive spec is stored.  */
   else if (COMPILEDP (fun))
     return ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE
-           ? Qt : Qnil);
+           ? Qt : if_prop);
 
   /* Strings and vectors are keyboard macros.  */
-  if (NILP (for_call_interactively) && (STRINGP (fun) || VECTORP (fun)))
-    return Qt;
+  if (STRINGP (fun) || VECTORP (fun))
+    return (NILP (for_call_interactively) ? Qt : Qnil);
 
   /* Lists may represent commands.  */
   if (!CONSP (fun))
     return Qnil;
   funcar = XCAR (fun);
   if (EQ (funcar, Qlambda))
-    return Fassq (Qinteractive, Fcdr (XCDR (fun)));
+    return !NILP (Fassq (Qinteractive, Fcdr (XCDR (fun)))) ? Qt : if_prop;
   if (EQ (funcar, Qautoload))
-    return Fcar (Fcdr (Fcdr (XCDR (fun))));
+    return !NILP (Fcar (Fcdr (Fcdr (XCDR (fun))))) ? Qt : if_prop;
   else
     return Qnil;
 }
@@ -2145,7 +2178,7 @@ do_autoload (fundef, funname)
      Lisp_Object fundef, funname;
 {
   int count = SPECPDL_INDEX ();
-  Lisp_Object fun, queue, first, second;
+  Lisp_Object fun;
   struct gcpro gcpro1, gcpro2, gcpro3;
 
   /* This is to make sure that loadup.el gives a clear picture
@@ -2164,21 +2197,7 @@ do_autoload (fundef, funname)
   /* Value saved here is to be restored into Vautoload_queue.  */
   record_unwind_protect (un_autoload, Vautoload_queue);
   Vautoload_queue = Qt;
-  Fload (Fcar (Fcdr (fundef)), Qnil, noninteractive ? Qt : Qnil, Qnil, Qt);
-
-  /* Save the old autoloads, in case we ever do an unload.  */
-  queue = Vautoload_queue;
-  while (CONSP (queue))
-    {
-      first = XCAR (queue);
-      second = Fcdr (first);
-      first = Fcar (first);
-
-      if (SYMBOLP (first) && CONSP (second) && EQ (XCAR (second), Qautoload))
-       Fput (first, Qautoload, (XCDR (second)));
-
-      queue = XCDR (queue);
-    }
+  Fload (Fcar (Fcdr (fundef)), Qnil, Qt, Qnil, Qt);
 
   /* Once loading finishes, don't undo it.  */
   Vautoload_queue = Qt;