From d2d23393cdbddf56f6a5211caf509a3c462eaea1 Mon Sep 17 00:00:00 2001 From: "Richard M. Stallman" Date: Thu, 21 May 1998 03:34:21 +0000 Subject: [PATCH] Support pdb. (pdb): New function. (gud-pdb-command-name): New variable. (pdb-minibuffer-local-map): Likewise. (gud-pdb-find-file): New function. (gud-pdb-marker-filter): New function. (gud-pdb-marker-regexp*): New variables. (gud-pdb-massage-args): New function. (gud-pdb-history): New variable. --- lisp/gud.el | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 135 insertions(+), 1 deletion(-) diff --git a/lisp/gud.el b/lisp/gud.el index a88fb98b65c..66cd552c7a8 100644 --- a/lisp/gud.el +++ b/lisp/gud.el @@ -47,7 +47,7 @@ (defgroup gud nil "Grand Unified Debugger mode for gdb and other debuggers under Emacs. -Supported debuggers include gdb, sdb, dbx, xdb, perldb, and jdb." +Supported debuggers include gdb, sdb, dbx, xdb, perldb, pdb (Python), and jdb." :group 'unix :group 'tools) @@ -1269,6 +1269,140 @@ and source-file directory for your debugger." ) ;; ====================================================================== +;; pdb (Python debugger) functions + +;;; History of argument lists passed to pdb. +(defvar gud-pdb-history nil) + +(defun gud-pdb-massage-args (file args) + args) + +;; Last group is for return value, e.g. "> test.py(2)foo()->None" +;; Either file or function name may be omitted: "> (0)?()" +(defvar gud-pdb-marker-regexp + "^> \\([-a-zA-Z0-9_/.]*\\|\\)(\\([0-9]+\\))\\([a-zA-Z0-9_]*\\|\\?\\)()\\(->[^\n]*\\)?\n") +(defvar gud-pdb-marker-regexp-file-group 1) +(defvar gud-pdb-marker-regexp-line-group 2) +(defvar gud-pdb-marker-regexp-fnname-group 3) + +(defvar gud-pdb-marker-regexp-start "^> ") + +;; There's no guarantee that Emacs will hand the filter the entire +;; marker at once; it could be broken up across several strings. We +;; might even receive a big chunk with several markers in it. If we +;; receive a chunk of text which looks like it might contain the +;; beginning of a marker, we save it here between calls to the +;; filter. +(defun gud-pdb-marker-filter (string) + (setq gud-marker-acc (concat gud-marker-acc string)) + (let ((output "")) + + ;; Process all the complete markers in this chunk. + (while (string-match gud-pdb-marker-regexp gud-marker-acc) + (setq + + ;; Extract the frame position from the marker. + gud-last-frame + (let ((file (match-string gud-pdb-marker-regexp-file-group + gud-marker-acc)) + (line (string-to-int + (match-string gud-pdb-marker-regexp-line-group + gud-marker-acc)))) + (if (string-equal file "") + gud-last-frame + (cons file line))) + + ;; Output everything instead of the below + output (concat output (substring gud-marker-acc 0 (match-end 0))) +;; ;; Append any text before the marker to the output we're going +;; ;; to return - we don't include the marker in this text. +;; output (concat output +;; (substring gud-marker-acc 0 (match-beginning 0))) + + ;; Set the accumulator to the remaining text. + gud-marker-acc (substring gud-marker-acc (match-end 0)))) + + ;; Does the remaining text look like it might end with the + ;; beginning of another marker? If it does, then keep it in + ;; gud-marker-acc until we receive the rest of it. Since we + ;; know the full marker regexp above failed, it's pretty simple to + ;; test for marker starts. + (if (string-match gud-pdb-marker-regexp-start gud-marker-acc) + (progn + ;; Everything before the potential marker start can be output. + (setq output (concat output (substring gud-marker-acc + 0 (match-beginning 0)))) + + ;; Everything after, we save, to combine with later input. + (setq gud-marker-acc + (substring gud-marker-acc (match-beginning 0)))) + + (setq output (concat output gud-marker-acc) + gud-marker-acc "")) + + output)) + +(defun gud-pdb-find-file (f) + (save-excursion + (let ((buf (find-file-noselect f))) + (set-buffer buf) + (gud-make-debug-menu) + ;; (local-set-key [menu-bar debug finish] '("Finish Function" . gud-finish)) + ;; (local-set-key [menu-bar debug up] '("Up Stack" . gud-up)) + ;; (local-set-key [menu-bar debug down] '("Down Stack" . gud-down)) + buf))) + +(defvar pdb-minibuffer-local-map nil + "Keymap for minibuffer prompting of pdb startup command.") +(if pdb-minibuffer-local-map + () + (setq pdb-minibuffer-local-map (copy-keymap minibuffer-local-map)) + (define-key + pdb-minibuffer-local-map "\C-i" 'comint-dynamic-complete-filename)) + +(defcustom gud-pdb-command-name "pdb" + "File name for executing the Python debugger. +This should be an executable on your path, or an absolute file name." + :type 'string + :group 'gud) + +;;;###autoload +(defun pdb (command-line) + "Run pdb on program FILE in buffer `*gud-FILE*'. +The directory containing FILE becomes the initial working directory +and source-file directory for your debugger." + (interactive + (list (read-from-minibuffer "Run pdb (like this): " + (if (consp gud-pdb-history) + (car gud-pdb-history) + (concat gud-pdb-command-name " ")) + pdb-minibuffer-local-map nil + '(gud-pdb-history . 1)))) + + (gud-common-init command-line 'gud-pdb-massage-args + 'gud-pdb-marker-filter 'gud-pdb-find-file) + + (gud-def gud-break "break %l" "\C-b" "Set breakpoint at current line.") + (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line") + (gud-def gud-step "step" "\C-s" "Step one source line with display.") + (gud-def gud-next "next" "\C-n" "Step one line (skip functions).") + (gud-def gud-cont "continue" "\C-r" "Continue with display.") + (gud-def gud-finish "return" "\C-f" "Finish executing current function.") + (gud-def gud-up "up" "<" "Up one stack frame.") + (gud-def gud-down "down" ">" "Down one stack frame.") + (gud-def gud-print "p %e" "\C-p" "Evaluate Python expression at point.") + ;; Is this right? + (gud-def gud-statement "! %e" "\C-e" "Execute Python statement at point.") + + (local-set-key [menu-bar debug finish] '("Finish Function" . gud-finish)) + (local-set-key [menu-bar debug up] '("Up Stack" . gud-up)) + (local-set-key [menu-bar debug down] '("Down Stack" . gud-down)) + ;; (setq comint-prompt-regexp "^(.*pdb[+]?) *") + (setq comint-prompt-regexp "^(Pdb) *") + (setq paragraph-start comint-prompt-regexp) + (run-hooks 'pdb-mode-hook)) + +;; ====================================================================== ;; ;; JDB support. ;; -- 2.39.2