1 ;;; sdcdb.el --- run sdcdb under Emacs
3 ;; Author: W. Schelter, University of Texas
4 ;; wfs@rascal.ics.utexas.edu
6 ;; Keywords: c, unix, tools, debugging
8 ;; Some ideas are due to Masanobu.
10 ;; This file is part of XEmacs.
12 ;; XEmacs is free software; you can redistribute it and/or modify it
13 ;; under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; XEmacs is distributed in the hope that it will be useful, but
18 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ;; General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with XEmacs; see the file COPYING. If not, write to the Free
24 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 ;;; Synched up with: Not in FSF
31 ;; Description of SDCDB interface:
33 ;; A facility is provided for the simultaneous display of the source code
34 ;; in one window, while using sdcdb to step through a function in the
35 ;; other. A small arrow in the source window, indicates the current
40 ;; In order to use this facility, invoke the command SDCDB to obtain a
41 ;; shell window with the appropriate command bindings. You will be asked
42 ;; for the name of a file to run. Sdcdb will be invoked on this file, in a
43 ;; window named *sdcdb-foo* if the file is foo.
45 ;; M-s steps by one line, and redisplays the source file and line.
47 ;; You may easily create additional commands and bindings to interact
48 ;; with the display. For example to put the sdcdb command next on \M-n
49 ;; (def-sdcdb next "\M-n")
51 ;; This causes the emacs command sdcdb-next to be defined, and runs
52 ;; sdcdb-display-frame after the command.
54 ;; sdcdb-display-frame is the basic display function. It tries to display
55 ;; in the other window, the file and line corresponding to the current
56 ;; position in the sdcdb window. For example after a sdcdb-step, it would
57 ;; display the line corresponding to the position for the last step. Or
58 ;; if you have done a backtrace in the sdcdb buffer, and move the cursor
59 ;; into one of the frames, it would display the position corresponding to
62 ;; sdcdb-display-frame is invoked automatically when a filename-and-line-number
63 ;; appears in the output.
71 (if (featurep 'toolbar
)
72 (require 'eos-toolbar
"sun-eos-toolbar"))
75 (defvar sdcdb-last-frame
)
76 (defvar sdcdb-delete-prompt-marker
)
77 (defvar sdcdb-filter-accumulator
)
78 (defvar sdcdb-last-frame-displayed-p
)
79 (defvar sdcdb-arrow-extent nil
)
80 (or (fboundp 'make-glyph
) (fset 'make-glyph
'identity
)) ; work w/ pre beta v12
81 (defvar sdcdb-arrow-glyph
(make-glyph "=>"))
83 (make-face 'sdcdb-arrow-face
)
84 (or (face-differs-from-default-p 'sdcdb-arrow-face
)
85 ;; Usually has a better default value than highlight does
86 (copy-face 'isearch
'sdcdb-arrow-face
))
88 ;; Hooks can side-effect extent arg to change extent properties
89 (defvar sdcdb-arrow-extent-hooks
'())
91 (defvar sdcdb-prompt-pattern
"^>\\|^(.*sdcdb[+]?) *\\|^---Type <return> to.*--- *"
92 "A regexp to recognize the prompt for sdcdb or sdcdb+.")
94 (defvar sdcdb-mode-map nil
95 "Keymap for sdcdb-mode.")
97 (defvar sdcdb-toolbar nil
)
101 (setq sdcdb-mode-map
(make-sparse-keymap))
102 (set-keymap-name sdcdb-mode-map
'sdcdb-mode-map
)
103 (set-keymap-parents sdcdb-mode-map
(list comint-mode-map
))
104 (define-key sdcdb-mode-map
"\C-l" 'sdcdb-refresh
)
105 (define-key sdcdb-mode-map
"\C-c\C-c" 'sdcdb-control-c-subjob
)
106 (define-key sdcdb-mode-map
"\t" 'comint-dynamic-complete
)
107 (define-key sdcdb-mode-map
"\M-?" 'comint-dynamic-list-completions
))
109 (define-key ctl-x-map
" " 'sdcdb-break
)
110 (define-key ctl-x-map
"&" 'send-sdcdb-command
)
112 ;;Of course you may use `def-sdcdb' with any other sdcdb command, including
115 (defmacro def-sdcdb
(name key
&optional doc
&rest forms
)
116 (let* ((fun (intern (format "sdcdb-%s" name
)))
117 (cstr (list 'if
'(not (= 1 arg
))
118 (list 'format
"%s %s" name
'arg
)
121 (nconc (list 'defun
fun '(arg)
124 (list 'sdcdb-call cstr
))
126 (and key
(list 'define-key
'sdcdb-mode-map key
(list 'quote fun
))))))
128 (def-sdcdb "step" "\M-s" "Step one source line with display"
129 (sdcdb-delete-arrow-extent))
130 (def-sdcdb "stepi" "\M-i" "Step one instruction with display"
131 (sdcdb-delete-arrow-extent))
132 (def-sdcdb "finish" "\C-c\C-f" "Finish executing current function"
133 (sdcdb-delete-arrow-extent))
134 (def-sdcdb "run" nil
"Run the current program"
135 (sdcdb-delete-arrow-extent))
137 ;;"next" and "cont" were bound to M-n and M-c in Emacs 18, but these are
138 ;;poor choices, since M-n is used for history navigation and M-c is
139 ;;capitalize-word. These are defined without key bindings so that users
140 ;;may choose their own bindings.
141 (def-sdcdb "next" "\C-c\C-n" "Step one source line (skip functions)"
142 (sdcdb-delete-arrow-extent))
143 (def-sdcdb "cont" "\C-c\M-c" "Proceed with the program"
144 (sdcdb-delete-arrow-extent))
146 (def-sdcdb "up" "\C-c<" "Go up N stack frames (numeric arg) with display")
147 (def-sdcdb "down" "\C-c>" "Go down N stack frames (numeric arg) with display")
149 (defvar sdcdb-display-mode nil
150 "Minor mode for sdcdb frame display")
151 (or (assq 'sdcdb-display-mode minor-mode-alist
)
152 (setq minor-mode-alist
154 (append minor-mode-alist
155 '((sdcdb-display-mode " Frame"))))))
157 (defun sdcdb-display-mode (&optional arg
)
158 "Toggle SDCDB Frame display mode
159 With arg, turn display mode on if and only if arg is positive.
160 In the display minor mode, source file are displayed in another
161 window for repective \\[sdcdb-display-frame] commands."
163 (setq sdcdb-display-mode
(if (null arg
)
164 (not sdcdb-display-mode
)
165 (> (prefix-numeric-value arg
) 0))))
167 ;; Using cc-mode's syntax table is broken.
168 (defvar sdcdb-mode-syntax-table nil
169 "Syntax table for SDCDB mode.")
171 ;; This is adapted from CC Mode 5.11.
172 (unless sdcdb-mode-syntax-table
173 (setq sdcdb-mode-syntax-table
(make-syntax-table))
174 ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
175 (modify-syntax-entry ?_
"_" sdcdb-mode-syntax-table
)
176 (modify-syntax-entry ?
\\ "\\" sdcdb-mode-syntax-table
)
177 (modify-syntax-entry ?
+ "." sdcdb-mode-syntax-table
)
178 (modify-syntax-entry ?-
"." sdcdb-mode-syntax-table
)
179 (modify-syntax-entry ?
= "." sdcdb-mode-syntax-table
)
180 (modify-syntax-entry ?%
"." sdcdb-mode-syntax-table
)
181 (modify-syntax-entry ?
< "." sdcdb-mode-syntax-table
)
182 (modify-syntax-entry ?
> "." sdcdb-mode-syntax-table
)
183 (modify-syntax-entry ?
& "." sdcdb-mode-syntax-table
)
184 (modify-syntax-entry ?|
"." sdcdb-mode-syntax-table
)
185 (modify-syntax-entry ?
\' "\"" sdcdb-mode-syntax-table
)
186 ;; add extra comment syntax
187 (modify-syntax-entry ?
/ ". 14" sdcdb-mode-syntax-table
)
188 (modify-syntax-entry ?
* ". 23" sdcdb-mode-syntax-table
))
192 "Major mode for interacting with an inferior Sdcdb process.
193 The following commands are available:
197 \\[sdcdb-display-frame] displays in the other window
198 the last line referred to in the sdcdb buffer. See also
199 \\[sdcdb-display-mode].
201 \\[sdcdb-step],\\[sdcdb-next], and \\[sdcdb-nexti] in the sdcdb window,
202 call sdcdb to step,next or nexti and then update the other window
203 with the current file and position.
205 If you are in a source file, you may select a point to break
206 at, by doing \\[sdcdb-break].
209 Many commands are inherited from comint mode.
210 Additionally we have:
212 \\[sdcdb-display-frame] display frames file in other window
213 \\[sdcdb-step] advance one line in program
214 \\[send-sdcdb-command] used for special printing of an arg at the current point.
215 C-x SPACE sets break point at current line."
218 (use-local-map sdcdb-mode-map
)
219 (set-syntax-table sdcdb-mode-syntax-table
)
220 (make-local-variable 'sdcdb-last-frame-displayed-p
)
221 (make-local-variable 'sdcdb-last-frame
)
222 (make-local-variable 'sdcdb-delete-prompt-marker
)
223 (make-local-variable 'sdcdb-display-mode
)
224 (make-local-variable' sdcdb-filter-accumulator
)
225 (setq sdcdb-last-frame nil
226 sdcdb-delete-prompt-marker nil
227 sdcdb-filter-accumulator nil
229 major-mode
'sdcdb-mode
230 mode-name
"Inferior SDCDB"
231 comint-prompt-regexp sdcdb-prompt-pattern
232 sdcdb-last-frame-displayed-p t
)
233 (set (make-local-variable 'shell-dirtrackp
) t
)
234 ;;(make-local-variable 'sdcdb-arrow-extent)
235 (and (extentp sdcdb-arrow-extent
)
236 (delete-extent sdcdb-arrow-extent
))
237 (setq sdcdb-arrow-extent nil
)
239 (make-local-hook 'kill-buffer-hook
)
240 (add-hook 'kill-buffer-hook
'sdcdb-delete-arrow-extent nil t
)
241 (add-hook 'comint-input-filter-functions
'shell-directory-tracker nil t
)
242 (run-hooks 'sdcdb-mode-hook
))
244 (defun sdcdb-delete-arrow-extent ()
245 (let ((inhibit-quit t
))
246 (if sdcdb-arrow-extent
247 (delete-extent sdcdb-arrow-extent
))
248 (setq sdcdb-arrow-extent nil
)))
250 (defvar current-sdcdb-buffer nil
)
253 (defvar sdcdb-command-name
"sdcdb"
254 "Pathname for executing sdcdb.")
257 (defun sdcdb (path &optional corefile
)
258 "Run sdcdb on program FILE in buffer *sdcdb-FILE*.
259 The directory containing FILE becomes the initial working directory
260 and source-file directory for SDCDB. If you wish to change this, use
261 the SDCDB commands `cd DIR' and `directory'."
262 (interactive "FRun sdcdb on file: ")
263 (setq path
(file-truename (expand-file-name path
)))
264 (let ((file (file-name-nondirectory path
)))
265 (switch-to-buffer (concat "*sdcdb-" file
"*"))
266 (setq default-directory
(file-name-directory path
))
267 (or (bolp) (newline))
268 (insert "Current directory is " default-directory
"\n")
270 (concat "sdcdb-" file
)
271 (substitute-in-file-name sdcdb-command-name
)
274 "-cd" default-directory
276 (and corefile
(list corefile
)))
277 (set-process-filter (get-buffer-process (current-buffer)) 'sdcdb-filter
)
278 (set-process-sentinel (get-buffer-process (current-buffer)) 'sdcdb-sentinel
)
279 ;; XEmacs change: turn on sdcdb mode after setting up the proc filters
280 ;; for the benefit of shell-font.el
285 (defun sdcdb-with-core (file corefile
)
286 "Debug a program using a corefile."
287 (interactive "fProgram to debug: \nfCore file to use: ")
288 (sdcdb file corefile
))
290 (defun sdcdb-set-buffer ()
291 (cond ((eq major-mode
'sdcdb-mode
)
292 (setq current-sdcdb-buffer
(current-buffer))
293 (if (featurep 'eos-toolbar
)
294 (set-specifier default-toolbar
(cons (current-buffer)
298 ;; This function is responsible for inserting output from SDCDB
300 ;; Aside from inserting the text, it notices and deletes
301 ;; each filename-and-line-number;
302 ;; that SDCDB prints to identify the selected frame.
303 ;; It records the filename and line number, and maybe displays that file.
304 (defun sdcdb-filter (proc string
)
305 (let ((inhibit-quit t
))
307 (set-buffer (process-buffer proc
))
308 (if sdcdb-filter-accumulator
309 (sdcdb-filter-accumulate-marker
310 proc
(concat sdcdb-filter-accumulator string
))
311 (sdcdb-filter-scan-input proc string
)))))
313 (defun sdcdb-filter-accumulate-marker (proc string
)
314 (setq sdcdb-filter-accumulator nil
)
315 (if (> (length string
) 1)
316 (if (= (aref string
1) ?
\032)
317 (let ((end (string-match "\n" string
)))
320 (let* ((first-colon (string-match ":" string
2))
322 (string-match ":" string
(1+ first-colon
))))
323 (setq sdcdb-last-frame
324 (cons (substring string
2 first-colon
)
326 (substring string
(1+ first-colon
)
328 (setq sdcdb-last-frame-displayed-p nil
)
329 (sdcdb-filter-scan-input proc
330 (substring string
(1+ end
))))
331 (setq sdcdb-filter-accumulator string
)))
332 (sdcdb-filter-insert proc
"\032")
333 (sdcdb-filter-scan-input proc
(substring string
1)))
334 (setq sdcdb-filter-accumulator string
)))
336 (defun sdcdb-filter-scan-input (proc string
)
337 (if (equal string
"")
338 (setq sdcdb-filter-accumulator nil
)
339 (let ((start (string-match "\032" string
)))
341 (progn (sdcdb-filter-insert proc
(substring string
0 start
))
342 (sdcdb-filter-accumulate-marker proc
343 (substring string start
)))
344 (sdcdb-filter-insert proc string
)))))
346 (defun sdcdb-filter-insert (proc string
)
347 (let ((moving (= (point) (process-mark proc
)))
348 (output-after-point (< (point) (process-mark proc
))))
350 ;; Insert the text, moving the process-marker.
351 (goto-char (process-mark proc
))
352 (insert-before-markers string
)
353 (set-marker (process-mark proc
) (point))
354 (sdcdb-maybe-delete-prompt)
355 ;; Check for a filename-and-line number.
357 ;; Don't display the specified file
358 ;; unless (1) point is at or after the position where output appears
359 ;; and (2) this buffer is on the screen.
360 (or output-after-point
361 (not (get-buffer-window (current-buffer))))
362 ;; Display a file only when a new filename-and-line-number appears.
364 (if moving
(goto-char (process-mark proc
))))
367 (if (and (should-use-dialog-box-p)
368 (setq s
(or (string-match " (y or n) *\\'" string
)
369 (string-match " (yes or no) *\\'" string
))))
370 (sdcdb-mouse-prompt-hack (substring string
0 s
) (current-buffer))))
373 (defun sdcdb-mouse-prompt-hack (prompt buffer
)
376 (vector "Yes" (list 'sdcdb-mouse-prompt-hack-answer
't buffer
) t
)
377 (vector "No" (list 'sdcdb-mouse-prompt-hack-answer
'nil buffer
) t
)
379 (vector "Cancel" (list 'sdcdb-mouse-prompt-hack-answer
'nil buffer
) t
)
382 (defun sdcdb-mouse-prompt-hack-answer (answer buffer
)
383 (let ((b (current-buffer)))
387 (goto-char (process-mark (get-buffer-process buffer
)))
388 (delete-region (point) (point-max))
389 (insert (if answer
"yes" "no"))
393 (defun sdcdb-sentinel (proc msg
)
394 (cond ((null (buffer-name (process-buffer proc
)))
396 ;; Stop displaying an arrow in a source file.
397 ;(setq overlay-arrow-position nil) -- done by kill-buffer-hook
398 (set-process-buffer proc nil
))
399 ((memq (process-status proc
) '(signal exit
))
400 ;; Stop displaying an arrow in a source file.
401 (sdcdb-delete-arrow-extent)
402 ;; Fix the mode line.
403 (setq modeline-process
404 (concat ": sdcdb " (symbol-name (process-status proc
))))
405 (let* ((obuf (current-buffer)))
406 ;; save-excursion isn't the right thing if
407 ;; process-buffer is current-buffer
410 ;; Write something in *compilation* and hack its mode line,
411 (set-buffer (process-buffer proc
))
412 ;; Force mode line redisplay soon
413 (set-buffer-modified-p (buffer-modified-p))
415 (insert ?
\n mode-name
" " msg
)
417 (goto-char (point-max))
418 (insert ?
\n mode-name
" " msg
)))
419 ;; If buffer and mode line will show that the process
420 ;; is dead, we can delete it now. Otherwise it
421 ;; will stay around until M-x list-processes.
422 (delete-process proc
))
423 ;; Restore old buffer, but don't restore old point
424 ;; if obuf is the sdcdb buffer.
425 (set-buffer obuf
))))))
428 (defun sdcdb-refresh (&optional arg
)
429 "Fix up a possibly garbled display, and redraw the arrow."
432 (sdcdb-display-frame))
434 (defun sdcdb-display-frame (&optional nodisplay noauto
)
435 "Find, obey and delete the last filename-and-line marker from SDCDB.
436 The marker looks like \\032\\032FILENAME:LINE:CHARPOS\\n.
437 Obeying it means displaying in another window the specified file and line."
440 (and sdcdb-last-frame
(not nodisplay
)
442 (or (not sdcdb-last-frame-displayed-p
) (not noauto
))
443 (progn (sdcdb-display-line (car sdcdb-last-frame
) (cdr sdcdb-last-frame
))
444 (setq sdcdb-last-frame-displayed-p t
))))
446 ;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
447 ;; and that its line LINE is visible.
448 ;; Put the overlay-arrow on the line LINE in that buffer.
450 (defun sdcdb-display-line (true-file line
&optional select-method
)
452 ;; LINE number to highlight and make visible
453 ;; SELECT-METHOD 'source, 'debugger, or 'none. (default is 'debugger)
454 (and (null select-method
) (setq select-method
'debugger
))
455 (let* ((pre-display-buffer-function nil
) ; screw it, put it all in one screen
457 (source-buffer (find-file-noselect true-file
))
458 (source-window (display-buffer source-buffer
))
459 (debugger-window (get-buffer-window current-sdcdb-buffer
))
460 (extent sdcdb-arrow-extent
)
462 ;; XEmacs change: make sure we find a window displaying the source file
463 ;; even if we are already sitting in it when a breakpoint is hit.
464 ;; Otherwise the t argument to display-buffer will prevent it from being
467 (cond ((eq select-method
'debugger
)
468 ;; might not already be displayed
469 (setq debugger-window
(display-buffer current-sdcdb-buffer
))
470 (select-window debugger-window
))
471 ((eq select-method
'source
)
472 (select-window source-window
))))
474 (not (eq (extent-object extent
) source-buffer
))
475 (setq extent
(delete-extent extent
)))
478 (setq extent
(make-extent 1 1 source-buffer
))
479 (set-extent-face extent
'sdcdb-arrow-face
)
480 (set-extent-begin-glyph extent sdcdb-arrow-glyph
)
481 (set-extent-begin-glyph-layout extent
'whitespace
)
482 (set-extent-priority extent
2000)
483 (setq sdcdb-arrow-extent extent
)))
485 (set-buffer source-buffer
)
489 (set-window-point source-window
(point))
492 (set-extent-endpoints extent pos
(point))
493 (run-hook-with-args 'sdcdb-arrow-extent-hooks extent
))
494 (cond ((or (< pos
(point-min)) (> pos
(point-max)))
497 ;; Added by Stig. It caused lots of problems for several users
498 ;; and since its purpose is unclear it is getting commented out.
499 ;;(and debugger-window
500 ;; (set-window-point debugger-window pos))
503 (defun sdcdb-call (command)
504 "Invoke sdcdb COMMAND displaying source in other window."
506 (goto-char (point-max))
507 ;; Record info on the last prompt in the buffer and its position.
508 ;; This is used in sdcdb-maybe-delete-prompt
509 ;; to prevent multiple prompts from accumulating.
511 (goto-char (process-mark (get-buffer-process current-sdcdb-buffer
)))
514 (setq sdcdb-delete-prompt-marker
517 (list (point-marker) (- pt
(point))
518 (buffer-substring (point) pt
))))))
520 (process-send-string (get-buffer-process current-sdcdb-buffer
)
521 (concat command
"\n")))
523 (defun sdcdb-maybe-delete-prompt ()
524 (if sdcdb-delete-prompt-marker
525 ;; Get the string that we used as the prompt before.
526 (let ((prompt (nth 2 sdcdb-delete-prompt-marker
))
527 (length (nth 1 sdcdb-delete-prompt-marker
)))
528 ;; Position after it.
529 (goto-char (+ (car sdcdb-delete-prompt-marker
) length
))
530 ;; Delete any duplicates of it which follow right after.
531 (while (and (<= (+ (point) length
) (point-max))
533 (buffer-substring (point) (+ (point) length
))))
534 (delete-region (point) (+ (point) length
)))
535 ;; If that didn't take us to where output is arriving,
536 ;; we have encountered something other than a prompt,
537 ;; so stop trying to delete any more prompts.
539 (process-mark (get-buffer-process current-sdcdb-buffer
))))
541 (set-marker (car sdcdb-delete-prompt-marker
) nil
)
542 (setq sdcdb-delete-prompt-marker nil
))))))
544 (defun sdcdb-break (temp)
545 "Set SDCDB breakpoint at this source line. With ARG set temporary breakpoint."
547 (let* ((file-name (file-name-nondirectory buffer-file-name
))
548 (line (save-restriction
551 (1+ (count-lines 1 (point)))))
552 (cmd (concat (if temp
"tbreak " "break ") file-name
":"
553 (int-to-string line
))))
554 (set-buffer current-sdcdb-buffer
)
555 (goto-char (process-mark (get-buffer-process current-sdcdb-buffer
)))
556 (delete-region (point) (point-max))
559 ;;(process-send-string (get-buffer-process current-sdcdb-buffer) cmd)
562 (defun sdcdb-clear ()
563 "Set SDCDB breakpoint at this source line."
565 (let* ((file-name (file-name-nondirectory buffer-file-name
))
566 (line (save-restriction
569 (1+ (count-lines 1 (point)))))
570 (cmd (concat "clear " file-name
":"
571 (int-to-string line
))))
572 (set-buffer current-sdcdb-buffer
)
573 (goto-char (process-mark (get-buffer-process current-sdcdb-buffer
)))
574 (delete-region (point) (point-max))
577 ;;(process-send-string (get-buffer-process current-sdcdb-buffer) cmd)
580 (defun sdcdb-read-address()
581 "Return a string containing the core-address found in the buffer at point."
583 (let ((pt (point)) found begin
)
584 (setq found
(if (search-backward "0x" (- pt
7) t
)(point)))
585 (cond (found (forward-char 2)
586 (buffer-substring found
587 (progn (re-search-forward "[^0-9a-f]")
590 (t (setq begin
(progn (re-search-backward "[^0-9]") (forward-char 1)
593 (re-search-forward "[^0-9]")
595 (buffer-substring begin
(point)))))))
598 (defvar sdcdb-commands nil
599 "List of strings or functions used by send-sdcdb-command.
600 It is for customization by you.")
602 (defun send-sdcdb-command (arg)
604 "This command reads the number where the cursor is positioned. It
605 then inserts this ADDR at the end of the sdcdb buffer. A numeric arg
606 selects the ARG'th member COMMAND of the list sdcdb-print-command. If
607 COMMAND is a string, (format COMMAND ADDR) is inserted, otherwise
608 (funcall COMMAND ADDR) is inserted. eg. \"p (rtx)%s->fld[0].rtint\"
609 is a possible string to be a member of sdcdb-commands. "
614 (if arg
(setq comm
(nth arg sdcdb-commands
)))
615 (setq addr
(sdcdb-read-address))
616 (if (eq (current-buffer) current-sdcdb-buffer
)
620 (if (stringp comm
) (format comm addr
) (funcall comm addr
))))
621 (t (setq comm addr
)))
622 (switch-to-buffer current-sdcdb-buffer
)
623 (goto-char (point-max))
626 (fset 'sdcdb-control-c-subjob
'comint-interrupt-subjob
)
628 ;(defun sdcdb-control-c-subjob ()
629 ; "Send a Control-C to the subprocess."
631 ; (process-send-string (get-buffer-process (current-buffer))
634 (defun sdcdb-toolbar-break ()
637 (message (car sdcdb-last-frame
))
638 (set-buffer (find-file-noselect (car sdcdb-last-frame
)))
641 (defun sdcdb-toolbar-clear ()
644 (message (car sdcdb-last-frame
))
645 (set-buffer (find-file-noselect (car sdcdb-last-frame
)))
650 ;;; sdcdb.el ends here