Annotation of GNUtools/emacs/lisp/debug.el, revision 1.1.1.1

1.1       root        1: ;; Debuggers and related commands for Emacs
                      2: ;; Copyright (C) 1985, 1986 Free Software Foundation, Inc.
                      3: 
                      4: ;; This file is part of GNU Emacs.
                      5: 
                      6: ;; GNU Emacs is free software; you can redistribute it and/or modify
                      7: ;; it under the terms of the GNU General Public License as published by
                      8: ;; the Free Software Foundation; either version 1, or (at your option)
                      9: ;; any later version.
                     10: 
                     11: ;; GNU Emacs is distributed in the hope that it will be useful,
                     12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: ;; GNU General Public License for more details.
                     15: 
                     16: ;; You should have received a copy of the GNU General Public License
                     17: ;; along with GNU Emacs; see the file COPYING.  If not, write to
                     18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
                     19: 
                     20: 
                     21: (setq debugger 'debug)
                     22: 
                     23: (defun debug (&rest debugger-args)
                     24:   "Enter debugger.  Returns if user says \"continue\".
                     25: Arguments are mainly for use when this is called
                     26:  from the internals of the evaluator.
                     27: You may call with no args, or you may
                     28:  pass nil as the first arg and any other args you like.
                     29:  In that case, the list of args after the first will 
                     30:  be printed into the backtrace buffer."
                     31:   (message "Entering debugger...")
                     32:   (let (debugger-value
                     33:        (debugger-match-data (match-data))
                     34:        (debug-on-error nil)
                     35:        (debug-on-quit nil)
                     36:        (debugger-buffer (let ((default-major-mode 'fundamental-mode))
                     37:                           (generate-new-buffer "*Backtrace*")))
                     38:        (debugger-old-buffer (current-buffer))
                     39:        (debugger-step-after-exit nil)
                     40:        ;; Don't keep reading from an executing kbd macro!
                     41:        (executing-macro nil)
                     42:        (cursor-in-echo-area nil))
                     43:     (unwind-protect
                     44:        (save-excursion
                     45:          (save-window-excursion
                     46:            (pop-to-buffer debugger-buffer)
                     47:            (erase-buffer)
                     48:            (let ((standard-output (current-buffer))
                     49:                  (print-escape-newlines t)
                     50:                  (print-length 50))
                     51:              (backtrace))
                     52:            (goto-char (point-min))
                     53:            (debugger-mode)
                     54:            (delete-region (point)
                     55:                           (progn
                     56:                             (forward-sexp 8)
                     57:                             (forward-line 1)
                     58:                             (point)))
                     59:            (cond ((memq (car debugger-args) '(lambda debug))
                     60:                   (insert "Entering:\n")
                     61:                   (if (eq (car debugger-args) 'debug)
                     62:                       (progn
                     63:                         (backtrace-debug 4 t)
                     64:                         (delete-char 1)
                     65:                         (insert ?*)
                     66:                         (beginning-of-line))))
                     67:                  ((eq (car debugger-args) 'exit)
                     68:                   (insert "Return value: ")
                     69:                   (setq debugger-value (nth 1 debugger-args))
                     70:                   (prin1 debugger-value (current-buffer))
                     71:                   (insert ?\n)
                     72:                   (delete-char 1)
                     73:                   (insert ? )
                     74:                   (beginning-of-line))
                     75:                  ((eq (car debugger-args) 'error)
                     76:                   (insert "Signalling: ")
                     77:                   (prin1 (nth 1 debugger-args) (current-buffer))
                     78:                   (insert ?\n))
                     79:                  ((eq (car debugger-args) t)
                     80:                   (insert "Beginning evaluation of function call form:\n"))
                     81:                  (t
                     82:                   (prin1 (if (eq (car debugger-args) 'nil)
                     83:                              (cdr debugger-args) debugger-args)
                     84:                          (current-buffer))
                     85:                   (insert ?\n)))
                     86:            (message "")
                     87:            (let ((inhibit-trace t)
                     88:                  (standard-output nil)
                     89:                  (buffer-read-only t))
                     90:              (message "")
                     91:              (recursive-edit))))
                     92:       ;; So that users do not try to execute debugger commands
                     93:       ;;  in an invalid context
                     94:       (kill-buffer debugger-buffer)
                     95:       (store-match-data debugger-match-data))
                     96:     (setq debug-on-next-call debugger-step-after-exit)
                     97:     debugger-value))
                     98: 
                     99: (defun debugger-step-through ()
                    100:   "Proceed, stepping through subexpressions of this expression.
                    101: Enter another debugger on next entry to eval, apply or funcall."
                    102:   (interactive)
                    103:   (setq debugger-step-after-exit t)
                    104:   (message "Proceding, will debug on next eval or call.")
                    105:   (exit-recursive-edit))
                    106: 
                    107: (defun debugger-continue ()
                    108:   "Continue, evaluating this expression without stopping."
                    109:   (interactive)
                    110:   (message "Continuing.")
                    111:   (exit-recursive-edit))
                    112: 
                    113: (defun debugger-return-value (val)
                    114:   "Continue, specifying value to return.
                    115: This is only useful when the value returned from the debugger
                    116: will be used, such as in a debug on exit from a frame."
                    117:   (interactive "XReturn value (evaluated): ")
                    118:   (setq debugger-value val)
                    119:   (princ "Returning " t)
                    120:   (prin1 debugger-value)
                    121:   (exit-recursive-edit))
                    122: 
                    123: (defun debugger-frame-number ()
                    124:   "Return number of frames in backtrace before the one point points at."
                    125:   (save-excursion
                    126:     (beginning-of-line)
                    127:     (let ((opoint (point))
                    128:          (count 0))
                    129:       (goto-char (point-min))
                    130:       (if (or (equal (buffer-substring (point) (+ (point) 6))
                    131:                     "Signal")
                    132:              (equal (buffer-substring (point) (+ (point) 6))
                    133:                     "Return"))
                    134:          (progn
                    135:            (search-forward ":")
                    136:            (forward-sexp 1)))
                    137:       (forward-line 1)
                    138:       (while (progn
                    139:               (forward-char 2)
                    140:               (if (= (following-char) ?\()
                    141:                   (forward-sexp 1)
                    142:                 (forward-sexp 2))
                    143:               (forward-line 1)
                    144:               (<= (point) opoint))
                    145:        (setq count (1+ count)))
                    146:       count)))
                    147: 
                    148: ;; Chosen empirically to account for all the frames
                    149: ;; that will exist when debugger-frame is called
                    150: ;; within the first one that appears in the backtrace buffer.
                    151: ;; Assumes debugger-frame is called from a key;
                    152: ;; will be wrong if it is called with Meta-x.
                    153: (defconst debugger-frame-offset 8 "")
                    154: 
                    155: (defun debugger-frame ()
                    156:   "Request entry to debugger when this frame exits.
                    157: Applies to the frame whose line point is on in the backtrace."
                    158:   (interactive)
                    159:   (beginning-of-line)
                    160:   (let ((level (debugger-frame-number)))
                    161:     (backtrace-debug (+ level debugger-frame-offset) t))
                    162:   (if (= (following-char) ? )
                    163:       (let ((buffer-read-only nil))
                    164:        (delete-char 1)
                    165:        (insert ?*)))
                    166:   (beginning-of-line))
                    167: 
                    168: (defun debugger-frame-clear ()
                    169:   "Do not enter to debugger when this frame exits.
                    170: Applies to the frame whose line point is on in the backtrace."
                    171:   (interactive)
                    172:   (beginning-of-line)
                    173:   (let ((level (debugger-frame-number)))
                    174:     (backtrace-debug (+ level debugger-frame-offset) nil))
                    175:   (if (= (following-char) ?*)
                    176:       (let ((buffer-read-only nil))
                    177:        (delete-char 1)
                    178:        (insert ? )))
                    179:   (beginning-of-line))
                    180: 
                    181: (defun debugger-eval-expression (exp)
                    182:   (interactive "xEval: ")
                    183:   (save-excursion
                    184:     (if (null (buffer-name debugger-old-buffer))
                    185:        ;; old buffer deleted
                    186:        (setq debugger-old-buffer (current-buffer)))
                    187:     (set-buffer debugger-old-buffer)
                    188:     (eval-expression exp)))
                    189: 
                    190: (defvar debugger-mode-map nil)
                    191: (if debugger-mode-map
                    192:     nil
                    193:   (let ((loop ? ))
                    194:     (setq debugger-mode-map (make-keymap))
                    195:     (suppress-keymap debugger-mode-map)
                    196:     (define-key debugger-mode-map "-" 'negative-argument)
                    197:     (define-key debugger-mode-map "b" 'debugger-frame)
                    198:     (define-key debugger-mode-map "c" 'debugger-continue)
                    199:     (define-key debugger-mode-map "r" 'debugger-return-value)
                    200:     (define-key debugger-mode-map "u" 'debugger-frame-clear)
                    201:     (define-key debugger-mode-map "d" 'debugger-step-through)
                    202:     (define-key debugger-mode-map "h" 'describe-mode)
                    203:     (define-key debugger-mode-map "q" 'top-level)
                    204:     (define-key debugger-mode-map "e" 'debugger-eval-expression)
                    205:     (define-key debugger-mode-map " " 'next-line)))
                    206: 
                    207: (put 'debugger-mode 'mode-class 'special)
                    208: 
                    209: (defun debugger-mode ()
                    210:   "Mode for backtrace buffers, selected in debugger.
                    211: \\{debugger-mode-map}
                    212: For the r command, when in debugger due to frame being exited,
                    213:     the value specified here will be used as the value of that frame.
                    214: 
                    215: Note lines starting with * are frames that will
                    216:  enter debugger when exited."
                    217:   (kill-all-local-variables)    
                    218:   (setq major-mode 'debugger-mode)
                    219:   (setq mode-name "Debugger")
                    220:   (setq truncate-lines t)
                    221:   (set-syntax-table emacs-lisp-mode-syntax-table)
                    222:   (use-local-map debugger-mode-map))
                    223: 
                    224: (defun debug-on-entry (function)
                    225:   "Request FUNCTION to invoke debugger each time it is called.
                    226: If the user continues, FUNCTION's execution proceeds.
                    227: Works by modifying the definition of FUNCTION,
                    228: which must be written in Lisp, not predefined.
                    229: Use `cancel-debug-on-entry' to cancel the effect of this command.
                    230: Redefining FUNCTION also does that."
                    231:   (interactive "aDebug on entry (to function): ")
                    232:   (let ((defn (symbol-function function)))
                    233:     (if (eq (car defn) 'macro)
                    234:        (fset function (cons 'macro (debug-on-entry-1 function (cdr defn) t)))
                    235:       (fset function (debug-on-entry-1 function defn t))))
                    236:   function)
                    237: 
                    238: (defun cancel-debug-on-entry (function)
                    239:   "Undoes effect of debug-on-entry on FUNCTION."
                    240:   (interactive "aCancel debug on entry (to function): ")
                    241:   (let ((defn (symbol-function function)))
                    242:     (if (eq (car defn) 'macro)
                    243:        (fset function
                    244:              (cons 'macro (debug-on-entry-1 function (cdr defn) nil)))
                    245:       (fset function (debug-on-entry-1 function defn nil))))
                    246:   function)
                    247: 
                    248: (defun debug-on-entry-1 (function defn flag)
                    249:   (or (eq (car defn) 'lambda)
                    250:       (error "%s not user-defined Lisp function." function))
                    251:   (let (tail prec)
                    252:     (if (stringp (car (nthcdr 2 defn)))
                    253:        (setq tail (nthcdr 3 defn)
                    254:              prec (list (car defn) (car (cdr defn)) (car (cdr (cdr defn)))))
                    255:       (setq tail (nthcdr 2 defn)
                    256:            prec (list (car defn) (car (cdr defn)))))
                    257:     (if (eq flag (equal (car tail) '(debug 'debug)))
                    258:        nil
                    259:       (if flag
                    260:          (nconc prec (cons '(debug 'debug) tail))
                    261:        (nconc prec (cdr tail))))))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.