Initial Commit
[packages] / xemacs-packages / jde / lisp / jde-jdb.el
1 ;;; jde-jdb.el -- Debugger mode for jdb.
2 ;; $Revision: 1.48 $ $Date: 2005/01/18 05:23:30 $ 
3
4 ;; Author: Paul Kinnucan <paulk@mathworks.com>x
5 ;; Maintainer: Paul Kinnucan
6 ;; Keywords: java, tools
7
8 ;; Copyright (C) 1997, 2000, 2001, 2002, 2003, 2004, 2005 Paul Kinnucan.
9
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, US
24 ;;; Commentary:
25
26 ;; This package interfaces emacs to jdb, the debugger
27 ;; distributed as part of JavaSoft's Java
28 ;; Development Kit (JDK).
29
30 ;; Please send bug reports and enhancement suggestions
31 ;; to Paul Kinnucan at <paulk@mathworks.com>
32
33 ;; See end of this file for change history.
34
35 ;;; Code:
36
37 (require 'jde-db)
38
39
40 ;; Thanks to "David J. Biesack" <sasdjb@unx.sas.com> for this function
41 ;; and its use in jde-db-marker-filter.
42 ;; Amended by "Patrick J. McNerthney" <pat@mcnerthney.com> to allow
43 ;; package names to begin with underscores.
44 (defun jde-jdb-make-qualified-class-name-regexp (class)
45   "Constructs a regular expression to extract a qualified class name from a jdb
46 breakpoint message."
47   (concat "\\(\\(\\(\\(\\w\\|[_]\\)*\\.\\)*\\)" class "\\)\\(\\b\\|\\$\\)"))
48
49
50 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
51 ;;                                                                            ;;
52 ;; jdb Debugger Commands                                                      ;;
53 ;;                                                                            ;;
54 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55
56 ;; Launch debuggee command
57
58
59 (defclass jde-jdb-cmd-launch (jde-db-cmd-launch) ()
60   "Asks jdb to launch a debuggee process.")
61
62 (defmethod jde-db-cmd-launch-buffer-name ((this jde-jdb-cmd-launch))
63   "Return the name of the buffer for this process. Descendant
64 classes should override this method to create a name that is appropriate
65 for the process being launched, e.g., an applet or application." nil)
66
67 (defmethod jde-db-cmd-launch-cmd-path ((this jde-jdb-cmd-launch))
68   "Return the path of the command to be used to launch the process. Descendant
69 classes should override this method to return a path appropriate to
70 the command to be used to launch the debuggee process, e.g., jdb or
71 appletviewer." nil)
72
73
74 (defmethod jde-db-cmd-launch-startup-cmds ((this jde-jdb-cmd-launch))
75   "Add commands to debugger's initial command queue. Derived classes
76 should override this method to specify commands that should be
77 executed immediately after the debugger starts, e.g., an initial
78 step command." nil)
79
80
81 (defmethod jde-db-cmd-init ((this jde-jdb-cmd-launch))
82   "The debugger invokes this method before executing the launch
83 command. Launch the debuggee process."
84   (let ((debugger (oref this debugger)))
85     (if (or
86          (not (slot-boundp debugger 'buffer))
87          (not (oref debugger :buffer))
88          (not (comint-check-proc (oref debugger :buffer))))
89         (let* ((debuggee  
90                 (oref debugger debuggee))
91                (source-directory default-directory)
92                (working-directory
93                 (jde-db-debugger-get-working-dir debugger))
94                (prog-args (jde-db-debugger-get-prog-args debugger))
95                (cmd-path (jde-db-cmd-launch-cmd-path this))
96                (command-string 
97                 (concat
98                  cmd-path " "
99                  (jde-run-make-arg-string prog-args) "\n\n")))
100
101         (oset debugger :buffer-name (jde-db-cmd-launch-buffer-name this))
102         (oset debugger :buffer (get-buffer-create (oref debugger :buffer-name)))
103
104         (jde-db-cmd-launch-startup-cmds this)
105
106         (oset debugger :path cmd-path)
107         (jde-db-jdb-start debugger prog-args command-string)
108
109         (let ((debuggee-status (oref debuggee status)))
110           (oset debuggee-status running-p t)
111           (oset debuggee-status stopped-p t)))
112     (progn
113       (message "An instance of %s is running." (oref this :buffer-name))        
114       (pop-to-buffer (oref this :buffer-name))))))
115
116 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-launch))
117   "Returns nil because jdb launches the debuggee application automatically
118 when it is started." nil)
119
120
121 ;; Launch application command
122
123 (defclass jde-jdb-cmd-launch-app (jde-jdb-cmd-launch 
124                                   jde-db-cmd-launch-app) ()
125   "Asks jdb to launch the debuggee application.")
126
127 (defmethod initialize-instance ((this jde-jdb-cmd-launch-app) &rest fields)
128   (call-next-method)
129   (oset this name "launch application in jdb debug mode"))
130
131 (defmethod jde-db-cmd-launch-cmd-path ((this jde-jdb-cmd-launch-app))
132   "Return the path of the jdb command."
133   (let* ((debugger (oref this :debugger)))
134     (oref debugger :path)))
135
136 (defmethod jde-db-cmd-launch-buffer-name ((this jde-jdb-cmd-launch-app))
137   (let* ((debugger (oref this :debugger))
138          (debuggee (oref debugger :debuggee))
139          (main-class (oref debuggee :main-class)))
140     (concat  "*debug"  main-class "*")))
141
142 (defmethod jde-db-cmd-launch-startup-cmds ((this jde-jdb-cmd-launch-app))
143   "If `jde-db-initial-step-p' is nonnil, add a step command to the
144 debugger's startup command queue." 
145   (if jde-db-initial-step-p
146       (let*  ((debugger (oref this debugger))
147               (step-cmd (oref (oref debugger cmd-set) step-into)))
148         (oset debugger next-cmd 
149                     (append (oref debugger next-cmd) (list step-cmd))))))
150
151
152 ;; Launch applet command
153
154 (defclass jde-jdb-cmd-launch-applet (jde-jdb-cmd-launch
155                                      jde-db-cmd-launch-applet) ()
156   "Asks jdb to launch the debuggee applet.")
157
158 (defmethod initialize-instance ((this jde-jdb-cmd-launch-applet) &rest fields)
159   (call-next-method)
160   (oset this name "launch applet in jdb debug mode"))
161
162 (defmethod jde-db-cmd-launch-cmd-path ((this jde-jdb-cmd-launch-applet))
163   "Return the path of the command to be used to launch the process. Descendant
164 classes should override this method to return a path appropriate to
165 the command to be used to launch the debuggee process, e.g., jdb or
166 appletviewer."
167   (let* ((debugger (oref this :debugger))
168          (jdb-path (oref debugger :path))
169          (jdb-dir (file-name-directory jdb-path)))
170     (expand-file-name "appletviewer" jdb-dir))) 
171
172 (defmethod jde-db-cmd-launch-buffer-name ((this jde-jdb-cmd-launch-applet))
173   (let* ((debugger (oref this :debugger))
174          (debuggee (oref debugger :debuggee))
175          (doc (oref debuggee :doc)))
176     (concat  "*debug"  (file-name-nondirectory doc) "*")))
177
178 (defmethod jde-db-cmd-launch-startup-cmds ((this jde-jdb-cmd-launch-applet))
179   "If `jde-db-initial-step-p' is nonnil, add a run command followed by a
180 step command to the debugger's startup command queue." 
181   (if jde-db-initial-step-p
182       (let*  ((debugger (oref this debugger))
183               (cmd-set (oref debugger cmd-set))
184               (run-cmd (oref cmd-set run))
185               (step-cmd (oref cmd-set step-into)))
186         (oset debugger next-cmd 
187                     (append 
188                      (oref debugger next-cmd) 
189                      (list run-cmd)
190                      (list step-cmd))))))
191
192
193
194 ;; Run command
195
196 (defclass jde-jdb-cmd-run (jde-db-cmd) ()
197   "Asks jdb to start the debuggee application.")
198
199 (defmethod initialize-instance ((this jde-jdb-cmd-run) &rest fields)
200   (call-next-method)
201   (oset this name "run"))
202
203 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-run))
204   "Creates command line for jdb run command."
205   "run")
206
207 ;; Cont command
208
209 (defclass jde-jdb-cmd-cont (jde-db-cmd) ()
210   "Asks jdb to continue the debuggee application from its current
211 stopping point.")
212
213 (defmethod initialize-instance ((this jde-jdb-cmd-cont) &rest fields)
214   (call-next-method)
215   (oset this name "cont"))
216
217 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-cont))
218   "Creates command line for jdb cont command."
219   "cont")
220
221 ;; Quit command
222
223 (defclass jde-jdb-cmd-quit (jde-db-cmd) ()
224   "Quit debugging the current application.")
225
226 (defmethod initialize-instance ((this jde-jdb-cmd-quit) &rest fields)
227   (call-next-method)
228   (oset this name "quit"))
229
230 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-quit))
231   "Creates command line for jdb quit command."
232   "quit")
233
234 ;; Step-over command
235
236 (defclass jde-jdb-cmd-step-over (jde-db-cmd) ()
237   "Step to the next line in the current frame.")
238
239 (defmethod initialize-instance ((this jde-jdb-cmd-step-over) &rest fields)
240   (call-next-method)
241   (oset this name "next"))
242
243 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-step-over))
244   "Creates command line for jdb step-over command."
245   "next")
246
247 ;; Step-into command
248
249 (defclass jde-jdb-cmd-step-into (jde-db-cmd) ()
250   "Step to the next line in the current program.")
251
252 (defmethod initialize-instance ((this jde-jdb-cmd-step-into) &rest fields)
253   (call-next-method)
254   (oset this name "step"))
255
256 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-step-into))
257   "Creates command line for jdb step-into command."
258   "step")
259
260 ;; Step-out command
261
262 (defclass jde-jdb-cmd-step-out (jde-db-cmd) ()
263   "Continue to the end of the current method.")
264
265 (defmethod initialize-instance ((this jde-jdb-cmd-step-out) &rest fields)
266   (call-next-method)
267   (oset this name "step up"))
268
269 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-step-out))
270   "Creates command line for jdb step-out command."
271   "step up")
272
273
274 ;; Up stack command
275
276 (defclass jde-jdb-cmd-up (jde-db-cmd) ()
277   "Move up one stack frame.")
278
279 (defmethod initialize-instance ((this jde-jdb-cmd-up) &rest fields)
280   (call-next-method)
281   (oset this name "up"))
282
283 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-up))
284   "Creates command line for jdb up command."
285   "up")
286
287 (defmethod jde-db-cmd-notify-response ((this jde-jdb-cmd-up) response)
288   "Invoked when the debugger responds to the command. RESPONSE
289 is the response. This method invokes the jdb where
290 command in order to position the debug pointer at the
291 current stack location."
292   ;; (jde-debug-where)
293   (let* ((jdb (oref this debugger))
294          (cmds (oref jdb cmd-set))
295          (cmd (oref cmds where)))
296     (jde-db-exec-cmd jdb cmd)))
297
298 ;; Down stack command
299
300 (defclass jde-jdb-cmd-down (jde-db-cmd) ()
301   "Move down one stack frame.")
302
303 (defmethod initialize-instance ((this jde-jdb-cmd-down) &rest fields)
304   (call-next-method)
305   (oset this name "down"))
306
307 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-down))
308   "Creates command line for jdb down command."
309   "down")
310
311 (defmethod jde-db-cmd-notify-response ((this jde-jdb-cmd-down) response)
312   "Invoked when the debugger responds to the command. RESPONSE
313 is the response. This method invokes the jdb where
314 command in order to position the debug pointer at the
315 current stack location."
316   ;;(jde-debug-where)
317   (let* ((jdb (oref this debugger))
318          (cmds (oref jdb cmd-set))
319          (cmd (oref cmds where)))
320     (jde-db-exec-cmd jdb cmd)))
321
322
323 ;; Where stack command
324
325 (defclass jde-jdb-cmd-where (jde-db-cmd) ()
326   "Point to current location on the stack.")
327
328 (defmethod initialize-instance ((this jde-jdb-cmd-where) &rest fields)
329   (call-next-method)
330   (oset this name "where"))
331
332 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-where))
333   "Creates command line for jdb where command."
334   "where")
335
336 (defmethod jde-db-cmd-notify-response ((this jde-jdb-cmd-where) output)
337 "Processes the output of the jdb where
338  command, which lists the current stack. An example of the output
339  is
340    
341       [1] jmath.LinearSystem$InnerClass.print (LinearSystem.java:36)
342       [2] jmath.LinearSystem.<init> (LinearSystem.java:52)
343       [3] jmath.Test.main (Test.java:38)
344    
345  This method positions the source line cursor at the position that
346  matches the current location of the debugger in the program's
347  stack (set by the jdb up and down stack commands)."
348   (let* ((jdb (oref this debugger))
349          (debuggee (oref jdb debuggee)))
350     ;; if the stack depth is not set default to 1
351     (if (string-equal "" (oref debuggee :stack-depth))
352         (oset debuggee :stack-depth "1"))
353     (if (string-match 
354          (concat "^  \\[" 
355                  (oref debuggee :stack-depth)
356                  "\\] .*(\\([^\$\n]*\\).*:\\([0-9]*[^[:digit:]]?[0-9]+\\))")
357          output)
358         (let ((marker (match-string 0 output))
359               (class (match-string 1 output))
360               (line-no (jde-jdb-string-to-int (match-string 2 output)))
361               (package ""))
362           
363           (if (equal ".java" (substring class -5))
364               (setq class (substring class 0 -5)))
365
366           ;; Extract package path from input.
367           (let ((case-fold-search nil)) ;; Make sure search is case-sensitive
368             (and (string-match (jde-jdb-make-qualified-class-name-regexp class) marker)
369                  (setq package
370                        (substring marker (match-beginning 2) (match-end 2)))))
371           (jde-db-set-debug-cursor 
372            (if package (concat package class) class)
373            (concat class ".java") line-no)))
374     output))
375
376 ;; Set Breakpoint command
377
378 (defclass jde-jdb-cmd-set-breakpoint (jde-db-cmd-breakpoint) ()
379   "Asks jdb to set the breakpoint specified by the
380 breakpoint field.")
381
382 (defmethod initialize-instance ((this jde-jdb-cmd-set-breakpoint) &rest fields)
383   (call-next-method)
384   (oset this name "stop at"))
385
386 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-set-breakpoint))
387   "Creates command line for jdb set breakpoint command."
388   (let* ((bps (oref this breakpoints))
389          (bp (car bps)))
390     (format "stop at %s:%d"  
391             (oref bp class)
392             (jde-db-breakpoint-get-line bp))))
393
394 (defmethod jde-db-cmd-notify-response ((this jde-jdb-cmd-set-breakpoint) output)
395   "Called when the debugger responds to the last set-breakpoint
396   command. Invokes `jde-db-mark-breakpoint-requested' on the breakpoint and
397 updates the breakpoint to `requested' status.  Removes the breakpoint
398 from the command's breakpoint list. If the list contains more
399 breakpoints, this method reissues the command on the next breakpoint
400 on the list."
401   ;; (message "set-bp resp <<%s>>" output)
402   (if (or
403        (string-match "Deferring breakpoint" output)
404        (string-match "Set breakpoint" output)
405        (string-match "Unable to set" output))
406       (let* ((bps (oref this breakpoints))
407              (bp (car bps)) file line)
408         (if (not (null bp))
409             (progn
410               (setq file (oref bp file))
411               (setq line (jde-db-breakpoint-get-line bp))
412               (if (string-match "Unable to set breakpoint" output)
413                   (jde-db-delete-breakpoint bp)
414                 (if (string-match "Unable to set deferred breakpoint" output)
415                     (if (jde-db-debuggee-running-p)
416                         (let* ((debugger (oref 'jde-db-debugger the-debugger))
417                                (bp-cmd
418                                 (oref (oref debugger cmd-set) clear-bp)))    
419                           (oset bp-cmd breakpoints (list bp))
420                           (jde-db-exec-cmd debugger bp-cmd))
421                       (jde-db-delete-breakpoint bp))
422                   (if (string-match "Deferring breakpoint" output)
423                       (progn
424                         (oset bp status 'requested)
425                         (jde-db-mark-breakpoint-requested file line))
426                     (if (string-match "Set breakpoint" output)
427                         (progn
428                           (oset bp status 'active)
429                           (jde-db-mark-breakpoint-active file line))))))
430               (setq bps (cdr bps))
431               (oset this breakpoints bps)
432               (if bps
433                   (let ((jdb (oref this debugger)))
434                     (jde-db-exec-cmd jdb this))))))))
435
436 ;; Clear Breakpoint command
437
438 (defclass jde-jdb-cmd-clear-breakpoint (jde-db-cmd-breakpoint) ()
439   "Asks jdb to clear the breakpoint specified by the 
440 breakpoint field.")
441
442 (defmethod initialize-instance ((this jde-jdb-cmd-clear-breakpoint) &rest fields)
443   (call-next-method)
444   (oset this name "clear"))
445
446 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-clear-breakpoint))
447   "Creates command line for jdb clear breakpoint command."
448   (let* ((bps (oref this breakpoints))
449          (bp (car bps)))
450     (format "clear %s:%d"  
451             (oref bp class)
452             (jde-db-breakpoint-get-line bp))))
453
454 (defmethod jde-db-cmd-notify-response ((this jde-jdb-cmd-clear-breakpoint) output)
455   "Called when the debugger responds to the last clear-breakpoint command.
456 Removes the breakpoint from the command's breakpoint list. If the list contains
457 more breakpoints, this method reissues the clear command on the next breakpoint
458 on the list."
459   (let* ((bps (oref this breakpoints))
460          (bp (car bps)))
461     (jde-db-delete-breakpoint bp)
462     (setq bps (cdr bps))
463     (oset this breakpoints bps)
464     (if bps
465         (let ((jdb (oref this debugger)))
466           (jde-db-exec-cmd jdb this)))))
467
468 ;; Print command
469 (defvar jde-jdb-cmd-print-history  nil)
470
471 (defclass jde-jdb-cmd-print (jde-db-cmd)
472   ((expr        :initarg :expr
473                 :type string
474                 :initform ""
475                 :documentation
476                 "Expression passed to jdb"))
477   "Asks jdb to print value of expression at point")
478
479 (defmethod initialize-instance ((this jde-jdb-cmd-print) &rest fields)
480   (call-next-method)
481   (oset this name "print")
482   (oset this expr ""))
483
484 (defmethod jde-db-cmd-init ((this jde-jdb-cmd-print))
485   "The debugger invokes this method before executing the 
486 command."
487   (oset this expr (read-from-minibuffer "expr: " (thing-at-point 'word)
488                                         nil nil 'jde-jdb-cmd-print-history)))
489
490 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-print))
491   "Creates a command line for jdb print command."
492   (format "%s %s"
493           (oref this name)
494           (oref this expr)))
495
496 ;; Dump command
497 (defclass jde-jdb-cmd-dump (jde-jdb-cmd-print) ()
498   "Asks jdb to print all object information of the expression at point")
499
500 (defmethod initialize-instance ((this jde-jdb-cmd-dump) &rest fields)
501   (call-next-method)
502   (oset this name "dump"))
503
504 ;; Eval command
505 (defclass jde-jdb-cmd-eval (jde-jdb-cmd-print) ()
506   "Ask jdb to evaluate the expression(Same as the print command)")
507
508 (defmethod initialize-instance ((this jde-jdb-cmd-eval) &rest fields)
509   (call-next-method)
510   (oset this name "eval"))
511
512 ;; Set command
513 (defclass jde-jdb-cmd-set-var (jde-jdb-cmd-print)
514   ((value :initarg :value
515           :type string
516           :initform "null"
517           :document
518           "Value to assign to the variable"))
519   "Ask jdb to assign new value to a field/variable/array element")
520
521 (defmethod initialize-instance ((this jde-jdb-cmd-set-var) &rest fields)
522   (call-next-method)
523   (oset this name "set"))
524
525 (defmethod jde-db-cmd-init ((this jde-jdb-cmd-set-var))
526   "The debugger invokes this method before executing the 
527 command."
528   (oset this expr (read-from-minibuffer "variable: " (thing-at-point 'word)
529                                         nil nil 'jde-jdb-cmd-print-history))
530   (oset this value (read-from-minibuffer "value: " nil
531                                         nil nil '(null))))
532
533 (defmethod jde-db-cmd-make-command-line ((this jde-jdb-cmd-set-var))
534   "Creates a command line for jdb print command."
535   (format "%s %s = %s"
536           (oref this name)
537           (oref this expr)
538           (oref this value)))
539
540 ;; Locals commands
541 (defclass jde-jdb-cmd-locals (jde-jdb-cmd-print) ()
542   "Ask jdb to print al local variables in current stack frame")
543
544 (defmethod initialize-instance ((this jde-jdb-cmd-locals) &rest fields)
545   (call-next-method)
546   (oset this name "locals"))
547
548 (defmethod jde-db-cmd-init ((this jde-jdb-cmd-locals))
549   "The debugger invokes this method before executing the 
550 command."
551   (oset this expr ""))
552
553 ;; jdb Command Set
554
555 (defclass jde-jdb-cmd-set (jde-db-cmd-set)
556   ((print :initarg :print
557           :type jde-jdb-cmd-print
558           :documentation
559           "Asks jdb to print the value of expression at point")
560    (dump :initarg :dump
561          :type jde-jdb-cmd-dump
562          :documentation
563          "Ask jdb to print all object information from the
564 expression at poing")
565    (eval :initarg :eval
566          :type jde-jdb-cmd-eval
567          :documentation
568          "Ask jdb to evaluate the expression at point")
569    (set-var :initarg :set-var
570             :type jde-jdb-cmd-set-var
571             :documentation
572             "Ask jdb to assign a new value to the expression at point")
573    (locals :initarg :locals
574          :type jde-jdb-cmd-locals
575          :documentation
576          "Ask jdb to print all local variables in current stack frame")
577    )
578   "Set of debugger commands implemented by jdb.")
579
580 (defmethod initialize-instance ((this jde-jdb-cmd-set) &rest fields)
581   "Construct jdb command set."
582   (call-next-method)
583   (let ((jdb (oref this debugger)))
584     (oset this launch-app
585           (jde-jdb-cmd-launch-app "launch" :debugger jdb))
586     (oset this launch-applet
587           (jde-jdb-cmd-launch-applet "launch" :debugger jdb))
588     (oset this run
589           (jde-jdb-cmd-run "run" :debugger jdb))
590     (oset this cont
591           (jde-jdb-cmd-cont "cont" :debugger jdb))
592     (oset this quit
593           (jde-jdb-cmd-quit "jdb quit" :debugger jdb))
594     (oset this step-over
595           (jde-jdb-cmd-step-over "jdb step-over cmd" :debugger jdb))
596     (oset this step-into
597           (jde-jdb-cmd-step-into "jdb step-into cmd" :debugger jdb))
598     (oset this step-out
599           (jde-jdb-cmd-step-out "jdb step-out cmd" :debugger jdb))
600     (oset this up
601           (jde-jdb-cmd-up "jdb up cmd" :debugger jdb))
602     (oset this down
603           (jde-jdb-cmd-down "jdb down cmd" :debugger jdb))
604     (oset this where
605           (jde-jdb-cmd-where "jdb where cmd" :debugger jdb))
606     (oset this set-bp 
607           (jde-jdb-cmd-set-breakpoint "jdb set breakpoint" :debugger jdb))
608     (oset this clear-bp
609           (jde-jdb-cmd-clear-breakpoint "jdb clear breakpoint" :debugger jdb))
610     (oset this print
611           (jde-jdb-cmd-print "jdb print cmd" :debugger jdb))
612     (oset this dump
613           (jde-jdb-cmd-dump "jdb dump cmd" :debugger jdb))
614     (oset this eval
615           (jde-jdb-cmd-eval "jdb eval cmd" :debugger jdb))
616     (oset this set-var
617           (jde-jdb-cmd-set-var "jdb set cmd" :debugger jdb))
618     (oset this locals
619           (jde-jdb-cmd-locals "jdb locals cmd" :debugger jdb))
620     ))
621
622 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
623 ;;                                                                            ;;
624 ;; jdb Breakpoint Listener                                                    ;;
625 ;;                                                                            ;;
626 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
627 (defclass jde-jdb-breakpoint-listener (jde-db-listener)
628   ((marker-regexp   :initarg :marker-regexp
629                     :type string
630                     :documentation 
631                     "Regular expression for parsing breakpoint messages.")
632    (class-index     :initarg :class-index
633                     :type integer
634                     :initform 3
635                     :documentation
636                     "Index of class name parsed by marker-regex")
637    (line-index      :initarg :line-index
638                     :type integer
639                     :initform 5
640                     :documentation
641                     "Index of line number parsed by marker-regex")
642    (noline-regexp   :initarg :noline-regexp
643                     :type string
644                     :documentation 
645                     "Regular expression for parsing breakpoint messages without line numbers.")
646    ;; There's no guarantee that Emacs will hand the filter the entire
647    ;; marker at once; it could be broken up across several strings.  We
648    ;; might even receive a big chunk with several markers in it.  If we
649    ;; receive a chunk of text which looks like it might contain the
650    ;; beginning of a marker, we save it here between calls to the
651    ;; filter.
652    (marker-acc      :initarg :marker-acc
653                     :type string
654                     :initform ""
655                     :documentation
656                     "Debug output accumulator")
657
658    )
659   "Handles jdb breakpoint events.")
660
661
662 (defmethod initialize-instance ((this jde-jdb-breakpoint-listener) &rest fields)
663   "Construct breakpoint listener."
664
665   (call-next-method)
666
667   ;; Regular expression used to find a jdb breakpoint position marker.
668   ;; The regular expression must have two subexpressions. The first matches
669   ;; the name of the class in which the breakpoint occurs; the second, the
670   ;; line number at which the breakpoint occurs. The default expression
671   ;; matches breakpoint messages emitted by jdb. You may need to change
672   ;; the expression to accommodate other debuggers."
673   (oset 
674    this
675    :marker-regexp
676    "^.*: thread=.*, \\(\\(.*[.]\\)*\\)\\([^\$]*\\)\\(\$.*\\)*[.].+(), line=\\([0-9,.]*\\),")
677   ;; Regular expression to match a breakpoint message that lacks a line
678   ;; number because the breakpoint occurs in a class compiled without deug
679   ;; information.
680   (oset 
681    this
682    :noline-regexp
683    "^Breakpoint hit: .*(pc \\([0-9]*\\))"))
684
685
686
687 (defmethod jde-jdb-fixup-output ((this jde-jdb-breakpoint-listener))
688     ;; This is a hack to accommodate reorder of message chunks
689     ;; on Solaris at debugger startup.
690     (if (string-match "running ...\n" (oref this :marker-acc))
691         (oset this :marker-acc
692               (concat "running ...\n"
693                       (substring (oref this :marker-acc) 0 (match-beginning 0))
694                       (substring (oref this :marker-acc) (match-end 0)))))
695
696
697     ;; This is a hack to fix reordering of message chunks on Windows 2000
698     ;; The problem is the debugger prompt - the thread name with the stack
699     ;; depth (eg main[1]) - sometimes shows up in the middle of the output
700     ;; from the command sent to the debugger.
701     ;; This seems to show up most often with step commands.
702     ;;(message "checking string %s" (oref jdb :marker-acc))
703     (if (string-match "^.*: \\([-a-zA-Z0-9_$]+\\[[0-9]+\\] \\)thread=" 
704                       (oref this :marker-acc))
705         (oset this :marker-acc
706               (concat (match-string 1 (oref this :marker-acc))
707                       (substring (oref this :marker-acc) 0 (match-beginning 1))
708                       (substring (oref this :marker-acc) (match-end 1)))))
709     ;; (message "fixed string is %s" jde-db-marker-acc)
710     )
711
712
713 (defmethod jde-jdb-set-breakpoint-listener ((this jde-jdb-breakpoint-listener) output)
714   "Listens for set breakpoint messages."
715   (let ((msgs (split-string output "\n")))
716     (loop for msg in msgs do
717           (if (and (string-match 
718                     "^.*Set .*breakpoint \\(.*\\):\\([0-9]+\\)"
719                     msg)
720                    (not (string-match "Unable to set.*" msg)))
721               (let* ((class (substring 
722                              msg
723                              (match-beginning 1) 
724                              (match-end 1)))
725                      (line (string-to-int 
726                             (substring 
727                              msg
728                              (match-beginning 2)
729                              (match-end 2))))
730                      (source-buffer (jde-db-find-class-source class))
731                      (path (buffer-file-name source-buffer))
732                      (bp (jde-db-find-breakpoint path line)))
733                 (oset bp status 'active)
734                 (jde-db-mark-breakpoint-active path  line))))))
735
736 (defmethod jde-db-listener-filter-output ((this jde-jdb-breakpoint-listener) input)
737   "Filters the output of the debugger."
738   (let ((jdb (oref this debugger))
739         (output ""))
740
741     ;; Accumulate next chunk of debugger output.
742     (oset this
743           :marker-acc (concat 
744                        (oref this :marker-acc) 
745                        input))
746
747     ;; (message (format "<acc-start>%s<acc-end>" (oref this :marker-acc)))
748
749     (jde-jdb-fixup-output this)
750
751     (let* ((marker-regexp (oref this :marker-regexp))
752            (marker-regexp-class-index (oref this :class-index))
753            (marker-regexp-line-index (oref this :line-index)))
754
755       ;; (message (concat "jdb output:" input))
756       ;; (message (concat "acc = " jde-db-marker-acc))
757     
758       ;; Process all the complete markers in this chunk.
759       (if (string-match marker-regexp (oref this :marker-acc))
760           ;; Extract the frame position from the marker.
761           (let ((premarker (substring 
762                             (oref this :marker-acc) 0 (match-beginning 0)))
763                 (marker (substring (oref this :marker-acc) 
764                                    (match-beginning 0) (match-end 0)))
765                 (rest (substring (oref this :marker-acc) (match-end 0)))
766                 (class (substring 
767                         (oref this :marker-acc)  
768                         (match-beginning marker-regexp-class-index) 
769                         (match-end marker-regexp-class-index)))
770                 (line-no (jde-jdb-string-to-int 
771                           (substring 
772                            (oref this :marker-acc)
773                            (match-beginning marker-regexp-line-index)
774                            (match-end marker-regexp-line-index))))
775                 (package ""))
776             ;; Extract package path from input.
777             (let ((case-fold-search nil)) ;; Make sure search is case-sensitive
778               (and (string-match (jde-jdb-make-qualified-class-name-regexp class) marker)
779                    (setq package
780                          (substring marker (match-beginning 2) (match-end 2))))
781
782                ;; (message "jde-db package: %s. marker = %s" jde-db-last-package marker)
783                ;;(message "case-fold-search = %s" (if case-fold-search "true" "false"))
784               )
785
786             ;; Insert debugger output into debugger buffer.
787             (setq output (concat premarker marker))
788
789             ;; Set the accumulator to the remaining text.
790             (oset this :marker-acc rest)
791
792             (jde-db-set-debug-cursor 
793              (concat package class) (concat class ".java") line-no)
794
795             (let* ((debuggee (oref jdb debuggee))
796                    (status (oref debuggee status)))
797               (oset status stopped-p t)))))
798
799    ;; Handle case where there is no line number info in current class.
800     (if (string-match (oref this noline-regexp) (oref this marker-acc))
801         (let ((premarker (substring 
802                           (oref this :marker-acc) 0 (match-beginning 0)))
803               (marker (substring (oref this :marker-acc)
804                                  (match-beginning 0) (match-end 0)))
805               (pc (substring (oref this :marker-acc)
806                              (match-beginning 1) (match-end 1)))
807               (rest (substring (oref this :marker-acc) (match-end 0))))
808
809           (setq output (concat premarker marker))
810           (oset this :marker-acc rest)))
811
812     ;; Does the remaining text look like it might end with the
813     ;; beginning of another marker?  If it does, then keep it in
814     ;; marker-acc until we receive the rest of it.  Since we
815     ;; know the full marker regexp above failed, it's pretty simple to
816     ;; test for marker starts.
817     (if (string-match "\\(^Breakpoint hit:\\)\\|\\(^Step completed:\\)" 
818                       (oref this :marker-acc))
819         (progn
820         ;; Everything before the potential marker start can be output.
821           (setq output (concat output 
822                                (substring (oref this :marker-acc)
823                                           0 (match-beginning 0))))
824
825           ;; Everything after, we save, to combine with later input.
826           (oset this 
827                 :marker-acc
828                 (substring (oref this :marker-acc) (match-beginning 0))))
829       (setq output 
830             (concat output (oref this :marker-acc)))
831       (oset this :marker-acc ""))
832
833     (jde-jdb-set-breakpoint-listener this output)
834     output))
835
836
837 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
838 ;;                                                                            ;;
839 ;; jdb Stack Listener                                                         ;;
840 ;;                                                                            ;;
841 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
842 (defclass jde-jdb-stack-listener (jde-db-listener)
843   ((stack-depth     :initarg :stack-depth
844                     :type string
845                     :initform ""
846                     :documentation
847                     "Stack depth."))
848   "Listens for changes in the current stack frame.")
849
850
851 ;; Thanks to Michael Ernst <mernst@cs.washington.edu> for the following
852 ;; stack-related code.
853 ;;
854 ;; Extract the index of the current stack frame from the jdb prompt, where
855 ;; the prompt is of the form 
856 ;;
857 ;;   thread[stack_index]
858 ;; 
859 ;; e.g.,
860 ;;
861 ;;   main[1]
862 ;;
863 ;; The user can move the debugger up and down the stack via the up and
864 ;; down commands. The debugger indicates the current location by the
865 ;; stack index portion of its prompt.
866 (defmethod jde-db-listener-filter-output ((this jde-jdb-stack-listener) output)
867   (let* ((jdb (oref this debugger))
868          (debuggee (oref jdb debuggee)))
869     (if (string-match "^[-a-zA-Z0-9_$ -]+\\[\\([0-9]*,?[0-9]+\\)\\] " output)
870         (oset debuggee :stack-depth (match-string 1 output)))
871     output))
872
873
874 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
875 ;;                                                                            ;;
876 ;; jdb Application Debuggee                                                   ;;
877 ;;                                                                            ;;
878 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
879 (defclass jde-jdb-debuggee-app (jde-db-debuggee-app) ()
880   "Application process being debugged with jdb.")
881
882 (defmethod initialize-instance ((this jde-jdb-debuggee-app) &rest fields)
883   "Constructs an instance of a jdb debuggee."
884   (call-next-method)
885   (oset  this  status  (jde-db-debuggee-status "jdb status")))
886
887 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
888 ;;                                                                            ;;
889 ;; jdb Applet Debuggee                                                        ;;
890 ;;                                                                            ;;
891 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
892 (defclass jde-jdb-debuggee-applet (jde-db-debuggee-applet) ()
893   "Application process being debugged with jdb.")
894
895 (defmethod initialize-instance ((this jde-jdb-debuggee-applet) &rest fields)
896   "Constructs an instance of a jdb debuggee."
897   (call-next-method)
898   (oset  this  status  (jde-db-debuggee-status "jdb status")))
899
900
901 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
902 ;;                                                                            ;;
903 ;; Class of JDE Debuggers based on jdb.                                       ;;
904 ;;                                                                            ;;
905 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
906 (defclass jde-db-jdb (jde-db-debugger)
907   ((exec-name       :initarg :exec-name
908                     :type string
909                     :initform "jdb"
910                     :documentation 
911                     "Name of the jdb executable.")
912    (path            :initarg :path
913                     :type string
914                     :initform "jdb"
915                     :documentation
916                     "Path of the jdb executable.")
917    (bp-listener     :initarg :bp-listener
918                     :type jde-jdb-breakpoint-listener
919                     :documentation "Breakpoint listener."))
920   (:allow-nil-initform t)
921 "Class of generic jdb debuggers")
922
923 (defmethod initialize-instance ((this jde-db-jdb) &rest fields)
924   "Constructor for generic jdb debugger."
925   (call-next-method)
926   (oset this :name "jdb")
927
928   ;; Install jdb versions of debugger commands.
929   (oset this cmd-set (jde-jdb-cmd-set "jdb commands" :debugger this))
930
931   (oset this bp-listener
932    (jde-jdb-breakpoint-listener 
933     "jdb breakpoint listener"
934     :debugger this))
935
936   (jde-db-add-listener this (oref this bp-listener))
937
938   (jde-db-add-listener
939    this
940    (jde-jdb-stack-listener 
941     "jdb stack listener"
942     :debugger this)))
943
944 (defmethod jde-db-create-debuggee-app ((this jde-db-jdb) main-class)
945   (oset 
946    this 
947    :debuggee (jde-jdb-debuggee-app 
948               (concat "Application: " main-class) 
949               :main-class main-class)))
950
951 (defmethod jde-db-create-debuggee-applet ((this jde-db-jdb) applet-doc)
952   (oset 
953    this
954    :debuggee (jde-jdb-debuggee-applet 
955               (concat "Applet: " applet-doc) 
956               :doc applet-doc)))
957
958 (defmethod jde-db-jdb-start ((this jde-db-jdb) prog-args cmdstr)
959   "Start the debugger."
960   (let ((w32-quote-process-args ?\")
961         (win32-quote-process-args ?\") ;; XEmacs
962         (source-directory default-directory)
963         (working-directory
964          (jde-db-debugger-get-working-dir this)))
965
966     (oset this :buffer (get-buffer-create (oref this :buffer-name)))
967
968     (save-excursion
969       (set-buffer (oref this :buffer))
970       ;; Do not erase the last transcript; user may wish to view it.
971       ;; (erase-buffer)
972       (goto-char (point-max))
973       (cd working-directory)
974       (insert (concat "cd " working-directory "\n"))
975       (insert cmdstr)
976       (comint-mode)
977       (make-local-variable 'comint-prompt-regexp)
978       (setq comint-prompt-regexp "\\(^> *\\)\\|\\(^.*\\[[0-9]+\\] *\\)")
979       (make-local-variable 'paragraph-start)
980       (setq paragraph-start comint-prompt-regexp)
981
982       (let ((process-connection-type nil))
983        (comint-exec (oref this :buffer)
984                    (oref this :buffer-name)
985                    (oref this :path)
986                    nil
987                    prog-args))    
988
989       (oset this process
990             (get-buffer-process (oref this buffer)))      
991
992       (cd source-directory)
993
994       (jde-db-set-process-filter this)
995       (jde-db-set-process-sentinel this)
996       (run-hooks 'jde-jdb-mode-hook)
997       (pop-to-buffer (oref this buffer))
998
999       (oset-default 'jde-db-debugger the-debugger this)
1000       (oset this running-p t))))
1001
1002
1003 (defmethod jde-jdb-connect ((this jde-db-jdb))
1004   "Connect the debugger to an existing process."
1005   (if (or
1006        (not (slot-boundp this 'buffer))
1007        (not (oref this :buffer))
1008        (not (comint-check-proc (oref this :buffer))))
1009       (let* ((debuggee (oref this debuggee))
1010              (source-directory default-directory)
1011              (connector (oref debuggee connector))
1012              (working-directory
1013               (jde-db-debugger-get-working-dir this))
1014              (prog-args 
1015               (if (typep connector 'jde-db-listen-connector)
1016                   (if (typep connector 'jde-db-socket-connector)
1017                       (list
1018                        "-connect"
1019                        (format 
1020                         "com.sun.jdi.SocketListen:port=%s"
1021                         (oref connector port)))
1022                     (if (typep connector 'jde-db-shared-memory-connector)
1023                         (list
1024                          "-connect"
1025                          (format
1026                           "com.sun.jdi.SharedMemoryListen:name=%s"
1027                           (oref connector name)))
1028                       (error "Invalid connector type.")))
1029                 (if (typep connector 'jde-db-attach-connector)
1030                     (if (typep connector 'jde-db-socket-connector)
1031                         (let ((host (oref connector host))
1032                               (port (oref connector port)))
1033                           (if host
1034                               (list
1035                                "-connect"
1036                                (format
1037                                 "com.sun.jdi.SocketAttach:hostname=%s,port=%s"
1038                                 host port))
1039                           (list
1040                            "-connect"
1041                            (format 
1042                             "com.sun.jdi.SocketAttach:port=%s"
1043                             port))))
1044                     (if (typep connector 'jde-db-shared-memory-connector)
1045                         (list
1046                          "-connect"
1047                          (format
1048                           "com.sun.jdi.SharedMemoryAttach:name=%s"
1049                           (oref connector name)))
1050                       (error "Invalid connector type."))))))
1051              (command-string 
1052               (format "%s %s\n\n"
1053                (oref this :path)  
1054                (mapconcat (lambda (x) x) prog-args " "))))
1055
1056         (oset 
1057          this 
1058          :buffer-name 
1059          (if (typep connector 'jde-db-shared-memory-connector)
1060              (format "*debug %s* debugee-shmem-name" (oref connector name))
1061            (format 
1062             "*debug %s:%s*" 
1063             (if (or (typep connector 'jde-db-listen-connector)
1064                     (not (oref connector port)))
1065                 "localhost" (oref connector host))
1066             (oref connector port))))
1067
1068         (oset this :buffer (get-buffer-create (oref this :buffer-name)))
1069
1070         ;; Forward to the debugger any breakpoint requests made
1071         ;; by the user before launching the application.
1072         (if jde-db-breakpoints
1073             (let ((bp-cmd (oref (oref this cmd-set) set-bp)))
1074               (oset 
1075                bp-cmd 
1076                breakpoints
1077                (mapcar (lambda (assoc-x) (cdr assoc-x)) jde-db-breakpoints))
1078
1079               (oset this next-cmd 
1080                     (append (oref this next-cmd) (list bp-cmd)))))
1081
1082         (jde-db-jdb-start this prog-args command-string)
1083
1084         (let* ((debuggee (oref this debuggee))
1085                (debuggee-status (oref debuggee status)))
1086           (oset debuggee-status running-p t)
1087           (oset debuggee-status stopped-p t)))
1088     (progn
1089       (message "An instance of %s is running." (oref this :buffer-name))        
1090       (pop-to-buffer (oref this :buffer-name)))))
1091
1092
1093 (defmethod jde-db-notify-process-exit ((this jde-db-jdb) msg)
1094   "The default debugger process sentinel invokes this method 
1095 when the jdb process terminates."
1096   (call-next-method)
1097   (let* ((debuggee (oref this debuggee))
1098          (debuggee-status (oref debuggee status)))
1099     (oset this running-p nil)
1100     (oset debuggee-status running-p nil)
1101     (oset debuggee-status stopped-p nil)
1102     (jde-db-set-all-breakpoints-specified)))
1103
1104 (defmethod jde-db-launch-arg ((this jde-db-jdb))
1105   "Generate the -launch option for jdb."
1106   (list "-launch"))
1107
1108
1109 (defmethod jde-db-debugger-get-prog-args ((this jde-db-jdb))
1110   (cond
1111    ((typep (oref this debuggee) 'jde-db-debuggee-app)
1112     (append 
1113      (jde-db-get-vm-args this)
1114      (jde-db-get-vm-args-from-user)
1115      (list (oref (oref this debuggee) main-class))
1116      jde-db-option-application-args
1117      (jde-db-get-app-args-from-user)))
1118    ((typep (oref this debuggee) 'jde-db-debuggee-applet)
1119     (list "-debug" 
1120           (oref (oref this debuggee) doc)))
1121    (t
1122     (error "Unrecognized jdb debuggee type."))))
1123     
1124
1125
1126
1127 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1128 ;;                                                                            ;;
1129 ;; JDK 1.1.x Support                                                          ;;
1130 ;;                                                                            ;;
1131 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1132
1133 (defclass jde-db-jdb-1-1 (jde-db-jdb)
1134   ()
1135   (:allow-nil-initform t)
1136 "Class of jdb shipped with JDK 1.1.x.")
1137
1138
1139 (defmethod initialize-instance ((this jde-db-jdb-1-1) &rest fields)
1140   "Constructor for jdb-1.1."
1141   (call-next-method)
1142   (oset (oref this bp-listener)
1143    :marker-regexp
1144    "^Breakpoint hit: .*(\\([^\$]*\\).*:\\([0-9]*\\))")
1145   (oset (oref this bp-listener) :class-index 1)
1146   (oset (oref this bp-listener) :line-index 2))
1147
1148 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1149 ;;                                                                            ;;
1150 ;; JDK 1.3.1 Support                                                          ;;
1151 ;;                                                                            ;;
1152 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1153 (defclass jde-db-old-jdb (jde-db-jdb-1-1)
1154   ()
1155   (:allow-nil-initform t)
1156 "Class of pre-JPDA jdb shipped with post-JPDA versions of the
1157 JDK.")
1158
1159 (defmethod initialize-instance ((this jde-db-old-jdb) &rest fields)
1160   "Constructor for old jdb."
1161
1162   (call-next-method)
1163   (oset this :exec-name "oldjdb"))
1164
1165
1166 (defclass jde-db-jdb-1-3 (jde-db-jdb)
1167   ()
1168   (:allow-nil-initform t)
1169   "Class of JPDA-based jdb shipped with JDK 1.3.")
1170
1171
1172 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1173 ;;                                                                            ;;
1174 ;; JDK 1.4.0 Support                                                          ;;
1175 ;;                                                                            ;;
1176 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1177 (defclass jde-db-jdb-1-4 (jde-db-jdb)
1178   ()
1179   (:allow-nil-initform t)
1180   "Class of JPDA-based jdb shipped with J2SDK 1.4")
1181
1182 (defmethod initialize-instance ((this jde-db-jdb-1-4) &rest fields)
1183   "Constructor for jdb-1.4."
1184   (call-next-method)
1185   ;; Regular expression used to find a jdb breakpoint position marker.
1186   ;; The regular expression has two subexpressions. The first matches
1187   ;; the name of the class in which the breakpoint occurs; the second, the
1188   ;; line number at which the breakpoint occurs."
1189   (oset (oref this bp-listener)
1190    :marker-regexp
1191    "^.*: \"thread=.*\", \\(\\(.*[.]\\)*\\)\\([^$]*\\)\\($.*\\)*[.].+(), line=\\([0-9,.]*\\)"))
1192
1193 (defun jde-jdb-get-jdb ()
1194   "Gets the version of jdb specified for the
1195 current project."
1196   (let (jdb)
1197     (cond
1198      ((string= (car jde-debugger) "jdb")
1199       (cond 
1200        ((and (< (jde-java-major-version) 2)
1201              (< (jde-java-minor-version) 2))
1202         (setq jdb (jde-db-jdb-1-1 "jdb 1.1")))
1203        ((and (< (jde-java-major-version) 2)
1204              (= (jde-java-minor-version) 3))
1205         (setq jdb (jde-db-jdb-1-3 "jdb 1.3")))
1206        (t
1207         (setq jdb (jde-db-jdb-1-4 "jdb 1.4")))))       
1208      ((string= (car jde-debugger) "old jdb")
1209       (if (and (< (jde-java-major-version) 2)
1210                (< (jde-java-minor-version) 2))
1211           (setq jdb (jde-db-jdb-1-1 "jdb 1.1"))
1212         (setq jdb (jde-db-old-jdb "old jdb"))))
1213      (t
1214       (error "%s is not a valid jdb debugger choice." 
1215              (car jde-debugger))))
1216     (oset 
1217      jdb 
1218      :path (jde-get-jdk-prog (oref jdb :exec-name)))
1219     jdb))
1220
1221 (defun jde-jdb-get-socket-address ()
1222   (if jde-db-option-connect-socket
1223       jde-db-option-connect-socket
1224     (let ((host
1225            (read-from-minibuffer  "Debuggee host: " "local"))
1226           (port
1227            (read-from-minibuffer "Debuggee port: " "4444")))
1228       (list
1229        (if (not (string= host "local"))
1230            host)
1231        port))))
1232
1233
1234
1235 (defun jde-jdb-attach-via-socket ()
1236   "Launch jdb in attach mode. In this mode, jdb connects itself to an
1237 existing debuggee process via a socket. The debuggee process itself must have been
1238 launched in debugger server mode. The JDK vm accepts command line
1239 arguments that starts the vm in the appropriate mode, e.g.,
1240
1241 java -Xdebug -Xrunjdwp:transport=dt_socket,address=4444,server=y,suspend=n MyClass
1242
1243 starts MyClass in debugger server mode at the socket address
1244 4444. See jdb in the tools section of the JDK documentation for
1245 more information on these arguments.
1246
1247 Selecting the Server mode option of the `jde-run-option-debug' customization 
1248 variable causes the JDEE to specify the appropriate command-line
1249 arguments when launching the debuggee process.
1250
1251 The attach command connects the debugger to the debuggee at the
1252 address specified by `jde-db-option-connect-socket'. If this variable
1253 is nil, this command prompts you to enter the address."
1254   (interactive)
1255   (let* ((socket (jde-jdb-get-socket-address))
1256          (host (nth 0 socket))
1257          (port (nth 1 socket)))
1258     (if (string= port "")
1259         (error "You must specify the port of the debuggee process.")
1260       (let* ((debugger (jde-jdb-get-jdb))
1261              (connector
1262               (jde-db-socket-attach-connector
1263                "connector"
1264                :host host
1265                :port port))
1266              (debuggee 
1267               (jde-jdb-debuggee-app 
1268               "debuggee"
1269               :main-class (format 
1270                            "Attached to socket %s:%s"
1271                            (if host host "localhost")
1272                            port)
1273               :connector connector)))
1274         (oset debugger the-debugger debugger)
1275         (oset debugger :debuggee debuggee)
1276         (jde-jdb-connect debugger)))))
1277
1278
1279 (defun jde-jdb-get-shared-memory-name ()
1280   (if jde-db-option-connect-shared-memory-name
1281       jde-db-option-connect-shared-memory-name
1282     (read-from-minibuffer  "Shared memory name: " "javadebug")))
1283
1284
1285 (defun jde-jdb-attach-via-shared-memory ()
1286   "Launch jdb in attach mode. In this mode, jdb connects itself to an
1287 existing debuggee process. This command specifies use of shared memory
1288 as the connection transport. The debuggee process itself must have
1289 been launched in debugger server mode. The JDK vm accepts command line
1290 arguments that starts the vm in the appropriate mode, e.g.,
1291
1292 java -Xdebug -Xrunjdwp:transport=dt_shmem,address=javadebug,server=y,suspend=n MyClass
1293
1294 starts MyClass in debugger server mode, specifying \"javadebug\" as
1295 the name of the shared memory transport. See jdb in the tools section
1296 of the JDK documentation for more information on these arguments.
1297
1298 Selecting the Server mode option of the `jde-run-option-debug' customization 
1299 variable causes the JDEE to specify the appropriate command-line
1300 arguments when launching the debuggee process.
1301
1302 The attach command connects the debugger to the debuggee at the
1303 address specified by `jde-db-option-connect-shared-memory', or, if
1304 this variable is nil, this command prompts you to enter a name."
1305   (interactive)
1306   (assert 
1307    (eq system-type 'windows-nt)
1308    "The debugger does not support shared memory connections on this platform.")
1309   (let ((shmem-name (jde-jdb-get-shared-memory-name)))
1310     (if (string= shmem-name "")
1311         (error "Shared memory name required.")
1312       (let* ((debugger (jde-jdb-get-jdb))
1313              (connector
1314               (jde-db-shared-memory-attach-connector
1315                "connector"
1316                :name shmem-name))
1317              (debuggee 
1318               (jde-jdb-debuggee-app 
1319                "debuggee"
1320                :main-class (format 
1321                             "Attached via shared memory: %s."
1322                             shmem-name)
1323                :connector connector)))
1324         (oset debugger the-debugger debugger)
1325         (oset debugger :debuggee debuggee)
1326         (jde-jdb-connect debugger)))))
1327
1328
1329 (defun jde-jdb-get-socket-listen-port ()
1330   (if jde-db-option-connect-socket
1331       (nth 1 jde-db-option-connect-socket)
1332     (read-from-minibuffer "Listen port: " "4444")))
1333
1334 (defun jde-jdb-listen-via-socket ()
1335   "Launch jdb in listen mode. In this mode, jdb launches itself and
1336 connects itself to a subsequently launched debuggee process. This
1337 command uses a socket as the method for connecting to the debuggee
1338 process. The debuggee process itself must be launched in debugger
1339 client mode The JDK vm accepts command line arguments that starts the
1340 vm in the appropriate mode, e.g.,
1341
1342 java -Xdebug -Xrunjdwp:transport=dt_socket,address=4444,server=n,suspend=n MyClass
1343
1344 starts MyClass in debugger client mode at the socket port 4444. See jdb in 
1345 the tools section of the JDK documentation for
1346 more information.
1347
1348 Selecting the Client mode option of the `jde-run-option-debug' customization 
1349 variable causes the JDEE to specify the appropriate command-line
1350 arguments when launching the debuggee process.
1351
1352 The listen command listens for the debugger at the
1353 address specified by `jde-db-option-connect-socket'. If this variable
1354 is nil, this command prompts you to enter the address. You can enter
1355 either the address that you plan to start the debuggee process at
1356 (e.g., jdbconn) or a null string.  If you enter a null string, this
1357 command startes the debugger in a mode that accepts connections from
1358 any debuggee process started in debugger client mode, regardless of
1359 address."
1360   (interactive)
1361   (let* ((debugger (jde-jdb-get-jdb))
1362          (port (jde-jdb-get-socket-listen-port))
1363          (connector
1364            (jde-db-socket-listen-connector
1365                "connector"
1366                :port port))
1367          (debuggee 
1368           (jde-jdb-debuggee-app 
1369            "debuggee"
1370           :main-class (concat "Listening at port " port)
1371           :connector connector)))
1372     (oset debugger the-debugger debugger)
1373     (oset debugger :debuggee debuggee)
1374     (jde-jdb-connect debugger)))
1375
1376 (defun jde-jdb-listen-via-shared-memory ()
1377   "Launch jdb in listen mode. In this mode, a subsequently
1378 launched debuggee process connects itself to jdb. This command uses
1379 Windows shared memory primitives as the method of communications
1380 between jdb andthe debuggee process. The debuggee process itself must
1381 be launched in debugger client mode. The JDK vm accepts command line
1382 arguments that starts the vm in the appropriate mode, e.g.,
1383
1384 java -Xdebug
1385 -Xrunjdwp:transport=dt_shmem,address=javadebug,server=n,suspend=n
1386 MyClass
1387
1388 starts MyClass in debugger client mode at the shared memory address
1389 javadebug. See jdb in the tools section of the JDK documentation for
1390 more information.
1391
1392 Selecting the Client mode option of the `jde-run-option-debug' customization 
1393 variable causes the JDEE to specify the appropriate command-line
1394 arguments when launching the debuggee process.
1395
1396 The listen command listens for the debugger at the
1397 address specified by `jde-db-option-connect-shared-memory'. If this variable
1398 is nil, this command prompts you to enter the address that you plan to start 
1399 the debuggee process at (e.g., jdbconn)."
1400   (interactive)
1401   (assert
1402    (eq system-type 'windows-nt)
1403    "The debugger does not support shared memory connections on this platform.")
1404   (let* ((debugger (jde-jdb-get-jdb))
1405          (name (jde-jdb-get-shared-memory-name))
1406          (connector
1407            (jde-db-shared-memory-listen-connector
1408                "connector"
1409                :name name))
1410          (debuggee 
1411           (jde-jdb-debuggee-app 
1412            "debuggee"
1413           :main-class (concat "Listening to " name)
1414           :connector connector)))
1415     (oset debugger the-debugger debugger)
1416     (oset debugger :debuggee debuggee)
1417     (jde-jdb-connect debugger)))
1418
1419 (defun jde-jdb-display (key)
1420   "Print expression at point."
1421   (interactive "sExpression: ")
1422   (jde-assert-source-or-debug-buffer)
1423   (let* ((debugger (oref 'jde-db-debugger the-debugger))
1424          (debuggee (oref debugger debuggee))
1425          (debuggee-status (oref debuggee status)))
1426     (if (and (oref debugger running-p)
1427              (oref debuggee-status stopped-p))
1428         (let* ((cmd-set (oref debugger cmd-set))
1429                cmd)
1430           (if (string= "print" key)
1431               (setq cmd (oref cmd-set print))
1432             (if (string= "dump" key)
1433                 (setq cmd (oref cmd-set dump))
1434               (if (string= "eval" key)
1435                   (setq cmd (oref cmd-set eval))
1436                 (if (string= "set" key)
1437                     (setq cmd (oref cmd-set set-var))
1438                   (if (string= "locals" key)
1439                       (setq cmd (oref cmd-set locals)))))))
1440           (jde-db-exec-cmd debugger cmd))
1441       (let ((class (oref debuggee main-class)))
1442         (error "Application %s is not stopped" class)))))
1443
1444 (defun jde-jdb-print ()
1445   (interactive)
1446   (jde-jdb-display "print"))
1447
1448 (defun jde-jdb-dump ()
1449   (interactive)
1450   (jde-jdb-display "dump"))
1451
1452 (defun jde-jdb-eval ()
1453   (interactive)
1454   (jde-jdb-display "eval"))
1455
1456 (defun jde-jdb-locals ()
1457   (interactive)
1458   (jde-jdb-display "locals"))
1459
1460 (defun jde-jdb-set ()
1461   (interactive)
1462   (jde-jdb-display "set"))
1463
1464 (defun jde-jdb-help ()
1465   (interactive)
1466   (let* ((jde-dir (jde-find-jde-doc-directory))
1467          (jdb-ug-path
1468           (if jde-dir
1469               (expand-file-name "doc/html/jdb-ug/jdb-ug-frame.html" jde-dir))))      
1470     (if (and
1471          jdb-ug-path
1472          (file-exists-p jdb-ug-path))
1473         (browse-url (concat "file://" (jde-convert-cygwin-path jdb-ug-path))
1474                     (if (boundp 'browse-url-new-window-flag)
1475                         'browse-url-new-window-flag
1476                       browse-url-new-window-p))
1477       (signal 'error '("Cannot find jdb user guide.")))))
1478
1479
1480 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1481 ;;                                                                            ;; 
1482 ;; Debug Commands                                                             ;;
1483 ;;                                                                            ;;
1484 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1485
1486
1487 (defvar jde-jdb-emacs-menu-spec
1488   (list "Jdb"
1489
1490         ["Step Over"                  
1491              jde-debug-step-over
1492              :active (jde-db-debuggee-stopped-p)
1493              :help "Step over the next method."]
1494           
1495
1496         ["Step Into"                  
1497          jde-debug-step-into
1498          :active (jde-db-debuggee-stopped-p)
1499          :help "Step into the next method."]
1500
1501         ["Step Out"                  
1502          jde-debug-step-out
1503          :active (jde-db-debuggee-stopped-p)
1504          :help "Step out of the current method."]
1505
1506         ["Run"
1507          jde-debug-run
1508          :active   (and
1509                     (slot-boundp 'jde-db-debugger 'the-debugger)
1510                     (let* ((debugger (oref 'jde-db-debugger the-debugger))
1511                            (debuggee (oref debugger debuggee))
1512                            (debuggee-status (oref debuggee status)))
1513                       (and (oref debugger running-p)
1514                            (not (oref debuggee-status running-p)))))
1515                         
1516          :included (or 
1517                     (not (slot-boundp 'jde-db-debugger 'the-debugger))
1518                     (let* ((debugger (oref 'jde-db-debugger the-debugger))
1519                            (debuggee (oref debugger debuggee))
1520                            (debuggee-status (oref debuggee status)))
1521                       (or (not (oref debugger running-p))
1522                           (not (oref debuggee-status running-p)))))
1523          :help "Start the current program."]
1524
1525         ["Continue"                   
1526          jde-debug-cont 
1527          :active   (or 
1528                     (jde-db-debuggee-stopped-p)
1529                     (jde-db-debuggee-suspended-p))
1530
1531          :included  (jde-db-debuggee-running-p)
1532          :help "Continue the current program."]
1533
1534         ["Quit"
1535          jde-debug-quit
1536          :active  (jde-db-debuggee-running-p)
1537          :help "Terminate the current debugging session."]
1538
1539         "-"
1540
1541         ["Toggle Breakpoint"          
1542          jde-debug-toggle-breakpoint 
1543          :active t
1544          :help "Set (or remove) a breakpoint at the current line."]
1545
1546         ["Clear Breakpoints"          
1547          jde-debug-clear-breakpoints 
1548          :active  jde-db-breakpoints
1549          :help "Remove all breakpoints."]
1550
1551         ["List Breakpoints"
1552          jde-debug-list-breakpoints
1553          :active  jde-db-breakpoints
1554          :help "Display a list of breakpoints."]
1555
1556         "-"
1557
1558         (list
1559          "Display"
1560          
1561          ["Expression"                  
1562           jde-jdb-print 
1563           :active  (jde-db-debuggee-stopped-p)
1564           :help "Evaluate an expression and display the results."]
1565           
1566          ["Object"
1567           jde-jdb-dump
1568           :active  (jde-db-debuggee-stopped-p)
1569           :help "Display the fields of an object referenced by a variable."]
1570
1571
1572          ["Locals"
1573           jde-jdb-locals
1574           :active  (jde-db-debuggee-stopped-p)
1575           :help "Display the variables in scope at the current line."]
1576          )
1577
1578          ["Set Variable"
1579           jde-jdb-set
1580           :active  (jde-db-debuggee-stopped-p)
1581           :help "Change the value of an in-scope variable."]
1582           
1583         (list
1584          "Stack"
1585
1586          ["Up"                        
1587           jde-debug-up
1588           :active  (jde-db-debuggee-stopped-p)
1589           :help "Move the debug cursor up the method call stack."]
1590
1591          ["Down"                      
1592           jde-debug-down
1593           :active (and
1594                    (jde-db-debuggee-stopped-p)
1595                    (let* ((debugger (oref 'jde-db-debugger the-debugger))
1596                           (debuggee (oref debugger debuggee)))
1597                      (> (jde-jdb-string-to-int
1598                          (oref debuggee :stack-depth)) 1)))
1599           :help "Move the debug cursor down the method call stack." ]
1600
1601          ["Where"                      
1602           jde-debug-where
1603           :active (jde-db-debuggee-stopped-p)
1604           :help "Display the call stack."]
1605
1606          )
1607         "-"
1608         (list
1609          "External Process"
1610          ["Attach Via Socket"
1611           jde-jdb-attach-via-socket
1612           :active (not (jde-db-debuggee-running-p))
1613           :help "Attach the debugger to an external process via a socket."]
1614          ["Attach Via Shared Memory"
1615           jde-jdb-attach-via-shared-memory
1616           :active (and
1617                    (eq system-type 'windows-nt)
1618                    (not (jde-db-debuggee-running-p)))
1619           :help "Attach the debugger to an external process via a shared memory connection."]
1620          ["Listen Via Socket"
1621           jde-jdb-listen-via-socket
1622           :active (not (jde-db-debuggee-running-p))
1623           :help "Listen at a socket for an external process."]
1624          ["Listen Via Shared Memory"
1625           jde-jdb-listen-via-shared-memory
1626           :active (and
1627                    (eq system-type 'windows-nt)
1628                    (not (jde-db-debuggee-running-p)))
1629           :help "Listen in shared memory for an external process."]
1630          )       
1631         "-"
1632
1633         ["Preferences"                
1634          jde-bug-show-preferences 
1635          :active nil
1636          :help "Not yet implemented."]
1637
1638         "-"
1639         ["Help"                       
1640          jde-jdb-help
1641          :active t
1642          :help "Display the JDEE's jdb user's guide in an HTML browser."]
1643         )
1644   "Defines the Jdb menu for Emacs.")
1645
1646 (defvar jde-jdb-xemacs-menu-spec
1647   (list "Jdb"
1648
1649         ["Step Over"                  
1650              jde-debug-step-over
1651              :active (jde-db-debuggee-stopped-p)]
1652           
1653
1654         ["Step Into"                  
1655          jde-debug-step-into
1656          :active (jde-db-debuggee-stopped-p)
1657          ]
1658
1659         ["Step Out"                  
1660          jde-debug-step-out
1661          :active (jde-db-debuggee-stopped-p)]
1662
1663         ["Run"
1664          jde-debug-run
1665          :active   (and
1666                     (slot-boundp 'jde-db-debugger 'the-debugger)
1667                     (let* ((debugger (oref 'jde-db-debugger the-debugger))
1668                            (debuggee (oref debugger debuggee))
1669                            (debuggee-status (oref debuggee status)))
1670                       (and (oref debugger running-p)
1671                            (not (oref debuggee-status running-p)))))
1672                         
1673          :included (or 
1674                     (not (slot-boundp 'jde-db-debugger 'the-debugger))
1675                     (let* ((debugger (oref 'jde-db-debugger the-debugger))
1676                            (debuggee (oref debugger debuggee))
1677                            (debuggee-status (oref debuggee status)))
1678                       (or (not (oref debugger running-p))
1679                           (not (oref debuggee-status running-p)))))]
1680
1681         ["Continue"                   
1682          jde-debug-cont 
1683          :active   (or 
1684                     (jde-db-debuggee-stopped-p)
1685                     (jde-db-debuggee-suspended-p))
1686
1687          :included  (jde-db-debuggee-running-p)]
1688
1689         ["Quit"
1690          jde-debug-quit
1691          :active  (jde-db-debuggee-running-p)]
1692
1693         "-"
1694
1695         ["Toggle Breakpoint"          
1696          jde-debug-toggle-breakpoint 
1697          t]
1698
1699         ["Clear Breakpoints"          
1700          jde-debug-clear-breakpoints 
1701          jde-db-breakpoints]
1702
1703         ["List Breakpoints"
1704          jde-debug-list-breakpoints
1705          jde-db-breakpoints]
1706         "-"
1707
1708         (list
1709          "Display"
1710          
1711          ["Expression"                  
1712           jde-jdb-print 
1713           :active  (jde-db-debuggee-stopped-p)]
1714           
1715          ["Object"
1716           jde-jdb-dump
1717           :active  (jde-db-debuggee-stopped-p)]
1718
1719
1720          ["Locals"
1721           jde-jdb-locals
1722           :active  (jde-db-debuggee-stopped-p)]
1723          )
1724
1725          ["Set Variable"
1726           jde-jdb-set
1727           :active  (jde-db-debuggee-stopped-p)]
1728           
1729         (list
1730          "Stack"
1731
1732          ["Up"                        
1733           jde-debug-up
1734           :active  (jde-db-debuggee-stopped-p)]
1735
1736          ["Down"                      
1737           jde-debug-down
1738           :active (and
1739                    (jde-db-debuggee-stopped-p)
1740                    (let* ((debugger (oref 'jde-db-debugger the-debugger))
1741                           (debuggee (oref debugger debuggee)))
1742                      (> (jde-jdb-string-to-int
1743                          (oref debuggee :stack-depth)) 1)))]
1744
1745          ["Where"                      
1746           jde-debug-where
1747           :active (jde-db-debuggee-stopped-p)]
1748
1749          )
1750         "-"
1751         (list
1752          "External Process"
1753          ["Attach Via Socket"
1754           jde-jdb-attach-via-socket
1755           :active (not (jde-db-debuggee-running-p))]
1756          ["Attach Via Shared Memory"
1757           jde-jdb-attach-via-shared-memory
1758           :active (and
1759                    (eq system-type 'windows-nt)
1760                    (not (jde-db-debuggee-running-p)))]
1761          ["Listen Via Socket"
1762           jde-jdb-listen-via-socket
1763           :active (not (jde-db-debuggee-running-p))]
1764          ["Listen Via Shared Memory"
1765           jde-jdb-listen-via-shared-memory
1766           :active (and
1767                    (eq system-type 'windows-nt)
1768                    (not (jde-db-debuggee-running-p)))]
1769
1770          )       
1771         "-"
1772         ["Preferences"                
1773          jde-bug-show-preferences nil]
1774         "-"
1775         ["Help"                       
1776          jde-jdb-help t]
1777         )
1778   "Defines the JDE's menu of jdb commands.")
1779
1780   
1781 (defvar jde-jdb-mode-map
1782   (let ((km (make-sparse-keymap)))
1783     (easy-menu-define jde-jdb-menu km "Jdb Minor Mode Menu"
1784                       jde-jdb-emacs-menu-spec)
1785     km)
1786   "Keymap for Jdb minor mode.")
1787
1788 (defvar jde-jdb-minor-mode nil
1789   "Non-nil if jdb minor mode is enabled.")
1790 (make-variable-buffer-local 'jde-jdb-minor-mode)
1791
1792 (defun jde-jdb-minor-mode (&optional arg)
1793   "Toggle jdb minor mode.
1794 With prefix argument ARG, turn on if positive, otherwise off..
1795
1796 \\{jde-jdb-mode-map}"
1797   (interactive
1798    (list (or current-prefix-arg
1799              (if jde-jdb-minor-mode 0 1))))
1800
1801   (setq jde-jdb-minor-mode
1802         (if arg
1803             (>
1804              (prefix-numeric-value arg)
1805              0)
1806           (not jde-jdb-minor-mode)))
1807
1808   (if jde-jdb-minor-mode
1809       (if (featurep 'xemacs)
1810             (easy-menu-add jde-jdb-xemacs-menu-spec jde-jdb-mode-map))
1811     (if (featurep 'xemacs)
1812       (easy-menu-remove jde-jdb-xemacs-menu-spec))))
1813
1814 (semantic-add-minor-mode 'jde-jdb-minor-mode " jdb" jde-jdb-mode-map)
1815
1816
1817 ;; (fmakunbound 'jde-jdb-key-bindings)
1818 (defcustom jde-jdb-key-bindings
1819   (list (cons "[?\C-c ?\C-a ?\C-s]" 'jde-debug-step-over)
1820         (cons "[?\C-c ?\C-a ?\C-n]" 'jde-debug-step-into)
1821         (cons "[?\C-c ?\C-a ?\C-o]" 'jde-debug-step-out)
1822         (cons "[?\C-c ?\C-a ?\C-c]" 'jde-debug-cont)
1823         (cons "[?\C-c ?\C-a ?\C-r]" 'jde-debug-run)
1824         (cons "[?\C-c ?\C-a ?\C-b]" 'jde-debug-toggle-breakpoint)
1825         (cons "[?\C-c ?\C-a ?\C-u]" 'jde-debug-up)
1826         (cons "[?\C-c ?\C-a ?\C-d]" 'jde-debug-down)
1827         (cons "[?\C-c ?\C-a ?\C-p]" 'jde-jdb-print)
1828         (cons "[?\C-c ?\C-a ?\C-d]" 'jde-jdb-dump)
1829         (cons "[?\C-c ?\C-a ?\C-e]" 'jde-jdb-eval)
1830         (cons "[?\C-c ?\C-a ?\C-v]" 'jde-jdb-set)
1831         (cons "[?\C-c ?\C-a ?\C-l]" 'jde-jdb-locals))
1832   "*Specifies key bindings for jdb debug commands.
1833 The value of this variable is an association list. The car of
1834 each element specifies a key sequence. The cdr specifies 
1835 an interactive command that the key sequence executes. To enter
1836 a key with a modifier, type C-q followed by the desired modified
1837 keystroke. For example, to enter C-s (Control s) as the key to be
1838 bound, type C-q C-s in the key field in the customization buffer.
1839 You can use the notation [f1], [f2], etc., to specify function keys."
1840   :group 'jde-project
1841   :type '(repeat
1842           (cons :tag "Key binding"
1843            (string :tag "Key")
1844            (function :tag "Command")))
1845   :set '(lambda (sym val)
1846           ;; Unmap existing key bindings
1847           (if (and
1848                (boundp 'jde-jdb-key-bindings)
1849                jde-jdb-key-bindings)
1850               (mapc 
1851                (lambda (binding)
1852                  (let ((key (car binding))
1853                        (fcn (cdr binding)))
1854                    (if (string-match "\\[.+]" key)
1855                        (setq key (car (read-from-string key))))
1856                    (define-key jde-jdb-mode-map key nil)))
1857                jde-jdb-key-bindings))
1858           ;; Map new key bindings.
1859           (mapc 
1860            (lambda (binding)
1861              (let ((key (car binding))
1862                    (fcn (cdr binding)))
1863                (if (string-match "\\[.+]" key)
1864                    (setq key (car (read-from-string key))))
1865                (define-key jde-jdb-mode-map key fcn)))
1866            val)
1867           (set-default sym val)))
1868
1869 (defun jde-jdb-string-to-int(number)
1870   "This method removes punctuation from a string, e.g, 1,200 (1.200 in Danish),
1871 and converts the result to an integer."
1872   (if (string-match "[^[:digit:]]" number)
1873       (setq number (replace-match "" nil nil number)))
1874   (string-to-int number))
1875
1876 (provide 'jde-jdb)
1877
1878 ;; Change History
1879 ;; $Log: jde-jdb.el,v $
1880 ;; Revision 1.48  2005/01/18 05:23:30  paulk
1881 ;; Change variables named assoc to assoc-x. This is intended to fix a "Symbol's value as variable is void: old-assoc" problem when debugging with the compiled version of JDE in xemacs/cygwin. Thanks to Henry S. Thompson.
1882 ;;
1883 ;; Revision 1.47  2004/12/17 05:22:25  paulk
1884 ;; Fix regression that caused DOS window to appear when running the debugger.
1885 ;;
1886 ;; Revision 1.46  2004/12/08 12:49:18  paulk
1887 ;; Updated regular expressions to accommodate non-English punctuation styles for numeric
1888 ;; expressions in jdb messages, e.g., 1.200 for the English 1,200. Thanks to Morten B. Isaksen.
1889 ;;
1890 ;; Revision 1.45  2004/10/18 03:37:34  paulk
1891 ;; Wrap call to comint-exec in save-w32-show-window macro.
1892 ;;
1893 ;; Revision 1.44  2004/10/03 03:33:12  paulk
1894 ;; Fix regression caused by renaming jde-jdb-debuggee as jde-jdb-debuggee-app.
1895 ;;
1896 ;; Revision 1.43  2004/09/20 05:29:34  paulk
1897 ;; Changes needed to make restructured debugging code work for applets.
1898 ;;
1899 ;; Revision 1.42  2004/09/02 04:49:01  paulk
1900 ;; More infrastructure work to support debugging of applets.
1901 ;;
1902 ;; Revision 1.41  2004/09/01 06:21:29  paulk
1903 ;; Restructured to accommodate debugging applets.
1904 ;;
1905 ;; Revision 1.40  2004/06/22 01:56:44  jslopez
1906 ;; Removes extra point from the class being passed to jde-db-set-debug-cursor.
1907 ;; It has an extra dot i.e. com.company..MyClass.
1908 ;;
1909 ;; Revision 1.39  2004/05/12 02:43:40  jslopez
1910 ;; Adds safety check to set the stack depth to 1 if it is not set. This can
1911 ;; happens if the regexpression fails, i.e A thread name with a character not in
1912 ;; the regexpression. Enhances the regexpression to parse the line number to allow
1913 ;; number larger than 999. Enhances the regexpression that parser the where
1914 ;; command to allow spaces and '-' since those are valid thread names. In
1915 ;; additions, adds support for line number larger than 999. Fixes unbound variable
1916 ;; "port" in jde-jdb-connect method.
1917 ;;
1918 ;; Revision 1.38  2004/02/18 13:48:21  jslopez
1919 ;; When a breakpoint was requested on a line that does not contain code and jdb
1920 ;; responded with "Unable to set breakpoint" it was being handle as a set
1921 ;; breakpoint,i.e. the breakpoint was being activated. Modifies
1922 ;; jde-jdb-set-breakpoint-listener to ignore this message. Modifies
1923 ;; jde-db-cmd-notify-response to delete the breakpoint in this situation. In
1924 ;; addition, adds a check for a null bp, in some instances it was null causing an
1925 ;; error.
1926 ;;
1927 ;; Revision 1.37  2003/09/18 05:30:41  paulk
1928 ;; Replace the attach and listen commands with separate commands for
1929 ;; attaching/listening via sockets and shared memory. This is necessary to support attaching via sockets on Windows platforms.
1930 ;;
1931 ;; Revision 1.36  2003/06/30 03:58:11  paulk
1932 ;; Provided help strings for Jdb menu items.
1933 ;;
1934 ;; Revision 1.35  2003/06/15 04:35:29  paulk
1935 ;; Fix docstrings for jde-jdb-attach and jde-jdb-listen.
1936 ;;
1937 ;; Revision 1.34  2003/06/12 04:06:19  paulk
1938 ;; Cosmetic fix to set-var command.
1939 ;;
1940 ;; Revision 1.33  2003/06/02 05:08:51  paulk
1941 ;; Reorganized Jdb->Display menu. Changed names of commands to reflect purpose, e.g., Display->Print
1942 ;; becomes Display->Expression. Deleted Display-Eval because it is the same as Display->Expression.
1943 ;; Moved Set (variable) command from the DIsplay submenu to the toplevel Jdb menu. Changed
1944 ;; first Jdb->Set Variable prompt from "Expression: " to Variable: ".
1945 ;;
1946 ;; Revision 1.32  2003/05/27 04:05:15  paulk
1947 ;; Adds jde-jdb-help command. This command displays the JDB user's guide.
1948 ;;
1949 ;; Revision 1.31  2003/05/14 11:09:30  paulk
1950 ;; Fix regression caused by renaming jdb classes.
1951 ;;
1952 ;; Revision 1.30  2003/05/14 06:38:48  paulk
1953 ;; Fix jde-jdb-attach and jde-jdb-listen to reflect replacement of
1954 ;; jde-db-option-connect-address with jde-db-option-listen-address and
1955 ;; jde-db-option-attach-address.
1956 ;;
1957 ;; Revision 1.29  2003/05/13 05:06:04  paulk
1958 ;; The attach and listen commands now prompt for a connect address if jde-db-connect-address
1959 ;; is nil. Also provided extensive doc strings for these commands.
1960 ;;
1961 ;; Revision 1.28  2003/02/25 17:19:59  jslopez
1962 ;; Fixes bug setting breakpoints that will leave breakpoints mark as
1963 ;; deferred even though they are not.
1964 ;;
1965 ;; Revision 1.27  2003/02/25 17:09:11  jslopez
1966 ;; Fixes regression bug. Updates the remaining jde-db-debuggee to jde-jdb-debuggee.
1967 ;;
1968 ;; Revision 1.26  2003/02/25 06:53:29  paulk
1969 ;; Created a generalized jde-debug command and wired it up to jdb.
1970 ;; Next step is to wire it up to JDEbug.
1971 ;;
1972 ;; Revision 1.25  2003/02/25 04:37:15  jslopez
1973 ;; Sets a main-class when attaching or listening through jdb to avoid
1974 ;; an unbound error.
1975 ;;
1976 ;; Revision 1.24  2003/02/24 18:03:28  jslopez
1977 ;; Fixes bug in jde-db-listener-filter-output.
1978 ;;
1979 ;; Revision 1.23  2003/01/12 19:17:17  jslopez
1980 ;; Adds command List Breakpoints to the JDB menu.
1981 ;;
1982 ;; Revision 1.22  2003/01/09 12:10:13  jslopez
1983 ;; Exposes the jdb methods: print, dump, eval, set, and locals.
1984 ;;
1985 ;; Revision 1.21  2003/01/08 21:49:13  jslopez
1986 ;; Fixes typo in menu.
1987 ;;
1988 ;; Revision 1.20  2003/01/07 00:05:32  jslopez
1989 ;; Fixes bug that would parse line number higher than 999.
1990 ;; JDB prints out the number as 1,999.
1991 ;;
1992 ;; Revision 1.19  2002/11/11 05:24:26  paulk
1993 ;; No need to add .exe to jdb path thanks to Mac compatibility fix.
1994 ;;
1995 ;; Revision 1.18  2002/11/05 07:56:20  paulk
1996 ;; Mac OS X (darwin) compatibility fix: find paths of jdb and appletviewer on the Mac. Thanks to Andrew Hyatt.
1997 ;;
1998 ;; Revision 1.17  2002/10/16 04:59:57  paulk
1999 ;; Debug cursor now works in files that do not belong to a package. Thanks to Andy Piper.
2000 ;;
2001 ;; Revision 1.16  2002/06/17 07:24:08  paulk
2002 ;; Updated the JDEE's applet debugging command to
2003 ;; work with its new jdb interface.
2004 ;;
2005 ;; Revision 1.15  2002/05/21 06:35:20  paulk
2006 ;; Updated to support J2SDK 1.4.0 version of jdb.
2007 ;;
2008 ;; Revision 1.14  2002/03/06 13:00:18  paulk
2009 ;; * Removed references to obsolete jde-db-option-attach variable.
2010 ;; * The jdb launch, attach, and listen commands now update the
2011 ;;   the-debugger field in the jde-db-debugger class.
2012 ;;
2013 ;; Revision 1.13  2002/03/04 06:43:41  paulk
2014 ;; Adds support for connecting debugger to an independently started
2015 ;; process, using either attach or listen mode.
2016 ;;
2017 ;; Revision 1.12  2002/02/08 12:04:00  paulk
2018 ;; Completed implementation of step-into and step-out commands.
2019 ;;
2020 ;; Revision 1.11  2002/02/04 05:47:17  paulk
2021 ;; Added code to rehighlight breakpoints if the user kills a
2022 ;; buffer for a source file that contains breakpoints and
2023 ;; then reopens the file.
2024 ;;
2025 ;; Revision 1.10  2002/01/15 13:34:24  paulk
2026 ;; Adds a Clear Breakpoints command for jdb.
2027 ;;
2028 ;; Revision 1.9  2002/01/14 13:33:57  paulk
2029 ;; - Now defines three breakpoint marker colors: green for a specified breakpoint,
2030 ;;   yellow for a requested breakpoint, and red for an enabled breakpoint.
2031 ;;
2032 ;; - The debug application command now requests all specified
2033 ;;   breakpoints at the beginning of a debug session.
2034 ;;
2035 ;; - The debug application command now changes the color of all breakpoints
2036 ;;   to green (specified) at the end of a debug session.
2037 ;;
2038 ;; Revision 1.8  2002/01/11 05:45:23  paulk
2039 ;; - Use overlays/extents to record location of breakpoints in a buffer.
2040 ;; - Use different colors to indicate requested and enabled breakpoints.
2041 ;;
2042 ;; Revision 1.7  2002/01/02 05:34:31  paulk
2043 ;; * Fixed some bugs in jdb stack navigation commands.
2044 ;; * Moved the where command out processing from the jdb stack listener
2045 ;;   to the whre cmd response method where it belongs.
2046 ;; * Added key bindings for jdb commands.* Fixed some bugs in jdb stack navigation commands.
2047 ;;
2048 ;; Revision 1.6  2001/12/31 07:54:39  paulk
2049 ;; Implemented jdb versions of generalized
2050 ;; quit, step-over, step-into, stack up, stack down,
2051 ;; and stack where commands.
2052 ;;
2053 ;; Revision 1.5  2001/12/28 05:35:45  paulk
2054 ;; * Implemented jdb versions of generalized stop and continue process commands.
2055 ;;
2056 ;; * Implemented breakpoint and stack message listeners.
2057 ;;
2058 ;; Revision 1.4  2001/12/17 08:07:47  paulk
2059 ;; jdb implementation of generalized clear breakpoint command.
2060 ;;
2061 ;; Revision 1.3  2001/12/10 04:29:54  paulk
2062 ;; Created generalized breakpoint framework. Provided initial
2063 ;; implementation for jdb. A lot of work remains.
2064 ;;
2065 ;; Revision 1.2  2001/12/04 06:05:36  paulk
2066 ;; Removed carriage returns.
2067 ;;
2068 ;; Revision 1.1  2001/12/04 05:25:40  paulk
2069 ;; Initial revision.
2070 ;;
2071
2072 ;;; end of jde-jdb.el