Annotation of GNUtools/emacs/lisp/debug.el, revision 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.