Initial revision
[bpt/emacs.git] / lisp / gud.el
CommitLineData
f961a17c
ER
1;;; gud.el --- Grand Unified Debugger mode for gdb, sdb, or dbx under Emacs
2
3;; Author: Eric S. Raymond <eric@snark.thyrsus.com>
4;; Keywords: unix, tools
5
24d725c2 6;; %W%
f961a17c
ER
7
8;; Copyright (C) 1992 Free Software Foundation, Inc.
13b80a60
ER
9
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
24d725c2 14;; the Free Software Foundation; either version 2, or (at your option)
13b80a60
ER
15;; any later version.
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs; see the file COPYING. If not, write to
24;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25
f961a17c
ER
26;;; Commentary:
27
13b80a60 28;; The ancestral gdb.el was by W. Schelter <wfs@rascal.ics.utexas.edu>
24d725c2 29;; It was later rewritten by rms. Some ideas were due to Masanobu.
f961a17c 30;; Grand Unification (sdb/dbx support) by Eric S. Raymond <esr@thyrsus.com>
13b80a60
ER
31;; The overloading code was then rewritten by Barry Warsaw <bwarsaw@cen.com>,
32;; who also hacked the mode to use comint.el.
33
f961a17c
ER
34;; Note: use of this package with sdb requires that your tags.el support
35;; the find-tag-noselect entry point. Stock distributions up to 18.57 do
36;; *not* include this feature; if it's not included with this file, email
37;; esr@snark.thyrsus.com for it or get 18.58.
38
39;; Further note: due to lossage in the Emacs-18 byte compiler, compiled
40;; versions of this code will fail with a complaint about gud-step if
41;; you invoke the gdb or sdb initializers. This should be fixed in 19.
42
43;;; Code:
44
13b80a60 45(require 'comint)
e8a57935 46(require 'etags)
13b80a60
ER
47
48;; ======================================================================
49;; the overloading mechanism
50
51(defun gud-overload-functions (gud-overload-alist)
52 "Overload functions defined in GUD-OVERLOAD-ALIST.
53This association list has elements of the form
13b80a60 54 (ORIGINAL-FUNCTION-NAME OVERLOAD-FUNCTION)"
24d725c2
ER
55 (mapcar
56 (function (lambda (p) (fset (car p) (symbol-function (cdr p)))))
57 gud-overload-alist))
13b80a60
ER
58
59(defun gud-debugger-startup (f d)
60 (error "GUD not properly entered."))
61
62(defun gud-marker-filter (proc s)
63 (error "GUD not properly entered."))
64
65(defun gud-visit-file (f)
66 (error "GUD not properly entered."))
67
68(defun gud-set-break (proc f n)
69 (error "GUD not properly entered."))
70
71;; This macro is used below to define some basic debugger interface commands.
f961a17c 72;; Of course you may use `gud-def' with any other debugger command, including
6bde8427
JB
73;; user defined ones.
74
75;; A macro call like (gud-def FUNC NAME KEY DOC) expands to a form
76;; which defines FUNC to send the command NAME to the debugger, gives
77;; it the docstring DOC, and binds that function to KEY. NAME should
78;; be a string. If a numeric prefix argument is given to FUNC, it
79;; gets sent after NAME.
13b80a60 80
f961a17c 81(defmacro gud-def (func name key &optional doc)
13b80a60 82 (let* ((cstr (list 'if '(not (= 1 arg))
6bde8427
JB
83 (list 'format "%s %s" name 'arg)
84 name)))
13b80a60
ER
85 (list 'progn
86 (list 'defun func '(arg)
87 (or doc "")
88 '(interactive "p")
89 (list 'gud-call cstr))
0d4ee849
RS
90 (if key
91 (list 'define-key 'gud-mode-map key (list 'quote func))))))
13b80a60 92
d840a865
JB
93;; Where gud-display-frame should put the debugging arrow. This is
94;; set by the marker-filter, which scans the debugger's output for
95;; indications of the current pc.
96(defvar gud-last-frame nil)
97
13b80a60
ER
98;; All debugger-specific information is collected here
99;; Here's how it works, in case you ever need to add a debugger to the table.
100;;
101;; Each entry must define the following at startup:
102;;
103;;<name>
104;; comint-prompt-regexp
24d725c2 105;; gud-<name>-debugger-startup
13b80a60 106;; gud-<name>-marker-filter
24d725c2 107;; gud-<name>-visit-file
13b80a60
ER
108;; gud-<name>-set-break
109;;
10a4c11f
JB
110;; The job of the startup-command method is to fire up a copy of the debugger,
111;; given an object file and source directory.
112;;
113;; The job of the marker-filter method is to detect file/line markers in
114;; strings and set the global gud-last-frame to indicate what display
115;; action (if any) should be triggered by the marker. Note that only
116;; whetever the method *returns* is displayed in the buffer; thus, you
117;; can filter the debugger's output, interpreting some and passing on
118;; the rest.
119;;
120;; The job of the visit-file method is to visit and return the buffer indicated
121;; by the car of gud-tag-frame. This may be a file name, a tag name, or
122;; something else.
123;;
124;; The job of the gud-set-break method is to send the commands necessary
125;; to set a breakpoint at a given line in a given source file.
126;;
127;; Debugger-specific information begins here:
13b80a60
ER
128
129;; ======================================================================
130;; gdb functions
131
132(defun gud-gdb-debugger-startup (f d)
133 (make-comint (concat "gud-" f) "gdb" nil "-fullname" "-cd" d f))
134
6bde8427
JB
135(defun gud-gdb-marker-filter (proc string)
136 (if (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n" string)
13b80a60
ER
137 (progn
138 (setq gud-last-frame
139 (cons
140 (substring string (match-beginning 1) (match-end 1))
141 (string-to-int
142 (substring string (match-beginning 2) (match-end 2)))))
143 ;; this computation means the ^Z^Z-initiated marker in the
144 ;; input string is never emitted.
145 (concat
146 (substring string 0 (match-beginning 0))
147 (substring string (match-end 0))
148 ))
149 string))
150
151(defun gud-gdb-visit-file (f)
152 (find-file-noselect f))
153
154(defun gud-gdb-set-break (proc f n)
155 (gud-call "break %s:%d" f n))
156
10a4c11f 157;;;###autoload
13b80a60
ER
158(defun gdb (path)
159 "Run gdb on program FILE in buffer *gud-FILE*.
160The directory containing FILE becomes the initial working directory
161and source-file directory for your debugger."
162 (interactive "fRun gdb on file: ")
24d725c2
ER
163 (gud-overload-functions '((gud-debugger-startup . gud-gdb-debugger-startup)
164 (gud-marker-filter . gud-gdb-marker-filter)
165 (gud-visit-file . gud-gdb-visit-file)
166 (gud-set-break . gud-gdb-set-break)))
13b80a60 167
b6df3e11
RS
168 (gud-def gud-step "step" "\C-c\C-s" "Step one source line with display")
169 (gud-def gud-stepi "stepi" "\C-c\C-i" "Step one instruction with display")
170 (gud-def gud-next "next" "\C-c\C-n" "Step one line (skip functions)")
6bde8427 171 (gud-def gud-cont "cont" "\C-c\C-r" "Continue with display")
13b80a60 172
f961a17c
ER
173 (gud-def gud-finish "finish" "\C-c\C-f" "Finish executing current function")
174 (gud-def gud-up "up" "\C-c<" "Up N stack frames (numeric arg)")
175 (gud-def gud-down "down" "\C-c>" "Down N stack frames (numeric arg)")
13b80a60
ER
176
177 (gud-common-init path)
178
179 (setq comint-prompt-regexp "^(.*gdb[+]?) *")
180 (run-hooks 'gdb-mode-hook)
181 )
182
183
184;; ======================================================================
185;; sdb functions
186
187(defun gud-sdb-debugger-startup (f d)
188 (make-comint (concat "gud-" f) "sdb" nil f "-" d))
189
6bde8427 190(defun gud-sdb-marker-filter (proc string)
13b80a60 191 (if (string-match "\\(^0x\\w* in \\|^\\|\n\\)\\([^:\n]*\\):\\([0-9]*\\):.*\n"
6bde8427 192 string)
13b80a60
ER
193 (setq gud-last-frame
194 (cons
195 (substring string (match-beginning 2) (match-end 2))
196 (string-to-int
197 (substring string (match-beginning 3) (match-end 3))))))
198 string)
199
200(defun gud-sdb-visit-file (f)
24d725c2 201 (find-tag-noselect f))
13b80a60
ER
202
203(defun gud-sdb-set-break (proc f n)
204 (gud-queue-send (format "e %s" f) (format "%d b" n)))
205
10a4c11f 206;;;###autoload
13b80a60
ER
207(defun sdb (path)
208 "Run sdb on program FILE in buffer *gud-FILE*.
209The directory containing FILE becomes the initial working directory
210and source-file directory for your debugger."
e8a57935 211 (interactive "fRun sdb on file: ")
13b80a60
ER
212 (if (not (and (boundp 'tags-file-name) (file-exists-p tags-file-name)))
213 (error "The sdb support requires a valid tags table to work."))
24d725c2
ER
214 (gud-overload-functions '((gud-debugger-startup . gud-sdb-debugger-startup)
215 (gud-marker-filter . gud-sdb-marker-filter)
216 (gud-visit-file . gud-sdb-visit-file)
217 (gud-set-break . gud-sdb-set-break)))
13b80a60 218
b6df3e11
RS
219 (gud-def gud-step "s" "\C-c\C-s" "Step one source line with display")
220 (gud-def gud-stepi "i" "\C-c\C-i" "Step one instruction with display")
221 (gud-def gud-next "S" "\C-c\C-n" "Step one source line (skip functions)")
6bde8427 222 (gud-def gud-cont "c" "\C-c\C-r" "Continue with display (`resume')")
13b80a60
ER
223
224 (gud-common-init path)
225
6bde8427 226 (setq comint-prompt-regexp "\\(^\\|\n\\)\\*")
13b80a60
ER
227 (run-hooks 'sdb-mode-hook)
228 )
229
230;; ======================================================================
231;; dbx functions
232
233(defun gud-dbx-debugger-startup (f d)
6bde8427 234 (make-comint (concat "gud-" f) "dbx" nil f))
13b80a60 235
6bde8427 236(defun gud-dbx-marker-filter (proc string)
13b80a60 237 (if (string-match
6bde8427 238 "stopped in .* at line \\([0-9]*\\) in file \"\\([^\"]*\\)\"" string)
13b80a60
ER
239 (setq gud-last-frame
240 (cons
241 (substring string (match-beginning 2) (match-end 2))
242 (string-to-int
243 (substring string (match-beginning 1) (match-end 1))))))
244 string)
245
246(defun gud-dbx-visit-file (f)
247 (find-file-noselect f))
248
249(defun gud-dbx-set-break (proc f n)
250 (gud-call "stop at \"%s\":%d" f n))
251
10a4c11f 252;;;###autoload
13b80a60
ER
253(defun dbx (path)
254 "Run dbx on program FILE in buffer *gud-FILE*.
255The directory containing FILE becomes the initial working directory
256and source-file directory for your debugger."
257 (interactive "fRun dbx on file: ")
24d725c2
ER
258 (gud-overload-functions '((gud-debugger-startup . gud-dbx-debugger-startup)
259 (gud-marker-filter . gud-dbx-marker-filter)
260 (gud-visit-file . gud-dbx-visit-file)
261 (gud-set-break . gud-dbx-set-break)))
262
b6df3e11
RS
263 (gud-def gud-step "step" "\C-c\C-s" "Step one source line with display")
264 (gud-def gud-stepi "stepi" "\C-c\C-i" "Step one instruction with display")
265 (gud-def gud-next "next" "\C-c\C-n" "Step one line (skip functions)")
6bde8427 266 (gud-def gud-cont "cont" "\C-c\C-r" "Continue with display (`resume')")
24d725c2
ER
267
268 (gud-def gud-up "up" "\C-c<" "Up N stack frames (numeric arg)")
269 (gud-def gud-down "down" "\C-c>" "Down N stack frames (numeric arg)")
13b80a60 270
13b80a60 271 (gud-common-init path)
f961a17c 272 (setq comint-prompt-regexp "^[^)]*dbx) *")
13b80a60
ER
273
274 (run-hooks 'dbx-mode-hook)
275 )
276
13b80a60
ER
277;;
278;; End of debugger-specific information
10a4c11f 279;;
13b80a60
ER
280
281(defvar gud-mode-map nil
282 "Keymap for gud-mode.")
283
24d725c2
ER
284(defvar gud-commands nil
285 "List of strings or functions used by send-gud-command.
286It is for customization by you.")
287
13b80a60
ER
288(defvar gud-command-queue nil)
289
53eb3a97
JB
290;;; When we send a command to the debugger via gud-call, it's annoying
291;;; to see the command and the new prompt inserted into the debugger's
292;;; buffer; we have other ways of knowing the command has completed.
293;;;
294;;; If the buffer looks like this:
295;;; --------------------
296;;; (gdb) set args foo bar
297;;; (gdb) -!-
298;;; --------------------
299;;; (the -!- marks the location of point), and we type `C-x SPC' in a
300;;; source file to set a breakpoint, we want the buffer to end up like
301;;; this:
302;;; --------------------
303;;; (gdb) set args foo bar
304;;; Breakpoint 1 at 0x92: file make-docfile.c, line 49.
305;;; (gdb) -!-
306;;; --------------------
307;;; Essentially, the old prompt is deleted, and the command's output
308;;; and the new prompt take its place.
309;;;
310;;; Not echoing the command is easy enough; you send it directly using
311;;; process-send-string, and it never enters the buffer. However,
312;;; getting rid of the old prompt is trickier; you don't want to do it
313;;; when you send the command, since that will result in an annoying
314;;; flicker as the prompt is deleted, redisplay occurs while Emacs
315;;; waits for a response from the debugger, and the new prompt is
316;;; inserted. Instead, we'll wait until we actually get some output
317;;; from the subprocess before we delete the prompt. If the command
318;;; produced no output other than a new prompt, that prompt will most
319;;; likely be in the first chunk of output received, so we will delete
320;;; the prompt and then replace it with an identical one. If the
321;;; command produces output, the prompt is moving anyway, so the
322;;; flicker won't be annoying.
323;;;
324;;; So - when we want to delete the prompt upon receipt of the next
325;;; chunk of debugger output, we position gud-delete-prompt-marker at
326;;; the start of the prompt; the process filter will notice this, and
327;;; delete all text between it and the process output marker. If
328;;; gud-delete-prompt-marker points nowhere, we leave the current
329;;; prompt alone.
330(defvar gud-delete-prompt-marker nil)
331
13b80a60
ER
332(if gud-mode-map
333 nil
334 (setq gud-mode-map (copy-keymap comint-mode-map))
6bde8427 335 (define-key gud-mode-map "\C-c\C-l" 'gud-refresh))
13b80a60 336
24d725c2 337;; Global mappings --- we'll invoke these from a source buffer.
13b80a60
ER
338(define-key ctl-x-map " " 'gud-break)
339(define-key ctl-x-map "&" 'send-gud-command)
340
341\f
342(defun gud-mode ()
343 "Major mode for interacting with an inferior debugger process.
24d725c2
ER
344
345 You start it up with one of the commands M-x gdb, M-x sdb, or
346M-x dbx. Each entry point finishes by executing a hook; gdb-mode-hook,
347sdb-mode-hook or dbx-mode-hook respectively.
348
349After startup, the following commands are available:
13b80a60
ER
350
351\\{gud-mode-map}
352
24d725c2
ER
353\\[gud-refresh] displays in the other window the last line referred to
354in the gud buffer.
13b80a60 355
24d725c2 356\\[gud-step], \\[gud-next], and \\[gud-stepi] in the gud window,
13b80a60
ER
357do a step-one-line, step-one-line (not entering function calls), and
358step-one-instruction and then update the other window
359with the current file and position. \\[gud-cont] continues
360execution.
361
24d725c2
ER
362The above commands are common to all supported debuggers. If you are
363using gdb or dbx, the following additional commands will be available:
364
365\\[gud-up] pops up through an enclosing stack frame. \\[gud-down] drops
366back down through one.
367
368If you are using gdb, \\[gdb-finish] runs execution to the return from
369the current function and stops.
370
371These functions repeat themselves the appropriate number of times if you give a
372prefix argument.
373
374If you are in a source file, you may do the following:
375
376Set a breakpoint at the current line by doing \\[gud-break]. This causes
377an appropriate set-break to be send to the debugger; of course, if the file
378you're visiting doesn't correspond to any code in the executable this will
379have no effect or raise an error.
13b80a60 380
24d725c2
ER
381Execute a user-defined command at point with \\[send-gud-command]; the
382prefix argument is taken as an index into the list of strings gud-commands.
383A %s in a gud-commands string is substituted with a number or address picked
384up from point.
13b80a60 385
24d725c2
ER
386Other commands for interacting with the debugger process are inherited from
387comint mode, which see."
13b80a60
ER
388 (interactive)
389 (comint-mode)
390; (kill-all-local-variables)
391 (setq major-mode 'gud-mode)
392 (setq mode-name "Debugger")
393 (setq mode-line-process '(": %s"))
394 (use-local-map gud-mode-map)
395 (make-local-variable 'gud-last-frame)
396 (setq gud-last-frame nil)
397 (make-local-variable 'comint-prompt-regexp)
53eb3a97
JB
398 (make-local-variable 'gud-delete-prompt-marker)
399 (setq gud-delete-prompt-marker (make-marker))
13b80a60
ER
400 (run-hooks 'gud-mode-hook)
401)
402
403(defvar current-gud-buffer nil)
404
405(defun gud-common-init (path)
406 ;; perform initializations common to all debuggers
407 (setq path (expand-file-name path))
408 (let ((file (file-name-nondirectory path)))
409 (switch-to-buffer (concat "*gud-" file "*"))
410 (setq default-directory (file-name-directory path))
411 (or (bolp) (newline))
412 (insert "Current directory is " default-directory "\n")
413 (gud-debugger-startup file default-directory))
414 (gud-mode)
415 (set-process-filter (get-buffer-process (current-buffer)) 'gud-filter)
416 (set-process-sentinel (get-buffer-process (current-buffer)) 'gud-sentinel)
417 (setq gud-command-queue nil)
418 (gud-set-buffer)
419 )
420
421(defun gud-set-buffer ()
422 (cond ((eq major-mode 'gud-mode)
423 (setq current-gud-buffer (current-buffer)))))
424\f
425(defun gud-filter (proc string)
426 ;; This function is responsible for inserting output from your debugger
427 ;; into the buffer. The hard work is done by the method that is
428 ;; the value of gud-marker-filter.
429 (let ((inhibit-quit t))
430 (gud-filter-insert proc (gud-marker-filter proc string))
431 ;; If we've got queued commands and we see a prompt, pop one and send it.
432 ;; In theory we should check that a prompt has been issued before sending
433 ;; queued commands. In practice, command responses from the first through
434 ;; penultimate elements of a command sequence are short enough that we
435 ;; don't really have to bother.
436 (if gud-command-queue
437 (progn
438 (gud-call (car gud-command-queue))
439 (setq gud-command-queue (cdr gud-command-queue))
440 )
441 )))
442
443(defun gud-filter-insert (proc string)
444 ;; Here's where the actual buffer insertion is done
6bde8427 445 (save-excursion
13b80a60 446 (set-buffer (process-buffer proc))
7739e1b8
JB
447 (let ((moving (= (point) (process-mark proc)))
448 (output-after-point (< (point) (process-mark proc))))
449 (save-excursion
450 (goto-char (process-mark proc))
451 ;; If we have been so requested, delete the debugger prompt.
452 (if (marker-buffer gud-delete-prompt-marker)
453 (progn
454 (delete-region (point) gud-delete-prompt-marker)
455 (set-marker gud-delete-prompt-marker nil)))
456 (insert-before-markers string)
457 ;; Check for a filename-and-line number.
458 ;; Don't display the specified file
459 ;; unless (1) point is at or after the position where output appears
460 ;; and (2) this buffer is on the screen.
461 (if (and gud-last-frame
462 (not output-after-point)
463 (get-buffer-window (current-buffer)))
464 (gud-display-frame)))
465 (if moving (goto-char (process-mark proc))))))
13b80a60
ER
466
467(defun gud-sentinel (proc msg)
468 (cond ((null (buffer-name (process-buffer proc)))
469 ;; buffer killed
470 ;; Stop displaying an arrow in a source file.
471 (setq overlay-arrow-position nil)
472 (set-process-buffer proc nil))
473 ((memq (process-status proc) '(signal exit))
474 ;; Stop displaying an arrow in a source file.
475 (setq overlay-arrow-position nil)
476 ;; Fix the mode line.
477 (setq mode-line-process
478 (concat ": "
479 (symbol-name (process-status proc))))
480 (let* ((obuf (current-buffer)))
481 ;; save-excursion isn't the right thing if
482 ;; process-buffer is current-buffer
483 (unwind-protect
484 (progn
485 ;; Write something in *compilation* and hack its mode line,
486 (set-buffer (process-buffer proc))
487 ;; Force mode line redisplay soon
488 (set-buffer-modified-p (buffer-modified-p))
489 (if (eobp)
490 (insert ?\n mode-name " " msg)
491 (save-excursion
492 (goto-char (point-max))
493 (insert ?\n mode-name " " msg)))
494 ;; If buffer and mode line will show that the process
495 ;; is dead, we can delete it now. Otherwise it
496 ;; will stay around until M-x list-processes.
497 (delete-process proc))
498 ;; Restore old buffer, but don't restore old point
499 ;; if obuf is the gud buffer.
500 (set-buffer obuf))))))
501
502
503(defun gud-refresh (&optional arg)
504 "Fix up a possibly garbled display, and redraw the arrow."
505 (interactive "P")
506 (recenter arg)
507 (gud-display-frame))
508
509(defun gud-display-frame ()
510 "Find and obey the last filename-and-line marker from the debugger.
511Obeying it means displaying in another window the specified file and line."
512 (interactive)
513 (if gud-last-frame
514 (progn
515 (gud-set-buffer)
516 (gud-display-line (car gud-last-frame) (cdr gud-last-frame))
517 (setq gud-last-frame nil))))
518
519;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
520;; and that its line LINE is visible.
521;; Put the overlay-arrow on the line LINE in that buffer.
522
523(defun gud-display-line (true-file line)
524 (let* ((buffer (gud-visit-file true-file))
525 (window (display-buffer buffer t))
526 (pos))
527 (save-excursion
528 (set-buffer buffer)
529 (save-restriction
530 (widen)
531 (goto-line line)
532 (setq pos (point))
533 (setq overlay-arrow-string "=>")
534 (or overlay-arrow-position
535 (setq overlay-arrow-position (make-marker)))
536 (set-marker overlay-arrow-position (point) (current-buffer)))
537 (cond ((or (< pos (point-min)) (> pos (point-max)))
538 (widen)
539 (goto-char pos))))
540 (set-window-point window overlay-arrow-position)))
541\f
542(defun gud-call (command &rest args)
543 "Invoke the debugger COMMAND displaying source in other window."
544 (interactive)
545 (gud-set-buffer)
13b80a60
ER
546 (let ((command (concat (apply 'format command args) "\n"))
547 (proc (get-buffer-process current-gud-buffer)))
53eb3a97
JB
548
549 ;; Arrange for the current prompt to get deleted.
550 (save-excursion
551 (set-buffer current-gud-buffer)
11270fa7 552 (goto-char (process-mark proc))
53eb3a97
JB
553 (beginning-of-line)
554 (if (looking-at comint-prompt-regexp)
555 (set-marker gud-delete-prompt-marker (point))))
556
557 (goto-char (point-max))
558 (process-send-string proc command)))
13b80a60
ER
559
560(defun gud-queue-send (&rest cmdlist)
561 ;; Send the first command, queue the rest for send after successive
562 ;; send on subsequent prompts
563 (interactive)
564 (gud-call (car cmdlist))
565 (setq gud-command-queue (append gud-command-queue (cdr cmdlist))))
566
567(defun gud-apply-from-source (func)
568 ;; Apply a method from the gud buffer environment, passing it file and line.
569 ;; This is intended to be used for gud commands called from a source file.
570 (if (not buffer-file-name)
571 (error "There is no file associated with this buffer"))
572 (let ((file (file-name-nondirectory buffer-file-name))
573 (line (save-restriction (widen) (1+ (count-lines 1 (point))))))
574 (save-excursion
575 (gud-set-buffer)
576 (funcall func
577 (get-buffer-process current-gud-buffer)
578 file
579 line)
580 )))
581
582(defun gud-break ()
583 "Set breakpoint at this source line."
584 (interactive)
585 (gud-apply-from-source 'gud-set-break))
586
6bde8427 587(defun gud-read-address ()
13b80a60
ER
588 "Return a string containing the core-address found in the buffer at point."
589 (save-excursion
6bde8427
JB
590 (let ((pt (point)) found begin)
591 (setq found (if (search-backward "0x" (- pt 7) t)(point)))
592 (cond
593 (found (forward-char 2)
594 (buffer-substring found
595 (progn (re-search-forward "[^0-9a-f]")
596 (forward-char -1)
597 (point))))
598 (t (setq begin (progn (re-search-backward "[^0-9]")
599 (forward-char 1)
600 (point)))
601 (forward-char 1)
602 (re-search-forward "[^0-9]")
603 (forward-char -1)
604 (buffer-substring begin (point)))))))
13b80a60
ER
605
606
13b80a60 607(defun send-gud-command (arg)
24d725c2
ER
608 "This command reads the number where the cursor is positioned. A numeric arg
609selects the ARG'th member COMMAND of the list gud-commands. If COMMAND is a
610string, (format COMMAND ADDR) is inserted at the end of the debugger buffer,
611otherwise (funcall COMMAND ADDR) is inserted.
612 For example, \"p (rtx)%s->fld[0].rtint\" is a possible string to be a
613member of gud-commands."
13b80a60
ER
614 (interactive "P")
615 (let (comm addr)
616 (if arg (setq comm (nth arg gud-commands)))
617 (setq addr (gud-read-address))
618 (if (eq (current-buffer) current-gud-buffer)
619 (set-mark (point)))
620 (cond (comm
621 (setq comm
622 (if (stringp comm) (format comm addr) (funcall comm addr))))
623 (t (setq comm addr)))
624 (switch-to-buffer current-gud-buffer)
e8a57935 625 (goto-char (point-max))
13b80a60 626 (insert-string comm)))
10a4c11f 627
f961a17c 628;;; gud.el ends here