comparison lisp/gud.el @ 2581:839d67a1dc58

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.
author Eric S. Raymond <esr@snark.thyrsus.com>
date Sun, 25 Apr 1993 22:26:45 +0000
parents 17a6b6d079cf
children e1277aec1738
comparison
equal deleted inserted replaced
2580:a66f7ed76416 2581:839d67a1dc58
1 ;;; gud.el --- Grand Unified Debugger mode for gdb, sdb, or dbx under Emacs 1 ;;; gud.el --- Grand Unified Debugger mode for gdb, sdb, or dbx under Emacs
2 2
3 ;; Author: Eric S. Raymond <esr@snark.thyrsus.com> 3 ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
4 ;; Version: 1.2 4 ;; Version: 1.3
5 ;; Keywords: unix, tools 5 ;; Keywords: unix, tools
6 6
7 ;; Copyright (C) 1992 Free Software Foundation, Inc. 7 ;; Copyright (C) 1992 Free Software Foundation, Inc.
8 8
9 ;; This file is part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
28 ;; It was later rewritten by rms. Some ideas were due to Masanobu. 28 ;; It was later rewritten by rms. Some ideas were due to Masanobu.
29 ;; Grand Unification (sdb/dbx support) by Eric S. Raymond <esr@thyrsus.com> 29 ;; Grand Unification (sdb/dbx support) by Eric S. Raymond <esr@thyrsus.com>
30 ;; The overloading code was then rewritten by Barry Warsaw <bwarsaw@cen.com>, 30 ;; The overloading code was then rewritten by Barry Warsaw <bwarsaw@cen.com>,
31 ;; who also hacked the mode to use comint.el. 31 ;; who also hacked the mode to use comint.el.
32 32
33 ;; This code will not work under Emacs 18. It relies on Emacs 19's
34 ;; minor-mode-keymap support and the find-tag-noselect entry point of etags.
35
36 ;;; Code: 33 ;;; Code:
37 34
38 (require 'comint) 35 (require 'comint)
39 (require 'etags) 36 (require 'etags)
40 37
41 ;; ====================================================================== 38 ;; ======================================================================
42 ;; minor-mode machinery for C buffers visited by GUD 39 ;; GUD commands must be visible in C buffers visited by GUD
43 40
44 (defvar gud-key-prefix "\C-x\C-a" 41 (defvar gud-key-prefix "\C-x\C-a"
45 "Prefix of all GUD minor-mode commands valid in C buffers.") 42 "Prefix of all GUD commands valid in C buffers.")
46 43
47 (defvar gud-minor-mode nil) 44 (global-set-key (concat gud-key-prefix "\C-l") 'gud-refresh)
48 (or (assq 'gud-minor-mode minor-mode-alist) 45 (global-set-key "\C-x " 'gud-break) ;; backward compatibility hack
49 (setq minor-mode-alist
50 (cons '(gud-minor-mode " GUD") minor-mode-alist)))
51
52 (defvar gud-mode-map nil)
53 (if gud-mode-map
54 nil
55 (setq gud-mode-map (make-sparse-keymap))
56 (define-key gud-mode-map gud-key-prefix (make-sparse-keymap))
57 (define-key gud-mode-map (concat gud-key-prefix "\C-l") 'gud-refresh)
58 )
59
60 (or (assq 'gud-minor-mode minor-mode-map-alist)
61 (setq minor-mode-map-alist
62 (cons
63 (cons 'gud-minor-mode gud-mode-map)
64 minor-mode-map-alist)))
65
66 (defun gud-minor-mode (&optional enable)
67 "GUD minor mode is enabled in C buffers visited due to a GUD stop at
68 breakpoint. All GUD-specific commands defined in GUD major mode will work,
69 but they get their current file and current line number from the context of
70 this buffer."
71 (interactive "P")
72 (setq gud-minor-mode
73 (if (null enable) (not gud-minor-mode)
74 (> (prefix-numeric-value enable) 0)))
75 )
76 46
77 ;; ====================================================================== 47 ;; ======================================================================
78 ;; the overloading mechanism 48 ;; the overloading mechanism
79 49
80 (defun gud-overload-functions (gud-overload-alist) 50 (defun gud-overload-functions (gud-overload-alist)
102 ;; user defined ones. 72 ;; user defined ones.
103 73
104 ;; A macro call like (gud-def FUNC NAME KEY DOC) expands to a form 74 ;; A macro call like (gud-def FUNC NAME KEY DOC) expands to a form
105 ;; which defines FUNC to send the command NAME to the debugger, gives 75 ;; which defines FUNC to send the command NAME to the debugger, gives
106 ;; it the docstring DOC, and binds that function to KEY in the GUD 76 ;; it the docstring DOC, and binds that function to KEY in the GUD
107 ;; major mode. The function is also bound in the GUD minor-mode 77 ;; major mode. The function is also bound in the global keymap with the
108 ;; keymap. If a numeric prefix argument is given to FUNC, it gets 78 ;; GUD prefix.
109 ;; sent after NAME.
110 79
111 (defmacro gud-def (func cmd key &optional doc) 80 (defmacro gud-def (func cmd key &optional doc)
112 "Define FUNC to be a command sending STR and bound to KEY, with 81 "Define FUNC to be a command sending STR and bound to KEY, with
113 optional doc string DOC. Certain %-escapes in the string arguments 82 optional doc string DOC. Certain %-escapes in the string arguments
114 are interpreted specially if present. These are: 83 are interpreted specially if present. These are:
117 %l number of current source line 86 %l number of current source line
118 %e text of the C lvalue or function-call expression surrounding point. 87 %e text of the C lvalue or function-call expression surrounding point.
119 %a text of the hexadecimal address surrounding point 88 %a text of the hexadecimal address surrounding point
120 %p prefix argument to the command (if any) as a number 89 %p prefix argument to the command (if any) as a number
121 90
122 The `current' source file is the file of the current buffer (if we're in a 91 The `current' source file is the file of the current buffer (if
123 C file with gud-minor-mode active) or the source file current at the last 92 we're in a C file) or the source file current at the last break or
124 break or step (if we're in the GUD buffer). 93 step (if we're in the GUD buffer).
125 The `current' line is that of the current buffer (if we're in a source 94 The `current' line is that of the current buffer (if we're in a
126 file with gud-minor-mode active) or the source line number at the last 95 source file) or the source line number at the last break or step (if
127 break or step (if we're in the GUD buffer)." 96 we're in the GUD buffer)."
128 (list 'progn 97 (list 'progn
129 (list 'defun func '(arg) 98 (list 'defun func '(arg)
130 (or doc "") 99 (or doc "")
131 '(interactive "p") 100 '(interactive "p")
132 (list 'gud-call cmd 'arg)) 101 (list 'gud-call cmd 'arg))
133 (if key 102 (if key
134 (list 'define-key 103 (progn
135 'gud-mode-map 104 (list 'define-key
136 (concat gud-key-prefix key) 105 '(current-local-map)
137 (list 'quote func))))) 106 (concat "\C-c" key)
107 (list 'quote func))
108 (list 'global-set-key
109 (concat gud-key-prefix key)
110 (list 'quote func))
111 ))))
138 112
139 ;; Where gud-display-frame should put the debugging arrow. This is 113 ;; Where gud-display-frame should put the debugging arrow. This is
140 ;; set by the marker-filter, which scans the debugger's output for 114 ;; set by the marker-filter, which scans the debugger's output for
141 ;; indications of the current program counter. 115 ;; indications of the current program counter.
142 (defvar gud-last-frame nil) 116 (defvar gud-last-frame nil)
200 (gud-overload-functions '((gud-debugger-startup . gud-gdb-debugger-startup) 174 (gud-overload-functions '((gud-debugger-startup . gud-gdb-debugger-startup)
201 (gud-marker-filter . gud-gdb-marker-filter) 175 (gud-marker-filter . gud-gdb-marker-filter)
202 (gud-find-file . gud-gdb-find-file) 176 (gud-find-file . gud-gdb-find-file)
203 )) 177 ))
204 178
179 (gud-common-init args)
180
205 (gud-def gud-break "break %f:%l" "b" "Set breakpoint at current line.") 181 (gud-def gud-break "break %f:%l" "b" "Set breakpoint at current line.")
206 (gud-def gud-tbreak "tbreak %f:%l" "t" "Set breakpoint at current line.") 182 (gud-def gud-tbreak "tbreak %f:%l" "t" "Set breakpoint at current line.")
207 (gud-def gud-remove "clear %l" "d" "Remove breakpoint at current line") 183 (gud-def gud-remove "clear %l" "d" "Remove breakpoint at current line")
208 (gud-def gud-step "step %p" "s" "Step one source line with display.") 184 (gud-def gud-step "step %p" "s" "Step one source line with display.")
209 (gud-def gud-stepi "stepi %p" "i" "Step one instruction with display.") 185 (gud-def gud-stepi "stepi %p" "i" "Step one instruction with display.")
211 (gud-def gud-cont "cont" "r" "Continue with display.") 187 (gud-def gud-cont "cont" "r" "Continue with display.")
212 (gud-def gud-finish "finish" "f" "Finish executing current function.") 188 (gud-def gud-finish "finish" "f" "Finish executing current function.")
213 (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).") 189 (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).")
214 (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).") 190 (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).")
215 (gud-def gud-print "print %e" "p" "Evaluate C expression at point.") 191 (gud-def gud-print "print %e" "p" "Evaluate C expression at point.")
216
217 (gud-common-init args)
218 192
219 (setq comint-prompt-regexp "^(.*gdb[+]?) *") 193 (setq comint-prompt-regexp "^(.*gdb[+]?) *")
220 (run-hooks 'gdb-mode-hook) 194 (run-hooks 'gdb-mode-hook)
221 ) 195 )
222 196
265 ;;;###autoload 239 ;;;###autoload
266 (defun sdb (args) 240 (defun sdb (args)
267 "Run sdb on program FILE in buffer *gud-FILE*. 241 "Run sdb on program FILE in buffer *gud-FILE*.
268 The directory containing FILE becomes the initial working directory 242 The directory containing FILE becomes the initial working directory
269 and source-file directory for your debugger." 243 and source-file directory for your debugger."
270
271 (interactive "sRun sdb (like this): sdb ") 244 (interactive "sRun sdb (like this): sdb ")
272
273 (if (and gud-sdb-needs-tags 245 (if (and gud-sdb-needs-tags
274 (not (and (boundp 'tags-file-name) (file-exists-p tags-file-name)))) 246 (not (and (boundp 'tags-file-name) (file-exists-p tags-file-name))))
275 (error "The sdb support requires a valid tags table to work.")) 247 (error "The sdb support requires a valid tags table to work."))
276 (gud-overload-functions '((gud-debugger-startup . gud-sdb-debugger-startup) 248 (gud-overload-functions '((gud-debugger-startup . gud-sdb-debugger-startup)
277 (gud-marker-filter . gud-sdb-marker-filter) 249 (gud-marker-filter . gud-sdb-marker-filter)
278 (gud-find-file . gud-sdb-find-file) 250 (gud-find-file . gud-sdb-find-file)
279 )) 251 ))
252
253 (gud-common-init args)
280 254
281 (gud-def gud-break "%l b" "b" "Set breakpoint at current line.") 255 (gud-def gud-break "%l b" "b" "Set breakpoint at current line.")
282 (gud-def gud-tbreak "%l c" "t" "Set temporary breakpoint at current line.") 256 (gud-def gud-tbreak "%l c" "t" "Set temporary breakpoint at current line.")
283 (gud-def gud-remove "%l d" "d" "Remove breakpoint at current line") 257 (gud-def gud-remove "%l d" "d" "Remove breakpoint at current line")
284 (gud-def gud-step "s %p" "s" "Step one source line with display.") 258 (gud-def gud-step "s %p" "s" "Step one source line with display.")
285 (gud-def gud-stepi "i %p" "i" "Step one instruction with display.") 259 (gud-def gud-stepi "i %p" "i" "Step one instruction with display.")
286 (gud-def gud-next "S %p" "n" "Step one line (skip functions).") 260 (gud-def gud-next "S %p" "n" "Step one line (skip functions).")
287 (gud-def gud-cont "c" "r" "Continue with display.") 261 (gud-def gud-cont "c" "r" "Continue with display.")
288 (gud-def gud-print "%e/" "p" "Evaluate C expression at point.") 262 (gud-def gud-print "%e/" "p" "Evaluate C expression at point.")
289
290 (gud-common-init args)
291 263
292 (setq comint-prompt-regexp "\\(^\\|\n\\)\\*") 264 (setq comint-prompt-regexp "\\(^\\|\n\\)\\*")
293 (run-hooks 'sdb-mode-hook) 265 (run-hooks 'sdb-mode-hook)
294 ) 266 )
295 267
321 (gud-overload-functions '((gud-debugger-startup . gud-dbx-debugger-startup) 293 (gud-overload-functions '((gud-debugger-startup . gud-dbx-debugger-startup)
322 (gud-marker-filter . gud-dbx-marker-filter) 294 (gud-marker-filter . gud-dbx-marker-filter)
323 (gud-find-file . gud-dbx-find-file) 295 (gud-find-file . gud-dbx-find-file)
324 )) 296 ))
325 297
298 (gud-common-init args)
299
326 (gud-def gud-break "stop at \"%f\":%l" 300 (gud-def gud-break "stop at \"%f\":%l"
327 "b" "Set breakpoint at current line.") 301 "b" "Set breakpoint at current line.")
328 (gud-def gud-remove "clear %l" "d" "Remove breakpoint at current line") 302 (gud-def gud-remove "clear %l" "d" "Remove breakpoint at current line")
329 (gud-def gud-step "step %p" "s" "Step one line with display.") 303 (gud-def gud-step "step %p" "s" "Step one line with display.")
330 (gud-def gud-stepi "stepi %p" "i" "Step one instruction with display.") 304 (gud-def gud-stepi "stepi %p" "i" "Step one instruction with display.")
332 (gud-def gud-cont "cont" "r" "Continue with display.") 306 (gud-def gud-cont "cont" "r" "Continue with display.")
333 (gud-def gud-up "up %p" "<" "Up (numeric arg) stack frames.") 307 (gud-def gud-up "up %p" "<" "Up (numeric arg) stack frames.")
334 (gud-def gud-down "down %p" ">" "Down (numeric arg) stack frames.") 308 (gud-def gud-down "down %p" ">" "Down (numeric arg) stack frames.")
335 (gud-def gud-print "print %e" "p" "Evaluate C expression at point.") 309 (gud-def gud-print "print %e" "p" "Evaluate C expression at point.")
336 310
337 (gud-common-init args)
338 (setq comint-prompt-regexp "^[^)]*dbx) *") 311 (setq comint-prompt-regexp "^[^)]*dbx) *")
339
340 (run-hooks 'dbx-mode-hook) 312 (run-hooks 'dbx-mode-hook)
341 ) 313 )
342 314
343 ;; 315 ;;
344 ;; End of debugger-specific information 316 ;; End of debugger-specific information
396 368
397 After startup, the following commands are available in both the GUD 369 After startup, the following commands are available in both the GUD
398 interaction buffer and any source buffer GUD visits due to a breakpoint stop 370 interaction buffer and any source buffer GUD visits due to a breakpoint stop
399 or step operation: 371 or step operation:
400 372
401 \\{gud-mode-map}
402
403 \\[gud-break] sets a breakpoint at the current file and line. In the 373 \\[gud-break] sets a breakpoint at the current file and line. In the
404 GUD buffer, the current file and line are those of the last breakpoint or 374 GUD buffer, the current file and line are those of the last breakpoint or
405 step. In a source buffer, they are the buffer's file and current line. 375 step. In a source buffer, they are the buffer's file and current line.
406 376
407 \\[gud-remove] removes breakpoints on the current file and line. 377 \\[gud-remove] removes breakpoints on the current file and line.
445 (comint-mode) 415 (comint-mode)
446 (setq major-mode 'gud-mode) 416 (setq major-mode 'gud-mode)
447 (setq mode-name "Debugger") 417 (setq mode-name "Debugger")
448 (setq mode-line-process '(": %s")) 418 (setq mode-line-process '(": %s"))
449 (use-local-map (copy-keymap comint-mode-map)) 419 (use-local-map (copy-keymap comint-mode-map))
450 (define-key (current-local-map)
451 gud-key-prefix (lookup-key gud-mode-map gud-key-prefix))
452 (define-key (current-local-map)
453 "\C-c" (lookup-key gud-mode-map gud-key-prefix))
454 (make-local-variable 'gud-last-frame) 420 (make-local-variable 'gud-last-frame)
455 (setq gud-last-frame nil) 421 (setq gud-last-frame nil)
456 (make-local-variable 'comint-prompt-regexp) 422 (make-local-variable 'comint-prompt-regexp)
457 (make-local-variable 'gud-delete-prompt-marker) 423 (make-local-variable 'gud-delete-prompt-marker)
458 (setq gud-delete-prompt-marker (make-marker)) 424 (setq gud-delete-prompt-marker (make-marker))
533 (defun gud-sentinel (proc msg) 499 (defun gud-sentinel (proc msg)
534 (cond ((null (buffer-name (process-buffer proc))) 500 (cond ((null (buffer-name (process-buffer proc)))
535 ;; buffer killed 501 ;; buffer killed
536 ;; Stop displaying an arrow in a source file. 502 ;; Stop displaying an arrow in a source file.
537 (setq overlay-arrow-position nil) 503 (setq overlay-arrow-position nil)
538 (setq gud-minor-mode nil)
539 (set-process-buffer proc nil)) 504 (set-process-buffer proc nil))
540 ((memq (process-status proc) '(signal exit)) 505 ((memq (process-status proc) '(signal exit))
541 ;; Stop displaying an arrow in a source file. 506 ;; Stop displaying an arrow in a source file.
542 (setq gud-minor-mode nil)
543 (setq overlay-arrow-position nil) 507 (setq overlay-arrow-position nil)
544 ;; Fix the mode line. 508 ;; Fix the mode line.
545 (setq mode-line-process 509 (setq mode-line-process
546 (concat ": " 510 (concat ": "
547 (symbol-name (process-status proc)))) 511 (symbol-name (process-status proc))))
586 550
587 (defun gud-display-line (true-file line) 551 (defun gud-display-line (true-file line)
588 (let* ((buffer (gud-find-file true-file)) 552 (let* ((buffer (gud-find-file true-file))
589 (window (display-buffer buffer)) 553 (window (display-buffer buffer))
590 (pos)) 554 (pos))
555 (if (equal buffer (current-buffer))
556 nil
557 (setq buffer-read-only nil))
591 (save-excursion 558 (save-excursion
592 (set-buffer buffer) 559 (set-buffer buffer)
593 (make-local-variable 'gud-minor-mode) 560 (setq buffer-read-only t)
594 (setq gud-minor-mode t)
595 (save-restriction 561 (save-restriction
596 (widen) 562 (widen)
597 (goto-line line) 563 (goto-line line)
598 (setq pos (point)) 564 (setq pos (point))
599 (setq overlay-arrow-string "=>") 565 (setq overlay-arrow-string "=>")
605 (goto-char pos)))) 571 (goto-char pos))))
606 (set-window-point window overlay-arrow-position))) 572 (set-window-point window overlay-arrow-position)))
607 573
608 ;;; The gud-call function must do the right thing whether its invoking 574 ;;; The gud-call function must do the right thing whether its invoking
609 ;;; keystroke is from the GUD buffer itself (via major-mode binding) 575 ;;; keystroke is from the GUD buffer itself (via major-mode binding)
610 ;;; or a C buffer in GUD minor mode. In the former case, we want to 576 ;;; or a C buffer. In the former case, we want to supply data from
611 ;;; supply data from gud-last-frame. Here's how we do it: 577 ;;; gud-last-frame. Here's how we do it:
612 578
613 (defun gud-format-command (str arg) 579 (defun gud-format-command (str arg)
614 (let ((minor (not (eq (current-buffer) gud-comint-buffer)))) 580 (let ((insource (not (eq (current-buffer) gud-comint-buffer))))
615 (if (string-match "\\(.*\\)%f\\(.*\\)" str) 581 (if (string-match "\\(.*\\)%f\\(.*\\)" str)
616 (progn 582 (progn
617 (setq str (concat 583 (setq str (concat
618 (substring str (match-beginning 1) (match-end 1)) 584 (substring str (match-beginning 1) (match-end 1))
619 (if minor 585 (if insource
620 (buffer-file-name) 586 (buffer-file-name)
621 (car gud-last-frame)) 587 (car gud-last-frame))
622 (substring str (match-beginning 2) (match-end 2)))))) 588 (substring str (match-beginning 2) (match-end 2))))))
623 (if (string-match "\\(.*\\)%l\\(.*\\)" str) 589 (if (string-match "\\(.*\\)%l\\(.*\\)" str)
624 (progn 590 (progn
625 (setq str (concat 591 (setq str (concat
626 (substring str (match-beginning 1) (match-end 1)) 592 (substring str (match-beginning 1) (match-end 1))
627 (if minor 593 (if insource
628 (save-excursion 594 (save-excursion
629 (beginning-of-line) 595 (beginning-of-line)
630 (save-restriction (widen) 596 (save-restriction (widen)
631 (1+ (count-lines 1 (point))))) 597 (1+ (count-lines 1 (point)))))
632 (cdr gud-last-frame)) 598 (cdr gud-last-frame))
849 ) 815 )
850 (t nil)) 816 (t nil))
851 ) 817 )
852 ) 818 )
853 819
820 ;;; There appears to be a bug in the byte compiler somewhere near macro
821 ;;; handling that (a) generates a spurious message about gud-key-prefix
822 ;;; when the global-set-key clause in gud-def is compiled, (b) generates
823 ;;; incorrect bytecode for gud-def. The symptom of this incorrectness
824 ;;; is that loading gud.elc brings in a compiled gud-def that doesn't
825 ;;; properly perform both global (C-x C-a) and local (C-c) bindings.
826 ;;; The workaround is to always load from source. Consequently, we try
827 ;;; to disable byte-compilation here.
828 ;;;
829 ;;; Local Variables:
830 ;;; no-byte-compile: t
831 ;;; End:
832
854 ;;; gud.el ends here 833 ;;; gud.el ends here