Annotation of 43BSD/contrib/emacs/lisp/debug.el, revision 1.1

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