]> code.delx.au - gnu-emacs/blobdiff - lisp/progmodes/gud.el
Update copyright year to 2014 by running admin/update-copyright.
[gnu-emacs] / lisp / progmodes / gud.el
index 5fabe5086db06b2944112389aeda66a643ff95c0..f1a8be240131d2ef682b9c18131e29d7f2049328 100644 (file)
@@ -1,6 +1,7 @@
 ;;; gud.el --- Grand Unified Debugger mode for running GDB and other debuggers
 
 ;;; gud.el --- Grand Unified Debugger mode for running GDB and other debuggers
 
-;; Copyright (C) 1992-1996, 1998, 2000-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1992-1996, 1998, 2000-2014 Free Software Foundation,
+;; Inc.
 
 ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
 ;; Maintainer: FSF
 
 ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
 ;; Maintainer: FSF
@@ -37,8 +38,6 @@
 
 ;;; Code:
 
 
 ;;; Code:
 
-(eval-when-compile (require 'cl)) ; for case macro
-
 (require 'comint)
 
 (defvar gdb-active-process)
 (require 'comint)
 
 (defvar gdb-active-process)
 (defvar gdb-show-changed-values)
 (defvar gdb-source-window)
 (defvar gdb-var-list)
 (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 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
 
 
 ;; ======================================================================
 ;; 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) and jdb."
+  "The \"Grand Unified Debugger\" interface.
+Supported debuggers include gdb, sdb, dbx, xdb, perldb,
+pdb (Python), and jdb."
   :group 'processes
   :group 'tools)
 
 
 (defcustom gud-key-prefix "\C-x\C-a"
   "Prefix of all GUD commands valid in C buffers."
   :group 'processes
   :group 'tools)
 
 
 (defcustom gud-key-prefix "\C-x\C-a"
   "Prefix of all GUD commands valid in C buffers."
-  :type 'string
+  :type 'key-sequence
   :group 'gud)
 
   :group 'gud)
 
-(global-set-key (concat gud-key-prefix "\C-l") 'gud-refresh)
-(define-key ctl-x-map " " 'gud-break)  ;; backward compatibility hack
+(global-set-key (vconcat gud-key-prefix "\C-l") 'gud-refresh)
+;; (define-key ctl-x-map " " 'gud-break); backward compatibility hack
 
 (defvar gud-marker-filter nil)
 (put 'gud-marker-filter 'permanent-local t)
 
 (defvar gud-marker-filter nil)
 (put 'gud-marker-filter 'permanent-local t)
@@ -149,7 +146,8 @@ Used to gray out relevant toolbar icons.")
     ([run]     menu-item "Run" gud-run
                   :enable (not gud-running)
                  :visible (memq gud-minor-mode '(gdbmi gdb dbx jdb)))
     ([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
+    ([go]      menu-item (if (bound-and-true-p gdb-active-process)
+                             "Continue" "Run") gud-go
                  :visible (and (eq gud-minor-mode 'gdbmi)
                                 (gdb-show-run-p)))
     ([stop]    menu-item "Stop" gud-stop-subjob
                  :visible (and (eq gud-minor-mode 'gdbmi)
                                 (gdb-show-run-p)))
     ([stop]    menu-item "Stop" gud-stop-subjob
@@ -179,7 +177,7 @@ Used to gray out relevant toolbar icons.")
                                 '(gdbmi gdb dbx xdb jdb pdb)))
     ([pp]      menu-item "Print S-expression" gud-pp
                   :enable (and (not gud-running)
                                 '(gdbmi gdb dbx xdb jdb pdb)))
     ([pp]      menu-item "Print S-expression" gud-pp
                   :enable (and (not gud-running)
-                                 gdb-active-process)
+                                 (bound-and-true-p gdb-active-process))
                  :visible (and (string-equal
                                 (buffer-local-value
                                  'gud-target-name gud-comint-buffer) "emacs")
                  :visible (and (string-equal
                                 (buffer-local-value
                                  'gud-target-name gud-comint-buffer) "emacs")
@@ -323,8 +321,9 @@ Uses `gud-<MINOR-MODE>-directories' to find the source files."
     (when buf
       ;; Copy `gud-minor-mode' to the found buffer to turn on the menu.
       (with-current-buffer buf
     (when buf
       ;; Copy `gud-minor-mode' to the found buffer to turn on the menu.
       (with-current-buffer buf
-       (set (make-local-variable 'gud-minor-mode) minor-mode)
-       (set (make-local-variable 'tool-bar-map) gud-tool-bar-map)
+       (setq-local gud-minor-mode minor-mode)
+       (if (boundp 'tool-bar-map)      ; not --without-x
+           (setq-local tool-bar-map gud-tool-bar-map))
        (when (and gud-tooltip-mode
                   (eq gud-minor-mode 'gdbmi))
          (make-local-variable 'gdb-define-alist)
        (when (and gud-tooltip-mode
                   (eq gud-minor-mode 'gdbmi))
          (make-local-variable 'gdb-define-alist)
@@ -415,7 +414,7 @@ we're in the GUD buffer)."
 \f
 ;; ======================================================================
 ;; speedbar support functions and variables.
 \f
 ;; ======================================================================
 ;; speedbar support functions and variables.
-(eval-when-compile (require 'speedbar))        ;For speedbar-with-attached-buffer.
+(eval-when-compile (require 'dframe)) ; for dframe-with-attached-buffer
 
 (defvar gud-last-speedbar-stackframe nil
   "Description of the currently displayed GUD stack.
 
 (defvar gud-last-speedbar-stackframe nil
   "Description of the currently displayed GUD stack.
@@ -424,19 +423,24 @@ 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.")
 
 (defvar gud-speedbar-key-map nil
   "Keymap used when in the buffers display mode.")
 
+;; At runtime, will be pulled in as a require of speedbar.
+(declare-function dframe-message "dframe" (fmt &rest args))
+
 (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 7 var)
 (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 7 var)
-       (speedbar-message "%s: %s" (nth 7 var) (nth 3 var))
-      (speedbar-message "%s" (nth 3 var)))))
+       (dframe-message "%s: %s" (nth 7 var) (nth 3 var))
+      (dframe-message "%s" (nth 3 var)))))
+
+(declare-function speedbar-make-specialized-keymap "speedbar" ())
+(declare-function speedbar-add-expansion-list "speedbar" (new-list))
+(defvar speedbar-mode-functions-list)
 
 (defun gud-install-speedbar-variables ()
   "Install those variables used by speedbar to enhance gud/gdb."
 
 (defun gud-install-speedbar-variables ()
   "Install those variables used by speedbar to enhance gud/gdb."
-  (if gud-speedbar-key-map
-      nil
+  (unless gud-speedbar-key-map
     (setq gud-speedbar-key-map (speedbar-make-specialized-keymap))
     (setq gud-speedbar-key-map (speedbar-make-specialized-keymap))
-
     (define-key gud-speedbar-key-map "j" 'speedbar-edit-line)
     (define-key gud-speedbar-key-map "e" 'speedbar-edit-line)
     (define-key gud-speedbar-key-map "\C-m" 'speedbar-edit-line)
     (define-key gud-speedbar-key-map "j" 'speedbar-edit-line)
     (define-key gud-speedbar-key-map "e" 'speedbar-edit-line)
     (define-key gud-speedbar-key-map "\C-m" 'speedbar-edit-line)
@@ -485,6 +489,13 @@ The value t means that there is no stack, and we are in display-file mode.")
 DIRECTORY and ZERO are not used, but are required by the caller."
   (gud-speedbar-buttons gud-comint-buffer))
 
 DIRECTORY and ZERO are not used, but are required by the caller."
   (gud-speedbar-buttons gud-comint-buffer))
 
+(declare-function speedbar-make-tag-line "speedbar"
+                  (type char func data tag tfunc tdata tface depth))
+(declare-function speedbar-remove-localized-speedbar-support "speedbar"
+                  (buffer))
+(declare-function speedbar-insert-button "speedbar"
+                 (text face mouse function &optional token prevline))
+
 (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
 (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
@@ -527,10 +538,10 @@ required by the caller."
                       nil 'gdb-edit-value)
                   nil
                   (if gdb-show-changed-values
                       nil 'gdb-edit-value)
                   nil
                   (if gdb-show-changed-values
-                      (or parent (case status
-                                   (changed 'font-lock-warning-face)
-                                   (out-of-scope 'shadow)
-                                   (t t)))
+                      (or parent (pcase status
+                                   (`changed 'font-lock-warning-face)
+                                   (`out-of-scope 'shadow)
+                                   (_ t)))
                     t)
                   depth)
                (if (eq status 'out-of-scope) (setq parent 'shadow))
                     t)
                   depth)
                (if (eq status 'out-of-scope) (setq parent 'shadow))
@@ -548,10 +559,10 @@ required by the caller."
                         nil 'gdb-edit-value)
                     nil
                     (if gdb-show-changed-values
                         nil 'gdb-edit-value)
                     nil
                     (if gdb-show-changed-values
-                        (or parent (case status
-                                     (changed 'font-lock-warning-face)
-                                     (out-of-scope 'shadow)
-                                     (t t)))
+                        (or parent (pcase status
+                                     (`changed 'font-lock-warning-face)
+                                     (`out-of-scope 'shadow)
+                                     (_ t)))
                       t)
                     depth)
                  (speedbar-make-tag-line
                       t)
                     depth)
                  (speedbar-make-tag-line
@@ -706,6 +717,16 @@ The option \"--fullname\" must be included in this value."
 (defvar gud-filter-pending-text nil
   "Non-nil means this is text that has been saved for later in `gud-filter'.")
 
 (defvar gud-filter-pending-text nil
   "Non-nil means this is text that has been saved for later in `gud-filter'.")
 
+;; One of the nice features of GDB is its impressive support for
+;; context-sensitive command completion.  We preserve that feature
+;; in the GUD buffer by using a GDB command designed just for Emacs.
+
+(defvar gud-gdb-completion-function nil
+  "Completion function for GDB commands.
+It receives two arguments: COMMAND, the prefix for which we seek
+completion; and CONTEXT, the text before COMMAND on the line.
+It should return a list of completion strings.")
+
 ;; If in gdb mode, gdb-mi is loaded.
 (declare-function gdb-restore-windows "gdb-mi" ())
 
 ;; If in gdb mode, gdb-mi is loaded.
 (declare-function gdb-restore-windows "gdb-mi" ())
 
@@ -749,7 +770,7 @@ directory and source-file directory for your debugger."
           "Evaluate C dereferenced pointer expression at point.")
 
   ;; For debugging Emacs only.
           "Evaluate C dereferenced pointer expression at point.")
 
   ;; For debugging Emacs only.
-  (gud-def gud-pv "pv1 %e"      "\C-v" "Print the value of the lisp variable.")
+  (gud-def gud-pv "pv %e"      "\C-v" "Print the value of the lisp variable.")
 
   (gud-def gud-until  "until %l" "\C-u" "Continue to current line.")
   (gud-def gud-run    "run"     nil    "Run the program.")
 
   (gud-def gud-until  "until %l" "\C-u" "Continue to current line.")
   (gud-def gud-run    "run"     nil    "Run the program.")
@@ -766,16 +787,6 @@ directory and source-file directory for your debugger."
   (setq gud-filter-pending-text nil)
   (run-hooks 'gud-gdb-mode-hook))
 
   (setq gud-filter-pending-text nil)
   (run-hooks 'gud-gdb-mode-hook))
 
-;; One of the nice features of GDB is its impressive support for
-;; context-sensitive command completion.  We preserve that feature
-;; in the GUD buffer by using a GDB command designed just for Emacs.
-
-(defvar gud-gdb-completion-function nil
-  "Completion function for GDB commands.
-It receives two arguments: COMMAND, the prefix for which we seek
-completion; and CONTEXT, the text before COMMAND on the line.
-It should return a list of completion strings.")
-
 ;; The completion process filter indicates when it is finished.
 (defvar gud-gdb-fetch-lines-in-progress)
 
 ;; The completion process filter indicates when it is finished.
 (defvar gud-gdb-fetch-lines-in-progress)
 
@@ -883,9 +894,14 @@ It is passed through `gud-gdb-marker-filter' before we look at it."
 
 ;; gdb speedbar functions
 
 
 ;; gdb speedbar functions
 
+;; Part of the macro expansion of dframe-with-attached-buffer.
+;; At runtime, will be pulled in as a require of speedbar.
+(declare-function dframe-select-attached-frame "dframe" (&optional frame))
+(declare-function dframe-maybee-jump-to-attached-frame "dframe" ())
+
 (defun gud-gdb-goto-stackframe (_text token _indent)
   "Goto the stackframe described by TEXT, TOKEN, and INDENT."
 (defun gud-gdb-goto-stackframe (_text token _indent)
   "Goto the stackframe described by TEXT, TOKEN, and INDENT."
-  (speedbar-with-attached-buffer
+  (dframe-with-attached-buffer
    (gud-basic-call (concat "server frame " (nth 1 token)))
    (sit-for 1)))
 
    (gud-basic-call (concat "server frame " (nth 1 token)))
    (sit-for 1)))
 
@@ -1046,7 +1062,7 @@ and source-file directory for your debugger."
 (defvar gud-dbx-history nil)
 
 (defcustom gud-dbx-directories nil
 (defvar gud-dbx-history nil)
 
 (defcustom gud-dbx-directories nil
-  "*A list of directories that dbx should search for source code.
+  "A list of directories that dbx should search for source code.
 If nil, only source files in the program directory
 will be known to dbx.
 
 If nil, only source files in the program directory
 will be known to dbx.
 
@@ -1358,7 +1374,7 @@ and source-file directory for your debugger."
 (defvar gud-xdb-history nil)
 
 (defcustom gud-xdb-directories nil
 (defvar gud-xdb-history nil)
 
 (defcustom gud-xdb-directories nil
-  "*A list of directories that xdb should search for source code.
+  "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.
 
 If nil, only source files in the program directory
 will be known to xdb.
 
@@ -1486,14 +1502,38 @@ into one that invokes an Emacs-enabled debugging session.
   (let ((output ""))
 
     ;; Process all the complete markers in this chunk.
   (let ((output ""))
 
     ;; Process all the complete markers in this chunk.
-    (while (string-match "\032\032\\(\\([a-zA-Z]:\\)?[^:\n]*\\):\\([0-9]*\\):.*\n"
-                        gud-marker-acc)
+    ;;
+    ;; Here I match the string coming out of perldb.
+    ;; The strings can look like any of
+    ;;
+    ;;  "\032\032/tmp/tst.pl:6:0\n"
+    ;;  "\032\032(eval 5)[/tmp/tst.pl:6]:3:0\n"
+    ;;  "\032\032(eval 17)[Basic/Core/Core.pm.PL (i.e. PDL::Core.pm):2931]:1:0\n"
+    ;;
+    ;; From those I want the filename and the line number.  First I look for
+    ;; the eval case.  If that doesn't match, I look for the "normal" case.
+    (while
+        (string-match
+         (eval-when-compile
+           (let ((file-re "\\(?:[a-zA-Z]:\\)?[^:\n]*"))
+             (concat "\032\032\\(?:"
+                     (concat
+                      "(eval [0-9]+)\\["
+                      "\\(" file-re "\\)" ; Filename.
+                      "\\(?: (i\\.e\\. [^)]*)\\)?"
+                      ":\\([0-9]*\\)\\]") ; Line number.
+                     "\\|"
+                     (concat
+                      "\\(?1:" file-re "\\)" ; Filename.
+                      ":\\(?2:[0-9]*\\)")    ; Line number.
+                     "\\):.*\n")))
+         gud-marker-acc)
       (setq
 
        ;; Extract the frame position from the marker.
        gud-last-frame
        (cons (match-string 1 gud-marker-acc)
       (setq
 
        ;; Extract the frame position from the marker.
        gud-last-frame
        (cons (match-string 1 gud-marker-acc)
-            (string-to-number (match-string 3 gud-marker-acc)))
+            (string-to-number (match-string 2 gud-marker-acc)))
 
        ;; Append any text before the marker to the output we're going
        ;; to return - we don't include the marker in this text.
 
        ;; Append any text before the marker to the output we're going
        ;; to return - we don't include the marker in this text.
@@ -1646,8 +1686,8 @@ and source-file directory for your debugger."
   (gud-common-init command-line nil 'gud-pdb-marker-filter)
   (set (make-local-variable 'gud-minor-mode) 'pdb)
 
   (gud-common-init command-line nil 'gud-pdb-marker-filter)
   (set (make-local-variable 'gud-minor-mode) 'pdb)
 
-  (gud-def gud-break  "break %f:%l"  "\C-b" "Set breakpoint at current line.")
-  (gud-def gud-remove "clear %f:%l"  "\C-d" "Remove breakpoint at current line")
+  (gud-def gud-break  "break %d%f:%l"  "\C-b" "Set breakpoint at current line.")
+  (gud-def gud-remove "clear %d%f:%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-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.")
@@ -1811,7 +1851,7 @@ source file information.")
 
 ;; List of Java source file directories.
 (defvar gud-jdb-directories (list ".")
 
 ;; List of Java source file directories.
 (defvar gud-jdb-directories (list ".")
-  "*A list of directories that gud jdb should search for source code.
+  "A list of directories that gud jdb should search for source code.
 The file names should be absolute, or relative to the current
 directory.
 
 The file names should be absolute, or relative to the current
 directory.
 
@@ -2120,10 +2160,8 @@ relative to a classpath directory."
                    (split-string
                     ;; Eliminate any subclass references in the class
                     ;; name string. These start with a "$"
                    (split-string
                     ;; Eliminate any subclass references in the class
                     ;; name string. These start with a "$"
-                    ((lambda (x)
-                       (if (string-match "$.*" x)
-                           (replace-match "" t t x) p))
-                     p)
+                     (if (string-match "$.*" p)
+                         (replace-match "" t t p) p)
                     "\\.") "/")
         ".java"))
        (cplist (append gud-jdb-sourcepath gud-jdb-classpath))
                     "\\.") "/")
         ".java"))
        (cplist (append gud-jdb-sourcepath gud-jdb-classpath))
@@ -2443,7 +2481,8 @@ comint mode, which see."
   (setq mode-line-process '(":%s"))
   (define-key (current-local-map) "\C-c\C-l" 'gud-refresh)
   (set (make-local-variable 'gud-last-frame) nil)
   (setq mode-line-process '(":%s"))
   (define-key (current-local-map) "\C-c\C-l" 'gud-refresh)
   (set (make-local-variable 'gud-last-frame) nil)
-  (set (make-local-variable 'tool-bar-map) gud-tool-bar-map)
+  (if (boundp 'tool-bar-map)            ; not --without-x
+      (setq-local tool-bar-map gud-tool-bar-map))
   (make-local-variable 'comint-prompt-regexp)
   ;; Don't put repeated commands in command history many times.
   (set (make-local-variable 'comint-input-ignoredups) t)
   (make-local-variable 'comint-prompt-regexp)
   ;; Don't put repeated commands in command history many times.
   (set (make-local-variable 'comint-input-ignoredups) t)
@@ -2611,6 +2650,8 @@ It is saved for when this flag is not set.")
 (add-to-list 'overlay-arrow-variable-list 'gud-overlay-arrow-position)
 
 (declare-function gdb-reset "gdb-mi" ())
 (add-to-list 'overlay-arrow-variable-list 'gud-overlay-arrow-position)
 
 (declare-function gdb-reset "gdb-mi" ())
+(declare-function speedbar-change-initial-expansion-list "speedbar" (new))
+(defvar speedbar-previously-used-expansion-list-name)
 
 (defun gud-sentinel (proc msg)
   (cond ((null (buffer-name (process-buffer proc)))
 
 (defun gud-sentinel (proc msg)
   (cond ((null (buffer-name (process-buffer proc)))
@@ -2618,7 +2659,7 @@ It is saved for when this flag is not set.")
         ;; Stop displaying an arrow in a source file.
         (setq gud-overlay-arrow-position nil)
         (set-process-buffer proc nil)
         ;; Stop displaying an arrow in a source file.
         (setq gud-overlay-arrow-position nil)
         (set-process-buffer proc nil)
-        (if (and (boundp 'speedbar-frame)
+        (if (and (boundp 'speedbar-initial-expansion-list-name)
                  (string-equal speedbar-initial-expansion-list-name "GUD"))
             (speedbar-change-initial-expansion-list
              speedbar-previously-used-expansion-list-name))
                  (string-equal speedbar-initial-expansion-list-name "GUD"))
             (speedbar-change-initial-expansion-list
              speedbar-previously-used-expansion-list-name))
@@ -2686,7 +2727,6 @@ Obeying it means displaying in another window the specified file and line."
 (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 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.
 
 ;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
 ;; and that its line LINE is visible.
@@ -2702,45 +2742,39 @@ Obeying it means displaying in another window the specified file and line."
            (gud-find-file true-file)))
         (window (and buffer
                      (or (get-buffer-window buffer)
            (gud-find-file true-file)))
         (window (and buffer
                      (or (get-buffer-window buffer)
-                         (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 'visible))))
                          (display-buffer buffer))))
         (pos))
                          (display-buffer buffer))))
         (pos))
-    (if buffer
-       (progn
-         (with-current-buffer buffer
-           (unless (or (verify-visited-file-modtime buffer) gud-keep-buffer)
-                 (if (yes-or-no-p
-                      (format "File %s changed on disk.  Reread from disk? "
-                              (buffer-name)))
-                     (revert-buffer t t)
-                   (setq gud-keep-buffer t)))
-           (save-restriction
-             (widen)
-             (goto-char (point-min))
-             (forward-line (1- line))
-             (setq pos (point))
-             (or gud-overlay-arrow-position
-                 (setq gud-overlay-arrow-position (make-marker)))
-             (set-marker gud-overlay-arrow-position (point) (current-buffer))
-             ;; If they turned on hl-line, move the hl-line highlight to
-             ;; the arrow's line.
-             (when (featurep 'hl-line)
-               (cond
-                (global-hl-line-mode
-                 (global-hl-line-highlight))
-                ((and hl-line-mode hl-line-sticky-flag)
-                 (hl-line-highlight)))))
-           (cond ((or (< pos (point-min)) (> pos (point-max)))
-                  (widen)
-                  (goto-char pos))))
-         (when window
-           (set-window-point window gud-overlay-arrow-position)
-           (if (eq gud-minor-mode 'gdbmi)
-               (setq gdb-source-window window)))))))
+    (when buffer
+      (with-current-buffer buffer
+       (unless (or (verify-visited-file-modtime buffer) gud-keep-buffer)
+         (if (yes-or-no-p
+              (format "File %s changed on disk.  Reread from disk? "
+                      (buffer-name)))
+             (revert-buffer t t)
+           (setq gud-keep-buffer t)))
+       (save-restriction
+         (widen)
+         (goto-char (point-min))
+         (forward-line (1- line))
+         (setq pos (point))
+         (or gud-overlay-arrow-position
+             (setq gud-overlay-arrow-position (make-marker)))
+         (set-marker gud-overlay-arrow-position (point) (current-buffer))
+         ;; If they turned on hl-line, move the hl-line highlight to
+         ;; the arrow's line.
+         (when (featurep 'hl-line)
+           (cond
+            (global-hl-line-mode
+             (global-hl-line-highlight))
+            ((and hl-line-mode hl-line-sticky-flag)
+             (hl-line-highlight)))))
+       (cond ((or (< pos (point-min)) (> pos (point-max)))
+              (widen)
+              (goto-char pos))))
+      (when window
+       (set-window-point window gud-overlay-arrow-position)
+       (if (eq gud-minor-mode 'gdbmi)
+           (setq gdb-source-window window))))))
 
 ;; The gud-call function must do the right thing whether its invoking
 ;; keystroke is from the GUD buffer itself (via major-mode binding)
 
 ;; The gud-call function must do the right thing whether its invoking
 ;; keystroke is from the GUD buffer itself (via major-mode binding)
@@ -2762,10 +2796,9 @@ Obeying it means displaying in another window the specified file and line."
                                                  (buffer-file-name)
                                                (car frame)))))
         ((eq key ?F)
                                                  (buffer-file-name)
                                                (car frame)))))
         ((eq key ?F)
-         (setq subst (file-name-sans-extension
-                      (file-name-nondirectory (if insource
-                                                  (buffer-file-name)
-                                                (car frame))))))
+         (setq subst (file-name-base (if insource
+                                          (buffer-file-name)
+                                        (car frame)))))
         ((eq key ?d)
          (setq subst (file-name-directory (if insource
                                               (buffer-file-name)
         ((eq key ?d)
          (setq subst (file-name-directory (if insource
                                               (buffer-file-name)
@@ -3249,6 +3282,8 @@ Treats actions as defuns."
 
 ;;; Customizable settings
 
 
 ;;; Customizable settings
 
+(defvar tooltip-mode)
+
 ;;;###autoload
 (define-minor-mode gud-tooltip-mode
   "Toggle the display of GUD tooltips.
 ;;;###autoload
 (define-minor-mode gud-tooltip-mode
   "Toggle the display of GUD tooltips.
@@ -3319,6 +3354,9 @@ only tooltips in the buffer containing the overlay arrow."
   :group 'gud
   :group 'tooltip)
 
   :group 'gud
   :group 'tooltip)
 
+(make-obsolete-variable 'gud-tooltip-echo-area
+                       "disable Tooltip mode instead" "24.4" 'set)
+
 ;;; Reacting on mouse movements
 
 (defun gud-tooltip-change-major-mode ()
 ;;; Reacting on mouse movements
 
 (defun gud-tooltip-change-major-mode ()
@@ -3370,9 +3408,6 @@ ACTIVATEP non-nil means activate mouse motion events."
 
 ;;; Tips for `gud'
 
 
 ;;; Tips for `gud'
 
-(defvar gud-tooltip-original-filter nil
-  "Process filter to restore after GUD output has been received.")
-
 (defvar gud-tooltip-dereference nil
   "Non-nil means print expressions with a `*' in front of them.
 For C this would dereference a pointer expression.")
 (defvar gud-tooltip-dereference nil
   "Non-nil means print expressions with a `*' in front of them.
 For C this would dereference a pointer expression.")
@@ -3403,22 +3438,23 @@ With arg, dereference expr if ARG is positive, otherwise do not dereference."
 ; 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 GDB/MI as 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 GDB/MI as in
-; gdb-mi.el gets round this problem.
+; gdb-mi.el gets around this problem.
 (defun gud-tooltip-process-output (process output)
   "Process debugger output and show it in a tooltip window."
 (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)
+  (remove-function (process-filter process) #'gud-tooltip-process-output)
   (tooltip-show (tooltip-strip-prompt process output)
   (tooltip-show (tooltip-strip-prompt process output)
-               (or gud-tooltip-echo-area tooltip-use-echo-area)))
+               (or gud-tooltip-echo-area tooltip-use-echo-area
+                    (not tooltip-mode))))
 
 (defun gud-tooltip-print-command (expr)
   "Return a suitable command to print the expression EXPR."
 
 (defun gud-tooltip-print-command (expr)
   "Return a suitable command to print the expression EXPR."
-  (case gud-minor-mode
-       (gdbmi (concat "-data-evaluate-expression " expr))
-       (dbx (concat "print " expr))
-       ((xdb pdb) (concat "p " expr))
-       (sdb (concat expr "/"))))
+  (pcase gud-minor-mode
+    (`gdbmi (concat "-data-evaluate-expression \"" expr "\""))
+    (`dbx (concat "print " expr))
+    ((or `xdb `pdb) (concat "p " expr))
+    (`sdb (concat expr "/"))))
 
 
-(declare-function gdb-input "gdb-mi" (command handler))
+(declare-function gdb-input "gdb-mi" (command handler &optional trigger))
 (declare-function tooltip-expr-to-print "tooltip" (event))
 (declare-function tooltip-event-buffer "tooltip" (event))
 
 (declare-function tooltip-expr-to-print "tooltip" (event))
 (declare-function tooltip-event-buffer "tooltip" (event))
 
@@ -3451,14 +3487,18 @@ This function must return nil if it doesn't handle EVENT."
                    (unless (null define-elt)
                      (tooltip-show
                       (cdr define-elt)
                    (unless (null define-elt)
                      (tooltip-show
                       (cdr define-elt)
-                      (or gud-tooltip-echo-area tooltip-use-echo-area))
+                      (or gud-tooltip-echo-area tooltip-use-echo-area
+                           (not tooltip-mode)))
                      expr))))
            (when gud-tooltip-dereference
              (setq expr (concat "*" expr)))
            (let ((cmd (gud-tooltip-print-command expr)))
              (when (and gud-tooltip-mode (eq gud-minor-mode 'gdb))
                (gud-tooltip-mode -1)
                      expr))))
            (when gud-tooltip-dereference
              (setq expr (concat "*" expr)))
            (let ((cmd (gud-tooltip-print-command expr)))
              (when (and gud-tooltip-mode (eq gud-minor-mode 'gdb))
                (gud-tooltip-mode -1)
-               (message-box "Using GUD tooltips in this mode is unsafe\n\
+               ;; The blank before the newline is for MS-Windows,
+               ;; whose emulation of message box removes newlines and
+               ;; displays a single long line.
+               (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 (eq gud-minor-mode 'gdbmi)
 so they have been disabled."))
              (unless (null cmd) ; CMD can be nil if unknown debugger
                (if (eq gud-minor-mode 'gdbmi)
@@ -3470,8 +3510,8 @@ so they have been disabled."))
                       (gdb-input
                       (concat cmd "\n")
                       `(lambda () (gdb-tooltip-print ,expr))))
                       (gdb-input
                       (concat cmd "\n")
                       `(lambda () (gdb-tooltip-print ,expr))))
-                 (setq gud-tooltip-original-filter (process-filter process))
-                 (set-process-filter process 'gud-tooltip-process-output)
+                  (add-function :override (process-filter process)
+                                #'gud-tooltip-process-output)
                  (gud-basic-call cmd))
                expr))))))))
 
                  (gud-basic-call cmd))
                expr))))))))