summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Roberts <nickrob@snap.net.nz>2006-08-31 03:22:23 +0000
committerNick Roberts <nickrob@snap.net.nz>2006-08-31 03:22:23 +0000
commit815395b6e60c164b1196685286c17f92d4faddb6 (patch)
treea2fac6241692f694534009f81e64abf003acef06
parent458f2301d40824bf027b99837f7c066235fa6022 (diff)
downloadgdb-815395b6e60c164b1196685286c17f92d4faddb6.tar.gz
Update to Emacs 22.
Numerous changes (prehistory).
-rw-r--r--gdb/mi/gdb-mi.el349
1 files changed, 208 insertions, 141 deletions
diff --git a/gdb/mi/gdb-mi.el b/gdb/mi/gdb-mi.el
index 8aa3d20791f..85453a6a750 100644
--- a/gdb/mi/gdb-mi.el
+++ b/gdb/mi/gdb-mi.el
@@ -60,16 +60,14 @@
;;
;; Known Bugs:
;;
-;; 0) VALUES OF WATCH EXPRESSIONS DON'T UPDATE.
;; 1) Cannot handle programs that need input without separating the I/O
;; of GDB with that of program.
;; 2) Completion doesn't work.
;; 3) To avoid extra output in the GUD buffer it is best not to use run, step,
-;; next or continue etc but their MI counterparts through gud-run, gud-step
-;; etc, e.g clicking on the appropriate icon in the toolbar.
-;; 4) With the "start" command the *stopped output doesn't give a reason field.
-;; so this mode fails.
-;; 5) Hangs when you try to quit with q or ^d.
+;; next or continue etc but their MI counterparts through gud-run, gud-step
+;; etc, e.g clicking on the appropriate icon in the toolbar.
+;; 4) With the "tbreak" or "start" command the *stopped output doesn't give a
+;; reason field so this mode fails.
;; TODO:
;; 1) Use MI command -data-read-memory for memory window.
@@ -95,10 +93,9 @@ Set to \"main\" at start if gdb-show-main is t.")
"List of variables in watch window.
Each element has the form (VARNUM EXPRESSION NUMCHILD TYPE VALUE STATUS) where
STATUS is nil (unchanged), `changed' or `out-of-scope'.")
-(defvar gdb-force-update t
- "Non-nil means that view of watch expressions will be updated in the speedbar.")
(defvar gdb-main-file nil "Source file from which program execution begins.")
(defvar gdb-overlay-arrow-position nil)
+(defvar gdb-stack-position nil)
(defvar gdb-server-prefix nil)
(defvar gdb-location-alist nil
"Alist of breakpoint numbers and full filenames.")
@@ -117,6 +114,7 @@ and #define directives otherwise.")
(defvar gdb-handler-alist '())
(defvar gdb-handler-number nil)
(defvar gdb-source-file-list nil)
+(defvar gdb-first-done-or-error t)
(defvar gdb-source-window nil)
(defvar gdb-continuation nil)
@@ -184,20 +182,20 @@ Also display the main routine in the disassembly buffer if present."
; Note: This mode seems to require a separate buffer for inferior IO.
(defcustom gdb-use-separate-io-buffer t
- "Non-nil means display output from the inferior in a separate buffer."
+ "Non-nil means display output from the debugged program in a separate buffer."
:type 'boolean
:group 'gud
:version "22.1")
(defun gdb-use-separate-io-buffer (arg)
- "Toggle separate IO for inferior.
+ "Toggle separate IO for debugged program.
With arg, use separate IO iff arg is positive."
(interactive "P")
(setq gdb-use-separate-io-buffer
(if (null arg)
(not gdb-use-separate-io-buffer)
(> (prefix-numeric-value arg) 0)))
- (message (format "Separate inferior IO %sabled"
+ (message (format "Separate IO %sabled"
(if gdb-use-separate-io-buffer "en" "dis")))
(if (and gud-comint-buffer
(buffer-name gud-comint-buffer))
@@ -353,26 +351,28 @@ detailed description of this mode.
'gdb-mouse-set-clear-breakpoint)
(define-key gud-minor-mode-map [left-fringe mouse-1]
'gdb-mouse-set-clear-breakpoint)
- (define-key gud-minor-mode-map [left-fringe mouse-2]
- 'gdb-mouse-until)
+ (define-key gud-minor-mode-map [left-margin C-mouse-1]
+ 'gdb-mouse-toggle-breakpoint-margin)
+ (define-key gud-minor-mode-map [left-fringe C-mouse-1]
+ 'gdb-mouse-toggle-breakpoint-fringe)
+
(define-key gud-minor-mode-map [left-margin drag-mouse-1]
'gdb-mouse-until)
(define-key gud-minor-mode-map [left-fringe drag-mouse-1]
'gdb-mouse-until)
- (define-key gud-minor-mode-map [left-margin mouse-2]
+ (define-key gud-minor-mode-map [left-margin mouse-3]
+ 'gdb-mouse-until)
+ (define-key gud-minor-mode-map [left-fringe mouse-3]
'gdb-mouse-until)
+
(define-key gud-minor-mode-map [left-margin C-drag-mouse-1]
'gdb-mouse-jump)
(define-key gud-minor-mode-map [left-fringe C-drag-mouse-1]
'gdb-mouse-jump)
- (define-key gud-minor-mode-map [left-fringe C-mouse-2]
+ (define-key gud-minor-mode-map [left-fringe C-mouse-3]
'gdb-mouse-jump)
- (define-key gud-minor-mode-map [left-margin C-mouse-2]
+ (define-key gud-minor-mode-map [left-margin C-mouse-3]
'gdb-mouse-jump)
- (define-key gud-minor-mode-map [left-margin mouse-3]
- 'gdb-mouse-toggle-breakpoint-margin)
- (define-key gud-minor-mode-map [left-fringe mouse-3]
- 'gdb-mouse-toggle-breakpoint-fringe)
(setq comint-input-sender 'gdbmi-send)
;;
@@ -385,7 +385,6 @@ detailed description of this mode.
gdb-current-frame nil
gdb-frame-number nil
gdb-var-list nil
- gdb-force-update t
gdb-pending-triggers nil
gdb-output-sink 'user
gdb-location-alist nil
@@ -395,6 +394,7 @@ detailed description of this mode.
gdb-handler-alist '()
gdb-handler-number nil
gdb-prompt-name nil
+ gdb-first-done-or-error t
gdb-buffer-fringe-width (car (window-fringes))
gdb-source-window nil
gdb-continuation nil)
@@ -578,15 +578,16 @@ With arg, enter name of variable to be watched in the minibuffer."
(if (and transient-mark-mode mark-active)
(buffer-substring (region-beginning) (region-end))
(tooltip-identifier-from-point (point))))))
+ (speedbar 1)
(catch 'already-watched
(dolist (var gdb-var-list)
(unless (string-match "\\." (car var))
(if (string-equal expr (nth 1 var))
(throw 'already-watched nil))))
- (set-text-properties 0 (length expr) nil expr)
- (gdb-input
- (list (concat"-var-create - * " expr "\n")
- `(lambda () (gdb-var-create-handler ,expr))))))))
+ (set-text-properties 0 (length expr) nil expr)
+ (gdb-input
+ (list (concat"-var-create - * " expr "\n")
+ `(lambda () (gdb-var-create-handler ,expr))))))))
(message "gud-watch is a no-op in this mode."))))
(defconst gdb-var-create-regexp
@@ -605,7 +606,6 @@ With arg, enter name of variable to be watched in the minibuffer."
(match-string 3)
nil nil)))
(push var gdb-var-list)
- (speedbar 1)
(unless (string-equal
speedbar-initial-expansion-list-name "GUD")
(speedbar-change-initial-expansion-list "GUD"))
@@ -613,11 +613,21 @@ With arg, enter name of variable to be watched in the minibuffer."
(list
(concat "-var-evaluate-expression " (car var) "\n")
`(lambda () (gdb-var-evaluate-expression-handler
- ,(car var) nil))))
- (with-current-buffer gud-comint-buffer
- (speedbar-timer-fn)))
+ ,(car var) nil)))))
(message-box "No symbol \"%s\" in current context." expr)))
+(defun gdb-speedbar-update ()
+ (when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
+ ;; Dummy command to update speedbar even when idle.
+ (gdb-input (list "server pwd\n" 'gdb-speedbar-timer-fn))
+ ;; Keep gdb-pending-triggers non-nil till end.
+ (push 'gdb-speedbar-timer gdb-pending-triggers)))
+
+(defun gdb-speedbar-timer-fn ()
+ (setq gdb-pending-triggers
+ (delq 'gdb-speedbar-timer gdb-pending-triggers))
+ (speedbar-timer-fn))
+
(defun gdb-var-evaluate-expression-handler (varnum changed)
(goto-char (point-min))
(re-search-forward ".*value=\\(\".*\"\\)" nil t)
@@ -625,8 +635,7 @@ With arg, enter name of variable to be watched in the minibuffer."
(when var
(if changed (setcar (nthcdr 5 var) 'changed))
(setcar (nthcdr 4 var) (read (match-string 1)))))
- (with-current-buffer gud-comint-buffer
- (speedbar-timer-fn)))
+ (gdb-speedbar-update))
; Uses "-var-list-children --all-values". Needs GDB 6.1 onwards.
(defun gdbmi-var-list-children (varnum)
@@ -638,8 +647,8 @@ With arg, enter name of variable to be watched in the minibuffer."
`(lambda () (gdbmi-var-list-children-handler ,varnum)))))
(defconst gdbmi-var-list-children-regexp
- "name=\"\\(.+?\\)\",exp=\"\\(.+?\\)\",numchild=\"\\(.+?\\)\",\
-value=\\(\".*?\"\\),type=\"\\(.+?\\)\"}")
+ "child={.*?name=\"\\(.+?\\)\",.*?exp=\"\\(.+?\\)\",.*?\
+numchild=\"\\(.+?\\)\",.*?value=\\(\".*?\"\\),.*?type=\"\\(.+?\\)\".*?}")
(defun gdbmi-var-list-children-handler (varnum)
(goto-char (point-min))
@@ -650,8 +659,8 @@ value=\\(\".*?\"\\),type=\"\\(.+?\\)\"}")
(progn
(push var var-list)
(while (re-search-forward gdbmi-var-list-children-regexp nil t)
- (let ((varchild (list (match-string 2)
- (match-string 1)
+ (let ((varchild (list (match-string 1)
+ (match-string 2)
(match-string 3)
(match-string 5)
(read (match-string 4))
@@ -661,15 +670,18 @@ value=\\(\".*?\"\\),type=\"\\(.+?\\)\"}")
(push varchild var-list))))
(push var var-list)))
(setq gdb-var-list (nreverse var-list))))
- (setq gdb-force-update t)
- (with-current-buffer gud-comint-buffer
- (speedbar-refresh)))
+ (gdb-speedbar-update))
; Uses "-var-update --all-values". Needs GDB 6.4 onwards.
(defun gdbmi-var-update ()
- (gdb-input (list "-var-update --all-values *\n" 'gdbmi-var-update-handler)))
+ (if (not (member 'gdb-var-update gdb-pending-triggers))
+ (gdb-input
+ (list "-var-update --all-values *\n" 'gdbmi-var-update-handler)))
+ (push 'gdb-var-update gdb-pending-triggers))
-(defconst gdbmi-var-update-regexp "name=\"\\(.*?\\)\",in_scope=\"\\(.*?\\)\"")
+(defconst gdbmi-var-update-regexp
+ "{.*?name=\"\\(.*?\\)\",.*?\\(?:value=\\(\".*?\"\\),\\)?.*?\
+in_scope=\"\\(.*?\\)\".*?}")
(defun gdbmi-var-update-handler ()
(dolist (var gdb-var-list)
@@ -684,8 +696,9 @@ value=\\(\".*?\"\\),type=\"\\(.+?\\)\"}")
(setcar (nthcdr 5 var) 'changed)
(setcar (nthcdr 4 var)
(read (match-string 2)))))))
- (with-current-buffer gud-comint-buffer
- (speedbar-timer-fn)))
+ (setq gdb-pending-triggers
+ (delq 'gdb-var-update gdb-pending-triggers))
+ (gdb-speedbar-update))
(defun gdb-var-delete ()
"Delete watch expression at point from the speedbar."
@@ -705,9 +718,7 @@ value=\\(\".*?\"\\),type=\"\\(.+?\\)\"}")
(setq gdb-var-list (delq var gdb-var-list))
(dolist (varchild gdb-var-list)
(if (string-match (concat (car var) "\\.") (car varchild))
- (setq gdb-var-list (delq varchild gdb-var-list)))))))
- (with-current-buffer gud-comint-buffer
- (speedbar-refresh)))
+ (setq gdb-var-list (delq varchild gdb-var-list))))))))
(defun gdb-edit-value (text token indent)
"Assign a value to a variable displayed in the speedbar."
@@ -850,7 +861,7 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'."
(interactive)
(if gdb-use-separate-io-buffer
(gdb-display-buffer
- (gdb-get-buffer-create 'gdb-inferior-io))))
+ (gdb-get-buffer-create 'gdb-inferior-io) t)))
(defconst gdb-frame-parameters
'((height . 14) (width . 80)
@@ -860,7 +871,7 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'."
(minibuffer . nil)))
(defun gdb-frame-separate-io-buffer ()
- "Display IO of inferior in a new frame."
+ "Display IO of debugged program in a new frame."
(interactive)
(if gdb-use-separate-io-buffer
(let ((special-display-regexps (append special-display-regexps '(".*")))
@@ -869,11 +880,11 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'."
(defvar gdb-inferior-io-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map "\C-c\C-c" 'gdb-inferior-io-interrupt)
- (define-key map "\C-c\C-z" 'gdb-inferior-io-stop)
- (define-key map "\C-c\C-\\" 'gdb-inferior-io-quit)
- (define-key map "\C-c\C-d" 'gdb-inferior-io-eof)
- (define-key map "\C-d" 'gdb-inferior-io-eof)
+ (define-key map "\C-c\C-c" 'gdb-separate-io-interrupt)
+ (define-key map "\C-c\C-z" 'gdb-separate-io-stop)
+ (define-key map "\C-c\C-\\" 'gdb-separate-io-quit)
+ (define-key map "\C-c\C-d" 'gdb-separate-io-eof)
+ (define-key map "\C-d" 'gdb-separate-io-eof)
map))
(define-derived-mode gdb-inferior-io-mode comint-mode "Inferior I/O"
@@ -887,29 +898,29 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'."
(defun gdb-inferior-filter (proc string)
(unless (string-equal string "")
- (gdb-display-buffer (gdb-get-buffer-create 'gdb-inferior-io)))
+ (gdb-display-buffer (gdb-get-buffer-create 'gdb-inferior-io) t))
(with-current-buffer (gdb-get-buffer-create 'gdb-inferior-io)
(insert-before-markers string)))
-(defun gdb-inferior-io-interrupt ()
+(defun gdb-separate-io-interrupt ()
"Interrupt the program being debugged."
(interactive)
(interrupt-process
(get-buffer-process gud-comint-buffer) comint-ptyp))
-(defun gdb-inferior-io-quit ()
+(defun gdb-separate-io-quit ()
"Send quit signal to the program being debugged."
(interactive)
(quit-process
(get-buffer-process gud-comint-buffer) comint-ptyp))
-(defun gdb-inferior-io-stop ()
+(defun gdb-separate-io-stop ()
"Stop the program being debugged."
(interactive)
(stop-process
(get-buffer-process gud-comint-buffer) comint-ptyp))
-(defun gdb-inferior-io-eof ()
+(defun gdb-separate-io-eof ()
"Send end-of-file to the program being debugged."
(interactive)
(process-send-eof
@@ -1015,20 +1026,22 @@ static char *magick[] = {
(push (cons 'mi-send (concat string "\n")) gdb-debug-ring))
(if (string-match "^-" string)
;; MI command
- (process-send-string proc (concat string "\n"))
+ (progn
+ (setq gdb-first-done-or-error t)
+ (process-send-string proc (concat string "\n")))
;; CLI command
(if (string-match "\\\\$" string)
(setq gdb-continuation (concat gdb-continuation string "\n"))
+ (setq gdb-first-done-or-error t)
(process-send-string proc (concat "-interpreter-exec console-quoted \""
gdb-continuation string "\"\n"))
(setq gdb-continuation nil))))
(defun gdb-input (item)
(if gdb-enable-debug (push (cons 'send-item item) gdb-debug-ring))
- (unless (stringp item)
- (setq gdb-token-number (1+ gdb-token-number))
- (setcar item (concat (number-to-string gdb-token-number) (car item)))
- (push (cons gdb-token-number (car (cdr item))) gdb-handler-alist))
+ (setq gdb-token-number (1+ gdb-token-number))
+ (setcar item (concat (number-to-string gdb-token-number) (car item)))
+ (push (cons gdb-token-number (car (cdr item))) gdb-handler-alist)
(process-send-string (get-buffer-process gud-comint-buffer)
(car item)))
@@ -1045,8 +1058,8 @@ static char *magick[] = {
;; fullname added GDB 6.4+.
(defconst gdb-stopped-regexp
- "\\*stopped,reason=.*?addr=\"\\(.*?\\)\",func=\"\\(.*?\\)\".*?,file=\".*?\"\
-,fullname=\"\\(.*?\\)\",line=\"\\(.*?\\)\"}\n")
+ "\\*stopped,reason=\"\\(.*?\\)\",\\(exit-code=.*?\\|\
+.*?file=\".*?\",fullname=\"\\(.*?\\)\",line=\"\\(.*?\\)\"\\).*?\n")
(defconst gdb-console-regexp "~\\(\".*?[^\\]\"\\)\n")
@@ -1076,7 +1089,8 @@ static char *magick[] = {
(gdbmi-invalidate-registers)
(gdbmi-invalidate-locals)
(when (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
- (setq gdb-force-update t)
+ (dolist (var gdb-var-list)
+ (setcar (nthcdr 5 var) nil))
(gdbmi-var-update)))
;; GUD displays the selected GDB frame. This might might not be the current
@@ -1107,24 +1121,22 @@ static char *magick[] = {
(let ((output "") (output-record) (preamble))
(if (string-match gdb-running-regexp gud-marker-acc)
- (setq gud-marker-acc (concat (substring gud-marker-acc 0 (match-beginning 0))
- (substring gud-marker-acc (match-end 0)))
+ (setq gud-marker-acc (substring gud-marker-acc (match-end 0))
gud-running t))
(when (string-match gdb-stopped-regexp gud-marker-acc)
- (setq
-
- gdb-current-frame (match-string 2 gud-marker-acc)
-
- ;; Extract the frame position from the marker.
- gud-last-frame (cons (match-string 3 gud-marker-acc)
- (string-to-number
- (match-string 4 gud-marker-acc)))
-
- gud-marker-acc (concat (substring gud-marker-acc 0 (match-beginning 0))
- (substring gud-marker-acc (match-end 0)))
- gud-running nil)
- (gdbmi-update))
+ (unless (string-equal (match-string 1 gud-marker-acc) "exited")
+ (setq
+ ;; Extract the frame position from the marker.
+ gud-last-frame (cons (match-string 3 gud-marker-acc)
+ (string-to-number
+ (match-string 4 gud-marker-acc))))
+ (gdbmi-update))
+
+ (setq gud-marker-acc
+ (concat (substring gud-marker-acc 0 (match-beginning 0))
+ (substring gud-marker-acc (match-end 0)))
+ gud-running nil))
;; process command outputs one by one.
(while (string-match gdb-gdb-regexp gud-marker-acc)
@@ -1133,34 +1145,38 @@ static char *magick[] = {
gud-marker-acc (substring gud-marker-acc (match-end 0)))
(if (string-match gdb-done-or-error-regexp output-record)
-
- (progn
- (unless gdb-handler-alist (gdbmi-update))
-
- ;; Identify the handler from token number
- (let ((match (or (match-string 2 output-record)
- (match-string 3 output-record))))
+
+ ;; Identify the handler from token number
+ (let ((match (or (match-string 2 output-record)
+ (match-string 3 output-record))))
- (if (string-equal match "")
- ;; Output from command entered by user
- (progn
- (setq gdb-output-sink 'user)
- (setq gdb-handler-number nil)
- ;; MI error - send to minibuffer
- (if (match-string 3 output-record)
- (message (read (match-string 4 output-record)))))
- ;; Output from command from frontend.
- (setq gdb-handler-number (string-to-number match))
- (setq gdb-output-sink 'emacs))
-
- (gdb-clear-partial-output)
- ;; preamble should just be console and log stream
- (setq preamble (substring output-record 0 (match-beginning 0)))
- (setq output-record (substring output-record (match-end 0)))))
-
- (setq preamble output-record)
- (setq output-record "")
- (setq gdb-handler-number nil))
+ (if (string-equal match "")
+ ;; Output from command entered by user
+ (progn
+ (setq gdb-output-sink 'user)
+ (setq gdb-handler-number nil)
+ ;; MI error - send to minibuffer
+ (if (match-string 3 output-record)
+ (message (read (match-string 4 output-record)))))
+ ;; Output from command from frontend.
+ (setq gdb-handler-number (string-to-number match))
+ (setq gdb-output-sink 'emacs))
+
+ (gdb-clear-partial-output)
+ ;; preamble should just be console, log stream or inferior output
+ (setq preamble (substring output-record 0 (match-beginning 0)))
+ (setq output-record (substring output-record (match-end 0)))
+ (when gdb-first-done-or-error
+ (gdbmi-update)
+ (setq gdb-first-done-or-error nil)))
+
+ (setq preamble output-record
+ output-record ""
+ gdb-handler-number nil
+ gud-running nil))
+
+ ;; FIXME: Order of console, log stream and inferior output might be lost
+ ;; with what follows:
;; Remove the trimmings from the console stream and send to GUD buffer
;; (frontend MI commands should not print to this stream)
@@ -1189,8 +1205,10 @@ static char *magick[] = {
error-message)
error-message))
- preamble (substring preamble (match-end 0))))
+ preamble (substring preamble (match-end 0))))
+ ;; Preamble here should just be inferior output.
+ (setq output (gdbmi-concat-output output preamble))
(setq output (gdbmi-concat-output output output-record))
(when gdb-handler-number
@@ -1201,8 +1219,9 @@ static char *magick[] = {
(assq-delete-all gdb-handler-number gdb-handler-alist))))
(unless gdb-handler-alist
- (if (string-equal gud-marker-acc "")
- (setq output (concat output gdb-prompt-name)))
+ (setq output (gdbmi-concat-output output gud-marker-acc))
+ (unless gud-running (setq output (concat output gdb-prompt-name)))
+ (setq gud-marker-acc "")
(setq gdb-output-sink 'user))
output))
@@ -1304,8 +1323,11 @@ addr=\"\\(.*?\\)\",\
(concat
(nth 0 breakpoint) " "
(nth 1 breakpoint) " "
- (nth 2 breakpoint) " "
- (nth 3 breakpoint) " "
+ (nth 2 breakpoint) " "
+ (propertize (nth 3 breakpoint)
+ 'face (if (eq (string-to-char (nth 3 breakpoint)) ?y)
+ font-lock-warning-face
+ font-lock-type-face)) " "
(nth 9 breakpoint) " "
(nth 4 breakpoint) " "
(if (nth 5 breakpoint)
@@ -1478,7 +1500,7 @@ of the current session."
"Display status of user-settable breakpoints."
(interactive)
(gdb-display-buffer
- (gdb-get-buffer-create 'gdb-breakpoints-buffer)))
+ (gdb-get-buffer-create 'gdb-breakpoints-buffer) t))
(defun gdb-frame-breakpoints-buffer ()
"Display status of user-settable breakpoints in a new frame."
@@ -1564,7 +1586,7 @@ of the current session."
(let* ((buffer (find-file-noselect
(if (file-exists-p file) file
(cdr (assoc bptno gdb-location-alist)))))
- (window (unless (gdb-display-source-buffer buffer)
+ (window (or (gdb-display-source-buffer buffer)
(display-buffer buffer))))
(setq gdb-source-window window)
(with-current-buffer buffer
@@ -1615,7 +1637,8 @@ from=\"\\(.*?\\)\"\\)")
(concat
(nth 0 frame) "\t"
(nth 1 frame) "\t"
- (nth 2 frame) "\t"
+ (propertize (nth 2 frame)
+ 'face font-lock-function-name-face) "\t"
(if (nth 3 frame)
(concat "at "(nth 3 frame) ":" (nth 4 frame) "\n")
(concat "from " (nth 5 frame) "\n")))))
@@ -1633,10 +1656,17 @@ from=\"\\(.*?\\)\"\\)")
'(mouse-face highlight
help-echo "mouse-2, RET: Select frame"))
(beginning-of-line)
- (when (and (looking-at "^[0-9]+\\s-+\\(\\S-+\\)")
+ (when (and (looking-at "^[0-9]+\\s-+\\S-+\\s-+\\(\\S-+\\)")
(equal (match-string 1) gdb-selected-frame))
- (put-text-property (point-at-bol) (point-at-eol)
- 'face '(:inverse-video t)))
+ (if (> (car (window-fringes)) 0)
+ (progn
+ (or gdb-stack-position
+ (setq gdb-stack-position (make-marker)))
+ (set-marker gdb-stack-position (point)))
+ (set-marker gdb-stack-position nil)
+ (let ((bl (point-at-bol)))
+ (put-text-property bl (+ bl 4)
+ 'face '(:inverse-video t)))))
(forward-line 1))))))
(defun gdb-stack-buffer-name ()
@@ -1647,7 +1677,7 @@ from=\"\\(.*?\\)\"\\)")
"Display backtrace of current stack."
(interactive)
(gdb-display-buffer
- (gdb-get-buffer-create 'gdb-stack-buffer)))
+ (gdb-get-buffer-create 'gdb-stack-buffer) t))
(defun gdb-frame-stack-buffer ()
"Display backtrace of current stack in a new frame."
@@ -1672,6 +1702,8 @@ from=\"\\(.*?\\)\"\\)")
(kill-all-local-variables)
(setq major-mode 'gdb-frames-mode)
(setq mode-name "Frames")
+ (setq gdb-stack-position nil)
+ (add-to-list 'overlay-arrow-variable-list 'gdb-stack-position)
(setq buffer-read-only t)
(use-local-map gdb-frames-mode-map)
(run-mode-hooks 'gdb-frames-mode-hook)
@@ -1707,10 +1739,31 @@ from=\"\\(.*?\\)\"\\)")
(defvar gdb-locals-watch-map
(let ((map (make-sparse-keymap)))
+ (suppress-keymap map)
+ (define-key map "\r" 'gud-watch)
(define-key map [mouse-2] 'gud-watch)
map)
"Keymap to create watch expression of a complex data type local variable.")
+(defvar gdb-edit-locals-map-1
+ (let ((map (make-sparse-keymap)))
+ (suppress-keymap map)
+ (define-key map "\r" 'gdb-edit-locals-value)
+ (define-key map [mouse-2] 'gdb-edit-locals-value)
+ map)
+ "Keymap to edit value of a simple data type local variable.")
+
+(defun gdb-edit-locals-value (&optional event)
+ "Assign a value to a variable displayed in the locals buffer."
+ (interactive (list last-input-event))
+ (save-excursion
+ (if event (posn-set-point (event-end event)))
+ (beginning-of-line)
+ (let* ((var (current-word))
+ (value (read-string (format "New value (%s): " var))))
+ (gud-basic-call
+ (concat gdb-server-prefix"set variable " var " = " value)))))
+
;; Dont display values of arrays or structures.
;; These can be expanded using gud-watch.
(defun gdb-stack-list-locals-handler nil
@@ -1730,17 +1783,23 @@ from=\"\\(.*?\\)\"\\)")
(let* ((window (get-buffer-window buf 0))
(start (window-start window))
(p (window-point window))
- (buffer-read-only nil))
+ (buffer-read-only nil) (name) (value))
(erase-buffer)
(dolist (local locals-list)
(setq name (car local))
- (if (or (not (nth 2 local))
- (string-match "\\0x" (nth 2 local)))
+ (setq value (nth 2 local))
+ (if (or (not value)
+ (string-match "\\0x" value))
(add-text-properties 0 (length name)
`(mouse-face highlight
help-echo "mouse-2: create watch expression"
local-map ,gdb-locals-watch-map)
- name))
+ name)
+ (add-text-properties 0 (length value)
+ `(mouse-face highlight
+ help-echo "mouse-2: edit value"
+ local-map ,gdb-edit-locals-map-1)
+ value))
(insert
(concat name "\t" (nth 1 local)
"\t" (nth 2 local) "\n")))
@@ -1775,7 +1834,7 @@ from=\"\\(.*?\\)\"\\)")
"Display local variables of current stack and their values."
(interactive)
(gdb-display-buffer
- (gdb-get-buffer-create 'gdb-locals-buffer)))
+ (gdb-get-buffer-create 'gdb-locals-buffer) t))
(defun gdb-frame-locals-buffer ()
"Display local variables of current stack and their values in a new frame."
@@ -1872,7 +1931,7 @@ from=\"\\(.*?\\)\"\\)")
"Display integer register contents."
(interactive)
(gdb-display-buffer
- (gdb-get-buffer-create 'gdb-registers-buffer)))
+ (gdb-get-buffer-create 'gdb-registers-buffer) t))
(defun gdb-frame-registers-buffer ()
"Display integer register contents in a new frame."
@@ -1974,7 +2033,7 @@ is set in them."
(setq gdb-prompt-name (match-string 1)))
;;;; Window management
-(defun gdb-display-buffer (buf &optional size)
+(defun gdb-display-buffer (buf dedicated &optional size)
(let ((answer (get-buffer-window buf 0))
(must-split nil))
(if answer
@@ -1994,7 +2053,7 @@ is set in them."
(new-size (and size (< size cur-size) (- cur-size size))))
(setq answer (split-window largest new-size))
(set-window-buffer answer buf)
- (set-window-dedicated-p answer t)))
+ (set-window-dedicated-p answer dedicated)))
answer)))
@@ -2011,7 +2070,7 @@ is set in them."
'("Disassembly" . gdb-display-assembler-buffer))
(define-key menu [registers] '("Registers" . gdb-display-registers-buffer))
(define-key menu [inferior]
- '(menu-item "Inferior IO" gdb-display-separate-io-buffer
+ '(menu-item "Separate IO" gdb-display-separate-io-buffer
:enable gdb-use-separate-io-buffer))
(define-key menu [locals] '("Locals" . gdb-display-locals-buffer))
(define-key menu [frames] '("Stack" . gdb-display-stack-buffer))
@@ -2028,7 +2087,7 @@ is set in them."
(define-key menu [disassembly] '("Disassembly" . gdb-frame-assembler-buffer))
(define-key menu [registers] '("Registers" . gdb-frame-registers-buffer))
(define-key menu [inferior]
- '(menu-item "Inferior IO" gdb-frame-separate-io-buffer
+ '(menu-item "Separate IO" gdb-frame-separate-io-buffer
:enable gdb-use-separate-io-buffer))
(define-key menu [locals] '("Locals" . gdb-frame-locals-buffer))
(define-key menu [frames] '("Stack" . gdb-frame-stack-buffer))
@@ -2039,8 +2098,8 @@ is set in them."
(define-key gud-menu-map [mi]
`(menu-item "GDB-MI" ,menu :visible (eq gud-minor-mode 'gdbmi)))
(define-key menu [gdb-use-separate-io]
- '(menu-item "Separate inferior IO" gdb-use-separate-io-buffer
- :help "Toggle separate IO for inferior."
+ '(menu-item "Separate IO" gdb-use-separate-io-buffer
+ :help "Toggle separate IO for debugged program."
:button (:toggle . gdb-use-separate-io-buffer)))
(define-key menu [gdb-many-windows]
'(menu-item "Display Other Windows" gdb-many-windows
@@ -2054,7 +2113,9 @@ is set in them."
"Display GUD buffer in a new frame."
(interactive)
(let ((special-display-regexps (append special-display-regexps '(".*")))
- (special-display-frame-alist gdb-frame-parameters)
+ (special-display-frame-alist
+ (remove '(menu-bar-lines) (remove '(tool-bar-lines)
+ gdb-frame-parameters)))
(same-window-regexps nil))
(display-buffer gud-comint-buffer)))
@@ -2086,7 +2147,12 @@ is set in them."
(switch-to-buffer
(if gud-last-last-frame
(gud-find-file (car gud-last-last-frame))
- (gud-find-file gdb-main-file)))
+ (if gdb-main-file
+ (gud-find-file gdb-main-file)
+ ;; Put buffer list in window if we
+ ;; can't find a source file.
+ (list-buffers-noselect))))
+ (setq gdb-source-window (selected-window))
(when gdb-use-separate-io-buffer
(split-window-horizontally)
(other-window 1)
@@ -2103,7 +2169,7 @@ is set in them."
"Nil means just pop up the GUD buffer unless `gdb-show-main' is t.
In this case it starts with two windows: one displaying the GUD
buffer and the other with the source file with the main routine
-of the inferior. Non-nil means display the layout shown for
+of the debugged program. Non-nil means display the layout shown for
`gdbmi'."
:type 'boolean
:group 'gud
@@ -2140,11 +2206,12 @@ This arrangement depends on the value of `gdb-many-windows'."
(if gud-last-last-frame
(gud-find-file (car gud-last-last-frame))
(gud-find-file gdb-main-file)))
+ (setq gdb-source-window (selected-window))
(other-window 1))))
(defun gdb-reset ()
"Exit a debugging session cleanly.
-Kills the gdb buffers and resets the source buffers."
+Kills the gdb buffers, and resets variables and the source buffers."
(dolist (buffer (buffer-list))
(unless (eq buffer gud-comint-buffer)
(with-current-buffer buffer
@@ -2155,14 +2222,14 @@ Kills the gdb buffers and resets the source buffers."
(setq gud-minor-mode nil)
(kill-local-variable 'tool-bar-map)
(kill-local-variable 'gdb-define-alist))))))
- (when (markerp gdb-overlay-arrow-position)
- (move-marker gdb-overlay-arrow-position nil)
- (setq gdb-overlay-arrow-position nil))
+ (setq gdb-overlay-arrow-position nil)
(setq overlay-arrow-variable-list
(delq 'gdb-overlay-arrow-position overlay-arrow-variable-list))
(setq fringe-indicator-alist '((overlay-arrow . right-triangle)))
- (if (and (boundp 'speedbar-frame) (frame-live-p speedbar-frame))
- (speedbar-refresh))
+ (setq gdb-stack-position nil)
+ (setq overlay-arrow-variable-list
+ (delq 'gdb-stack-position overlay-arrow-variable-list))
+ (if (boundp 'speedbar-frame) (speedbar-timer-fn))
(setq gud-running nil)
(setq gdb-active-process nil)
(remove-hook 'after-save-hook 'gdb-create-define-alist t))
@@ -2323,4 +2390,4 @@ BUFFER nil or omitted means use the current buffer."
(display-buffer (get-buffer-create "xbacktrace"))))
(provide 'gdb-mi)
-;;; gdbmiasync.el ends here
+;;; gdb-mi.el ends here