comparison lisp/comint/gdb.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children b82b59fe008d
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 ;;; gdb.el --- run gdb under Emacs
2
3 ;; Author: W. Schelter, University of Texas
4 ;; wfs@rascal.ics.utexas.edu
5 ;; Rewritten by rms.
6 ;; Keywords: c, unix, tools, debugging
7
8 ;; Some ideas are due to Masanobu.
9
10 ;; This file is part of XEmacs.
11
12 ;; XEmacs is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; any later version.
16
17 ;; XEmacs is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
21
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free
24 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 ;; Description of GDB interface:
27
28 ;; A facility is provided for the simultaneous display of the source code
29 ;; in one window, while using gdb to step through a function in the
30 ;; other. A small arrow in the source window, indicates the current
31 ;; line.
32
33 ;; Starting up:
34
35 ;; In order to use this facility, invoke the command GDB to obtain a
36 ;; shell window with the appropriate command bindings. You will be asked
37 ;; for the name of a file to run. Gdb will be invoked on this file, in a
38 ;; window named *gdb-foo* if the file is foo.
39
40 ;; M-s steps by one line, and redisplays the source file and line.
41
42 ;; You may easily create additional commands and bindings to interact
43 ;; with the display. For example to put the gdb command next on \M-n
44 ;; (def-gdb next "\M-n")
45
46 ;; This causes the emacs command gdb-next to be defined, and runs
47 ;; gdb-display-frame after the command.
48
49 ;; gdb-display-frame is the basic display function. It tries to display
50 ;; in the other window, the file and line corresponding to the current
51 ;; position in the gdb window. For example after a gdb-step, it would
52 ;; display the line corresponding to the position for the last step. Or
53 ;; if you have done a backtrace in the gdb buffer, and move the cursor
54 ;; into one of the frames, it would display the position corresponding to
55 ;; that frame.
56
57 ;; gdb-display-frame is invoked automatically when a filename-and-line-number
58 ;; appears in the output.
59
60 (require 'comint)
61 (require 'shell)
62
63 (condition-case nil
64 (if (featurep 'toolbar)
65 (require 'eos-toolbar "sun-eos-toolbar"))
66 (error nil))
67
68 (defvar gdb-last-frame)
69 (defvar gdb-delete-prompt-marker)
70 (defvar gdb-filter-accumulator)
71 (defvar gdb-last-frame-displayed-p)
72 (defvar gdb-arrow-extent nil)
73 (or (fboundp 'make-glyph) (fset 'make-glyph 'identity)) ; work w/ pre beta v12
74 (defvar gdb-arrow-glyph (make-glyph "=>"))
75
76 (make-face 'gdb-arrow-face)
77 (or (face-differs-from-default-p 'gdb-arrow-face)
78 ;; Usually has a better default value than highlight does
79 (copy-face 'isearch 'gdb-arrow-face))
80
81 ;; Hooks can side-effect extent arg to change extent properties
82 (defvar gdb-arrow-extent-hooks '())
83
84 (defvar gdb-prompt-pattern "^>\\|^(.*gdb[+]?) *\\|^---Type <return> to.*--- *"
85 "A regexp to recognize the prompt for gdb or gdb+.")
86
87 (defvar gdb-mode-map nil
88 "Keymap for gdb-mode.")
89
90 (defvar gdb-toolbar
91 '([eos::toolbar-stop-at-icon
92 gdb-toolbar-break
93 t
94 "Stop at selected position"]
95 [eos::toolbar-stop-in-icon
96 gdb-toolbar-break
97 t
98 "Stop in function whose name is selected"]
99 [eos::toolbar-clear-at-icon
100 gdb-toolbar-clear
101 t
102 "Clear at selected position"]
103 [eos::toolbar-evaluate-icon
104 nil
105 nil
106 "Evaluate selected expression; shows in separate XEmacs frame"]
107 [eos::toolbar-evaluate-star-icon
108 nil
109 nil
110 "Evaluate selected expression as a pointer; shows in separate XEmacs frame"]
111 [eos::toolbar-run-icon
112 gdb-run
113 t
114 "Run current program"]
115 [eos::toolbar-cont-icon
116 gdb-cont
117 t
118 "Continue current program"]
119 [eos::toolbar-step-into-icon
120 gdb-step
121 t
122 "Step into (aka step)"]
123 [eos::toolbar-step-over-icon
124 gdb-next
125 t
126 "Step over (aka next)"]
127 [eos::toolbar-up-icon
128 gdb-up
129 t
130 "Stack Up (towards \"cooler\" - less recently visited - frames)"]
131 [eos::toolbar-down-icon
132 gdb-down
133 t
134 "Stack Down (towards \"warmer\" - more recently visited - frames)"]
135 [eos::toolbar-fix-icon nil nil "Fix (not available with gdb)"]
136 [eos::toolbar-build-icon
137 toolbar-compile
138 t
139 "Build (aka make -NYI)"]
140 ))
141
142 (if gdb-mode-map
143 nil
144 (setq gdb-mode-map (make-sparse-keymap))
145 (set-keymap-name gdb-mode-map 'gdb-mode-map)
146 (set-keymap-parents gdb-mode-map (list comint-mode-map))
147 (define-key gdb-mode-map "\C-l" 'gdb-refresh)
148 (define-key gdb-mode-map "\C-c\C-c" 'gdb-control-c-subjob)
149 (define-key gdb-mode-map "\t" 'comint-dynamic-complete)
150 (define-key gdb-mode-map "\M-?" 'comint-dynamic-list-completions))
151
152 (define-key ctl-x-map " " 'gdb-break)
153 (define-key ctl-x-map "&" 'send-gdb-command)
154
155 ;;Of course you may use `def-gdb' with any other gdb command, including
156 ;;user defined ones.
157
158 (defmacro def-gdb (name key &optional doc &rest forms)
159 (let* ((fun (intern (format "gdb-%s" name)))
160 (cstr (list 'if '(not (= 1 arg))
161 (list 'format "%s %s" name 'arg)
162 name)))
163 (list 'progn
164 (nconc (list 'defun fun '(arg)
165 (or doc "")
166 '(interactive "p")
167 (list 'gdb-call cstr))
168 forms)
169 (and key (list 'define-key 'gdb-mode-map key (list 'quote fun))))))
170
171 (def-gdb "step" "\M-s" "Step one source line with display"
172 (gdb-delete-arrow-extent))
173 (def-gdb "stepi" "\M-i" "Step one instruction with display"
174 (gdb-delete-arrow-extent))
175 (def-gdb "finish" "\C-c\C-f" "Finish executing current function"
176 (gdb-delete-arrow-extent))
177 (def-gdb "run" nil "Run the current program"
178 (gdb-delete-arrow-extent))
179
180 ;;"next" and "cont" were bound to M-n and M-c in Emacs 18, but these are
181 ;;poor choices, since M-n is used for history navigation and M-c is
182 ;;capitalize-word. These are defined without key bindings so that users
183 ;;may choose their own bindings.
184 (def-gdb "next" "\C-c\C-n" "Step one source line (skip functions)"
185 (gdb-delete-arrow-extent))
186 (def-gdb "cont" "\C-c\M-c" "Proceed with the program"
187 (gdb-delete-arrow-extent))
188
189 (def-gdb "up" "\C-c<" "Go up N stack frames (numeric arg) with display")
190 (def-gdb "down" "\C-c>" "Go down N stack frames (numeric arg) with display")
191
192 (defvar gdb-display-mode nil
193 "Minor mode for gdb frame display")
194 (or (assq 'gdb-display-mode minor-mode-alist)
195 (setq minor-mode-alist
196 (purecopy
197 (append minor-mode-alist
198 '((gdb-display-mode " Frame"))))))
199
200 (defun gdb-display-mode (&optional arg)
201 "Toggle GDB Frame display mode
202 With arg, turn display mode on if and only if arg is positive.
203 In the display minor mode, source file are displayed in another
204 window for repective \\[gdb-display-frame] commands."
205 (interactive "P")
206 (setq gdb-display-mode (if (null arg)
207 (not gdb-display-mode)
208 (> (prefix-numeric-value arg) 0))))
209
210
211 (defun gdb-mode ()
212 "Major mode for interacting with an inferior Gdb process.
213 The following commands are available:
214
215 \\{gdb-mode-map}
216
217 \\[gdb-display-frame] displays in the other window
218 the last line referred to in the gdb buffer. See also
219 \\[gdb-display-mode].
220
221 \\[gdb-step],\\[gdb-next], and \\[gdb-nexti] in the gdb window,
222 call gdb to step,next or nexti and then update the other window
223 with the current file and position.
224
225 If you are in a source file, you may select a point to break
226 at, by doing \\[gdb-break].
227
228 Commands:
229 Many commands are inherited from comint mode.
230 Additionally we have:
231
232 \\[gdb-display-frame] display frames file in other window
233 \\[gdb-step] advance one line in program
234 \\[send-gdb-command] used for special printing of an arg at the current point.
235 C-x SPACE sets break point at current line."
236 (interactive)
237 (comint-mode)
238 (use-local-map gdb-mode-map)
239 (set-syntax-table c-mode-syntax-table)
240 (make-local-variable 'gdb-last-frame-displayed-p)
241 (make-local-variable 'gdb-last-frame)
242 (make-local-variable 'gdb-delete-prompt-marker)
243 (make-local-variable 'gdb-display-mode)
244 (make-local-variable' gdb-filter-accumulator)
245 (setq gdb-last-frame nil
246 gdb-delete-prompt-marker nil
247 gdb-filter-accumulator nil
248 gdb-display-mode t
249 major-mode 'gdb-mode
250 mode-name "Inferior GDB"
251 comint-prompt-regexp gdb-prompt-pattern
252 gdb-last-frame-displayed-p t)
253 (set (make-local-variable 'shell-dirtrackp) t)
254 ;;(make-local-variable 'gdb-arrow-extent)
255 (and (extentp gdb-arrow-extent)
256 (delete-extent gdb-arrow-extent))
257 (setq gdb-arrow-extent nil)
258 ;; XEmacs change:
259 (make-local-hook 'kill-buffer-hook)
260 (add-hook 'kill-buffer-hook 'gdb-delete-arrow-extent nil t)
261 (setq comint-input-sentinel 'shell-directory-tracker)
262 (run-hooks 'gdb-mode-hook))
263
264 (defun gdb-delete-arrow-extent ()
265 (let ((inhibit-quit t))
266 (if gdb-arrow-extent
267 (delete-extent gdb-arrow-extent))
268 (setq gdb-arrow-extent nil)))
269
270 (defvar current-gdb-buffer nil)
271
272 ;;;###autoload
273 (defvar gdb-command-name "gdb"
274 "Pathname for executing gdb.")
275
276 ;;;###autoload
277 (defun gdb (path &optional corefile)
278 "Run gdb on program FILE in buffer *gdb-FILE*.
279 The directory containing FILE becomes the initial working directory
280 and source-file directory for GDB. If you wish to change this, use
281 the GDB commands `cd DIR' and `directory'."
282 (interactive "FRun gdb on file: ")
283 (setq path (file-truename (expand-file-name path)))
284 (let ((file (file-name-nondirectory path)))
285 (switch-to-buffer (concat "*gdb-" file "*"))
286 (setq default-directory (file-name-directory path))
287 (or (bolp) (newline))
288 (insert "Current directory is " default-directory "\n")
289 (apply 'make-comint
290 (concat "gdb-" file)
291 (substitute-in-file-name gdb-command-name)
292 nil
293 "-fullname"
294 "-cd" default-directory
295 file
296 (and corefile (list corefile)))
297 (set-process-filter (get-buffer-process (current-buffer)) 'gdb-filter)
298 (set-process-sentinel (get-buffer-process (current-buffer)) 'gdb-sentinel)
299 ;; XEmacs change: turn on gdb mode after setting up the proc filters
300 ;; for the benefit of shell-font.el
301 (gdb-mode)
302 (gdb-set-buffer)))
303
304 ;;;####autoload
305 (defun gdb-with-core (file corefile)
306 "Debug a program using a corefile."
307 (interactive "fProgram to debug: \nfCore file to use: ")
308 (gdb file corefile))
309
310 (defun gdb-set-buffer ()
311 (cond ((eq major-mode 'gdb-mode)
312 (setq current-gdb-buffer (current-buffer))
313 (if (featurep 'eos-toolbar)
314 (set-specifier default-toolbar (cons (current-buffer)
315 gdb-toolbar))))))
316
317
318 ;; This function is responsible for inserting output from GDB
319 ;; into the buffer.
320 ;; Aside from inserting the text, it notices and deletes
321 ;; each filename-and-line-number;
322 ;; that GDB prints to identify the selected frame.
323 ;; It records the filename and line number, and maybe displays that file.
324 (defun gdb-filter (proc string)
325 (let ((inhibit-quit t))
326 (save-current-buffer
327 (set-buffer (process-buffer proc))
328 (if gdb-filter-accumulator
329 (gdb-filter-accumulate-marker
330 proc (concat gdb-filter-accumulator string))
331 (gdb-filter-scan-input proc string)))))
332
333 (defun gdb-filter-accumulate-marker (proc string)
334 (setq gdb-filter-accumulator nil)
335 (if (> (length string) 1)
336 (if (= (aref string 1) ?\032)
337 (let ((end (string-match "\n" string)))
338 (if end
339 (progn
340 (let* ((first-colon (string-match ":" string 2))
341 (second-colon
342 (string-match ":" string (1+ first-colon))))
343 (setq gdb-last-frame
344 (cons (substring string 2 first-colon)
345 (string-to-int
346 (substring string (1+ first-colon)
347 second-colon)))))
348 (setq gdb-last-frame-displayed-p nil)
349 (gdb-filter-scan-input proc
350 (substring string (1+ end))))
351 (setq gdb-filter-accumulator string)))
352 (gdb-filter-insert proc "\032")
353 (gdb-filter-scan-input proc (substring string 1)))
354 (setq gdb-filter-accumulator string)))
355
356 (defun gdb-filter-scan-input (proc string)
357 (if (equal string "")
358 (setq gdb-filter-accumulator nil)
359 (let ((start (string-match "\032" string)))
360 (if start
361 (progn (gdb-filter-insert proc (substring string 0 start))
362 (gdb-filter-accumulate-marker proc
363 (substring string start)))
364 (gdb-filter-insert proc string)))))
365
366 (defun gdb-filter-insert (proc string)
367 (let ((moving (= (point) (process-mark proc)))
368 (output-after-point (< (point) (process-mark proc))))
369 (save-excursion
370 ;; Insert the text, moving the process-marker.
371 (goto-char (process-mark proc))
372 (insert-before-markers string)
373 (set-marker (process-mark proc) (point))
374 (gdb-maybe-delete-prompt)
375 ;; Check for a filename-and-line number.
376 (gdb-display-frame
377 ;; Don't display the specified file
378 ;; unless (1) point is at or after the position where output appears
379 ;; and (2) this buffer is on the screen.
380 (or output-after-point
381 (not (get-buffer-window (current-buffer))))
382 ;; Display a file only when a new filename-and-line-number appears.
383 t))
384 (if moving (goto-char (process-mark proc))))
385
386 (let (s)
387 (if (and (should-use-dialog-box-p)
388 (setq s (or (string-match " (y or n) *\\'" string)
389 (string-match " (yes or no) *\\'" string))))
390 (gdb-mouse-prompt-hack (substring string 0 s) (current-buffer))))
391 )
392
393 (defun gdb-mouse-prompt-hack (prompt buffer)
394 (popup-dialog-box
395 (list prompt
396 (vector "Yes" (list 'gdb-mouse-prompt-hack-answer 't buffer) t)
397 (vector "No" (list 'gdb-mouse-prompt-hack-answer 'nil buffer) t)
398 nil
399 (vector "Cancel" (list 'gdb-mouse-prompt-hack-answer 'nil buffer) t)
400 )))
401
402 (defun gdb-mouse-prompt-hack-answer (answer buffer)
403 (let ((b (current-buffer)))
404 (unwind-protect
405 (progn
406 (set-buffer buffer)
407 (goto-char (process-mark (get-buffer-process buffer)))
408 (delete-region (point) (point-max))
409 (insert (if answer "yes" "no"))
410 (comint-send-input))
411 (set-buffer b))))
412
413 (defun gdb-sentinel (proc msg)
414 (cond ((null (buffer-name (process-buffer proc)))
415 ;; buffer killed
416 ;; Stop displaying an arrow in a source file.
417 ;(setq overlay-arrow-position nil) -- done by kill-buffer-hook
418 (set-process-buffer proc nil))
419 ((memq (process-status proc) '(signal exit))
420 ;; Stop displaying an arrow in a source file.
421 (gdb-delete-arrow-extent)
422 ;; Fix the mode line.
423 (setq modeline-process
424 (concat ": gdb " (symbol-name (process-status proc))))
425 (let* ((obuf (current-buffer)))
426 ;; save-excursion isn't the right thing if
427 ;; process-buffer is current-buffer
428 (unwind-protect
429 (progn
430 ;; Write something in *compilation* and hack its mode line,
431 (set-buffer (process-buffer proc))
432 ;; Force mode line redisplay soon
433 (set-buffer-modified-p (buffer-modified-p))
434 (if (eobp)
435 (insert ?\n mode-name " " msg)
436 (save-excursion
437 (goto-char (point-max))
438 (insert ?\n mode-name " " msg)))
439 ;; If buffer and mode line will show that the process
440 ;; is dead, we can delete it now. Otherwise it
441 ;; will stay around until M-x list-processes.
442 (delete-process proc))
443 ;; Restore old buffer, but don't restore old point
444 ;; if obuf is the gdb buffer.
445 (set-buffer obuf))))))
446
447
448 (defun gdb-refresh (&optional arg)
449 "Fix up a possibly garbled display, and redraw the arrow."
450 (interactive "P")
451 (recenter arg)
452 (gdb-display-frame))
453
454 (defun gdb-display-frame (&optional nodisplay noauto)
455 "Find, obey and delete the last filename-and-line marker from GDB.
456 The marker looks like \\032\\032FILENAME:LINE:CHARPOS\\n.
457 Obeying it means displaying in another window the specified file and line."
458 (interactive)
459 (gdb-set-buffer)
460 (and gdb-last-frame (not nodisplay)
461 gdb-display-mode
462 (or (not gdb-last-frame-displayed-p) (not noauto))
463 (progn (gdb-display-line (car gdb-last-frame) (cdr gdb-last-frame))
464 (setq gdb-last-frame-displayed-p t))))
465
466 ;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
467 ;; and that its line LINE is visible.
468 ;; Put the overlay-arrow on the line LINE in that buffer.
469
470 (defun gdb-display-line (true-file line &optional select-method)
471 ;; FILE to display
472 ;; LINE number to highlight and make visible
473 ;; SELECT-METHOD 'source, 'debugger, or 'none. (default is 'debugger)
474 (and (null select-method) (setq select-method 'debugger))
475 (let* ((pre-display-buffer-function nil) ; screw it, put it all in one screen
476 (pop-up-windows t)
477 (source-buffer (find-file-noselect true-file))
478 (source-window (display-buffer source-buffer))
479 (debugger-window (get-buffer-window current-gdb-buffer))
480 (extent gdb-arrow-extent)
481 pos)
482 ;; XEmacs change: make sure we find a window displaying the source file
483 ;; even if we are already sitting in it when a breakpoint is hit.
484 ;; Otherwise the t argument to display-buffer will prevent it from being
485 ;; displayed.
486 (save-excursion
487 (cond ((eq select-method 'debugger)
488 ;; might not already be displayed
489 (setq debugger-window (display-buffer current-gdb-buffer))
490 (select-window debugger-window))
491 ((eq select-method 'source)
492 (select-window source-window))))
493 (and extent
494 (not (eq (extent-object extent) source-buffer))
495 (setq extent (delete-extent extent)))
496 (or extent
497 (progn
498 (setq extent (make-extent 1 1 source-buffer))
499 (set-extent-face extent 'gdb-arrow-face)
500 (set-extent-begin-glyph extent gdb-arrow-glyph)
501 (set-extent-begin-glyph-layout extent 'whitespace)
502 (set-extent-priority extent 2000)
503 (setq gdb-arrow-extent extent)))
504 (save-current-buffer
505 (set-buffer source-buffer)
506 (save-restriction
507 (widen)
508 (goto-line line)
509 (set-window-point source-window (point))
510 (setq pos (point))
511 (end-of-line)
512 (set-extent-endpoints extent pos (point))
513 (run-hook-with-args 'gdb-arrow-extent-hooks extent))
514 (cond ((or (< pos (point-min)) (> pos (point-max)))
515 (widen)
516 (goto-char pos))))
517 ;; Added by Stig. It caused lots of problems for several users
518 ;; and since its purpose is unclear it is getting commented out.
519 ;;(and debugger-window
520 ;; (set-window-point debugger-window pos))
521 ))
522
523 (defun gdb-call (command)
524 "Invoke gdb COMMAND displaying source in other window."
525 (interactive)
526 (goto-char (point-max))
527 ;; Record info on the last prompt in the buffer and its position.
528 ;; This is used in gdb-maybe-delete-prompt
529 ;; to prevent multiple prompts from accumulating.
530 (save-excursion
531 (goto-char (process-mark (get-buffer-process current-gdb-buffer)))
532 (let ((pt (point)))
533 (beginning-of-line)
534 (setq gdb-delete-prompt-marker
535 (if (= (point) pt)
536 nil
537 (list (point-marker) (- pt (point))
538 (buffer-substring (point) pt))))))
539 (gdb-set-buffer)
540 (process-send-string (get-buffer-process current-gdb-buffer)
541 (concat command "\n")))
542
543 (defun gdb-maybe-delete-prompt ()
544 (if gdb-delete-prompt-marker
545 ;; Get the string that we used as the prompt before.
546 (let ((prompt (nth 2 gdb-delete-prompt-marker))
547 (length (nth 1 gdb-delete-prompt-marker)))
548 ;; Position after it.
549 (goto-char (+ (car gdb-delete-prompt-marker) length))
550 ;; Delete any duplicates of it which follow right after.
551 (while (and (<= (+ (point) length) (point-max))
552 (string= prompt
553 (buffer-substring (point) (+ (point) length))))
554 (delete-region (point) (+ (point) length)))
555 ;; If that didn't take us to where output is arriving,
556 ;; we have encountered something other than a prompt,
557 ;; so stop trying to delete any more prompts.
558 (if (not (= (point)
559 (process-mark (get-buffer-process current-gdb-buffer))))
560 (progn
561 (set-marker (car gdb-delete-prompt-marker) nil)
562 (setq gdb-delete-prompt-marker nil))))))
563
564 (defun gdb-break (temp)
565 "Set GDB breakpoint at this source line. With ARG set temporary breakpoint."
566 (interactive "P")
567 (let* ((file-name (file-name-nondirectory buffer-file-name))
568 (line (save-restriction
569 (widen)
570 (beginning-of-line)
571 (1+ (count-lines 1 (point)))))
572 (cmd (concat (if temp "tbreak " "break ") file-name ":"
573 (int-to-string line))))
574 (set-buffer current-gdb-buffer)
575 (goto-char (process-mark (get-buffer-process current-gdb-buffer)))
576 (delete-region (point) (point-max))
577 (insert cmd)
578 (comint-send-input)
579 ;;(process-send-string (get-buffer-process current-gdb-buffer) cmd)
580 ))
581
582 (defun gdb-clear ()
583 "Set GDB breakpoint at this source line."
584 (interactive)
585 (let* ((file-name (file-name-nondirectory buffer-file-name))
586 (line (save-restriction
587 (widen)
588 (beginning-of-line)
589 (1+ (count-lines 1 (point)))))
590 (cmd (concat "clear " file-name ":"
591 (int-to-string line))))
592 (set-buffer current-gdb-buffer)
593 (goto-char (process-mark (get-buffer-process current-gdb-buffer)))
594 (delete-region (point) (point-max))
595 (insert cmd)
596 (comint-send-input)
597 ;;(process-send-string (get-buffer-process current-gdb-buffer) cmd)
598 ))
599
600 (defun gdb-read-address()
601 "Return a string containing the core-address found in the buffer at point."
602 (save-excursion
603 (let ((pt (point)) found begin)
604 (setq found (if (search-backward "0x" (- pt 7) t)(point)))
605 (cond (found (forward-char 2)
606 (buffer-substring found
607 (progn (re-search-forward "[^0-9a-f]")
608 (forward-char -1)
609 (point))))
610 (t (setq begin (progn (re-search-backward "[^0-9]") (forward-char 1)
611 (point)))
612 (forward-char 1)
613 (re-search-forward "[^0-9]")
614 (forward-char -1)
615 (buffer-substring begin (point)))))))
616
617
618 (defvar gdb-commands nil
619 "List of strings or functions used by send-gdb-command.
620 It is for customization by you.")
621
622 (defun send-gdb-command (arg)
623
624 "This command reads the number where the cursor is positioned. It
625 then inserts this ADDR at the end of the gdb buffer. A numeric arg
626 selects the ARG'th member COMMAND of the list gdb-print-command. If
627 COMMAND is a string, (format COMMAND ADDR) is inserted, otherwise
628 (funcall COMMAND ADDR) is inserted. eg. \"p (rtx)%s->fld[0].rtint\"
629 is a possible string to be a member of gdb-commands. "
630
631
632 (interactive "P")
633 (let (comm addr)
634 (if arg (setq comm (nth arg gdb-commands)))
635 (setq addr (gdb-read-address))
636 (if (eq (current-buffer) current-gdb-buffer)
637 (set-mark (point)))
638 (cond (comm
639 (setq comm
640 (if (stringp comm) (format comm addr) (funcall comm addr))))
641 (t (setq comm addr)))
642 (switch-to-buffer current-gdb-buffer)
643 (goto-char (point-max))
644 (insert comm)))
645
646 (defun gdb-control-c-subjob ()
647 "Send a Control-C to the subprocess."
648 (interactive)
649 (process-send-string (get-buffer-process (current-buffer))
650 "\C-c"))
651
652 (defun gdb-toolbar-break ()
653 (interactive)
654 (save-excursion
655 (message (car gdb-last-frame))
656 (set-buffer (find-file-noselect (car gdb-last-frame)))
657 (gdb-break nil)))
658
659 (defun gdb-toolbar-clear ()
660 (interactive)
661 (save-excursion
662 (message (car gdb-last-frame))
663 (set-buffer (find-file-noselect (car gdb-last-frame)))
664 (gdb-clear)))
665
666 (provide 'gdb)