comparison lisp/progmodes/gdb-ui.el @ 90317:34c8b755296d

Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-23 Merge from emacs--devo--0 Patches applied: * emacs--devo--0 (patch 113-118) - Update from CVS - Merge from gnus--rel--5.10 * gnus--rel--5.10 (patch 38-39) - Update from CVS
author Miles Bader <miles@gnu.org>
date Fri, 24 Feb 2006 08:08:56 +0000
parents d1c5430c5bff 8ff0077b3342
children 5754737d1e04
comparison
equal deleted inserted replaced
90316:458ed0c8c4c3 90317:34c8b755296d
121 and #define directives otherwise.") 121 and #define directives otherwise.")
122 (defvar gdb-error "Non-nil when GDB is reporting an error.") 122 (defvar gdb-error "Non-nil when GDB is reporting an error.")
123 (defvar gdb-macro-info nil 123 (defvar gdb-macro-info nil
124 "Non-nil if GDB knows that the inferior includes preprocessor macro info.") 124 "Non-nil if GDB knows that the inferior includes preprocessor macro info.")
125 (defvar gdb-buffer-fringe-width nil) 125 (defvar gdb-buffer-fringe-width nil)
126 (defvar gdb-signalled nil)
126 127
127 (defvar gdb-buffer-type nil 128 (defvar gdb-buffer-type nil
128 "One of the symbols bound in `gdb-buffer-rules'.") 129 "One of the symbols bound in `gdb-buffer-rules'.")
129 (make-variable-buffer-local 'gdb-buffer-type) 130 (make-variable-buffer-local 'gdb-buffer-type)
130 131
256 ;; 257 ;;
257 ;; Let's start with a basic gud-gdb buffer and then modify it a bit. 258 ;; Let's start with a basic gud-gdb buffer and then modify it a bit.
258 (gdb command-line) 259 (gdb command-line)
259 (gdb-init-1)) 260 (gdb-init-1))
260 261
261 (defvar gdb-debug-log nil) 262 (defcustom gdb-debug-ring-max 128
263 "Maximum size of `gdb-debug-ring'."
264 :group 'gud
265 :type 'integer
266 :version "22.1")
267
268 (defvar gdb-debug-ring nil
269 "List of commands, most recent first, sent to and replies received from GDB.
270 This variable is used to debug GDB-UI.")
262 271
263 ;;;###autoload 272 ;;;###autoload
264 (defcustom gdb-enable-debug-log nil 273 (defcustom gdb-enable-debug nil
265 "Non-nil means record the process input and output in `gdb-debug-log'." 274 "Non-nil means record the process input and output in `gdb-debug-ring'."
266 :type 'boolean 275 :type 'boolean
267 :group 'gud 276 :group 'gud
268 :version "22.1") 277 :version "22.1")
269 278
270 (defcustom gdb-cpp-define-alist-program "gcc -E -dM -" 279 (defcustom gdb-cpp-define-alist-program "gcc -E -dM -"
388 (if (string-equal (nth 1 var1) (match-string 1 varno)) 397 (if (string-equal (nth 1 var1) (match-string 1 varno))
389 (setq expr (concat (car var1) "." (match-string 2 varno))))) 398 (setq expr (concat (car var1) "." (match-string 2 varno)))))
390 expr)) 399 expr))
391 400
392 (defun gdb-init-1 () 401 (defun gdb-init-1 ()
393 (setq gdb-debug-log nil)
394 (set (make-local-variable 'gud-minor-mode) 'gdba) 402 (set (make-local-variable 'gud-minor-mode) 'gdba)
395 (set (make-local-variable 'gud-marker-filter) 'gud-gdba-marker-filter) 403 (set (make-local-variable 'gud-marker-filter) 'gud-gdba-marker-filter)
396 ;; 404 ;;
397 (gud-def gud-break (if (not (string-match "Machine" mode-name)) 405 (gud-def gud-break (if (not (string-match "Machine" mode-name))
398 (gud-call "break %f:%l" arg) 406 (gud-call "break %f:%l" arg)
434 'gdb-mouse-set-clear-breakpoint) 442 'gdb-mouse-set-clear-breakpoint)
435 (define-key gud-minor-mode-map [left-fringe mouse-1] 443 (define-key gud-minor-mode-map [left-fringe mouse-1]
436 'gdb-mouse-set-clear-breakpoint) 444 'gdb-mouse-set-clear-breakpoint)
437 (define-key gud-minor-mode-map [left-fringe mouse-2] 445 (define-key gud-minor-mode-map [left-fringe mouse-2]
438 'gdb-mouse-until) 446 'gdb-mouse-until)
447 (define-key gud-minor-mode-map [left-margin drag-mouse-1]
448 'gdb-mouse-until)
439 (define-key gud-minor-mode-map [left-fringe drag-mouse-1] 449 (define-key gud-minor-mode-map [left-fringe drag-mouse-1]
440 'gdb-mouse-until) 450 'gdb-mouse-until)
441 (define-key gud-minor-mode-map [left-margin mouse-2] 451 (define-key gud-minor-mode-map [left-margin mouse-2]
442 'gdb-mouse-until) 452 'gdb-mouse-until)
443 (define-key gud-minor-mode-map [left-margin mouse-3] 453 (define-key gud-minor-mode-map [left-margin C-drag-mouse-1]
454 'gdb-mouse-jump)
455 (define-key gud-minor-mode-map [left-fringe C-drag-mouse-1]
456 'gdb-mouse-jump)
457 (define-key gud-minor-mode-map [left-fringe C-mouse-2]
458 'gdb-mouse-jump)
459 (define-key gud-minor-mode-map [left-margin C-mouse-2]
460 'gdb-mouse-jump)
461 (define-key gud-minor-mode-map [left-margin mouse-3]
444 'gdb-mouse-toggle-breakpoint-margin) 462 'gdb-mouse-toggle-breakpoint-margin)
445 (define-key gud-minor-mode-map [left-fringe mouse-3] 463 (define-key gud-minor-mode-map [left-fringe mouse-3]
446 'gdb-mouse-toggle-breakpoint-fringe) 464 'gdb-mouse-toggle-breakpoint-fringe)
447 465
448 (setq comint-input-sender 'gdb-send) 466 (setq comint-input-sender 'gdb-send)
467 gdb-flush-pending-output nil 485 gdb-flush-pending-output nil
468 gdb-location-alist nil 486 gdb-location-alist nil
469 gdb-source-file-list nil 487 gdb-source-file-list nil
470 gdb-error nil 488 gdb-error nil
471 gdb-macro-info nil 489 gdb-macro-info nil
472 gdb-buffer-fringe-width (car (window-fringes))) 490 gdb-buffer-fringe-width (car (window-fringes))
491 gdb-debug-ring nil
492 gdb-signalled nil)
473 493
474 (setq gdb-buffer-type 'gdba) 494 (setq gdb-buffer-type 'gdba)
475 495
476 (if gdb-use-separate-io-buffer (gdb-clear-inferior-io)) 496 (if gdb-use-separate-io-buffer (gdb-clear-inferior-io))
477 497
478 ;; Hack to see test for GDB 6.4+ (-stack-info-frame was implemented in 6.4) 498 ;; Hack to see test for GDB 6.4+ (-stack-info-frame was implemented in 6.4)
479 (setq gdb-version nil)
480 (gdb-enqueue-input (list "server interpreter mi -stack-info-frame\n" 499 (gdb-enqueue-input (list "server interpreter mi -stack-info-frame\n"
481 'gdb-get-version))) 500 'gdb-get-version)))
482 501
483 (defun gdb-init-2 () 502 (defun gdb-init-2 ()
484 (if (eq window-system 'w32) 503 (if (eq window-system 'w32)
514 (setq gdb-version "pre-6.4") 533 (setq gdb-version "pre-6.4")
515 (setq gdb-version "6.4+")) 534 (setq gdb-version "6.4+"))
516 (gdb-init-2)) 535 (gdb-init-2))
517 536
518 (defun gdb-mouse-until (event) 537 (defun gdb-mouse-until (event)
519 "Execute source lines by dragging the overlay arrow (fringe) with the mouse." 538 "Continue running until a source line past the current line.
539 The destination source line can be selected either by clicking with mouse-2
540 on the fringe/margin or dragging the arrow with mouse-1 (default bindings)."
520 (interactive "e") 541 (interactive "e")
521 (if gud-overlay-arrow-position 542 (if gud-overlay-arrow-position
522 (let ((start (event-start event)) 543 (let ((start (event-start event))
523 (end (event-end event)) 544 (end (event-end event))
524 (buffer (marker-buffer gud-overlay-arrow-position)) (line)) 545 (buffer (marker-buffer gud-overlay-arrow-position)) (line))
540 (save-excursion 561 (save-excursion
541 (goto-line (line-number-at-pos (posn-point end))) 562 (goto-line (line-number-at-pos (posn-point end)))
542 (forward-char 2) 563 (forward-char 2)
543 (gud-call (concat "until *%a"))))))))) 564 (gud-call (concat "until *%a")))))))))
544 565
566 (defun gdb-mouse-jump (event)
567 "Set execution address/line.
568 The destination source line can be selected either by clicking with mouse-2
569 on the fringe/margin or dragging the arrow with mouse-1 (default bindings).
570 Unlike gdb-mouse-until the destination address can be before the current
571 line, and no execution takes place."
572 (interactive "e")
573 (if gud-overlay-arrow-position
574 (let ((start (event-start event))
575 (end (event-end event))
576 (buffer (marker-buffer gud-overlay-arrow-position)) (line))
577 (if (not (string-match "Machine" mode-name))
578 (if (equal buffer (window-buffer (posn-window end)))
579 (with-current-buffer buffer
580 (when (or (equal start end)
581 (equal (posn-point start)
582 (marker-position
583 gud-overlay-arrow-position)))
584 (setq line (line-number-at-pos (posn-point end)))
585 (progn (gud-call (concat "tbreak " (number-to-string line)))
586 (gud-call (concat "jump " (number-to-string line)))))))
587 (if (equal (marker-buffer gdb-overlay-arrow-position)
588 (window-buffer (posn-window end)))
589 (when (or (equal start end)
590 (equal (posn-point start)
591 (marker-position
592 gdb-overlay-arrow-position)))
593 (save-excursion
594 (goto-line (line-number-at-pos (posn-point end)))
595 (forward-char 2)
596 (progn
597 (gud-call (concat "tbreak *%a"))
598 (gud-call (concat "jump *%a"))))))))))
599
545 (defcustom gdb-speedbar-auto-raise nil 600 (defcustom gdb-speedbar-auto-raise nil
546 "If non-nil raise speedbar every time display of watch expressions is\ 601 "If non-nil raise speedbar every time display of watch expressions is\
547 updated." 602 updated."
548 :type 'boolean 603 :type 'boolean
549 :group 'gud 604 :group 'gud
571 (interactive (list last-input-event)) 626 (interactive (list last-input-event))
572 (if event (posn-set-point (event-end event))) 627 (if event (posn-set-point (event-end event)))
573 (require 'tooltip) 628 (require 'tooltip)
574 (save-selected-window 629 (save-selected-window
575 (let ((expr (tooltip-identifier-from-point (point)))) 630 (let ((expr (tooltip-identifier-from-point (point))))
576 (if (and (string-equal gdb-current-language "c")
577 gdb-use-colon-colon-notation gdb-selected-frame)
578 (setq expr (concat gdb-selected-frame "::" expr)))
579 (catch 'already-watched 631 (catch 'already-watched
580 (dolist (var gdb-var-list) 632 (dolist (var gdb-var-list)
581 (if (string-equal expr (car var)) (throw 'already-watched nil))) 633 (if (string-equal expr (car var)) (throw 'already-watched nil)))
582 (set-text-properties 0 (length expr) nil expr) 634 (set-text-properties 0 (length expr) nil expr)
583 (gdb-enqueue-input 635 (gdb-enqueue-input
591 "name=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\",type=\"\\(.*?\\)\"") 643 "name=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\",type=\"\\(.*?\\)\"")
592 644
593 (defun gdb-var-create-handler (expr) 645 (defun gdb-var-create-handler (expr)
594 (goto-char (point-min)) 646 (goto-char (point-min))
595 (if (re-search-forward gdb-var-create-regexp nil t) 647 (if (re-search-forward gdb-var-create-regexp nil t)
596 (let ((var (list expr 648 (let ((var (list
597 (match-string 1) 649 (if (and (string-equal gdb-current-language "c")
598 (match-string 2) 650 gdb-use-colon-colon-notation gdb-selected-frame)
599 (match-string 3) 651 (setq expr (concat gdb-selected-frame "::" expr))
600 nil nil))) 652 expr)
653 (match-string 1)
654 (match-string 2)
655 (match-string 3)
656 nil nil)))
601 (push var gdb-var-list) 657 (push var gdb-var-list)
602 (speedbar 1) 658 (speedbar 1)
603 (unless (string-equal 659 (unless (string-equal
604 speedbar-initial-expansion-list-name "GUD") 660 speedbar-initial-expansion-list-name "GUD")
605 (speedbar-change-initial-expansion-list "GUD")) 661 (speedbar-change-initial-expansion-list "GUD"))
611 (concat "-var-evaluate-expression " (nth 1 var) "\n")) 667 (concat "-var-evaluate-expression " (nth 1 var) "\n"))
612 `(lambda () (gdb-var-evaluate-expression-handler 668 `(lambda () (gdb-var-evaluate-expression-handler
613 ,(nth 1 var) nil))))) 669 ,(nth 1 var) nil)))))
614 (if (search-forward "Undefined command" nil t) 670 (if (search-forward "Undefined command" nil t)
615 (message-box "Watching expressions requires gdb 6.0 onwards") 671 (message-box "Watching expressions requires gdb 6.0 onwards")
616 (message "No symbol \"%s\" in current context." expr)))) 672 (message-box "No symbol \"%s\" in current context." expr))))
617 673
618 (defun gdb-var-evaluate-expression-handler (varnum changed) 674 (defun gdb-var-evaluate-expression-handler (varnum changed)
619 (goto-char (point-min)) 675 (goto-char (point-min))
620 (re-search-forward ".*value=\\(\".*\"\\)" nil t) 676 (re-search-forward ".*value=\\(\".*\"\\)" nil t)
621 (catch 'var-found 677 (catch 'var-found
862 (concat "*input/output of " 918 (concat "*input/output of "
863 (gdb-get-target-string) 919 (gdb-get-target-string)
864 "*")) 920 "*"))
865 921
866 (defun gdb-display-separate-io-buffer () 922 (defun gdb-display-separate-io-buffer ()
867 "Display IO of inferior in a separate window." 923 "Display IO of debugged program in a separate window."
868 (interactive) 924 (interactive)
869 (if gdb-use-separate-io-buffer 925 (if gdb-use-separate-io-buffer
870 (gdb-display-buffer 926 (gdb-display-buffer
871 (gdb-get-create-buffer 'gdb-inferior-io)))) 927 (gdb-get-create-buffer 'gdb-inferior-io))))
872 928
961 (let ((inhibit-read-only t)) 1017 (let ((inhibit-read-only t))
962 (remove-text-properties (point-min) (point-max) '(face)))) 1018 (remove-text-properties (point-min) (point-max) '(face))))
963 (let ((item (concat string "\n"))) 1019 (let ((item (concat string "\n")))
964 (if gud-running 1020 (if gud-running
965 (progn 1021 (progn
966 (if gdb-enable-debug-log (push (cons 'send item) gdb-debug-log)) 1022 (if gdb-enable-debug (push (cons 'send item) gdb-debug-ring))
967 (process-send-string proc item)) 1023 (process-send-string proc item))
968 (gdb-enqueue-input item)))) 1024 (gdb-enqueue-input item))))
969 1025
970 ;; Note: Stuff enqueued here will be sent to the next prompt, even if it 1026 ;; Note: Stuff enqueued here will be sent to the next prompt, even if it
971 ;; is a query, or other non-top-level prompt. 1027 ;; is a query, or other non-top-level prompt.
984 (unless (nbutlast queue) (setq gdb-input-queue '())) 1040 (unless (nbutlast queue) (setq gdb-input-queue '()))
985 last)))) 1041 last))))
986 1042
987 (defun gdb-send-item (item) 1043 (defun gdb-send-item (item)
988 (setq gdb-flush-pending-output nil) 1044 (setq gdb-flush-pending-output nil)
989 (if gdb-enable-debug-log (push (cons 'send-item item) gdb-debug-log)) 1045 (if gdb-enable-debug (push (cons 'send-item item) gdb-debug-ring))
990 (setq gdb-current-item item) 1046 (setq gdb-current-item item)
991 (let ((process (get-buffer-process gud-comint-buffer))) 1047 (let ((process (get-buffer-process gud-comint-buffer)))
992 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba) 1048 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba)
993 (if (stringp item) 1049 (if (stringp item)
994 (progn 1050 (progn
1037 ("prompt-for-continue" gdb-subprompt) 1093 ("prompt-for-continue" gdb-subprompt)
1038 ("post-prompt" gdb-post-prompt) 1094 ("post-prompt" gdb-post-prompt)
1039 ("source" gdb-source) 1095 ("source" gdb-source)
1040 ("starting" gdb-starting) 1096 ("starting" gdb-starting)
1041 ("exited" gdb-exited) 1097 ("exited" gdb-exited)
1042 ("signalled" gdb-exited) 1098 ("signalled" gdb-signalled)
1043 ("signal" gdb-stopping) 1099 ("signal" gdb-stopping)
1044 ("breakpoint" gdb-stopping) 1100 ("breakpoint" gdb-stopping)
1045 ("watchpoint" gdb-stopping) 1101 ("watchpoint" gdb-stopping)
1046 ("frame-begin" gdb-frame-begin) 1102 ("frame-begin" gdb-frame-begin)
1047 ("stopped" gdb-stopped) 1103 ("stopped" gdb-stopped)
1154 (setq gdb-active-process nil) 1210 (setq gdb-active-process nil)
1155 (setq gud-overlay-arrow-position nil) 1211 (setq gud-overlay-arrow-position nil)
1156 (setq gdb-overlay-arrow-position nil) 1212 (setq gdb-overlay-arrow-position nil)
1157 (gdb-stopping ignored)) 1213 (gdb-stopping ignored))
1158 1214
1215 (defun gdb-signalled (ignored)
1216 (setq gdb-signalled t))
1217
1159 (defun gdb-frame-begin (ignored) 1218 (defun gdb-frame-begin (ignored)
1160 (let ((sink gdb-output-sink)) 1219 (let ((sink gdb-output-sink))
1161 (cond 1220 (cond
1162 ((eq sink 'inferior) 1221 ((eq sink 'inferior)
1163 (setq gdb-output-sink 'user)) 1222 (setq gdb-output-sink 'user))
1170 (defun gdb-stopped (ignored) 1229 (defun gdb-stopped (ignored)
1171 "An annotation handler for `stopped'. 1230 "An annotation handler for `stopped'.
1172 It is just like `gdb-stopping', except that if we already set the output 1231 It is just like `gdb-stopping', except that if we already set the output
1173 sink to `user' in `gdb-stopping', that is fine." 1232 sink to `user' in `gdb-stopping', that is fine."
1174 (setq gud-running nil) 1233 (setq gud-running nil)
1175 (setq gdb-active-process t)
1176 (let ((sink gdb-output-sink)) 1234 (let ((sink gdb-output-sink))
1177 (cond 1235 (cond
1178 ((eq sink 'inferior) 1236 ((eq sink 'inferior)
1179 (setq gdb-output-sink 'user)) 1237 (setq gdb-output-sink 'user))
1180 ((eq sink 'user) t) 1238 ((eq sink 'user) t)
1181 (t 1239 (t
1182 (gdb-resync) 1240 (gdb-resync)
1183 (error "Unexpected stopped annotation"))))) 1241 (error "Unexpected stopped annotation"))))
1242 (if gdb-signalled (gdb-exited ignored)))
1184 1243
1185 (defun gdb-error (ignored) 1244 (defun gdb-error (ignored)
1186 (setq gdb-error (not gdb-error))) 1245 (setq gdb-error (not gdb-error)))
1187 1246
1188 (defun gdb-post-prompt (ignored) 1247 (defun gdb-post-prompt (ignored)
1231 1290
1232 (defun gud-gdba-marker-filter (string) 1291 (defun gud-gdba-marker-filter (string)
1233 "A gud marker filter for gdb. Handle a burst of output from GDB." 1292 "A gud marker filter for gdb. Handle a burst of output from GDB."
1234 (if gdb-flush-pending-output 1293 (if gdb-flush-pending-output
1235 nil 1294 nil
1236 (if gdb-enable-debug-log (push (cons 'recv string) gdb-debug-log)) 1295 (when gdb-enable-debug
1296 (push (cons 'recv string) gdb-debug-ring)
1297 (if (> (length gdb-debug-ring) gdb-debug-ring-max)
1298 (setcdr (nthcdr (1- gdb-debug-ring-max) gdb-debug-ring) nil)))
1237 ;; Recall the left over gud-marker-acc from last time. 1299 ;; Recall the left over gud-marker-acc from last time.
1238 (setq gud-marker-acc (concat gud-marker-acc string)) 1300 (setq gud-marker-acc (concat gud-marker-acc string))
1239 ;; Start accumulating output for the GUD buffer. 1301 ;; Start accumulating output for the GUD buffer.
1240 (let ((output "")) 1302 (let ((output ""))
1241 ;; 1303 ;;