home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / gnu / emacs / help / 4804 < prev    next >
Encoding:
Text File  |  1992-11-16  |  15.5 KB  |  436 lines

  1. Xref: sparky gnu.emacs.help:4804 gnu.emacs.sources:797
  2. Newsgroups: gnu.emacs.help,gnu.emacs.sources
  3. Path: sparky!uunet!mcsun!sunic!aun.uninett.no!nuug!nntp.uio.no!egilp
  4. From: egilp@ulrik.uio.no (Egil Pedersen)
  5. Subject: Re: Is there a dbx-mode for DEC's Ultrix dbx?
  6. In-Reply-To: whaley@kpc.com's message of Mon, 16 Nov 1992 03:20:27 GMT
  7. Message-ID: <EGILP.92Nov16112814@ulrik.uio.no>
  8. Sender: news@ulrik.uio.no (Mr News)
  9. Nntp-Posting-Host: ulrik
  10. Organization: University of Oslo, Norway
  11. References: <whaley.721884027@kpc.com>
  12. Date: Mon, 16 Nov 1992 10:28:14 GMT
  13. Lines: 421
  14.  
  15. In article <whaley.721884027@kpc.com> whaley@kpc.com (Kenneth Whaley) writes:
  16.  
  17.    Unfortunately, DEC's Ultrix dbx outputs different strings  for breakpoints,
  18.    etc. than the dbx that all the "dbx.el"s I've found on the net are
  19.    written to work with.  If it were simply a matter of changing the 
  20.    regexp of breakpoints, then I could get this to work, but
  21.    unfortunately the DEC dbx does not print out the file name at every
  22.    breakpoint, only the line number (and the breakpoint number, the function
  23.    name, and the PC).
  24.  
  25. You may try this one. It works with 18.58. I do not remember where I got it.
  26.  
  27. ;; Run MIPS dbx under Emacs
  28. ;; Author: W. Schelter, University of Texas
  29. ;;     wfs@rascal.ics.utexas.edu
  30. ;; Rewritten by rms.
  31. ;; Some ideas are due to Masanobu.
  32. ;; Converted from gdb.el to mipsdbx.el by Kung and Killian.
  33.  
  34. ;; This file is part of GNU Emacs.
  35. ;; Copyright (C) 1988 Free Software Foundation, Inc.
  36.  
  37. ;; GNU Emacs is distributed in the hope that it will be useful, but
  38. ;; WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  39. ;; to anyone for the consequences of using it or for whether it serves
  40. ;; any particular purpose or works at all, unless he says so in writing.
  41. ;; Refer to the GNU Emacs General Public License for full details.
  42.  
  43. ;; Everyone is granted permission to copy, modify and redistribute GNU
  44. ;; Emacs, but only under the conditions described in the GNU Emacs
  45. ;; General Public License.  A copy of this license is supposed to have
  46. ;; been given to you along with GNU Emacs so you can know your rights and
  47. ;; responsibilities.  It should be in a file named COPYING.  Among other
  48. ;; things, the copyright notice and this notice must be preserved on all
  49. ;; copies.
  50.  
  51. ;; Description of DBX interface:
  52.  
  53. ;; A facility is provided for the simultaneous display of the source code
  54. ;; in one window, while using dbx to step through a function in the
  55. ;; other.  A small arrow in the source window, indicates the current
  56. ;; line.
  57.  
  58. ;; Starting up:
  59.  
  60. ;; In order to use this facility, invoke the command DBX to obtain a
  61. ;; shell window with the appropriate command bindings.  You will be asked
  62. ;; for the name of a file to run.  Dbx will be invoked on this file, in a
  63. ;; window named *dbx-foo* if the file is foo.
  64.  
  65. ;; M-s steps by one line, and redisplays the source file and line.
  66.  
  67. ;; You may easily create additional commands and bindings to interact
  68. ;; with the display.  For example to put the dbx command next on \M-n
  69. ;; (def-dbx next "\M-n")
  70.  
  71. ;; This causes the emacs command dbx-next to be defined, and runs
  72. ;; dbx-display-frame after the command.
  73.  
  74. ;; dbx-display-frame is the basic display function.  It tries to display
  75. ;; in the other window, the file and line corresponding to the current
  76. ;; position in the dbx window.  For example after a dbx-step, it would
  77. ;; display the line corresponding to the position for the last step.  Or
  78. ;; if you have done a backtrace in the dbx buffer, and move the cursor
  79. ;; into one of the frames, it would display the position corresponding to
  80. ;; that frame.
  81.  
  82. ;; dbx-display-frame is invoked automatically when a filename-and-line-number
  83. ;; appears in the output.
  84.  
  85.  
  86. (require 'shell)
  87.  
  88. (defvar dbx-prompt-pattern "^(.*dbx[+]?) *"
  89.   "A regexp to recognize the prompt for dbx or dbx+.")
  90.  
  91. (defvar dbx-mode-map nil
  92.   "Keymap for dbx-mode.")
  93.  
  94. (if dbx-mode-map
  95.    nil
  96.   (setq dbx-mode-map (copy-keymap shell-mode-map))
  97.   (define-key dbx-mode-map "\C-l" 'dbx-refresh))
  98.  
  99. (define-key ctl-x-map " " 'dbx-break)
  100. (define-key ctl-x-map "&" 'send-dbx-command)
  101.  
  102. ;;Of course you may use `def-dbx' with any other dbx command, including
  103. ;;user defined ones.
  104.  
  105. (defmacro def-dbx (name key &optional doc)
  106.   (let* ((fun (intern (format "dbx-%s" name)))
  107.      (cstr (list 'if '(not (= 1 arg))
  108.              (list 'format "%s %s" name 'arg)
  109.              name)))
  110.     (list 'progn
  111.        (list 'defun fun '(arg)
  112.         (or doc "")
  113.         '(interactive "p")
  114.         (list 'dbx-call cstr))
  115.       (list 'define-key 'dbx-mode-map key  (list 'quote fun)))))
  116.  
  117. (def-dbx "step"   "\M-s" "Step one source line with display")
  118. (def-dbx "stepi"  "\M-i" "Step one instruction with display")
  119. (def-dbx "next"   "\M-n" "Step one source line (skip functions)")
  120. (def-dbx "cont"   "\M-c" "Continue with display")
  121.  
  122. (def-dbx "quit!" "\C-c\C-f" "Finish executing current function")
  123. (def-dbx "up"     "\M-u"   "Go up N stack frames (numeric arg) with display")
  124. (def-dbx "down"   "\M-d"   "Go down N stack frames (numeric arg) with display")
  125.  
  126. (defun dbx-mode ()
  127.   "Major mode for interacting with an child Dbx process.
  128. The following commands are available:
  129.  
  130. \\{dbx-mode-map}
  131.  
  132. \\[dbx-display-frame] displays in the other window
  133. the last line referred to in the dbx buffer.
  134.  
  135. \\[dbx-step],\\[dbx-next], and \\[dbx-nexti] in the dbx window,
  136. call dbx to step,next or nexti and then update the other window
  137. with the current file and position.
  138.  
  139. If you are in a source file, you may select a point to break
  140. at, by doing \\[dbx-break].
  141.  
  142. Commands:
  143. Many commands are inherited from shell mode.
  144. Additionally we have:
  145.  
  146. \\[dbx-display-frame] display frames file in other window
  147. \\[dbx-step] advance one line in program
  148. \\[dbx-next] advance one line in program (skip over calls).
  149. \\[send-dbx-command] used for special printing of an arg at the current point.
  150. C-x SPACE sets break point at current line."
  151.   (interactive)
  152.   (kill-all-local-variables)
  153.   (setq major-mode 'dbx-mode)
  154.   (setq mode-name "Child Dbx")
  155.   (setq mode-line-process '(": %s"))
  156.   (use-local-map dbx-mode-map)
  157.   (make-local-variable 'last-input-start)
  158.   (setq last-input-start (make-marker))
  159.   (make-local-variable 'last-input-end)
  160.   (setq last-input-end (make-marker))
  161.   (make-local-variable 'dbx-last-frame)
  162.   (setq dbx-last-frame nil)
  163.   (make-local-variable 'dbx-last-frame-displayed-p)
  164.   (setq dbx-last-frame-displayed-p t)
  165.   (make-local-variable 'dbx-delete-prompt-marker)
  166.   (setq dbx-delete-prompt-marker nil)
  167.   (make-local-variable 'dbx-filter-accumulator)
  168.   (setq dbx-filter-accumulator nil)
  169.   (make-local-variable 'shell-prompt-pattern)
  170.   (setq shell-prompt-pattern dbx-prompt-pattern)
  171.   (run-hooks 'shell-mode-hook 'dbx-mode-hook))
  172.  
  173. (defvar current-dbx-buffer nil)
  174.  
  175. (defvar dbx-command-name "dbx"
  176.   "Pathname for executing dbx.")
  177.  
  178. (defun dbx (path &optional dbxargs)
  179.   "Run dbx on program FILE in buffer *dbx-FILE*.
  180. The directory containing FILE becomes the initial working directory
  181. and source-file directory for DBX.  If you wish to change this, use
  182. the DBX commands `cd DIR' and `directory'."
  183.   (interactive "FRun dbx on file: ")
  184.   (setq path (expand-file-name path))
  185.   (let ((file (file-name-nondirectory path)))
  186.     (switch-to-buffer (concat "*dbx-" file "*"))
  187.     (setq default-directory (file-name-directory path))
  188.     (or (bolp) (newline))
  189.     (insert "Current directory is " default-directory "\n")
  190.     (if dbxargs
  191.     (make-shell (concat "dbx-" file) dbx-command-name nil "-emacs" dbxargs file)
  192.       (make-shell (concat "dbx-" file) dbx-command-name nil "-emacs" file))
  193.     (dbx-mode)
  194.     (set-process-filter (get-buffer-process (current-buffer)) 'dbx-filter)
  195.     (set-process-sentinel (get-buffer-process (current-buffer)) 'dbx-sentinel)
  196.     (dbx-set-buffer)))
  197.  
  198. (defun dbx-set-buffer ()
  199.   (cond ((eq major-mode 'dbx-mode)
  200.     (setq current-dbx-buffer (current-buffer)))))
  201.  
  202. ;; This function is responsible for inserting output from DBX
  203. ;; into the buffer.
  204. ;; Aside from inserting the text, it notices and deletes
  205. ;; each filename-and-line-number;
  206. ;; that DBX prints to identify the selected frame.
  207. ;; It records the filename and line number, and maybe displays that file.
  208. (defun dbx-filter (proc string)
  209.   (let ((inhibit-quit t))
  210.     (if dbx-filter-accumulator
  211.     (dbx-filter-accumulate-marker proc
  212.                       (concat dbx-filter-accumulator string))
  213.     (dbx-filter-scan-input proc string))))
  214.  
  215. (defun dbx-filter-accumulate-marker (proc string)
  216.   (setq dbx-filter-accumulator nil)
  217.   (if (> (length string) 1)
  218.       (if (= (aref string 1) ?\032)
  219.       (let ((end (string-match "\n" string)))
  220.         (if end
  221.         (progn
  222.           (let* ((first-colon (string-match ":" string 2))
  223.              (second-colon
  224.               (string-match ":" string (1+ first-colon))))
  225.             (setq dbx-last-frame
  226.               (cons (substring string 2 first-colon)
  227.                 (cons (string-to-int
  228.                      (substring string (1+ first-colon)
  229.                         second-colon))
  230.                       (string-to-int
  231.                      (substring string (1+ second-colon)
  232.                         end))))))
  233.           (setq dbx-last-frame-displayed-p nil)
  234.           (dbx-filter-scan-input proc
  235.                      (substring string (1+ end))))
  236.           (setq dbx-filter-accumulator string)))
  237.     (dbx-filter-insert proc "\032")
  238.     (dbx-filter-scan-input proc (substring string 1)))
  239.     (setq dbx-filter-accumulator string)))
  240.  
  241. (defun dbx-filter-scan-input (proc string)
  242.   (if (equal string "")
  243.       (setq dbx-filter-accumulator nil)
  244.       (let ((start (string-match "\032" string)))
  245.     (if start
  246.         (progn (dbx-filter-insert proc (substring string 0 start))
  247.            (dbx-filter-accumulate-marker proc
  248.                          (substring string start)))
  249.         (dbx-filter-insert proc string)))))
  250.  
  251. (defun dbx-filter-insert (proc string)
  252.   (let ((moving (= (point) (process-mark proc)))
  253.     (output-after-point (< (point) (process-mark proc)))
  254.     (old-buffer (current-buffer))
  255.     start)
  256.     (set-buffer (process-buffer proc))
  257.     (unwind-protect
  258.     (save-excursion
  259.       ;; Insert the text, moving the process-marker.
  260.       (goto-char (process-mark proc))
  261.       (setq start (point))
  262.       (insert string)
  263.       (set-marker (process-mark proc) (point))
  264.       (dbx-maybe-delete-prompt)
  265.       ;; Check for a filename-and-line number.
  266.       (dbx-display-frame
  267.        ;; Don't display the specified file
  268.        ;; unless (1) point is at or after the position where output appears
  269.        ;; and (2) this buffer is on the screen.
  270.        (or output-after-point
  271.            (not (get-buffer-window (current-buffer))))
  272.        ;; Display a file only when a new filename-and-line-number appears.
  273.        t))
  274.       (set-buffer old-buffer))
  275.     (if moving (goto-char (process-mark proc)))))
  276.  
  277. (defun dbx-sentinel (proc msg)
  278.   (cond ((null (buffer-name (process-buffer proc)))
  279.      ;; buffer killed
  280.      ;; Stop displaying an arrow in a source file.
  281.      (setq overlay-arrow-position nil)
  282.      (set-process-buffer proc nil))
  283.     ((memq (process-status proc) '(signal exit))
  284.      ;; Stop displaying an arrow in a source file.
  285.      (setq overlay-arrow-position nil)
  286.      ;; Fix the mode line.
  287.      (setq mode-line-process
  288.            (concat ": "
  289.                (symbol-name (process-status proc))))
  290.      (let* ((obuf (current-buffer)))
  291.        ;; save-excursion isn't the right thing if
  292.        ;;  process-buffer is current-buffer
  293.        (unwind-protect
  294.            (progn
  295.          ;; Write something in *compilation* and hack its mode line,
  296.          (set-buffer (process-buffer proc))
  297.          ;; Force mode line redisplay soon
  298.          (set-buffer-modified-p (buffer-modified-p))
  299.          (if (eobp)
  300.              (insert ?\n mode-name " " msg)
  301.            (save-excursion
  302.              (goto-char (point-max))
  303.              (insert ?\n mode-name " " msg)))
  304.          ;; If buffer and mode line will show that the process
  305.          ;; is dead, we can delete it now.  Otherwise it
  306.          ;; will stay around until M-x list-processes.
  307.          (delete-process proc))
  308.          ;; Restore old buffer, but don't restore old point
  309.          ;; if obuf is the dbx buffer.
  310.          (set-buffer obuf))))))
  311.  
  312.  
  313. (defun dbx-refresh ()
  314.   "Fix up a possibly garbled display, and redraw the arrow."
  315.   (interactive)
  316.   (redraw-display)
  317.   (dbx-display-frame))
  318.  
  319. (defun dbx-display-frame (&optional nodisplay noauto)
  320.   "Find, obey and delete the last filename-and-line marker from DBX.
  321. The marker looks like \\032\\032FILENAME:LINE:CHARPOS\\n.
  322. Obeying it means displaying in another window the specified file and line."
  323.   (interactive)
  324.   (dbx-set-buffer)
  325.   (and dbx-last-frame (not nodisplay)
  326.        (or (not dbx-last-frame-displayed-p) (not noauto))
  327.        (progn (dbx-display-line (car dbx-last-frame)
  328.                        (car (cdr dbx-last-frame))
  329.                 (cdr (cdr dbx-last-frame)))
  330.           (setq dbx-last-frame-displayed-p t))))
  331.  
  332. ;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
  333. ;; and that its line LINE is visible.
  334. ;; Put the overlay-arrow on the line LINE in that buffer.
  335.  
  336. (defun dbx-display-line (true-file line chpos)
  337.   (let* ((buffer (find-file-noselect true-file))
  338.      (window (display-buffer buffer t))
  339.      (pos))
  340.     (save-excursion
  341.       (set-buffer buffer)
  342.       (save-restriction
  343.     (widen)
  344.     (goto-line line)
  345.     (setq pos (point))
  346.     (cond ((not (= chpos 0)) (setq overlay-arrow-string "=>"))
  347.           (t (setq overlay-arrow-string "")))
  348.     (or overlay-arrow-position
  349.         (setq overlay-arrow-position (make-marker)))
  350.     (set-marker overlay-arrow-position (point) (current-buffer)))
  351.       (cond ((or (< pos (point-min)) (> pos (point-max)))
  352.          (widen)
  353.          (goto-char pos))))
  354.     (set-window-point window overlay-arrow-position)))
  355.  
  356. (defun dbx-call (command)
  357.   "Invoke dbx COMMAND displaying source in other window."
  358.   (interactive)
  359.   (goto-char (point-max))
  360.   (setq dbx-delete-prompt-marker (point-marker))
  361.   (dbx-set-buffer)
  362.   (send-string (get-buffer-process current-dbx-buffer)
  363.            (concat command "\n")))
  364.  
  365. (defun dbx-maybe-delete-prompt ()
  366.   (if (and dbx-delete-prompt-marker
  367.        (> (point-max) (marker-position dbx-delete-prompt-marker)))
  368.       (let (start)
  369.     (goto-char dbx-delete-prompt-marker)
  370.     (setq start (point))
  371.     (beginning-of-line)
  372.     (delete-region (point) start)
  373.     (setq dbx-delete-prompt-marker nil))))
  374.  
  375. (defun dbx-break ()
  376.   "Set DBX breakpoint at this source line."
  377.   (interactive)
  378.   (let ((file-name (file-name-nondirectory buffer-file-name))
  379.     (line (save-restriction
  380.         (widen)
  381.         (1+ (count-lines 1 (point))))))
  382.     (send-string (get-buffer-process current-dbx-buffer)
  383.          (concat "stop at \"" file-name "\":" line "\n"))))
  384.  
  385. (defun dbx-read-address()
  386.   "Return a string containing the core-address found in the buffer at point."
  387.   (save-excursion
  388.    (let ((pt (dot)) found begin)
  389.      (setq found (if (search-backward "0x" (- pt 7) t)(dot)))
  390.      (cond (found (forward-char 2)(setq result
  391.             (buffer-substring found
  392.                  (progn (re-search-forward "[^0-9a-f]")
  393.                     (forward-char -1)
  394.                     (dot)))))
  395.        (t (setq begin (progn (re-search-backward "[^0-9]") (forward-char 1)
  396.                  (dot)))
  397.           (forward-char 1)
  398.           (re-search-forward "[^0-9]")
  399.           (forward-char -1)
  400.           (buffer-substring begin (dot)))))))
  401.  
  402.  
  403. (defvar dbx-commands nil
  404.   "List of strings or functions used by send-dbx-command.
  405. It is for customization by you.")
  406.  
  407. (defun send-dbx-command (arg)
  408.  
  409.   "This command reads the number where the cursor is positioned.  It
  410.  then inserts this ADDR at the end of the dbx buffer.  A numeric arg
  411.  selects the ARG'th member COMMAND of the list dbx-print-command.  If
  412.  COMMAND is a string, (format COMMAND ADDR) is inserted, otherwise
  413.  (funcall COMMAND ADDR) is inserted.  eg. \"p (rtx)%s->fld[0].rtint\"
  414.  is a possible string to be a member of dbx-commands.  "
  415.  
  416.  
  417.   (interactive "P")
  418.   (let (comm addr)
  419.     (if arg (setq comm (nth arg dbx-commands)))
  420.     (setq addr (dbx-read-address))
  421.     (if (eq (current-buffer) current-dbx-buffer)
  422.     (set-mark (point)))
  423.     (cond (comm
  424.        (setq comm
  425.          (if (stringp comm) (format comm addr) (funcall comm addr))))
  426.       (t (setq comm addr)))
  427.     (switch-to-buffer current-dbx-buffer)
  428.     (goto-char (dot-max))
  429.     (insert-string comm)))
  430.  
  431. --
  432. ------
  433. Egil Pedersen (egilp@mizar.sds.no) Tel: +47 2 95 68 99 Fax: +47 2 35 40 13
  434. Statens Datasentral a.s (Norwegian Government Computer Centre)
  435. Postboks 6664 Rodelokka, N-0502 Oslo, Norway
  436.