Imported from ../bash-3.2.48.tar.gz.
[platform/upstream/bash.git] / examples / bashdb / bashdb.el
1 ;;; bashdb.el --- Grand Unified Debugger mode for running bashdb
2 ;; Copyright (C) 2000, 2001 Masatake YAMATO 
3
4 ;; Author: Masatake YAMATO <jet@gyve.org>
5
6 ;; This program is free software; you can redistribute it and/or modify it
7 ;; under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 2 of the License, or
9 ;; (at your option) any later version.
10
11 ;; This program is distributed in the hope that it will be useful, but
12 ;; 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 this program; if not, write to the Free Software Foundation,
18 ;; Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 ;; Commentary:
21 ;; This program may run on Emacs 21.0.91 and XEmacs 21.1. 
22 ;;
23 ;; Put 
24 ;; (autoload 'bashdb "bashdb" "Run bashdb" t nil)
25 ;;  to your .emacs.
26 ;; M-x bashdb
27 ;; Run bashdb (like this): bashdb target.sh
28 ;;
29 ;; About bashdb:
30 ;; You can get bashdb from
31 ;; http://www.oranda.demon.co.uk/development.html
32 ;;
33 ;; bashdb.el is based on perldb in gud.el in XEmacs 21.1.
34
35 ;; Revision:
36 ;; $Revision: 1.6 $
37 ;; $Log: bashdb.el,v $
38 ;; Revision 1.6  2001/01/06 12:18:06  masata-y
39 ;; Write note about XEmacs.
40 ;;
41 ;;
42
43
44 ;;; Code: 
45 (require 'gud)
46
47 ;; User customizable variable
48 (defcustom gud-bashdb-command-name "bashdb"
49   "File name for executing Bashdb."
50   :type 'string
51   :group 'gud)
52
53 ;; History of argument lists passed to bashdb.
54 (defvar gud-bashdb-history nil)
55
56 (defun gud-bashdb-massage-args (file args)
57   (if xemacsp
58       (cons (file-name-nondirectory file) args) 
59     args))
60
61 ;; There's no guarantee that Emacs will hand the filter the entire
62 ;; marker at once; it could be broken up across several strings.  We
63 ;; might even receive a big chunk with several markers in it.  If we
64 ;; receive a chunk of text which looks like it might contain the
65 ;; beginning of a marker, we save it here between calls to the
66 ;; filter.
67 (if xemacsp
68     (defvar gud-bashdb-marker-acc ""))
69 (defun gud-bashdb-marker-acc ()
70   (if xemacsp
71       gud-bashdb-marker-acc
72     gud-marker-acc))
73 (defun gud-bashdb-marker-acc-quote ()
74   (if xemacsp
75       'gud-bashdb-marker-acc
76     'gud-marker-acc))
77
78 (defun gud-bashdb-marker-filter (string)
79   (save-match-data
80     (set (gud-bashdb-marker-acc-quote)
81          (concat (gud-bashdb-marker-acc) string))
82     (let ((output ""))
83       ;; Process all the complete markers in this chunk.
84       (while (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>.*\n"
85                            (gud-bashdb-marker-acc))
86         (setq
87          ;; Extract the frame position from the marker.
88          gud-last-frame (cons
89                          (substring (gud-bashdb-marker-acc)
90                                     (match-beginning 1)
91                                     (match-end 1))
92                          (string-to-int 
93                           (substring (gud-bashdb-marker-acc)
94                                      (match-beginning 2) 
95                                      (match-end 2))))
96          ;; Append any text before the marker to the output we're going
97          ;; to return - we don't include the marker in this text.
98          output (concat output
99                         (substring (gud-bashdb-marker-acc) 0 (match-beginning 0))))
100          ;; Set the accumulator to the remaining text.
101         (set
102          (gud-bashdb-marker-acc-quote) (substring 
103                                         (gud-bashdb-marker-acc) (match-end 0))))
104
105       ;; Does the remaining text look like it might end with the
106       ;; beginning of another marker?  If it does, then keep it in
107       ;; (gud-bashdb-marker-acc) until we receive the rest of it.  Since we
108       ;; know the full marker regexp above failed, it's pretty simple to
109       ;; test for marker starts.
110       (if (string-match "^\\([^:\n]+\\):\\([0-9]+\\)[ *]*>" (gud-bashdb-marker-acc))
111           (progn
112             ;; Everything before the potential marker start can be output.
113             (setq output (concat output (substring (gud-bashdb-marker-acc)
114                                                    0 (match-beginning 0))))
115             ;; Everything after, we save, to combine with later input.
116             (set (gud-bashdb-marker-acc-quote)
117                  (substring (gud-bashdb-marker-acc) (match-beginning 0))))
118         
119         (setq output (concat output (gud-bashdb-marker-acc)))
120         (set (gud-bashdb-marker-acc-quote) ""))
121       
122       output)))
123       
124 (defun gud-bashdb-find-file (f)
125   (find-file-noselect f))
126
127 ;;;###autoload
128 (defun bashdb (command-line)
129   "Run bashdb on program FILE in buffer *gud-FILE*.
130 The directory containing FILE becomes the initial working directory
131 and source-file directory for your debugger."
132   (interactive
133    (if xemacsp
134        (list (read-from-minibuffer "Run bashdb (like this): "
135                                    (if (consp gud-bashdb-history)
136                                        (car gud-bashdb-history)
137                                      (format "%s " gud-bashdb-command-name))
138                                    nil nil
139                                    '(gud-bashdb-history . 1)))
140      (list (gud-query-cmdline 'bashdb))
141      ))
142   
143   (if xemacsp
144       (progn
145         (gud-overload-functions '((gud-massage-args . gud-bashdb-massage-args)
146                                   (gud-marker-filter . gud-bashdb-marker-filter)
147                                   (gud-find-file . gud-bashdb-find-file)))
148         (gud-common-init command-line gud-bashdb-command-name))
149     (gud-common-init command-line 'gud-bashdb-massage-args
150                      'gud-bashdb-marker-filter 'gud-bashdb-find-file)
151     (set (make-local-variable 'gud-minor-mode) 'bashdb))
152
153 ;; Unsupported commands
154 ;;  condition foo       set break condition to foo
155 ;;  condition   clear break condition
156 ;;  display EXP evaluate and display EXP for each debug step
157 ;;  display             show a list of display expressions
158 ;;  undisplay N remove display expression N
159 ;;  ! string    passes string to a shell
160 ;;  quit                quit
161
162   (gud-def gud-break       "break %l"     "\C-b" "Set breakpoint at current line.")
163   (gud-def gud-list-break  "break"        "b"    "List breakpoints & break condition.")
164   (gud-def gud-remove      "delete %l"    "\C-d" "Remove breakpoint at current line")
165   (gud-def gud-remove-all  "delete"       "d"    "Clear all breakpoints")
166   (gud-def gud-cont   "continue"          "\C-r" "Continue with display.")
167   (gud-def gud-next   "next"              "\C-n" "Step one line (skip functions).")
168   (gud-def gud-print  "print %e"          "\C-p" "Evaluate bash expression at point.")
169   (gud-def gud-help   "help"              "h"    "Show all commands.")
170   (gud-def gud-trace  "trace"             "t"    "Toggle execution trace on/off")
171
172   (setq comint-prompt-regexp "^bashdb> ")
173   (setq paragraph-start comint-prompt-regexp)
174   (run-hooks 'bashdb-mode-hook))
175
176 (provide 'bashdb)
177 ;; bashdb.el ends here