From: cperkonig Date: Tue, 4 Oct 2005 10:34:20 +0000 (+0000) Subject: Initial implementation of the new Debug Plugin X-Git-Url: http://git.phpeclipse.com Initial implementation of the new Debug Plugin --- diff --git a/net.sourceforge.phpeclipse.xdebug.core/META-INF/MANIFEST.MF b/net.sourceforge.phpeclipse.xdebug.core/META-INF/MANIFEST.MF new file mode 100644 index 0000000..dcab269 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-Name: XDebug Core Plug-in +Bundle-SymbolicName: net.sourceforge.phpeclipse.xdebug.core; singleton=true +Bundle-Version: 0.0.1 +Bundle-ClassPath: core.jar +Bundle-Activator: net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.debug.core, + org.eclipse.core.resources, + net.sourceforge.phpeclipse +Eclipse-AutoStart: true +Provide-Package: net.sourceforge.phpeclipse.xdebug.core, + net.sourceforge.phpeclipse.xdebug.php.launching, + net.sourceforge.phpeclipse.xdebug.php.model diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/IXDebugConstants.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/IXDebugConstants.java new file mode 100644 index 0000000..4aae1ed --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/IXDebugConstants.java @@ -0,0 +1,33 @@ +package net.sourceforge.phpeclipse.xdebug.php.launching; + +/** + * Constants for the PDA debugger. + */ +public interface IXDebugConstants { + + /** + * Unique identifier for the PHP debug model (value + * et.sourceforge.phpeclipse.debug.). + */ + public static final String ID_PHP_DEBUG_MODEL = "net.sourceforge.phpeclipse.xdebug.php"; + + /** + * Launch configuration key. Value is a PHPProject name + * program. The path is a string representing a full path + * to a perl program in the workspace. + */ + public static final String ATTR_PHP_PROJECT = ID_PHP_DEBUG_MODEL + ".ATTR_PDA_PROFECT"; + /** + * Launch configuration key. Value is a php program. + * The path is a string representing a relative path + * to a php program in the project. + */ + public static final String ATTR_PHP_FILE = ID_PHP_DEBUG_MODEL + ".ATTR_PDA_FILE"; + + public static final String ATTR_PHP_DEFAULT_INTERPRETER = ID_PHP_DEBUG_MODEL + ".ATTR_PHP_DEFAULT_INTERPRETER"; + + public static final String ATTR_PHP_INTERPRETER = ID_PHP_DEBUG_MODEL + ".ATTR_PHP_INTERPRETER"; + + +} + diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/PHPLaunchConfigurationDelegate.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/PHPLaunchConfigurationDelegate.java new file mode 100644 index 0000000..484f75a --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/launching/PHPLaunchConfigurationDelegate.java @@ -0,0 +1,118 @@ +/********************************************************************** + Copyright (c) 2000, 2002 IBM Corp. and others. + All rights reserved. This program and the accompanying materials + are made available under the terms of the Common Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/cpl-v10.html + + Contributors: + IBM Corporation - Initial implementation + Vicente Fernando - www.alfersoft.com.ar + **********************************************************************/ +package net.sourceforge.phpeclipse.xdebug.php.launching; + +import java.io.File; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; + +import net.sourceforge.phpeclipse.xdebug.core.IXDebugPreferenceConstants; +import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; +import net.sourceforge.phpeclipse.xdebug.php.model.XDebugTarget; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.ILaunchConfigurationDelegate; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.core.model.LaunchConfigurationDelegate; + + +public class PHPLaunchConfigurationDelegate extends LaunchConfigurationDelegate { + + /** + * @see ILaunchConfigurationDelegate#launch(ILaunchConfiguration, String, ILaunch, IProgressMonitor) + */ + public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { + List commandList = new ArrayList(); + + String phpInterpreter = configuration.getAttribute(IXDebugConstants.ATTR_PHP_INTERPRETER, (String)null); + boolean useDefaultInterpreter= configuration.getAttribute(IXDebugConstants.ATTR_PHP_DEFAULT_INTERPRETER, true); + + if (useDefaultInterpreter) + phpInterpreter=XDebugCorePlugin.getDefault().getPreferenceStore().getString(IXDebugPreferenceConstants.PHP_INTERPRETER_PREFERENCE); + + File exe = new File(phpInterpreter); + if (!exe.exists()) { + abort(MessageFormat.format("Specified PHP executable {0} does not exist. Check value of PHP-Interpreter.", new String[]{phpInterpreter}), null); + } + commandList.add(phpInterpreter); + + // program name + String projectName = configuration.getAttribute(IXDebugConstants.ATTR_PHP_PROJECT, (String)null); + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + + if (project == null) { + abort("PHP-Script unspecified.", null); + } + String fileName = configuration.getAttribute(IXDebugConstants.ATTR_PHP_FILE, (String)null); + +// String program = project.getFile(fileName); + IFile file = project.getFile(fileName); +// IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program)); + if (!file.exists()) { + abort(MessageFormat.format("PHP-Script {0} does not exist.", new String[] {file.getFullPath().toString()}), null); + } + + commandList.add(file.getLocation().toOSString()); +// Map nativeEnvVars = DebugPlugin.getDefault().getLaunchManager().getNativeEnvironment(); + // Environment variables + String[] envp=DebugPlugin.getDefault().getLaunchManager().getEnvironment(configuration); + // Map envVars=configuration.getAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, nativeEnvVars); + int debugPort=XDebugCorePlugin.getDefault().getPreferenceStore().getInt(IXDebugPreferenceConstants.DEBUGPORT_PREFERENCE); + if (debugPort<1024) + debugPort=IXDebugPreferenceConstants.DEFAULT_DEBUGPORT; +// if (mode.equals(ILaunchManager.DEBUG_MODE)) { +// nativeEnvVars.put("XDEBUG_CONFIG", "idekey=xdebug_test remote_enable=1"); +// } + if (mode.equals(ILaunchManager.DEBUG_MODE)) { + String[] env = new String[envp.length+1]; + for(int i=0;i0); + } + + public boolean isArray() { + return ((fType & VALUETYPE_ARRAY) > 0); + } + + public abstract void setType(String typeName); + public abstract void renderValueString(String data); + + public abstract boolean verifyValue(String expression); + + public boolean setValue(String expression) { + if (!verifyValue(expression)) + return false; + if(fTarget.setVarValue(fVariable.getFullName(),expression)) { + renderValueString(expression); + return true; + } + return false; + } + + public boolean supportsValueModification() { + return false; + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugArrayValue.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugArrayValue.java new file mode 100644 index 0000000..dd01675 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugArrayValue.java @@ -0,0 +1,27 @@ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import org.w3c.dom.Node; + +public class XDebugArrayValue extends XDebugAbstractValue { + + public XDebugArrayValue(XDebugVariable variable, Node varNode, + String typeName) { + super(variable, varNode, typeName); + } + + public void setType(String typeName) { + fType=XDebugAbstractValue.VALUETYPE_ARRAY; + fTypeName=typeName; + + } + + public void renderValueString(String data) { + fValueString= data +" element(s)"; + } + + public boolean verifyValue(String expression) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugBooleanValue.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugBooleanValue.java new file mode 100644 index 0000000..6216046 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugBooleanValue.java @@ -0,0 +1,55 @@ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import org.w3c.dom.Node; + +public class XDebugBooleanValue extends XDebugAbstractValue { + + public XDebugBooleanValue(XDebugVariable variable, Node varNode, + String typeName) { + super(variable, varNode, typeName); + } + + public boolean supportsValueModification() { + return true; + } + + public void setType(String typeName) { + fType=XDebugAbstractValue.VALUETYPE_BOOLEAN; + fTypeName=typeName; } + + public void renderValueString(String data) { + int value=-1; + try { + value=Integer.parseInt(data); + } catch (NumberFormatException e) { + data=data.toLowerCase(); + if (data.equals("true") || data.equals("false")) + fValueString=data; + else + fValueString="not defined"; + } + if (value==0) + fValueString="false"; + else if (value==1) + fValueString="true"; + else + fValueString="not defined"; + } + + public boolean verifyValue(String expression) { + int value=-1; + try { + value=Integer.parseInt(expression); + } catch (NumberFormatException e) { + expression=expression.toLowerCase(); + if (expression.equals("true") || expression.equals("false")) + return true; + else + return false; + } + if ((value>=0)&& (value <=1)) + return true; + return false; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugElement.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugElement.java new file mode 100644 index 0000000..fcfd8af --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugElement.java @@ -0,0 +1,120 @@ +/** + * + */ +package net.sourceforge.phpeclipse.xdebug.php.model; + + +import net.sourceforge.phpeclipse.xdebug.core.ResponseData; +import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants; + +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IDebugTarget; + +/** + * @author Christian + * + */ +public class XDebugElement extends PlatformObject implements IDebugElement { + + // containing target + protected XDebugTarget fTarget; + + /** + * Constructs a new debug element contained in the given + * debug target. + * + * @param target debug target (PDA VM) + */ + public XDebugElement(XDebugTarget target) { + fTarget = target; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier() + */ + public String getModelIdentifier() { + return IXDebugConstants.ID_PHP_DEBUG_MODEL; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() + */ + public IDebugTarget getDebugTarget() { + return fTarget; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() + */ + public ILaunch getLaunch() { + return getDebugTarget().getLaunch(); + } + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class adapter) { + if (adapter == IDebugElement.class) { + return this; + } + return super.getAdapter(adapter); + } + + protected void abort(String message, Throwable e) throws DebugException { +/* Axel auskommentiert + throw new DebugException(new Status(IStatus.ERROR, DebugExamplesPlugin.getDefault().getDescriptor().getUniqueIdentifier(), + DebugPlugin.INTERNAL_ERROR, message, e)); +*/ + } + + /** + * Fires a debug event + * + * @param event the event to be fired + */ + protected void fireEvent(DebugEvent event) { + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {event}); + } + + /** + * Fires a CREATE event for this element. + */ + public void fireCreationEvent() { + fireEvent(new DebugEvent(this, DebugEvent.CREATE)); + } + + /** + * Fires a RESUME event for this element with + * the given detail. + * + * @param detail event detail code + */ + public void fireResumeEvent(int detail) { + fireEvent(new DebugEvent(this, DebugEvent.RESUME, detail)); + } + + /** + * Fires a SUSPEND event for this element with + * the given detail. + * + * @param detail event detail code + */ + public void fireSuspendEvent(int detail) { + fireEvent(new DebugEvent(this, DebugEvent.SUSPEND, detail)); + } + + /** + * Fires a TERMINATE event for this element. + */ + protected void fireTerminateEvent() { + fireEvent(new DebugEvent(this, DebugEvent.TERMINATE)); + } + + public void fireDebugResponseEvent(ResponseData data) { + DebugEvent de=new DebugEvent(this, DebugEvent.MODEL_SPECIFIC); + de.setData(data); + fireEvent(de); + } +} \ No newline at end of file diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugFloatValue.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugFloatValue.java new file mode 100644 index 0000000..5d2d4ee --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugFloatValue.java @@ -0,0 +1,35 @@ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import org.w3c.dom.Node; + +public class XDebugFloatValue extends XDebugAbstractValue { + + public XDebugFloatValue(XDebugVariable variable, Node varNode,String TypeName) { + super(variable, varNode,TypeName); + + } + + public boolean supportsValueModification() { + return true; + } + + + public void setType(String typeName) { + fType=XDebugAbstractValue.VALUETYPE_FLOAT; + fTypeName=typeName; + } + + public void renderValueString(String data) { + fValueString=data; + } + + public boolean verifyValue(String expression) { + try { + Float.parseFloat(expression); + } catch (NumberFormatException e) { + return false; + } + return true; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugIntValue.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugIntValue.java new file mode 100644 index 0000000..b7e0418 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugIntValue.java @@ -0,0 +1,39 @@ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import org.w3c.dom.Node; + +public class XDebugIntValue extends XDebugAbstractValue { + + public XDebugIntValue(XDebugVariable variable, Node varNode,String TypeName) { + super(variable, varNode,TypeName); + + } + + public void setType(String typeName) { + fType=XDebugAbstractValue.VALUETYPE_INT; + fTypeName=typeName; + } + + public boolean supportsValueModification() { + return true; + } + + public void renderValueString(String dataString) { + fValueString=dataString; + } + + + public boolean verifyValue(String expression) { + try { + Integer.parseInt(expression); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public String toString() { + return fValueString; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugLineBreakpoint.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugLineBreakpoint.java new file mode 100644 index 0000000..a626e8c --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugLineBreakpoint.java @@ -0,0 +1,141 @@ + +/* + * Created on 25.11.2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package net.sourceforge.phpeclipse.xdebug.php.model; + + +import java.util.HashMap; +import java.util.Map; + +import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.LineBreakpoint; + + +/** + * @author Axel + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class XDebugLineBreakpoint extends LineBreakpoint { + + /** + * Default constructor is required for the breakpoint manager + * to re-create persisted breakpoints. After instantiating a breakpoint, + * the setMarker(...) method is called to restore + * this breakpoint's attributes. + */ + private static final String XDEBUG_LINE_BREAKPOINT = "net.sourceforge.phpeclipse.xdebug.core.XDebugLineBreakpoint"; //$NON-NLS-1$ + + /** + * Breakpoint attribute storing the fully qualified name of the type + * this breakpoint is located in. + * (value "net.sourceforge.phpeclipse.debug.typeName"). This attribute is a String. + */ + protected static final String TYPE_NAME = "net.sourceforge.phpeclipse.debug.typeName"; //$NON-NLS-1$ + +// public PHPLineBreakpoint() { +// } +// +// public PHPLineBreakpoint(IResource resource, int lineNumber, int charStart, int charEnd, int hitCount, boolean add, Map attributes) throws DebugException { +// this(resource, lineNumber, charStart, charEnd, hitCount, add, attributes, PHP_LINE_BREAKPOINT); +// } +// +// public PHPLineBreakpoint(IResource resource, int lineNumber, int hitCount, boolean add, Map attributes) throws DebugException { +// this(resource, lineNumber, -1, -1, hitCount, add, attributes, PHP_LINE_BREAKPOINT); +// } + + + public static final String BREAKPOINT_ID ="XDebugLineBreakpointID"; + + public XDebugLineBreakpoint() { + } + + /** + * Constructs a line breakpoint on the given resource at the given + * line number. The line number is 1-based (i.e. the first line of a + * file is line number 1). + * + * @param resource file on which to set the breakpoint + * @param lineNumber 1-based line number of the breakpoint + * @throws CoreException if unable to create the breakpoint + */ + public XDebugLineBreakpoint(final IResource resource, final int lineNumber) throws CoreException { +// IMarker marker = resource.createMarker("net.sourceforge.phpeclipse.xdebug.core.XDebugLineBreakpoint"); +// setMarker(marker); +// setEnabled(true); +// XDebugCorePlugin.log(IStatus.INFO,"Markertype: "+ marker.getType()); +// ensureMarker().setAttribute(IMarker.LINE_NUMBER, lineNumber); +// ensureMarker().setAttribute(IBreakpoint.ID, IXDebugConstants.ID_PHP_DEBUG_MODEL); +// ensureMarker().setAttribute(BREAKPOINT_ID,-1); + IWorkspaceRunnable wr= new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + + // create the marker + setMarker(resource.createMarker(XDEBUG_LINE_BREAKPOINT)); + + // add attributes + Map attributes = new HashMap(10); + addLineBreakpointAttributes(attributes, getModelIdentifier(), true, lineNumber, -1, -1); + + // set attributes + ensureMarker().setAttributes(attributes); + + // add to breakpoint manager if requested + register(true); + } + }; + run(getMarkerRule(resource), wr); + + } + + protected void register(boolean register) throws CoreException { + if (register) { + DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(this); + } else { + setRegistered(false); + } + } + + public void addLineBreakpointAttributes(Map attributes, String modelIdentifier, boolean enabled, int lineNumber, int charStart, int charEnd) { + attributes.put(IBreakpoint.ID, modelIdentifier); + attributes.put(IBreakpoint.ENABLED, new Boolean(enabled)); + attributes.put(IMarker.LINE_NUMBER, new Integer(lineNumber)); + if (charStart!=-1) + { + attributes.put(IMarker.CHAR_START, new Integer(charStart)); + attributes.put(IMarker.CHAR_END, new Integer(charEnd)); + } + attributes.put(TYPE_NAME, "typeName"); + attributes.put(BREAKPOINT_ID,new Integer(-1)); + } + + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier() + */ + public String getModelIdentifier() { + return IXDebugConstants.ID_PHP_DEBUG_MODEL; + } + + public void setID(int id) throws CoreException + { + ensureMarker().setAttribute(BREAKPOINT_ID,id); + } + public int getID() throws CoreException + { + return ensureMarker().getAttribute(BREAKPOINT_ID,-1); + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugObjectValue.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugObjectValue.java new file mode 100644 index 0000000..370e44d --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugObjectValue.java @@ -0,0 +1,32 @@ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import org.w3c.dom.Node; + +public class XDebugObjectValue extends XDebugAbstractValue { + + public XDebugObjectValue(XDebugVariable variable, Node varNode, + String typeName) { + super(variable, varNode, typeName); + } + + public void setType(String typeName) { + fType=XDebugAbstractValue.VALUETYPE_OBJECT; + fTypeName=typeName; + + } + + public void renderValueString(String data) { + fValueString= data; + + } + + public String toString() { + return "class "+fValueString; + } + + public boolean verifyValue(String expression) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugStackFrame.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugStackFrame.java new file mode 100644 index 0000000..ece6842 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugStackFrame.java @@ -0,0 +1,283 @@ +/* + * Created on 23.11.2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import java.net.URI; +import java.net.URISyntaxException; + +import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils; +import net.sourceforge.phpeclipse.xdebug.core.DebugConnection.DebugResponse; + +import org.eclipse.core.runtime.Path; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IRegisterGroup; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.core.model.IVariable; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * @author Axel + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class XDebugStackFrame extends XDebugElement implements IStackFrame { + + private XDebugThread fThread; +// private String fName; + private int fLineNo; + private String fFileName; + private int fId; + private IVariable[] fVariables; + private String fLevel; + private String fType; + private String fWhere; + + /** + * Constructs a stack frame in the given thread with the given + * frame data. + * + * @param thread + * @param data frame data + * @param id stack frame id (0 is the bottom of the stack) + */ + public XDebugStackFrame(XDebugThread thread, Node stackNode, int id) { + super((XDebugTarget) thread.getDebugTarget()); + fId = id; + fThread = thread; + init(stackNode); + } + + /** + * Initializes this frame based on its data + * + * @param data + */ + private void init(Node stackNode) { + + fLevel=PHPDebugUtils.getAttributeValue(stackNode,"level"); + fType=PHPDebugUtils.getAttributeValue(stackNode,"type"); + String fileName=PHPDebugUtils.unescapeString(PHPDebugUtils.getAttributeValue(stackNode,"filename")); + String lineNo=PHPDebugUtils.getAttributeValue(stackNode,"lineno"); + + if (lineNo!="") + fLineNo= Integer.parseInt(lineNo); + + fWhere=PHPDebugUtils.getAttributeValue(stackNode,"where"); + + fFileName = (new Path(fileName)).lastSegment(); + int id=-1; + try { + id=((XDebugTarget)getDebugTarget()).sendRequest("context_get","-d "+fLevel); + } catch (DebugException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + DebugResponse response=((XDebugTarget)getDebugTarget()).getResponse(id); + Node responseNode = response.getParentNode(); + NodeList property = responseNode.getChildNodes(); + fVariables = new IVariable[property.getLength()]; + for (int i = 0; i < property.getLength(); i++) { + Node propertyNode = property.item(i); + fVariables[i] = new XDebugVariable(this, propertyNode); + } + +// int numVars = strings.length - 3; +// fVariables = new IVariable[numVars]; +// for (int i = 0; i < numVars; i++) { +// fVariables[i] = new XDebugVariable(this, strings[i + 3]); +// } + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#getThread() + */ + public IThread getThread() { + return fThread; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#getVariables() + */ + public IVariable[] getVariables() throws DebugException { + return fVariables; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#hasVariables() + */ + public boolean hasVariables() throws DebugException { + return fVariables.length > 0; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#getLineNumber() + */ + public int getLineNumber() throws DebugException { + return fLineNo; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#getCharStart() + */ + public int getCharStart() throws DebugException { + return -1; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#getCharEnd() + */ + public int getCharEnd() throws DebugException { + return -1; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#getName() + */ + public String getName() throws DebugException { + return fFileName+"::"+fWhere+ " : lineno "+ fLineNo; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#getRegisterGroups() + */ + public IRegisterGroup[] getRegisterGroups() throws DebugException { + return null; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStackFrame#hasRegisterGroups() + */ + public boolean hasRegisterGroups() throws DebugException { + return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#canStepInto() + */ + public boolean canStepInto() { + return getThread().canStepInto(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#canStepOver() + */ + public boolean canStepOver() { + return getThread().canStepOver(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#canStepReturn() + */ + public boolean canStepReturn() { + return getThread().canStepReturn(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#isStepping() + */ + public boolean isStepping() { + return getThread().isStepping(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#stepInto() + */ + public void stepInto() throws DebugException { + getThread().stepInto(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#stepOver() + */ + public void stepOver() throws DebugException { + getThread().stepOver(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#stepReturn() + */ + public void stepReturn() throws DebugException { + getThread().stepReturn(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#canResume() + */ + public boolean canResume() { + return getThread().canResume(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend() + */ + public boolean canSuspend() { + return getThread().canSuspend(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended() + */ + public boolean isSuspended() { + return getThread().isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#resume() + */ + public void resume() throws DebugException { + getThread().resume(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#suspend() + */ + public void suspend() throws DebugException { + getThread().suspend(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#canTerminate() + */ + public boolean canTerminate() { + return getThread().canTerminate(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#isTerminated() + */ + public boolean isTerminated() { + return getThread().isTerminated(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#terminate() + */ + public void terminate() throws DebugException { + getThread().terminate(); + } + + /** + * Returns the name of the source file this stack frame is associated + * with. + * + * @return the name of the source file this stack frame is associated + * with + */ + public String getSourceName() { + return fFileName; + } + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (obj instanceof XDebugStackFrame) { + XDebugStackFrame sf = (XDebugStackFrame)obj; + try { + return sf.getSourceName().equals(getSourceName()) && + sf.getLineNumber() == getLineNumber() && + sf.fId == fId; + } catch (DebugException e) { + } + } + return false; + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return getSourceName().hashCode() + fId; + } + + /** + * Returns this stack frame's unique identifier within its thread + * + * @return this stack frame's unique identifier within its thread + */ + protected int getIdentifier() { + return fId; + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugStringValue.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugStringValue.java new file mode 100644 index 0000000..388c412 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugStringValue.java @@ -0,0 +1,39 @@ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import org.w3c.dom.Node; + +public class XDebugStringValue extends XDebugAbstractValue { + + private String fDataString; + public XDebugStringValue(XDebugVariable variable, Node varNode, + String typeName) { + super(variable, varNode, typeName); + fDataString=null; + } + + public void setType(String typeName) { + fType=XDebugAbstractValue.VALUETYPE_STRING; + fTypeName=typeName; + + } + + public void renderValueString(String data) { + fDataString=data; + fValueString="\""+data+"\""; + } + + public boolean supportsValueModification() { + return true; + } + + + public String toString() { + return fDataString; + } + + public boolean verifyValue(String expression) { + // TODO Auto-generated method stub + return true; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugTarget.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugTarget.java new file mode 100644 index 0000000..b8d3f86 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugTarget.java @@ -0,0 +1,528 @@ +/** + * + */ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import net.sourceforge.phpeclipse.xdebug.core.Base64; +import net.sourceforge.phpeclipse.xdebug.core.DebugConnection; +import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils; +import net.sourceforge.phpeclipse.xdebug.core.XDebugCorePlugin; +import net.sourceforge.phpeclipse.xdebug.core.DebugConnection.DebugResponse; +import net.sourceforge.phpeclipse.xdebug.php.launching.IXDebugConstants; + +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.ILineBreakpoint; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IProcess; +import org.eclipse.debug.core.model.IStackFrame; +import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.core.model.IValue; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * @author Christian + * + */ +public class XDebugTarget extends XDebugElement implements IDebugTarget, IDebugEventSetListener{ + // associated system process (VM) + private IProcess fProcess; + + // containing launch object + private ILaunch fLaunch; + + // debugPort + private int fDebugPort; + + // program name +// private String fName; + + + // suspend state + private boolean fSuspended = true; + + // terminated state + private boolean fTerminated = false; + + // threads + private XDebugThread fThread; + private IThread[] fThreads; + + // event dispatch job +// private EventDispatchJob fEventDispatch; + + + private DebugConnection fDebugConnection; +// private DebugResponse lastResponse; + + + + /** + * Constructs a new debug target in the given launch for the + * associated PDA VM process. + * + * @param launch containing launch + * @param debugPort port to read events from + * @exception CoreException if unable to connect to host + */ + public XDebugTarget(ILaunch launch, IProcess process, int debugPort) throws CoreException { + super(null); + fLaunch = launch; + fProcess = process; + fTarget = this; + fDebugConnection= new DebugConnection(this,debugPort); + fThread = new XDebugThread(this); + fThreads = new IThread[] {fThread}; + DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this); + DebugPlugin.getDefault().addDebugEventListener(this); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugTarget#getProcess() + */ + public IProcess getProcess() { + return fProcess; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugTarget#getThreads() + */ + public IThread[] getThreads() throws DebugException { + return fThreads; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugTarget#hasThreads() + */ + public boolean hasThreads() throws DebugException { + return (fThreads.length>0); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugTarget#getName() + */ + public String getName() throws DebugException { + return "PHP XDebug Client at localhost:" + fDebugPort; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(org.eclipse.debug.core.model.IBreakpoint) + */ + public boolean supportsBreakpoint(IBreakpoint breakpoint) { + if (breakpoint.getModelIdentifier().equals(IXDebugConstants.ID_PHP_DEBUG_MODEL)) { + return true; + } + return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget() + */ + public IDebugTarget getDebugTarget() { + return this; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDebugElement#getLaunch() + */ + public ILaunch getLaunch() { + return fLaunch; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#canTerminate() + */ + public boolean canTerminate() { + return getProcess().canTerminate(); +// return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#isTerminated() + */ + public boolean isTerminated() { +// return getProcess().isTerminated(); + return fTerminated; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#terminate() + */ + public void terminate() throws DebugException { + fDebugConnection.sendRequest ("stop"); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#canResume() + */ + public boolean canResume() { + return !isTerminated() && isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend() + */ + public boolean canSuspend() { + return !isTerminated() && !isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended() + */ + public boolean isSuspended() { + return fSuspended; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#resume() + */ + public void resume() throws DebugException { + fDebugConnection.sendRequest("run"); + } + + /** + * Notification the target has resumed for the given reason + * + * @param detail reason for the resume + */ + private void resumed(int detail) { + fSuspended = false; + fThread.fireResumeEvent(detail); + } + + /** + * Notification the target has suspended for the given reason + * + * @param detail reason for the suspend + */ + public void suspended(int detail) { + fSuspended = true; + fThread.fireSuspendEvent(detail); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#suspend() + */ + public void suspend() throws DebugException { + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint) + */ + public void breakpointAdded(IBreakpoint breakpoint) { + + if (supportsBreakpoint(breakpoint)) { + try { + if (breakpoint.isEnabled()) { + IMarker marker = breakpoint.getMarker(); + if (marker != null) { + try { + String fileName = PHPDebugUtils.escapeString(marker.getResource().getLocation().toString()); + String arg="-t line -f file:///"+fileName+" -n "+((ILineBreakpoint)breakpoint).getLineNumber(); + int id =fDebugConnection.sendRequest("breakpoint_set",arg); + // set the marker Attribute to make later idetification possible +// TODO: make sure that attribute is set before response from debugger is beeing prosessed + marker.setAttribute(XDebugLineBreakpoint.BREAKPOINT_ID,id); + + } catch (CoreException e) { + } + } + } + } catch (CoreException e) { + + } + } + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta) + */ + public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) { + if (supportsBreakpoint(breakpoint)) { + try { + int id =((XDebugLineBreakpoint)breakpoint).getID(); + if (id >0) + fDebugConnection.sendRequest("breakpoint_remove","-d "+id); + } catch (CoreException e) { + } + } + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta) + */ + public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) { +// if (supportsBreakpoint(breakpoint)) { +// try { +// if (breakpoint.isEnabled()) { +// breakpointAdded(breakpoint); +// } else { +// breakpointRemoved(breakpoint, null); +// } +// } catch (CoreException e) { +// } +// } + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect() + */ + public boolean canDisconnect() { + return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDisconnect#disconnect() + */ + public void disconnect() throws DebugException { + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected() + */ + public boolean isDisconnected() { + return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#supportsStorageRetrieval() + */ + public boolean supportsStorageRetrieval() { + return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IMemoryBlockRetrieval#getMemoryBlock(long, long) + */ + public IMemoryBlock getMemoryBlock(long startAddress, long length) throws DebugException { + return null; + } + + /** + * Notification we have connected to the PHP debugger and it has started. + * Resume the the debugger. + */ + public void started() { + + fThread.setBreakpoints(null); + fThread.setStepping(false); + + installDeferredBreakpoints(); + try { + resume(); +// step(); + } catch (DebugException e) { + } + } + + /** + * Install breakpoints that are already registered with the breakpoint + * manager. + */ + private void installDeferredBreakpoints() { + IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints(); + for (int i = 0; i < breakpoints.length; i++) { + breakpointAdded(breakpoints[i]); + } + } + + /** + * Called when this debug target terminates. + */ + public void terminated() { + fTerminated = true; + fSuspended = false; + XDebugCorePlugin.getBreakpointManager().removeBreakpointListener(this); + fireTerminateEvent(); + DebugPlugin.getDefault().removeDebugEventListener(this); + fThread.removeEventListeners(); + } + + /** + * Returns the current stack frames in the target. + * + * @return the current stack frames in the target + * @throws DebugException if unable to perform the request + */ + protected IStackFrame[] getStackFrames() throws DebugException { + int id=fDebugConnection.sendRequest("stack_get"); + DebugResponse lastResponse=fDebugConnection.waitforTransID(id); + if (lastResponse.isError()) + return new IStackFrame[0]; + Node response = lastResponse.getParentNode(); + NodeList frames = response.getChildNodes(); + IStackFrame[] theFrames = new IStackFrame[frames.getLength()]; + for (int i = 0; i < frames.getLength(); i++) { + Node stackNode = frames.item(i); + theFrames[i] = new XDebugStackFrame(fThread, stackNode, i); + } + return theFrames; + } + + /** + * Single step the interpreter. + * + * @throws DebugException if the request fails + */ + protected void step_over() throws DebugException { + fThread.setStepping(true); + resumed(DebugEvent.STEP_OVER); + fDebugConnection.sendRequest("step_over"); + } + + /** + * Single step the interpreter. + * + * @throws DebugException if the request fails + */ + protected void step_into() throws DebugException { + fThread.setStepping(true); + resumed(DebugEvent.STEP_INTO); + fDebugConnection.sendRequest("step_into"); + } + + /** + * Single step the interpreter. + * + * @throws DebugException if the request fails + */ + protected void step_out() throws DebugException { + fThread.setStepping(true); + resumed(DebugEvent.STEP_RETURN); + fDebugConnection.sendRequest("step_out"); + } + + + + /** + * Returns the current value of the given variable. + * + * @param variable + * @return variable value + * @throws DebugException if the request fails + */ + protected IValue getVariableValue(XDebugVariable variable) throws DebugException { +// synchronized (fDebugSocket) { +// fDebugConnection.sendRequest("var","" + variable.getStackFrame().getIdentifier() + " " + variable.getName()); +// try { +// String value = fDebugReader.readLine(); +// //return new XDebugValue(this, value); +// +// } catch (IOException e) { +// abort(MessageFormat.format("Unable to retrieve value for variable {0}", new String[]{variable.getName()}), e); +// } +// } + return null; + } + + /** + * Returns the values on the data stack (top down) + * + * @return the values on the data stack (top down) + */ + public IValue[] getDataStack() throws DebugException { +// synchronized (fDebugSocket) { +// fDebugConnection.sendRequest ("data"); +// try { +// String valueString = fDebugReader.readLine(); +// if (valueString != null && valueString.length() > 0) { +// String[] values = valueString.split("\\|"); +// IValue[] theValues = new IValue[values.length]; +// for (int i = 0; i < values.length; i++) { +// String value = values[values.length - i - 1]; +//// theValues[i] = new XDebugValue(this, value); +// } +// return theValues; +// } +// } catch (IOException e) { +// abort("Unable to retrieve data stack", e); +// } +// } + return new IValue[0]; + } + + public boolean setVarValue(String name, String value) { + int id=-1; + String str=Base64.encodeBytes(value.getBytes()); + int len=str.length(); + + try { + id =fDebugConnection.sendRequest("property_set","-n "+name+" -l "+len + " -- "+str); + } catch (DebugException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + DebugResponse dr=getResponse(id); + if ((dr.getAttributeValue("success")).equals("1")) + return true; + + return false; + } + + public DebugResponse getResponse(int id) { + return fDebugConnection.waitforTransID(id); + } + + /** + * Sends a request to the Debugengine and waits for an OK. + * + * @param command debug command + * @throws DebugException if the request fails + */ + + public int sendRequest(String command) throws DebugException { + return fDebugConnection.sendRequest(command,""); + } + + + /** + * Sends a request to the Debugengine and waits for an OK. + * + * @param command debug command + * @arguments arguments for the command + * @throws DebugException if the request fails + */ + + public int sendRequest(String command, String arguments) throws DebugException { + return fDebugConnection.sendRequest(command,arguments); + } + + /** + * Notification a breakpoint was encountered. Determine + * which breakpoint was hit and fire a suspend event. + * + * @param event debug event + */ + public void breakpointHit(Node node) { + // determine which breakpoint was hit, and set the thread's breakpoint + Node child=node.getFirstChild(); + if (child.getNodeName().equals("stack")) { + int lineNumber = Integer.parseInt(PHPDebugUtils.getAttributeValue(child, "lineno")); + String filename=PHPDebugUtils.getAttributeValue(child, "filename").substring(8); // remove file:/// + IBreakpoint[] breakpoints = XDebugCorePlugin.getBreakpoints(); + for (int i = 0; i < breakpoints.length; i++) { + IBreakpoint breakpoint = breakpoints[i]; + if (supportsBreakpoint(breakpoint)) { + if (breakpoint instanceof ILineBreakpoint) { + ILineBreakpoint lineBreakpoint = (ILineBreakpoint) breakpoint; + try { + if (breakpoint.isEnabled()) { + IMarker marker = breakpoint.getMarker(); + if (marker != null) { + + String name = marker.getResource().getLocation().toOSString(); + if(name.equals(PHPDebugUtils.unescapeString(filename)) && (lineBreakpoint.getLineNumber() == lineNumber)) { + fThread.setBreakpoints(new IBreakpoint[]{breakpoint}); + break; + } + } + + } + } catch (CoreException e) { + } + } + } + } + } + suspended(DebugEvent.BREAKPOINT); + } + public void handleDebugEvents(DebugEvent[] events) { + for (int i=0;inull + * if none. + */ + + private IStackFrame[] fStackFrames=null; + + private IBreakpoint[] fBreakpoints; + + /** + * Whether this thread is stepping + */ + private boolean fStepping = false; + + /** + * Constructs a new thread for the given target + * + * @param target VM + */ + public XDebugThread(XDebugTarget target) { + super(target); + DebugPlugin.getDefault().addDebugEventListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IThread#getStackFrames() + */ + public IStackFrame[] getStackFrames() throws DebugException { + if (isSuspended()) { + if (fStackFrames==null) + { +// XDebugCorePlugin.log(IStatus.INFO,"vor getStackFrames"); + fStackFrames=((XDebugTarget) getDebugTarget()).getStackFrames(); +// XDebugCorePlugin.log(IStatus.INFO,"nach getStackFrames"); + } + return fStackFrames; + } else { + return new IStackFrame[0]; + } + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IThread#hasStackFrames() + */ + public boolean hasStackFrames() throws DebugException { + return isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IThread#getPriority() + */ + public int getPriority() throws DebugException { + return 0; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IThread#getTopStackFrame() + */ + public IStackFrame getTopStackFrame() throws DebugException { + IStackFrame[] frames = getStackFrames(); + if (frames.length > 0) { + return frames[0]; + } + return null; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IThread#getName() + */ + public String getName() throws DebugException { +// if (fStackFrames!=null) +// return fStackFrames[0].getName(); +// else + return "Thread[1]"; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IThread#getBreakpoints() + */ + public IBreakpoint[] getBreakpoints() { + if (fBreakpoints == null) { + return new IBreakpoint[0]; + } + return fBreakpoints; + } + /** + * Sets the breakpoints this thread is suspended at, or null + * if none. + * + * @param breakpoints the breakpoints this thread is suspended at, or null + * if none + */ + protected void setBreakpoints(IBreakpoint[] breakpoints) { + fBreakpoints = breakpoints; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#canResume() + */ + public boolean canResume() { + return isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend() + */ + public boolean canSuspend() { + return !isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended() + */ + public boolean isSuspended() { + return getDebugTarget().isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#resume() + */ + public void resume() throws DebugException { + fStackFrames=null; + fBreakpoints=null; + getDebugTarget().resume(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ISuspendResume#suspend() + */ + public void suspend() throws DebugException { + getDebugTarget().suspend(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#canStepInto() + */ + public boolean canStepInto() { + return isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#canStepOver() + */ + public boolean canStepOver() { + return isSuspended(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#canStepReturn() + */ + public boolean canStepReturn() { + if (fStackFrames!=null) + return (fStackFrames.length>1); + else + return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#isStepping() + */ + public boolean isStepping() { + return fStepping; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#stepInto() + */ + public void stepInto() throws DebugException { + fStackFrames=null; + fBreakpoints=null; + ((XDebugTarget)getDebugTarget()).step_into(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#stepOver() + */ + public void stepOver() throws DebugException { + fStackFrames=null; + fBreakpoints=null; + ((XDebugTarget)getDebugTarget()).step_over(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IStep#stepReturn() + */ + public void stepReturn() throws DebugException { + fStackFrames=null; + fBreakpoints=null; + ((XDebugTarget)getDebugTarget()).step_out(); + + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#canTerminate() + */ + public boolean canTerminate() { + return !isTerminated(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#isTerminated() + */ + public boolean isTerminated() { + return getDebugTarget().isTerminated(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.ITerminate#terminate() + */ + public void terminate() throws DebugException { + getDebugTarget().terminate(); + } + + /** + * Sets whether this thread is stepping + * + * @param stepping whether stepping + */ + protected void setStepping(boolean stepping) { + fStepping = stepping; + } + + public void handleDebugEvents(DebugEvent[] events) { + DebugEvent de=events[0]; + System.out.println(de.toString()); + + } + + public void removeEventListeners() { + DebugPlugin.getDefault().removeDebugEventListener(this); + + } +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugValue.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugValue.java new file mode 100644 index 0000000..cc158a9 --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugValue.java @@ -0,0 +1,25 @@ +package net.sourceforge.phpeclipse.xdebug.php.model; + +import org.w3c.dom.Node; + +public class XDebugValue extends XDebugAbstractValue { + + public XDebugValue(XDebugVariable variable, Node varNode, String typeName) { + super(variable, varNode, typeName); + // TODO Auto-generated constructor stub + } + + public void setType(String typeName) { + fType=XDebugAbstractValue.VALUETYPE_UNINITIALIZED; + fTypeName="unknown"; + } + public void renderValueString(String data) { + fValueString="uninitialized"; + } + + public boolean verifyValue(String expression) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugVariable.java b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugVariable.java new file mode 100644 index 0000000..a6646da --- /dev/null +++ b/net.sourceforge.phpeclipse.xdebug.core/src/net/sourceforge/phpeclipse/xdebug/php/model/XDebugVariable.java @@ -0,0 +1,209 @@ +/* + * Created on 23.11.2004 + * + * TODO To change the template for this generated file go to + * Window - Preferences - Java - Code Style - Code Templates + */ +package net.sourceforge.phpeclipse.xdebug.php.model; + + +import net.sourceforge.phpeclipse.xdebug.core.PHPDebugUtils; + +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.core.model.IVariable; +import org.w3c.dom.Node; + +/** + * @author Axel + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class XDebugVariable extends XDebugElement implements IVariable { + + public static final int VARTYPE_UNKNOWN = -1; + public static final int VARTYPE_UNINITIALIZED = 0; + public static final int VARTYPE_STRING = 1; + public static final int VARTYPE_INT = 2; + public static final int VARTYPE_FLOAT = 3; + public static final int VARTYPE_ARRAY = 8; + public static final int VARTYPE_HASH = 9; + public static final int VARTYPE_OBJECT = 10; + + + // name & stack frmae + private String fName; + private XDebugStackFrame fFrame; + private String fFullName; +// private String fTypeName; +// private int fType; + private XDebugAbstractValue fValue; + private String fEncoding; + private int fNumChildren; +// private Node fVariableNode; + + /** + * Constructs a variable contained in the given stack frame + * with the given name. + * + * @param frame owning stack frame + * @param name variable name + */ + public XDebugVariable(XDebugStackFrame frame, Node property) { + super((XDebugTarget) frame.getDebugTarget()); + fFrame = frame; + init(property); + + } + + private void init(Node property) { + fFullName=PHPDebugUtils.getAttributeValue(property,"fullname"); + fName=PHPDebugUtils.getAttributeValue(property,"name"); + fEncoding=PHPDebugUtils.getAttributeValue(property,"encoding"); + if (PHPDebugUtils.getAttributeValue(property,"numchildren").equals("")) + fNumChildren = 0; + else + fNumChildren=Integer.parseInt(PHPDebugUtils.getAttributeValue(property,"numchildren")); + + String typeName=PHPDebugUtils.getAttributeValue(property,"type"); + +// if (typeName.equals("uninitialized") ) +// fValue= new XDebugValue(this,property,typeName); + if (typeName.equals("int") ) + fValue= new XDebugIntValue(this,property,typeName); + else if (typeName.equals("float") ) + fValue= new XDebugFloatValue(this,property,typeName); + else if (typeName.equals("bool") ) + fValue= new XDebugBooleanValue(this,property,typeName); + else if (typeName.equals("string") ) + fValue= new XDebugStringValue(this,property,typeName); + else if (typeName.equals("array") ) + fValue= new XDebugArrayValue(this,property,typeName); + else if (typeName.equals("hash") ) + fValue= new XDebugArrayValue(this,property,typeName); + else if (typeName.equals("object") ) + fValue= new XDebugArrayValue(this,property,typeName); + else + fValue= new XDebugValue(this,property,typeName); + +// else if (typeName.equals("float") ) +// fTypeName= VARTYPE_FLOAT; +// else if (typeName.equals("string") ) +// fTypeName= VARTYPE_STRING; +// else if (typeName.equals("hash") ) +// fTypeName= VARTYPE_HASH; +// else if (typeName.equals("array") ) +// fTypeName= VARTYPE_ARRAY; +// else if (typeName.equals("object") ) +// fTypeName= VARTYPE_OBJECT; + + + +// fTypeName=type; +// +// fValue= new XDebugValue(this,property); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IVariable#getValue() + */ + public IValue getValue() throws DebugException { + return fValue; +// return ((XDebugTarget)getDebugTarget()).getVariableValue(this); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IVariable#getName() + */ + public String getName() throws DebugException { + if (fFullName.endsWith("]")) + return fFullName.substring(fFullName.lastIndexOf('[')); + else + return fName; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IVariable#getReferenceTypeName() + */ + public String getReferenceTypeName() throws DebugException { + return fValue.getReferenceTypeName(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IVariable#hasValueChanged() + */ + public boolean hasValueChanged() throws DebugException { + // TODO Auto-generated method stub + return false; + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#setValue(java.lang.String) + */ + public void setValue(String expression) throws DebugException { + if(fValue.setValue(expression)) + fireEvent(new DebugEvent(this, DebugEvent.CHANGE, DebugEvent.CONTENT)); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#setValue(org.eclipse.debug.core.model.IValue) + */ + public void setValue(IValue value) throws DebugException { + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#supportsValueModification() + */ + public boolean supportsValueModification() { + return fValue.supportsValueModification(); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#verifyValue(java.lang.String) + */ + public boolean verifyValue(String expression) throws DebugException { + return fValue.verifyValue(expression); + } + /* (non-Javadoc) + * @see org.eclipse.debug.core.model.IValueModification#verifyValue(org.eclipse.debug.core.model.IValue) + */ + public boolean verifyValue(IValue value) throws DebugException { + return false; + } + + /** + * Returns the stack frame owning this variable. + * + * @return the stack frame owning this variable + */ + protected XDebugStackFrame getStackFrame() { + return fFrame; + } + +// public int getType() { +// return fType; +// } + + public String getValueString() throws DebugException { + return fValue.getValueString(); + } + + public boolean hasChildren() { + return (fNumChildren>0); + } + + public boolean isArray() { + return (fValue.isArray()); + } + + public String getEncoding() { + return fEncoding; + } + + public void setEncoding(String encoding) { + fEncoding = encoding; + } + + public String toString() { + return fValue.toString(); + } + + public String getFullName() { + return fFullName; + } + +}