home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / emacs / 3816 < prev    next >
Encoding:
Text File  |  1992-12-17  |  19.6 KB  |  597 lines

  1. Path: sparky!uunet!dtix!mimsy!lhc!lhc!warsaw
  2. From: warsaw@nlm.nih.gov (Barry A. Warsaw)
  3. Newsgroups: comp.emacs
  4. Subject: Re: comint.el + gdb.el = ?
  5. Message-ID: <WARSAW.92Dec17123915@anthem.nlm.nih.gov>
  6. Date: 17 Dec 92 17:39:15 GMT
  7. References: <IK.92Dec16181247@puffin.ctt.bellcore.com>
  8. Sender: news@nlm.nih.gov
  9. Reply-To: warsaw@nlm.nih.gov (Barry A. Warsaw)
  10. Distribution: usa
  11. Organization: Century Computing, Inc.
  12. Lines: 582
  13. In-Reply-To: ik@puffin.ctt.bellcore.com's message of 17 Dec 92 02:12:47 GMT
  14.  
  15.  
  16.     Ik> Has anyone successfully modified gdb mode to use comint.el
  17.     Ik> instead of shell.el? Thanks.  --
  18.  
  19. What you want is gud.el.  GUD-mode stands for Grand Unified Debugger
  20. and is able to run sdb, dbx, or gdb as its underlying debugger. It
  21. uses comint.  I've been using it for months and I love it.  I don't
  22. think its ever been posted but since its such a phenomimal package, I
  23. suppose I'll do the honors.
  24.  
  25. This was originally written by Eric Raymond <eric@thyrsus.com>. I've
  26. made a few modifications since the last version Eric sent me.
  27.  
  28. -Barry
  29.  
  30. -------------------- snip snip --------------------
  31. ;; Grand Unified Debugger mode --- run gdb, sdb, dbx under Emacs control
  32. ;;    @(#)gud.el    1.8a
  33.  
  34. ;; MODIFICATIONS:
  35. ;;  4-Dec-1992 bwarsaw@cen.com
  36. ;; * Added gud-<debugger>-exec variables so we can redefine the
  37. ;;   underlying debugger executable.
  38. ;; * Added a provide at the end of the file
  39. ;; * Cosmetic cleanups in file
  40.  
  41. ;; This file is part of GNU Emacs.
  42.  
  43. ;; GNU Emacs is free software; you can redistribute it and/or modify
  44. ;; it under the terms of the GNU General Public License as published by
  45. ;; the Free Software Foundation; either version 1, or (at your option)
  46. ;; any later version.
  47.  
  48. ;; GNU Emacs is distributed in the hope that it will be useful,
  49. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  50. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  51. ;; GNU General Public License for more details.
  52.  
  53. ;; You should have received a copy of the GNU General Public License
  54. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  55. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  56.  
  57. ;; The ancestral gdb.el was by W. Schelter <wfs@rascal.ics.utexas.edu>
  58. ;; It was later ewritten by rms.  Some ideas were due to Masanobu. 
  59. ;; Grand Unification (sdb/dbx support) by Eric S. Raymond <eric@thyrsus.com>
  60. ;; The overloading code was then rewritten by Barry Warsaw <bwarsaw@cen.com>,
  61. ;; who also hacked the mode to use comint.el.
  62.  
  63. ;; Note: use of this package with sdb requires that your tags.el support
  64. ;; the find-tag-noselect entry point.  Stock distributions up to 18.57 do 
  65. ;; *not* include this feature; if it's not included with this file, email
  66. ;; eric@snark.thyrsus.com for it or get 18.58.
  67.  
  68. (require 'comint)
  69. (require 'tags)
  70.  
  71.  
  72. ;; user definable variables
  73. ;; vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  74.  
  75. (defvar gud-gdb-exec "gdb" "*Name of gdb executable.")
  76. (defvar gud-sdb-exec "sdb" "*Name of sdb executable.")
  77. (defvar gud-dbx-exec "dbx" "*Name of dbx executable.")
  78.  
  79. ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  80. ;; end of user definable variables
  81.  
  82. (defvar gud-last-frame nil
  83.   "Global variable which holds the last gud frame.")
  84.  
  85.  
  86. ;; the overloading mechanism
  87. (defun gud-overload-functions (gud-overload-alist)
  88.   "Overload functions defined in GUD-OVERLOAD-ALIST.
  89. This association list has elements of the form
  90.  
  91.      (ORIGINAL-FUNCTION-NAME  OVERLOAD-FUNCTION)"
  92.   (let ((binding nil)
  93.     (overloads gud-overload-alist))
  94.     (while overloads
  95.       (setq binding (car overloads)
  96.         overloads (cdr overloads))
  97.       (fset (car binding) (symbol-function (car (cdr binding))))
  98.       )))
  99.  
  100. (defun gud-debugger-startup (f d)
  101.   (error "GUD not properly entered."))
  102.  
  103. (defun gud-marker-filter (proc s)
  104.   (error "GUD not properly entered."))
  105.  
  106. (defun gud-visit-file (f)
  107.   (error "GUD not properly entered."))
  108.  
  109. (defun gud-set-break (proc f n)
  110.   (error "GUD not properly entered."))
  111.  
  112. ;; This macro is used below to define some basic debugger interface commands.
  113. ;; Of course you may use `gud-def' with any other debugger command, including
  114. ;; user defined ones.   
  115.  
  116. (defmacro gud-def (name key &optional doc)
  117.   (let ((func    (format "gud-%s" name))
  118.     (funcell (list 'lambda '(arg)
  119.                (or doc "")
  120.                '(interactive "p")
  121.                (list 'gud-call
  122.                  (list 'if '(not (= 1 arg))
  123.                    (list 'format "%s %s" name 'arg) name)))))
  124.     (list 'let (list (list 'sym (list 'intern func)))
  125.       (list 'fset 'sym (list 'function funcell))
  126.       (list 'define-key 'gud-mode-map key 'sym))))
  127.  
  128.  
  129.  
  130. ;; All debugger-specific information is collected here
  131. ;; Here's how it works, in case you ever need to add a debugger to the table.
  132. ;;
  133. ;; Each entry must define the following at startup:
  134. ;;
  135. ;;<name>
  136. ;; comint-prompt-regexp
  137. ;; gud-<name>-startup-command
  138. ;; gud-<name>-marker-filter
  139. ;; gud-<name>-file-visit
  140. ;; gud-<name>-set-break
  141. ;;
  142.  
  143.  
  144.  
  145. ;; gdb functions
  146. (defun gud-gdb-debugger-startup (f d)
  147.   (make-comint (concat "gud-" f) gud-gdb-exec nil "-fullname" "-cd" d f))
  148.  
  149. (defun gud-gdb-marker-filter (proc s)
  150.   (if (string-match  "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n" s)
  151.       (setq gud-last-frame
  152.         (cons
  153.          (substring string (match-beginning 1) (match-end 1))
  154.          (string-to-int
  155.           (substring string (match-beginning 2) (match-end 2))))))
  156.   string)
  157.  
  158. (defun gud-gdb-visit-file (f)
  159.   (find-file-noselect f))
  160.  
  161. (defun gud-gdb-set-break (proc f n) 
  162.   (gud-call "break %s:%d" f n))
  163.  
  164. (defun gdb (path)
  165.   "Run gdb on program FILE in buffer *gud-FILE*.
  166. The directory containing FILE becomes the initial working directory
  167. and source-file directory for your debugger."
  168.   (interactive "FRun gdb on file: ")
  169.   (gud-overload-functions '((gud-debugger-startup gud-gdb-debugger-startup)
  170.                 (gud-marker-filter    gud-gdb-marker-filter)
  171.                 (gud-visit-file       gud-gdb-visit-file)
  172.                 (gud-set-break        gud-gdb-set-break)))
  173.  
  174.   (gud-def "step"  "\C-cs" "Step one source line with display")
  175.   (gud-def "stepi" "\C-ci" "Step one instruction with display")
  176.   (gud-def "next"  "\C-cn" "Step one line (skip functions)")
  177.   (gud-def "cont"  "\C-cc" "Continue with display")
  178.  
  179.   (gud-def "finish" "\C-c\C-f" "Finish executing current function")
  180.   (gud-def "up"     "\C-cu"    "Up N stack frames (numeric arg)")
  181.   (gud-def "down"   "\C-cd"    "Down N stack frames (numeric arg)")
  182.  
  183.   (gud-common-init path)
  184.  
  185.   (setq comint-prompt-regexp "^(.*gdb[+]?) *")
  186.   (run-hooks 'gdb-mode-hook)
  187.   )
  188.  
  189.  
  190.  
  191. ;; sdb functions
  192. (defun gud-sdb-debugger-startup (f d)
  193.   (make-comint (concat "gud-" f) gud-sdb-exec nil f "-" d))
  194.  
  195. (defun gud-sdb-marker-filter (proc str)
  196.   (if (string-match "\\(^0x\\w* in \\|^\\|\n\\)\\([^:\n]*\\):\\([0-9]*\\):.*\n"
  197.             str)
  198.       (setq gud-last-frame
  199.         (cons
  200.          (substring string (match-beginning 2) (match-end 2))
  201.          (string-to-int 
  202.           (substring string (match-beginning 3) (match-end 3))))))
  203.   string)
  204.  
  205. (defun gud-sdb-visit-file (f)
  206.   (find-tag-noselect f t))
  207.  
  208. (defun gud-sdb-set-break (proc f n)
  209.   (gud-queue-send (format "e %s" f) (format "%d b" n)))
  210.  
  211. (defun sdb (path)
  212.   "Run sdb on program FILE in buffer *gud-FILE*.
  213. The directory containing FILE becomes the initial working directory
  214. and source-file directory for your debugger."
  215.   (if (not (and (boundp 'tags-file-name) (file-exists-p tags-file-name)))
  216.       (error "The sdb support requires a valid tags table to work."))
  217.   (interactive "FRun sdb on file: ")
  218.   (gud-overload-functions '((gud-debugger-startup gud-sdb-debugger-startup)
  219.                 (gud-marker-filter    gud-sdb-marker-filter)
  220.                 (gud-visit-file       gud-sdb-visit-file)
  221.                 (gud-set-break        gud-sdb-set-break)))
  222.  
  223.   (gud-def "s" "\C-cs" "Step one source line with display")
  224.   (gud-def "i" "\C-ci" "Step one instruction with display")
  225.   (gud-def "S" "\C-cn" "Step one source line (skip functions)")
  226.   (gud-def "c" "\C-cc" "Continue with display")
  227.  
  228.   (gud-common-init path)
  229.  
  230.   (setq comint-prompt-pattern  "\\(^\\|\n\\)\\*")
  231.   (run-hooks 'sdb-mode-hook)
  232.   )
  233.  
  234.  
  235.  
  236. ;; dbx functions
  237. (defun gud-dbx-debugger-startup (f d)
  238.   (make-comint (concat "gud-" file) gud-dbx-exec nil f))
  239.  
  240. (defun gud-dbx-marker-filter (proc str)
  241.   (if (string-match
  242.        "stopped in .* at line \\([0-9]*\\) in file \"\\([^\"]*\\)\"" str)
  243.       (setq gud-last-frame
  244.         (cons
  245.          (substring string (match-beginning 2) (match-end 2))
  246.          (string-to-int 
  247.           (substring string (match-beginning 1) (match-end 1))))))
  248.   string)
  249.  
  250. (defun gud-dbx-visit-file (f)
  251.   (find-file-noselect f))
  252.  
  253. (defun gud-dbx-set-break (proc f n)
  254.   (gud-call "stop at \"%s\":%d" f n))
  255.  
  256. (defun dbx (path)
  257.   "Run dbx on program FILE in buffer *gud-FILE*.
  258. The directory containing FILE becomes the initial working directory
  259. and source-file directory for your debugger."
  260.   (interactive "FRun dbx on file: ")
  261.   (gud-overload-functions '((gud-debugger-startup gud-dbx-debugger-startup)
  262.                 (gud-marker-filter    gud-dbx-marker-filter)
  263.                 (gud-visit-file       gud-dbx-visit-file)
  264.                 (gud-set-break        gud-dbx-set-break)))
  265.  
  266.   (gud-def "step"  "\C-cs" "Step one source line with display")
  267.   (gud-def "next"  "\C-cn" "Step one line (skip functions)")
  268.   (gud-def "cont"  "\C-cc" "Continue with display")
  269.  
  270.   (gud-def "where"  "\C-cw" "Print stack trace")
  271.   (gud-def "up"     "\C-cu" "Up N stack frames (numeric arg)")
  272.   (gud-def "down"   "\C-cd" "Down N stack frames (numeric arg)")
  273.  
  274.   (gud-common-init path)
  275.   (setq comint-prompt-regexp  "^[^)]*dbx) *")
  276.  
  277.   (run-hooks 'dbx-mode-hook)
  278.   )
  279.  
  280.  
  281.  
  282. ;; The job of the debugger-startup method is to fire up a copy of the debugger,
  283. ;; given an object file and source directory.
  284. ;;
  285. ;; The job of the marker-filter method is to detect file/line markers in
  286. ;; strings and set the global gud-last-frame to indicate what display
  287. ;; action (if any) should be triggered by the marker
  288. ;;
  289. ;; The job of the visit-file method is to visit and return the buffer indicated
  290. ;; by the car of gud-tag-frame.  This may be a file name, a tag name, or
  291. ;; something else.
  292. ;;
  293. ;; The job of the gud-set-break method is to send the commands necessary
  294. ;; to set a breakpoint at a given line in a given source file.
  295. ;;
  296. ;; End of debugger-specific information
  297.  
  298. (defvar gud-mode-map nil
  299.   "Keymap for gud-mode.")
  300.  
  301. (defvar gud-command-queue nil)
  302.  
  303. (if gud-mode-map
  304.    nil
  305.   (setq gud-mode-map (copy-keymap comint-mode-map))
  306.   (define-key gud-mode-map "\C-l" 'gud-refresh))
  307.  
  308. (define-key ctl-x-map " " 'gud-break)
  309. (define-key ctl-x-map "&" 'send-gud-command)
  310.  
  311.  
  312.  
  313. (defun gud-mode ()
  314.   "Major mode for interacting with an inferior debugger process.
  315. The following commands are available:
  316.  
  317. \\{gud-mode-map}
  318.  
  319. \\[gud-display-frame] displays in the other window
  320. the last line referred to in the gud buffer.
  321.  
  322. \\[gud-step],\\[gud-next], and \\[gud-nexti] in the gud window,
  323. do a step-one-line, step-one-line (not entering function calls), and 
  324. step-one-instruction and then update the other window
  325. with the current file and position.  \\[gud-cont] continues
  326. execution.
  327.  
  328. If you are in a source file, you may set a breakpoint at the current
  329. line in the current source file by doing \\[gud-break].
  330.  
  331. Commands:
  332. Many commands are inherited from comint mode. 
  333. Additionally we have:
  334.  
  335. \\[gud-display-frame] display frames file in other window
  336. \\[gud-step] advance one line in program
  337. \\[gud-next] advance one line in program (skip over calls).
  338. \\[send-gud-command] used for special printing of an arg at the current point.
  339. C-x SPACE sets break point at current line."
  340.   (interactive)
  341.   (comint-mode)
  342. ; (kill-all-local-variables)
  343.   (setq major-mode 'gud-mode)
  344.   (setq mode-name "Debugger")
  345.   (setq mode-line-process '(": %s"))
  346.   (use-local-map gud-mode-map)
  347.   (make-local-variable 'gud-last-frame)
  348.   (setq gud-last-frame nil)
  349. ; (make-local-variable 'gud-delete-prompt-marker)
  350. ; (setq gud-delete-prompt-marker nil)
  351.   (make-local-variable 'comint-prompt-regexp)
  352.   (run-hooks 'gud-mode-hook)
  353. )
  354.  
  355. (defvar current-gud-buffer nil)
  356.  
  357. (defun gud-common-init (path)
  358.   ;; perform initializations common to all debuggers
  359.   (setq path (expand-file-name path))
  360.   (let ((file (file-name-nondirectory path)))
  361.     (switch-to-buffer (concat "*gud-" file "*"))
  362.     (setq default-directory (file-name-directory path))
  363.     (or (bolp) (newline))
  364.     (insert "Current directory is " default-directory "\n")
  365.     (gud-debugger-startup file default-directory))
  366.   (gud-mode)
  367.   (set-process-filter (get-buffer-process (current-buffer)) 'gud-filter)
  368.   (set-process-sentinel (get-buffer-process (current-buffer)) 'gud-sentinel)
  369.   (setq gud-command-queue nil)
  370.   (gud-set-buffer)
  371.   )
  372.  
  373. (defun gud-set-buffer ()
  374.   (cond ((eq major-mode 'gud-mode)
  375.     (setq current-gud-buffer (current-buffer)))))
  376.  
  377.  
  378.  
  379. (defun gud-filter (proc string)
  380.   ;; This function is responsible for inserting output from your debugger
  381.   ;; into the buffer.  The hard work is done by the method that is
  382.   ;; the value of gud-marker-filter.
  383.   (let ((inhibit-quit t))
  384.     (gud-filter-insert proc (gud-marker-filter proc string))
  385.     ;; If we've got queued commands and we see a prompt, pop one and send it.
  386.     ;; In theory we should check that a prompt has been issued before sending
  387.     ;; queued commands.  In practice, command responses from the first through
  388.     ;; penultimate elements of a command sequence are short enough that we
  389.     ;; don't really have to bother.
  390.     (if gud-command-queue
  391.     (progn
  392.       (gud-call (car gud-command-queue))
  393.       (setq gud-command-queue (cdr gud-command-queue))
  394.       )
  395.       )))
  396.  
  397. (defun gud-filter-insert (proc string)
  398.   ;; Here's where the actual buffer insertion is done
  399.   (let ((moving (= (point) (process-mark proc)))
  400.     (output-after-point (< (point) (process-mark proc)))
  401.     (old-buffer (current-buffer))
  402.     start)
  403.     (set-buffer (process-buffer proc))
  404.     (unwind-protect
  405.     (save-excursion
  406.       ;; Insert the text, moving the process-marker.
  407.       (goto-char (process-mark proc))
  408.       (setq start (point))
  409.       (insert string)
  410.       (set-marker (process-mark proc) (point))
  411. ;      (gud-maybe-delete-prompt)
  412.       ;; Check for a filename-and-line number.
  413.       ;; Don't display the specified file
  414.       ;; unless (1) point is at or after the position where output appears
  415.       ;; and (2) this buffer is on the screen.
  416.       (if (and gud-last-frame (not output-after-point)
  417.           (get-buffer-window (current-buffer)))
  418.           (gud-display-frame))
  419.       )
  420.       (set-buffer old-buffer))
  421.     (if moving (goto-char (process-mark proc)))))
  422.  
  423. (defun gud-sentinel (proc msg)
  424.   (cond ((null (buffer-name (process-buffer proc)))
  425.      ;; buffer killed
  426.      ;; Stop displaying an arrow in a source file.
  427.      (setq overlay-arrow-position nil)
  428.      (set-process-buffer proc nil))
  429.     ((memq (process-status proc) '(signal exit))
  430.      ;; Stop displaying an arrow in a source file.
  431.      (setq overlay-arrow-position nil)
  432.      ;; Fix the mode line.
  433.      (setq mode-line-process
  434.            (concat ": "
  435.                (symbol-name (process-status proc))))
  436.      (let* ((obuf (current-buffer)))
  437.        ;; save-excursion isn't the right thing if
  438.        ;;  process-buffer is current-buffer
  439.        (unwind-protect
  440.            (progn
  441.          ;; Write something in *compilation* and hack its mode line,
  442.          (set-buffer (process-buffer proc))
  443.          ;; Force mode line redisplay soon
  444.          (set-buffer-modified-p (buffer-modified-p))
  445.          (if (eobp)
  446.              (insert ?\n mode-name " " msg)
  447.            (save-excursion
  448.              (goto-char (point-max))
  449.              (insert ?\n mode-name " " msg)))
  450.          ;; If buffer and mode line will show that the process
  451.          ;; is dead, we can delete it now.  Otherwise it
  452.          ;; will stay around until M-x list-processes.
  453.          (delete-process proc))
  454.          ;; Restore old buffer, but don't restore old point
  455.          ;; if obuf is the gud buffer.
  456.          (set-buffer obuf))))))
  457.  
  458.  
  459. (defun gud-refresh ()
  460.   "Fix up a possibly garbled display, and redraw the arrow."
  461.   (interactive)
  462.   (redraw-display)
  463.   (gud-display-frame))
  464.  
  465. (defun gud-display-frame ()
  466.   "Find and obey the last filename-and-line marker from the debugger.
  467. Obeying it means displaying in another window the specified file and line."
  468.   (interactive)
  469.   (if gud-last-frame
  470.    (progn 
  471.      (gud-set-buffer)
  472.      (gud-display-line (car gud-last-frame) (cdr gud-last-frame))
  473.      (setq gud-last-frame nil))))
  474.  
  475. ;; Make sure the file named TRUE-FILE is in a buffer that appears on the screen
  476. ;; and that its line LINE is visible.
  477. ;; Put the overlay-arrow on the line LINE in that buffer.
  478.  
  479. (defun gud-display-line (true-file line)
  480.   (let* ((buffer (gud-visit-file true-file))
  481.      (window (display-buffer buffer t))
  482.      (pos))
  483.     (save-excursion
  484.       (set-buffer buffer)
  485.       (save-restriction
  486.     (widen)
  487.     (goto-line line)
  488.     (setq pos (point))
  489.     (setq overlay-arrow-string "=>")
  490.     (or overlay-arrow-position
  491.         (setq overlay-arrow-position (make-marker)))
  492.     (set-marker overlay-arrow-position (point) (current-buffer)))
  493.       (cond ((or (< pos (point-min)) (> pos (point-max)))
  494.          (widen)
  495.          (goto-char pos))))
  496.     (set-window-point window overlay-arrow-position)))
  497.  
  498.  
  499.  
  500. (defun gud-call (command &rest args)
  501.   "Invoke the debugger COMMAND displaying source in other window."
  502.   (interactive)
  503. ; (setq gud-delete-prompt-marker (point-marker))
  504.   (gud-set-buffer)
  505.   (goto-char (point-max))
  506.   (let ((command (concat (apply 'format command args) "\n"))
  507.     (proc (get-buffer-process current-gud-buffer)))
  508.     (gud-filter-insert proc command)
  509.     (send-string proc command)
  510.     ))
  511.  
  512. (defun gud-queue-send (&rest cmdlist)
  513.   ;; Send the first command, queue the rest for send after successive
  514.   ;; send on subsequent prompts
  515.   (interactive)
  516.   (gud-call (car cmdlist))
  517.   (setq gud-command-queue (append gud-command-queue (cdr cmdlist))))
  518.  
  519. (defun gud-maybe-delete-prompt ()
  520.   (if (and gud-delete-prompt-marker
  521.        (> (point-max) (marker-position gud-delete-prompt-marker)))
  522.       (let (start)
  523.     (goto-char gud-delete-prompt-marker)
  524.     (setq start (point))
  525.     (beginning-of-line)
  526.     (delete-region (point) start)
  527.     (setq gud-delete-prompt-marker nil))))
  528.  
  529. (defun gud-apply-from-source (func)
  530.   ;; Apply a method from the gud buffer environment, passing it file and line.
  531.   ;; This is intended to be used for gud commands called from a source file.
  532.   (if (not buffer-file-name)
  533.       (error "There is no file associated with this buffer")) 
  534.   (let ((file (file-name-nondirectory buffer-file-name))
  535.     (line (save-restriction (widen) (1+ (count-lines 1 (point))))))
  536.     (save-excursion
  537.       (gud-set-buffer)
  538.       (funcall func
  539.            (get-buffer-process current-gud-buffer)
  540.            file
  541.            line)
  542.       )))
  543.  
  544. (defun gud-break ()
  545.   "Set breakpoint at this source line."
  546.   (interactive)
  547.   (gud-apply-from-source 'gud-set-break))
  548.  
  549. (defun gud-read-address()
  550.   "Return a string containing the core-address found in the buffer at point."
  551.   (save-excursion
  552.    (let ((pt (point)) found begin)
  553.      (setq found (if (search-backward "0x" (- pt 7) t) (point)))
  554.      (cond (found (forward-char 2)(setq result
  555.             (buffer-substring found
  556.                  (progn (re-search-forward "[^0-9a-f]")
  557.                     (forward-char -1)
  558.                     (point)))))
  559.        (t (setq begin (progn (re-search-backward "[^0-9]") (forward-char 1)
  560.                  (point)))
  561.           (forward-char 1)
  562.           (re-search-forward "[^0-9]")
  563.           (forward-char -1)
  564.           (buffer-substring begin (point)))))))
  565.  
  566.  
  567. (defvar gud-commands nil
  568.   "List of strings or functions used by send-gud-command.
  569. It is for customization by you.")
  570.  
  571. (defun send-gud-command (arg)
  572.  
  573.   "This command reads the number where the cursor is positioned.  It
  574.  then inserts this ADDR at the end of the debugger buffer.  A numeric arg
  575.  selects the ARG'th member COMMAND of the list gud-print-command.  If
  576.  COMMAND is a string, (format COMMAND ADDR) is inserted, otherwise
  577.  (funcall COMMAND ADDR) is inserted.  eg. \"p (rtx)%s->fld[0].rtint\"
  578.  is a possible string to be a member of gud-commands.  "
  579.  
  580.  
  581.   (interactive "P")
  582.   (let (comm addr)
  583.     (if arg (setq comm (nth arg gud-commands)))
  584.     (setq addr (gud-read-address))
  585.     (if (eq (current-buffer) current-gud-buffer)
  586.     (set-mark (point)))
  587.     (cond (comm
  588.        (setq comm
  589.          (if (stringp comm) (format comm addr) (funcall comm addr))))
  590.       (t (setq comm addr)))
  591.     (switch-to-buffer current-gud-buffer)
  592.     (goto-char (point-max))
  593.     (insert-string comm)))
  594.  
  595.  
  596. (provide 'gud)
  597.