]> code.delx.au - gnu-emacs-elpa/commitdiff
Add stock Python debugger.
authorrocky <rocky@gnu.org>
Sat, 12 May 2012 21:20:01 +0000 (17:20 -0400)
committerrocky <rocky@gnu.org>
Sat, 12 May 2012 21:20:01 +0000 (17:20 -0400)
17 files changed:
.gitignore
README.textile
configure.ac
dbgr.el
dbgr/debugger/Makefile.am
dbgr/debugger/pdb/.gitignore [new file with mode: 0644]
dbgr/debugger/pdb/Makefile.am [new file with mode: 0644]
dbgr/debugger/pdb/core.el [new file with mode: 0644]
dbgr/debugger/pdb/init.el [new file with mode: 0644]
dbgr/debugger/pdb/pdb.el [new file with mode: 0644]
dbgr/debugger/pdb/track-mode.el [new file with mode: 0644]
dbgr/debugger/pydbgr/init.el
dbgr/debugger/pydbgr/pydbgr.el
test/test-bt-pdb.el [new file with mode: 0644]
test/test-pdb.el [new file with mode: 0644]
test/test-regexp-pdb.el [new file with mode: 0644]
test/test-regexp-trepan.el

index 6693f715cbad51f667a5d5e858a44ec6be099812..bf3e1dac905a3ada0d99b7e5a6bfebc882f4a3c5 100644 (file)
@@ -1,6 +1,7 @@
-/*.elc
+*.elc
+*~
+elc-stamp
 /*.tar.gz
-/*~
 /COPYING
 /Makefile
 /Makefile.in
@@ -14,3 +15,4 @@
 /elc-temp
 /install-sh
 /missing
+script
index 9f7fe46573183770be02ae1f179d7b40395a70d5..785a3c65cdde4b6a2bbbc72276302dbf497e3569 100644 (file)
@@ -9,6 +9,7 @@ Debuggers we currently support are:
  * "kshdb":https://github.com/rocky/kshdb/wiki (Korn Shell)
  * perldb (Perl)
  * "Devel::Trepan":https://github.com/rocky/Perl-Devel-Trepan/wiki (Perl)
+ * pdb (Stock C Python debugger)
  * "pydb":http://bashdb.sourceforge.net/pydb/ (Python)
  * "pydbgr":http://code.google.com/p/pydbgr/ (Python)
  * "trepanning":https://github.com/rocky/rb-trepanning/wiki (Ruby 1.9)
index 3facf29a0794fbd89f298f44640f37d0fe393fbf..14ea4f9fbf60139c9aee4c4b1ab3de3896789c5d 100644 (file)
@@ -38,6 +38,7 @@ AC_CONFIG_FILES([Makefile \
                 dbgr/debugger/gdb/Makefile \
                 dbgr/debugger/kshdb/Makefile \
                 dbgr/debugger/perldb/Makefile \
+                dbgr/debugger/pdb/Makefile \
                 dbgr/debugger/pydbgr/Makefile \
                 dbgr/debugger/rdebug/Makefile \
                 dbgr/debugger/remake/Makefile \
diff --git a/dbgr.el b/dbgr.el
index 40870319624558ae220ba17827f57408af9590b2..9f435b970f9a94a8937c9d150294945562b452ac 100644 (file)
--- a/dbgr.el
+++ b/dbgr.el
@@ -16,6 +16,7 @@
      "./dbgr/debugger/bashdb/bashdb"
      "./dbgr/debugger/gdb/gdb"
      "./dbgr/debugger/kshdb/kshdb"
+     "./dbgr/debugger/pdb/pdb"
      "./dbgr/debugger/pydbgr/pydbgr"
      "./dbgr/debugger/perldb/perldb"
      "./dbgr/debugger/rdebug/rdebug"
index 8397e5c70745efb8e824d8821b7cd35796a48d28..ac512f8cd3e00048d0ae20e681f63b2d23c36d16 100644 (file)
@@ -1,4 +1,4 @@
-SUBDIRS = bashdb gdb kshdb perldb pydbgr rdebug remake \
+SUBDIRS = bashdb gdb kshdb pdb perldb pydbgr rdebug remake \
        trepan trepan.pl trepanx trepan8 zshdb
 EXTRA_DIST = common.mk
 
diff --git a/dbgr/debugger/pdb/.gitignore b/dbgr/debugger/pdb/.gitignore
new file mode 100644 (file)
index 0000000..0e2662c
--- /dev/null
@@ -0,0 +1,3 @@
+/Makefile
+/Makefile.in
+/core.elc
diff --git a/dbgr/debugger/pdb/Makefile.am b/dbgr/debugger/pdb/Makefile.am
new file mode 100644 (file)
index 0000000..23f8a8f
--- /dev/null
@@ -0,0 +1 @@
+include ../common.mk
diff --git a/dbgr/debugger/pdb/core.el b/dbgr/debugger/pdb/core.el
new file mode 100644 (file)
index 0000000..3c2afd7
--- /dev/null
@@ -0,0 +1,153 @@
+;;; Copyright (C) 2012 Rocky Bernstein <rocky@gnu.org>
+(eval-when-compile (require 'cl))
+  
+(require 'load-relative)
+(require-relative-list '("../../common/track" 
+                        "../../common/core" 
+                        "../../common/lang")
+                      "dbgr-")
+(require-relative-list '("init") "dbgr-pdb-")
+
+
+;; FIXME: I think the following could be generalized and moved to 
+;; dbgr-... probably via a macro.
+(defvar pdb-minibuffer-history nil
+  "minibuffer history list for the command `pdb'.")
+
+(easy-mmode-defmap pdb-minibuffer-local-map
+  '(("\C-i" . comint-dynamic-complete-filename))
+  "Keymap for minibuffer prompting of gud startup command."
+  :inherit minibuffer-local-map)
+
+;; FIXME: I think this code and the keymaps and history
+;; variable chould be generalized, perhaps via a macro.
+(defun pdb-query-cmdline (&optional opt-debugger)
+  (dbgr-query-cmdline 
+   'pdb-suggest-invocation
+   pdb-minibuffer-local-map
+   'pdb-minibuffer-history
+   opt-debugger))
+
+(defun pdb-parse-cmd-args (orig-args)
+  "Parse command line ARGS for the annotate level and name of script to debug.
+
+ARGS should contain a tokenized list of the command line to run.
+
+We return the a list containing
+- the command processor (e.g. python) and it's arguments if any - a list of strings
+- the name of the debugger given (e.g. pdb) and its arguments - a list of strings
+- the script name and its arguments - list of strings
+- whether the annotate or emacs option was given ('-A', '--annotate' or '--emacs) - a boolean
+
+For example for the following input 
+  (map 'list 'symbol-name
+   '(python2.6 -O -Qold ./gcd.py a b))
+
+we might return:
+   ((python2.6 -O -Qold) (pdb) (./gcd.py a b) 't)
+
+NOTE: the above should have each item listed in quotes.
+"
+
+  ;; Parse the following kind of pattern:
+  ;;  [python python-options] pdb pdb-options script-name script-options
+  (let (
+       (args orig-args)
+       (pair)          ;; temp return from 
+       (python-opt-two-args '())
+       ;; Python doesn't have mandatory 2-arg options in our sense,
+       ;; since the two args can be run together, e.g. "-C/tmp" or "-C /tmp"
+       ;; 
+       (python-two-args '())
+       ;; pdb doesn't have any arguments
+       (pdb-two-args '())
+       (pdb-opt-two-args '())
+       (interp-regexp 
+        (if (member system-type (list 'windows-nt 'cygwin 'msdos))
+            "^python[-0-9.]*\\(.exe\\)?$"
+          "^python[-0-9.]*$"))
+
+       ;; Things returned
+       (annotate-p nil)
+       (debugger-args '())
+       (debugger-name nil)
+       (interpreter-args '())
+       (script-args '())
+       (script-name nil)
+       )
+
+    (if (not (and args))
+       ;; Got nothing: return '(nil, nil)
+       (list interpreter-args debugger-args script-args annotate-p)
+      ;; else
+      ;; Strip off optional "python" or "python182" etc.
+      (when (string-match interp-regexp
+                         (file-name-sans-extension
+                          (file-name-nondirectory (car args))))
+       (setq interpreter-args (list (pop args)))
+
+       ;; Strip off Python-specific options
+       (while (and args
+                   (string-match "^-" (car args)))
+         (setq pair (dbgr-parse-command-arg 
+                     args python-two-args python-opt-two-args))
+         (nconc interpreter-args (car pair))
+         (setq args (cadr pair))))
+
+      ;; Remove "pdb" from "pdb --pdb-options script
+      ;; --script-options"
+      (setq debugger-name (file-name-sans-extension
+                          (file-name-nondirectory (car args))))
+      (unless (string-match "^\\(pdb\\|cli.py\\)$" debugger-name)
+       (message 
+        "Expecting debugger name `%s' to be `pdb' or `cli.py'"
+        debugger-name))
+      (setq debugger-args (list (pop args)))
+
+      ;; Skip to the first non-option argument.
+      (while (and args (not script-name))
+       (let ((arg (car args)))
+         (cond
+          ;; Options with arguments.
+          ((string-match "^-" arg)
+           (setq pair (dbgr-parse-command-arg 
+                       args pdb-two-args pdb-opt-two-args))
+           (nconc debugger-args (car pair))
+           (setq args (cadr pair)))
+          ;; Anything else must be the script to debug.
+          (t (setq script-name arg)
+             (setq script-args args))
+          )))
+      (list interpreter-args debugger-args script-args annotate-p))))
+
+(defvar pdb-command-name) ; # To silence Warning: reference to free variable
+(defun pdb-suggest-invocation (debugger-name)
+  "Suggest a pdb command invocation via `dbgr-suggest-invocaton'"
+  (dbgr-suggest-invocation pdb-command-name pdb-minibuffer-history 
+                          "python" "\\.py"))
+
+(defun pdb-reset ()
+  "Pdb cleanup - remove debugger's internal buffers (frame,
+breakpoints, etc.)."
+  (interactive)
+  ;; (pdb-breakpoint-remove-all-icons)
+  (dolist (buffer (buffer-list))
+    (when (string-match "\\*pdb-[a-z]+\\*" (buffer-name buffer))
+      (let ((w (get-buffer-window buffer)))
+        (when w
+          (delete-window w)))
+      (kill-buffer buffer))))
+
+;; (defun pdb-reset-keymaps()
+;;   "This unbinds the special debugger keys of the source buffers."
+;;   (interactive)
+;;   (setcdr (assq 'pdb-debugger-support-minor-mode minor-mode-map-alist)
+;;       pdb-debugger-support-minor-mode-map-when-deactive))
+
+
+(defun pdb-customize ()
+  "Use `customize' to edit the settings of the `pdb' debugger."
+  (interactive)
+  (customize-group 'pdb))
+
+(provide-me "dbgr-pdb-")
diff --git a/dbgr/debugger/pdb/init.el b/dbgr/debugger/pdb/init.el
new file mode 100644 (file)
index 0000000..eaf3bf2
--- /dev/null
@@ -0,0 +1,99 @@
+;;; Copyright (C) 2012 Rocky Bernstein <rocky@gnu.org>
+;;; Stock Python debugger pdb 
+
+(eval-when-compile (require 'cl))
+
+(require 'load-relative)
+(require-relative-list '("../../common/regexp" 
+                        "../../common/loc" 
+                        "../../common/init")
+                      "dbgr-")
+(require-relative-list '("../../lang/python") "dbgr-lang-")
+
+(defvar dbgr-pat-hash)
+(declare-function make-dbgr-loc-pat (dbgr-loc))
+
+(defvar dbgr-pdb-pat-hash (make-hash-table :test 'equal)
+  "Hash key is the what kind of pattern we want to match:
+backtrace, prompt, etc.  The values of a hash entry is a
+dbgr-loc-pat struct")
+
+(declare-function make-dbgr-loc "dbgr-loc" (a b c d e f))
+
+;; Regular expression that describes a pdb location generally shown
+;; before a command prompt.
+;;
+;; Program-location lines look like this:
+;;   > /usr/bin/zonetab2pot.py(15)<module>()
+;; or MS Windows:
+;;   > c:\\mydirectory\\gcd.py(10)<module>
+(setf (gethash "loc" dbgr-pdb-pat-hash)
+      (make-dbgr-loc-pat
+       :regexp "^> \\(\\(?:[a-zA-Z]:\\)?[-a-zA-Z0-9_/.\\\\ ]+\\)(\\([0-9]+\\))"
+       :file-group 1
+       :line-group 2))
+
+(setf (gethash "prompt" dbgr-pdb-pat-hash)
+      (make-dbgr-loc-pat
+       :regexp   "^[(]+Pdb[)]+ "
+       ))
+
+;;  Regular expression that describes a Python backtrace line.
+(setf (gethash "lang-backtrace" dbgr-pdb-pat-hash) 
+      dbgr-python-backtrace-loc-pat)
+
+;;  Regular expression that describes a "breakpoint set" line. For example:
+;;     Breakpoint 1 at /usr/bin/pdb:7
+(setf (gethash "brkpt-set" dbgr-pdb-pat-hash)
+      (make-dbgr-loc-pat
+       :regexp "^Breakpoint \\([0-9]+\\) at[ \t\n]+\\(.+\\):\\([0-9]+\\)\\(\n\\|$\\)"
+       :num 1
+       :file-group 2
+       :line-group 3))
+
+;;  Regular expression that describes a "delete breakpoint" line
+(setf (gethash "brkpt-del" dbgr-pdb-pat-hash)
+      (make-dbgr-loc-pat
+       :regexp "^Deleted breakpoint \\([0-9]+\\)\n"
+       :num 1))
+
+(setf (gethash "font-lock-keywords" dbgr-pdb-pat-hash)
+      '(
+       ;; The frame number and first type name, if present.
+       ("^\\(->\\|##\\)\\([0-9]+\\) \\(<module>\\)? *\\([a-zA-Z_][a-zA-Z0-9_]*\\)(\\(.+\\))?"
+        (2 dbgr-backtrace-number-face)
+        (4 font-lock-function-name-face nil t))     ; t means optional.
+
+       ;; Parameter sequence, E.g. gcd(a=3, b=5)
+       ;;                             ^^^^^^^^^
+       ("(\\(.+\\))"
+        (1 font-lock-variable-name-face))
+
+       ;; File name. E.g  file '/test/gcd.py'
+       ;;                 ------^^^^^^^^^^^^-
+       ("[ \t]+file '\\([^ ]+*\\)'"
+        (1 dbgr-file-name-face))
+
+       ;; Line number. E.g. at line 28
+        ;;                  ---------^^
+       ("[ \t]+at line \\([0-9]+\\)$"
+        (1 dbgr-line-number-face))
+
+       ;; Function name.
+       ("\\<\\([a-zA-Z_][a-zA-Z0-9_]*\\)\\.\\([a-zA-Z_][a-zA-Z0-9_]*\\)"
+        (1 font-lock-type-face)
+        (2 font-lock-function-name-face))
+       ;; (pdb-frames-match-current-line
+       ;;  (0 pdb-frames-current-frame-face append))
+       ))
+
+(setf (gethash "pdb" dbgr-pat-hash) dbgr-pdb-pat-hash)
+
+(defvar dbgr-pdb-command-hash (make-hash-table :test 'equal)
+  "Hash key is command name like 'shell' and the value is 
+  the pdb command to use, like 'python'")
+
+(setf (gethash "shell" dbgr-pdb-command-hash) "python")
+(setf (gethash "pdb" dbgr-command-hash) dbgr-pdb-command-hash)
+
+(provide-me "dbgr-pdb-")
diff --git a/dbgr/debugger/pdb/pdb.el b/dbgr/debugger/pdb/pdb.el
new file mode 100644 (file)
index 0000000..d195a9f
--- /dev/null
@@ -0,0 +1,65 @@
+;;; Copyright (C) 2012 Rocky Bernstein <rocky@gnu.org>
+;;  `pdb' Main interface to pdb via Emacs
+(require 'load-relative)
+(require-relative-list '("../../common/helper"
+                        "../../common/track") "dbgr-")
+(require-relative-list '("core" "track-mode") "dbgr-pdb-")
+
+;; This is needed, or at least the docstring part of it is needed to
+;; get the customization menu to work in Emacs 23.
+(defgroup pdb nil
+  "The Python pdb debugger"
+  :group 'processes
+  :group 'dbgr
+  :group 'python
+  :version "23.1")
+
+;; -------------------------------------------------------------------
+;; User definable variables
+;;
+
+(defcustom pdb-command-name
+  "pdb"
+  "File name for executing the stock Python debugger and command options.
+This should be an executable on your path, or an absolute file name."
+  :type 'string
+  :group 'pdb)
+
+(declare-function pdb-track-mode (bool))
+
+;; -------------------------------------------------------------------
+;; The end.
+;;
+
+;;;###autoload
+(defun dbgr-pdb (&optional opt-command-line no-reset)
+  "Invoke the pdb Python debugger and start the Emacs user interface.
+
+String COMMAND-LINE specifies how to run pdb.
+
+Normally command buffers are reused when the same debugger is
+reinvoked inside a command buffer with a similar command. If we
+discover that the buffer has prior command-buffer information and
+NO-RESET is nil, then that information which may point into other
+buffers and source buffers which may contain marks and fringe or
+marginal icons is reset."
+
+  
+  (interactive)
+  (let* (
+        (cmd-str (or opt-command-line (pdb-query-cmdline 
+                                       "pdb")))
+        (cmd-args (split-string-and-unquote cmd-str))
+        (parsed-args (pdb-parse-cmd-args cmd-args))
+        (script-args (cdr cmd-args))
+        (script-name (car script-args))
+        (cmd-buf))
+    (dbgr-run-process "pdb" script-name cmd-args 
+                     'pdb-track-mode no-reset)
+    )
+  )
+
+
+(defalias 'pdb 'dbgr-pdb)
+
+(provide-me "dbgr-")
diff --git a/dbgr/debugger/pdb/track-mode.el b/dbgr/debugger/pdb/track-mode.el
new file mode 100644 (file)
index 0000000..516ee27
--- /dev/null
@@ -0,0 +1,50 @@
+;;; Copyright (C) 2010, 2012 Rocky Bernstein <rocky@gnu.org>
+;;; Python "pdb" Debugger tracking a comint
+;;; or eshell buffer.
+
+(eval-when-compile (require 'cl))
+(require 'load-relative)
+(require-relative-list '(
+                        "../../common/cmds" 
+                        "../../common/menu"
+                        "../../common/track"
+                        "../../common/track-mode"
+                        ) 
+                      "dbgr-")
+(require-relative-list '("core" "init") "dbgr-pdb-")
+
+(dbgr-track-mode-vars "pdb")
+
+(declare-function dbgr-track-mode(bool))
+
+(dbgr-python-populate-command-keys pdb-track-mode-map)
+
+(defun pdb-track-mode-hook()
+  (if pdb-track-mode
+      (progn
+       (use-local-map pdb-track-mode-map)
+       (message "using pdb mode map")
+       )
+    (message "pdb track-mode-hook disable called")
+    )
+)
+
+(define-minor-mode pdb-track-mode
+  "Minor mode for tracking ruby debugging inside a process shell."
+  :init-value nil
+  ;; :lighter " pdb"   ;; mode-line indicator from dbgr-track is sufficient.
+  ;; The minor mode bindings.
+  :global nil
+  :group 'pdb
+  :keymap pdb-track-mode-map
+  (dbgr-track-set-debugger "pdb")
+  (if pdb-track-mode
+      (progn 
+       (setq dbgr-track-mode 't)
+       (run-mode-hooks (intern (pdb-track-mode-hook))))
+    (progn 
+      (setq dbgr-track-mode nil)
+      ))
+)
+
+(provide-me "dbgr-pdb-")
index 20c6f6d8764f0d43ddc6f78cd821fac31e2c6050..0c169e76acc3b0f90d490fb1ba742566e45369a5 100644 (file)
@@ -1,5 +1,5 @@
-;;; Copyright (C) 2010, 2011 Rocky Bernstein <rocky@gnu.org>
-;;; pydbgr: Python 2.5 and beyond 
+;;; Copyright (C) 2010, 2011, 2012 Rocky Bernstein <rocky@gnu.org>
+;;; pydbgr: Python 2.5 but less than 3K
 
 (eval-when-compile (require 'cl))
 
@@ -23,12 +23,10 @@ dbgr-loc-pat struct")
 ;; Regular expression that describes a pydbgr location generally shown
 ;; before a command prompt.
 ;;
-;; Program-location lines look like this:
+;; For example:
 ;;   (/usr/bin/zonetab2pot.py:15): <module>
 ;; or MS Windows:
 ;;   (c:\\mydirectory\\gcd.py:10): <module>
-;;  and in backtrace like this:
-;;   (/usr/bin/zonetab2pot.py:15)
 (setf (gethash "loc" dbgr-pydbgr-pat-hash)
       (make-dbgr-loc-pat
        :regexp "^(\\(\\(?:[a-zA-Z]:\\)?[-a-zA-Z0-9_/.\\\\ ]+\\):\\([0-9]+\\))"
index c607cce74356bc2601adc58c194e0fd78c4e259a..be4015c649a7a11d62d0ecc3d4ea8c771c1d6b95 100644 (file)
@@ -1,4 +1,4 @@
-;;; Copyright (C) 2010, 2011 Rocky Bernstein <rocky@gnu.org>
+;;; Copyright (C) 2010, 2011, 2012 Rocky Bernstein <rocky@gnu.org>
 ;;  `pydbgr' Main interface to pydbgr via Emacs
 (require 'load-relative)
 (require-relative-list '("../../common/helper"
@@ -21,7 +21,7 @@
 (defcustom pydbgr-command-name
   ;;"pydbgr --emacs 3"
   "pydbgr"
-  "File name for executing the Ruby debugger and command options.
+  "File name for executing the Python debugger and command options.
 This should be an executable on your path, or an absolute file name."
   :type 'string
   :group 'pydbgr)
diff --git a/test/test-bt-pdb.el b/test/test-bt-pdb.el
new file mode 100644 (file)
index 0000000..794a576
--- /dev/null
@@ -0,0 +1,59 @@
+(require 'test-unit)
+(require 'font-lock)
+
+(load-file "../dbgr/common/buffer/command.el")
+(load-file "../dbgr/common/buffer/backtrace.el")
+(load-file "../dbgr/common/backtrace-mode.el")
+(load-file "../dbgr/common/init.el")
+(load-file "../dbgr/debugger/pdb/init.el")
+
+(test-unit-clear-contexts)
+
+(defun setup-bt(string temp-bt temp-cmdbuf)
+  (with-current-buffer temp-bt
+    (dbgr-backtrace-mode temp-cmdbuf)
+    (goto-char (point-min))
+    (setq buffer-read-only nil)
+    (insert string)
+    (font-lock-fontify-buffer)
+    (goto-char (point-min))
+    ))
+
+
+(context "dbgr-buffer-backtrace-pdb"
+        (tag dbgr-buf-bt-pdb)
+        (specify "fontify"
+                 (setq temp-cmdbuf (generate-new-buffer "*cmdbuf-test*"))
+                 (with-current-buffer temp-cmdbuf
+                   (dbgr-cmdbuf-init temp-cmdbuf "pdb" 
+                                     (gethash "pdb" dbgr-pat-hash))
+                   
+                   )
+                 (setq temp-bt (generate-new-buffer "*bt-test*"))
+                 (setup-bt 
+"->0 gcd(a=3, b=5) called from file '/test/gcd.py' at line 28
+##1 <module> execfile() file '/test/gcd.py' at line 41
+"
+                           temp-bt temp-cmdbuf)
+                 (with-current-buffer temp-bt
+                   (goto-char (point-min))
+                   (dolist (pair 
+                            '(
+                              ("->" .    dbgr-backtrace-number )
+                              ("gc"    . font-lock-function-name-face )
+                              ("("     . font-lock-variable-name-face )
+                              ("/test" . dbgr-file-name)
+                              ("2"     . dbgr-line-number)
+                              ("##"    . dbgr-backtrace-number)
+                              ("/test" . dbgr-file-name)
+                              ("4"     . dbgr-line-number)
+                              ))
+                     (search-forward (car pair))
+                     (assert-equal (cdr pair)
+                                   (get-text-property (point) 'face))
+                     )
+                   )
+                 )
+        )
+(test-unit "dbgr-buf-bt-pdb")
+
diff --git a/test/test-pdb.el b/test/test-pdb.el
new file mode 100644 (file)
index 0000000..ac8032a
--- /dev/null
@@ -0,0 +1,19 @@
+(require 'test-unit)
+(load-file "../dbgr/debugger/pdb/pdb.el")
+
+(test-unit-clear-contexts)
+
+(context "pdb"
+        (tag pdb)
+
+        (specify "pdb-parse-cmd-args"
+             (assert-equal '(nil ("pdb") ("foo") nil)
+                           (pdb-parse-cmd-args '("pdb" "foo")))
+             (assert-equal '(nil ("pdb") ("program.py" "foo") nil)
+                           (pdb-parse-cmd-args 
+                            '("pdb" "program.py" "foo")))
+             )
+        )
+
+(test-unit "pdb")
+
diff --git a/test/test-regexp-pdb.el b/test/test-regexp-pdb.el
new file mode 100644 (file)
index 0000000..0a8b1cf
--- /dev/null
@@ -0,0 +1,107 @@
+(require 'test-unit)
+(load-file "../dbgr/debugger/pdb/init.el")
+
+(test-unit-clear-contexts)
+
+
+(setq bps-pat    (gethash "brkpt-set" dbgr-pdb-pat-hash))
+(setq loc-pat    (gethash "loc"       dbgr-pdb-pat-hash))
+(setq prompt-pat (gethash "prompt"    dbgr-pdb-pat-hash))
+(setq tb-pat     (gethash "lang-backtrace" dbgr-pdb-pat-hash))
+
+(defun loc-match(text var) 
+  (string-match (dbgr-loc-pat-regexp var) text)
+)
+
+(defun prompt-match(prompt-str msg-fmt)
+  (assert-equal 0 (loc-match prompt-str prompt-pat)
+               (format msg-fmt  prompt-str))
+)
+
+;; FIXME: we get a void variable somewhere in here when running
+;;        even though we define it in lexical-let. Dunno why.
+;;        setq however will workaround this.
+(setq text "  File \"/usr/lib/python2.6/code.py\", line 281, in raw_input")
+(context "traceback location matching"
+        (tag regexp-pdb)
+        (specify "basic traceback location"
+                 (assert-t (numberp (loc-match text tb-pat))))
+        (specify "extract file name"
+                 (assert-equal "/usr/lib/python2.6/code.py"
+                               (match-string (dbgr-loc-pat-file-group tb-pat)
+                                             text)
+                               (format "Failing file group is %s" 
+                                       (dbgr-loc-pat-file-group tb-pat))))
+        (specify "extract line number"
+                 (assert-equal "281"
+                               (match-string (dbgr-loc-pat-line-group tb-pat)
+                                             text))
+                 ))
+
+(context "breakpoint location matching"
+        (tag regexp-pdb)
+        (lexical-let ((text "Breakpoint 1 at /src/git/code/gcd.py:13"))
+          (specify "basic breakpoint location"
+                   (assert-t (numberp (loc-match text bps-pat))))
+          (specify "extract breakpoint file name"
+                   (assert-equal "/src/git/code/gcd.py"
+                                 (match-string (dbgr-loc-pat-file-group 
+                                                bps-pat)
+                                               text)))
+          (specify "extract breakpoint line number"
+                   (assert-equal "13"
+                                 (match-string (dbgr-loc-pat-line-group 
+                                                bps-pat)
+                                               text)))
+          )
+        )
+
+(context "prompt matching"
+        (tag regexp-pdb)
+        ;; (lexical-let ((text "(c:\\working\\python\\helloworld.py:30): <module>"))
+        ;;   (specify "MS DOS position location"
+        ;;         (assert-t (numberp (loc-match text loc-pat))))
+        ;;   (specify "extract file name"
+        ;;         (assert-equal "c:\\working\\python\\helloworld.py"
+        ;;                     (match-string (dbgr-loc-pat-file-group loc-pat)
+        ;;                                   text)
+        ;;                     (format "Failing file group is %s" 
+        ;;                             (dbgr-loc-pat-file-group tb-pat))))
+        ;; (specify "extract line number"
+        ;;       (assert-equal "30"
+        ;;                     (match-string (dbgr-loc-pat-line-group loc-pat)
+        ;;                                   text)))
+
+        ;;   )
+        (lexical-let ((text "> /usr/bin/ipython(24)<module>"))
+          (specify "position location"
+                   (assert-t (numberp (loc-match text loc-pat))))
+          (specify "extract file name"
+                   (assert-equal "/usr/bin/ipython"
+                               (match-string (dbgr-loc-pat-file-group loc-pat)
+                                             text)
+                               (format "Failing file group is %s" 
+                                       (dbgr-loc-pat-file-group tb-pat))))
+          (specify "extract line number"
+                   (assert-equal "24"
+                                 (match-string (dbgr-loc-pat-line-group 
+                                                loc-pat)
+                                               text)))
+          
+          )
+
+        (lexical-let ((prompt-str "(Pdb) "))
+          (specify "prompt matching"
+                   (prompt-match prompt-str "valid debugger prompt: %s")
+                   (setq prompt_str "((Pdb)) ")
+                   (prompt-match prompt-str "valid nested debugger prompt: %s")
+                   (setq prompt-str "Pdb) ")
+                   (assert-nil (numberp (loc-match prompt-str prompt))
+                               (format "%s %s" "invalid debugger prompt"
+                                       prompt-str))
+                   )
+          )
+        )
+
+(test-unit "regexp-pdb")
+
index e4a41192208ee526e78ecdf7dc3141b77079c4f3..eca0d88516d893d3a46c89f6c1a73a2eb4485590 100644 (file)
@@ -15,7 +15,8 @@
 )
 
 (defun prompt-match(prompt-str) 
-  (assert-equal 0 (loc-match prompt-str prompt-pat))
+  (assert-equal 0 (loc-match prompt-str prompt-pat)
+               (format "valid prompt %s" prompt-str))
 )
 
 ;; FIXME: we get a void variable somewhere in here when running
@@ -75,6 +76,8 @@
                    (prompt-match "((trepan)): ")
                    (prompt-match "((trepan@55)): ")
                    (prompt-match "((trepan@main)): ")
+                   (assert-nil (loc-match "trepan:" prompt-pat)
+                               (format "invalid prompt %s" prompt-str))
                    )
 
           (specify "control-frame"