]> git.eshelyaron.com Git - emacs.git/commitdiff
(gud-menu-map): Update for bashdb.
authorRichard M. Stallman <rms@gnu.org>
Wed, 4 Dec 2002 11:56:55 +0000 (11:56 +0000)
committerRichard M. Stallman <rms@gnu.org>
Wed, 4 Dec 2002 11:56:55 +0000 (11:56 +0000)
(perldb): Change prompt regexp.
(gud-bashdb-history, gud-bashdb-massage-args, gud-bashdb-marker-filter)
(gud-bashdb-find-file, gud-bashdb-command-name, bashdb): New.

lisp/gud.el

index 4deae7a4e0557bfa6ce278462a386846629bb142..8c6350463d9a8c700426c71efe6ad3f9cdd0ff3e 100644 (file)
@@ -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, pdb (Python), and jdb."
+Supported debuggers include gdb, sdb, dbx, xdb, perldb, pdb (Python), jdb, and bash."
   :group 'unix
   :group 'tools)
 
@@ -100,23 +100,26 @@ Used to grey out relevant toolbar icons.")
     ([remove]  menu-item "Remove Breakpoint" gud-remove
                      :enable (not gud-running))
     ([tbreak]  menu-item "Temporary Breakpoint" gud-tbreak
-                    :enable (memq gud-minor-mode '(gdba gdb sdb xdb)))
+                    :enable (memq gud-minor-mode '(gdba gdb sdb xdb bashdb)))
     ([break]   menu-item "Set Breakpoint" gud-break
                      :enable (not gud-running))
     ([up]      menu-item "Up Stack" gud-up
-                    :enable (and (not gud-running)
-                                 (memq gud-minor-mode '(gdba gdb dbx xdb jdb))))
+                    :enable (and (not gdb-running)
+                                 (memq gud-minor-mode
+                                       '(gdba gdb dbx xdb jdb bashdb))))
     ([down]    menu-item "Down Stack" gud-down
-                    :enable (and (not gud-running)
-                    (memq gud-minor-mode '(gdba gdb dbx xdb jdb))))
+                    :enable (and (not gdb-running)
+                                 (memq gud-minor-mode
+                                       '(gdba gdb dbx xdb jdb bashdb))))
     ([print]   menu-item "Print Expression" gud-print
                      :enable (not gud-running))
     ([display] menu-item "Display Expression" gud-display
                     :enable (and (not gud-running)
                                  (eq gud-minor-mode 'gdba)))
     ([finish]  menu-item "Finish Function" gud-finish
-                       :enable  (and (not gud-running)
-                       (memq gud-minor-mode '(gdba gdb xdb jdb))))
+                    :enable (and (not gdb-running)
+                                 (memq gud-minor-mode
+                                       '(gdba gdb xdb jdb bashdb))))
     ([stepi]   "Step Instruction" . gud-stepi)
     ([step]    menu-item "Step Line" gud-step
                      :enable (not gud-running))
@@ -1318,7 +1321,7 @@ and source-file directory for your debugger."
 ;  (gud-def gud-down   "down %p"      ">" "Down N stack frames (numeric arg).")
   (gud-def gud-print  "%e"           "\C-p" "Evaluate perl expression at point.")
 
-  (setq comint-prompt-regexp "^         DB<+[0-9]+>+ ")
+  (setq comint-prompt-regexp "^  DB<+(*[0-9])*+>+ ")
   (setq paragraph-start comint-prompt-regexp)
   (run-hooks 'perldb-mode-hook))
 \f
@@ -2104,6 +2107,167 @@ gud, see `gud-mode'."
     (fset 'gud-jdb-find-source 'gud-jdb-find-source-file)))
 \f
 
+;; ======================================================================
+;;
+;; BASHDB support. See http://bashdb.sourceforge.net
+;;
+;; AUTHOR:     Rocky Bernstein <rocky@panix.com>
+;;
+;; CREATED:    Sun Nov 10 10:46:38 2002 Rocky Bernstein.
+;;
+;; INVOCATION NOTES:
+;;
+;; You invoke bashdb-mode with:
+;;
+;;    M-x bashdb <enter>
+;;
+;; It responds with:
+;;
+;;    Run bashdb (like this): bash
+;;
+
+;;; History of argument lists passed to bashdb.
+(defvar gud-bashdb-history nil)
+
+;; Convert a command line as would be typed normally to run a script
+;; into one that invokes an Emacs-enabled debugging session.
+;; "--debugger" in inserted as the first switch.
+
+(defun gud-bashdb-massage-args (file args)
+  (let* ((new-args (list "--debugger"))
+        (seen-e nil)
+        (shift (lambda ()
+                 (setq new-args (cons (car args) new-args))
+                 (setq args (cdr args)))))
+    
+    ;; Pass all switches and -e scripts through.
+    (while (and args
+               (string-match "^-" (car args))
+               (not (equal "-" (car args)))
+               (not (equal "--" (car args))))
+      (funcall shift))
+    
+    (if (or (not args)
+           (string-match "^-" (car args)))
+       (error "Can't use stdin as the script to debug"))
+    ;; This is the program name.
+    (funcall shift)
+
+  (while args
+    (funcall shift))
+  
+  (nreverse new-args)))
+
+;; 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-bashdb-marker-filter (string)
+  (setq gud-marker-acc (concat gud-marker-acc string))
+  (let ((output ""))
+
+    ;; Process all the complete markers in this chunk.
+    ;; Format of line looks like this:
+    ;;   (/etc/init.d/ntp.init:16):
+    ;; but we also allow DOS drive letters
+    ;;   (d:/etc/init.d/ntp.init:16):
+    (while (string-match "\\(^\\|\n\\)(\\(\\([a-zA-Z]:\\)?[^:\n]*\\):\\([0-9]*\\)):.*\n"
+                        gud-marker-acc)
+      (setq
+
+       ;; Extract the frame position from the marker.
+       gud-last-frame
+       (cons (substring gud-marker-acc (match-beginning 2) (match-end 2))
+            (string-to-int (substring gud-marker-acc
+                                      (match-beginning 4)
+                                      (match-end 4))))
+
+       ;; 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 "\032.*\\'" 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-bashdb-find-file (f)
+  (save-excursion
+    (let ((buf (find-file-noselect f 'nowarn)))
+      (set-buffer buf)
+      buf)))
+
+(defcustom gud-bashdb-command-name "bash"
+  "File name for executing bash debugger."
+  :type 'string
+  :group 'gud)
+
+;;;###autoload
+(defun bashdb (command-line)
+  "Run bashdb 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 bashdb (like this): "
+                              (if (consp gud-bashdb-history)
+                                  (car gud-bashdb-history)
+                                (concat gud-bashdb-command-name
+                                        " "))
+                              gud-minibuffer-local-map nil
+                              '(gud-bashdb-history . 1))))
+
+  (gud-common-init command-line 'gud-bashdb-massage-args
+                  'gud-bashdb-marker-filter 'gud-bashdb-find-file)
+
+  (set (make-local-variable 'gud-minor-mode) 'bashdb)
+
+  (gud-def gud-break  "break %l"   "\C-b" "Set breakpoint at current line.")
+  (gud-def gud-tbreak "tbreak %l"  "\C-t" "Set temporary 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 "finish"     "\C-f" "Finish executing current function.")
+  (gud-def gud-up     "up %p"      "<" "Up N stack frames (numeric arg).")
+  (gud-def gud-down   "down %p"    ">" "Down N stack frames (numeric arg).")
+  (gud-def gud-print  "pe %e"      "\C-p" "Evaluate bash expression at point.")
+
+  ;; Is this right?
+  (gud-def gud-statement "eval %e" "\C-e" "Execute Python statement at point.")
+
+  (local-set-key [menu-bar debug tbreak] '("Temporary Breakpoint" . gud-tbreak))
+  (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 "^bashdb<+[0-9]*>+ ")
+  (setq paragraph-start comint-prompt-regexp)
+  (run-hooks 'bashdb-mode-hook)
+  )
+
+(provide 'bashdb)
+
 ;;
 ;; End of debugger-specific information
 ;;