(function (lambda (p) (fset (car p) (symbol-function (cdr p)))))
gud-overload-alist))
-(defun gud-debugger-startup (file args)
+(defun gud-massage-args (file args)
(error "GUD not properly entered."))
(defun gud-marker-filter (str)
;;
;;<name>
;; comint-prompt-regexp
-;; gud-<name>-debugger-startup
+;; gud-<name>-massage-args
;; gud-<name>-marker-filter
;; gud-<name>-find-file
;;
-;; The job of the startup-command method is to fire up a copy of the debugger,
-;; given a list of debugger arguments.
+;; The job of the massage-args method is to modify the given list of
+;; debugger arguments before running the debugger.
;;
;; The job of the marker-filter method is to detect file/line markers in
;; strings and set the global gud-last-frame to indicate what display
;; ======================================================================
;; gdb functions
-(defun gud-gdb-debugger-startup (file args)
- (apply 'make-comint (concat "gud-" file) "gdb" nil "-fullname" args))
+;;; History of argument lists passed to gdb.
+(defvar gud-gdb-history nil)
+
+(defun gud-gdb-massage-args (file args)
+ (cons "-fullname" (cons file args)))
(defun gud-gdb-marker-filter (string)
(if (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n" string)
(find-file-noselect f))
;;;###autoload
-(defun gdb (args)
+(defun gdb (command-line)
"Run gdb on program FILE in buffer *gud-FILE*.
The directory containing FILE becomes the initial working directory
and source-file directory for your debugger."
- (interactive "sRun gdb (like this): gdb ")
- (gud-overload-functions '((gud-debugger-startup . gud-gdb-debugger-startup)
- (gud-marker-filter . gud-gdb-marker-filter)
- (gud-find-file . gud-gdb-find-file)
+ (interactive
+ (list (read-from-minibuffer "Run gdb (like this): "
+ (if (consp gud-gdb-history)
+ (car gud-gdb-history)
+ "gdb ")
+ nil nil
+ '(gud-gdb-history . 1))))
+ (gud-overload-functions '((gud-massage-args . gud-gdb-massage-args)
+ (gud-marker-filter . gud-gdb-marker-filter)
+ (gud-find-file . gud-gdb-find-file)
))
- (gud-common-init args)
+ (gud-common-init command-line)
(gud-def gud-break "break %f:%l" "\C-b" "Set breakpoint at current line.")
(gud-def gud-tbreak "tbreak %f:%l" "\C-t" "Set breakpoint at current line.")
;; ======================================================================
;; sdb functions
+;;; History of argument lists passed to sdb.
+(defvar gud-sdb-history nil)
+
(defvar gud-sdb-needs-tags (not (file-exists-p "/var"))
"If nil, we're on a System V Release 4 and don't need the tags hack.")
(defvar gud-sdb-lastfile nil)
-(defun gud-sdb-debugger-startup (file args)
- (apply 'make-comint (concat "gud-" file) "sdb" nil args))
+(defun gud-sdb-massage-args (file args)
+ (cons file args))
(defun gud-sdb-marker-filter (string)
(cond
(find-file-noselect f)))
;;;###autoload
-(defun sdb (args)
+(defun sdb (command-line)
"Run sdb on program FILE in buffer *gud-FILE*.
The directory containing FILE becomes the initial working directory
and source-file directory for your debugger."
- (interactive "sRun sdb (like this): sdb ")
+ (interactive
+ (list (read-from-minibuffer "Run sdb (like this): "
+ (if (consp gud-sdb-history)
+ (car gud-sdb-history)
+ "sdb ")
+ nil nil
+ '(gud-sdb-history . 1))))
(if (and gud-sdb-needs-tags
(not (and (boundp 'tags-file-name) (file-exists-p tags-file-name))))
(error "The sdb support requires a valid tags table to work."))
- (gud-overload-functions '((gud-debugger-startup . gud-sdb-debugger-startup)
- (gud-marker-filter . gud-sdb-marker-filter)
- (gud-find-file . gud-sdb-find-file)
+ (gud-overload-functions '((gud-massage-args . gud-sdb-massage-args)
+ (gud-marker-filter . gud-sdb-marker-filter)
+ (gud-find-file . gud-sdb-find-file)
))
- (gud-common-init args)
+ (gud-common-init command-line)
(gud-def gud-break "%l b" "\C-b" "Set breakpoint at current line.")
(gud-def gud-tbreak "%l c" "\C-t" "Set temporary breakpoint at current line.")
;; ======================================================================
;; dbx functions
-(defun gud-dbx-debugger-startup (file args)
- (apply 'make-comint (concat "gud-" file) "dbx" nil args))
+;;; History of argument lists passed to dbx.
+(defvar gud-dbx-history nil)
+
+(defun gud-dbx-massage-args (file args)
+ (cons file args))
(defun gud-dbx-marker-filter (string)
(if (string-match
(find-file-noselect f))
;;;###autoload
-(defun dbx (args)
+(defun dbx (command-line)
"Run dbx on program FILE in buffer *gud-FILE*.
The directory containing FILE becomes the initial working directory
and source-file directory for your debugger."
- (interactive "sRun dbx (like this): dbx")
- (gud-overload-functions '((gud-debugger-startup . gud-dbx-debugger-startup)
- (gud-marker-filter . gud-dbx-marker-filter)
- (gud-find-file . gud-dbx-find-file)
+ (interactive
+ (list (read-from-minibuffer "Run dbx (like this): "
+ (if (consp gud-dbx-history)
+ (car gud-dbx-history)
+ "dbx ")
+ nil nil
+ '(gud-dbx-history . 1))))
+ (gud-overload-functions '((gud-massage-args . gud-dbx-massage-args)
+ (gud-marker-filter . gud-dbx-marker-filter)
+ (gud-find-file . gud-dbx-find-file)
))
- (gud-common-init args)
+ (gud-common-init command-line)
(gud-def gud-break "stop at \"%f\":%l"
"\C-b" "Set breakpoint at current line.")
;; ======================================================================
;; xdb (HP PARISC debugger) functions
-(defun gud-xdb-debugger-startup (file args)
- (apply 'make-comint (concat "gud-" file) "xdb" nil
- (append (let ((paths gud-xdb-paths)
- (result nil))
- (while paths
- (setq result (cons (car paths) (cons "-d" result)))
- (setq paths (cdr paths)))
- (nreverse result))
- args)))
+;;; History of argument lists passed to xdb.
+(defvar gud-xdb-history nil)
+
+(defvar gud-xdb-directories nil
+ "*A list of directories that xdb should search for source code.
+If nil, only source files in the program directory
+will be known to xdb.
+
+The file names should be absolute, or relative to the directory
+containing the executable being debugged.")
+
+(defun gud-xdb-massage-args (file args)
+ (nconc (let ((directories gud-xdb-directories)
+ (result nil))
+ (while directories
+ (setq result (cons (car directories) (cons "-d" result)))
+ (setq directories (cdr directories)))
+ (nreverse (cons file result)))
+ args))
(defun gud-xdb-file-name (f)
"Transform a relative pathname to a full pathname in xdb mode"
(let ((result nil))
(if (file-exists-p f)
(setq result (expand-file-name f))
- (let ((paths gud-xdb-paths))
- (while paths
- (let ((path (concat (car paths) "/" f)))
+ (let ((directories gud-xdb-directories))
+ (while directories
+ (let ((path (concat (car directories) "/" f)))
(if (file-exists-p path)
(setq result (expand-file-name path)
- paths nil)))
- (setq paths (cdr paths)))))
+ directories nil)))
+ (setq directories (cdr directories)))))
result))
;; xdb does not print the lines all at once, so we have to accumulate them
(setq gud-last-frame (cons file line))))))
(or result "")))
-(defvar gud-xdb-paths nil
- "*A list of directories containing source code that should be made known
-to xdb on startup. If nil, only source files in the program directory
-will be known to xdb.
-
-The pathnames should be full, or relative to the program directory.
-Program directory refers to the directory of the program that is being
-debugged.")
-
(defun gud-xdb-find-file (f)
(let ((realf (gud-xdb-file-name f)))
(if realf (find-file-noselect realf))))
;;;###autoload
-(defun xdb (args)
+(defun xdb (command-line)
"Run xdb on program FILE in buffer *gud-FILE*.
The directory containing FILE becomes the initial working directory
and source-file directory for your debugger.
-The variable 'gud-xdb-paths' can be set to a list of program source
+You can set the variable 'gud-xdb-directories' to a list of program source
directories if your program contains sources from more than one directory."
- (interactive "sRun xdb (like this): xdb")
- (gud-overload-functions '((gud-debugger-startup . gud-xdb-debugger-startup)
- (gud-marker-filter . gud-xdb-marker-filter)
- (gud-find-file . gud-xdb-find-file)))
-
- (gud-common-init args)
+ (interactive
+ (list (read-from-minibuffer "Run xdb (like this): "
+ (if (consp gud-xdb-history)
+ (car gud-xdb-history)
+ "xdb ")
+ nil nil
+ '(gud-xdb-history . 1))))
+ (gud-overload-functions '((gud-massage-args . gud-xdb-massage-args)
+ (gud-marker-filter . gud-xdb-marker-filter)
+ (gud-find-file . gud-xdb-find-file)))
+
+ (gud-common-init command-line)
(gud-def gud-break "b %f:%l" "\C-b" "Set breakpoint at current line.")
(gud-def gud-tbreak "b %f:%l\\t" "\C-t"
(defvar gud-comint-buffer nil)
-(defun gud-common-init (args)
- ;; Perform initializations common to all debuggers
- ;; There *must* be a cleaner way to lex the arglist...
- (let (file i)
- (if (string= args "")
- (setq args nil)
- (save-excursion
- (set-buffer (get-buffer-create "*gud-scratch*"))
- (erase-buffer)
- (insert args)
- (goto-char (point-max))
- (insert "\")")
- (goto-char (point-min))
- (insert "(\"")
- (while (re-search-forward " +" nil t)
- (replace-match "\" \"" nil nil))
- (goto-char (point-min))
- (while (re-search-forward "\"\"" nil t)
- (replace-match "" nil nil))
- (setq args (read (buffer-string)))
- (kill-buffer (current-buffer))))
- (setq i (1- (length args)))
- (while (and (>= i 0) (not (= (aref (nth i args) 0) ?-)))
- (setq file (nth i args)) (setq i (1- i)))
- (let* ((path (expand-file-name file))
- (filepart (file-name-nondirectory path)))
+;; Chop STRING into words separated by SPC or TAB and return a list of them.
+(defun gud-chop-words (string)
+ (let ((i 0) (beg 0)
+ (len (length string))
+ (words nil))
+ (while (< i len)
+ (if (memq (aref string i) '(?\t ? ))
+ (progn
+ (setq words (cons (substring string beg i) words)
+ beg (1+ i))
+ (while (and (< beg len) (memq (aref string beg) '(?\t ? )))
+ (setq beg (1+ beg)))
+ (setq i (1+ beg)))
+ (setq i (1+ i))))
+ (if (< beg len)
+ (setq words (cons (substring string beg) words)))
+ (nreverse words)))
+
+;; Perform initializations common to all debuggers.
+(defun gud-common-init (command-line)
+ (let* ((words (gud-chop-words command-line))
+ (program (car words))
+ (file-word (let ((w (cdr words)))
+ (while (and w (= ?- (aref (car w) 0)))
+ (setq w (cdr w)))
+ (car w)))
+ (args (delq file-word (cdr words)))
+ (file (expand-file-name file-word))
+ (filepart (file-name-nondirectory file)))
(switch-to-buffer (concat "*gud-" filepart "*"))
- (setq default-directory (file-name-directory path))
+ (setq default-directory (file-name-directory file))
(or (bolp) (newline))
(insert "Current directory is " default-directory "\n")
- (gud-debugger-startup filepart args)))
+ (apply 'make-comint (concat "gud-" filepart) program nil
+ (gud-massage-args file args)))
(gud-mode)
(set-process-filter (get-buffer-process (current-buffer)) 'gud-filter)
(set-process-sentinel (get-buffer-process (current-buffer)) 'gud-sentinel)
)
(t nil))))
+(provide 'gud)
+
;;; gud.el ends here