From xemacs-m  Tue Jun 17 22:15:49 1997
Received: from jagor.srce.hr (hniksic@jagor.srce.hr [161.53.2.130])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id WAA17172
	for <xemacs-beta@xemacs.org>; Tue, 17 Jun 1997 22:15:47 -0500 (CDT)
Received: (from hniksic@localhost)
          by jagor.srce.hr (8.8.5/8.8.4)
	  id FAA23538; Wed, 18 Jun 1997 05:15:46 +0200 (MET DST)
To: XEmacs Developers <xemacs-beta@xemacs.org>
Subject: [PATCH] `debug-ignored-errors': take two
X-Attribution: Hrv
X-Face: Mie8:rOV<\c/~z{s.X4A{!?vY7{drJ([U]0O=W/<W*SMo/Mv:58:*_y~ki>xDi&N7XG
        KV^$k0m3Oe/)'e%3=$PCR&3ITUXH,cK>]bci&<qQ>Ff%x_>1`T(+M2Gg/fgndU%k*ft
        [(7._6e0n-V%|%'[c|q:;}td$#INd+;?!-V=c8Pqf}3J
From: Hrvoje Niksic <hniksic@srce.hr>
Date: 18 Jun 1997 05:15:46 +0200
Message-ID: <kig9108ha8t.fsf@jagor.srce.hr>
Lines: 213
X-Mailer: Gnus v5.4.52/XEmacs 20.3(beta7)

After having spent a few months meditating over XEmacs C source, I
have decided to give this another try.  I think I now even understand
what the following patch does -- as much as any human can understand
Emacs, at any rate.  Jokes aside -- this implementation should be the
correct one.

It's fun to be able to set `debug-on-error' to t, and be able to live
peacefully! :-)

NOTES:

The patch to loaddefs.el simply puts in the expression copied from GNU
Emacs 19.34.  I'll tune that variable for XEmacs in the next release,
if the patch is accepted.

We should probably remove the old ChangeLog entry incorrectly claiming
that this patch has already been applied at 1997-04-23.

src/ChangeLog:
1997-06-17  Hrvoje Niksic  <hniksic@srce.hr>

	* eval.c (vars_of_eval): New variable Vdebug_ignored_errors.
	(skip_debugger): New function; use Vdebug_ignored_errors.
	(signal_call_debugger): Use it.

lisp/ChangeLog:
1997-06-18  Hrvoje Niksic  <hniksic@srce.hr>

	* prim/loaddefs.el (debug-ignored-errors): Initialize it.

--- src/eval.c.orig	Tue Jun 17 16:02:20 1997
+++ src/eval.c	Wed Jun 18 05:06:15 1997
@@ -148,6 +148,10 @@
    if an error is handled by the command loop's error handler.  */
 Lisp_Object Vdebug_on_error;
 
+/* List of conditions and regexps specifying error messages which
+   do not enter the debugger even if Vdebug_on_error says they should.  */
+Lisp_Object Vdebug_ignored_errors;
+
 /* List of conditions (non-nil atom means all) which cause a backtrace
    if any error is signalled.  */
 Lisp_Object Vstack_trace_on_signal;
@@ -468,6 +472,43 @@
   return 0;
 }
 
+
+/* Return 1 if an error with condition-symbols CONDITIONS,
+   and described by SIGNAL-DATA, should skip the debugger
+   according to debugger-ignore-errors.  */
+
+static int
+skip_debugger (Lisp_Object conditions, Lisp_Object data)
+{
+  Lisp_Object tail;
+  int first_string = 1;
+  Lisp_Object error_message;
+
+  for (tail = Vdebug_ignored_errors; CONSP (tail); tail = XCDR (tail))
+    {
+      if (STRINGP (XCAR (tail)))
+	{
+	  if (first_string)
+	    {
+	      error_message = Ferror_message_string (data);
+	      first_string = 0;
+	    }
+	  if (fast_lisp_string_match (XCAR (tail), error_message) >= 0)
+	    return 1;
+	}
+      else
+	{
+	  Lisp_Object contail;
+
+          for (contail = conditions; CONSP (contail); contail = XCDR (contail))
+            if (EQ (XCAR (tail), XCAR (contail)))
+	      return 1;
+	}
+    }
+
+  return 0;
+}
+
 /* Actually generate a backtrace on STREAM. */
 
 static Lisp_Object
@@ -515,12 +556,16 @@
   Lisp_Object val = Qunbound;
   Lisp_Object all_handlers = Vcondition_handlers;
   int speccount = specpdl_depth_counter;
+  int skip_debugger_for_error = 0;
   struct gcpro gcpro1;
   GCPRO1 (all_handlers);
 
   Vcondition_handlers = active_handlers;
 
-  if (!entering_debugger && !*stack_trace_displayed && !signal_vars_only 
+  skip_debugger_for_error = skip_debugger (conditions, Fcons (sig, data));
+
+  if (!entering_debugger && !*stack_trace_displayed && !signal_vars_only
+      && !skip_debugger_for_error
       && wants_debugger (Vstack_trace_on_error, conditions))
     {
       specbind (Qdebug_on_error, Qnil);
@@ -537,6 +582,7 @@
     }
       
   if (!entering_debugger && !*debugger_entered && !signal_vars_only
+      && !skip_debugger_for_error
       && (EQ (sig, Qquit)
 	  ? debug_on_quit
 	  : wants_debugger (Vdebug_on_error, conditions)))
@@ -5158,6 +5204,16 @@
 See also variable `stack-trace-on-error'.
 */ );
   Vstack_trace_on_signal = Qnil;
+
+  DEFVAR_LISP ("debug-ignored-errors", &Vdebug_ignored_errors /*
+*List of errors for which the debugger should not be called.
+Each element may be a condition-name or a regexp that matches error messages.
+If any element applies to a given error, that error skips the debugger
+and just returns to top level.
+This overrides the variable `debug-on-error'.
+It does not apply to errors handled by `condition-case'.
+*/ );
+  Vdebug_ignored_errors = Qnil;
 
   DEFVAR_LISP ("debug-on-error", &Vdebug_on_error /*
 *Non-nil means enter debugger if an unhandled error is signalled.
--- lisp/prim/loaddefs.el.orig	Tue Jun 17 16:46:48 1997
+++ lisp/prim/loaddefs.el	Tue Jun 17 16:46:56 1997
@@ -90,6 +90,73 @@
 		  ".lof" ".blg" ".bbl" ".glo" ".idx" ".lot" ".fmt"
 		  ".diff" ".oi"))))
 
+(setq debug-ignored-errors
+      (mapcar 'purecopy
+       '(beginning-of-line beginning-of-buffer end-of-line
+	 end-of-buffer end-of-file buffer-read-only
+	 "^Previous command was not a yank\\'"
+	 "^Minibuffer window is not active\\'"
+	 "^End of history; no next item\\'"
+	 "^Beginning of history; no preceding item\\'"
+	 "^No recursive edit is in progress\\'"
+	 "^Changes to be undone are outside visible portion of buffer\\'"
+	 "^No undo information in this buffer\\'"
+	 "^No further undo information\\'"
+	 "^Save not confirmed\\'"
+	 "^Recover-file cancelled\\.\\'"
+
+	 ;; comint
+	 "^Not at command line\\'"
+	 "^Empty input ring\\'"
+	 "^No history\\'"
+	 "^Not found\\'";; To common?
+	 "^Current buffer has no process\\'"
+
+	 ;; dabbrev
+	 "^No dynamic expansion for \".*\" found\\.\\'"
+	 "^No further dynamic expansions for \".*\" found\\.\\'"
+	 "^No further dynamic expansions for `.*' found\\'"
+
+	 ;; Completion
+	 "^To complete, the point must be after a symbol at least [0-9]* character long\\.\\'"
+	 "^The string \".*\" is too short to be saved as a completion\\.\\'"
+
+	 ;; Compile
+	 "^No more errors\\( yet\\|\\)\\'"
+
+	 ;; Gnus
+	 "^NNTP: Connection closed\\.\\'"
+
+	 ;; info
+	 "^Node has no Previous\\'"
+	 "^No \".*\" in index\\'"
+
+	 ;; imenu
+	 "^No items suitable for an index found in this buffer\\.\\'"
+	 "^The mode \".*\" does not take full advantage of imenu\\.el yet\\.\\'"
+
+	 ;; ispell
+	 "^No word found to check!\\'"
+
+	 ;; man
+
+	 ;; etags
+	 "^No tags table in use!  Use .* to select one\\.\\'"
+	 "^There is no default tag\\'"
+	 "^No previous tag locations\\'"
+	 "^File .* is not a valid tags table\\'"
+	 "^No \\(more \\|\\)tags \\(matching\\|containing\\) "
+	 "^Rerun etags: `.*' not found in "
+	 "^All files processed\\.\\'"
+	 "^No .* or .* in progress.\\'"
+	 "^File .* not in current tags tables\\'"
+	 "No tags table loaded."
+	 "^Nothing to complete\\'"
+
+	 ;; BBDB
+	 "^no previous record\\'"
+	 "^no next record\\'")))
+
 (make-variable-buffer-local 'indent-tabs-mode)
 
 


-- 
Hrvoje Niksic <hniksic@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
You'll notice that perl is not itself written in Perl.
                                                 -- The Perl FAQ

