aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Roberts2005-12-06 21:42:54 +0000
committerNick Roberts2005-12-06 21:42:54 +0000
commit25c7f31583f8b8de5138d6d82ca4917befc4712c (patch)
treeb96d80d9545f4d7e6f7d52268c784f3d0948a25e
parent7a96cae66e8e99f965d6e31c2a4139d9e7bf7c27 (diff)
downloademacs-25c7f31583f8b8de5138d6d82ca4917befc4712c.tar.gz
emacs-25c7f31583f8b8de5138d6d82ca4917befc4712c.zip
(gdb-error-regexp, gdb-first-post-prompt)
(gdb-version): New variables. (gdb-source-file-list, gdb-register-names) (gdb-changed-registers): New variables for use with GDB 6.4+. (gdb-ann3): Replace with... (gdb-init-1, gdb-init-2): ...two new functions. (gdba, gdb-prompt): Call gdb-init-1. (gdb-get-version): New function. Call gdb-init-2 from here. (gud-watch): Make it work with mouse events too. (gdb-post-prompt): Don't add to queue until GDB version is known. (gdb-speedbar-expand-node, gdb-post-prompt, gdb-registers-mode) (gdb-locals-mode): Use gdb-version. (gdb-memory-format-map, gdb-memory-unit-map) (gdb-locals-watch-map): Rename from gdb-*-*-keymap. (gdb-locals-font-lock-keywords-1) (gdb-locals-font-lock-keywords-2): New variables. (gdb-find-file-hook): fgfg. (gdb-set-gud-minor-mode-existing-buffers-1) (gdb-var-list-children-1, gdb-var-list-children-handler-1) (gdb-var-update-1, gdb-var-update-handler-1) (gdb-data-list-register-values-handler) (gdb-data-list-register-values-custom) (gdb-get-changed-registers, gdb-get-changed-registers-handler) (gdb-stack-list-locals-handler, gdb-get-register-names): New functions for use with GDB 6.4+. (gdb-locals-watch-map-1): New variable for use with GDB 6.4+. (gdb-source-file-regexp, gdb-var-list-children-regexp-1) (gdb-var-update-regexp-1, gdb-data-list-register-values-regexp) (gdb-stack-list-locals-regexp) (gdb-data-list-register-names-regexp): New regexps for use with GDB 6.4+.
-rw-r--r--lisp/progmodes/gdb-ui.el457
1 files changed, 386 insertions, 71 deletions
diff --git a/lisp/progmodes/gdb-ui.el b/lisp/progmodes/gdb-ui.el
index 3e4f7a4447b..680c879a9e2 100644
--- a/lisp/progmodes/gdb-ui.el
+++ b/lisp/progmodes/gdb-ui.el
@@ -93,6 +93,7 @@
93(require 'gud) 93(require 'gud)
94 94
95(defvar tool-bar-map) 95(defvar tool-bar-map)
96(defvar speedbar-initial-expansion-list-name)
96 97
97(defvar gdb-frame-address "main" "Initialization for Assembler buffer.") 98(defvar gdb-frame-address "main" "Initialization for Assembler buffer.")
98(defvar gdb-previous-frame-address nil) 99(defvar gdb-previous-frame-address nil)
@@ -156,7 +157,44 @@ gdba (gdb-ui.el) uses all five values, gdbmi (gdb-mi.el) only two
156 "A list of trigger functions that have run later than their output 157 "A list of trigger functions that have run later than their output
157handlers.") 158handlers.")
158 159
159;; end of gdb variables 160(defvar gdb-first-post-prompt nil)
161(defvar gdb-version nil)
162(defvar gdb-locals-font-lock-keywords nil)
163(defconst gdb-error-regexp "\\^error,msg=\"\\(.+\\)\"")
164
165(defvar gdb-locals-font-lock-keywords-1
166 '(
167 ;; var = (struct struct_tag) value
168 ( "\\(^\\(\\sw\\|[_.]\\)+\\) += +(\\(struct\\) \\(\\(\\sw\\|[_.]\\)+\\)"
169 (1 font-lock-variable-name-face)
170 (3 font-lock-keyword-face)
171 (4 font-lock-type-face))
172 ;; var = (type) value
173 ( "\\(^\\(\\sw\\|[_.]\\)+\\) += +(\\(\\(\\sw\\|[_.]\\)+\\)"
174 (1 font-lock-variable-name-face)
175 (3 font-lock-type-face))
176 ;; var = val
177 ( "\\(^\\(\\sw\\|[_.]\\)+\\) += +[^(]"
178 (1 font-lock-variable-name-face))
179 )
180 "Font lock keywords used in `gdb-local-mode'.")
181
182(defvar gdb-locals-font-lock-keywords-2
183 '(
184 ;; var = type value
185 ( "\\(^\\(\\sw\\|[_.]\\)+\\)\t+\\(\\(\\sw\\|[_.]\\)+\\)"
186 (1 font-lock-variable-name-face)
187 (3 font-lock-type-face))
188 )
189 "Font lock keywords used in `gdb-local-mode'.")
190
191;; Variables for GDB 6.4+
192
193(defvar gdb-source-file-list nil
194 "List of source files for the current executable")
195(defvar gdb-register-names nil "List of register names.")
196(defvar gdb-changed-registers nil
197 "List of changed register numbers (strings).")
160 198
161;;;###autoload 199;;;###autoload
162(defun gdba (command-line) 200(defun gdba (command-line)
@@ -213,7 +251,7 @@ detailed description of this mode.
213 ;; 251 ;;
214 ;; Let's start with a basic gud-gdb buffer and then modify it a bit. 252 ;; Let's start with a basic gud-gdb buffer and then modify it a bit.
215 (gdb command-line) 253 (gdb command-line)
216 (gdb-ann3)) 254 (gdb-init-1))
217 255
218(defvar gdb-debug-log nil) 256(defvar gdb-debug-log nil)
219 257
@@ -356,7 +394,7 @@ With arg, use separate IO iff arg is positive."
356 (setq expr (concat (car var1) "." (match-string 2 varno))))) 394 (setq expr (concat (car var1) "." (match-string 2 varno)))))
357 expr)) 395 expr))
358 396
359(defun gdb-ann3 () 397(defun gdb-init-1 ()
360 (setq gdb-debug-log nil) 398 (setq gdb-debug-log nil)
361 (set (make-local-variable 'gud-minor-mode) 'gdba) 399 (set (make-local-variable 'gud-minor-mode) 'gdba)
362 (set (make-local-variable 'gud-marker-filter) 'gud-gdba-marker-filter) 400 (set (make-local-variable 'gud-marker-filter) 'gud-gdba-marker-filter)
@@ -413,7 +451,7 @@ With arg, use separate IO iff arg is positive."
413 'gdb-mouse-toggle-breakpoint-fringe) 451 'gdb-mouse-toggle-breakpoint-fringe)
414 452
415 (setq comint-input-sender 'gdb-send) 453 (setq comint-input-sender 'gdb-send)
416 ;; 454
417 ;; (re-)initialize 455 ;; (re-)initialize
418 (setq gdb-frame-address (if gdb-show-main "main" nil)) 456 (setq gdb-frame-address (if gdb-show-main "main" nil))
419 (setq gdb-previous-frame-address nil 457 (setq gdb-previous-frame-address nil
@@ -424,7 +462,7 @@ With arg, use separate IO iff arg is positive."
424 gdb-frame-number nil 462 gdb-frame-number nil
425 gdb-var-list nil 463 gdb-var-list nil
426 gdb-var-changed nil 464 gdb-var-changed nil
427 gdb-first-prompt nil 465 gdb-first-post-prompt t
428 gdb-prompting nil 466 gdb-prompting nil
429 gdb-input-queue nil 467 gdb-input-queue nil
430 gdb-current-item nil 468 gdb-current-item nil
@@ -434,14 +472,21 @@ With arg, use separate IO iff arg is positive."
434 gdb-flush-pending-output nil 472 gdb-flush-pending-output nil
435 gdb-location-alist nil 473 gdb-location-alist nil
436 gdb-find-file-unhook nil 474 gdb-find-file-unhook nil
475 gdb-source-file-list nil
437 gdb-error nil 476 gdb-error nil
438 gdb-macro-info nil 477 gdb-macro-info nil
439 gdb-buffer-fringe-width (car (window-fringes))) 478 gdb-buffer-fringe-width (car (window-fringes)))
440 ;; 479
441 (setq gdb-buffer-type 'gdba) 480 (setq gdb-buffer-type 'gdba)
442 ;; 481
443 (if gdb-use-inferior-io-buffer (gdb-clear-inferior-io)) 482 (if gdb-use-inferior-io-buffer (gdb-clear-inferior-io))
444 ;; 483
484 ;; Hack to see test for GDB 6.4+ (-stack-info-frame was implemented in 6.4)
485 (setq gdb-version nil)
486 (gdb-enqueue-input (list "server interpreter mi -stack-info-frame\n"
487 'gdb-get-version)))
488
489(defun gdb-init-2 ()
445 (if (eq window-system 'w32) 490 (if (eq window-system 'w32)
446 (gdb-enqueue-input (list "set new-console off\n" 'ignore))) 491 (gdb-enqueue-input (list "set new-console off\n" 'ignore)))
447 (gdb-enqueue-input (list "set height 0\n" 'ignore)) 492 (gdb-enqueue-input (list "set height 0\n" 'ignore))
@@ -450,10 +495,30 @@ With arg, use separate IO iff arg is positive."
450 (gdb-enqueue-input (list "server list main\n" 'ignore)) ; C program 495 (gdb-enqueue-input (list "server list main\n" 'ignore)) ; C program
451 (gdb-enqueue-input (list "server list MAIN__\n" 'ignore)) ; Fortran program 496 (gdb-enqueue-input (list "server list MAIN__\n" 'ignore)) ; Fortran program
452 (gdb-enqueue-input (list "server info source\n" 'gdb-source-info)) 497 (gdb-enqueue-input (list "server info source\n" 'gdb-source-info))
453 ;; 498
454 (gdb-set-gud-minor-mode-existing-buffers) 499 (if (string-equal gdb-version "pre-6.4")
500 (progn
501 (gdb-set-gud-minor-mode-existing-buffers)
502 (setq gdb-locals-font-lock-keywords gdb-locals-font-lock-keywords-1))
503 (gdb-enqueue-input
504 (list "server interpreter mi -data-list-register-names\n"
505 'gdb-get-register-names))
506 ; Needs GDB 6.2 onwards.
507 (gdb-enqueue-input
508 (list "server interpreter mi \"-file-list-exec-source-files\"\n"
509 'gdb-set-gud-minor-mode-existing-buffers-1))
510 (setq gdb-locals-font-lock-keywords gdb-locals-font-lock-keywords-2))
511
455 (run-hooks 'gdba-mode-hook)) 512 (run-hooks 'gdba-mode-hook))
456 513
514(defun gdb-get-version ()
515 (goto-char (point-min))
516 (if (and (re-search-forward gdb-error-regexp nil t)
517 (string-match ".*(missing implementation)" (match-string 1)))
518 (setq gdb-version "pre-6.4")
519 (setq gdb-version "6.4+"))
520 (gdb-init-2))
521
457(defun gdb-mouse-until (event) 522(defun gdb-mouse-until (event)
458 "Execute source lines by dragging the overlay arrow (fringe) with the mouse." 523 "Execute source lines by dragging the overlay arrow (fringe) with the mouse."
459 (interactive "e") 524 (interactive "e")
@@ -504,9 +569,10 @@ With arg, use separate IO iff arg is positive."
504 :group 'gud 569 :group 'gud
505 :version "22.1") 570 :version "22.1")
506 571
507(defun gud-watch () 572(defun gud-watch (&optional event)
508 "Watch expression at point." 573 "Watch expression at point."
509 (interactive) 574 (interactive (list last-input-event))
575 (if event (posn-set-point (event-end event)))
510 (require 'tooltip) 576 (require 'tooltip)
511 (save-selected-window 577 (save-selected-window
512 (let ((expr (tooltip-identifier-from-point (point)))) 578 (let ((expr (tooltip-identifier-from-point (point))))
@@ -692,7 +758,9 @@ TOKEN is data related to this node.
692INDENT is the current indentation depth." 758INDENT is the current indentation depth."
693 (cond ((string-match "+" text) ;expand this node 759 (cond ((string-match "+" text) ;expand this node
694 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba) 760 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba)
695 (gdb-var-list-children token) 761 (if (string-equal gdb-version "pre-6.4")
762 (gdb-var-list-children token)
763 (gdb-var-list-children-1 token))
696 (progn 764 (progn
697 (gdbmi-var-update) 765 (gdbmi-var-update)
698 (gdbmi-var-list-children token)))) 766 (gdbmi-var-list-children token))))
@@ -781,7 +849,6 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'."
781;; GUD buffers are an exception to the rules 849;; GUD buffers are an exception to the rules
782(gdb-set-buffer-rules 'gdba 'error) 850(gdb-set-buffer-rules 'gdba 'error)
783 851
784;;
785;; Partial-output buffer : This accumulates output from a command executed on 852;; Partial-output buffer : This accumulates output from a command executed on
786;; behalf of emacs (rather than the user). 853;; behalf of emacs (rather than the user).
787;; 854;;
@@ -877,7 +944,6 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'."
877 (get-buffer-process gud-comint-buffer))) 944 (get-buffer-process gud-comint-buffer)))
878 945
879 946
880;;
881;; gdb communications 947;; gdb communications
882;; 948;;
883 949
@@ -1031,7 +1097,9 @@ happens to be in effect."
1031(defun gdb-prompt (ignored) 1097(defun gdb-prompt (ignored)
1032 "An annotation handler for `prompt'. 1098 "An annotation handler for `prompt'.
1033This sends the next command (if any) to gdb." 1099This sends the next command (if any) to gdb."
1034 (when gdb-first-prompt (gdb-ann3)) 1100 (when gdb-first-prompt
1101 (gdb-init-1)
1102 (setq gdb-first-prompt nil))
1035 (let ((sink gdb-output-sink)) 1103 (let ((sink gdb-output-sink))
1036 (cond 1104 (cond
1037 ((eq sink 'user) t) 1105 ((eq sink 'user) t)
@@ -1128,16 +1196,25 @@ sink to `user' in `gdb-stopping', that is fine."
1128 "An annotation handler for `post-prompt'. 1196 "An annotation handler for `post-prompt'.
1129This begins the collection of output from the current command if that 1197This begins the collection of output from the current command if that
1130happens to be appropriate." 1198happens to be appropriate."
1131 (unless gdb-pending-triggers 1199 ;; Don't add to queue if there outstanding items or GDB is not known yet.
1200 (unless (or gdb-pending-triggers gdb-first-post-prompt)
1132 (gdb-get-selected-frame) 1201 (gdb-get-selected-frame)
1133 (gdb-invalidate-frames) 1202 (gdb-invalidate-frames)
1134 (gdb-invalidate-breakpoints) 1203 (gdb-invalidate-breakpoints)
1135 ;; Do this through gdb-get-selected-frame -> gdb-frame-handler 1204 ;; Do this through gdb-get-selected-frame -> gdb-frame-handler
1136 ;; so gdb-frame-address is updated. 1205 ;; so gdb-frame-address is updated.
1137 ;; (gdb-invalidate-assembler) 1206 ;; (gdb-invalidate-assembler)
1138 (gdb-invalidate-registers) 1207
1208 (if (string-equal gdb-version "pre-6.4")
1209 (gdb-invalidate-registers)
1210 (gdb-get-changed-registers)
1211 (gdb-invalidate-registers-1))
1212
1139 (gdb-invalidate-memory) 1213 (gdb-invalidate-memory)
1140 (gdb-invalidate-locals) 1214 (if (string-equal gdb-version "pre-6.4")
1215 (gdb-invalidate-locals)
1216 (gdb-invalidate-locals-1))
1217
1141 (gdb-invalidate-threads) 1218 (gdb-invalidate-threads)
1142 (unless (eq system-type 'darwin) ;Breaks on Darwin's GDB-5.3. 1219 (unless (eq system-type 'darwin) ;Breaks on Darwin's GDB-5.3.
1143 ;; FIXME: with GDB-6 on Darwin, this might very well work. 1220 ;; FIXME: with GDB-6 on Darwin, this might very well work.
@@ -1146,7 +1223,10 @@ happens to be appropriate."
1146 (setq gdb-var-changed t) ; force update 1223 (setq gdb-var-changed t) ; force update
1147 (dolist (var gdb-var-list) 1224 (dolist (var gdb-var-list)
1148 (setcar (nthcdr 5 var) nil)) 1225 (setcar (nthcdr 5 var) nil))
1149 (gdb-var-update)))) 1226 (if (string-equal gdb-version "pre-6.4")
1227 (gdb-var-update)
1228 (gdb-var-update-1)))))
1229 (setq gdb-first-post-prompt nil)
1150 (let ((sink gdb-output-sink)) 1230 (let ((sink gdb-output-sink))
1151 (cond 1231 (cond
1152 ((eq sink 'user) t) 1232 ((eq sink 'user) t)
@@ -1908,13 +1988,15 @@ static char *magick[] = {
1908\\{gdb-registers-mode-map}" 1988\\{gdb-registers-mode-map}"
1909 (kill-all-local-variables) 1989 (kill-all-local-variables)
1910 (setq major-mode 'gdb-registers-mode) 1990 (setq major-mode 'gdb-registers-mode)
1911 (setq mode-name (if gdb-all-registers "Registers:All" "Registers:")) 1991 (setq mode-name "Registers")
1912 (setq buffer-read-only t) 1992 (setq buffer-read-only t)
1913 (use-local-map gdb-registers-mode-map) 1993 (use-local-map gdb-registers-mode-map)
1914 (run-mode-hooks 'gdb-registers-mode-hook) 1994 (run-mode-hooks 'gdb-registers-mode-hook)
1915 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba) 1995 (if (string-equal gdb-version "pre-6.4")
1916 'gdb-invalidate-registers 1996 (progn
1917 'gdbmi-invalidate-registers)) 1997 (if gdb-all-registers (setq mode-name "Registers:All"))
1998 'gdb-invalidate-registers)
1999 'gdb-invalidate-registers-1))
1918 2000
1919(defun gdb-registers-buffer-name () 2001(defun gdb-registers-buffer-name ()
1920 (with-current-buffer gud-comint-buffer 2002 (with-current-buffer gud-comint-buffer
@@ -1934,19 +2016,20 @@ static char *magick[] = {
1934 (display-buffer (gdb-get-create-buffer 'gdb-registers-buffer)))) 2016 (display-buffer (gdb-get-create-buffer 'gdb-registers-buffer))))
1935 2017
1936(defun gdb-all-registers () 2018(defun gdb-all-registers ()
1937 "Toggle the display of floating-point registers." 2019 "Toggle the display of floating-point registers (pre GDB 6.4 only)."
1938 (interactive) 2020 (interactive)
1939 (if gdb-all-registers 2021 (when (string-equal gdb-version "pre-6.4")
1940 (progn 2022 (if gdb-all-registers
1941 (setq gdb-all-registers nil) 2023 (progn
1942 (with-current-buffer (gdb-get-create-buffer 'gdb-registers-buffer) 2024 (setq gdb-all-registers nil)
1943 (setq mode-name "Registers:"))) 2025 (with-current-buffer (gdb-get-create-buffer 'gdb-registers-buffer)
1944 (setq gdb-all-registers t) 2026 (setq mode-name "Registers")))
1945 (with-current-buffer (gdb-get-create-buffer 'gdb-registers-buffer) 2027 (setq gdb-all-registers t)
1946 (setq mode-name "Registers:All"))) 2028 (with-current-buffer (gdb-get-create-buffer 'gdb-registers-buffer)
1947 (message (format "Display of floating-point registers %sabled" 2029 (setq mode-name "Registers:All")))
1948 (if gdb-all-registers "en" "dis"))) 2030 (message (format "Display of floating-point registers %sabled"
1949 (gdb-invalidate-registers)) 2031 (if gdb-all-registers "en" "dis")))
2032 (gdb-invalidate-registers)))
1950 2033
1951 2034
1952;; Memory buffer. 2035;; Memory buffer.
@@ -2050,7 +2133,7 @@ static char *magick[] = {
2050 (customize-set-variable 'gdb-memory-format "x") 2133 (customize-set-variable 'gdb-memory-format "x")
2051 (gdb-invalidate-memory)) 2134 (gdb-invalidate-memory))
2052 2135
2053(defvar gdb-memory-format-keymap 2136(defvar gdb-memory-format-map
2054 (let ((map (make-sparse-keymap))) 2137 (let ((map (make-sparse-keymap)))
2055 (define-key map [header-line down-mouse-3] 'gdb-memory-format-menu-1) 2138 (define-key map [header-line down-mouse-3] 'gdb-memory-format-menu-1)
2056 map) 2139 map)
@@ -2112,7 +2195,7 @@ static char *magick[] = {
2112 (customize-set-variable 'gdb-memory-unit "b") 2195 (customize-set-variable 'gdb-memory-unit "b")
2113 (gdb-invalidate-memory)) 2196 (gdb-invalidate-memory))
2114 2197
2115(defvar gdb-memory-unit-keymap 2198(defvar gdb-memory-unit-map
2116 (let ((map (make-sparse-keymap))) 2199 (let ((map (make-sparse-keymap)))
2117 (define-key map [header-line down-mouse-3] 'gdb-memory-unit-menu-1) 2200 (define-key map [header-line down-mouse-3] 'gdb-memory-unit-menu-1)
2118 map) 2201 map)
@@ -2227,13 +2310,13 @@ corresponding to the mode line clicked."
2227 'face font-lock-warning-face 2310 'face font-lock-warning-face
2228 'help-echo "mouse-3: Select display format" 2311 'help-echo "mouse-3: Select display format"
2229 'mouse-face 'mode-line-highlight 2312 'mouse-face 'mode-line-highlight
2230 'local-map gdb-memory-format-keymap) 2313 'local-map gdb-memory-format-map)
2231 " Unit Size: " 2314 " Unit Size: "
2232 (propertize gdb-memory-unit 2315 (propertize gdb-memory-unit
2233 'face font-lock-warning-face 2316 'face font-lock-warning-face
2234 'help-echo "mouse-3: Select unit size" 2317 'help-echo "mouse-3: Select unit size"
2235 'mouse-face 'mode-line-highlight 2318 'mouse-face 'mode-line-highlight
2236 'local-map gdb-memory-unit-keymap)))) 2319 'local-map gdb-memory-unit-map))))
2237 (set (make-local-variable 'font-lock-defaults) 2320 (set (make-local-variable 'font-lock-defaults)
2238 '(gdb-memory-font-lock-keywords)) 2321 '(gdb-memory-font-lock-keywords))
2239 (run-mode-hooks 'gdb-memory-mode-hook) 2322 (run-mode-hooks 'gdb-memory-mode-hook)
@@ -2268,7 +2351,7 @@ corresponding to the mode line clicked."
2268 "server info locals\n" 2351 "server info locals\n"
2269 gdb-info-locals-handler) 2352 gdb-info-locals-handler)
2270 2353
2271(defvar gdb-locals-watch-keymap 2354(defvar gdb-locals-watch-map
2272 (let ((map (make-sparse-keymap))) 2355 (let ((map (make-sparse-keymap)))
2273 (define-key map "\r" '(lambda () (interactive) 2356 (define-key map "\r" '(lambda () (interactive)
2274 (beginning-of-line) 2357 (beginning-of-line)
@@ -2284,13 +2367,13 @@ corresponding to the mode line clicked."
2284 (concat (propertize "[struct/union]" 2367 (concat (propertize "[struct/union]"
2285 'mouse-face 'highlight 2368 'mouse-face 'highlight
2286 'help-echo "mouse-2: create watch expression" 2369 'help-echo "mouse-2: create watch expression"
2287 'local-map gdb-locals-watch-keymap) "\n")) 2370 'local-map gdb-locals-watch-map) "\n"))
2288 2371
2289(defconst gdb-array-string 2372(defconst gdb-array-string
2290 (concat " " (propertize "[array]" 2373 (concat " " (propertize "[array]"
2291 'mouse-face 'highlight 2374 'mouse-face 'highlight
2292 'help-echo "mouse-2: create watch expression" 2375 'help-echo "mouse-2: create watch expression"
2293 'local-map gdb-locals-watch-keymap) "\n")) 2376 'local-map gdb-locals-watch-map) "\n"))
2294 2377
2295;; Abbreviate for arrays and structures. 2378;; Abbreviate for arrays and structures.
2296;; These can be expanded using gud-display. 2379;; These can be expanded using gud-display.
@@ -2326,23 +2409,6 @@ corresponding to the mode line clicked."
2326 (define-key map "q" 'kill-this-buffer) 2409 (define-key map "q" 'kill-this-buffer)
2327 map)) 2410 map))
2328 2411
2329(defvar gdb-locals-font-lock-keywords
2330 '(
2331 ;; var = (struct struct_tag) value
2332 ( "\\(^\\(\\sw\\|[_.]\\)+\\) += +(\\(struct\\) \\(\\(\\sw\\|[_.]\\)+\\)"
2333 (1 font-lock-variable-name-face)
2334 (3 font-lock-keyword-face)
2335 (4 font-lock-type-face))
2336 ;; var = (type) value
2337 ( "\\(^\\(\\sw\\|[_.]\\)+\\) += +(\\(\\(\\sw\\|[_.]\\)+\\)"
2338 (1 font-lock-variable-name-face)
2339 (3 font-lock-type-face))
2340 ;; var = val
2341 ( "\\(^\\(\\sw\\|[_.]\\)+\\) += +[^(]"
2342 (1 font-lock-variable-name-face))
2343 )
2344 "Font lock keywords used in `gdb-local-mode'.")
2345
2346(defun gdb-locals-mode () 2412(defun gdb-locals-mode ()
2347 "Major mode for gdb locals. 2413 "Major mode for gdb locals.
2348 2414
@@ -2356,7 +2422,9 @@ corresponding to the mode line clicked."
2356 '(gdb-locals-font-lock-keywords)) 2422 '(gdb-locals-font-lock-keywords))
2357 (run-mode-hooks 'gdb-locals-mode-hook) 2423 (run-mode-hooks 'gdb-locals-mode-hook)
2358 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba) 2424 (if (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 'gdba)
2359 'gdb-invalidate-locals 2425 (if (string-equal gdb-version "pre-6.4")
2426 'gdb-invalidate-locals
2427 'gdb-invalidate-locals-1)
2360 'gdbmi-invalidate-locals)) 2428 'gdbmi-invalidate-locals))
2361 2429
2362(defun gdb-locals-buffer-name () 2430(defun gdb-locals-buffer-name ()
@@ -2614,21 +2682,25 @@ Add directory to search path for source files using the GDB command, dir."))
2614(add-hook 'find-file-hook 'gdb-find-file-hook) 2682(add-hook 'find-file-hook 'gdb-find-file-hook)
2615 2683
2616(defun gdb-find-file-hook () 2684(defun gdb-find-file-hook ()
2617"Set up buffer for debugging if file is part of the source code 2685 "Set up buffer for debugging if file is part of the source code
2618of the current session." 2686of the current session."
2619 (if (and (not gdb-find-file-unhook) 2687 (if (and (buffer-name gud-comint-buffer)
2620 ;; in case gud or gdb-ui is just loaded 2688 ;; in case gud or gdb-ui is just loaded
2621 gud-comint-buffer 2689 gud-comint-buffer
2622 (buffer-name gud-comint-buffer)
2623 (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer) 2690 (eq (buffer-local-value 'gud-minor-mode gud-comint-buffer)
2624 'gdba)) 2691 'gdba))
2625 (condition-case nil 2692 (if (string-equal gdb-version "pre-6.4")
2626 (gdb-enqueue-input 2693 (condition-case nil
2627 (list (concat gdb-server-prefix "list " 2694 (gdb-enqueue-input
2628 (file-name-nondirectory buffer-file-name) 2695 (list (concat gdb-server-prefix "list "
2629 ":1\n") 2696 (file-name-nondirectory buffer-file-name)
2630 `(lambda () (gdb-set-gud-minor-mode ,(current-buffer))))) 2697 ":1\n")
2631 (error (setq gdb-find-file-unhook t))))) 2698 `(lambda () (gdb-set-gud-minor-mode ,(current-buffer)))))
2699 (error (setq gdb-find-file-unhook t)))
2700 (if (member buffer-file-name gdb-source-file-list)
2701 (with-current-buffer (find-buffer-visiting buffer-file-name)
2702 (set (make-local-variable 'gud-minor-mode) 'gdba)
2703 (set (make-local-variable 'tool-bar-map) gud-tool-bar-map))))))
2632 2704
2633;;from put-image 2705;;from put-image
2634(defun gdb-put-string (putstring pos &optional dprop &rest sprops) 2706(defun gdb-put-string (putstring pos &optional dprop &rest sprops)
@@ -2907,6 +2979,249 @@ BUFFER nil or omitted means use the current buffer."
2907 (setq gdb-current-language (match-string 1))) 2979 (setq gdb-current-language (match-string 1)))
2908 (gdb-invalidate-assembler)) 2980 (gdb-invalidate-assembler))
2909 2981
2982;; Code specific to GDB 6.4
2983
2984(defconst gdb-source-file-regexp "fullname=\"\\(.*?\\)\"")
2985
2986(defun gdb-set-gud-minor-mode-existing-buffers-1 ()
2987 "Create list of source files for current GDB session."
2988 (goto-char (point-min))
2989 (while (re-search-forward gdb-source-file-regexp nil t)
2990 (push (match-string 1) gdb-source-file-list))
2991 (dolist (buffer (buffer-list))
2992 (with-current-buffer buffer
2993 (when (member buffer-file-name gdb-source-file-list)
2994 (set (make-local-variable 'gud-minor-mode) 'gdba)
2995 (set (make-local-variable 'tool-bar-map) gud-tool-bar-map)
2996 (when gud-tooltip-mode
2997 (make-local-variable 'gdb-define-alist)
2998 (gdb-create-define-alist)
2999 (add-hook 'after-save-hook 'gdb-create-define-alist nil t))))))
3000
3001; Uses "-var-list-children --all-values". Needs GDB 6.1 onwards.
3002(defun gdb-var-list-children-1 (varnum)
3003 (gdb-enqueue-input
3004 (list (concat "server interpreter mi \"-var-update " varnum "\"\n")
3005 'ignore))
3006 (gdb-enqueue-input
3007 (list (concat "server interpreter mi \"-var-list-children --all-values "
3008 varnum "\"\n")
3009 `(lambda () (gdb-var-list-children-handler-1 ,varnum)))))
3010
3011(defconst gdb-var-list-children-regexp-1
3012 "name=\"\\(.+?\\)\",exp=\"\\(.+?\\)\",numchild=\"\\(.+?\\)\",\
3013value=\\(\".*?\"\\),type=\"\\(.+?\\)\"}")
3014
3015(defun gdb-var-list-children-handler-1 (varnum)
3016 (goto-char (point-min))
3017 (let ((var-list nil))
3018 (catch 'child-already-watched
3019 (dolist (var gdb-var-list)
3020 (if (string-equal varnum (cadr var))
3021 (progn
3022 (push var var-list)
3023 (while (re-search-forward gdb-var-list-children-regexp-1 nil t)
3024 (let ((varchild (list (match-string 2)
3025 (match-string 1)
3026 (match-string 3)
3027 (match-string 5)
3028 (read (match-string 4))
3029 nil)))
3030 (dolist (var1 gdb-var-list)
3031 (if (string-equal (cadr var1) (cadr varchild))
3032 (throw 'child-already-watched nil)))
3033 (push varchild var-list))))
3034 (push var var-list)))
3035 (setq gdb-var-changed t)
3036 (setq gdb-var-list (nreverse var-list)))))
3037
3038; Uses "-var-update --all-values". Needs GDB 6.4 onwards.
3039(defun gdb-var-update-1 ()
3040 (if (not (member 'gdb-var-update gdb-pending-triggers))
3041 (progn
3042 (gdb-enqueue-input
3043 (list
3044 (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba))
3045 "server interpreter mi \"-var-update --all-values *\"\n"
3046 "-var-update --all-values *\n")
3047 'gdb-var-update-handler-1))
3048 (push 'gdb-var-update gdb-pending-triggers))))
3049
3050(defconst gdb-var-update-regexp-1 "name=\"\\(.*?\\)\",value=\\(\".*?\"\\),")
3051
3052(defun gdb-var-update-handler-1 ()
3053 (goto-char (point-min))
3054 (while (re-search-forward gdb-var-update-regexp-1 nil t)
3055 (let ((varnum (match-string 1)))
3056 (catch 'var-found1
3057 (let ((num 0))
3058 (dolist (var gdb-var-list)
3059 (if (string-equal varnum (cadr var))
3060 (progn
3061 (setcar (nthcdr 5 var) t)
3062 (setcar (nthcdr 4 var) (read (match-string 2)))
3063 (setcar (nthcdr num gdb-var-list) var)
3064 (throw 'var-found1 nil)))
3065 (setq num (+ num 1))))))
3066 (setq gdb-var-changed t))
3067 (setq gdb-pending-triggers
3068 (delq 'gdb-var-update gdb-pending-triggers))
3069 (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
3070 ;; dummy command to update speedbar at right time
3071 (gdb-enqueue-input (list "server pwd\n" 'gdb-speedbar-timer-fn))
3072 ;; keep gdb-pending-triggers non-nil till end
3073 (push 'gdb-speedbar-timer gdb-pending-triggers)))
3074
3075;; Registers buffer.
3076;;
3077(gdb-set-buffer-rules 'gdb-registers-buffer
3078 'gdb-registers-buffer-name
3079 'gdb-registers-mode)
3080
3081(def-gdb-auto-update-trigger gdb-invalidate-registers-1
3082 (gdb-get-buffer 'gdb-registers-buffer)
3083 (if (eq gud-minor-mode 'gdba)
3084 "server interpreter mi \"-data-list-register-values x\"\n"
3085 "-data-list-register-values x\n")
3086 gdb-data-list-register-values-handler)
3087
3088(defconst gdb-data-list-register-values-regexp
3089 "number=\"\\(.*?\\)\",value=\"\\(.*?\\)\"")
3090
3091(defun gdb-data-list-register-values-handler ()
3092 (setq gdb-pending-triggers (delq 'gdb-invalidate-registers
3093 gdb-pending-triggers))
3094 (goto-char (point-min))
3095 (if (re-search-forward gdb-error-regexp nil t)
3096 (with-current-buffer (gdb-get-buffer 'gdb-registers-buffer)
3097 (let ((buffer-read-only nil))
3098 (erase-buffer)
3099 (insert (match-string 1))
3100 (goto-char (point-min))))
3101 (let ((register-list (reverse gdb-register-names))
3102 (register nil) (register-string nil) (register-values nil))
3103 (goto-char (point-min))
3104 (while (re-search-forward gdb-data-list-register-values-regexp nil t)
3105 (setq register (pop register-list))
3106 (setq register-string (concat register "\t" (match-string 2) "\n"))
3107 (if (member (match-string 1) gdb-changed-registers)
3108 (put-text-property 0 (length register-string)
3109 'face 'font-lock-warning-face
3110 register-string))
3111 (setq register-values
3112 (concat register-values register-string)))
3113 (let ((buf (gdb-get-buffer 'gdb-registers-buffer)))
3114 (with-current-buffer buf
3115 (let ((p (window-point (get-buffer-window buf 0)))
3116 (buffer-read-only nil))
3117 (erase-buffer)
3118 (insert register-values)
3119 (set-window-point (get-buffer-window buf 0) p))))))
3120 (gdb-data-list-register-values-custom))
3121
3122(defun gdb-data-list-register-values-custom ()
3123 (with-current-buffer (gdb-get-buffer 'gdb-registers-buffer)
3124 (save-excursion
3125 (let ((buffer-read-only nil)
3126 start end)
3127 (goto-char (point-min))
3128 (while (< (point) (point-max))
3129 (setq start (line-beginning-position))
3130 (setq end (line-end-position))
3131 (when (looking-at "^[^\t]+")
3132 (unless (string-equal (match-string 0) "No registers.")
3133 (put-text-property start (match-end 0)
3134 'face font-lock-variable-name-face)
3135 (add-text-properties start end
3136 '(help-echo "mouse-2: edit value"
3137 mouse-face highlight))))
3138 (forward-line 1))))))
3139
3140;; Needs GDB 6.4 onwards (used to fail with no stack).
3141(defun gdb-get-changed-registers ()
3142 (if (not (member 'gdb-get-changed-registers gdb-pending-triggers))
3143 (progn
3144 (gdb-enqueue-input
3145 (list
3146 (if (eq gud-minor-mode 'gdba)
3147 "server interpreter mi -data-list-changed-registers\n"
3148 "-data-list-changed-registers\n")
3149 'gdb-get-changed-registers-handler))
3150 (push 'gdb-get-changed-registers gdb-pending-triggers))))
3151
3152(defconst gdb-data-list-register-names-regexp "\"\\(.*?\\)\"")
3153
3154(defun gdb-get-changed-registers-handler ()
3155 (setq gdb-pending-triggers
3156 (delq 'gdb-get-changed-registers gdb-pending-triggers))
3157 (setq gdb-changed-registers nil)
3158 (goto-char (point-min))
3159 (while (re-search-forward gdb-data-list-register-names-regexp nil t)
3160 (push (match-string 1) gdb-changed-registers)))
3161
3162
3163;; Locals buffer.
3164;;
3165;; uses "-stack-list-locals --simple-values". Needs GDB 6.1 onwards.
3166(gdb-set-buffer-rules 'gdb-locals-buffer
3167 'gdb-locals-buffer-name
3168 'gdb-locals-mode)
3169
3170(def-gdb-auto-update-trigger gdb-invalidate-locals-1
3171 (gdb-get-buffer 'gdb-locals-buffer)
3172 "server interpreter mi -\"stack-list-locals --simple-values\"\n"
3173 gdb-stack-list-locals-handler)
3174
3175(defconst gdb-stack-list-locals-regexp
3176 "name=\"\\(.*?\\)\",type=\"\\(.*?\\)\"")
3177
3178(defvar gdb-locals-watch-map-1
3179 (let ((map (make-sparse-keymap)))
3180 (define-key map [mouse-2] 'gud-watch)
3181 map)
3182 "Keymap to create watch expression of a complex data type local variable.")
3183
3184;; Dont display values of arrays or structures.
3185;; These can be expanded using gud-watch.
3186(defun gdb-stack-list-locals-handler ()
3187 (setq gdb-pending-triggers (delq 'gdb-invalidate-locals-1
3188 gdb-pending-triggers))
3189 (let (local locals-list)
3190 (goto-char (point-min))
3191 (while (re-search-forward gdb-stack-list-locals-regexp nil t)
3192 (let ((local (list (match-string 1)
3193 (match-string 2)
3194 nil)))
3195 (if (looking-at ",value=\\(\".*\"\\)}")
3196 (setcar (nthcdr 2 local) (read (match-string 1))))
3197 (push local locals-list)))
3198 (let ((buf (gdb-get-buffer 'gdb-locals-buffer)))
3199 (and buf (with-current-buffer buf
3200 (let* ((window (get-buffer-window buf 0))
3201 (p (window-point window))
3202 (buffer-read-only nil))
3203 (erase-buffer)
3204 (dolist (local locals-list)
3205 (setq name (car local))
3206 (if (or (not (nth 2 local))
3207 (string-match "\\*$" (nth 1 local)))
3208 (add-text-properties 0 (length name)
3209 `(mouse-face highlight
3210 help-echo "mouse-2: create watch expression"
3211 local-map ,gdb-locals-watch-map-1)
3212 name))
3213 (insert
3214 (concat name "\t" (nth 1 local)
3215 "\t" (nth 2 local) "\n")))
3216 (set-window-point window p)))))))
3217
3218(defun gdb-get-register-names ()
3219 "Create a list of register names."
3220 (goto-char (point-min))
3221 (setq gdb-register-names nil)
3222 (while (re-search-forward gdb-data-list-register-names-regexp nil t)
3223 (push (match-string 1) gdb-register-names)))
3224
2910(provide 'gdb-ui) 3225(provide 'gdb-ui)
2911 3226
2912;; arch-tag: e9fb00c5-74ef-469f-a088-37384caae352 3227;; arch-tag: e9fb00c5-74ef-469f-a088-37384caae352