;;; gud.el --- Grand Unified Debugger mode for running GDB and other debuggers
+;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003,
+;; 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
;; Maintainer: FSF
;; Keywords: unix, tools
-;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003,
-;; 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
-
;; This file is part of GNU Emacs.
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
-;; The ancestral gdb.el was by W. Schelter <wfs@rascal.ics.utexas.edu> It was
-;; later rewritten by rms. Some ideas were due to Masanobu. Grand
+;; The ancestral gdb.el was by W. Schelter <wfs@rascal.ics.utexas.edu>.
+;; It was later rewritten by rms. Some ideas were due to Masanobu. Grand
;; Unification (sdb/dbx support) by Eric S. Raymond <esr@thyrsus.com> Barry
;; Warsaw <bwarsaw@cen.com> hacked the mode to use comint.el. Shane Hartman
;; <shane@spr.com> added support for xdb (HPUX debugger). Rick Sladkey
(defvar gdb-active-process)
(defvar gdb-define-alist)
(defvar gdb-macro-info)
-(defvar gdb-server-prefix)
(defvar gdb-show-changed-values)
+(defvar gdb-source-window)
(defvar gdb-var-list)
(defvar gdb-speedbar-auto-raise)
+(defvar gud-tooltip-mode)
+(defvar hl-line-mode)
+(defvar hl-line-sticky-flag)
(defvar tool-bar-map)
+
;; ======================================================================
;; GUD commands must be visible in C buffers visited by GUD
(defgroup gud nil
"Grand Unified Debugger mode for gdb and other debuggers under Emacs.
-Supported debuggers include gdb, sdb, dbx, xdb, perldb, pdb (Python), jdb."
+Supported debuggers include gdb, sdb, dbx, xdb, perldb, pdb (Python) and jdb."
:group 'processes
:group 'tools)
(defun gud-symbol (sym &optional soft minor-mode)
"Return the symbol used for SYM in MINOR-MODE.
-MINOR-MODE defaults to `gud-minor-mode.
+MINOR-MODE defaults to `gud-minor-mode'.
The symbol returned is `gud-<MINOR-MODE>-<SYM>'.
If SOFT is non-nil, returns nil if the symbol doesn't already exist."
(unless (or minor-mode gud-minor-mode) (error "Gud internal error"))
"Non-nil if debugged program is running.
Used to grey out relevant toolbar icons.")
-(defvar gdb-ready nil)
+(defvar gud-target-name "--unknown--"
+ "The apparent name of the program being debugged in a gud buffer.")
;; Use existing Info buffer, if possible.
(defun gud-goto-info ()
(throw 'info-found nil))))
nil 0)
(select-frame (make-frame)))
- (if (memq gud-minor-mode '(gdbmi gdba))
+ (if (eq gud-minor-mode 'gdbmi)
(info "(emacs)GDB Graphical Interface")
(info "(emacs)Debuggers"))))
(defun gud-tool-bar-item-visible-no-fringe ()
(not (or (eq (buffer-local-value 'major-mode (window-buffer)) 'speedbar-mode)
- (and (memq gud-minor-mode '(gdbmi gdba))
+ (eq (buffer-local-value 'major-mode (window-buffer)) 'gdb-memory-mode)
+ (and (eq gud-minor-mode 'gdbmi)
(> (car (window-fringes)) 0)))))
+(declare-function gdb-gud-context-command "gdb-mi.el")
+
(defun gud-stop-subjob ()
(interactive)
(with-current-buffer gud-comint-buffer
- (if (string-equal gud-target-name "emacs")
- (comint-stop-subjob)
- (comint-interrupt-subjob))))
+ (cond ((string-equal gud-target-name "emacs")
+ (comint-stop-subjob))
+ ((eq gud-minor-mode 'jdb)
+ (gud-call "suspend"))
+ ((eq gud-minor-mode 'gdbmi)
+ (gud-call (gdb-gud-context-command "-exec-interrupt")))
+ (t
+ (comint-interrupt-subjob)))))
(easy-mmode-defmap gud-menu-map
- '(([help] "Info" . gud-goto-info)
- ([tooltips] menu-item "Toggle GUD tooltips" gud-tooltip-mode
+ '(([help] "Info (debugger)" . gud-goto-info)
+ ([tooltips] menu-item "Show GUD tooltips" gud-tooltip-mode
:enable (and (not emacs-basic-display)
(display-graphic-p)
(fboundp 'x-show-tip))
:visible (memq gud-minor-mode
- '(gdbmi gdba dbx sdb xdb pdb))
+ '(gdbmi dbx sdb xdb pdb))
:button (:toggle . gud-tooltip-mode))
([refresh] "Refresh" . gud-refresh)
([run] menu-item "Run" gud-run
:enable (not gud-running)
:visible (memq gud-minor-mode '(gdbmi gdb dbx jdb)))
([go] menu-item (if gdb-active-process "Continue" "Run") gud-go
- :visible (and (not gud-running)
- (eq gud-minor-mode 'gdba)))
+ :visible (and (eq gud-minor-mode 'gdbmi)
+ (gdb-show-run-p)))
([stop] menu-item "Stop" gud-stop-subjob
- :visible (or (not (memq gud-minor-mode '(gdba pdb)))
- (and gud-running
- (eq gud-minor-mode 'gdba))))
+ :visible (or (not (memq gud-minor-mode '(gdbmi pdb)))
+ (gdb-show-stop-p)))
([until] menu-item "Continue to selection" gud-until
:enable (not gud-running)
- :visible (and (memq gud-minor-mode '(gdbmi gdba gdb perldb))
+ :visible (and (memq gud-minor-mode '(gdbmi gdb perldb))
(gud-tool-bar-item-visible-no-fringe)))
([remove] menu-item "Remove Breakpoint" gud-remove
:enable (not gud-running)
([tbreak] menu-item "Temporary Breakpoint" gud-tbreak
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdba gdb sdb xdb)))
+ '(gdbmi gdb sdb xdb)))
([break] menu-item "Set Breakpoint" gud-break
:enable (not gud-running)
:visible (gud-tool-bar-item-visible-no-fringe))
([up] menu-item "Up Stack" gud-up
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdba gdb dbx xdb jdb pdb)))
+ '(gdbmi gdb dbx xdb jdb pdb)))
([down] menu-item "Down Stack" gud-down
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdba gdb dbx xdb jdb pdb)))
+ '(gdbmi gdb dbx xdb jdb pdb)))
([pp] menu-item "Print S-expression" gud-pp
:enable (and (not gud-running)
gdb-active-process)
:visible (and (string-equal
(buffer-local-value
'gud-target-name gud-comint-buffer) "emacs")
- (eq gud-minor-mode 'gdba)))
- ([print*] menu-item "Print Dereference" gud-pstar
+ (eq gud-minor-mode 'gdbmi)))
+ ([print*] menu-item (if (eq gud-minor-mode 'jdb)
+ "Dump object"
+ "Print Dereference") gud-pstar
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdba gdb)))
+ :visible (memq gud-minor-mode '(gdbmi gdb jdb)))
([print] menu-item "Print Expression" gud-print
:enable (not gud-running))
([watch] menu-item "Watch Expression" gud-watch
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdba)))
+ :visible (eq gud-minor-mode 'gdbmi))
([finish] menu-item "Finish Function" gud-finish
:enable (not gud-running)
:visible (memq gud-minor-mode
- '(gdbmi gdba gdb xdb jdb pdb)))
+ '(gdbmi gdb xdb jdb pdb)))
([stepi] menu-item "Step Instruction" gud-stepi
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdba gdb dbx)))
+ :visible (memq gud-minor-mode '(gdbmi gdb dbx)))
([nexti] menu-item "Next Instruction" gud-nexti
:enable (not gud-running)
- :visible (memq gud-minor-mode '(gdbmi gdba gdb dbx)))
+ :visible (memq gud-minor-mode '(gdbmi gdb dbx)))
([step] menu-item "Step Line" gud-step
:enable (not gud-running))
([next] menu-item "Next Line" gud-next
:enable (not gud-running))
([cont] menu-item "Continue" gud-cont
:enable (not gud-running)
- :visible (not (eq gud-minor-mode 'gdba))))
+ :visible (not (eq gud-minor-mode 'gdbmi))))
"Menu for `gud-mode'."
:name "Gud")
. (,(propertize "next" 'face 'font-lock-doc-face) . gud-next))
([menu-bar until] menu-item
,(propertize "until" 'face 'font-lock-doc-face) gud-until
- :visible (memq gud-minor-mode '(gdbmi gdba gdb perldb)))
+ :visible (memq gud-minor-mode '(gdbmi gdb perldb)))
([menu-bar cont] menu-item
,(propertize "cont" 'face 'font-lock-doc-face) gud-cont
- :visible (not (eq gud-minor-mode 'gdba)))
+ :visible (not (eq gud-minor-mode 'gdbmi)))
([menu-bar run] menu-item
,(propertize "run" 'face 'font-lock-doc-face) gud-run
:visible (memq gud-minor-mode '(gdbmi gdb dbx jdb)))
([menu-bar go] menu-item
,(propertize " go " 'face 'font-lock-doc-face) gud-go
- :visible (and (not gud-running)
- (eq gud-minor-mode 'gdba)))
+ :visible (and (eq gud-minor-mode 'gdbmi)
+ (gdb-show-run-p)))
([menu-bar stop] menu-item
,(propertize "stop" 'face 'font-lock-doc-face) gud-stop-subjob
- :visible (or gud-running
- (not (eq gud-minor-mode 'gdba))))
+ :visible (or (and (eq gud-minor-mode 'gdbmi)
+ (gdb-show-stop-p))
+ (not (eq gud-minor-mode 'gdbmi))))
([menu-bar print]
. (,(propertize "print" 'face 'font-lock-doc-face) . gud-print))
([menu-bar tools] . undefined)
"`gud-mode' keymap.")
(defvar gud-tool-bar-map
- (if (display-graphic-p)
- (let ((map (make-sparse-keymap)))
- (dolist (x '((gud-break . "gud/break")
- (gud-remove . "gud/remove")
- (gud-print . "gud/print")
- (gud-pstar . "gud/pstar")
- (gud-pp . "gud/pp")
- (gud-watch . "gud/watch")
- (gud-run . "gud/run")
- (gud-go . "gud/go")
- (gud-stop-subjob . "gud/stop")
- (gud-cont . "gud/cont")
- (gud-until . "gud/until")
- (gud-next . "gud/next")
- (gud-step . "gud/step")
- (gud-finish . "gud/finish")
- (gud-nexti . "gud/nexti")
- (gud-stepi . "gud/stepi")
- (gud-up . "gud/up")
- (gud-down . "gud/down")
- (gud-goto-info . "info"))
- map)
- (tool-bar-local-item-from-menu
- (car x) (cdr x) map gud-minor-mode-map)))))
+ (let ((map (make-sparse-keymap)))
+ (dolist (x '((gud-break . "gud/break")
+ (gud-remove . "gud/remove")
+ (gud-print . "gud/print")
+ (gud-pstar . "gud/pstar")
+ (gud-pp . "gud/pp")
+ (gud-watch . "gud/watch")
+ (gud-run . "gud/run")
+ (gud-go . "gud/go")
+ (gud-stop-subjob . "gud/stop")
+ (gud-cont . "gud/cont")
+ (gud-until . "gud/until")
+ (gud-next . "gud/next")
+ (gud-step . "gud/step")
+ (gud-finish . "gud/finish")
+ (gud-nexti . "gud/nexti")
+ (gud-stepi . "gud/stepi")
+ (gud-up . "gud/up")
+ (gud-down . "gud/down")
+ (gud-goto-info . "info"))
+ map)
+ (tool-bar-local-item-from-menu
+ (car x) (cdr x) map gud-minor-mode-map))))
(defun gud-file-name (f)
"Transform a relative file name to an absolute file name.
(setq directories (cdr directories)))
result)))
+(declare-function gdb-create-define-alist "gdb-mi" ())
+
(defun gud-find-file (file)
;; Don't get confused by double slashes in the name that comes from GDB.
(while (string-match "//+" file)
(set (make-local-variable 'gud-minor-mode) minor-mode)
(set (make-local-variable 'tool-bar-map) gud-tool-bar-map)
(when (and gud-tooltip-mode
- (memq gud-minor-mode '(gdbmi gdba)))
+ (eq gud-minor-mode 'gdbmi))
(make-local-variable 'gdb-define-alist)
(unless gdb-define-alist (gdb-create-define-alist))
(add-hook 'after-save-hook 'gdb-create-define-alist nil t))
;; Of course you may use `gud-def' with any other debugger command, including
;; user defined ones.
-;; A macro call like (gud-def FUNC NAME KEY DOC) expands to a form
-;; which defines FUNC to send the command NAME to the debugger, gives
+;; A macro call like (gud-def FUNC CMD KEY DOC) expands to a form
+;; which defines FUNC to send the command CMD to the debugger, gives
;; it the docstring DOC, and binds that function to KEY in the GUD
;; major mode. The function is also bound in the global keymap with the
;; GUD prefix.
(defmacro gud-def (func cmd key &optional doc)
- "Define FUNC to be a command sending STR and bound to KEY, with
+ "Define FUNC to be a command sending CMD and bound to KEY, with
optional doc string DOC. Certain %-escapes in the string arguments
are interpreted specially if present. These are:
(defun ,func (arg)
,@(if doc (list doc))
(interactive "p")
- ,(if (stringp cmd)
- `(gud-call ,cmd arg)
- cmd))
+ (if (not gud-running)
+ ,(if (stringp cmd)
+ `(gud-call ,cmd arg)
+ cmd)))
,(if key `(local-set-key ,(concat "\C-c" key) ',func))
,(if key `(global-set-key (vconcat gud-key-prefix ,key) ',func))))
(defvar gud-last-speedbar-stackframe nil
"Description of the currently displayed GUD stack.
-t means that there is no stack, and we are in display-file mode.")
+The value t means that there is no stack, and we are in display-file mode.")
(defvar gud-speedbar-key-map nil
"Keymap used when in the buffers display mode.")
(defun gud-speedbar-item-info ()
"Display the data type of the watch expression element."
(let ((var (nth (- (line-number-at-pos (point)) 2) gdb-var-list)))
- (if (nth 6 var)
- (speedbar-message "%s: %s" (nth 6 var) (nth 3 var))
+ (if (nth 7 var)
+ (speedbar-message "%s: %s" (nth 7 var) (nth 3 var))
(speedbar-message "%s" (nth 3 var)))))
(defun gud-install-speedbar-variables ()
(defvar gud-speedbar-menu-items
'(["Jump to stack frame" speedbar-edit-line
- :visible (not (memq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
- '(gdbmi gdba)))]
+ :visible (not (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
+ 'gdbmi))]
["Edit value" speedbar-edit-line
- :visible (memq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
- '(gdbmi gdba))]
+ :visible (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
+ 'gdbmi)]
["Delete expression" gdb-var-delete
- :visible (memq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
- '(gdbmi gdba))]
+ :visible (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
+ 'gdbmi)]
["Auto raise frame" gdb-speedbar-auto-raise
:style toggle :selected gdb-speedbar-auto-raise
- :visible (memq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
- '(gdbmi gdba))])
+ :visible (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
+ 'gdbmi)]
+ ("Output Format"
+ :visible (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
+ 'gdbmi)
+ ["Binary" (gdb-var-set-format "binary") t]
+ ["Natural" (gdb-var-set-format "natural") t]
+ ["Hexadecimal" (gdb-var-set-format "hexadecimal") t]))
"Additional menu items to add to the speedbar frame.")
;; Make sure our special speedbar mode is loaded
(add-hook 'speedbar-load-hook 'gud-install-speedbar-variables))
(defun gud-expansion-speedbar-buttons (directory zero)
- "Wrapper for call to speedbar-add-expansion-list. DIRECTORY and
-ZERO are not used, but are required by the caller."
+ "Wrapper for call to `speedbar-add-expansion-list'.
+DIRECTORY and ZERO are not used, but are required by the caller."
(gud-speedbar-buttons gud-comint-buffer))
(defun gud-speedbar-buttons (buffer)
"Create a speedbar display based on the current state of GUD.
If the GUD BUFFER is not running a supported debugger, then turn
-off the specialized speedbar mode. BUFFER is not used, but are
+off the specialized speedbar mode. BUFFER is not used, but is
required by the caller."
(when (and gud-comint-buffer
;; gud-comint-buffer might be killed
(start (window-start window))
(p (window-point window)))
(cond
- ((memq minor-mode '(gdbmi gdba))
+ ((eq minor-mode 'gdbmi)
(erase-buffer)
(insert "Watch Expressions:\n")
- (if gdb-speedbar-auto-raise
- (raise-frame speedbar-frame))
(let ((var-list gdb-var-list) parent)
(while var-list
(let* (char (depth 0) (start 0) (var (car var-list))
(varnum (car var)) (expr (nth 1 var))
(type (if (nth 3 var) (nth 3 var) " "))
- (value (nth 4 var)) (status (nth 5 var)))
+ (value (nth 4 var)) (status (nth 5 var))
+ (has-more (nth 6 var)))
(put-text-property
0 (length expr) 'face font-lock-variable-name-face expr)
(put-text-property
(setq depth (1+ depth)
start (1+ (match-beginning 0))))
(if (eq depth 0) (setq parent nil))
- (if (or (equal (nth 2 var) "0")
- (and (equal (nth 2 var) "1")
- (string-match "char \\*$" type)))
+ (if (and (or (not has-more) (string-equal has-more "0"))
+ (or (equal (nth 2 var) "0")
+ (and (equal (nth 2 var) "1")
+ (string-match "char \\*$" type)) ))
(speedbar-make-tag-line
'bracket ?? nil nil
(concat expr "\t" value)
(car frame)
'speedbar-file-face
'speedbar-highlight-face
- (cond ((memq minor-mode '(gdbmi gdba gdb))
+ (cond ((memq minor-mode '(gdbmi gdb))
'gud-gdb-goto-stackframe)
(t (error "Should never be here")))
frame t))))
;; Set the accumulator to the remaining text.
gud-marker-acc (substring gud-marker-acc (match-end 0))))
- ;; Check for annotations and change gud-minor-mode to 'gdba if
- ;; they are found.
(while (string-match "\n\032\032\\(.*\\)\n" gud-marker-acc)
(let ((match (match-string 1 gud-marker-acc)))
(defvar gud-filter-pending-text nil
"Non-nil means this is text that has been saved for later in `gud-filter'.")
-;; The old gdb command. The new one is in gdb-ui.el.
+;; If in gdb mode, gdb-mi is loaded.
+(declare-function gdb-restore-windows "gdb-mi" ())
+
+;; The old gdb command (text command mode). The new one is in gdb-mi.el.
;;;###autoload
(defun gud-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. By
-default this command starts GDB using a graphical interface. See
-`gdba' for more information.
-
-To run GDB in text command mode, replace the GDB \"--annotate=3\"
-option with \"--fullname\" either in the minibuffer for the
-current Emacs session, or the custom variable
-`gud-gdb-command-name' for all future sessions. You need to use
-text command mode to debug multiple programs within one Emacs
-session."
+directory and source-file directory for your debugger."
(interactive (list (gud-query-cmdline 'gud-gdb)))
- (require 'gdb-ui)
-
(when (and gud-comint-buffer
(buffer-name gud-comint-buffer)
(get-buffer-process gud-comint-buffer)
- (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)))
- (gdb-restore-windows)
- (error
- "Multiple debugging requires restarting in text command mode"))
+ (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdbmi)))
+ (gdb-restore-windows)
+ (error
+ "Multiple debugging requires restarting in text command mode"))
- (gud-common-init command-line nil 'gud-gdba-marker-filter)
- (set (make-local-variable 'gud-minor-mode) 'gdba)
+ (gud-common-init command-line nil 'gud-gdb-marker-filter)
+ (set (make-local-variable 'gud-minor-mode) 'gdb)
(gud-def gud-break "break %f:%l" "\C-b" "Set breakpoint at current line.")
(gud-def gud-tbreak "tbreak %f:%l" "\C-t"
(setq paragraph-start comint-prompt-regexp)
(setq gdb-first-prompt t)
(setq gud-running nil)
- (setq gdb-ready nil)
(setq gud-filter-pending-text nil)
(run-hooks 'gud-gdb-mode-hook))
(string-match "^#\\([0-9]+\\) +[0-9a-fx]+ in \\([:0-9a-zA-Z_]+\\) (" e)
(string-match "^#\\([0-9]+\\) +\\([:0-9a-zA-Z_]+\\) (" e)))
(if (not (string-match
- "at \\([-0-9a-zA-Z_.]+\\):\\([0-9]+\\)$" e))
+ "at \\([-0-9a-zA-Z_/.]+\\):\\([0-9]+\\)$" e))
nil
(setcar newlst
(list (nth 0 (car newlst))
(setq newlst
(cons
(if (string-match
- "at \\([-0-9a-zA-Z_.]+\\):\\([0-9]+\\)$" e)
+ "at \\([-0-9a-zA-Z_/.]+\\):\\([0-9]+\\)$" e)
(list name num (match-string 1 e)
(match-string 2 e))
(list name num))
(defun gud-gdb-run-command-fetch-lines (command buffer &optional skip)
"Run COMMAND, and return the list of lines it outputs.
BUFFER is the current buffer which may be the GUD buffer in which to run.
-SKIP is the number of chars to skip on each lines, it defaults to 0."
+SKIP is the number of chars to skip on each line, it defaults to 0."
(with-current-buffer gud-comint-buffer
(if (and (eq gud-comint-buffer buffer)
(save-excursion
(defvar gud-dbx-use-stopformat-p
(string-match "irix[6-9]\\.[1-9]" system-configuration)
"Non-nil to use the dbx feature present at least from Irix 6.1
- whereby $stopformat=1 produces an output format compatiable with
- `gud-dbx-marker-filter'.")
+whereby $stopformat=1 produces an output format compatible with
+`gud-dbx-marker-filter'.")
;; [Irix dbx seems to be a moving target. The dbx output changed
;; subtly sometime between OS v4.0.5 and v5.2 so that, for instance,
;; the output from `up' is no longer spotted by gud (and it's probably
(setq result (substring result 0 (match-beginning 0))))))
(or result "")))
-(defvar gud-dgux-p (string-match "-dgux" system-configuration)
- "Non-nil means to assume the interface approriate for DG/UX dbx.
-This was tested using R4.11.")
-
;; There are a couple of differences between DG's dbx output and normal
;; dbx output which make it nontrivial to integrate this into the
;; standard dbx-marker-filter (mainly, there are a different number of
(gud-irix-p
(gud-common-init command-line 'gud-dbx-massage-args
'gud-irixdbx-marker-filter))
- (gud-dgux-p
- (gud-common-init command-line 'gud-dbx-massage-args
- 'gud-dguxdbx-marker-filter))
(t
(gud-common-init command-line 'gud-dbx-massage-args
'gud-dbx-marker-filter)))
:group 'gud)
(defvar gud-jdb-classpath nil
- "Java/jdb classpath directories list.
+ "Java/jdb classpath directories list.
If `gud-jdb-use-classpath' is non-nil, gud-jdb derives the `gud-jdb-classpath'
list automatically using the following methods in sequence
\(with subsequent successful steps overriding the results of previous
1) Read the CLASSPATH environment variable,
2) Read any \"-classpath\" argument used to run jdb,
or detected in jdb output (e.g. if jdb is run by a script
- that echoes the actual jdb command before starting jdb)
+ that echoes the actual jdb command before starting jdb),
3) Send a \"classpath\" command to jdb and scan jdb output for
classpath information if jdb is invoked with an \"-attach\" (to
an already running VM) argument (This case typically does not
to the VM when it is started).
Note that method 3 cannot be used with oldjdb (or Java 1 jdb) since
-those debuggers do not support the classpath command. Use 1) or 2).")
+those debuggers do not support the classpath command. Use 1) or 2).")
(defvar gud-jdb-sourcepath nil
"Directory list provided by an (optional) \"-sourcepath\" option to jdb.
source file information.")
(defvar gud-jdb-history nil
-"History of argument lists passed to jdb.")
+ "History of argument lists passed to jdb.")
;; List of Java source file directories.
the source code display in sync with the debugging session.")
(defvar gud-jdb-source-files nil
-"List of the java source files for this debugging session.")
+ "List of the java source files for this debugging session.")
;; Association list of fully qualified class names (package + class name)
;; and their source files.
(defvar gud-jdb-class-source-alist nil
-"Association list of fully qualified class names and source files.")
+ "Association list of fully qualified class names and source files.")
;; This is used to hold a source file during analysis.
(defvar gud-jdb-analysis-buffer nil)
(defvar gud-jdb-classpath-string nil
-"Holds temporary classpath values.")
+ "Holds temporary classpath values.")
(defun gud-jdb-build-source-files-list (path extn)
-"Return a list of java source files (absolute paths).
+ "Return a list of java source files (absolute paths).
PATH gives the directories in which to search for files with
extension EXTN. Normally EXTN is given as the regular expression
\"\\.java$\" ."
(defvar gud-jdb-lowest-stack-level 999)
(defun gud-jdb-find-source-using-classpath (p)
-"Find source file corresponding to fully qualified class p.
-Convert p from jdb's output, converted to a pathname
+ "Find source file corresponding to fully qualified class P.
+Convert P from jdb's output, converted to a pathname
relative to a classpath directory."
(save-match-data
(let
(if found-file (concat (car cplist) "/" filename)))))
(defun gud-jdb-find-source (string)
-"Alias for function used to locate source files.
+ "Alias for function used to locate source files.
Set to `gud-jdb-find-source-using-classpath' or `gud-jdb-find-source-file'
during jdb initialization depending on the value of
`gud-jdb-use-classpath'."
-nil)
+ nil)
(defun gud-jdb-parse-classpath-string (string)
-"Parse the classpath list and convert each item to an absolute pathname."
+ "Parse the classpath list and convert each item to an absolute pathname."
(mapcar (lambda (s) (if (string-match "[/\\]$" s)
(replace-match "" nil nil s) s))
(mapcar 'file-truename
switch is given, omit all whitespace between it and its value.
See `gud-jdb-use-classpath' and `gud-jdb-classpath' documentation for
-information on how jdb accesses source files. Alternatively (if
+information on how jdb accesses source files. Alternatively (if
`gud-jdb-use-classpath' is nil), see `gud-jdb-directories' for the
original source file access method.
;; Set gud-jdb-classpath from the CLASSPATH environment variable,
;; if CLASSPATH is set.
- (setq gud-jdb-classpath-string (getenv "CLASSPATH"))
+ (setq gud-jdb-classpath-string (or (getenv "CLASSPATH") "."))
(if gud-jdb-classpath-string
(setq gud-jdb-classpath
(gud-jdb-parse-classpath-string gud-jdb-classpath-string)))
(gud-def gud-up "up\C-Mwhere" "<" "Up one stack frame.")
(gud-def gud-down "down\C-Mwhere" ">" "Up one stack frame.")
(gud-def gud-run "run" nil "Run the program.") ;if VM start using jdb
- (gud-def gud-print "print %e" "\C-p" "Evaluate Java expression at point.")
-
+ (gud-def gud-print "print %e" "\C-p" "Print value of expression at point.")
+ (gud-def gud-pstar "dump %e" nil "Print all object information at point.")
(setq comint-prompt-regexp "^> \\|^[^ ]+\\[[0-9]+\\] ")
(setq paragraph-start comint-prompt-regexp)
;; Cause our buffers to be displayed, by default,
;; in the selected window.
-;;;###autoload (add-hook 'same-window-regexps "\\*gud-.*\\*\\(\\|<[0-9]+>\\)")
+;;;###autoload (add-hook 'same-window-regexps (purecopy "\\*gud-.*\\*\\(\\|<[0-9]+>\\)"))
(defcustom gud-chdir-before-run t
"Non-nil if GUD should `cd' to the debugged executable."
:group 'gud
:type 'boolean)
-(defvar gud-target-name "--unknown--"
- "The apparent name of the program being debugged in a gud buffer.")
+(declare-function tramp-file-name-localname "tramp" (vec))
+(declare-function tramp-dissect-file-name "tramp" (name &optional nodefault))
;; Perform initializations common to all debuggers.
;; The first arg is the specified command line,
(setq w (cdr w)))
(if w
(setcar w
- (if (file-remote-p default-directory)
- (setq file (file-name-nondirectory file))
+ (if (file-remote-p file)
+ ;; Tramp has already been loaded if we are here.
+ (setq file (tramp-file-name-localname
+ (tramp-dissect-file-name file)))
file))))
(apply 'make-comint (concat "gud" filepart) program nil
(if massage-args (funcall massage-args file args) args))
(gud-set-buffer))
(defun gud-set-buffer ()
- (when (eq major-mode 'gud-mode)
+ (when (derived-mode-p 'gud-mode)
(setq gud-comint-buffer (current-buffer))))
(defvar gud-filter-defer-flag nil
(defvar gud-overlay-arrow-position nil)
(add-to-list 'overlay-arrow-variable-list 'gud-overlay-arrow-position)
+(declare-function gdb-reset "gdb-mi" ())
+
(defun gud-sentinel (proc msg)
(cond ((null (buffer-name (process-buffer proc)))
;; buffer killed
(string-equal speedbar-initial-expansion-list-name "GUD"))
(speedbar-change-initial-expansion-list
speedbar-previously-used-expansion-list-name))
- (if (memq gud-minor-mode-type '(gdbmi gdba))
+ (if (eq gud-minor-mode-type 'gdbmi)
(gdb-reset)
(gud-reset)))
((memq (process-status proc) '(signal exit))
;; Stop displaying an arrow in a source file.
(setq gud-overlay-arrow-position nil)
- (if (memq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
- '(gdba gdbmi))
+ (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
+ 'gdbmi)
(gdb-reset)
(gud-reset))
(let* ((obuf (current-buffer)))
(defun gud-kill-buffer-hook ()
(setq gud-minor-mode-type gud-minor-mode)
(condition-case nil
- (kill-process (get-buffer-process (current-buffer)))
+ (progn
+ (kill-process (get-buffer-process (current-buffer)))
+ (delete-process (get-process "gdb-inferior")))
(error nil)))
(defun gud-reset ()
(setq gud-last-last-frame gud-last-frame
gud-last-frame nil)))
+(declare-function global-hl-line-highlight "hl-line" ())
+(declare-function hl-line-highlight "hl-line" ())
+(declare-function gdb-display-source-buffer "gdb-mi" (buffer))
+(declare-function gdb-display-buffer "gdb-mi" (buf dedicated &optional size))
+
;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
;; and that its line LINE is visible.
;; Put the overlay-arrow on the line LINE in that buffer.
(gud-find-file true-file)))
(window (and buffer
(or (get-buffer-window buffer)
- (if (memq gud-minor-mode '(gdbmi gdba))
- (or (if (get-buffer-window buffer 0)
- (display-buffer buffer nil 0))
+ (if (eq gud-minor-mode 'gdbmi)
+ (or (if (get-buffer-window buffer 'visible)
+ (display-buffer buffer nil 'visible))
(unless (gdb-display-source-buffer buffer)
- (gdb-display-buffer buffer nil))))
+ (gdb-display-buffer buffer nil 'visible))))
(display-buffer buffer))))
(pos))
(if buffer
(setq gud-keep-buffer t)))
(save-restriction
(widen)
- (goto-line line)
+ (goto-char (point-min))
+ (forward-line (1- line))
(setq pos (point))
(or gud-overlay-arrow-position
(setq gud-overlay-arrow-position (make-marker)))
(goto-char pos))))
(when window
(set-window-point window gud-overlay-arrow-position)
- (if (memq gud-minor-mode '(gdbmi gdba))
+ (if (eq gud-minor-mode 'gdbmi)
(setq gdb-source-window window)))))))
;; The gud-call function must do the right thing whether its invoking
(let ((proc (get-buffer-process gud-comint-buffer)))
(or proc (error "Current buffer has no process"))
;; Arrange for the current prompt to get deleted.
- (save-excursion
- (set-buffer gud-comint-buffer)
- (save-restriction
- (widen)
- (if (marker-position gud-delete-prompt-marker)
- ;; We get here when printing an expression.
- (goto-char gud-delete-prompt-marker)
- (goto-char (process-mark proc))
- (forward-line 0))
- (if (looking-at comint-prompt-regexp)
- (set-marker gud-delete-prompt-marker (point)))
- (if (memq gud-minor-mode '(gdbmi gdba))
- (apply comint-input-sender (list proc command))
- (process-send-string proc (concat command "\n")))))))
+ (with-current-buffer gud-comint-buffer
+ (save-excursion
+ (save-restriction
+ (widen)
+ (if (marker-position gud-delete-prompt-marker)
+ ;; We get here when printing an expression.
+ (goto-char gud-delete-prompt-marker)
+ (goto-char (process-mark proc))
+ (forward-line 0))
+ (if (looking-at comint-prompt-regexp)
+ (set-marker gud-delete-prompt-marker (point)))
+ (if (eq gud-minor-mode 'gdbmi)
+ (apply comint-input-sender (list proc command))
+ (process-send-string proc (concat command "\n"))))))))
(defun gud-refresh (&optional arg)
"Fix up a possibly garbled display, and redraw the arrow."
(set-marker-insertion-type gud-delete-prompt-marker t))
(unless (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
'jdb)
- (insert (concat expr " = "))))))
+ (insert (concat expr " = "))))))
expr))
;; The next eight functions are hacked from gdbsrc.el by
(t nil)))
(t nil))))
+
+(declare-function c-langelem-sym "cc-defs" (langelem))
+(declare-function c-langelem-pos "cc-defs" (langelem))
+(declare-function syntax-symbol "gud" (x))
+(declare-function syntax-point "gud" (x))
+
(defun gud-find-class (f line)
"Find fully qualified class in file F at line LINE.
This function uses the `gud-jdb-classpath' (and optional
`gud-jdb-sourcepath') list(s) to derive a file
-pathname relative to its classpath directory. The values in
+pathname relative to its classpath directory. The values in
`gud-jdb-classpath' are assumed to have been converted to absolute
pathname standards using file-truename.
If F is visited by a buffer and its mode is CC-mode(Java),
;; symbols until 'topmost-intro is reached to find out if
;; point is within a nested class
(if (and fbuffer (equal (symbol-file 'java-mode) "cc-mode"))
- (save-excursion
- (set-buffer fbuffer)
+ (with-current-buffer fbuffer
(let ((nclass) (syntax))
;; While the c-syntactic information does not start
;; with the 'topmost-intro symbol, there may be
("\\$\\(\\w+\\)" (1 font-lock-variable-name-face))
("^\\s-*\\(\\w\\(\\w\\|\\s_\\)*\\)" (1 font-lock-keyword-face))))
-(defvar gdb-script-font-lock-syntactic-keywords
- '(("^document\\s-.*\\(\n\\)" (1 "< b"))
- ("^end\\>"
- (0 (unless (eq (match-beginning 0) (point-min))
+(defconst gdb-script-syntax-propertize-function
+ (syntax-propertize-rules
+ ("^document\\s-.*\\(\n\\)" (1 "< b"))
+ ("^end\\(\\>\\)"
+ (1 (ignore
+ (unless (eq (match-beginning 0) (point-min))
;; We change the \n in front, which is more difficult, but results
;; in better highlighting. If the doc is empty, the single \n is
;; both the beginning and the end of the docstring, which can't be
'syntax-table (eval-when-compile
(string-to-syntax "> b")))
;; Make sure that rehighlighting the previous line won't erase our
- ;; syntax-table property.
+ ;; syntax-table property and that modifying `end' will.
(put-text-property (1- (match-beginning 0)) (match-end 0)
- 'font-lock-multiline t)
- nil)))))
+ 'syntax-multiline t)))))))
(defun gdb-script-font-lock-syntactic-face (state)
(cond
(goto-char (point-max)))
t)
-;; Besides .gdbinit, gdb documents other names to be usable for init
-;; files, cross-debuggers can use something like
-;; .PROCESSORNAME-gdbinit so that the host and target gdbinit files
-;; don't interfere with each other.
-;;;###autoload
-(add-to-list 'auto-mode-alist '("/\\.[a-z0-9-]*gdbinit" . gdb-script-mode))
-
;;;###autoload
(define-derived-mode gdb-script-mode nil "GDB-Script"
- "Major mode for editing GDB scripts"
+ "Major mode for editing GDB scripts."
(set (make-local-variable 'comment-start) "#")
(set (make-local-variable 'comment-start-skip) "#+\\s-*")
(set (make-local-variable 'outline-regexp) "[ \t]")
#'gdb-script-end-of-defun)
(set (make-local-variable 'font-lock-defaults)
'(gdb-script-font-lock-keywords nil nil ((?_ . "w")) nil
- (font-lock-syntactic-keywords
- . gdb-script-font-lock-syntactic-keywords)
(font-lock-syntactic-face-function
- . gdb-script-font-lock-syntactic-face))))
+ . gdb-script-font-lock-syntactic-face)))
+ ;; Recognize docstrings.
+ (set (make-local-variable 'syntax-propertize-function)
+ gdb-script-syntax-propertize-function)
+ (add-hook 'syntax-propertize-extend-region-functions
+ #'syntax-propertize-multiline 'append 'local))
\f
;;; tooltips for GUD
;;; Customizable settings
+;;;###autoload
(define-minor-mode gud-tooltip-mode
"Toggle the display of GUD tooltips."
:global t
(progn
(add-hook 'change-major-mode-hook 'gud-tooltip-change-major-mode)
(add-hook 'pre-command-hook 'tooltip-hide)
- (add-hook 'tooltip-hook 'gud-tooltip-tips)
+ (add-hook 'tooltip-functions 'gud-tooltip-tips)
(define-key global-map [mouse-movement] 'gud-tooltip-mouse-motion))
(unless tooltip-mode (remove-hook 'pre-command-hook 'tooltip-hide)
(remove-hook 'change-major-mode-hook 'gud-tooltip-change-major-mode)
- (remove-hook 'tooltip-hook 'gud-tooltip-tips)
+ (remove-hook 'tooltip-functions 'gud-tooltip-tips)
(define-key global-map [mouse-movement] 'ignore)))
(gud-tooltip-activate-mouse-motions-if-enabled)
(if (and gud-comint-buffer
(buffer-name gud-comint-buffer); gud-comint-buffer might be killed
- (memq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
- '(gdbmi gdba)))
+ (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
+ 'gdbmi))
(if gud-tooltip-mode
(progn
(dolist (buffer (buffer-list))
(unless (eq buffer gud-comint-buffer)
(with-current-buffer buffer
- (when (and (memq gud-minor-mode '(gdbmi gdba))
+ (when (and (eq gud-minor-mode 'gdbmi)
(not (string-match "\\`\\*.+\\*\\'"
(buffer-name))))
(make-local-variable 'gdb-define-alist)
(kill-local-variable 'gdb-define-alist)
(remove-hook 'after-save-hook 'gdb-create-define-alist t))))
+(define-obsolete-variable-alias 'tooltip-gud-modes
+ 'gud-tooltip-modes "22.1")
+
(defcustom gud-tooltip-modes '(gud-mode c-mode c++-mode fortran-mode
python-mode)
"List of modes for which to enable GUD tooltips."
:group 'gud
:group 'tooltip)
+(define-obsolete-variable-alias 'tooltip-gud-display
+ 'gud-tooltip-display "22.1")
+
(defcustom gud-tooltip-display
'((eq (tooltip-event-buffer gud-tooltip-event)
(marker-buffer gud-overlay-arrow-position)))
:group 'gud
:group 'tooltip)
-(define-obsolete-variable-alias 'tooltip-gud-modes
- 'gud-tooltip-modes "22.1")
-(define-obsolete-variable-alias 'tooltip-gud-display
- 'gud-tooltip-display "22.1")
-
;;; Reacting on mouse movements
(defun gud-tooltip-change-major-mode ()
(remove-hook 'post-command-hook
'gud-tooltip-activate-mouse-motions-if-enabled)
(dolist (buffer (buffer-list))
- (save-excursion
- (set-buffer buffer)
+ (with-current-buffer buffer
(if (and gud-tooltip-mode
(memq major-mode gud-tooltip-modes))
(gud-tooltip-activate-mouse-motions t)
ACTIVATEP non-nil means activate mouse motion events."
(if activatep
(progn
- (make-local-variable 'gud-tooltip-mouse-motions-active)
- (setq gud-tooltip-mouse-motions-active t)
- (make-local-variable 'track-mouse)
- (setq track-mouse t))
+ (set (make-local-variable 'gud-tooltip-mouse-motions-active) t)
+ (set (make-local-variable 'track-mouse) t))
(when gud-tooltip-mouse-motions-active
(kill-local-variable 'gud-tooltip-mouse-motions-active)
(kill-local-variable 'track-mouse))))
+(defvar tooltip-last-mouse-motion-event)
+(declare-function tooltip-hide "tooltip" (&optional ignored-arg))
+(declare-function tooltip-start-delayed-tip "tooltip" ())
+
(defun gud-tooltip-mouse-motion (event)
"Command handler for mouse movement events in `global-map'."
(interactive "e")
(defvar gud-tooltip-event nil
"The mouse movement event that led to a tooltip display.
-This event can be examined by forms in GUD-TOOLTIP-DISPLAY.")
+This event can be examined by forms in `gud-tooltip-display'.")
(defun gud-tooltip-dereference (&optional arg)
"Toggle whether tooltips should show `* expr' or `expr'.
(define-obsolete-function-alias 'tooltip-gud-toggle-dereference
'gud-tooltip-dereference "22.1")
+(defvar tooltip-use-echo-area)
+(declare-function tooltip-show "tooltip" (text &optional use-echo-area))
+(declare-function tooltip-strip-prompt "tooltip" (process output))
; This will only display data that comes in one chunk.
; Larger arrays (say 400 elements) are displayed in
; the tooltip incompletely and spill over into the gud buffer.
; Switching the process-filter creates timing problems and
-; it may be difficult to do better. Using annotations as in
-; gdb-ui.el gets round this problem.
+; it may be difficult to do better. Using GDB/MI as in
+; gdb-mi.el gets round this problem.
(defun gud-tooltip-process-output (process output)
"Process debugger output and show it in a tooltip window."
(set-process-filter process gud-tooltip-original-filter)
(defun gud-tooltip-print-command (expr)
"Return a suitable command to print the expression EXPR."
(case gud-minor-mode
- (gdba (concat "server print " expr))
- ((dbx gdbmi) (concat "print " expr))
+ (gdbmi (concat "-data-evaluate-expression " expr))
+ (dbx (concat "print " expr))
((xdb pdb) (concat "p " expr))
(sdb (concat expr "/"))))
+(declare-function gdb-input "gdb-mi" (item))
+(declare-function tooltip-expr-to-print "tooltip" (event))
+(declare-function tooltip-event-buffer "tooltip" (event))
+
(defun gud-tooltip-tips (event)
"Show tip for identifier or selection under the mouse.
The mouse must either point at an identifier or inside a selected
-region for the tip window to be shown. If gud-tooltip-dereference is t,
-add a `*' in front of the printed expression. In the case of a C program
+region for the tip window to be shown. If `gud-tooltip-dereference' is t,
+add a `*' in front of the printed expression. In the case of a C program
controlled by GDB, show the associated #define directives when program is
not executing.
(buffer-name gud-comint-buffer); might be killed
(setq process (get-buffer-process gud-comint-buffer))
(posn-point (event-end event))
- (or (and (eq gud-minor-mode 'gdba) (not gdb-active-process))
+ (or (and (eq gud-minor-mode 'gdbmi) (not gdb-active-process))
(progn (setq gud-tooltip-event event)
(eval (cons 'and gud-tooltip-display)))))
(let ((expr (tooltip-expr-to-print event)))
(when expr
- (if (and (eq gud-minor-mode 'gdba)
+ (if (and (eq gud-minor-mode 'gdbmi)
(not gdb-active-process))
(progn
- (with-current-buffer
- (window-buffer (let ((mouse (mouse-position)))
- (window-at (cadr mouse)
- (cddr mouse))))
+ (with-current-buffer (tooltip-event-buffer event)
(let ((define-elt (assoc expr gdb-define-alist)))
(unless (null define-elt)
(tooltip-show
(message-box "Using GUD tooltips in this mode is unsafe\n\
so they have been disabled."))
(unless (null cmd) ; CMD can be nil if unknown debugger
- (if (memq gud-minor-mode '(gdba gdbmi))
+ (if (eq gud-minor-mode 'gdbmi)
(if gdb-macro-info
- (gdb-enqueue-input
+ (gdb-input
(list (concat
- gdb-server-prefix "macro expand " expr "\n")
+ "server macro expand " expr "\n")
`(lambda () (gdb-tooltip-print-1 ,expr))))
- (gdb-enqueue-input
+ (gdb-input
(list (concat cmd "\n")
`(lambda () (gdb-tooltip-print ,expr)))))
(setq gud-tooltip-original-filter (process-filter process))
(provide 'gud)
-;;; arch-tag: 6d990948-df65-461a-be39-1c7fb83ac4c4
;;; gud.el ends here