;;; jde-db.el -- Debugger mode for jdb.;; $Revision$ $Date$ ;; Author: Paul Kinnucan <paulk@mathworks.com>;; Maintainer: Paul Kinnucan;; Keywords: java, tools;; Copyright (C) 1997, 2000, 2001, 2002 Paul Kinnucan.;; GNU Emacs is free software; you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation; either version 2, or (at your option);; any later version.;; GNU Emacs is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU Emacs; see the file COPYING. If not, write to the;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, US;;; Commentary:;; This package interfaces emacs to jdb, the debugger;; distributed as part of JavaSoft's Java;; Development Kit (JDK).;; Please send bug reports and enhancement suggestions;; to Paul Kinnucan at <paulk@mathworks.com>;; See end of this file for change history.;;; Code:(require'jde-parse)(require'eieio)(require'jde-util);; ======================================================================;; jde-db variables(defcustomjde-db-query-missing-source-filest"If nonnil, this variable causes the debugger to query youfor the path of a class source file that it cannot find in`jde-sourcepath'.":group'jde-project:type'boolean)(defcustomjde-db-mode-hooknil"*Customization hook for jde-db inferior mode.":group'jde-project:type'hook)(defcustomjde-db-initial-step-pt"*If non-nil, this option causes the debuggerto issue a step-into command after launchinga program. This causes the vm to step to thefirst line of the debuggee program.":group'jde-project:type'boolean)(defcustomjde-db-startup-commandsnil"*Commands to run at debugger startup.":group'jde-project:type'(repeat(string:tag"Command")))(defcustomjde-db-read-vm-argsnil"*Read vm arguments from the minibuffer.If this variable is non-nil, the jde-db command reads vm argumentsfrom the minibuffer and appends them to those specified bythe `jde-db-option' variable group.":group'jde-project:type'boolean)(defvarjde-db-interactive-vm-arg-historynil"History of vm arguments read from the minibuffer")(defcustomjde-db-read-app-argsnil"*Read arguments to be passed to application from the minibuffer.":group'jde-project:type'boolean)(defvarjde-db-interactive-app-arg-historynil"History of application arguments read from the minibuffer")(defcustomjde-db-classic-mode-vmnil"Runs applications in the classic (i.e., not HotSpot) mode whendebugging.":group'jde-project:type'boolean)(defgroupjde-db-optionsnil"JDE Debugger Options":group'jde:prefix"jde-db-option-")(defcustomjde-db-option-classpathnil"*Specify paths of classes required to run this application.The JDE uses the specified paths to construct a -classpathargument to pass to the Java interpreter. This option overrides the`jde-global-classpath' option.":group'jde-db-options:type'(repeat(file:tag"Path")))(defcustomjde-db-option-verbose(listnilnilnil)"*Print messages about the running process.The messages are printed in the run buffer.":group'jde-db-options:type'(list:indent2(checkbox:format"\n %[%v%] %h \n":doc"Print classes loaded.Prints a message in the run buffer each time a class is loaded.")(checkbox:format"%[%v%] %h \n":doc"Print memory freed.Prints a message in the run buffer each time the garbage collectorfrees memory.")(checkbox:format"%[%v%] %h \n":doc"Print JNI info.Prints JNI-related messages including information about which nativemethods have been linked and warnings about excessive creation oflocal references.")))(defcustomjde-db-option-propertiesnil"*Specify property values.Enter the name of the property, for example, awt.button.color, in theProperty Name field; enter its value, for example, green, in theProperty Value field. You can specify as many properties as you like.":group'jde-db-options:type'(repeat(cons(string:tag"Property Name")(string:tag"Property Value"))))(defcustomjde-db-option-heap-size(list(cons1"megabytes")(cons16"megabytes"))"*Specify the initial and maximum size of the interpreter heap.":group'jde-db-options:type'(list(cons(integer:tag"Start")(radio-button-choice(const"bytes")(const"kilobytes")(const"megabytes")))(cons(integer:tag"Max")(radio-button-choice(const"bytes")(const"kilobytes")(const"megabytes")))))(defcustomjde-db-option-stack-size(list(cons128"kilobytes")(cons400"kilobytes"))"*Specify size of the C and Java stacks.":group'jde-db-options:type'(list(cons(integer:tag"C Stack")(radio-button-choice(const"bytes")(const"kilobytes")(const"megabytes")))(cons(integer:tag"Java Stack")(radio-button-choice(const"bytes")(const"kilobytes")(const"megabytes")))))(defcustomjde-db-option-garbage-collection(listtt)"*Specify garbage collection options.":group'jde-db-options:type'(list:indent2(checkbox:format"%[%v%] %t \n":tag"Collect garbage asynchronously.")(checkbox:format"%[%v%] %t \n":tag"Collect unused classes.")))(defcustomjde-db-option-java-profile(consnil"./java.prof")"*Enable Java profiling.":group'jde-db-options:type'(consboolean(file:tag"File":help-echo"Specify where to put profile results here.")))(defcustomjde-db-option-heap-profile(consnil(list"./java.hprof"520"Allocation objects"))"*Output heap profiling data.":group'jde-db-options:type'(consboolean(list(string:tag"Output File Path")(integer:tag"Stack Trace Depth")(integer:tag"Allocation Sites")(radio-button-choice:format"%t \n%v":tag"Sort output based on:"(const"Allocation objects")(const"Live objects")))))(defcustomjde-db-option-verify(listnilt)"*Verify classes.":group'jde-db-options:type'(list:indent2(checkbox:format"%[%v%] %t \n":tag"Executed code in all classes.")(checkbox:format"%[%v%] %t \n":tag"Classes loaded by a classloader.")))(defcustomjde-db-option-host"""Host of a remote process to which you wish to attach. Thisoption is invalid for JDK verions greater than JDK 1.1.x.":group'jde-db-options:type'string);; (makunbound 'jde-db-option-connect-address)(defcustomjde-db-option-connect-addressnil"Specify address used to connect the debugger to a running process.If nil, this option defaults to \"javadebug\" on Windows systemsand \"4444\" on UNIX systems.":group'jde-db-options:type'(choice(const:menu-tag"Use Default"nil)(string:menu-tag"Specify Value":tag"value")))(defcustomjde-db-option-vm-argsnil"*Specify arguments to be passed to the Java vm.This option allows you to specify one or more arguments to be passedto the Java interpreter. It is an alternative to using JDE Run Optionvariables, such as `jde-run-option-stack-size', to specify Javainterpreter options. Also, it makes it possible to use the JDE withinterpreters that accept command line arguments not supported by the JDE Run Option variable set.":group'jde-db-options:type'(repeat(string:tag"Argument")))(defcustomjde-db-option-application-argsnil"*Specify command-line arguments to pass to the application.The JDE passes the specified arguments to the application onthe command line.":group'jde-db-options:type'(repeat(string:tag"Argument")))(defmacrojde-assert-source-or-debug-buffer()"Asserts that the current buffer is aJava source or a debug buffer."'(assert(or(eqmajor-mode'jde-mode)(and(slot-boundp'jde-db-debugger'the-debugger)(eq(current-buffer)(oref(oref'jde-db-debuggerthe-debugger)buffer))))nil"This command works only in a Java source or debug buffer."))(defcustomjde-db-log-debugger-output-flagnil"Log raw debugger output to a buffer. This variable is intendedto be used for debugging the JDEE's debuggers.":group'jde-db-options:type'boolean)(defunjde-db-log-debugger-output(output)(ifjde-db-log-debugger-output-flag(let((buf(get-buffer"debugger output")))(when(notbuf)(setqbuf(get-buffer-create"debugger output"))(pop-to-bufferbuf))(save-excursion(set-bufferbuf)(goto-char(point-max))(insert-stringoutput)))))(defunjde-db-get-debuggee-status()"Get the`jde-db-debuggee-status' of the current debuggee process."(if(slot-boundp'jde-db-debugger'the-debugger)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee)))(orefdebuggeestatus))))(defunjde-db-debuggee-stopped-p()"Return t if current debuggee process is stopped."(let((status(jde-db-get-debuggee-status)))(ifstatus(orefstatusstopped-p))))(defunjde-db-debuggee-suspended-p()"Return t if current debuggee process is suspended."(let((status(jde-db-get-debuggee-status)))(ifstatus(orefstatussuspended-p))))(defunjde-db-debuggee-running-p()"Return t if current debuggee process is running."(let((status(jde-db-get-debuggee-status)))(ifstatus(orefstatusrunning-p))));;;###autoload(defunjde-db-set-debugger(nameis-executable)"Specify the pathname of the debugger, if an executable, or thedebugger's fully qualified class name, if a class."(interactive"sEnter name of Java interpreter: \nsIs %s executable? (yes): ")(let((dbname)(type(if(stringpis-executable)(if(or(string=is-executable"")(eq(arefis-executable0)?y))"Executable""Class")"Executable")))(setqjde-db-debugger(cons"Other"(consdbtype)))));;;###autoload(defunjde-db-set-args(args)"Specify the arguments (except -classpath) to be passed to the debugger."(interactive"sEnter arguments: ")(setqjde-db-option-vm-args(jde-run-parse-argsargs)));;;###autoload(defunjde-db-set-app-args(args)"Specify the arguments to be passed to the Java application class."(interactive"sEnter arguments: ")(setqjde-db-option-application-args(jde-run-parse-argsargs)));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Breakpoints ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defcustomjde-db-spec-breakpoint-face-colors(cons"black""green")"*Specifies the foreground and background colors used to highlightthe line at which you have specified that a breakpoint to be set.":group'jde-project:type'(cons:tag"Colors"(string:tag"Foreground")(string:tag"Background")):set'(lambda(symval)(make-face'jde-db-spec-breakpoint-face)(set-face-foreground'jde-db-spec-breakpoint-face(carval))(set-face-background'jde-db-spec-breakpoint-face(cdrval))(set-defaultsymval)))(defcustomjde-db-requested-breakpoint-face-colors(cons"black""yellow")"*Specifies the foreground and background colors used to highlightthe line at which you have requested a breakpoint to be set.":group'jde-project:type'(cons:tag"Colors"(string:tag"Foreground")(string:tag"Background")):set'(lambda(symval)(make-face'jde-db-requested-breakpoint-face)(set-face-foreground'jde-db-requested-breakpoint-face(carval))(set-face-background'jde-db-requested-breakpoint-face(cdrval))(set-defaultsymval)))(defcustomjde-db-active-breakpoint-face-colors(cons"black""red")"*Specifies the foreground and background colors used to highlighta line where an active breakpoint exists.":group'jde-project:type'(cons:tag"Colors"(string:tag"Foreground")(string:tag"Background")):set'(lambda(symval)(make-face'jde-db-active-breakpoint-face)(set-face-foreground'jde-db-active-breakpoint-face(carval))(set-face-background'jde-db-active-breakpoint-face(cdrval))(set-defaultsymval)));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Breakpoint Marker Class ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defclassjde-db-breakpoint-marker()((marker:initarg:marker:documentation"Overlay in Emacs, extent in XEmacs"))"Indicates the location of breakpoints in a source buffer. This classuses overlays as markers in Emacs and extents in XEmacs.")(defmethodinitialize-instance((thisjde-db-breakpoint-marker)&restfields)"Create a breakpoint overlay at LINE in FILE.";; Call parent initializer.(call-next-method)(osetthismarker(if(featurep'xemacs)(if(or(not(extent-at(line-beginning-position)))(not(jde-db-breakpoint-marker-p(extent-at(line-beginning-position)))))(make-extent(line-beginning-position)(1+(line-end-position))))(make-overlay(line-beginning-position)(1+(line-end-position))(current-buffer)nilt))))(defmethodjde-db-breakpoint-marker-set-face((thisjde-db-breakpoint-marker)face)"Apply FACE to OVERLAY."(let((marker(orefthismarker)))(if(featurep'xemacs)(progn(set-extent-facemarkerface)(set-extent-prioritymarker98))(progn(overlay-putmarker'faceface)(overlay-putmarker'priority98)))))(defunjde-db-breakpoint-marker-p(marker)"Return t if overlay is a breakpoint marker overlay."(let((marker-face(if(featurep'xemacs)(extent-propertymarker'facenil)(overlay-getmarker'face))))(or(eqmarker-face'jde-db-spec-breakpoint-face)(eqmarker-face'jde-db-requested-breakpoint-face)(eqmarker-face'jde-db-active-breakpoint-face))))(defmethodjde-db-breakpoint-marker-delete((thisjde-db-breakpoint-marker))"Remove breakpoint overlay at LINE in FILE."(if(featurep'xemacs)(delete-extent(orefthismarker))(delete-overlay(orefthismarker))));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Breakpoint Class ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defclassjde-db-breakpoint()((id:initarg:id:typeinteger:documentation"Identifies this breakpoint.")(file:initarg:file:initform"":typestring:documentation"Pathname of file containing this breakpoint.")(line:initarg:line:typeinteger:documentation"Number of line at which breakpoint is set.")(marker:initarg:marker:type(ornulljde-db-breakpoint-marker):initformnil:documentation"Marker used to highlight breakpoint line.")(class:initarg:class:typestring:documentation"Qualified name of class containing breakpoint.")(status:initargstatus:typesymbol:initformspecified:documentation"Status of this breakpoint. Legal values are `specified', `requested', `active'."))(:allow-nil-initformt)"Class of breakpoints.")(defmethodinitialize-instance((thisjde-db-breakpoint)&restfields)"Constructor for a breakpoint specification.";; Call parent initializer.(call-next-method)(assert(orefthisfile))(osetthismarker(jde-db-breakpoint-marker"breakpoint marker"))(jde-db-breakpoint-marker-set-face(orefthismarker)'jde-db-spec-breakpoint-face))(defmethodjde-db-breakpoint-get-line((thisjde-db-breakpoint))"Get the number of the line at which this breakpoint is set."(save-excursion(set-buffer(find-file-noselect(orefthisfile)))(if(orefthismarker)(let((marker-start(if(featurep'xemacs)(extent-start-position(oref(orefthismarker)marker))(overlay-start(oref(orefthismarker)marker)))))(jde-get-line-at-pointmarker-start))(orefthisline))))(defvarjde-db-breakpointsnil"Current breakpoints.")(defunjde-db-get-breakpoint-marker(fileline)"Get breakpoint marker at FILE and LINE."(let((bp(jde-db-find-breakpointfileline)))(ifbp(orefbpmarker))))(defunjde-db-mark-breakpoint-specified(fileline)"Changes the face of the breakpoint marker at LINE in FILE to the specified face."(let((marker(jde-db-get-breakpoint-markerfileline)))(ifmarker(jde-db-breakpoint-marker-set-facemarker'jde-db-spec-breakpoint-face))))(defunjde-db-mark-breakpoint-active(fileline)"Changes the face of the breakpoint marker at LINE in FILE to the active face."(let((marker(jde-db-get-breakpoint-markerfileline)))(ifmarker(jde-db-breakpoint-marker-set-facemarker'jde-db-active-breakpoint-face))))(defunjde-db-mark-breakpoint-requested(fileline)"Changes the face of the breakpoint marker at LINE in FILE to the active face."(let((marker(jde-db-get-breakpoint-markerfileline)))(ifmarker(jde-db-breakpoint-marker-set-facemarker'jde-db-requested-breakpoint-face))))(defunjde-db-set-all-breakpoints-specified()"Changes the face of all breakpoints to `jde-db-spec-breakpoint-face'and sets the status of all breakpoints to `specified'."(loopforbp-associnjde-db-breakpointsdo(let*((bp(cdrbp-assoc))(marker(orefbpmarker)))(osetbpstatus'specified)(ifmarker(jde-db-breakpoint-marker-set-facemarker'jde-db-spec-breakpoint-face)))))(defunjde-db-delete-breakpoint(bp)"Delete the breakpoint at LINE in FILE."(setqjde-db-breakpoints(remove-if(lambda(assoc)(let*((xbp(cdrassoc))(xfile(orefxbpfile))(xline(jde-db-breakpoint-get-linexbp))(deletep(and(string=(orefbpfile)xfile)(equal(jde-db-breakpoint-get-linebp)xline))))(ifdeletep(jde-db-breakpoint-marker-delete(orefbpmarker)))deletep))jde-db-breakpoints)))(defunjde-db-clear-breakpoints()"Clear all breakpoints from all buffers."(mapc(lambda(assoc)(let*((xbp(cdrassoc))(file(orefxbpfile))(buf(find-buffer-visitingfile)))(ifbuf(save-excursion(set-bufferbuf)(let((xmarker(orefxbpmarker)))(jde-db-breakpoint-marker-deletexmarker))))))jde-db-breakpoints)(setqjde-db-breakpointsnil))(defunjde-db-breakpoints-add(bp)"Adds this breakpoint to the list of breakpoints."(setqjde-db-breakpoints(cons(cons(orefbpid)bp)jde-db-breakpoints)))(defunjde-db-find-breakpoint(fileline)"Finds the breakpoint object for the breakpoint at FILE and LINE."(cdr(find-if(lambda(assoc)(let((bp(cdrassoc)))(and(string=(orefbpfile)file)(equal(jde-db-breakpoint-get-linebp)line))))jde-db-breakpoints)))(defvarjde-db-breakpoint-id-counter0"Counter for generating breakpoint ids")(defunjde-db-nullify-breakpoint-markers()"Set the marker field for each breakpointin the current buffer to nil."(when(eqmajor-mode'jde-mode)(let((file(buffer-file-name)))(loopforbp-associnjde-db-breakpointsdo(let((bp(cdrbp-assoc)))(when(string=(orefbpfile)file)(osetbpline(jde-db-breakpoint-get-linebp))(osetbpmarkernil)))))))(add-hook'kill-buffer-hook'jde-db-nullify-breakpoint-markers)(defunjde-db-remark-breakpoints()"Highlights all breakpoints in the current buffer if not already highlighted."(save-excursion(loopforbp-associnjde-db-breakpointsdo(let*((bp(cdrbp-assoc))(file(buffer-file-name))(line(orefbpline))(status(orefbpstatus)))(goto-lineline)(osetbpmarker(jde-db-breakpoint-marker"breakpoint marker"))(cond((eqstatus'specified)(jde-db-mark-breakpoint-specifiedfileline))((eqstatus'requested)(jde-db-mark-breakpoint-requestedfileline))((eqstatus'active)(jde-db-mark-breakpoint-activefileline))(t(error"Unknown breakpoint status: %s"(symbol-namestatus))))))))(add-hook'jde-mode-hook'jde-db-remark-breakpoints);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Debug Cursor Handling ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defunjde-db-query-source-file(class)(let((source-file(read-file-name(format"Cannot find %s source. Enter path: "class))))(if(andsource-file(file-exists-psource-file)(not(file-directory-psource-file)))(find-file-noselectsource-file))))(defunjde-db-find-class-source(class)"Find and open the source file for a class. CLASS is the fullyqualified name of the class. If this function is unable to find thesource for CLASS in `jde-sourcepath' and`jde-db-query-missing-source-files' is nonnil, this function queriesthe user for the path to the source file. If successful, this functionreturns an unselected buffer containing the source file for theclass. Otherwise, it returns nil."(let*((source-file(jde-find-class-source-fileclass))(source-buffer(ifsource-file(find-file-noselectsource-file)(ifjde-db-query-missing-source-files(jde-db-query-source-fileclass)))))source-buffer))(defunjde-db-set-debug-cursor(classfileline)"Shows the source at LINE in CLASS."(let*((buffer(jde-db-find-class-sourceclass))(window(andbuffer(or(get-buffer-windowbuffer)(selected-window))))pos)(ifbuffer(progn(if(not(get-buffer-windowbuffer))(set-window-bufferwindowbuffer))(save-excursion(set-bufferbuffer)(save-restriction(widen)(goto-lineline)(setqpos(point))(setqoverlay-arrow-string"=>")(oroverlay-arrow-position(setqoverlay-arrow-position(make-marker)))(set-markeroverlay-arrow-position(point)(current-buffer)))(cond((or(<pos(point-min))(>pos(point-max)))(widen)(goto-charpos))))(set-window-pointwindowoverlay-arrow-position)))));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Debuggee Process Class ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defclassjde-db-debuggee-status()((running-p:initarg:running-p:typeboolean:initformnil:documentation"Non-nil if debuggee process is running.")(stopped-p:initarg:stopped-p:typeboolean:initformnil:documentation"Non-nil if debugee process is stopped.")(suspended-p:initarg:suspended-p:typeboolean:initformnil:documentation"Non-nil if debugee process is suspended."))"Status of debuggee process.")(defmethodinitialize-instance((thisjde-db-debuggee-status)&restfields)"Status of debuggee process."(call-next-method));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Debuggee Process Class ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defclassjde-db-debuggee()((main-class:initarg:main-class:typestring:documentation"Qualified name of debuggee main class.")(address:initarg:address:type(ornullstring):initformnil:documentation"String that identifies the vm to be debugged.")(status:initarg:status:typejde-db-debuggee-status:documentation"Status of debuggee process.")(stack-depth:initarg:stack-depth:typestring:initform"":documentation"Stack depth."))"Application being debugged.")(defmethodinitialize-instance((thisjde-db-debuggee)&restfields)"Constructs an instance of a debuggee."(call-next-method)(assert(or(slot-boundpthis'main-class)(slot-boundpthis'address)))(osetthisstatus(jde-db-debuggee-status"debuggee status")));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Debugger Command Line Commands ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defclassjde-db-cmd()((name:initarg:name:typestring:documentation"Name of command.")(debugger:initarg:debugger:typejde-db-debugger:documentation"Debugger."))"Super class of debugger commands.")(defmethodinitialize-instance((thisjde-db-cmd)&restfields)"Constructor for debugger commands."(call-next-method))(defmethodjde-db-cmd-init((thisjde-db-cmd))"The debugger invokes this method before executing the command.")(defmethodjde-db-cmd-make-command-line((thisjde-db-cmd))"Creates the command line for this command."(orefthisname))(defmethodjde-db-cmd-notify-response((thisjde-db-cmd)response)"Invoked when the debugger responds to the command. RESPONSEis the response.")(defmethodjde-db-cmd-response-p((thisjde-db-cmd)output)"Returns nonnil if external debugger's output is a response to this command."t)(defclassjde-db-cmd-breakpoint(jde-db-cmd)((breakpoints:initarg:breakpoints:typelist:documentation"List of breakpoint specification."))"Class of breakpoint commands.");; Generic Debugger Command Set.(defclassjde-db-cmd-set()((debugger:initarg:debugger:typejde-db-debugger:documentation"Debugger that owns this command set.")(launch:initarg:launch:typejde-db-cmd:documentation"Launch debuggee application")(run:initarg:run:typejde-db-cmd:documentation"Starts the current debuggee application.")(cont:initarg:cont:typejde-db-cmd:documentation"Continues the current debuggee application.")(quit:initarg:quit:typejde-db-cmd:documentation"Quit debugging the current application.")(step-over:initarg:step-over:typejde-db-cmd:documentation"Step to the next line in the current frame.")(step-into:initarg:step-into:typejde-db-cmd:documentation"Step to the next line in the current program.")(step-out:initarg:step-out:typejde-db-cmd:documentation"Continue to the end of the current method.")(up:initarg:up:typejde-db-cmd:documentation"Move up the stack.")(down:initarg:down:typejde-db-cmd:documentation"Move down the stack.")(where:initarg:where:typejde-db-cmd:documentation"Point to the current stopping point.")(set-bp:initarg:set-bp:typejde-db-cmd:documentation"Cmd that asks debugger to set a breakpoint.")(clear-bp:initarg:clear-bp:typejde-db-cmd:documentation"Cmd that asks debugger to set a breakpoint."))"Set of debugger commands implemented by this debugger.");;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Debug Process Listener ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defclassjde-db-listener()((debugger:initarg:debugger:typejde-db-debugger:documentation"The debugger"))"Listens to the output from the debugger.")(defmethodjde-db-listener-filter-output((thisjde-db-listener)output)"Filters the output of the debugger."output);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Class of JDE Debuggers ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;(defclassjde-db-debugger()((name:initarg:name:typestring:initform"Java debugger":documentation"Name of this Java debugger.")(buffer-name:initarg:buffer-name:initform"Java Debugger":typestring:documentation"Name of buffer used to interact with debugger.")(buffer:initarg:buffer:typebuffer:documentation"Buffer used to interact with debugger.")(process:initarg:process:documentation"Debugger process.")(running-p:initarg:process:typeboolean:initformnil:documentation"Non-nil if debugger process is running.")(proc-filter:initarg:proc-filter:typefunction:documentation"Function used to parse debug output.")(listeners:initarg:listeners:typelist:initformnil:documentation"List of debugger output listeners.")(cmd-set:initarg:cmd-set:typejde-db-cmd-set:documentation"Commands implemented by this debugger.")(next-cmd:initarg:next-cmd:typelist:initformnil:documentation"Next command(s) to execute.")(last-cmd:initarg:last-cmd:type(ornulljde-db-cmd):documentation"Last command send to the debugger.")(debuggee:initarg:debuggee:typejde-db-debuggee:documentation"Application process being debugged.")(the-debugger:typejde-db-debugger:allocation:class:documentation"The currently active debugger."))"Class of Java debuggers.")(defmethodinitialize-instance((thisjde-db-debugger)&restfields)"Constructor for generic debugger."(osetthiscmd-set(jde-db-cmd-set"Generic commands":debuggerthis))(osetthislast-cmdnil))(defmethodjde-db-ready-p((thisjde-db-debugger)output)"Nonnil if OUTPUT indicates that the debugger is ready to accept the next command."(andoutput(or(string-match">[ ]*$"output)(string-match"[a-zA-Z0-9]+\[[0-9]+\][ ]*$"output)(string-match"VM Started:[ ]*$"output))))(defmethodjde-db-process-debugger-output((thisjde-db-debugger)output)"Process debugger output."(jde-db-log-debugger-output(concat"<<"output">>"))(let((proc(orefthisprocess))(listeners(orefthislisteners))(responseoutput)(last-cmd(orefthislast-cmd)))(loopforlistenerinlistenersdo(setqoutput(jde-db-listener-filter-outputlisteneroutput)))(comint-output-filterprocoutput)(iflast-cmd(jde-db-cmd-notify-responselast-cmdresponse))(if(jde-db-ready-pthis(car(last(split-stringoutput"\n"))))(jde-db-exec-next-cmdthis))))(defmethodjde-db-add-listener((thisjde-db-debugger)listener)"Adds LISTENER to the list of listeners listening for responsefrom the debugger. LISTENER must be an object of type`jde-db-listener'."(assert(typeplistenerjde-db-listener))(osetthislisteners(conslistener(orefthislisteners))))(defmethodjde-db-remove-listener((thisjde-db-debugger)listener)"Removes LISTENER from the list of listeners listening for aresponse from the debugger. LISTENER must be an object of type`jde-db-listener'."(assert(typeplistenerjde-db-listener))(osetthislisteners(removelistener(orefthislisteners))))(defmethodjde-db-set-process-filter((thisjde-db-debugger))"Set debugger process output filter. The default method sets afunction that invokes `jde-db-process-debugger-output'."(set-process-filter(orefthisprocess)(lambda(processoutput)(jde-db-process-debugger-output(oref'jde-db-debuggerthe-debugger)output))))(defmethodjde-db-notify-process-exit((thisjde-db-debugger)msg)"The default debugger process sentinel invokes this method when the debugger process terminates."(let((proc(orefthisprocess)))(cond((null(buffer-name(process-bufferproc)));; buffer killed;; Stop displaying an arrow in a source file.(setqoverlay-arrow-positionnil)(set-process-bufferprocnil))((memq(process-statusproc)'(signalexit));; Stop displaying an arrow in a source file.(setqoverlay-arrow-positionnil)(let*((obuf(current-buffer)));; save-excursion isn't the right thing if;; process-buffer is current-buffer(unwind-protect(progn;; Write something in debugger buffer and hack its mode line,(set-buffer(process-bufferproc));; Fix the mode line.(setqmode-line-process(concat":"(symbol-name(process-statusproc))))(force-mode-line-update)(if(eobp)(insert?\nmode-name" "msg)(save-excursion(goto-char(point-max))(insert?\nmode-name" "msg)));; If buffer and mode line will show that the process;; is dead, we can delete it now. Otherwise it;; will stay around until M-x list-processes.(delete-processproc));; Restore old buffer, but don't restore old point;; if obuf is the command buffer.(set-bufferobuf)))))))(defmethodjde-db-notify-process-status-change((thisjde-db-debugger)msg)"The debugger process sentinel invokes this method when the status ofthe debugger process changes. The default method invokes `jde-db-notify-process-exit'."(jde-db-notify-process-exitthismsg))(defmethodjde-db-set-process-sentinel((thisjde-db-debugger))(set-process-sentinel(orefthisprocess)(lambda(processmsg)(jde-db-notify-process-status-change(oref'jde-db-debuggerthe-debugger)msg))))(defmethodjde-db-exec-next-cmd((thisjde-db-debugger))"Executes the next command on the debugger's pendingcommand list."(let((curr-cmd(car(orefthisnext-cmd))))(ifcurr-cmd(progn(osetthisnext-cmd(cdr(orefthisnext-cmd)))(osetthislast-cmdcurr-cmd)(jde-db-cmd-initcurr-cmd)(save-excursion(set-buffer(orefthisbuffer))(let((proc(orefthisprocess)))(goto-char(point-max))(insert(jde-db-cmd-make-command-linecurr-cmd))(comint-send-input)))))))(defmethodjde-db-exec-cmds((thisjde-db-debugger)cmds)"Executes list of debugger CMDS."(osetthisnext-cmdcmds)(jde-db-exec-next-cmdthis))(defmethodjde-db-exec-cmd((thisjde-db-debugger)cmd)"Executes CMD."(assert(andcmd(typepcmd'jde-db-cmd)))(jde-db-exec-cmdsthis(listcmd)))(defmethodjde-db-classpath-arg((thisjde-db-debugger))"Generate the -classpath command line argument for jdb.";; Set the classpath option. Use the local;; classpath, if set; otherwise, the global;; classpath.(let((classpath(ifjde-db-option-classpathjde-db-option-classpathjde-global-classpath))(symbol(ifjde-db-option-classpath'jde-db-option-classpath'jde-global-classpath)))(ifclasspath(list"-classpath"(jde-build-classpathclasspathsymbol)))))(defmethodjde-db-classic-mode-arg((thisjde-db-debugger))"Generate the classic mode command-line argument for jdb."(ifjde-db-classic-mode-vm(list"-classic")))(defmethodjde-db-property-args((thisjde-db-debugger))"Generate property arguments."(ifjde-db-option-properties(mapcar(lambda(prop)(concat"-D"(carprop)"="(cdrprop)))jde-db-option-properties)))(defmethodjde-db-verbose-args((thisjde-db-debugger))"Get the debugger verbosity arguments for jdb."(let((print-classes-loaded(nth0jde-db-option-verbose))(print-memory-freed(nth1jde-db-option-verbose))(print-jni-info(nth2jde-db-option-verbose))options)(ifprint-classes-loaded(add-to-list'options"-verbose:class"))(ifprint-memory-freed(add-to-list'options"-verbosegc"))(ifprint-jni-info(add-to-listoptions"-verbosejni"))options))(defmethodjde-db-heap-size-args((thisjde-db-debugger))"Generate heap size options."(let*((memory-unit-abbrevs(list(cons"bytes""")(cons"kilobytes""k")(cons"megabytes""m")))(start-cons(nth0jde-db-option-heap-size))(start-size(format"%d%s"(carstart-cons)(cdr(assoc(cdrstart-cons)memory-unit-abbrevs))))(max-cons(nth1jde-db-option-heap-size))(max-size(format"%d%s"(carmax-cons)(cdr(assoc(cdrmax-cons)memory-unit-abbrevs))))options)(if(not(string=start-size"1m"))(setqoptions(appendoptions(list(concat"-Xms"start-size)))))(if(not(string=max-size"16m"))(setqoptions(appendoptions(list(concat"-Xmx"max-size)))))options))(defmethodjde-db-stack-size-args((thisjde-db-debugger))"Generate stack size arguments."(let*((memory-unit-abbrevs(list(cons"bytes""")(cons"kilobytes""k")(cons"megabytes""m")))(c-cons(nth0jde-db-option-stack-size))(c-size(format"%d%s"(carc-cons)(cdr(assoc(cdrc-cons)memory-unit-abbrevs))))(java-cons(nth1jde-db-option-stack-size))(java-size(format"%d%s"(carjava-cons)(cdr(assoc(cdrjava-cons)memory-unit-abbrevs))))option)(if(not(string=c-size"128k"))(setqoption(appendoption(list(concat"-Xss"c-size)))))(if(not(string=java-size"400k"))(setqoption(appendoption(list(concat"-Xoss"java-size)))))option))(defmethodjde-db-garbage-collection-args((thisjde-db-debugger))"Set garbage collection options."(let((no-gc-asynch(not(nth0jde-db-option-garbage-collection)))(no-gc-classes(not(nth1jde-db-option-garbage-collection)))options)(ifno-gc-asynch(setqoptions(appendoptions'("-Xnoasyncgc"))))(ifno-gc-classes(setqoptions(appendoptions'("-Xnoclassgc"))))options))(defmethodjde-db-garbage-collection-arg((thisjde-db-debugger))"Generate Java profile arg."(let((profilep(carjde-db-option-java-profile))(file(cdrjde-db-option-java-profile)))(ifprofilep(if(string=file"./java.prof")(list"-Xprof")(list(concat"-Xprof:"file))))))(defmethodjde-db-heap-profile-arg((thisjde-db-debugger))"Generate heap profile option."(let*((profilep(carjde-db-option-heap-profile))(prof-options(cdrjde-db-option-heap-profile))(file(nth0prof-options))(depth(nth1prof-options))(top(nth2prof-options))(sort(downcase(substring(nth3prof-options)01))))(ifprofilep(if(and(string=file"./java.hprof")(equaldepth5)(equaltop20)(string=sort"a"))(list"-Xhprof")(list(format"-Xhprof:file=%s,depth=%d,top=%d,sort=%s"filedepthtopsort))))))(defmethodjde-db-verify-arg((thisjde-db-debugger));; Set verify options.(let((verify-all(nth0jde-db-option-verify))(verify-remote(nth1jde-db-option-verify)))(ifverify-all(list"-Xverify"); (if verify-remote; (list "-Xverifyremote"))(if(and(notverify-all)(notverify-remote))(list"-Xnoverify")))))(defmethodjde-db-command-line-args((thisjde-db-debugger))"Generate command line args."(ifjde-db-option-vm-args(mapcar(lambda(arg)arg)jde-db-option-vm-args)))(defmethodjde-db-host-arg((thisjde-db-debugger))(if(not(string=jde-db-option-host""))(list"-host"jde-db-option-host)))(defmethodjde-db-launch-arg((thisjde-db-debugger))"Argument that tells the debugger to launch the debuggee vm immediately instead of waiting for a run command. Only the new (JDK 1.3) version of jdbprovides this option."nil)(defmethodjde-db-get-vm-args((thisjde-db-debugger))(append(jde-db-classic-mode-argthis)(jde-db-launch-argthis)(jde-db-classpath-argthis)(jde-db-property-argsthis)(jde-db-verbose-argsthis)(jde-db-heap-size-argsthis)(jde-db-command-line-argsthis)))(defmethodjde-db-debugger-get-working-dir((thisjde-db-debugger))(if(string=jde-run-working-directory"")default-directory(jde-normalize-path'jde-run-working-directory)))(defmethodjde-db-debugger-get-prog-args((thisjde-db-debugger)))(defmethodjde-db-debugger-start((thisjde-db-debugger)prog-argscmdstr)"Start the debugger."(let((w32-quote-process-args?\")(win32-quote-process-args?\");; XEmacs(source-directorydefault-directory)(working-directory(jde-db-debugger-get-working-dirthis)))(osetthis:buffer(get-buffer-create(orefthis:buffer-name)))(save-excursion(set-buffer(orefthis:buffer));; Do not erase the last transcript; user may wish to view it.;; (erase-buffer)(goto-char(point-max))(cdworking-directory)(insert(concat"cd "working-directory"\n"))(insertcmdstr)(comint-mode)(make-local-variable'comint-prompt-regexp)(setqcomint-prompt-regexp"\\(^> *\\)\\|\\(^.*\\[[0-9]+\\] *\\)")(make-local-variable'paragraph-start)(setqparagraph-startcomint-prompt-regexp)(comint-exec(orefthis:buffer)(orefthis:buffer-name)(orefthis:path)nilprog-args)(osetthisprocess(get-buffer-process(orefthisbuffer)))(cdsource-directory)(jde-db-set-process-filterthis)(jde-db-set-process-sentinelthis)(run-hooks'jde-jdb-mode-hook)(pop-to-buffer(orefthisbuffer))(oset-default'jde-db-debuggerthe-debuggerthis)(osetthisrunning-pt))))(defmethodjde-db-debugger-launch((thisjde-db-debugger))"Launch the debugger."(if(or(not(slot-boundpthis'buffer))(not(orefthis:buffer))(not(comint-check-proc(orefthis:buffer))))(let*((debuggee(orefthisdebuggee))(main-class(orefdebuggeemain-class))(source-directorydefault-directory)(working-directory(jde-db-debugger-get-working-dirthis))(prog-args(jde-db-debugger-get-prog-argsthis))(command-string(concat(orefthis:path)" "(jde-run-make-arg-stringprog-args)"\n\n")))(osetthis:buffer-name(concat"*debug"main-class"*"))(osetthis:buffer(get-buffer-create(orefthis:buffer-name)))(ifjde-db-initial-step-p(let((step-cmd(oref(orefthiscmd-set)step-into)))(osetthisnext-cmd(append(orefthisnext-cmd)(liststep-cmd)))));; Forward to the debugger any breakpoint requests made;; by the user before launching the application.(ifjde-db-breakpoints(let((bp-cmd(oref(orefthiscmd-set)set-bp)))(osetbp-cmdbreakpoints(mapcar(lambda(assoc)(cdrassoc))jde-db-breakpoints))(osetthisnext-cmd(append(orefthisnext-cmd)(listbp-cmd)))))(jde-db-debugger-startthisprog-argscommand-string)(let*((debuggee(orefthisdebuggee))(debuggee-status(orefdebuggeestatus)))(osetdebuggee-statusrunning-pt)(osetdebuggee-statusstopped-pt)))(progn(message"An instance of %s is running."(orefthis:buffer-name))(pop-to-buffer(orefthis:buffer-name)))))(defmethodjde-db-debugger-connect((thisjde-db-debugger)&optionallistenp)"Launch the debugger."(if(or(not(slot-boundpthis'buffer))(not(orefthis:buffer))(not(comint-check-proc(orefthis:buffer))))(let*((debuggee(orefthisdebuggee))(source-directorydefault-directory)(address(orefdebuggee:address))(working-directory(jde-db-debugger-get-working-dirthis))(prog-args(iflistenp(ifaddress(list"-listen"address)(list"-listenany"))(list"-attach"address)))(command-string(format"%s %s\n\n"(orefthis:path)(mapconcat(lambda(x)x)prog-args" "))))(osetthis:buffer-name(concat"*debug "address"*"))(osetthis:buffer(get-buffer-create(orefthis:buffer-name)));; Forward to the debugger any breakpoint requests made;; by the user before launching the application.(ifjde-db-breakpoints(let((bp-cmd(oref(orefthiscmd-set)set-bp)))(osetbp-cmdbreakpoints(mapcar(lambda(assoc)(cdrassoc))jde-db-breakpoints))(osetthisnext-cmd(append(orefthisnext-cmd)(listbp-cmd)))))(jde-db-debugger-startthisprog-argscommand-string)(let*((debuggee(orefthisdebuggee))(debuggee-status(orefdebuggeestatus)))(osetdebuggee-statusrunning-pt)(osetdebuggee-statusstopped-pt)))(progn(message"An instance of %s is running."(orefthis:buffer-name))(pop-to-buffer(orefthis:buffer-name)))));;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Generic Debug Commands ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; The following commands serve as a generalized interface between the;; JDE user and JDE-supported debuggers, e.g., jdb or JDEbug.;; This section is a work in progress. It entails generalizing the;; existing jdb and JDEbug commands and replacing those commands;; with the generalized commands.(defunjde-debug-run()"Start the current debuggee application."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(orefdebuggee-statusrunning-p))(error"Application %s is already running."(orefdebuggeemain-class))(let*((cmd-set(orefdebuggercmd-set))(run(orefcmd-setrun)))(osetdebuggee-statusrunning-pt)(osetdebuggee-statusstopped-pnil)(osetdebuggee-statussuspended-pnil)(jde-db-exec-cmddebuggerrun)))))(defunjde-debug-cont()"Continues the current debuggee application from its currentstopping point."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(or(orefdebuggee-statusstopped-p)(orefdebuggee-statussuspended-p)))(let*((cmd-set(orefdebuggercmd-set))(cont(orefcmd-setcont)))(osetdebuggee-statusstopped-pnil)(osetdebuggee-statussuspended-pnil)(jde-db-exec-cmddebuggercont))(let((class(orefdebuggeemain-class)))(message"Application %s is not stopped"class)))))(defunjde-debug-quit()"Quit debugging the current application."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(orefdebuggee-statusrunning-p))(let*((cmd-set(orefdebuggercmd-set))(quit(orefcmd-setquit)))(jde-db-exec-cmddebuggerquit))(let((class(orefdebuggeemain-class)))(error"Application %s is not running"class)))))(defunjde-debug-step-over()"Step to the next line in the current stack frame."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(orefdebuggee-statusstopped-p))(let*((cmd-set(orefdebuggercmd-set))(step-over(orefcmd-setstep-over)))(osetdebuggee-statusstopped-pnil)(jde-db-exec-cmddebuggerstep-over))(let((class(orefdebuggeemain-class)))(error"Application %s is not stopped"class)))))(defunjde-debug-step-into()"Step to the next line in the current program."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(orefdebuggee-statusstopped-p))(let*((cmd-set(orefdebuggercmd-set))(step-into(orefcmd-setstep-into)))(osetdebuggee-statusstopped-pnil)(jde-db-exec-cmddebuggerstep-into))(let((class(orefdebuggeemain-class)))(error"Application %s is not stopped"class)))))(defunjde-debug-step-out()"Continue execution to the end of the current method."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(orefdebuggee-statusstopped-p))(let*((cmd-set(orefdebuggercmd-set))(step-out(orefcmd-setstep-out)))(osetdebuggee-statusstopped-pnil)(jde-db-exec-cmddebuggerstep-out))(let((class(orefdebuggeemain-class)))(error"Application %s is not stopped"class)))))(defunjde-debug-up()"Move up the stack."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(orefdebuggee-statusstopped-p))(let*((cmd-set(orefdebuggercmd-set))(up(orefcmd-setup)))(jde-db-exec-cmddebuggerup))(let((class(orefdebuggeemain-class)))(error"Application %s is not stopped"class)))))(defunjde-debug-down()"Move down the stack."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(orefdebuggee-statusstopped-p))(let*((cmd-set(orefdebuggercmd-set))(down(orefcmd-setdown)))(jde-db-exec-cmddebuggerdown))(let((class(orefdebuggeemain-class)))(error"Application %s is not stopped"class)))))(defunjde-debug-where()"Show current stopping point."(interactive)(jde-assert-source-or-debug-buffer)(let*((debugger(oref'jde-db-debuggerthe-debugger))(debuggee(orefdebuggerdebuggee))(debuggee-status(orefdebuggeestatus)))(if(and(orefdebuggerrunning-p)(orefdebuggee-statusstopped-p))(let*((cmd-set(orefdebuggercmd-set))(where(orefcmd-setwhere)))(jde-db-exec-cmddebuggerwhere))(let((class(orefdebuggeemain-class)))(error"Application %s is not stopped"class)))))(defunjde-db-spec-breakpoint()"Creates a specification for the breakpoint at the current line in the current file. Returns an object of type `jde-db-breakpoint'."(let((file(buffer-file-name)))(setqjde-db-breakpoint-id-counter(1+jde-db-breakpoint-id-counter))(jde-db-breakpoint(format"breakpoint: %s %d"(file-name-nondirectoryfile)jde-db-breakpoint-id-counter):idjde-db-breakpoint-id-counter:filefile:class(concat(jde-db-get-package)(jde-db-get-class)))))(defunjde-debug-set-breakpoint()"Ask debugger to set a breakpoint at the current line in the current buffer."(interactive)(let*((file(buffer-file-name))(line(jde-get-line-at-point))(bp(jde-db-find-breakpointfileline)))(unlessbp(setqbp(jde-db-spec-breakpoint))(osetbplineline)(jde-db-breakpoints-addbp))(if(and(jde-db-debuggee-running-p)(or(jde-db-debuggee-stopped-p)(jde-db-debuggee-suspended-p)))(let*((debugger(oref'jde-db-debuggerthe-debugger))(bp-cmd(oref(orefdebuggercmd-set)set-bp)))(osetbp-cmdbreakpoints(listbp))(jde-db-exec-cmddebuggerbp-cmd)))))(defunjde-debug-clear-breakpoint()"Clear the breakpoint at the current line in the current buffer."(interactive)(jde-assert-source-buffer)(let*((file(buffer-file-name))(line(jde-get-line-at-point))(bp(jde-db-find-breakpointfileline)))(ifbp(if(and(jde-db-debuggee-running-p)(or(jde-db-debuggee-stopped-p)(jde-db-debuggee-suspended-p)))(let*((debugger(oref'jde-db-debuggerthe-debugger))(bp-cmd(oref(orefdebuggercmd-set)clear-bp)))(osetbp-cmdbreakpoints(listbp))(jde-db-exec-cmddebuggerbp-cmd))(jde-db-delete-breakpointbp)))))(defunjde-debug-toggle-breakpoint()"Sets or clears a breakpoint at the current line."(interactive)(assert(eqmajor-mode'jde-mode)nil"This command works only in a Java source buffer.")(let*((file(buffer-file-name))(line(jde-get-line-at-point))(bp(jde-db-find-breakpointfileline)))(assert(jde-db-src-dir-matches-file-pfile)nil"You cannot set a breakpoint in a file that is not in `jde-sourcepath'.")(ifbp(jde-debug-clear-breakpoint)(jde-debug-set-breakpoint))))(defunjde-debug-clear-breakpoints()"Clear all existing breakpoints."(interactive)(ifjde-db-breakpoints(if(jde-db-debuggee-running-p)(let*((debugger(oref'jde-db-debuggerthe-debugger))(bp-cmd(oref(orefdebuggercmd-set)clear-bp)))(osetbp-cmdbreakpoints(mapcar(lambda(assoc)(cdrassoc))jde-db-breakpoints))(jde-db-exec-cmddebuggerbp-cmd))(loopforbp-associnjde-db-breakpointsdo(let((bp(cdrbp-assoc)))(jde-db-delete-breakpointbp))))))(defvarjde-db-minibuffer-local-mapnil"Keymap for minibuffer prompting of jdb startup command.")(ifjde-db-minibuffer-local-map()(setqjde-db-minibuffer-local-map(copy-keymapminibuffer-local-map))(define-keyjde-db-minibuffer-local-map"\C-i"'comint-dynamic-complete-filename))(defunclass-from-file-name(file-name)(file-name-sans-extension(file-name-nondirectoryfile-name)))(defunjde-db-get-vm-args-from-user()(ifjde-db-read-vm-args(jde-run-parse-args(read-from-minibuffer"Vm args: "(carjde-db-interactive-vm-arg-history)nilnil'jde-db-interactive-vm-arg-history))))(defunjde-db-get-app-args-from-user()(ifjde-db-read-app-args(jde-run-parse-args(read-from-minibuffer"Application args: "(carjde-db-interactive-app-arg-history)nilnil'jde-db-interactive-app-arg-history))))(defunjde-db-get-package()"Return the package of the class whose source file resides in the currentbuffer."(save-excursion(goto-char(point-min))(if(re-search-forward"^[ \t]*\\<\\(package\\) +\\([^ \t\n]*\\) *;"(point-max)t)(concat(buffer-substring-no-properties(match-beginning2)(match-end2))"."))))(defunjde-db-get-class()"Lookups and return fully qualified classname, e.g. A$B if point is in inner class B of A."(interactive)(let((class-info(jde-parse-get-innermost-class-at-point)))(ifclass-info(save-excursion(goto-char(cdrclass-info))(let((parent(jde-db-get-class)))(if(notparent)(carclass-info)(concatparent"$"(carclass-info))))))))(defunjde-db-src-dir-matches-file-p(file)"Return true if one of `jde-sourcepath'matches FILE."(let*((directory-sep-char?/)(filename(jde-normalize-pathfile)))(find-if(lambda(dir-x)(string-match(concat"^"(jde-normalize-pathdir-x'jde-sourcepath))filename))jde-sourcepath)))(provide'jde-db);; Change History;; $Log$;; Revision 1.111 2002/08/27 04:19:01 paulk;; Fixes bug in jde-db-src-dir-matches-file-p. Thanks to Andy Piper.;;;; Revision 1.110 2002/08/10 03:18:30 paulk;; Modified jde-db-breakpoint-marker class so that breakpoint highlighting extends;; the entire width of the buffer window--not just to the end of the line.;; Thanks to Kevin A. Burton.;;;; Revision 1.109 2002/08/07 06:36:18 paulk;; Removed code intended to eliminate spurious warnings when byte-compiling the JDEE. The;; removed code now resides in a separate package, jde-compat.el. Thanks to Andy Piper;; for suggesting this restructuring. Also fixed a number of compiler warnings caused;; by genuine bugs.;;;; Revision 1.108 2002/07/12 12:20:27 jslopez;; Fixes jde-db-option-verbose when set to load classes.;; It was appending -v instead -f -verbose:class.;;;; Revision 1.107 2002/06/17 07:24:08 paulk;; Updated the JDEE's applet debugging command to;; work with its new jdb interface.;;;; Revision 1.106 2002/06/12 07:04:28 paulk;; XEmacs compatibility fix: set win32-quote-process-args wherever;; the JDEE sets w32-quote-process-args. This allows use of spaces in;; paths passed as arguments to processes (e.g., javac) started by;; the JDEE.;;;; Revision 1.105 2002/06/11 06:34:38 paulk;; Provides support for paths containing spaces as jdb arguments via the following change:;; locally set the w32-quote-process-args variable to a quotation mark when launching;; the jdb process.;;;; Revision 1.104 2002/05/21 06:34:27 paulk;; Updated to support J2SDK 1.4.0 version of jdb.;;;; Revision 1.103 2002/05/12 06:37:33 paulk;; Moved jde-db-search-src-dirs to the jde-util package as jde-search-src-dirs.;;;; Revision 1.102 2002/03/31 07:49:51 paulk;; Renamed jde-db-source-directories. The new name is jde-sourcepath.;;;; Revision 1.101 2002/03/12 04:43:38 paulk;; Removed initarg for class slots to silence eieio warning.;;;; Revision 1.100 2002/03/06 13:00:18 paulk;; * Removed references to obsolete jde-db-option-attach variable.;; * The jdb launch, attach, and listen commands now update the;; the-debugger field in the jde-db-debugger class.;;;; Revision 1.99 2002/03/04 06:43:41 paulk;; Adds support for connecting debugger to an independently started;; process, using either attach or listen mode.;;;; Revision 1.98 2002/02/04 05:47:17 paulk;; Added code to rehighlight breakpoints if the user kills a;; buffer for a source file that contains breakpoints and;; then reopens the file.;;;; Revision 1.97 2002/01/19 06:42:22 paulk;; Minor updates.;;;; Revision 1.96 2002/01/15 13:33:27 paulk;; Adds a Clear Breakpoints command for jdb.;;;; Revision 1.95 2002/01/14 13:30:42 paulk;; - Now defines three breakpoint marker colors: green for a specified breakpoint,;; yellow for a requested breakpoint, and red for an enabled breakpoint.;;;; - The debug application command now requests all specified;; breakpoints at the beginning of a debug session.;;;; - The debug application command now changes the color of all breakpoints;; to specified at the end of a debug session.;;;; Revision 1.94 2002/01/11 05:43:37 paulk;; - Use overlays/extents to record location of breakpoints in a buffer.;; - Use different colors to indicate requested and enabled breakpoints.;;;; Revision 1.93 2002/01/04 07:12:17 paulk;; Fixed XEmacs compatibility bug that caused the toggle;; breakpoint command to signal an error that it could not;; find the source file in jde-db-source-directories.;;;; Revision 1.92 2002/01/02 05:29:45 paulk;; Added a stack-depth field to the jde-db-debuggee class.;;;; Revision 1.91 2001/12/31 07:51:09 paulk;; Implemented generalized quit, step-over, step-into, stack up, stack down,;; and stack where commands.;;;; Revision 1.90 2001/12/28 05:32:55 paulk;; Implemented generalized debuggee process run and continue commands.;;;; Revision 1.89 2001/12/17 08:02:05 paulk;; Initial version of generalized clear breakpoint command. Created generalized;; classes to represent the debuggee process.;;;; Revision 1.88 2001/12/14 05:08:37 paulk;; Setup generic methods for processing the debugger output and status;; change notification.;;;; Revision 1.87 2001/12/10 04:29:55 paulk;; Created generalized breakpoint framework. Provided initial;; implementation for jdb. A lot of work remains.;;;; Revision 1.86 2001/12/04 05:37:35 paulk;; Moved jdb related code to jde-jdb.el.;;;; Revision 1.85 2001/11/30 03:08:03 jslopez;; Fixes reference to free variables.;;;; Revision 1.84 2001/11/27 08:03:46 paulk;; Updated jdb-db to invoke the version of jdb appropriate to the JDK for the current project.;;;; Revision 1.83 2001/11/26 02:45:51 paulk;; Added reference to jde-db-source-directories in invocation of jde-normalize-path;; in jde-db-src-dir-matches-file-p.;;;; Revision 1.82 2001/11/25 06:34:12 paulk;; Added function jde-db-src-dir-matches-file-p. Thanks to;; Kevin Burton for initial implementation.;;;; Revision 1.81 2001/11/04 14:58:05 paulk;; Restored jde-db-classic-mode-vm option.;;;; Revision 1.80 2001/11/04 14:51:23 paulk;; Fixed typo in classic mode argument (i.e., -tclassic should be -classic).;;;; Revision 1.79 2001/09/30 05:29:32 paulk;; Changed the name of the customization variable jde-db-debugger to be consistent with jde-compiler and to avoid conflict with jde-db-debugger class.;;;; Revision 1.78 2001/09/28 04:48:00 paulk;; Defines a new eieio class of debuggers that serves as the parent;; for jdb and JDEbug debuggers. Create a jde-db-jdb class that serves;; as the root of jdb and oldjdb.;;;; Revision 1.77 2001/07/31 05:11:50 paulk;; ReleaseNotes.txt;;;; Revision 1.76 2001/04/16 05:49:34 paulk;; Normalized paths. Thanks to Nick Sieger.;;;; Revision 1.75 2001/04/12 04:42:23 paulk;; Normalize jde-run-working-directory.;;;; Revision 1.74 2001/04/11 03:21:33 paulk;; Updated to resolve relative paths relative to the project file that defines them. Thanks to Nick Sieger.;;;; Revision 1.73 2001/04/08 04:14:29 paulk;; jdb interface has been fixed to work around JDK 1.3 bug that causes the jdb command prompt to sometimes appear in the wrong place in jdb output. Thanks to Andy Bennett <andrew.bennett@ericsson.com> for this fix.;;;; Revision 1.72 2001/03/16 04:07:03 paulk;; Fixed regular expression for finding package in source buffer so that there must be a space between package and the package name. This is to prevent false hits. Thanks to Rory Molinari <molinari@math.lsa.umich.edu>.;;;; Revision 1.71 2001/03/13 04:14:54 paulk;; Split jde-find-class-source into to files, one of which returns the path of the source file while the other opens the file in a buffer.;;;; Revision 1.70 2001/02/26 04:17:50 paulk;; jde-db now handles case where jde-global-classpath and jde-db-option-classpath are nil.;;;; Revision 1.69 2001/02/03 08:44:56 paulk;; Changed declaration of customized variables to allow path completion.;; Now allows environment variables in jde-db-source-directories.;;;; Revision 1.68 2001/02/03 07:28:06 paulk;; Now uses generalized jde-build-classpath function to build classpath argument to debugger.;;;; Revision 1.67 2000/12/18 05:22:45 paulk;; *** empty log message ***;;;; Revision 1.66 2000/10/10 06:36:59 paulk;; Fixed bug where selecting Other and Executable as the debugger results in the executable name being inserted twice.;;;; Revision 1.65 2000/10/08 12:55:39 paulk;; *** empty log message ***;;;; Revision 1.64 2000/08/19 06:46:22 paulk;; Updated to handle JDK 1.3 version of jdb. Source pointer now moves to;; current location in current stack frame.;;;; Revision 1.63 2000/06/12 08:37:43 paulk;; Now displays JDEbug menu when running XEmacs.;;;; Revision 1.62 2000/05/10 05:41:32 paulk;; The JDEbug menu now appears or disappears when you select or deselect JDEbug as the current debugger.;;;; Revision 1.61 2000/03/16 05:08:25 paulk;; Added JDEbug option to jde-db-debugger.;;;; Revision 1.60 2000/03/08 05:40:01 paulk;; jde-db-format-command now signals an error it it cannot determine the containing class.;;;; Revision 1.59 2000/02/10 02:50:32 paulk;; Replaced jde expand file name function with expand-file-name.;;;; Revision 1.58 2000/02/01 04:08:12 paulk;; Modified the Jdb->Set Breakpoint command (gud-break) to set breakpoints correctly;; in inner classes.;;;; Revision 1.57 2000/01/15 08:01:52 paulk;; Reimplemented directory search functions.;;;; Revision 1.56 1999/11/16 05:58:17 paulk;; Added trace method commands and skeletons for trace class and cancel;; trace commands.;;;; Revision 1.55 1999/11/04 05:49:10 paulk;; Amended jde-db-make-qualified-class-name-regexp to permit package names to begin;; with non-word characters, e.g., underscores. Contributed by "Patrick J. McNerthney";; <pat@mcnerthney.com>.;;;; Revision 1.54 1999/09/28 04:06:59 paulk;; Supplied missing left parentheses.;;;; Revision 1.53 1999/09/05 04:33:28 paulk;; Added support for running vm in classic mode.;;;; Revision 1.52 1999/03/10 16:55:02 paulk;; Fixed jde-db-find-file to return the current buffer if it cannot find a file and;; XEmacs is the editor.;;;; Revision 1.51 1999/03/06 00:55:38 paulk;; Changed default value of jde-db-source-directories to be nil.;;;; Revision 1.50 1999/03/06 00:44:08 paulk;; Make sure that case-sensitive matching is used when extracting package names from;; debugger breakpoint messages.;;;; Revision 1.49 1999/02/26 15:52:52 paulk;; Catch non-existent directory errors when searching for source;; files and packages. Thanks to Thanh Nguyen <Thanh.Nguyen@Eng.Sun.COM>;; for finding and providing a fix for this bug.;;;; Revision 1.48 1999/02/25 15:24:43 paulk;; Fixed jde-db-find-file so that it displays an error when it cannot find a file instead of;; opening an empty source buffer.;;;; Provided a set-value function for jde-db-source-directories that appends a slash to;; the end of each path if the path does not already end in a slash.;;;; Defined a new command, jde-find-class-source, that finds and opens the source file;; for a specified class.;;;; Improved the regular expression used by jde-db-get-package to ignore tabs at the;; beginning of a line.;;;; Revision 1.47 1999/02/15 02:02:35 paulk;; Forgot to concatenate in last fix.;;;; Revision 1.46 1999/02/15 00:52:44 paulk;; Fixed bug in qualified-class-name-regexp.;;;; Revision 1.45 1999/02/10 18:35:51 paulk;; Added support for appletviewer -encoding and -J options.;;;; Revision 1.44 1999/02/08 17:18:17 paulk;; jde-db-applet now supports file completion and remembers the last path entered.;;;; Revision 1.43 1999/02/06 03:55:11 paulk;; Fixed bug and generalized regular expression in jde-db-make-qualified-class-name-regexp.;;;; Revision 1.42 1999/02/03 18:12:03 paulk;; Fixed regular expression in jde-db-get-package to eliminate spurious hits, e.g.;; commented out package statements. Thanks to Frederic Baumann <baumann@ilog.fr>;; for reporting this bug.;;;; Revision 1.41 1999/02/03 17:48:34 paulk;; Patched jde-db-get-app-args-from-user to remember arguments.;; Thanks to Brian Burton <brian@burton-computer.com>;;;; Revision 1.40 1999/02/03 17:41:56 paulk;; Fixed jde-db-make-qualified-class-name-regexp to handle packages with underscores.;; Thanks to Brian Burton <brian@burton-computer.com>.;;;; Revision 1.39 1999/02/03 17:26:46 paulk;; Changed jde-db-make-qualified-class-name-regexp to handle inner classes.;; Thanks to Michael Lepore <lepore@process.com> for this fix.;;;; Revision 1.38 1999/02/03 01:53:49 paulk;; Fixed jde-db-applet to check the current directory for the html file to run.;;;; Revision 1.37 1999/02/02 16:06:01 paulk;; Added the jde-db-applet command. This command allows you to debug an applet, using;; appletviewer.;;;; Revision 1.36 1999/02/02 15:25:28 paulk;; Removed unwanted space in -D (properties) debug option.;;;; Revision 1.35 1999/01/17 00:36:43 paulk;; Now uses gud-find-c-expr or find-c-expr, whichever is bound.;;;; Revision 1.34 1999/01/13 22:18:08 paulk;; Added Andy Piper's NT/XEmacs 21 compatibility changes.;; Changed find-c-expr to gud-findc-expr;;;; Revision 1.33 1998/11/22 18:18:36 paulk;; Made comint-prompt-regexp and paragraph-start local variables.;;;; Revision 1.32 1998/11/04 02:59:09 paulk;; Corrected verbiage in Jde Debugger Options description.;;;; Revision 1.31 1998/09/12 00:05:57 paulk;; Debugger now runs application from directory specified by jde-run-working-directory.;;;; Revision 1.30 1998/06/30 04:03:19 paulk;; Added variables `jde-db-read-vm-args' and `jde-db-read-app-args'. The use of;; these variables is the same as the corresponding jde-run variables.;;;; Revision 1.29 1998/06/29 02:50:44 paulk;; Fixed bug in marker filter.;;;; Revision 1.28 1998/06/27 03:34:31 paulk;; Provided a hack to handle reordering of threaded messages on Solaris.;;;; Provided code to handle case where current class has no line number;; information.;;;; Revision 1.27 1998/06/25 04:27:23 paulk;; Removed debug messages from jde-db-marker-filter.;;;; Revision 1.26 1998/06/25 04:21:10 paulk;; Modified jde-db-marker-filter to accummulate debugger output;; in chunks. Fixes bug reported by Eric Prud'hommeaux (eric@w3.org).;;;; Revision 1.25 1998/06/22 03:52:28 paulk;; Added jde-db-startup-commands variable. This variable allows you to;; specify debugger commands to run when the debugger is started.;;;; Revision 1.24 1998/06/21 00:09:43 paulk;; Added a customizable feature, jde-db-set-initial-breakpoint, that causes;; the JDE to set an initial breakpoint in an app's main routine and run;; to the breakpoint on debugger startup. The feature is enabled by default.;;;; Revision 1.23 1998/06/20 23:42:07 paulk;; Made jde-db-marker-regexp a custom variable to facilitate the use of the JDE;; with debuggers other than jdb.;;;; Changed the marker regular expression to detect only jdb breakpoint messages,;; i.e., messages of the form;;;; Breakpoint hit: qualified.class.name (class:line);;;; This should eliminate the problem of spurious hits when exceptions occur and;; stack traces are printed.;;;; Revision 1.22 1998/05/27 06:09:46 paulk;; Added autoload comments.;;;; Revision 1.21 1998/03/27 04:16:12 kinnucan;; Fixed typo in the code that displays the jdb menu on XEmacs.;;;; Revision 1.20 1998/03/27 04:14:53 kinnucan;; Modified jde-db-search-src-dirs to take current package as an;; argument rather than use a global variable. This allows;; it to be used by jde-java-build function.;;;; Revision 1.19 1998/03/18 03:54:06 kinnucan;; Changed jde-db-marker-regexp to account for inner classes.;; Thanks to Andreas Rasmusson <Andreas.Rasmusson@sics.se> for;; providing this fix.;;;; Revision 1.18 1998/03/04 04:28:36 kinnucan;; Added test for jde-run-application-class = "" to jde-db;;;; Revision 1.17 1998/02/27 22:16:34 kinnucan;; Changed copyright to Paul Kinnucan.;; Have not yet assigned rights to FSF.;;;; Revision 1.16 1998/02/27 22:15:24 kinnucan;; Added support for Emacs customization feature.;;;; Revision 1.15 1998/02/17 04:16:38 kinnucan;; Fixed bug in jde-deb-set-source-paths that caused the last;; directory to not be normalized (i.e., slash appended).;;;; Revision 1.14 1998/02/12 05:15:38 kinnucan;; Changed the jde-db-search-src-dirs to search the source directory list from;; front to back instead of back to front. The former search order did not allow newer versions of the same class to shadow older versions. Thanks to "David J. Biesack" <sasdjb@unx.sas.com> for supplying this fix.;;;; Revision 1.13 1998/02/12 04:57:13 kinnucan;; Fixed bug in jde-db-marker-filter that sometimes prevented the JDE from;; loading the correct source file. Thanks to David J. Biesack;; <sasdjb@unx.sas.com> for supplying the fix.;;;; Revision 1.12 1997/10/30 05:42:37 kinnucan;; Made configuration variables settable.;;;; Revision 1.11 1997/10/26 05:49:59 kinnucan;; Applied Derek Young's patch to cause jde to qualify class names;; when setting a breakpoint.;;;; Revision 1.10 1997/10/20 05:27:48 kinnucan;; Removed reference to deleted function jde-db-massage-args;;;; Revision 1.9 1997/10/11 01:36:05 kinnucan;; Fixed bug in jde-db-search-src-dirs discovered by Jonathan Payne.;;;; Revision 1.8 1997/10/06 14:40:53 kinnucan;; Fixed bugs in jde-db-set-debugger command.;;;; Revision 1.7 1997/10/05 21:20:15 kinnucan;; 1. Added the variables jde-db-debugger and jde-db-debugger-is-executable;; and the associated setter function jde-db-set-debugger. These allow;; you to specify a custom debugger for the JDE>;;;; 2. Added jde-db-args and jde-db-app-args and the associated setter;; functions. These allow you to specify debugger and application;; command line arguments.;;;; Revision 1.6 1997/10/05 04:53:04 kinnucan;; Fixed bug in print object menu item.;;;; Revision 1.5 1997/08/26 14:53:39 paulk;; Fixed bug in check-source-path.;;;; Revision 1.4 1997/08/26 08:52:14 kinnucan;; Tweaked JDE Version number for JDE 1.8 release.;;;; Revision 1.3 1997/07/05 04:18:10 kinnucan;; Updated make-jdb-command to run either the class previously specifed with;; the jde-run-set-app command or the class corresponding to the code in the;; current buffer.;;;; Revision 1.2 1997/06/18 18:45:11 paulk;; Added error-checking to jde-db-set-source-paths function. Now checks for;; existence of specified directories and appends a terminal slash to paths;; that lack it.;;;; Revision 1.1 1997/06/18 17:21:59 paulk;; Initial revision;;;;; end of jde-db.el