[net.emacs] dbx-mode for GNU Emacs

umerin@flab.UUCP (Masanobu UMEDA) (10/16/86)

	Here is a dbx mode for GNU Emacs 17.64. It provides Sun's
	dbxtool like interface. Everyone is granted permission to
	copy, modify and redistribute this software under the same
	conditions as GNU Emacs. Any comment is welcome.

				Masanobu UMEDA
				umerin@flab.fujitsu.junet

	P.S. I have a prolog mode for GNU Emacs 17.64. If you are
	interested in it, please mail me.
----------------------------------------------------------------------
;; Run dbx under Emacs
;; Copyright (C) 1986 Masanobu UMEDA (umerin@flab.fujitsu.junet)

;; This file is part of GNU Emacs.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY.  No author or distributor
;; accepts responsibility to anyone for the consequences of using it
;; or for whether it serves any particular purpose or works at all,
;; unless he says so in writing.  Refer to the GNU Emacs General Public
;; License for full details.

;; Everyone is granted permission to copy, modify and redistribute
;; GNU Emacs, but only under the conditions described in the
;; GNU Emacs General Public License.   A copy of this license is
;; supposed to have been given to you along with GNU Emacs so you
;; can know your rights and responsibilities.  It should be in a
;; file named COPYING.  Among other things, the copyright notice
;; and this notice must be preserved on all copies.

(require 'shell)

(make-variable-buffer-local 'shell-prompt-pattern)

(defvar dbx-language-mode-list '(c-mode)
  "List of major mode name of the language supported by both emacs and dbx.")

(defvar inferior-dbx-mode-map nil)
(if inferior-dbx-mode-map
    nil
  (setq inferior-dbx-mode-map (copy-alist shell-mode-map))
  (define-key inferior-dbx-mode-map "\C-c\C-j" 'dbx-where)
  (define-key inferior-dbx-mode-map "\C-c\C-s" 'dbx-step)
  (define-key inferior-dbx-mode-map "\C-c\C-n" 'dbx-next)
  (define-key ctl-x-map "\C-@" 'dbx-stop-at))

(defun inferior-dbx-mode ()
  "Major mode for interacting with an inferior Dbx process.

The following commands are available:
\\{inferior-dbx-mode-map}

Entry to this mode calls the value of dbx-mode-hook with no arguments,
if that value is non-nil.  Likewise with the value of shell-mode-hook.
dbx-mode-hook is called after shell-mode-hook.

You can display the debugging program in other window and point out
where your are now using the command \\[dbx-where].

\\[dbx-step] and \\[dbx-next] resume debugging process with `step' and
`next' command of dbx, respectively. These commands wait for dbx
prompt, and point out where you are now using dbx-where command.

The command \\[dbx-stop-at] sets break point at current line of
program in the buffer. Major mode name of the buffer must be in
dbx-language-mode-list.

Commands:

Return at end of buffer sends line as input.
Return not at end copies rest of line to end and sends it.
C-c C-d sends end-of-file as input.
C-d deletes or kills characters.
C-c C-u and C-c C-w are kill commands, imitating normal Unix input editing.
C-c C-c interrupts the shell or its current subjob if any.
C-c C-z stops, likewise.  C-c C-\\ sends quit signal, likewise.
C-c C-j displays debugging program in other window and
        points out where you are now.
C-c C-s executes single step one line.
C-c C-n steps to next line (skip over calls).
C-x C-@ sets break point at current line."
  (interactive)
  (kill-all-local-variables)
  (setq major-mode 'inferior-dbx-mode)
  (setq mode-name "Inferior Dbx")
  (setq mode-line-format 
	"--%1*%1*-Emacs: %17b   %M   %[(%m: %s)%]----%3p--%-")
  (use-local-map inferior-dbx-mode-map)
  (make-local-variable 'last-input-start)
  (setq last-input-start (make-marker))
  (make-local-variable 'last-input-end)
  (setq last-input-end (make-marker))
  (setq shell-prompt-pattern "^(.*dbx) *") ;Set dbx prompt pattern
  (run-hooks 'shell-mode-hook 'dbx-mode-hook))

(defun run-dbx ()
  "Run an inferior Dbx process, input and output via buffer *dbx*."
  (interactive)
  (switch-to-buffer (make-shell "dbx" "dbx"))
  (inferior-dbx-mode))

(defun dbx-where ()
  "Display dbx'ed program in other window and point out where you are now."
  (interactive)
  (let (file line)
    (save-excursion
      (if (re-search-backward "stopped in .* at line ")
	  (progn
	    (setq line (buffer-substring
			(progn (re-search-forward " at line ")
			       (point))
			(progn (forward-word 1)
			       (point))))
	    (setq file (buffer-substring
			(progn (re-search-forward "in file \"")
			       (point))
			(progn (re-search-forward "\"")
			       (forward-char -1)
			       (point))))
	    )))
    (find-file-other-window (expand-file-name file nil))
    (setq buffer-read-only t)		;Read-only
    (sit-for 0)				;Wait a little
    (send-string-to-terminal "\r  \r")	;Clear "=>"
    (send-string-to-terminal		;Re-display
     (buffer-substring (point) (min (+ (point) 2)
				    (progn (end-of-line) (point)))))
    (goto-line (string-to-int line))	;Jump to the line
    (sit-for 0)				;Wait a little
    (send-string-to-terminal "\r=>")	;Print "=>"
    (other-window 1)			;Return to dbx
    ))

(defun dbx-stop-at ()
  "Set break point at current line."
  (interactive)
  (if (not (memq major-mode dbx-language-mode-list))
      (error "Dbx-stop-at: this language is not supported yet."))
  (let ((file-name
	 (substring buffer-file-name
		    (length (file-name-directory buffer-file-name))))
	(line (what-line)))
    (setq line (string-to-int		;I don't know how to get
					; the line number directly.
		(substring line (cdr (read-from-string line)))))
    (send-string "dbx" (concat "stop at \"" file-name "\":" line "\n"))))

(defun dbx-step ()
  "Execute dbx step command, and wait for its termination."
  (interactive)
  (dbx-exec-and-wait "step"))

(defun dbx-next ()
  "Execute dbx next command, and wait for its termination."
  (interactive)
  (dbx-exec-and-wait "next"))

(defun dbx-exec-and-wait (command)
  "Execute dbx COMMAND, wait for its prompt,\
 and then point out where you are now.
This command will not terminate until dbx prompt appears at the end of buffer."
  (interactive)
  (goto-char (point-max))
  (let ((stopped nil) (pos (point)))
    (send-string "dbx" (concat command "\n")) ;Resume debugging process
    (while (not stopped)		;Wait for dbx prompt
      (sleep-for 1)
      (goto-char (point-max))
      (beginning-of-line)
      (if (and (> (point) pos)		;Must be new prompt pattern
	       (looking-at shell-prompt-pattern))
	  (setq stopped t)))
    (dbx-where)				;Point out where you are
    (goto-char (point-max))))
-- 
=============================================================================
			Masanobu UMEDA
			...!titcca!flab!umerin
			umerin@flab.fujitsu.junet

	NOTES: Views and conclusions contained in this article are
	the authors' and should not be interpreted as representing
	the official opinion or policy of Fujitsu.