bf46cad1295c0e67afb68203b266913a87bd977d
[binutils-gdb.git] / gdb / gdba.el
1 (defmacro gud (form)
2 (` (save-excursion (set-buffer "*gud-a.out*") (, form))))
3
4 (defun dbug (foo &optional fun)
5 (save-excursion
6 (set-buffer (get-buffer-create "*trace*"))
7 (goto-char (point-max))
8 (insert "***" (symbol-name foo) "\n")
9 (if fun
10 (funcall fun))))
11
12
13 ;;; gud.el --- Grand Unified Debugger mode for gdb, sdb, dbx, or xdb
14 ;;; under Emacs
15
16 ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
17 ;; Maintainer: FSF
18 ;; Version: 1.3
19 ;; Keywords: unix, tools
20
21 ;; Copyright (C) 1992, 1993 Free Software Foundation, Inc.
22
23 ;; This file is part of GNU Emacs.
24
25 ;; GNU Emacs is free software; you can redistribute it and/or modify
26 ;; it under the terms of the GNU General Public License as published by
27 ;; the Free Software Foundation; either version 2, or (at your option)
28 ;; any later version.
29
30 ;; GNU Emacs is distributed in the hope that it will be useful,
31 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
32 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 ;; GNU General Public License for more details.
34
35 ;; You should have received a copy of the GNU General Public License
36 ;; along with GNU Emacs; see the file COPYING. If not, write to
37 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
38
39 ;;; Commentary:
40
41 ;; The ancestral gdb.el was by W. Schelter <wfs@rascal.ics.utexas.edu>
42 ;; It was later rewritten by rms. Some ideas were due to Masanobu.
43 ;; Grand Unification (sdb/dbx support) by Eric S. Raymond <esr@thyrsus.com>
44 ;; The overloading code was then rewritten by Barry Warsaw <bwarsaw@cen.com>,
45 ;; who also hacked the mode to use comint.el. Shane Hartman <shane@spr.com>
46 ;; added support for xdb (HPUX debugger).
47
48 ;; Cygnus Support added support for gdb's --annotate=2.
49
50 ;;; Code:
51
52 (require 'comint)
53 (require 'etags)
54
55 ;; ======================================================================
56 ;; GUD commands must be visible in C buffers visited by GUD
57
58 (defvar gud-key-prefix "\C-x\C-a"
59 "Prefix of all GUD commands valid in C buffers.")
60
61 (global-set-key (concat gud-key-prefix "\C-l") 'gud-refresh)
62 (global-set-key "\C-x " 'gud-break) ;; backward compatibility hack
63
64 ;; ======================================================================
65 ;; the overloading mechanism
66
67 (defun gud-overload-functions (gud-overload-alist)
68 "Overload functions defined in GUD-OVERLOAD-ALIST.
69 This association list has elements of the form
70 (ORIGINAL-FUNCTION-NAME OVERLOAD-FUNCTION)"
71 (mapcar
72 (function (lambda (p) (fset (car p) (symbol-function (cdr p)))))
73 gud-overload-alist))
74
75 (defun gud-massage-args (file args)
76 (error "GUD not properly entered."))
77
78 (defun gud-marker-filter (str)
79 (error "GUD not properly entered."))
80
81 (defun gud-find-file (f)
82 (error "GUD not properly entered."))
83 \f
84 ;; ======================================================================
85 ;; command definition
86
87 ;; This macro is used below to define some basic debugger interface commands.
88 ;; Of course you may use `gud-def' with any other debugger command, including
89 ;; user defined ones.
90
91 ;; A macro call like (gud-def FUNC NAME KEY DOC) expands to a form
92 ;; which defines FUNC to send the command NAME to the debugger, gives
93 ;; it the docstring DOC, and binds that function to KEY in the GUD
94 ;; major mode. The function is also bound in the global keymap with the
95 ;; GUD prefix.
96
97 (defmacro gud-def (func cmd key &optional doc)
98 "Define FUNC to be a command sending STR and bound to KEY, with
99 optional doc string DOC. Certain %-escapes in the string arguments
100 are interpreted specially if present. These are:
101
102 %f name (without directory) of current source file.
103 %d directory of current source file.
104 %l number of current source line
105 %e text of the C lvalue or function-call expression surrounding point.
106 %a text of the hexadecimal address surrounding point
107 %p prefix argument to the command (if any) as a number
108
109 The `current' source file is the file of the current buffer (if
110 we're in a C file) or the source file current at the last break or
111 step (if we're in the GUD buffer).
112 The `current' line is that of the current buffer (if we're in a
113 source file) or the source line number at the last break or step (if
114 we're in the GUD buffer)."
115 (list 'progn
116 (list 'defun func '(arg)
117 (or doc "")
118 '(interactive "p")
119 (list 'gud-call cmd 'arg))
120 (if key
121 (list 'define-key
122 '(current-local-map)
123 (concat "\C-c" key)
124 (list 'quote func)))
125 (if key
126 (list 'global-set-key
127 (list 'concat 'gud-key-prefix key)
128 (list 'quote func)))))
129
130 ;; Where gud-display-frame should put the debugging arrow. This is
131 ;; set by the marker-filter, which scans the debugger's output for
132 ;; indications of the current program counter.
133 (defvar gud-last-frame nil)
134
135 ;; Used by gud-refresh, which should cause gud-display-frame to redisplay
136 ;; the last frame, even if it's been called before and gud-last-frame has
137 ;; been set to nil.
138 (defvar gud-last-last-frame nil)
139
140 ;; All debugger-specific information is collected here.
141 ;; Here's how it works, in case you ever need to add a debugger to the mode.
142 ;;
143 ;; Each entry must define the following at startup:
144 ;;
145 ;;<name>
146 ;; comint-prompt-regexp
147 ;; gud-<name>-massage-args
148 ;; gud-<name>-marker-filter
149 ;; gud-<name>-find-file
150 ;;
151 ;; The job of the massage-args method is to modify the given list of
152 ;; debugger arguments before running the debugger.
153 ;;
154 ;; The job of the marker-filter method is to detect file/line markers in
155 ;; strings and set the global gud-last-frame to indicate what display
156 ;; action (if any) should be triggered by the marker. Note that only
157 ;; whatever the method *returns* is displayed in the buffer; thus, you
158 ;; can filter the debugger's output, interpreting some and passing on
159 ;; the rest.
160 ;;
161 ;; The job of the find-file method is to visit and return the buffer indicated
162 ;; by the car of gud-tag-frame. This may be a file name, a tag name, or
163 ;; something else.
164 \f
165 ;; ======================================================================
166 ;; gdb functions
167
168 ;;; History of argument lists passed to gdb.
169 (defvar gud-gdb-history nil)
170
171 (defun gud-gdb-massage-args (file args)
172 (cons "--annotate=2" (cons file args)))
173
174 \f
175 ;;
176 ;; In this world, there are gdb instance objects (of unspecified
177 ;; representation) and buffers associated with those objects.
178 ;;
179
180 ;;
181 ;; gdb-instance objects
182 ;;
183
184 (defun make-gdb-instance (proc)
185 "Create a gdb instance object from a gdb process."
186 (setq last-proc proc)
187 (let ((instance (cons 'gdb-instance proc)))
188 (save-excursion
189 (set-buffer (process-buffer proc))
190 (setq gdb-buffer-instance instance)
191 (progn
192 (mapcar 'make-variable-buffer-local gdb-instance-variables)
193 (setq gdb-buffer-type 'gud)
194 ;; If we're taking over the buffer of another process,
195 ;; take over it's ancillery buffers as well.
196 ;;
197 (let ((dead (or old-gdb-buffer-instance)))
198 (mapcar
199 (function
200 (lambda (b)
201 (progn
202 (set-buffer b)
203 (if (eq dead gdb-buffer-instance)
204 (setq gdb-buffer-instance instance)))))
205 (buffer-list)))))
206 instance))
207
208 (defun gdb-instance-process (inst) (cdr inst))
209
210 ;;; The list of instance variables is built up by the expansions of
211 ;;; DEF-GDB-VARIABLE
212 ;;;
213 (defvar gdb-instance-variables '()
214 "A list of variables that are local to the gud buffer associated
215 with a gdb instance.")
216
217 (defmacro def-gdb-variable
218 (name accessor setter &optional default doc)
219 (`
220 (progn
221 (defvar (, name) (, default) (, (or doc "undocumented")))
222 (if (not (memq '(, name) gdb-instance-variables))
223 (setq gdb-instance-variables
224 (cons '(, name) gdb-instance-variables)))
225 (, (and accessor
226 (`
227 (defun (, accessor) (instance)
228 (let
229 ((buffer (gdb-get-instance-buffer instance 'gud)))
230 (and buffer
231 (save-excursion
232 (set-buffer buffer)
233 (, name))))))))
234 (, (and setter
235 (`
236 (defun (, setter) (instance val)
237 (let
238 ((buffer (gdb-get-instance-buffer instance 'gud)))
239 (and buffer
240 (save-excursion
241 (set-buffer buffer)
242 (setq (, name) val)))))))))))
243
244 (defmacro def-gdb-var (root-symbol &optional default doc)
245 (let* ((root (symbol-name root-symbol))
246 (accessor (intern (concat "gdb-instance-" root)))
247 (setter (intern (concat "set-gdb-instance-" root)))
248 (var-name (intern (concat "gdb-" root))))
249 (` (def-gdb-variable
250 (, var-name) (, accessor) (, setter)
251 (, default) (, doc)))))
252
253 (def-gdb-var buffer-instance nil
254 "In an instance buffer, the buffer's instance.")
255
256 (def-gdb-var buffer-type nil
257 "One of the symbols bound in gdb-instance-buffer-rules")
258
259 (def-gdb-var burst ""
260 "A string of characters from gdb that have not yet been processed.")
261
262 (def-gdb-var input-queue ()
263 "A list of high priority gdb command objects.")
264
265 (def-gdb-var idle-input-queue ()
266 "A list of low priority gdb command objects.")
267
268 (def-gdb-var prompting nil
269 "True when gdb is idle with no pending input.")
270
271 (def-gdb-var output-sink 'user
272 "The disposition of the output of the current gdb command.
273 Possible values are these symbols:
274
275 user -- gdb output should be copied to the gud buffer
276 for the user to see.
277
278 pre-emacs -- output should be ignored util the post-prompt
279 annotation is received. Then the output-sink
280 becomes:...
281 emacs -- output should be collected in the partial-output-buffer
282 for subsequent processing by a command. This is the
283 disposition of output generated by commands that
284 gud mode sends to gdb on its own behalf.
285 post-emacs -- ignore input until the prompt annotation is
286 received, then go to USER disposition.
287 ")
288
289 (def-gdb-var current-item nil
290 "The most recent command item sent to gdb.")
291
292 (def-gdb-var pending-triggers '()
293 "A list of trigger functions that have run later than their output
294 handlers.")
295
296 (defun in-gdb-instance-context (instance form)
297 "Funcall `form' in the gud buffer of `instance'"
298 (save-excursion
299 (set-buffer (gdb-get-instance-buffer instance 'gud))
300 (funcall form)))
301
302 ;; end of instance vars
303
304 ;;
305 ;; finding instances
306 ;;
307
308 (defun gdb-proc->instance (proc)
309 (save-excursion
310 (set-buffer (process-buffer proc))
311 gdb-buffer-instance))
312
313 (defun gdb-mru-instance-buffer ()
314 "Return the most recently used (non-auxiliary) gdb gud buffer."
315 (save-excursion
316 (gdb-goto-first-gdb-instance (buffer-list))))
317
318 (defun gdb-goto-first-gdb-instance (blist)
319 "Use gdb-mru-instance-buffer -- not this."
320 (and blist
321 (progn
322 (set-buffer (car blist))
323 (or (and gdb-buffer-instance
324 (eq gdb-buffer-type 'gud)
325 (car blist))
326 (gdb-goto-first-gdb-instance (cdr blist))))))
327
328 (defun buffer-gdb-instance (buf)
329 (save-excursion
330 (set-buffer buf)
331 gdb-buffer-instance))
332
333 (defun gdb-needed-default-instance ()
334 "Return the most recently used gdb instance or signal an error."
335 (let ((buffer (gdb-mru-instance-buffer)))
336 (or (and buffer (buffer-gdb-instance buffer))
337 (error "No instance of gdb found."))))
338
339 (defun gdb-instance-target-string (instance)
340 "The apparent name of the program being debugged by a gdb instance.
341 For sure this the root string used in smashing together the gud
342 buffer's name, even if that doesn't happen to be the name of a
343 program."
344 (in-gdb-instance-context
345 instance
346 (function (lambda () gud-target-name))))
347
348 \f
349
350 ;;
351 ;; Instance Buffers.
352 ;;
353
354 ;; More than one buffer can be associated with a gdb instance.
355 ;;
356 ;; Each buffer has a TYPE -- a symbol that identifies the function
357 ;; of that particular buffer.
358 ;;
359 ;; The usual gud interaction buffer is given the type `gud' and
360 ;; is constructed specially.
361 ;;
362 ;; Others are constructed by gdb-get-create-instance-buffer and
363 ;; named according to the rules set forth in the gdb-instance-buffer-rules-assoc
364
365 (defun gdb-get-instance-buffer (instance key)
366 "Return the instance buffer for `instance' tagged with type `key'.
367 The key should be one of the cars in `gdb-instance-buffer-rules-assoc'."
368 (save-excursion
369 (gdb-look-for-tagged-buffer instance key (buffer-list))))
370
371 (defun gdb-get-create-instance-buffer (instance key)
372 "Create a new gdb instance buffer of the type specified by `key'.
373 The key should be one of the cars in `gdb-instance-buffer-rules-assoc'."
374 (or (gdb-get-instance-buffer instance key)
375 (let* ((rules (assoc key gdb-instance-buffer-rules-assoc))
376 (name (funcall (gdb-rules-name-maker rules) instance))
377 (new (get-buffer-create name)))
378 (save-excursion
379 (set-buffer new)
380 (make-variable-buffer-local 'gdb-buffer-type)
381 (setq gdb-buffer-type key)
382 (make-variable-buffer-local 'gdb-buffer-instance)
383 (setq gdb-buffer-instance instance)
384 (if (cdr (cdr rules))
385 (funcall (car (cdr (cdr rules)))))
386 new))))
387
388 (defun gdb-rules-name-maker (rules) (car (cdr rules)))
389
390 (defun gdb-look-for-tagged-buffer (instance key bufs)
391 (let ((retval nil))
392 (while (and (not retval) bufs)
393 (set-buffer (car bufs))
394 (if (and (eq gdb-buffer-instance instance)
395 (eq gdb-buffer-type key))
396 (setq retval (car bufs)))
397 (setq bufs (cdr bufs))
398 )
399 retval))
400
401 (defun gdb-instance-buffer-p (buf)
402 (save-excursion
403 (set-buffer buf)
404 (and gdb-buffer-type
405 (not (eq gdb-buffer-type 'gud)))))
406
407 ;;
408 ;; This assoc maps buffer type symbols to rules. Each rule is a list of
409 ;; at least one and possible more functions. The functions have these
410 ;; roles in defining a buffer type:
411 ;;
412 ;; NAME - take an instance, return a name for this type buffer for that
413 ;; instance.
414 ;; The remaining function(s) are optional:
415 ;;
416 ;; MODE - called in new new buffer with no arguments, should establish
417 ;; the proper mode for the buffer.
418 ;;
419
420 (defvar gdb-instance-buffer-rules-assoc '())
421
422 (defun gdb-set-instance-buffer-rules (buffer-type &rest rules)
423 (let ((binding (assoc buffer-type gdb-instance-buffer-rules-assoc)))
424 (if binding
425 (setcdr binding rules)
426 (setq gdb-instance-buffer-rules-assoc
427 (cons (cons buffer-type rules)
428 gdb-instance-buffer-rules-assoc)))))
429
430 (gdb-set-instance-buffer-rules 'gud 'error) ; gud buffers are an exception to the rules
431
432 ;;
433 ;; partial-output buffers
434 ;;
435 ;; These accumulate output from a command executed on
436 ;; behalf of emacs (rather than the user).
437 ;;
438
439 (gdb-set-instance-buffer-rules 'gdb-partial-output-buffer
440 'gdb-partial-output-name)
441
442 (defun gdb-partial-output-name (instance)
443 (concat "*partial-output-"
444 (gdb-instance-target-string instance)
445 "*"))
446
447 \f
448 (gdb-set-instance-buffer-rules 'gdb-inferior-io 'gdb-inferior-io-name)
449
450 (defun gdb-inferior-io-name (instance)
451 (concat "*input/output of "
452 (gdb-instance-target-string instance)
453 "*"))
454
455 (defvar gud-inferior-io-mode-map nil)
456 (setq gud-inferior-io-mode-map (make-keymap))
457 (suppress-keymap gud-inferior-io-mode-map)
458 (define-key gud-inferior-io-mode-map " " 'gud-toggle-bp-this-line)
459 (define-key gud-inferior-io-mode-map "d" 'gud-delete-bp-this-line)
460
461 (defun gud-inferior-io-mode ()
462 "Major mode for gud inferior-io.
463
464 \\{gud-inferior-io-mode-map}"
465 (setq major-mode 'gud-inferior-io-mode)
466 (setq mode-name "Debuggee I/O")
467 (use-local-map gud-inferior-io-mode-map)
468 )
469
470 \f
471
472 ;;
473 ;; gdb communications
474 ;;
475
476 ;; INPUT: things sent to gdb
477 ;;
478 ;; Each instance has a high and low priority
479 ;; input queue. Low priority input is sent only
480 ;; when the high priority queue is idle.
481 ;;
482 ;; The queues are lists. Each element is either
483 ;; a string (indicating user or user-like input)
484 ;; or a list of the form:
485 ;;
486 ;; (INPUT-STRING HANDLER-FN)
487 ;;
488 ;;
489 ;; The handler function will be called from the
490 ;; partial-output buffer when the command completes.
491 ;; This is the way to write commands which
492 ;; invoke gdb commands autonomously.
493 ;;
494 ;; These lists are consumed tail first.
495 ;;
496
497 (defun gdb-send (proc string)
498 "A comint send filter for gdb.
499 This filter may simply queue output for a later time."
500 (let ((instance (gdb-proc->instance proc)))
501 (gdb-instance-enqueue-input instance (concat string "\n"))))
502
503 ;; Note: Stuff enqueued here will be sent to the next prompt, even if it
504 ;; is a query, or other non-top-level prompt. To guarantee stuff will get
505 ;; sent to the top-level prompt, currently it must be put in the idle queue.
506 ;; ^^^^^^^^^
507 ;; [This should encourage gud extentions that invoke gdb commands to let
508 ;; the user go first; it is not a bug. -t]
509 ;;
510
511 (defun gdb-instance-enqueue-input (instance item)
512 (if (gdb-instance-prompting instance)
513 (progn
514 (gdb-send-item instance item)
515 (set-gdb-instance-prompting instance nil))
516 (set-gdb-instance-input-queue
517 instance
518 (cons item (gdb-instance-input-queue instance)))))
519
520 (defun gdb-instance-dequeue-input (instance)
521 (let ((queue (gdb-instance-input-queue instance)))
522 (and queue
523 (if (not (cdr queue))
524 (let ((answer (car queue)))
525 (set-gdb-instance-input-queue instance '())
526 answer)
527 (gdb-take-last-elt queue)))))
528
529 (defun gdb-instance-enqueue-idle-input (instance item)
530 (if (and (gdb-instance-prompting instance)
531 (not (gdb-instance-input-queue instance)))
532 (progn
533 (gdb-send-item instance item)
534 (set-gdb-instance-prompting instance nil))
535 (set-gdb-instance-idle-input-queue
536 instance
537 (cons item (gdb-instance-idle-input-queue instance)))))
538
539 (defun gdb-instance-dequeue-idle-input (instance)
540 (let ((queue (gdb-instance-idle-input-queue instance)))
541 (and queue
542 (if (not (cdr queue))
543 (let ((answer (car queue)))
544 (set-gdb-instance-idle-input-queue instance '())
545 answer)
546 (gdb-take-last-elt queue)))))
547
548 ; Don't use this in general.
549 (defun gdb-take-last-elt (l)
550 (if (cdr (cdr l))
551 (gdb-take-last-elt (cdr l))
552 (let ((answer (car (cdr l))))
553 (setcdr l '())
554 answer)))
555
556 \f
557 ;;
558 ;; output -- things gdb prints to emacs
559 ;;
560 ;; GDB output is a stream interrupted by annotations.
561 ;; Annotations can be recognized by their beginning
562 ;; with \C-j\C-z\C-z<tag><opt>\C-j
563 ;;
564 ;; The tag is a string obeying symbol syntax.
565 ;;
566 ;; The optional part `<opt>' can be either the empty string
567 ;; or a space followed by more data relating to the annotation.
568 ;; For example, the SOURCE annotation is followed by a filename,
569 ;; line number and various useless goo. This data must not include
570 ;; any newlines.
571 ;;
572
573
574 (defun gud-gdb-marker-filter (string)
575 "A gud marker filter for gdb."
576 ;; Bogons don't tell us the process except through scoping crud.
577 (let ((instance (gdb-proc->instance proc)))
578 (gdb-output-burst instance string)))
579
580 (defvar gdb-annotation-rules
581 '(("frames-invalid" gdb-invalidate-frames)
582 ("breakpoints-invalid" gdb-invalidate-breakpoints)
583 ("pre-prompt" gdb-pre-prompt)
584 ("prompt" gdb-prompt)
585 ("commands" gdb-subprompt)
586 ("overload-choice" gdb-subprompt)
587 ("query" gdb-subprompt)
588 ("prompt-for-continue" gdb-subprompt)
589 ("post-prompt" gdb-post-prompt)
590 ("source" gdb-source)
591 ("starting" gdb-starting)
592 ("exited" gdb-stopping)
593 ("signalled" gdb-stopping)
594 ("signal" gdb-stopping)
595 ("breakpoint" gdb-stopping)
596 ("watchpoint" gdb-stopping)
597 )
598 "An assoc mapping annotation tags to functions which process them.")
599
600
601 (defun gdb-ignore-annotation (instance args)
602 nil)
603
604 (defconst gdb-source-spec-regexp
605 "\\(.*\\):\\([0-9]*\\):[0-9]*:[a-z]*:0x[a-f0-9]*")
606
607 ;; Do not use this except as an annotation handler."
608 (defun gdb-source (instance args)
609 (string-match gdb-source-spec-regexp args)
610 ;; Extract the frame position from the marker.
611 (setq gud-last-frame
612 (cons
613 (substring args (match-beginning 1) (match-end 1))
614 (string-to-int (substring args
615 (match-beginning 2)
616 (match-end 2))))))
617
618 ;; An annotation handler for `prompt'.
619 ;; This sends the next command (if any) to gdb.
620 (defun gdb-prompt (instance ignored)
621 (let ((sink (gdb-instance-output-sink instance)))
622 (cond
623 ((eq sink 'user) t)
624 ((eq sink 'post-emacs)
625 (set-gdb-instance-output-sink instance 'user))
626 (t
627 (set-gdb-instance-output-sink instance 'user)
628 (error "Phase error in gdb-prompt (got %s)" sink))))
629 (let ((highest (gdb-instance-dequeue-input instance)))
630 (if highest
631 (gdb-send-item instance highest)
632 (let ((lowest (gdb-instance-dequeue-idle-input instance)))
633 (if lowest
634 (gdb-send-item instance lowest)
635 (progn
636 (set-gdb-instance-prompting instance t)
637 (gud-display-frame)))))))
638
639 ;; An annotation handler for non-top-level prompts.
640 (defun gdb-subprompt (instance ignored)
641 (let ((highest (gdb-instance-dequeue-input instance)))
642 (if highest
643 (gdb-send-item instance highest)
644 (set-gdb-instance-prompting instance t))))
645
646 (defun gdb-send-item (instance item)
647 (set-gdb-instance-current-item instance item)
648 (if (stringp item)
649 (progn
650 (set-gdb-instance-output-sink instance 'user)
651 (process-send-string (gdb-instance-process instance)
652 item))
653 (progn
654 (gdb-clear-partial-output instance)
655 (set-gdb-instance-output-sink instance 'pre-emacs)
656 (process-send-string (gdb-instance-process instance)
657 (car item)))))
658
659 ;; An annotation handler for `pre-prompt'.
660 ;; This terminates the collection of output from a previous
661 ;; command if that happens to be in effect.
662 (defun gdb-pre-prompt (instance ignored)
663 (let ((sink (gdb-instance-output-sink instance)))
664 (cond
665 ((eq sink 'user) t)
666 ((eq sink 'emacs)
667 (set-gdb-instance-output-sink instance 'post-emacs)
668 (let ((handler
669 (car (cdr (gdb-instance-current-item instance)))))
670 (save-excursion
671 (set-buffer (gdb-get-create-instance-buffer
672 instance 'gdb-partial-output-buffer))
673 (funcall handler))))
674 (t
675 (set-gdb-instance-output-sink instance 'user)
676 (error "Output sink phase error 1.")))))
677
678 ;; An annotation handler for `starting'. This says that I/O for the subprocess
679 ;; is now the program being debugged, not GDB.
680 (defun gdb-starting (instance ignored)
681 (let ((sink (gdb-instance-output-sink instance)))
682 (cond
683 ((eq sink 'user)
684 (set-gdb-instance-output-sink instance 'inferior)
685 ;; FIXME: need to send queued input
686 )
687 (t (error "Unexpected `starting' annotation")))))
688
689 ;; An annotation handler for `exited' and other annotations which say that
690 ;; I/O for the subprocess is now GDB, not the program being debugged.
691 (defun gdb-stopping (instance ignored)
692 (let ((sink (gdb-instance-output-sink instance)))
693 (cond
694 ((eq sink 'inferior)
695 (set-gdb-instance-output-sink instance 'user)
696 )
697 (t (error "Unexpected stopping annotation")))))
698
699 ;; An annotation handler for `post-prompt'.
700 ;; This begins the collection of output from the current
701 ;; command if that happens to be appropriate."
702 (defun gdb-post-prompt (instance ignored)
703 (gdb-invalidate-registers instance ignored)
704 (let ((sink (gdb-instance-output-sink instance)))
705 (cond
706 ((eq sink 'user) t)
707 ((eq sink 'pre-emacs)
708 (set-gdb-instance-output-sink instance 'emacs))
709
710 (t
711 (set-gdb-instance-output-sink instance 'user)
712 (error "Output sink phase error 3.")))))
713
714 ;; A buffer-local indication of how output from an inferior gdb
715 ;; should be directed. Legit values are:
716 ;;
717 ;; USER -- the output should be appended to the gud
718 ;; buffer.
719 ;;
720 ;; PRE-EMACS -- throw away output preceding output for emacs.
721 ;; EMACS -- redirect output to the partial-output buffer.
722 ;; POST-EMACS -- throw away output following output for emacs."
723 ;;
724
725 ;; Handle a burst of output from a gdb instance.
726 ;; This function is (indirectly) used as a gud-marker-filter.
727 ;; It must return output (if any) to be insterted in the gud
728 ;; buffer.
729
730 (defun gdb-output-burst (instance string)
731 "Handle a burst of output from a gdb instance.
732 This function is (indirectly) used as a gud-marker-filter.
733 It must return output (if any) to be insterted in the gud
734 buffer."
735
736 (save-match-data
737 (let (
738 ;; Recall the left over burst from last time
739 (burst (concat (gdb-instance-burst instance) string))
740 ;; Start accumulating output for the gud buffer
741 (output ""))
742
743 ;; Process all the complete markers in this chunk.
744
745 (while (string-match "\n\032\032\\(.*\\)\n" burst)
746 (let ((annotation (substring burst
747 (match-beginning 1)
748 (match-end 1))))
749
750 ;; Stuff prior to the match is just ordinary output.
751 ;; It is either concatenated to OUTPUT or directed
752 ;; elsewhere.
753 (setq output
754 (gdb-concat-output
755 instance
756 output
757 (substring burst 0 (match-beginning 0))))
758
759 ;; Take that stuff off the burst.
760 (setq burst (substring burst (match-end 0)))
761
762 ;; Parse the tag from the annotation, and maybe its arguments.
763 (string-match "\\(\\S-*\\) ?\\(.*\\)" annotation)
764 (let* ((annotation-type (substring annotation
765 (match-beginning 1)
766 (match-end 1)))
767 (annotation-arguments (substring annotation
768 (match-beginning 2)
769 (match-end 2)))
770 (annotation-rule (assoc annotation-type
771 gdb-annotation-rules)))
772 ;; Call the handler for this annotation.
773 (if annotation-rule
774 (funcall (car (cdr annotation-rule))
775 instance
776 annotation-arguments)
777 ;; Else the annotation is not recognized. Ignore it silently,
778 ;; so that GDB can add new annotations without causing
779 ;; us to blow up.
780 ))))
781
782
783 ;; Does the remaining text end in a partial line?
784 ;; If it does, then keep part of the burst until we get more.
785 (if (string-match "\n\\'\\|\n\032\\'\\|\n\032\032.*\\'"
786 burst)
787 (progn
788 ;; Everything before the potential marker start can be output.
789 (setq output
790 (gdb-concat-output
791 instance
792 output
793 (substring burst 0 (match-beginning 0))))
794
795 ;; Everything after, we save, to combine with later input.
796 (setq burst (substring burst (match-beginning 0))))
797
798 ;; In case we know the burst contains no partial annotations:
799 (progn
800 (setq output (gdb-concat-output instance output burst))
801 (setq burst "")))
802
803 ;; Save the remaining burst for the next call to this function.
804 (set-gdb-instance-burst instance burst)
805 output)))
806
807 (defun gdb-concat-output (instance so-far new)
808 (let ((sink (gdb-instance-output-sink instance)))
809 (cond
810 ((eq sink 'user) (concat so-far new))
811 ((or (eq sink 'pre-emacs) (eq sink 'post-emacs)) so-far)
812 ((eq sink 'emacs)
813 (gdb-append-to-partial-output instance new)
814 so-far)
815 ((eq sink 'inferior)
816 (gdb-append-to-inferior-io instance new)
817 so-far)
818 (t (error "Bogon output sink %S" sink)))))
819
820 (defun gdb-append-to-partial-output (instance string)
821 (save-excursion
822 (set-buffer
823 (gdb-get-create-instance-buffer
824 instance 'gdb-partial-output-buffer))
825 (goto-char (point-max))
826 (insert string)))
827
828 (defun gdb-clear-partial-output (instance)
829 (save-excursion
830 (set-buffer
831 (gdb-get-create-instance-buffer
832 instance 'gdb-partial-output-buffer))
833 (delete-region (point-min) (point-max))))
834
835 (defun gdb-append-to-inferior-io (instance string)
836 (save-excursion
837 (set-buffer
838 (gdb-get-create-instance-buffer
839 instance 'gdb-inferior-io))
840 (goto-char (point-max))
841 (insert string))
842 (gud-display-buffer
843 (gdb-get-create-instance-buffer instance
844 'gdb-inferior-io)))
845
846 (defun gdb-clear-inferior-io (instance)
847 (save-excursion
848 (set-buffer
849 (gdb-get-create-instance-buffer
850 instance 'gdb-inferior-io))
851 (delete-region (point-min) (point-max))))
852 \f
853
854
855 ;; One trick is to have a command who's output is always available in
856 ;; a buffer of it's own, and is always up to date. We build several
857 ;; buffers of this type.
858 ;;
859 ;; There are two aspects to this: gdb has to tell us when the output
860 ;; for that command might have changed, and we have to be able to run
861 ;; the command behind the user's back.
862 ;;
863 ;; The idle input queue and the output phasing associated with
864 ;; the instance variable `(gdb-instance-output-sink instance)' help
865 ;; us to run commands behind the user's back.
866 ;;
867 ;; Below is the code for specificly managing buffers of output from one
868 ;; command.
869 ;;
870
871
872 ;; The trigger function is suitable for use in the assoc GDB-ANNOTATION-RULES
873 ;; It adds an idle input for the command we are tracking. It should be the
874 ;; annotation rule binding of whatever gdb sends to tell us this command
875 ;; might have changed it's output.
876 ;;
877 ;; NAME is the fucntion name. DEMAND-PREDICATE tests if output is really needed.
878 ;; GDB-COMMAND is a string of such. OUTPUT-HANDLER is the function bound to the
879 ;; input in the input queue (see comment about ``gdb communications'' above).
880 (defmacro def-gdb-auto-update-trigger (name demand-predicate gdb-command output-handler)
881 (`
882 (defun (, name) (instance &optional ignored)
883 (if (and ((, demand-predicate) instance)
884 (not (member '(, name)
885 (gdb-instance-pending-triggers instance))))
886 (progn
887 (gdb-instance-enqueue-idle-input
888 instance
889 (list (, gdb-command) '(, output-handler)))
890 (set-gdb-instance-pending-triggers
891 instance
892 (cons '(, name)
893 (gdb-instance-pending-triggers instance))))))))
894
895 (defmacro def-gdb-auto-update-handler (name trigger buf-key)
896 (`
897 (defun (, name) ()
898 (set-gdb-instance-pending-triggers
899 instance
900 (delq '(, trigger)
901 (gdb-instance-pending-triggers instance)))
902 (let ((buf (gdb-get-instance-buffer instance
903 '(, buf-key))))
904 (and buf
905 (save-excursion
906 (set-buffer buf)
907 (let ((p (point))
908 (buffer-read-only nil))
909 (delete-region (point-min) (point-max))
910 (insert-buffer (gdb-get-create-instance-buffer
911 instance
912 'gdb-partial-output-buffer))
913 (goto-char p))))))))
914
915 (defmacro def-gdb-auto-updated-buffer
916 (buffer-key trigger-name gdb-command output-handler-name)
917 (`
918 (progn
919 (def-gdb-auto-update-trigger (, trigger-name)
920 ;; The demand predicate:
921 (lambda (instance)
922 (gdb-get-instance-buffer instance '(, buffer-key)))
923 (, gdb-command)
924 (, output-handler-name))
925 (def-gdb-auto-update-handler (, output-handler-name)
926 (, trigger-name) (, buffer-key)))))
927
928
929 \f
930 ;;
931 ;; Breakpoint buffers
932 ;;
933 ;; These display the output of `info breakpoints'.
934 ;;
935
936
937 (gdb-set-instance-buffer-rules 'gdb-breakpoints-buffer
938 'gdb-breakpoints-buffer-name
939 'gud-breakpoints-mode)
940
941 (def-gdb-auto-updated-buffer gdb-breakpoints-buffer
942 ;; This defines the auto update rule for buffers of type
943 ;; `gdb-breakpoints-buffer'.
944 ;;
945 ;; It defines a function to serve as the annotation handler that
946 ;; handles the `foo-invalidated' message. That function is called:
947 gdb-invalidate-breakpoints
948
949 ;; To update the buffer, this command is sent to gdb.
950 "server info breakpoints\n"
951
952 ;; This also defines a function to be the handler for the output
953 ;; from the command above. That function will copy the output into
954 ;; the appropriately typed buffer. That function will be called:
955 gdb-info-breakpoints-handler)
956
957 (defun gdb-breakpoints-buffer-name (instance)
958 (save-excursion
959 (set-buffer (process-buffer (gdb-instance-process instance)))
960 (concat "*breakpoints of " (gdb-instance-target-string instance) "*")))
961
962 (defun gud-display-breakpoints-buffer (instance)
963 (interactive (list (gdb-needed-default-instance)))
964 (gud-display-buffer
965 (gdb-get-create-instance-buffer instance
966 'gdb-breakpoints-buffer)))
967
968 (defun gud-frame-breakpoints-buffer (instance)
969 (interactive (list (gdb-needed-default-instance)))
970 (gud-frame-buffer
971 (gdb-get-create-instance-buffer instance
972 'gdb-breakpoints-buffer)))
973
974 (defvar gud-breakpoints-mode-map nil)
975 (setq gud-breakpoints-mode-map (make-keymap))
976 (suppress-keymap gud-breakpoints-mode-map)
977 (define-key gud-breakpoints-mode-map " " 'gud-toggle-bp-this-line)
978 (define-key gud-breakpoints-mode-map "d" 'gud-delete-bp-this-line)
979
980 (defun gud-breakpoints-mode ()
981 "Major mode for gud breakpoints.
982
983 \\{gud-breakpoints-mode-map}"
984 (setq major-mode 'gud-breakpoints-mode)
985 (setq mode-name "Breakpoints")
986 (use-local-map gud-breakpoints-mode-map)
987 (setq buffer-read-only t)
988 (gdb-invalidate-breakpoints gdb-buffer-instance))
989
990 (defun gud-toggle-bp-this-line ()
991 (interactive)
992 (save-excursion
993 (beginning-of-line 1)
994 (if (not (looking-at "\\([0-9]*\\)\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)"))
995 (error "Not recognized as breakpoint line (demo foo).")
996 (gdb-instance-enqueue-idle-input
997 gdb-buffer-instance
998 (list
999 (concat
1000 (if (eq ?y (char-after (match-beginning 2)))
1001 "server disable "
1002 "server enable ")
1003 (buffer-substring (match-beginning 0)
1004 (match-end 1))
1005 "\n")
1006 '(lambda () nil)))
1007 )))
1008
1009 (defun gud-delete-bp-this-line ()
1010 (interactive)
1011 (save-excursion
1012 (beginning-of-line 1)
1013 (if (not (looking-at "\\([0-9]*\\)\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)"))
1014 (error "Not recognized as breakpoint line (demo foo).")
1015 (gdb-instance-enqueue-idle-input
1016 gdb-buffer-instance
1017 (list
1018 (concat
1019 "server delete "
1020 (buffer-substring (match-beginning 0)
1021 (match-end 1))
1022 "\n")
1023 '(lambda () nil)))
1024 )))
1025
1026
1027
1028 \f
1029 ;;
1030 ;; Frames buffers. These display a perpetually correct bactracktrace
1031 ;; (from the command `where').
1032 ;;
1033 ;; Alas, if your stack is deep, they are costly.
1034 ;;
1035
1036 (gdb-set-instance-buffer-rules 'gdb-stack-buffer
1037 'gdb-stack-buffer-name
1038 'gud-frames-mode)
1039
1040 (def-gdb-auto-updated-buffer gdb-stack-buffer
1041 gdb-invalidate-frames
1042 "server where\n"
1043 gdb-info-frames-handler)
1044
1045 (defun gdb-stack-buffer-name (instance)
1046 (save-excursion
1047 (set-buffer (process-buffer (gdb-instance-process instance)))
1048 (concat "*stack frames of "
1049 (gdb-instance-target-string instance) "*")))
1050
1051 (defun gud-display-stack-buffer (instance)
1052 (interactive (list (gdb-needed-default-instance)))
1053 (gud-display-buffer
1054 (gdb-get-create-instance-buffer instance
1055 'gdb-stack-buffer)))
1056
1057 (defun gud-frame-stack-buffer (instance)
1058 (interactive (list (gdb-needed-default-instance)))
1059 (gud-frame-buffer
1060 (gdb-get-create-instance-buffer instance
1061 'gdb-stack-buffer)))
1062
1063 (defvar gud-frames-mode-map nil)
1064 (setq gud-frames-mode-map (make-keymap))
1065 (suppress-keymap gud-frames-mode-map)
1066 (define-key gud-frames-mode-map [mouse-2]
1067 'gud-frames-select-by-mouse)
1068
1069 (defun gud-frames-mode ()
1070 "Major mode for gud frames.
1071
1072 \\{gud-frames-mode-map}"
1073 (setq major-mode 'gud-frames-mode)
1074 (setq mode-name "Frames")
1075 (setq buffer-read-only t)
1076 (use-local-map gud-frames-mode-map)
1077 (gdb-invalidate-frames gdb-buffer-instance))
1078
1079 (defun gud-get-frame-number ()
1080 (save-excursion
1081 (let* ((pos (re-search-backward "^#\\([0-9]*\\)" nil t))
1082 (n (or (and pos
1083 (string-to-int
1084 (buffer-substring (match-beginning 1)
1085 (match-end 1))))
1086 0)))
1087 n)))
1088
1089 (defun gud-frames-select-by-mouse (e)
1090 (interactive "e")
1091 (let (selection)
1092 (save-excursion
1093 (set-buffer (window-buffer (posn-window (event-end e))))
1094 (save-excursion
1095 (goto-char (posn-point (event-end e)))
1096 (setq selection (gud-get-frame-number))))
1097 (select-window (posn-window (event-end e)))
1098 (save-excursion
1099 (set-buffer (gdb-get-instance-buffer (gdb-needed-default-instance) 'gud))
1100 (gud-call "fr %p" selection)
1101 (gud-display-frame))))
1102
1103 \f
1104 ;;
1105 ;; Registers buffers
1106 ;;
1107
1108 (def-gdb-auto-updated-buffer gdb-registers-buffer
1109 gdb-invalidate-registers
1110 "server info registers\n"
1111 gdb-info-registers-handler)
1112
1113 (gdb-set-instance-buffer-rules 'gdb-registers-buffer
1114 'gdb-registers-buffer-name
1115 'gud-registers-mode)
1116
1117 (defvar gud-registers-mode-map nil)
1118 (setq gud-registers-mode-map (make-keymap))
1119 (suppress-keymap gud-registers-mode-map)
1120
1121 (defun gud-registers-mode ()
1122 "Major mode for gud registers.
1123
1124 \\{gud-registers-mode-map}"
1125 (setq major-mode 'gud-registers-mode)
1126 (setq mode-name "Registers")
1127 (setq buffer-read-only t)
1128 (use-local-map gud-registers-mode-map)
1129 (gdb-invalidate-registers gdb-buffer-instance))
1130
1131 (defun gdb-registers-buffer-name (instance)
1132 (save-excursion
1133 (set-buffer (process-buffer (gdb-instance-process instance)))
1134 (concat "*registers of " (gdb-instance-target-string instance) "*")))
1135
1136 (defun gud-display-registers-buffer (instance)
1137 (interactive (list (gdb-needed-default-instance)))
1138 (gud-display-buffer
1139 (gdb-get-create-instance-buffer instance
1140 'gdb-registers-buffer)))
1141
1142 (defun gud-frame-registers-buffer (instance)
1143 (interactive (list (gdb-needed-default-instance)))
1144 (gud-frame-buffer
1145 (gdb-get-create-instance-buffer instance
1146 'gdb-registers-buffer)))
1147
1148 \f
1149
1150 ;;;; Menu windows:
1151
1152
1153 ;; MENU-LIST is ((option option option...) (option option ...)...)
1154 ;;
1155 (defun gud-display-menu (menu-list)
1156 (setq fill-column (min 120 (- (window-width)
1157 (min 8 (window-width)))))
1158 (while menu-list
1159 (mapcar (function (lambda (x) (insert (symbol-name x) " "))) (car menu-list))
1160 (fill-paragraph nil)
1161 (insert "\n\n")
1162 (setq menu-list (cdr menu-list)))
1163 (goto-char (point-min))
1164 (while (re-search-forward "\\([^ \n]+\\)\\(\n\\| \\)" nil t)
1165 (put-text-property (match-beginning 1) (match-end 1)
1166 'mouse-face 'highlight))
1167 (goto-char (point-min)))
1168
1169 (defun gud-goto-menu (menu)
1170 (setq gud-menu-position menu)
1171 (let ((buffer-read-only nil))
1172 (delete-region (point-min) (point-max))
1173 (gud-display-menu menu)))
1174
1175 (defun gud-menu-pick (event)
1176 "Choose an item from a gdb command menu."
1177 (interactive "e")
1178 (let (choice)
1179 (save-excursion
1180 (set-buffer (window-buffer (posn-window (event-start event))))
1181 (goto-char (posn-point (event-start event)))
1182 (let (beg end)
1183 (skip-chars-forward "^ \t\n")
1184 (setq end (point))
1185 (skip-chars-backward "^ \t\n")
1186 (setq beg (point))
1187 (setq choice (buffer-substring beg end))
1188 (message choice)
1189 (gud-invoke-menu (intern choice))))))
1190
1191 (defun gud-invoke-menu (symbol)
1192 (let ((meaning (assoc symbol gud-menu-rules)))
1193 (cond
1194 ((and (consp meaning)
1195 (consp (car (cdr meaning))))
1196 (gud-goto-menu (car (cdr meaning))))
1197 (meaning (call-interactively (car (cdr meaning)))))))
1198
1199 \f
1200
1201 (gdb-set-instance-buffer-rules 'gdb-command-buffer
1202 'gdb-command-buffer-name
1203 'gud-command-mode)
1204
1205 (defvar gud-command-mode-map nil)
1206 (setq gud-command-mode-map (make-keymap))
1207 (suppress-keymap gud-command-mode-map)
1208 (define-key gud-command-mode-map [mouse-2] 'gud-menu-pick)
1209
1210 (defun gud-command-mode ()
1211 "Major mode for gud menu.
1212
1213 \\{gud-command-mode-map}" (interactive) (setq major-mode 'gud-command-mode)
1214 (setq mode-name "Menu") (setq buffer-read-only t) (use-local-map
1215 gud-command-mode-map) (make-variable-buffer-local 'gud-menu-position)
1216 (if (not gud-menu-position) (gud-goto-menu gud-running-menu)))
1217
1218 (defun gdb-command-buffer-name (instance)
1219 (save-excursion
1220 (set-buffer (process-buffer (gdb-instance-process instance)))
1221 (concat "*menu of " (gdb-instance-target-string instance) "*")))
1222
1223 (defun gud-display-command-buffer (instance)
1224 (interactive (list (gdb-needed-default-instance)))
1225 (gud-display-buffer
1226 (gdb-get-create-instance-buffer instance
1227 'gdb-command-buffer)
1228 6))
1229
1230 (defun gud-frame-command-buffer (instance)
1231 (interactive (list (gdb-needed-default-instance)))
1232 (gud-frame-buffer
1233 (gdb-get-create-instance-buffer instance
1234 'gdb-command-buffer)))
1235
1236 (defvar gud-selected-menu-titles ())
1237 (setq gud-selected-menu-titles
1238 '(RUNNING STACK DATA BREAKPOINTS FILES))
1239
1240 (setq gud-running-menu
1241 (list
1242 '(RUNNING stack breakpoints files)
1243 '(target run next step continue finish stepi kill help-running)))
1244
1245 (setq gud-stack-menu
1246 (list
1247 '(running STACK breakpoints files)
1248 '(up down frame backtrace return help-stack)))
1249
1250 (setq gud-data-menu
1251 (list
1252 '(running stack DATA breakpoints files)
1253 '(whatis ptype print set display undisplay disassemble help-data)))
1254
1255 (setq gud-breakpoints-menu
1256 (list
1257 '(running stack BREAKPOINTS files)
1258 '(awatch rwatch watch break delete enable disable condition ignore help-breakpoints)))
1259
1260 (setq gud-files-menu
1261 (list
1262 '(running stack breakpoints FILES)
1263 '(file core-file help-files)
1264 '(exec-file load symbol-file add-symbol-file sharedlibrary)))
1265
1266 (setq gud-menu-rules
1267 (list
1268 (list 'running gud-running-menu)
1269 (list 'RUNNING gud-running-menu)
1270 (list 'stack gud-stack-menu)
1271 (list 'STACK gud-stack-menu)
1272 (list 'data gud-data-menu)
1273 (list 'DATA gud-data-menu)
1274 (list 'breakpoints gud-breakpoints-menu)
1275 (list 'BREAKPOINTS gud-breakpoints-menu)
1276 (list 'files gud-files-menu)
1277 (list 'FILES gud-files-menu)
1278
1279 (list 'target 'gud-target)
1280 (list 'kill 'gud-kill)
1281 (list 'stepi 'gud-stepi)
1282 (list 'step 'gud-step)
1283 (list 'next 'gud-next)
1284 (list 'finish 'gud-finish)
1285 (list 'continue 'gud-cont)
1286 (list 'run 'gud-run)
1287
1288 (list 'backtrace 'gud-backtrace)
1289 (list 'frame 'gud-frame)
1290 (list 'down 'gud-down)
1291 (list 'up 'gud-up)
1292 (list 'return 'gud-return)
1293
1294 (list 'file 'gud-file)
1295 (list 'core-file 'gud-core-file)
1296 (list 'cd 'gud-cd)
1297
1298 (list 'exec-file 'gud-exec-file)
1299 (list 'load 'gud-load)
1300 (list 'symbol-file 'gud-symbol-file)
1301 (list 'add-symbol-file 'gud-add-symbol-file)
1302 (list 'sharedlibrary 'gud-sharedlibrary)
1303 ))
1304
1305
1306 \f
1307
1308 (defun gdb-call-showing-gud (instance command)
1309 (gud-display-gud-buffer instance)
1310 (comint-input-sender (gdb-instance-process instance) command))
1311
1312 (defvar gud-target-history ())
1313
1314 (defun gud-temp-buffer-show (buf)
1315 (let ((ow (selected-window)))
1316 (unwind-protect
1317 (progn
1318 (pop-to-buffer buf)
1319
1320 ;; This insertion works around a bug in emacs.
1321 ;; The bug is that all the empty space after a
1322 ;; highlighted word that terminates a buffer
1323 ;; gets highlighted. That's really ugly, so
1324 ;; make sure a highlighted word can't ever
1325 ;; terminate the buffer.
1326 (goto-char (point-max))
1327 (insert "\n")
1328 (goto-char (point-min))
1329
1330 (if (< (window-height) 10)
1331 (enlarge-window (- 10 (window-height)))))
1332 (select-window ow))))
1333
1334 (defun gud-target (instance command)
1335 (interactive
1336 (let* ((instance (gdb-needed-default-instance))
1337 (temp-buffer-show-function (function gud-temp-buffer-show))
1338 (target-name (completing-read (format "Target type: ")
1339 '(("remote")
1340 ("core")
1341 ("child")
1342 ("exec"))
1343 nil
1344 t
1345 nil
1346 'gud-target-history)))
1347 (list instance
1348 (cond
1349 ((equal target-name "child") "run")
1350
1351 ((equal target-name "core")
1352 (concat "target core "
1353 (read-file-name "core file: "
1354 nil
1355 "core"
1356 t)))
1357
1358 ((equal target-name "exec")
1359 (concat "target exec "
1360 (read-file-name "exec file: "
1361 nil
1362 "a.out"
1363 t)))
1364
1365 ((equal target-name "remote")
1366 (concat "target remote "
1367 (read-file-name "serial line for remote: "
1368 "/dev/"
1369 "ttya"
1370 t)))
1371
1372 (t "echo No such target command!")))))
1373
1374 (gud-display-gud-buffer instance)
1375 (apply comint-input-sender
1376 (list (gdb-instance-process instance) command)))
1377
1378 (defun gud-backtrace ()
1379 (interactive)
1380 (let ((instance (gdb-needed-default-instance)))
1381 (gud-display-gud-buffer instance)
1382 (apply comint-input-sender
1383 (list (gdb-instance-process instance)
1384 "backtrace"))))
1385
1386 (defun gud-frame ()
1387 (interactive)
1388 (let ((instance (gdb-needed-default-instance)))
1389 (apply comint-input-sender
1390 (list (gdb-instance-process instance)
1391 "frame"))))
1392
1393 (defun gud-return (instance command)
1394 (interactive
1395 (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
1396 (list (gdb-needed-default-instance)
1397 (concat "return " (read-string "Expression to return: ")))))
1398 (gud-display-gud-buffer instance)
1399 (apply comint-input-sender
1400 (list (gdb-instance-process instance) command)))
1401
1402
1403 (defun gud-file (instance command)
1404 (interactive
1405 (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
1406 (list (gdb-needed-default-instance)
1407 (concat "file " (read-file-name "Executable to debug: "
1408 nil
1409 "a.out"
1410 t)))))
1411 (gud-display-gud-buffer instance)
1412 (apply comint-input-sender
1413 (list (gdb-instance-process instance) command)))
1414
1415 (defun gud-core-file (instance command)
1416 (interactive
1417 (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
1418 (list (gdb-needed-default-instance)
1419 (concat "core " (read-file-name "Core file to debug: "
1420 nil
1421 "core-file"
1422 t)))))
1423 (gud-display-gud-buffer instance)
1424 (apply comint-input-sender
1425 (list (gdb-instance-process instance) command)))
1426
1427 (defun gud-cd (dir)
1428 (interactive "FChange GDB's default directory: ")
1429 (let ((instance (gdb-needed-default-instance)))
1430 (save-excursion
1431 (set-buffer (gdb-get-instance-buffer instance 'gud))
1432 (cd dir))
1433 (gud-display-gud-buffer instance)
1434 (apply comint-input-sender
1435 (list (gdb-instance-process instance)
1436 (concat "cd " dir)))))
1437
1438
1439 (defun gud-exec-file (instance command)
1440 (interactive
1441 (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
1442 (list (gdb-needed-default-instance)
1443 (concat "exec-file " (read-file-name "Init memory from executable: "
1444 nil
1445 "a.out"
1446 t)))))
1447 (gud-display-gud-buffer instance)
1448 (apply comint-input-sender
1449 (list (gdb-instance-process instance) command)))
1450
1451 (defun gud-load (instance command)
1452 (interactive
1453 (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
1454 (list (gdb-needed-default-instance)
1455 (concat "load " (read-file-name "Dynamicly load from file: "
1456 nil
1457 "a.out"
1458 t)))))
1459 (gud-display-gud-buffer instance)
1460 (apply comint-input-sender
1461 (list (gdb-instance-process instance) command)))
1462
1463 (defun gud-symbol-file (instance command)
1464 (interactive
1465 (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
1466 (list (gdb-needed-default-instance)
1467 (concat "symbol-file " (read-file-name "Read symbol table from file: "
1468 nil
1469 "a.out"
1470 t)))))
1471 (gud-display-gud-buffer instance)
1472 (apply comint-input-sender
1473 (list (gdb-instance-process instance) command)))
1474
1475
1476 (defun gud-add-symbol-file (instance command)
1477 (interactive
1478 (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
1479 (list (gdb-needed-default-instance)
1480 (concat "add-symbol-file "
1481 (read-file-name "Add symbols from file: "
1482 nil
1483 "a.out"
1484 t)))))
1485 (gud-display-gud-buffer instance)
1486 (apply comint-input-sender
1487 (list (gdb-instance-process instance) command)))
1488
1489
1490 (defun gud-sharedlibrary (instance command)
1491 (interactive
1492 (let ((temp-buffer-show-function (function gud-temp-buffer-show)))
1493 (list (gdb-needed-default-instance)
1494 (concat "sharedlibrary "
1495 (read-string "Load symbols for files matching regexp: ")))))
1496 (gud-display-gud-buffer instance)
1497 (apply comint-input-sender
1498 (list (gdb-instance-process instance) command)))
1499
1500
1501
1502 \f
1503
1504 ;;;; Window management
1505
1506
1507 ;;; FIXME: This should only return true for buffers in the current instance
1508 (defun gud-protected-buffer-p (buffer)
1509 "Is BUFFER a buffer which we want to leave displayed?"
1510 (save-excursion
1511 (set-buffer buffer)
1512 (or gdb-buffer-type
1513 overlay-arrow-position)))
1514
1515 ;;; The way we abuse the dedicated-p flag is pretty gross, but seems
1516 ;;; to do the right thing. Seeing as there is no way for Lisp code to
1517 ;;; get at the use_time field of a window, I'm not sure there exists a
1518 ;;; more elegant solution without writing C code.
1519
1520 (defun gud-display-buffer (buf &optional size)
1521 (let ((must-split nil)
1522 (answer nil))
1523 (unwind-protect
1524 (progn
1525 (walk-windows
1526 '(lambda (win)
1527 (if (gud-protected-buffer-p (window-buffer win))
1528 (set-window-dedicated-p win t))))
1529 (setq answer (get-buffer-window buf))
1530 (if (not answer)
1531 (let ((window (get-lru-window)))
1532 (if window
1533 (progn
1534 (set-window-buffer window buf)
1535 (setq answer window))
1536 (setq must-split t)))))
1537 (walk-windows
1538 '(lambda (win)
1539 (if (gud-protected-buffer-p (window-buffer win))
1540 (set-window-dedicated-p win nil)))))
1541 (if must-split
1542 (let* ((largest (get-largest-window))
1543 (cur-size (window-height largest))
1544 (new-size (and size (< size cur-size) (- cur-size size))))
1545 (setq answer (split-window largest new-size))
1546 (set-window-buffer answer buf)))
1547 answer))
1548
1549 (defun existing-source-window (buffer)
1550 (catch 'found
1551 (save-excursion
1552 (walk-windows
1553 (function
1554 (lambda (win)
1555 (if (and overlay-arrow-position
1556 (eq (window-buffer win)
1557 (marker-buffer overlay-arrow-position)))
1558 (progn
1559 (set-window-buffer win buffer)
1560 (throw 'found win))))))
1561 nil)))
1562
1563 (defun gud-display-source-buffer (buffer)
1564 (or (existing-source-window buffer)
1565 (gud-display-buffer buffer)))
1566
1567 (defun gud-frame-buffer (buf)
1568 (save-excursion
1569 (set-buffer buf)
1570 (make-frame)))
1571
1572 \f
1573
1574 ;;; Shared keymap initialization:
1575
1576 (defun make-windows-menu (map)
1577 (define-key map [menu-bar displays]
1578 (cons "GDB-Windows" (make-sparse-keymap "GDB-Windows")))
1579 (define-key map [menu-bar displays gdb]
1580 '("Gdb" . gud-display-gud-buffer))
1581 (define-key map [menu-bar displays registers]
1582 '("Registers" . gud-display-registers-buffer))
1583 (define-key map [menu-bar displays frames]
1584 '("Stack" . gud-display-stack-buffer))
1585 (define-key map [menu-bar displays breakpoints]
1586 '("Breakpoints" . gud-display-breakpoints-buffer))
1587 (define-key map [menu-bar displays commands]
1588 '("Commands" . gud-display-command-buffer)))
1589
1590 (defun gud-display-gud-buffer (instance)
1591 (interactive (list (gdb-needed-default-instance)))
1592 (gud-display-buffer
1593 (gdb-get-create-instance-buffer instance 'gud)))
1594
1595 (make-windows-menu gud-breakpoints-mode-map)
1596 (make-windows-menu gud-frames-mode-map)
1597 (make-windows-menu gud-registers-mode-map)
1598
1599
1600
1601 (defun make-frames-menu (map)
1602 (define-key map [menu-bar frames]
1603 (cons "GDB-Frames" (make-sparse-keymap "GDB-Frames")))
1604 (define-key map [menu-bar frames gdb]
1605 '("Gdb" . gud-frame-gud-buffer))
1606 (define-key map [menu-bar frames registers]
1607 '("Registers" . gud-frame-registers-buffer))
1608 (define-key map [menu-bar frames frames]
1609 '("Stack" . gud-frame-stack-buffer))
1610 (define-key map [menu-bar frames breakpoints]
1611 '("Breakpoints" . gud-frame-breakpoints-buffer))
1612 (define-key map [menu-bar displays commands]
1613 '("Commands" . gud-display-command-buffer)))
1614
1615 (defun gud-frame-gud-buffer (instance)
1616 (interactive (list (gdb-needed-default-instance)))
1617 (gud-frame-buffer
1618 (gdb-get-create-instance-buffer instance 'gud)))
1619
1620 (make-frames-menu gud-breakpoints-mode-map)
1621 (make-frames-menu gud-frames-mode-map)
1622 (make-frames-menu gud-registers-mode-map)
1623
1624 \f
1625 (defun gud-gdb-find-file (f)
1626 (find-file-noselect f))
1627
1628 ;;;###autoload
1629 (defun gdb (command-line)
1630 "Run gdb on program FILE in buffer *gud-FILE*.
1631 The directory containing FILE becomes the initial working directory
1632 and source-file directory for your debugger."
1633 (interactive
1634 (list (read-from-minibuffer "Run gdb (like this): "
1635 (if (consp gud-gdb-history)
1636 (car gud-gdb-history)
1637 "gdb ")
1638 nil nil
1639 '(gud-gdb-history . 1))))
1640 (gud-overload-functions
1641 '((gud-massage-args . gud-gdb-massage-args)
1642 (gud-marker-filter . gud-gdb-marker-filter)
1643 (gud-find-file . gud-gdb-find-file)
1644 ))
1645
1646 (let* ((words (gud-chop-words command-line))
1647 (program (car words))
1648 (file-word (let ((w (cdr words)))
1649 (while (and w (= ?- (aref (car w) 0)))
1650 (setq w (cdr w)))
1651 (car w)))
1652 (args (delq file-word (cdr words)))
1653 (file (expand-file-name file-word))
1654 (filepart (file-name-nondirectory file))
1655 (buffer-name (concat "*gud-" filepart "*")))
1656 (setq gdb-first-time (not (get-buffer-process buffer-name))))
1657
1658 (gud-common-init command-line)
1659
1660 (gud-def gud-break "break %f:%l" "\C-b" "Set breakpoint at current line.")
1661 (gud-def gud-tbreak "tbreak %f:%l" "\C-t" "Set breakpoint at current line.")
1662 (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line")
1663 (gud-def gud-kill "kill" nil "Kill the program.")
1664 (gud-def gud-run "run" nil "Run the program.")
1665 (gud-def gud-stepi "stepi %p" "\C-i" "Step one instruction with display.")
1666 (gud-def gud-step "step %p" "\C-s" "Step one source line with display.")
1667 (gud-def gud-next "next %p" "\C-n" "Step one line (skip functions).")
1668 (gud-def gud-finish "finish" "\C-f" "Finish executing current function.")
1669 (gud-def gud-cont "cont" "\C-r" "Continue with display.")
1670 (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).")
1671 (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).")
1672 (gud-def gud-print "print %e" "\C-p" "Evaluate C expression at point.")
1673
1674 (setq comint-prompt-regexp "^(.*gdb[+]?) *")
1675 (setq comint-input-sender 'gdb-send)
1676 (run-hooks 'gdb-mode-hook)
1677 (let ((instance
1678 (make-gdb-instance (get-buffer-process (current-buffer)))
1679 ))
1680 (if gdb-first-time (gdb-clear-inferior-io instance)))
1681 )
1682
1683 \f
1684 ;; ======================================================================
1685 ;; sdb functions
1686
1687 ;;; History of argument lists passed to sdb.
1688 (defvar gud-sdb-history nil)
1689
1690 (defvar gud-sdb-needs-tags (not (file-exists-p "/var"))
1691 "If nil, we're on a System V Release 4 and don't need the tags hack.")
1692
1693 (defvar gud-sdb-lastfile nil)
1694
1695 (defun gud-sdb-massage-args (file args)
1696 (cons file args))
1697
1698 (defun gud-sdb-marker-filter (string)
1699 (cond
1700 ;; System V Release 3.2 uses this format
1701 ((string-match "\\(^0x\\w* in \\|^\\|\n\\)\\([^:\n]*\\):\\([0-9]*\\):.*\n"
1702 string)
1703 (setq gud-last-frame
1704 (cons
1705 (substring string (match-beginning 2) (match-end 2))
1706 (string-to-int
1707 (substring string (match-beginning 3) (match-end 3))))))
1708 ;; System V Release 4.0
1709 ((string-match "^\\(BREAKPOINT\\|STEPPED\\) process [0-9]+ function [^ ]+ in \\(.+\\)\n"
1710 string)
1711 (setq gud-sdb-lastfile
1712 (substring string (match-beginning 2) (match-end 2))))
1713 ((and gud-sdb-lastfile (string-match "^\\([0-9]+\\):" string))
1714 (setq gud-last-frame
1715 (cons
1716 gud-sdb-lastfile
1717 (string-to-int
1718 (substring string (match-beginning 1) (match-end 1))))))
1719 (t
1720 (setq gud-sdb-lastfile nil)))
1721 string)
1722
1723 (defun gud-sdb-find-file (f)
1724 (if gud-sdb-needs-tags
1725 (find-tag-noselect f)
1726 (find-file-noselect f)))
1727
1728 ;;;###autoload
1729 (defun sdb (command-line)
1730 "Run sdb on program FILE in buffer *gud-FILE*.
1731 The directory containing FILE becomes the initial working directory
1732 and source-file directory for your debugger."
1733 (interactive
1734 (list (read-from-minibuffer "Run sdb (like this): "
1735 (if (consp gud-sdb-history)
1736 (car gud-sdb-history)
1737 "sdb ")
1738 nil nil
1739 '(gud-sdb-history . 1))))
1740 (if (and gud-sdb-needs-tags
1741 (not (and (boundp 'tags-file-name) (file-exists-p tags-file-name))))
1742 (error "The sdb support requires a valid tags table to work."))
1743 (gud-overload-functions '((gud-massage-args . gud-sdb-massage-args)
1744 (gud-marker-filter . gud-sdb-marker-filter)
1745 (gud-find-file . gud-sdb-find-file)
1746 ))
1747
1748 (gud-common-init command-line)
1749
1750 (gud-def gud-break "%l b" "\C-b" "Set breakpoint at current line.")
1751 (gud-def gud-tbreak "%l c" "\C-t" "Set temporary breakpoint at current line.")
1752 (gud-def gud-remove "%l d" "\C-d" "Remove breakpoint at current line")
1753 (gud-def gud-step "s %p" "\C-s" "Step one source line with display.")
1754 (gud-def gud-stepi "i %p" "\C-i" "Step one instruction with display.")
1755 (gud-def gud-next "S %p" "\C-n" "Step one line (skip functions).")
1756 (gud-def gud-cont "c" "\C-r" "Continue with display.")
1757 (gud-def gud-print "%e/" "\C-p" "Evaluate C expression at point.")
1758
1759 (setq comint-prompt-regexp "\\(^\\|\n\\)\\*")
1760 (run-hooks 'sdb-mode-hook)
1761 )
1762 \f
1763 ;; ======================================================================
1764 ;; dbx functions
1765
1766 ;;; History of argument lists passed to dbx.
1767 (defvar gud-dbx-history nil)
1768
1769 (defun gud-dbx-massage-args (file args)
1770 (cons file args))
1771
1772 (defun gud-dbx-marker-filter (string)
1773 (if (or (string-match
1774 "stopped in .* at line \\([0-9]*\\) in file \"\\([^\"]*\\)\""
1775 string)
1776 (string-match
1777 "signal .* in .* at line \\([0-9]*\\) in file \"\\([^\"]*\\)\""
1778 string))
1779 (setq gud-last-frame
1780 (cons
1781 (substring string (match-beginning 2) (match-end 2))
1782 (string-to-int
1783 (substring string (match-beginning 1) (match-end 1))))))
1784 string)
1785
1786 (defun gud-dbx-find-file (f)
1787 (find-file-noselect f))
1788
1789 ;;;###autoload
1790 (defun dbx (command-line)
1791 "Run dbx on program FILE in buffer *gud-FILE*.
1792 The directory containing FILE becomes the initial working directory
1793 and source-file directory for your debugger."
1794 (interactive
1795 (list (read-from-minibuffer "Run dbx (like this): "
1796 (if (consp gud-dbx-history)
1797 (car gud-dbx-history)
1798 "dbx ")
1799 nil nil
1800 '(gud-dbx-history . 1))))
1801 (gud-overload-functions '((gud-massage-args . gud-dbx-massage-args)
1802 (gud-marker-filter . gud-dbx-marker-filter)
1803 (gud-find-file . gud-dbx-find-file)
1804 ))
1805
1806 (gud-common-init command-line)
1807
1808 (gud-def gud-break "file \"%d%f\"\nstop at %l"
1809 "\C-b" "Set breakpoint at current line.")
1810 ;; (gud-def gud-break "stop at \"%f\":%l"
1811 ;; "\C-b" "Set breakpoint at current line.")
1812 (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line")
1813 (gud-def gud-step "step %p" "\C-s" "Step one line with display.")
1814 (gud-def gud-stepi "stepi %p" "\C-i" "Step one instruction with display.")
1815 (gud-def gud-next "next %p" "\C-n" "Step one line (skip functions).")
1816 (gud-def gud-cont "cont" "\C-r" "Continue with display.")
1817 (gud-def gud-up "up %p" "<" "Up (numeric arg) stack frames.")
1818 (gud-def gud-down "down %p" ">" "Down (numeric arg) stack frames.")
1819 (gud-def gud-print "print %e" "\C-p" "Evaluate C expression at point.")
1820
1821 (setq comint-prompt-regexp "^[^)]*dbx) *")
1822 (run-hooks 'dbx-mode-hook)
1823 )
1824 \f
1825 ;; ======================================================================
1826 ;; xdb (HP PARISC debugger) functions
1827
1828 ;;; History of argument lists passed to xdb.
1829 (defvar gud-xdb-history nil)
1830
1831 (defvar gud-xdb-directories nil
1832 "*A list of directories that xdb should search for source code.
1833 If nil, only source files in the program directory
1834 will be known to xdb.
1835
1836 The file names should be absolute, or relative to the directory
1837 containing the executable being debugged.")
1838
1839 (defun gud-xdb-massage-args (file args)
1840 (nconc (let ((directories gud-xdb-directories)
1841 (result nil))
1842 (while directories
1843 (setq result (cons (car directories) (cons "-d" result)))
1844 (setq directories (cdr directories)))
1845 (nreverse (cons file result)))
1846 args))
1847
1848 (defun gud-xdb-file-name (f)
1849 "Transform a relative pathname to a full pathname in xdb mode"
1850 (let ((result nil))
1851 (if (file-exists-p f)
1852 (setq result (expand-file-name f))
1853 (let ((directories gud-xdb-directories))
1854 (while directories
1855 (let ((path (concat (car directories) "/" f)))
1856 (if (file-exists-p path)
1857 (setq result (expand-file-name path)
1858 directories nil)))
1859 (setq directories (cdr directories)))))
1860 result))
1861
1862 ;; xdb does not print the lines all at once, so we have to accumulate them
1863 (defvar gud-xdb-accumulation "")
1864
1865 (defun gud-xdb-marker-filter (string)
1866 (let (result)
1867 (if (or (string-match comint-prompt-regexp string)
1868 (string-match ".*\012" string))
1869 (setq result (concat gud-xdb-accumulation string)
1870 gud-xdb-accumulation "")
1871 (setq gud-xdb-accumulation (concat gud-xdb-accumulation string)))
1872 (if result
1873 (if (or (string-match "\\([^\n \t:]+\\): [^:]+: \\([0-9]+\\):" result)
1874 (string-match "[^: \t]+:[ \t]+\\([^:]+\\): [^:]+: \\([0-9]+\\):"
1875 result))
1876 (let ((line (string-to-int
1877 (substring result (match-beginning 2) (match-end 2))))
1878 (file (gud-xdb-file-name
1879 (substring result (match-beginning 1) (match-end 1)))))
1880 (if file
1881 (setq gud-last-frame (cons file line))))))
1882 (or result "")))
1883
1884 (defun gud-xdb-find-file (f)
1885 (let ((realf (gud-xdb-file-name f)))
1886 (if realf (find-file-noselect realf))))
1887
1888 ;;;###autoload
1889 (defun xdb (command-line)
1890 "Run xdb on program FILE in buffer *gud-FILE*.
1891 The directory containing FILE becomes the initial working directory
1892 and source-file directory for your debugger.
1893
1894 You can set the variable 'gud-xdb-directories' to a list of program source
1895 directories if your program contains sources from more than one directory."
1896 (interactive
1897 (list (read-from-minibuffer "Run xdb (like this): "
1898 (if (consp gud-xdb-history)
1899 (car gud-xdb-history)
1900 "xdb ")
1901 nil nil
1902 '(gud-xdb-history . 1))))
1903 (gud-overload-functions '((gud-massage-args . gud-xdb-massage-args)
1904 (gud-marker-filter . gud-xdb-marker-filter)
1905 (gud-find-file . gud-xdb-find-file)))
1906
1907 (gud-common-init command-line)
1908
1909 (gud-def gud-break "b %f:%l" "\C-b" "Set breakpoint at current line.")
1910 (gud-def gud-tbreak "b %f:%l\\t" "\C-t"
1911 "Set temporary breakpoint at current line.")
1912 (gud-def gud-remove "db" "\C-d" "Remove breakpoint at current line")
1913 (gud-def gud-step "s %p" "\C-s" "Step one line with display.")
1914 (gud-def gud-next "S %p" "\C-n" "Step one line (skip functions).")
1915 (gud-def gud-cont "c" "\C-r" "Continue with display.")
1916 (gud-def gud-up "up %p" "<" "Up (numeric arg) stack frames.")
1917 (gud-def gud-down "down %p" ">" "Down (numeric arg) stack frames.")
1918 (gud-def gud-finish "bu\\t" "\C-f" "Finish executing current function.")
1919 (gud-def gud-print "p %e" "\C-p" "Evaluate C expression at point.")
1920
1921 (setq comint-prompt-regexp "^>")
1922 (make-local-variable 'gud-xdb-accumulation)
1923 (setq gud-xdb-accumulation "")
1924 (run-hooks 'xdb-mode-hook))
1925 \f
1926 ;; ======================================================================
1927 ;; perldb functions
1928
1929 ;;; History of argument lists passed to perldb.
1930 (defvar gud-perldb-history nil)
1931
1932 (defun gud-perldb-massage-args (file args)
1933 (cons "-d" (cons file (cons "-emacs" args))))
1934
1935 ;; There's no guarantee that Emacs will hand the filter the entire
1936 ;; marker at once; it could be broken up across several strings. We
1937 ;; might even receive a big chunk with several markers in it. If we
1938 ;; receive a chunk of text which looks like it might contain the
1939 ;; beginning of a marker, we save it here between calls to the
1940 ;; filter.
1941 (defvar gud-perldb-marker-acc "")
1942
1943 (defun gud-perldb-marker-filter (string)
1944 (save-match-data
1945 (setq gud-perldb-marker-acc (concat gud-perldb-marker-acc string))
1946 (let ((output ""))
1947
1948 ;; Process all the complete markers in this chunk.
1949 (while (string-match "^\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n"
1950 gud-perldb-marker-acc)
1951 (setq
1952
1953 ;; Extract the frame position from the marker.
1954 gud-last-frame
1955 (cons (substring gud-perldb-marker-acc (match-beginning 1) (match-end 1))
1956 (string-to-int (substring gud-perldb-marker-acc
1957 (match-beginning 2)
1958 (match-end 2))))
1959
1960 ;; Append any text before the marker to the output we're going
1961 ;; to return - we don't include the marker in this text.
1962 output (concat output
1963 (substring gud-perldb-marker-acc 0 (match-beginning 0)))
1964
1965 ;; Set the accumulator to the remaining text.
1966 gud-perldb-marker-acc (substring gud-perldb-marker-acc (match-end 0))))
1967
1968 ;; Does the remaining text look like it might end with the
1969 ;; beginning of another marker? If it does, then keep it in
1970 ;; gud-perldb-marker-acc until we receive the rest of it. Since we
1971 ;; know the full marker regexp above failed, it's pretty simple to
1972 ;; test for marker starts.
1973 (if (string-match "^\032.*\\'" gud-perldb-marker-acc)
1974 (progn
1975 ;; Everything before the potential marker start can be output.
1976 (setq output (concat output (substring gud-perldb-marker-acc
1977 0 (match-beginning 0))))
1978
1979 ;; Everything after, we save, to combine with later input.
1980 (setq gud-perldb-marker-acc
1981 (substring gud-perldb-marker-acc (match-beginning 0))))
1982
1983 (setq output (concat output gud-perldb-marker-acc)
1984 gud-perldb-marker-acc ""))
1985
1986 output)))
1987
1988 (defun gud-perldb-find-file (f)
1989 (find-file-noselect f))
1990
1991 ;;;###autoload
1992 (defun perldb (command-line)
1993 "Run perldb on program FILE in buffer *gud-FILE*.
1994 The directory containing FILE becomes the initial working directory
1995 and source-file directory for your debugger."
1996 (interactive
1997 (list (read-from-minibuffer "Run perldb (like this): "
1998 (if (consp gud-perldb-history)
1999 (car gud-perldb-history)
2000 "perl ")
2001 nil nil
2002 '(gud-perldb-history . 1))))
2003 (gud-overload-functions '((gud-massage-args . gud-perldb-massage-args)
2004 (gud-marker-filter . gud-perldb-marker-filter)
2005 (gud-find-file . gud-perldb-find-file)
2006 ))
2007
2008 (gud-common-init command-line)
2009
2010 (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.")
2011 (gud-def gud-remove "d %l" "\C-d" "Remove breakpoint at current line")
2012 (gud-def gud-step "s" "\C-s" "Step one source line with display.")
2013 (gud-def gud-next "n" "\C-n" "Step one line (skip functions).")
2014 (gud-def gud-cont "c" "\C-r" "Continue with display.")
2015 ; (gud-def gud-finish "finish" "\C-f" "Finish executing current function.")
2016 ; (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).")
2017 ; (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).")
2018 (gud-def gud-print "%e" "\C-p" "Evaluate perl expression at point.")
2019
2020 (setq comint-prompt-regexp "^ DB<[0-9]+> ")
2021 (run-hooks 'perldb-mode-hook)
2022 )
2023
2024 ;;
2025 ;; End of debugger-specific information
2026 ;;
2027
2028 \f
2029 ;;; When we send a command to the debugger via gud-call, it's annoying
2030 ;;; to see the command and the new prompt inserted into the debugger's
2031 ;;; buffer; we have other ways of knowing the command has completed.
2032 ;;;
2033 ;;; If the buffer looks like this:
2034 ;;; --------------------
2035 ;;; (gdb) set args foo bar
2036 ;;; (gdb) -!-
2037 ;;; --------------------
2038 ;;; (the -!- marks the location of point), and we type `C-x SPC' in a
2039 ;;; source file to set a breakpoint, we want the buffer to end up like
2040 ;;; this:
2041 ;;; --------------------
2042 ;;; (gdb) set args foo bar
2043 ;;; Breakpoint 1 at 0x92: file make-docfile.c, line 49.
2044 ;;; (gdb) -!-
2045 ;;; --------------------
2046 ;;; Essentially, the old prompt is deleted, and the command's output
2047 ;;; and the new prompt take its place.
2048 ;;;
2049 ;;; Not echoing the command is easy enough; you send it directly using
2050 ;;; comint-input-sender, and it never enters the buffer. However,
2051 ;;; getting rid of the old prompt is trickier; you don't want to do it
2052 ;;; when you send the command, since that will result in an annoying
2053 ;;; flicker as the prompt is deleted, redisplay occurs while Emacs
2054 ;;; waits for a response from the debugger, and the new prompt is
2055 ;;; inserted. Instead, we'll wait until we actually get some output
2056 ;;; from the subprocess before we delete the prompt. If the command
2057 ;;; produced no output other than a new prompt, that prompt will most
2058 ;;; likely be in the first chunk of output received, so we will delete
2059 ;;; the prompt and then replace it with an identical one. If the
2060 ;;; command produces output, the prompt is moving anyway, so the
2061 ;;; flicker won't be annoying.
2062 ;;;
2063 ;;; So - when we want to delete the prompt upon receipt of the next
2064 ;;; chunk of debugger output, we position gud-delete-prompt-marker at
2065 ;;; the start of the prompt; the process filter will notice this, and
2066 ;;; delete all text between it and the process output marker. If
2067 ;;; gud-delete-prompt-marker points nowhere, we leave the current
2068 ;;; prompt alone.
2069 (defvar gud-delete-prompt-marker nil)
2070
2071 \f
2072 (defvar gdbish-comint-mode-map (copy-keymap comint-mode-map))
2073 (define-key gdbish-comint-mode-map "\C-c\M-\C-r" 'gud-display-registers-buffer)
2074 (define-key gdbish-comint-mode-map "\C-c\M-\C-f" 'gud-display-stack-buffer)
2075 (define-key gdbish-comint-mode-map "\C-c\M-\C-b" 'gud-display-breakpoints-buffer)
2076
2077 (make-windows-menu gdbish-comint-mode-map)
2078 (make-frames-menu gdbish-comint-mode-map)
2079
2080 (defun gud-mode ()
2081 "Major mode for interacting with an inferior debugger process.
2082
2083 You start it up with one of the commands M-x gdb, M-x sdb, M-x dbx,
2084 or M-x xdb. Each entry point finishes by executing a hook; `gdb-mode-hook',
2085 `sdb-mode-hook', `dbx-mode-hook' or `xdb-mode-hook' respectively.
2086
2087 After startup, the following commands are available in both the GUD
2088 interaction buffer and any source buffer GUD visits due to a breakpoint stop
2089 or step operation:
2090
2091 \\[gud-break] sets a breakpoint at the current file and line. In the
2092 GUD buffer, the current file and line are those of the last breakpoint or
2093 step. In a source buffer, they are the buffer's file and current line.
2094
2095 \\[gud-remove] removes breakpoints on the current file and line.
2096
2097 \\[gud-refresh] displays in the source window the last line referred to
2098 in the gud buffer.
2099
2100 \\[gud-step], \\[gud-next], and \\[gud-stepi] do a step-one-line,
2101 step-one-line (not entering function calls), and step-one-instruction
2102 and then update the source window with the current file and position.
2103 \\[gud-cont] continues execution.
2104
2105 \\[gud-print] tries to find the largest C lvalue or function-call expression
2106 around point, and sends it to the debugger for value display.
2107
2108 The above commands are common to all supported debuggers except xdb which
2109 does not support stepping instructions.
2110
2111 Under gdb, sdb and xdb, \\[gud-tbreak] behaves exactly like \\[gud-break],
2112 except that the breakpoint is temporary; that is, it is removed when
2113 execution stops on it.
2114
2115 Under gdb, dbx, and xdb, \\[gud-up] pops up through an enclosing stack
2116 frame. \\[gud-down] drops back down through one.
2117
2118 If you are using gdb or xdb, \\[gud-finish] runs execution to the return from
2119 the current function and stops.
2120
2121 All the keystrokes above are accessible in the GUD buffer
2122 with the prefix C-c, and in all buffers through the prefix C-x C-a.
2123
2124 All pre-defined functions for which the concept make sense repeat
2125 themselves the appropriate number of times if you give a prefix
2126 argument.
2127
2128 You may use the `gud-def' macro in the initialization hook to define other
2129 commands.
2130
2131 Other commands for interacting with the debugger process are inherited from
2132 comint mode, which see."
2133 (interactive)
2134 (comint-mode)
2135 (setq major-mode 'gud-mode)
2136 (setq mode-name "Debugger")
2137 (setq mode-line-process '(": %s"))
2138 (use-local-map (copy-keymap gdbish-comint-mode-map))
2139 (setq gud-last-frame nil)
2140 (make-local-variable 'comint-prompt-regexp)
2141 (make-local-variable 'gud-delete-prompt-marker)
2142 (setq gud-delete-prompt-marker (make-marker))
2143 (run-hooks 'gud-mode-hook)
2144 )
2145
2146 (defvar gud-comint-buffer nil)
2147
2148 ;; Chop STRING into words separated by SPC or TAB and return a list of them.
2149 (defun gud-chop-words (string)
2150 (let ((i 0) (beg 0)
2151 (len (length string))
2152 (words nil))
2153 (while (< i len)
2154 (if (memq (aref string i) '(?\t ? ))
2155 (progn
2156 (setq words (cons (substring string beg i) words)
2157 beg (1+ i))
2158 (while (and (< beg len) (memq (aref string beg) '(?\t ? )))
2159 (setq beg (1+ beg)))
2160 (setq i (1+ beg)))
2161 (setq i (1+ i))))
2162 (if (< beg len)
2163 (setq words (cons (substring string beg) words)))
2164 (nreverse words)))
2165
2166 (defvar gud-target-name "--unknown--"
2167 "The apparent name of the program being debugged in a gud buffer.
2168 For sure this the root string used in smashing together the gud
2169 buffer's name, even if that doesn't happen to be the name of a
2170 program.")
2171
2172 ;; Perform initializations common to all debuggers.
2173 (defun gud-common-init (command-line)
2174 (let* ((words (gud-chop-words command-line))
2175 (program (car words))
2176 (file-word (let ((w (cdr words)))
2177 (while (and w (= ?- (aref (car w) 0)))
2178 (setq w (cdr w)))
2179 (car w)))
2180 (args (delq file-word (cdr words)))
2181 (file (expand-file-name file-word))
2182 (filepart (file-name-nondirectory file))
2183 (buffer-name (concat "*gud-" filepart "*")))
2184 (switch-to-buffer buffer-name)
2185 (setq default-directory (file-name-directory file))
2186 (or (bolp) (newline))
2187 (insert "Current directory is " default-directory "\n")
2188 (let ((old-instance gdb-buffer-instance))
2189 (apply 'make-comint (concat "gud-" filepart) program nil
2190 (gud-massage-args file args))
2191 (gud-mode)
2192 (make-variable-buffer-local 'old-gdb-buffer-instance)
2193 (setq old-gdb-buffer-instance old-instance))
2194 (make-variable-buffer-local 'gud-target-name)
2195 (setq gud-target-name filepart))
2196 (set-process-filter (get-buffer-process (current-buffer)) 'gud-filter)
2197 (set-process-sentinel (get-buffer-process (current-buffer)) 'gud-sentinel)
2198 (gud-set-buffer)
2199 )
2200
2201 (defun gud-set-buffer ()
2202 (cond ((eq major-mode 'gud-mode)
2203 (setq gud-comint-buffer (current-buffer)))))
2204
2205 ;; These functions are responsible for inserting output from your debugger
2206 ;; into the buffer. The hard work is done by the method that is
2207 ;; the value of gud-marker-filter.
2208
2209 (defun gud-filter (proc string)
2210 ;; Here's where the actual buffer insertion is done
2211 (let ((inhibit-quit t))
2212 (save-excursion
2213 (set-buffer (process-buffer proc))
2214 (let (moving output-after-point)
2215 (save-excursion
2216 (goto-char (process-mark proc))
2217 ;; If we have been so requested, delete the debugger prompt.
2218 (if (marker-buffer gud-delete-prompt-marker)
2219 (progn
2220 (delete-region (point) gud-delete-prompt-marker)
2221 (set-marker gud-delete-prompt-marker nil)))
2222 (insert-before-markers (gud-marker-filter string))
2223 (setq moving (= (point) (process-mark proc)))
2224 (setq output-after-point (< (point) (process-mark proc)))
2225 ;; Check for a filename-and-line number.
2226 ;; Don't display the specified file
2227 ;; unless (1) point is at or after the position where output appears
2228 ;; and (2) this buffer is on the screen.
2229 (if (and gud-last-frame
2230 (not output-after-point)
2231 (get-buffer-window (current-buffer)))
2232 (gud-display-frame)))
2233 (if moving (goto-char (process-mark proc)))))))
2234
2235 (defun gud-sentinel (proc msg)
2236 (cond ((null (buffer-name (process-buffer proc)))
2237 ;; buffer killed
2238 ;; Stop displaying an arrow in a source file.
2239 (setq overlay-arrow-position nil)
2240 (set-process-buffer proc nil))
2241 ((memq (process-status proc) '(signal exit))
2242 ;; Stop displaying an arrow in a source file.
2243 (setq overlay-arrow-position nil)
2244 ;; Fix the mode line.
2245 (setq mode-line-process
2246 (concat ": "
2247 (symbol-name (process-status proc))))
2248 (let* ((obuf (current-buffer)))
2249 ;; save-excursion isn't the right thing if
2250 ;; process-buffer is current-buffer
2251 (unwind-protect
2252 (progn
2253 ;; Write something in *compilation* and hack its mode line,
2254 (set-buffer (process-buffer proc))
2255 ;; Force mode line redisplay soon
2256 (set-buffer-modified-p (buffer-modified-p))
2257 (if (eobp)
2258 (insert ?\n mode-name " " msg)
2259 (save-excursion
2260 (goto-char (point-max))
2261 (insert ?\n mode-name " " msg)))
2262 ;; If buffer and mode line will show that the process
2263 ;; is dead, we can delete it now. Otherwise it
2264 ;; will stay around until M-x list-processes.
2265 (delete-process proc))
2266 ;; Restore old buffer, but don't restore old point
2267 ;; if obuf is the gud buffer.
2268 (set-buffer obuf))))))
2269
2270 (defun gud-display-frame ()
2271 "Find and obey the last filename-and-line marker from the debugger.
2272 Obeying it means displaying in another window the specified file and line."
2273 (interactive)
2274 (if gud-last-frame
2275 (progn
2276 ; (gud-set-buffer)
2277 (gud-display-line (car gud-last-frame) (cdr gud-last-frame))
2278 (setq gud-last-last-frame gud-last-frame
2279 gud-last-frame nil))))
2280
2281 ;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
2282 ;; and that its line LINE is visible.
2283 ;; Put the overlay-arrow on the line LINE in that buffer.
2284 ;; Most of the trickiness in here comes from wanting to preserve the current
2285 ;; region-restriction if that's possible. We use an explicit display-buffer
2286 ;; to get around the fact that this is called inside a save-excursion.
2287
2288 (defun gud-display-line (true-file line)
2289 (let* ((buffer (gud-find-file true-file))
2290 (window (gud-display-source-buffer buffer))
2291 (pos))
2292 (if (not window)
2293 (error "foo bar baz"))
2294 ;;; (if (equal buffer (current-buffer))
2295 ;;; nil
2296 ;;; (setq buffer-read-only nil))
2297 (save-excursion
2298 ;;; (setq buffer-read-only t)
2299 (set-buffer buffer)
2300 (save-restriction
2301 (widen)
2302 (goto-line line)
2303 (setq pos (point))
2304 (setq overlay-arrow-string "=>")
2305 (or overlay-arrow-position
2306 (setq overlay-arrow-position (make-marker)))
2307 (set-marker overlay-arrow-position (point) (current-buffer)))
2308 (cond ((or (< pos (point-min)) (> pos (point-max)))
2309 (widen)
2310 (goto-char pos))))
2311 (set-window-point window overlay-arrow-position)))
2312
2313 ;;; The gud-call function must do the right thing whether its invoking
2314 ;;; keystroke is from the GUD buffer itself (via major-mode binding)
2315 ;;; or a C buffer. In the former case, we want to supply data from
2316 ;;; gud-last-frame. Here's how we do it:
2317
2318 (defun gud-format-command (str arg)
2319 (let ((insource (not (eq (current-buffer) gud-comint-buffer))))
2320 (if (string-match "\\(.*\\)%f\\(.*\\)" str)
2321 (setq str (concat
2322 (substring str (match-beginning 1) (match-end 1))
2323 (file-name-nondirectory (if insource
2324 (buffer-file-name)
2325 (car gud-last-frame)))
2326 (substring str (match-beginning 2) (match-end 2)))))
2327 (if (string-match "\\(.*\\)%d\\(.*\\)" str)
2328 (setq str (concat
2329 (substring str (match-beginning 1) (match-end 1))
2330 (file-name-directory (if insource
2331 (buffer-file-name)
2332 (car gud-last-frame)))
2333 (substring str (match-beginning 2) (match-end 2)))))
2334 (if (string-match "\\(.*\\)%l\\(.*\\)" str)
2335 (setq str (concat
2336 (substring str (match-beginning 1) (match-end 1))
2337 (if insource
2338 (save-excursion
2339 (beginning-of-line)
2340 (save-restriction (widen)
2341 (1+ (count-lines 1 (point)))))
2342 (cdr gud-last-frame))
2343 (substring str (match-beginning 2) (match-end 2)))))
2344 (if (string-match "\\(.*\\)%e\\(.*\\)" str)
2345 (setq str (concat
2346 (substring str (match-beginning 1) (match-end 1))
2347 (find-c-expr)
2348 (substring str (match-beginning 2) (match-end 2)))))
2349 (if (string-match "\\(.*\\)%a\\(.*\\)" str)
2350 (setq str (concat
2351 (substring str (match-beginning 1) (match-end 1))
2352 (gud-read-address)
2353 (substring str (match-beginning 2) (match-end 2)))))
2354 (if (string-match "\\(.*\\)%p\\(.*\\)" str)
2355 (setq str (concat
2356 (substring str (match-beginning 1) (match-end 1))
2357 (if arg (int-to-string arg) "")
2358 (substring str (match-beginning 2) (match-end 2)))))
2359 )
2360 str
2361 )
2362
2363 (defun gud-read-address ()
2364 "Return a string containing the core-address found in the buffer at point."
2365 (save-excursion
2366 (let ((pt (point)) found begin)
2367 (setq found (if (search-backward "0x" (- pt 7) t) (point)))
2368 (cond
2369 (found (forward-char 2)
2370 (buffer-substring found
2371 (progn (re-search-forward "[^0-9a-f]")
2372 (forward-char -1)
2373 (point))))
2374 (t (setq begin (progn (re-search-backward "[^0-9]")
2375 (forward-char 1)
2376 (point)))
2377 (forward-char 1)
2378 (re-search-forward "[^0-9]")
2379 (forward-char -1)
2380 (buffer-substring begin (point)))))))
2381
2382 (defun gud-call (fmt &optional arg)
2383 (let ((msg (gud-format-command fmt arg)))
2384 (message "Command: %s" msg)
2385 (sit-for 0)
2386 (gud-basic-call msg)))
2387
2388 (defun gud-basic-call (command)
2389 "Invoke the debugger COMMAND displaying source in other window."
2390 (interactive)
2391 (gud-set-buffer)
2392 (let ((proc (get-buffer-process gud-comint-buffer)))
2393
2394 ;; Arrange for the current prompt to get deleted.
2395 (save-excursion
2396 (set-buffer gud-comint-buffer)
2397 (goto-char (process-mark proc))
2398 (beginning-of-line)
2399 (if (looking-at comint-prompt-regexp)
2400 (set-marker gud-delete-prompt-marker (point)))
2401 (apply comint-input-sender (list proc command)))))
2402
2403 (defun gud-refresh (&optional arg)
2404 "Fix up a possibly garbled display, and redraw the arrow."
2405 (interactive "P")
2406 (recenter arg)
2407 (or gud-last-frame (setq gud-last-frame gud-last-last-frame))
2408 (gud-display-frame))
2409 \f
2410 ;;; Code for parsing expressions out of C code. The single entry point is
2411 ;;; find-c-expr, which tries to return an lvalue expression from around point.
2412 ;;;
2413 ;;; The rest of this file is a hacked version of gdbsrc.el by
2414 ;;; Debby Ayers <ayers@asc.slb.com>,
2415 ;;; Rich Schaefer <schaefer@asc.slb.com> Schlumberger, Austin, Tx.
2416
2417 (defun find-c-expr ()
2418 "Returns the C expr that surrounds point."
2419 (interactive)
2420 (save-excursion
2421 (let ((p) (expr) (test-expr))
2422 (setq p (point))
2423 (setq expr (expr-cur))
2424 (setq test-expr (expr-prev))
2425 (while (expr-compound test-expr expr)
2426 (setq expr (cons (car test-expr) (cdr expr)))
2427 (goto-char (car expr))
2428 (setq test-expr (expr-prev)))
2429 (goto-char p)
2430 (setq test-expr (expr-next))
2431 (while (expr-compound expr test-expr)
2432 (setq expr (cons (car expr) (cdr test-expr)))
2433 (setq test-expr (expr-next))
2434 )
2435 (buffer-substring (car expr) (cdr expr)))))
2436
2437 (defun expr-cur ()
2438 "Returns the expr that point is in; point is set to beginning of expr.
2439 The expr is represented as a cons cell, where the car specifies the point in
2440 the current buffer that marks the beginning of the expr and the cdr specifies
2441 the character after the end of the expr."
2442 (let ((p (point)) (begin) (end))
2443 (expr-backward-sexp)
2444 (setq begin (point))
2445 (expr-forward-sexp)
2446 (setq end (point))
2447 (if (>= p end)
2448 (progn
2449 (setq begin p)
2450 (goto-char p)
2451 (expr-forward-sexp)
2452 (setq end (point))
2453 )
2454 )
2455 (goto-char begin)
2456 (cons begin end)))
2457
2458 (defun expr-backward-sexp ()
2459 "Version of `backward-sexp' that catches errors."
2460 (condition-case nil
2461 (backward-sexp)
2462 (error t)))
2463
2464 (defun expr-forward-sexp ()
2465 "Version of `forward-sexp' that catches errors."
2466 (condition-case nil
2467 (forward-sexp)
2468 (error t)))
2469
2470 (defun expr-prev ()
2471 "Returns the previous expr, point is set to beginning of that expr.
2472 The expr is represented as a cons cell, where the car specifies the point in
2473 the current buffer that marks the beginning of the expr and the cdr specifies
2474 the character after the end of the expr"
2475 (let ((begin) (end))
2476 (expr-backward-sexp)
2477 (setq begin (point))
2478 (expr-forward-sexp)
2479 (setq end (point))
2480 (goto-char begin)
2481 (cons begin end)))
2482
2483 (defun expr-next ()
2484 "Returns the following expr, point is set to beginning of that expr.
2485 The expr is represented as a cons cell, where the car specifies the point in
2486 the current buffer that marks the beginning of the expr and the cdr specifies
2487 the character after the end of the expr."
2488 (let ((begin) (end))
2489 (expr-forward-sexp)
2490 (expr-forward-sexp)
2491 (setq end (point))
2492 (expr-backward-sexp)
2493 (setq begin (point))
2494 (cons begin end)))
2495
2496 (defun expr-compound-sep (span-start span-end)
2497 "Returns '.' for '->' & '.', returns ' ' for white space,
2498 returns '?' for other punctuation."
2499 (let ((result ? )
2500 (syntax))
2501 (while (< span-start span-end)
2502 (setq syntax (char-syntax (char-after span-start)))
2503 (cond
2504 ((= syntax ? ) t)
2505 ((= syntax ?.) (setq syntax (char-after span-start))
2506 (cond
2507 ((= syntax ?.) (setq result ?.))
2508 ((and (= syntax ?-) (= (char-after (+ span-start 1)) ?>))
2509 (setq result ?.)
2510 (setq span-start (+ span-start 1)))
2511 (t (setq span-start span-end)
2512 (setq result ??)))))
2513 (setq span-start (+ span-start 1)))
2514 result))
2515
2516 (defun expr-compound (first second)
2517 "Non-nil if concatenating FIRST and SECOND makes a single C token.
2518 The two exprs are represented as a cons cells, where the car
2519 specifies the point in the current buffer that marks the beginning of the
2520 expr and the cdr specifies the character after the end of the expr.
2521 Link exprs of the form:
2522 Expr -> Expr
2523 Expr . Expr
2524 Expr (Expr)
2525 Expr [Expr]
2526 (Expr) Expr
2527 [Expr] Expr"
2528 (let ((span-start (cdr first))
2529 (span-end (car second))
2530 (syntax))
2531 (setq syntax (expr-compound-sep span-start span-end))
2532 (cond
2533 ((= (car first) (car second)) nil)
2534 ((= (cdr first) (cdr second)) nil)
2535 ((= syntax ?.) t)
2536 ((= syntax ? )
2537 (setq span-start (char-after (- span-start 1)))
2538 (setq span-end (char-after span-end))
2539 (cond
2540 ((= span-start ?) ) t )
2541 ((= span-start ?] ) t )
2542 ((= span-end ?( ) t )
2543 ((= span-end ?[ ) t )
2544 (t nil))
2545 )
2546 (t nil))))
2547
2548 (provide 'gud)
2549
2550 ;;; gud.el ends here