mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-23 07:19:15 +00:00
Set no-byte-compile local variable t to work around a byte-compiler bug.
(gud-def, global-map): Move C-x C-a commands to global map. Restore original C-x SPC global binding.
This commit is contained in:
parent
8c0aaf4075
commit
5b08a462d2
121
lisp/gud.el
121
lisp/gud.el
@ -1,7 +1,7 @@
|
||||
;;; gud.el --- Grand Unified Debugger mode for gdb, sdb, or dbx under Emacs
|
||||
|
||||
;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
|
||||
;; Version: 1.2
|
||||
;; Version: 1.3
|
||||
;; Keywords: unix, tools
|
||||
|
||||
;; Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
@ -30,49 +30,19 @@
|
||||
;; The overloading code was then rewritten by Barry Warsaw <bwarsaw@cen.com>,
|
||||
;; who also hacked the mode to use comint.el.
|
||||
|
||||
;; This code will not work under Emacs 18. It relies on Emacs 19's
|
||||
;; minor-mode-keymap support and the find-tag-noselect entry point of etags.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'comint)
|
||||
(require 'etags)
|
||||
|
||||
;; ======================================================================
|
||||
;; minor-mode machinery for C buffers visited by GUD
|
||||
;; GUD commands must be visible in C buffers visited by GUD
|
||||
|
||||
(defvar gud-key-prefix "\C-x\C-a"
|
||||
"Prefix of all GUD minor-mode commands valid in C buffers.")
|
||||
"Prefix of all GUD commands valid in C buffers.")
|
||||
|
||||
(defvar gud-minor-mode nil)
|
||||
(or (assq 'gud-minor-mode minor-mode-alist)
|
||||
(setq minor-mode-alist
|
||||
(cons '(gud-minor-mode " GUD") minor-mode-alist)))
|
||||
|
||||
(defvar gud-mode-map nil)
|
||||
(if gud-mode-map
|
||||
nil
|
||||
(setq gud-mode-map (make-sparse-keymap))
|
||||
(define-key gud-mode-map gud-key-prefix (make-sparse-keymap))
|
||||
(define-key gud-mode-map (concat gud-key-prefix "\C-l") 'gud-refresh)
|
||||
)
|
||||
|
||||
(or (assq 'gud-minor-mode minor-mode-map-alist)
|
||||
(setq minor-mode-map-alist
|
||||
(cons
|
||||
(cons 'gud-minor-mode gud-mode-map)
|
||||
minor-mode-map-alist)))
|
||||
|
||||
(defun gud-minor-mode (&optional enable)
|
||||
"GUD minor mode is enabled in C buffers visited due to a GUD stop at
|
||||
breakpoint. All GUD-specific commands defined in GUD major mode will work,
|
||||
but they get their current file and current line number from the context of
|
||||
this buffer."
|
||||
(interactive "P")
|
||||
(setq gud-minor-mode
|
||||
(if (null enable) (not gud-minor-mode)
|
||||
(> (prefix-numeric-value enable) 0)))
|
||||
)
|
||||
(global-set-key (concat gud-key-prefix "\C-l") 'gud-refresh)
|
||||
(global-set-key "\C-x " 'gud-break) ;; backward compatibility hack
|
||||
|
||||
;; ======================================================================
|
||||
;; the overloading mechanism
|
||||
@ -104,9 +74,8 @@ This association list has elements of the form
|
||||
;; 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
|
||||
;; it the docstring DOC, and binds that function to KEY in the GUD
|
||||
;; major mode. The function is also bound in the GUD minor-mode
|
||||
;; keymap. If a numeric prefix argument is given to FUNC, it gets
|
||||
;; sent after NAME.
|
||||
;; 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
|
||||
@ -119,22 +88,27 @@ are interpreted specially if present. These are:
|
||||
%a text of the hexadecimal address surrounding point
|
||||
%p prefix argument to the command (if any) as a number
|
||||
|
||||
The `current' source file is the file of the current buffer (if we're in a
|
||||
C file with gud-minor-mode active) or the source file current at the last
|
||||
break or step (if we're in the GUD buffer).
|
||||
The `current' line is that of the current buffer (if we're in a source
|
||||
file with gud-minor-mode active) or the source line number at the last
|
||||
break or step (if we're in the GUD buffer)."
|
||||
The `current' source file is the file of the current buffer (if
|
||||
we're in a C file) or the source file current at the last break or
|
||||
step (if we're in the GUD buffer).
|
||||
The `current' line is that of the current buffer (if we're in a
|
||||
source file) or the source line number at the last break or step (if
|
||||
we're in the GUD buffer)."
|
||||
(list 'progn
|
||||
(list 'defun func '(arg)
|
||||
(or doc "")
|
||||
'(interactive "p")
|
||||
(list 'gud-call cmd 'arg))
|
||||
(if key
|
||||
(list 'define-key
|
||||
'gud-mode-map
|
||||
(concat gud-key-prefix key)
|
||||
(list 'quote func)))))
|
||||
(progn
|
||||
(list 'define-key
|
||||
'(current-local-map)
|
||||
(concat "\C-c" key)
|
||||
(list 'quote func))
|
||||
(list 'global-set-key
|
||||
(concat gud-key-prefix key)
|
||||
(list 'quote func))
|
||||
))))
|
||||
|
||||
;; Where gud-display-frame should put the debugging arrow. This is
|
||||
;; set by the marker-filter, which scans the debugger's output for
|
||||
@ -202,6 +176,8 @@ and source-file directory for your debugger."
|
||||
(gud-find-file . gud-gdb-find-file)
|
||||
))
|
||||
|
||||
(gud-common-init args)
|
||||
|
||||
(gud-def gud-break "break %f:%l" "b" "Set breakpoint at current line.")
|
||||
(gud-def gud-tbreak "tbreak %f:%l" "t" "Set breakpoint at current line.")
|
||||
(gud-def gud-remove "clear %l" "d" "Remove breakpoint at current line")
|
||||
@ -214,8 +190,6 @@ and source-file directory for your debugger."
|
||||
(gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).")
|
||||
(gud-def gud-print "print %e" "p" "Evaluate C expression at point.")
|
||||
|
||||
(gud-common-init args)
|
||||
|
||||
(setq comint-prompt-regexp "^(.*gdb[+]?) *")
|
||||
(run-hooks 'gdb-mode-hook)
|
||||
)
|
||||
@ -267,9 +241,7 @@ and source-file directory for your debugger."
|
||||
"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 ")
|
||||
|
||||
(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."))
|
||||
@ -278,6 +250,8 @@ and source-file directory for your debugger."
|
||||
(gud-find-file . gud-sdb-find-file)
|
||||
))
|
||||
|
||||
(gud-common-init args)
|
||||
|
||||
(gud-def gud-break "%l b" "b" "Set breakpoint at current line.")
|
||||
(gud-def gud-tbreak "%l c" "t" "Set temporary breakpoint at current line.")
|
||||
(gud-def gud-remove "%l d" "d" "Remove breakpoint at current line")
|
||||
@ -287,8 +261,6 @@ and source-file directory for your debugger."
|
||||
(gud-def gud-cont "c" "r" "Continue with display.")
|
||||
(gud-def gud-print "%e/" "p" "Evaluate C expression at point.")
|
||||
|
||||
(gud-common-init args)
|
||||
|
||||
(setq comint-prompt-regexp "\\(^\\|\n\\)\\*")
|
||||
(run-hooks 'sdb-mode-hook)
|
||||
)
|
||||
@ -323,6 +295,8 @@ and source-file directory for your debugger."
|
||||
(gud-find-file . gud-dbx-find-file)
|
||||
))
|
||||
|
||||
(gud-common-init args)
|
||||
|
||||
(gud-def gud-break "stop at \"%f\":%l"
|
||||
"b" "Set breakpoint at current line.")
|
||||
(gud-def gud-remove "clear %l" "d" "Remove breakpoint at current line")
|
||||
@ -334,9 +308,7 @@ and source-file directory for your debugger."
|
||||
(gud-def gud-down "down %p" ">" "Down (numeric arg) stack frames.")
|
||||
(gud-def gud-print "print %e" "p" "Evaluate C expression at point.")
|
||||
|
||||
(gud-common-init args)
|
||||
(setq comint-prompt-regexp "^[^)]*dbx) *")
|
||||
|
||||
(run-hooks 'dbx-mode-hook)
|
||||
)
|
||||
|
||||
@ -398,8 +370,6 @@ After startup, the following commands are available in both the GUD
|
||||
interaction buffer and any source buffer GUD visits due to a breakpoint stop
|
||||
or step operation:
|
||||
|
||||
\\{gud-mode-map}
|
||||
|
||||
\\[gud-break] sets a breakpoint at the current file and line. In the
|
||||
GUD buffer, the current file and line are those of the last breakpoint or
|
||||
step. In a source buffer, they are the buffer's file and current line.
|
||||
@ -447,10 +417,6 @@ comint mode, which see."
|
||||
(setq mode-name "Debugger")
|
||||
(setq mode-line-process '(": %s"))
|
||||
(use-local-map (copy-keymap comint-mode-map))
|
||||
(define-key (current-local-map)
|
||||
gud-key-prefix (lookup-key gud-mode-map gud-key-prefix))
|
||||
(define-key (current-local-map)
|
||||
"\C-c" (lookup-key gud-mode-map gud-key-prefix))
|
||||
(make-local-variable 'gud-last-frame)
|
||||
(setq gud-last-frame nil)
|
||||
(make-local-variable 'comint-prompt-regexp)
|
||||
@ -535,11 +501,9 @@ comint mode, which see."
|
||||
;; buffer killed
|
||||
;; Stop displaying an arrow in a source file.
|
||||
(setq overlay-arrow-position nil)
|
||||
(setq gud-minor-mode nil)
|
||||
(set-process-buffer proc nil))
|
||||
((memq (process-status proc) '(signal exit))
|
||||
;; Stop displaying an arrow in a source file.
|
||||
(setq gud-minor-mode nil)
|
||||
(setq overlay-arrow-position nil)
|
||||
;; Fix the mode line.
|
||||
(setq mode-line-process
|
||||
@ -588,10 +552,12 @@ Obeying it means displaying in another window the specified file and line."
|
||||
(let* ((buffer (gud-find-file true-file))
|
||||
(window (display-buffer buffer))
|
||||
(pos))
|
||||
(if (equal buffer (current-buffer))
|
||||
nil
|
||||
(setq buffer-read-only nil))
|
||||
(save-excursion
|
||||
(set-buffer buffer)
|
||||
(make-local-variable 'gud-minor-mode)
|
||||
(setq gud-minor-mode t)
|
||||
(setq buffer-read-only t)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-line line)
|
||||
@ -607,16 +573,16 @@ Obeying it means displaying in another window the specified file and line."
|
||||
|
||||
;;; The gud-call function must do the right thing whether its invoking
|
||||
;;; keystroke is from the GUD buffer itself (via major-mode binding)
|
||||
;;; or a C buffer in GUD minor mode. In the former case, we want to
|
||||
;;; supply data from gud-last-frame. Here's how we do it:
|
||||
;;; or a C buffer. In the former case, we want to supply data from
|
||||
;;; gud-last-frame. Here's how we do it:
|
||||
|
||||
(defun gud-format-command (str arg)
|
||||
(let ((minor (not (eq (current-buffer) gud-comint-buffer))))
|
||||
(let ((insource (not (eq (current-buffer) gud-comint-buffer))))
|
||||
(if (string-match "\\(.*\\)%f\\(.*\\)" str)
|
||||
(progn
|
||||
(setq str (concat
|
||||
(substring str (match-beginning 1) (match-end 1))
|
||||
(if minor
|
||||
(if insource
|
||||
(buffer-file-name)
|
||||
(car gud-last-frame))
|
||||
(substring str (match-beginning 2) (match-end 2))))))
|
||||
@ -624,7 +590,7 @@ Obeying it means displaying in another window the specified file and line."
|
||||
(progn
|
||||
(setq str (concat
|
||||
(substring str (match-beginning 1) (match-end 1))
|
||||
(if minor
|
||||
(if insource
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
(save-restriction (widen)
|
||||
@ -851,4 +817,17 @@ Link exprs of the form:
|
||||
)
|
||||
)
|
||||
|
||||
;;; There appears to be a bug in the byte compiler somewhere near macro
|
||||
;;; handling that (a) generates a spurious message about gud-key-prefix
|
||||
;;; when the global-set-key clause in gud-def is compiled, (b) generates
|
||||
;;; incorrect bytecode for gud-def. The symptom of this incorrectness
|
||||
;;; is that loading gud.elc brings in a compiled gud-def that doesn't
|
||||
;;; properly perform both global (C-x C-a) and local (C-c) bindings.
|
||||
;;; The workaround is to always load from source. Consequently, we try
|
||||
;;; to disable byte-compilation here.
|
||||
;;;
|
||||
;;; Local Variables:
|
||||
;;; no-byte-compile: t
|
||||
;;; End:
|
||||
|
||||
;;; gud.el ends here
|
||||
|
Loading…
Reference in New Issue
Block a user