Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarin Wright2007-10-09 21:03:43 +0000
committerDarin Wright2007-10-09 21:03:43 +0000
commit07f1e796ae8a43d56d3010bd3e85063b318a0ad3 (patch)
tree35f7610d1674c644f814f9a8b8bb8a858feffd39 /org.eclipse.debug.examples.core/src/org/eclipse/debug/examples
parent50371b66ac350e9f64991048058ad251a191c90d (diff)
downloadeclipse.platform.debug-07f1e796ae8a43d56d3010bd3e85063b318a0ad3.tar.gz
eclipse.platform.debug-07f1e796ae8a43d56d3010bd3e85063b318a0ad3.tar.xz
eclipse.platform.debug-07f1e796ae8a43d56d3010bd3e85063b318a0ad3.zip
release of original PDA code base
Diffstat (limited to 'org.eclipse.debug.examples.core/src/org/eclipse/debug/examples')
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/DebugCorePlugin.java128
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java202
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDARunToLineBreakpoint.java70
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java222
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java151
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java62
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java50
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArrayEntry.java98
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java117
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java525
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java251
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java47
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java426
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java79
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java107
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/WordStructureDelegate.java53
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java32
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java38
-rw-r--r--org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java65
19 files changed, 2723 insertions, 0 deletions
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/DebugCorePlugin.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/DebugCorePlugin.java
new file mode 100644
index 000000000..f58fe8613
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/DebugCorePlugin.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.*;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class DebugCorePlugin extends Plugin {
+ //The shared instance.
+ private static DebugCorePlugin plugin;
+ //Resource bundle.
+ private ResourceBundle resourceBundle;
+
+ /**
+ * Unique identifier for the PDA debug model (value
+ * <code>pda.debugModel</code>).
+ */
+ public static final String ID_PDA_DEBUG_MODEL = "pda.debugModel";
+
+ /**
+ * Name of the string substitution variable that resolves to the
+ * location of a local Perl executable (value <code>perlExecutable</code>).
+ */
+ public static final String VARIALBE_PERL_EXECUTABLE = "perlExecutable";
+ /**
+ * Launch configuration attribute key. Value is a path to a perl
+ * program. The path is a string representing a full path
+ * to a perl program in the workspace.
+ */
+ public static final String ATTR_PDA_PROGRAM = ID_PDA_DEBUG_MODEL + ".ATTR_PDA_PROGRAM";
+
+ /**
+ * Identifier for the PDA launch configuration type
+ * (value <code>pda.launchType</code>)
+ */
+ public static final String ID_PDA_LAUNCH_CONFIGURATION_TYPE = "pda.launchType";
+
+ /**
+ * The constructor.
+ */
+ public DebugCorePlugin() {
+ super();
+ plugin = this;
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ plugin = null;
+ resourceBundle = null;
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static DebugCorePlugin getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the string from the plugin's resource bundle,
+ * or 'key' if not found.
+ */
+ public static String getResourceString(String key) {
+ ResourceBundle bundle = DebugCorePlugin.getDefault().getResourceBundle();
+ try {
+ return (bundle != null) ? bundle.getString(key) : key;
+ } catch (MissingResourceException e) {
+ return key;
+ }
+ }
+
+ /**
+ * Returns the plugin's resource bundle,
+ */
+ public ResourceBundle getResourceBundle() {
+ try {
+ if (resourceBundle == null)
+ resourceBundle = ResourceBundle.getBundle("org.eclipse.debug.examples.core.pda.DebugCorePluginResources");
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ return resourceBundle;
+ }
+
+ /**
+ * Return a <code>java.io.File</code> object that corresponds to the specified
+ * <code>IPath</code> in the plugin directory, or <code>null</code> if none.
+ */
+ public static File getFileInPlugin(IPath path) {
+ try {
+ URL installURL =
+ new URL(getDefault().getDescriptor().getInstallURL(), path.toString());
+ URL localURL = Platform.asLocalURL(installURL);
+ return new File(localURL.getFile());
+ } catch (IOException ioe) {
+ return null;
+ }
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java
new file mode 100644
index 000000000..24062b0b5
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDALineBreakpoint.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.breakpoints;
+
+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.DebugException;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.LineBreakpoint;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.examples.core.pda.model.IPDAEventListener;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
+
+
+/**
+ * PDA line breakpoint
+ */
+public class PDALineBreakpoint extends LineBreakpoint implements IPDAEventListener {
+
+ // target currently installed in
+ private PDADebugTarget fTarget;
+
+ /**
+ * Default constructor is required for the breakpoint manager
+ * to re-create persisted breakpoints. After instantiating a breakpoint,
+ * the <code>setMarker(...)</code> method is called to restore
+ * this breakpoint's attributes.
+ */
+ public PDALineBreakpoint() {
+ }
+
+ /**
+ * 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). The PDA VM uses 0-based line numbers,
+ * so this line number translation is done at breakpoint install time.
+ *
+ * @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 PDALineBreakpoint(final IResource resource, final int lineNumber) throws CoreException {
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IMarker marker = resource.createMarker("org.eclipse.debug.examples.core.pda.markerType.lineBreakpoint");
+ setMarker(marker);
+ marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE);
+ marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
+ marker.setAttribute(IBreakpoint.ID, getModelIdentifier());
+ marker.setAttribute(IMarker.MESSAGE, "Line Breakpoint: " + resource.getName() + " [line: " + lineNumber + "]");
+ }
+ };
+ run(getMarkerRule(resource), runnable);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IBreakpoint#getModelIdentifier()
+ */
+ public String getModelIdentifier() {
+ return DebugCorePlugin.ID_PDA_DEBUG_MODEL;
+ }
+
+ /**
+ * Returns whether this breakpoint is a run-to-line breakpoint
+ *
+ * @return whether this breakpoint is a run-to-line breakpoint
+ */
+ public boolean isRunToLineBreakpoint() {
+ return false;
+ }
+
+ /**
+ * Installs this breakpoint in the given interprettor.
+ * Registeres this breakpoint as an event listener in the
+ * given target and creates the breakpoint specific request.
+ *
+ * @param target PDA interprettor
+ * @throws CoreException if installation fails
+ */
+ public void install(PDADebugTarget target) throws CoreException {
+ fTarget = target;
+ target.addEventListener(this);
+ createRequest(target);
+ }
+
+ /**
+ * Create the breakpoint specific request in the target. Subclasses
+ * should override.
+ *
+ * @param target PDA interprettor
+ * @throws CoreException if request creation fails
+ */
+ protected void createRequest(PDADebugTarget target) throws CoreException {
+ //#ifdef ex3
+//# // TODO: Exercise 3 - create breakpoint request in interpreter
+ //#else
+ target.sendRequest("set " + (getLineNumber() - 1));
+ //#endif
+ }
+
+ /**
+ * Removes this breakpoint's event request from the target. Subclasses
+ * should override.
+ *
+ * @param target PDA interprettor
+ * @throws CoreException if clearing the request fails
+ */
+ protected void clearRequest(PDADebugTarget target) throws CoreException {
+ //#ifdef ex3
+//# // TODO: Exercise 3 - clear breakpoint request in interpreter
+ //#else
+ target.sendRequest("clear " + (getLineNumber() - 1));
+ //#endif
+ }
+
+ /**
+ * Removes this breakpoint from the given interprettor.
+ * Removes this breakpoint as an event listener and clears
+ * the request for the interprettor.
+ *
+ * @param target PDA interprettor
+ * @throws CoreException if removal fails
+ */
+ public void remove(PDADebugTarget target) throws CoreException {
+ target.removeEventListener(this);
+ clearRequest(target);
+ fTarget = null;
+
+ }
+
+ /**
+ * Returns the target this breakpoint is installed in or <code>null</code>.
+ *
+ * @return the target this breakpoint is installed in or <code>null</code>
+ */
+ protected PDADebugTarget getDebugTarget() {
+ return fTarget;
+ }
+
+ /**
+ * Notify's the PDA interprettor that this breakpoint has been hit.
+ */
+ protected void notifyThread() {
+ if (fTarget != null) {
+ try {
+ IThread[] threads = fTarget.getThreads();
+ if (threads.length == 1) {
+ PDAThread thread = (PDAThread)threads[0];
+ thread.suspendedBy(this);
+ }
+ } catch (DebugException e) {
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ *
+ * Subclasses should override to handle their breakpoint specific event.
+ *
+ * @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
+ */
+ public void handleEvent(String event) {
+ if (event.startsWith("suspended breakpoint")) {
+ handleHit(event);
+ }
+ }
+
+ /**
+ * Determines if this breakpoint was hit and notifies the thread.
+ *
+ * @param event breakpoint event
+ */
+ private void handleHit(String event) {
+ int lastSpace = event.lastIndexOf(' ');
+ if (lastSpace > 0) {
+ String line = event.substring(lastSpace + 1);
+ int lineNumber = Integer.parseInt(line);
+ // breakpoints event line numbers are 0 based, model objects are 1 based
+ lineNumber++;
+ try {
+ if (getLineNumber() == lineNumber) {
+ notifyThread();
+ }
+ } catch (CoreException e) {
+ }
+ }
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDARunToLineBreakpoint.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDARunToLineBreakpoint.java
new file mode 100644
index 000000000..b861fff20
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDARunToLineBreakpoint.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.breakpoints;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IBreakpoint;
+
+/**
+ * A run to line breakpoint.
+ */
+public class PDARunToLineBreakpoint extends PDALineBreakpoint {
+
+ private IFile fSourceFile;
+
+ /**
+ * Constructs a run-to-line breakpoint in the given PDA program.
+ *
+ * @param resource PDA source file
+ * @param lineNumber line to run to
+ * @exception DebugException if unable to create the breakpoint
+ */
+ public PDARunToLineBreakpoint(final IFile resource, final int lineNumber) throws DebugException {
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ // associate with workspace root to avoid drawing in editor ruler
+ IMarker marker = ResourcesPlugin.getWorkspace().getRoot().createMarker("org.eclipse.debug.examples.core.pda.markerType.lineBreakpoint");
+ setMarker(marker);
+ marker.setAttribute(IBreakpoint.ENABLED, Boolean.TRUE);
+ marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
+ marker.setAttribute(IBreakpoint.ID, getModelIdentifier());
+ setRegistered(false);
+ fSourceFile = resource;
+ }
+ };
+ run(getMarkerRule(resource), runnable);
+ }
+
+ /**
+ * Returns whether this breakpoint is a run-to-line breakpoint
+ *
+ * @return whether this breakpoint is a run-to-line breakpoint
+ */
+ public boolean isRunToLineBreakpoint() {
+ return true;
+ }
+
+ /**
+ * Returns the source file this breakpoint is contained in.
+ *
+ * @return the source file this breakpoint is contained in
+ */
+ public IFile getSourceFile() {
+ return fSourceFile;
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java
new file mode 100644
index 000000000..ab819d0b5
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/breakpoints/PDAWatchpoint.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.breakpoints;
+
+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.model.IBreakpoint;
+import org.eclipse.debug.core.model.IWatchpoint;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+
+
+/**
+ * A watchpoint.
+ */
+public class PDAWatchpoint extends PDALineBreakpoint implements IWatchpoint {
+
+ // 'read' or 'write' depending on what caused the last suspend for this watchpoint
+ private String fLastSuspendType;
+
+ // marker attributes
+ public static final String ACCESS = "ACCESS";
+ public static final String MODIFICATION = "MODIFICATION";
+ public static final String FUNCTION_NAME = "FUNCTION_NAME";
+ public static final String VAR_NAME = "VAR_NAME";
+
+ /**
+ * Default constructor is required for the breakpoint manager
+ * to re-create persisted breakpoints. After instantiating a breakpoint,
+ * the <code>setMarker(...)</code> method is called to restore
+ * this breakpoint's attributes.
+ */
+ public PDAWatchpoint() {
+ }
+ /**
+ * 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). The PDA VM uses 0-based line numbers,
+ * so this line number translation is done at breakpoint install time.
+ *
+ * @param resource file on which to set the breakpoint
+ * @param lineNumber 1-based line number of the breakpoint
+ * @param functionName function name the variable is defined in
+ * @param varName variable name that watchpoint is set on
+ * @param access whether this is an access watchpoint
+ * @param modification whether this in a modification watchpoint
+ * @throws CoreException if unable to create the watchpoint
+ */
+ public PDAWatchpoint(final IResource resource, final int lineNumber, final String functionName, final String varName, final boolean access, final boolean modification) throws CoreException {
+ IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IMarker marker = resource.createMarker("org.eclipse.debug.examples.core.pda.markerType.watchpoint");
+ setMarker(marker);
+ setEnabled(true);
+ ensureMarker().setAttribute(IMarker.LINE_NUMBER, lineNumber);
+ ensureMarker().setAttribute(IBreakpoint.ID, getModelIdentifier());
+ setAccess(access);
+ setModification(modification);
+ setVariable(functionName, varName);
+ marker.setAttribute(IMarker.MESSAGE, "Watchpoint: " + resource.getName() + " [line: " + lineNumber + "]");
+ }
+ };
+ run(getMarkerRule(resource), runnable);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IWatchpoint#isAccess()
+ */
+ public boolean isAccess() throws CoreException {
+ return getMarker().getAttribute(ACCESS, true);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IWatchpoint#setAccess(boolean)
+ */
+ public void setAccess(boolean access) throws CoreException {
+ setAttribute(ACCESS, access);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IWatchpoint#isModification()
+ */
+ public boolean isModification() throws CoreException {
+ return getMarker().getAttribute(MODIFICATION, true);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IWatchpoint#setModification(boolean)
+ */
+ public void setModification(boolean modification) throws CoreException {
+ setAttribute(MODIFICATION, modification);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IWatchpoint#supportsAccess()
+ */
+ public boolean supportsAccess() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IWatchpoint#supportsModification()
+ */
+ public boolean supportsModification() {
+ return true;
+ }
+
+ /**
+ * Sets the variable and function names the watchpoint is set on.
+ *
+ * @param functionName function name
+ * @param variableName variable name
+ * @throws CoreException if an exception occurrs setting marker attribtues
+ */
+ protected void setVariable(String functionName, String variableName) throws CoreException {
+ setAttribute(VAR_NAME, variableName);
+ setAttribute(FUNCTION_NAME, functionName);
+ }
+
+ /**
+ * Returns the name of the variable this watchpoint is set on.
+ *
+ * @return the name of the variable this watchpoint is set on
+ * @throws CoreException if unable to access the attribute
+ */
+ public String getVariableName() throws CoreException {
+ return getMarker().getAttribute(VAR_NAME, (String)null);
+ }
+
+ /**
+ * Returns the name of the function the variable associted with this watchpoint is defined in.
+ *
+ * @return the name of the function the variable associted with this watchpoint is defined in
+ * @throws CoreException if unable to access the attribute
+ */
+ public String getFunctionName() throws CoreException {
+ return getMarker().getAttribute(FUNCTION_NAME, (String)null);
+ }
+
+ /**
+ * Sets the type of event that causes the last suspend event.
+ *
+ * @param description one of 'read' or 'write'
+ */
+ public void setSuspendType(String description) {
+ fLastSuspendType = description;
+ }
+
+ /**
+ * Returns the type of event that caused the last suspend.
+ *
+ * @return 'read', 'write', or <code>null</code> if undefined
+ */
+ public String getSuspendType() {
+ return fLastSuspendType;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.examples.core.pda.breakpoints.PDALineBreakpoint#createRequest(org.eclipse.debug.examples.core.pda.model.PDADebugTarget)
+ */
+ protected void createRequest(PDADebugTarget target) throws CoreException {
+ int flag = 0;
+ if (isAccess()) {
+ flag = flag | 1;
+ }
+ if (isModification()) {
+ flag = flag | 2;
+ }
+ target.sendRequest("watch " + getFunctionName() + "::" + getVariableName() + " " + flag);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.examples.core.pda.breakpoints.PDALineBreakpoint#clearRequest(org.eclipse.debug.examples.core.pda.model.PDADebugTarget)
+ */
+ protected void clearRequest(PDADebugTarget target) throws CoreException {
+ target.sendRequest("watch " + getFunctionName() + "::" + getVariableName() + " " + 0);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
+ */
+ public void handleEvent(String event) {
+ if (event.startsWith("suspended watch")) {
+ handleHit(event);
+ }
+ }
+
+ /**
+ * Determines if this breakpoint was hit and notifies the thread.
+ *
+ * @param event breakpoint event
+ */
+ private void handleHit(String event) {
+ String[] strings = event.split(" ");
+ if (strings.length == 4) {
+ String fv = strings[3];
+ int j = fv.indexOf("::");
+ if (j > 0) {
+ String fcn = fv.substring(0, j);
+ String var = fv.substring(j + 2);
+ try {
+ if (getVariableName().equals(var) && getFunctionName().equals(fcn)) {
+ setSuspendType(strings[2]);
+ notifyThread();
+ }
+ } catch (CoreException e) {
+ }
+ }
+ }
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java
new file mode 100644
index 000000000..e78fc56b6
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/launcher/PDALaunchDelegate.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.launcher;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+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.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.variables.IValueVariable;
+import org.eclipse.core.variables.VariablesPlugin;
+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.IProcess;
+import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+
+
+/**
+ * Launches PDA program on a PDA interpretter written in Perl
+ */
+public class PDALaunchDelegate extends LaunchConfigurationDelegate {
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException {
+ //#ifdef ex1
+//# // TODO: Exercise 1 - Launch a command shell as a system process to echo "foo"
+ //#elseif ex1_answer
+//# Process process = DebugPlugin.exec(new String[]{"cmd", "/C", "\"echo foo\""}, null);
+//# new RuntimeProcess(launch, process, "Hello", null);
+ //#else
+
+ List commandList = new ArrayList();
+
+ // Perl executable
+ IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(DebugCorePlugin.VARIALBE_PERL_EXECUTABLE);
+ if (perl == null) {
+ abort("Perl executable location undefined. Check value of ${perlExecutable}.", null);
+ }
+ String path = perl.getValue();
+ if (path == null) {
+ abort("Perl executable location unspecified. Check value of ${perlExecutable}.", null);
+ }
+ File exe = new File(path);
+ if (!exe.exists()) {
+ abort(MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $perlExecutable.", new String[]{path}), null);
+ }
+ commandList.add(path);
+
+ // Add PDA VM
+ File vm = DebugCorePlugin.getFileInPlugin(new Path("pdavm/pda.pl"));
+ if (vm == null) {
+ abort("Missing PDA VM", null);
+ }
+ commandList.add(vm.getAbsolutePath());
+
+ // program name
+ String program = configuration.getAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, (String)null);
+ if (program == null) {
+ abort("Perl program unspecified.", null);
+ }
+
+ IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program));
+ if (!file.exists()) {
+ abort(MessageFormat.format("Perl program {0} does not exist.", new String[] {file.getFullPath().toString()}), null);
+ }
+
+ commandList.add(file.getLocation().toOSString());
+
+ // if in debug mode, add debug arguments - i.e. '-debug requestPort eventPort'
+ int requestPort = -1;
+ int eventPort = -1;
+ if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ requestPort = findFreePort();
+ eventPort = findFreePort();
+ if (requestPort == -1 || eventPort == -1) {
+ abort("Unable to find free port", null);
+ }
+ commandList.add("-debug");
+ commandList.add("" + requestPort);
+ commandList.add("" + eventPort);
+ }
+
+ String[] commandLine = (String[]) commandList.toArray(new String[commandList.size()]);
+ Process process = DebugPlugin.exec(commandLine, null);
+ IProcess p = DebugPlugin.newProcess(launch, process, path);
+ // if in debug mode, create a debug target
+ if (mode.equals(ILaunchManager.DEBUG_MODE)) {
+ IDebugTarget target = new PDADebugTarget(launch, p, requestPort, eventPort);
+ launch.addDebugTarget(target);
+ }
+ //#endif
+ }
+
+ /**
+ * Throws an exception with a new status containing the given
+ * message and optional exception.
+ *
+ * @param message error message
+ * @param e underlying exception
+ * @throws CoreException
+ */
+ private void abort(String message, Throwable e) throws CoreException {
+ throw new CoreException(new Status(IStatus.ERROR, DebugCorePlugin.getDefault().getDescriptor().getUniqueIdentifier(), 0, message, e));
+ }
+
+ /**
+ * Returns a free port number on localhost, or -1 if unable to find a free port.
+ *
+ * @return a free port number on localhost, or -1 if unable to find a free port
+ */
+ public static int findFreePort() {
+ ServerSocket socket= null;
+ try {
+ socket= new ServerSocket(0);
+ return socket.getLocalPort();
+ } catch (IOException e) {
+ } finally {
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ return -1;
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java
new file mode 100644
index 000000000..6935ad32b
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/IPDAEventListener.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+/**
+ * Listeners are notified of events occurring in a PDA program
+ * being interpreted.
+ * <p>
+ * The events generated by the interpreter are:
+ * <ul>
+ * <li><code>started</code> - the interpreter has started (guaranteed to be the
+ * first event sent)</li>
+ * <li><code>terminated</code> - the interpreter has terminated (guaranteed to be
+ * the last event sent)</li>
+ * <li><code>suspended X</code> - the interpreter has suspended and entered debug mode;
+ * <code>X</code> is the cause of the suspension:
+ * <ul>
+ * <li><code>breakpoint N</code> - a breakpoint at line <code>N</code> was hit</li>
+ * <li><code>client</code> - a client request to suspend has completed</li>
+ * <li><code>drop</code> - a client request to drop a frame has completed</li>
+ * <li><code>event E</code> - an error was encountered, where <code>E</code> is one
+ * of <code>unimpinstr</code> or <code>nosuchlabel</code></li>
+ * <li><code>step</code> - a step request has completed</li>
+ * <li><code>watch A F::V</code> - a watchpoint was hit for reason <code>A</code>
+ * (<code>read</code> or <code>write</code>), on variable <code>V</code> in
+ * function <code>F</code></li>
+ * </ul>
+ * </li>
+ * <li><code>resumed X</code> - the interpreter has resumed execution in run mode;
+ * <code>X</code> is the cause of the resume:
+ * <ul>
+ * <li><code>step</code> - a step request has been initiated</li>
+ * <li><code>client</code> - a client request to resume has been initiated</li>
+ * </ul>
+ * </li>
+ * <li><code>unimplemented instruction X</code> - an unimplemented instruction <code>X</code>
+ * was encountered</li>
+ * <li><code>no such label X</code> - a branch or call to an unknown label <code>X</code>
+ * was encountered</li>
+ * </ul>
+ * </p>
+ */
+public interface IPDAEventListener {
+
+ /**
+ * Notification the given event occurred in the target program
+ * being interpreted.
+ *
+ * @param event the event
+ */
+ public void handleEvent(String event);
+
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java
new file mode 100644
index 000000000..e27e1bad1
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArray.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IVariable;
+
+public class PDAArray extends PDAValue {
+
+ /**
+ * An array splits a value into its words
+ *
+ * @param value existing value
+ * @throws DebugException
+ */
+ public PDAArray(PDAValue value) throws DebugException {
+ super(value.getPDADebugTarget(), value.getValueString());
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#hasVariables()
+ */
+ public boolean hasVariables() throws DebugException {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#getVariables()
+ */
+ public IVariable[] getVariables() throws DebugException {
+ String string = getValueString();
+ String[] words = string.split("\\W+");
+ IVariable[] variables = new IVariable[words.length];
+ for (int i = 0; i < words.length; i++) {
+ String word = words[i];
+ variables[i] = new PDAArrayEntry(getPDADebugTarget(), i, new PDAValue(getPDADebugTarget(), word));
+ }
+ return variables;
+ }
+
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArrayEntry.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArrayEntry.java
new file mode 100644
index 000000000..9ff3ca74e
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAArrayEntry.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+
+public class PDAArrayEntry extends PDADebugElement implements IVariable {
+
+ private IValue fValue;
+ private int fIndex;
+
+ /**
+ * Constructs a new array entry
+ *
+ * @param target debug target
+ * @param index index in the array
+ * @param value value of the entry
+ */
+ public PDAArrayEntry(IDebugTarget target, int index, IValue value) {
+ super(target);
+ fValue = value;
+ fIndex = index;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IVariable#getValue()
+ */
+ public IValue getValue() throws DebugException {
+ return fValue;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IVariable#getName()
+ */
+ public String getName() throws DebugException {
+ return "[" + fIndex + "]";
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IVariable#getReferenceTypeName()
+ */
+ public String getReferenceTypeName() throws DebugException {
+ return "String";
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IVariable#hasValueChanged()
+ */
+ public boolean hasValueChanged() throws DebugException {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValueModification#setValue(java.lang.String)
+ */
+ public void setValue(String expression) throws DebugException {
+ }
+
+ /* (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 false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValueModification#verifyValue(java.lang.String)
+ */
+ public boolean verifyValue(String expression) throws DebugException {
+ return false;
+ }
+
+ /* (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;
+ }
+
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java
new file mode 100644
index 000000000..e64f22050
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugElement.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.model.DebugElement;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+
+
+/**
+ * Common function for PDA debug elements.
+ */
+public class PDADebugElement extends DebugElement {
+
+ /**
+ * Constructs a new debug element in the given target.
+ *
+ * @param target debug target
+ */
+ public PDADebugElement(IDebugTarget target) {
+ super(target);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugElement#getModelIdentifier()
+ */
+ public String getModelIdentifier() {
+ return DebugCorePlugin.ID_PDA_DEBUG_MODEL;
+ }
+
+ /**
+ * Sends a request to the PDA interpreter, waits for and returns the reply.
+ * <p>
+ * Interpreter commands and replies are as follows:
+ * <ul>
+ * <li><code>clear N</code> - clear the breakpoint on line <code>N</code>;
+ * reply is <code>ok</code></li>
+ * <li><code>data</code> - return the contents of the data stack; reply is the data
+ * from oldest to newest as a single string <code>"value|value|value|...|value|"</code></li>
+ * <li><code>drop</code> - pops the top stack frame off the call stack setting the
+ * instruction pointer to the calling statement in the calling frame</li>
+ * <li><code>eventstop E B</code> - optionally stop the interpreter when an error event
+ * <code>E</code> is encountered; <code>B</code> specifies stop (<code>1</code>) or
+ * continue (<code>0</code>). The possible events are <code>unimpinstr</code> and
+ * <code>nosuchlabel</code>. Reply is <code>ok</code>. When an event is encountered,
+ * the interpreter sends the error event (for example <code>unimlpemented instruction foo</code>)
+ * and corresponding suspend event (for example <code>suspended event unimpinstr</code>).</li>
+ * <li><code>exit</code> - end the interpreter; reply is <code>ok</code></li>
+ * <li><code>popdata</code> - pop the top value off the data stack; reply is the value</li>
+ * <li><code>pushdata V</code> - push the value <code>V</code> onto the data stack; reply is
+ * <code>ok</code></li>
+ * <li><code>resume</code> - resume execution of the program; reply is <code>ok</code></li>
+ * <li><code>set N</code> - set a line breakpoint on line <code>N</code> (lines are indexed
+ * from 0); reply is <code>ok</code></li>
+ * <li><code>setdata N V</code> - set the contents of data stack element <code>N</code> to
+ * value <code>V</code> (the data stack is indexed from 0, 0 being the oldest); reply
+ * is <code>ok</code></li>
+ * <li><code>setvar N M V</code> - set the contents of variable <code>M</code> from the control
+ * stack <code>N</code> to value <code>V</code> (the control stack is indexed from 0,
+ * 0 being the oldest); reply is <code>ok</code></li>
+ * <li><code>stack</code> - return the contents of the control stack (program counters, function and
+ * variable names); reply is control stack from oldest to newest as a single string
+ * <code>frame#frame#frame...#frame</code> where each frame is a string
+ * <code>"filename|pc|function name|variable name|variable name|...|variable name"</code></li>
+ * <li><code>step</code> - single step forward; reply is <code>ok</code></li>
+ * <li><code>stepreturn</code> - single step forward until the next <code>return</code> op code;
+ * stop before executing the <code>return</code> ; reply is <code>ok</code></li>
+ * <li><code>suspend</code> - suspend execution of the program and listen for debug commands;
+ * reply is <code>ok</code></li>
+ * <li><code>watch F::V M</code> - set a watchpoint on variable <code>V</code> in function
+ * <code>F</code> to magic value <code>M</code>; the magic value is a bit flag corresponding
+ * to read access (1), write access (2), or both (3); the magic value 0 clears the watchpoint;
+ * reply is <code>ok</code></li>
+ * <li><code>var N M</code> - return the contents of variable <code>M</code> in the control
+ * stack frame <code>N</code> (stack frames are indexed from 0, 0 being the oldest);
+ * reply is variable value</li>
+ * </ul>
+ * </p>
+ *
+ * @param request command
+ * @return reply
+ * @throws DebugException if the request fails
+ */
+ public String sendRequest(String request) throws DebugException {
+ return getPDADebugTarget().sendRequest(request);
+ }
+
+ /**
+ * Returns the debug target as a PDA target.
+ *
+ * @return PDA debug target
+ */
+ protected PDADebugTarget getPDADebugTarget() {
+ return (PDADebugTarget) getDebugTarget();
+ }
+
+ /**
+ * Returns the breakpoint manager
+ *
+ * @return the breakpoint manager
+ */
+ protected IBreakpointManager getBreakpointManager() {
+ return DebugPlugin.getDefault().getBreakpointManager();
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java
new file mode 100644
index 000000000..6df9fad76
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDADebugTarget.java
@@ -0,0 +1,525 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Vector;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.IBreakpointManager;
+import org.eclipse.debug.core.IBreakpointManagerListener;
+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.IMemoryBlock;
+import org.eclipse.debug.core.model.IProcess;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.examples.core.pda.breakpoints.PDALineBreakpoint;
+import org.eclipse.debug.examples.core.pda.breakpoints.PDARunToLineBreakpoint;
+
+
+/**
+ * PDA Debug Target
+ */
+public class PDADebugTarget extends PDADebugElement implements IDebugTarget, IBreakpointManagerListener, IPDAEventListener {
+
+ // associated system process (VM)
+ private IProcess fProcess;
+
+ // containing launch object
+ private ILaunch fLaunch;
+
+ // sockets to communicate with VM
+ private Socket fRequestSocket;
+ private PrintWriter fRequestWriter;
+ private BufferedReader fRequestReader;
+ private Socket fEventSocket;
+ private BufferedReader fEventReader;
+
+ // terminated state
+ private boolean fTerminated = false;
+
+ // threads
+ private IThread[] fThreads;
+ private PDAThread fThread;
+
+ // event dispatch job
+ private EventDispatchJob fEventDispatch;
+ // event listeners
+ private Vector fEventListeners = new Vector();
+
+ /**
+ * Listens to events from the PDA VM and fires corresponding
+ * debug events.
+ */
+ class EventDispatchJob extends Job {
+
+ public EventDispatchJob() {
+ super("PDA Event Dispatch");
+ setSystem(true);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ protected IStatus run(IProgressMonitor monitor) {
+ String event = "";
+ while (!isTerminated() && event != null) {
+ try {
+ event = fEventReader.readLine();
+ if (event != null) {
+ Object[] listeners = fEventListeners.toArray();
+ for (int i = 0; i < listeners.length; i++) {
+ ((IPDAEventListener)listeners[i]).handleEvent(event);
+ }
+ }
+ } catch (IOException e) {
+ terminated();
+ }
+ }
+ return Status.OK_STATUS;
+ }
+
+ }
+
+ /**
+ * Registers the given event listener. The listener will be notified of
+ * events in the program being interpretted. Has no effect if the listener
+ * is already registered.
+ *
+ * @param listener event listener
+ */
+ public void addEventListener(IPDAEventListener listener) {
+ if (!fEventListeners.contains(listener)) {
+ fEventListeners.add(listener);
+ }
+ }
+
+ /**
+ * Deregisters the given event listener. Has no effect if the listener is
+ * not currently registered.
+ *
+ * @param listener event listener
+ */
+ public void removeEventListener(IPDAEventListener listener) {
+ fEventListeners.remove(listener);
+ }
+
+ /**
+ * Constructs a new debug target in the given launch for the
+ * associated PDA VM process.
+ *
+ * @param launch containing launch
+ * @param process PDA VM
+ * @param requestPort port to send requests to the VM
+ * @param eventPort port to read events from
+ * @exception CoreException if unable to connect to host
+ */
+ public PDADebugTarget(ILaunch launch, IProcess process, int requestPort, int eventPort) throws CoreException {
+ super(null);
+ fLaunch = launch;
+ fProcess = process;
+ addEventListener(this);
+ try {
+ // give interpreter a chance to start
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ fRequestSocket = new Socket("localhost", requestPort);
+ fRequestWriter = new PrintWriter(fRequestSocket.getOutputStream());
+ fRequestReader = new BufferedReader(new InputStreamReader(fRequestSocket.getInputStream()));
+ // give interpreter a chance to open next socket
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ fEventSocket = new Socket("localhost", eventPort);
+ fEventReader = new BufferedReader(new InputStreamReader(fEventSocket.getInputStream()));
+ } catch (UnknownHostException e) {
+ requestFailed("Unable to connect to PDA VM", e);
+ } catch (IOException e) {
+ requestFailed("Unable to connect to PDA VM", e);
+ }
+ fThread = new PDAThread(this);
+ fThreads = new IThread[] {fThread};
+ fEventDispatch = new EventDispatchJob();
+ fEventDispatch.schedule();
+ IBreakpointManager breakpointManager = getBreakpointManager();
+ breakpointManager.addBreakpointListener(this);
+ breakpointManager.addBreakpointManagerListener(this);
+ // initialize error hanlding to suspend on 'unimplemented instructions'
+ // and 'no such label' errors
+ sendRequest("eventstop unimpinstr 1");
+ sendRequest("eventstop nosuchlabel 1");
+ }
+
+ /* (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 true;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugTarget#getName()
+ */
+ public String getName() throws DebugException {
+ return "PDA";
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IDebugTarget#supportsBreakpoint(org.eclipse.debug.core.model.IBreakpoint)
+ */
+ public boolean supportsBreakpoint(IBreakpoint breakpoint) {
+ if (!isTerminated() && breakpoint.getModelIdentifier().equals(getModelIdentifier())) {
+ try {
+ String program = getLaunch().getLaunchConfiguration().getAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, (String)null);
+ if (program != null) {
+ IResource resource = null;
+ if (breakpoint instanceof PDARunToLineBreakpoint) {
+ PDARunToLineBreakpoint rtl = (PDARunToLineBreakpoint) breakpoint;
+ resource = rtl.getSourceFile();
+ } else {
+ IMarker marker = breakpoint.getMarker();
+ if (marker != null) {
+ resource = marker.getResource();
+ }
+ }
+ if (resource != null) {
+ IPath p = new Path(program);
+ return resource.getFullPath().equals(p);
+ }
+ }
+ } catch (CoreException e) {
+ }
+ }
+ 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();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
+ */
+ public boolean isTerminated() {
+ return fTerminated || getProcess().isTerminated();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ITerminate#terminate()
+ */
+ public void terminate() throws DebugException {
+ getThread().terminate();
+ }
+ /* (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 !isTerminated() && 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.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
+ */
+ public void breakpointAdded(IBreakpoint breakpoint) {
+ if (supportsBreakpoint(breakpoint)) {
+ try {
+ if ((breakpoint.isEnabled() && getBreakpointManager().isEnabled()) || !breakpoint.isRegistered()) {
+ PDALineBreakpoint pdaBreakpoint = (PDALineBreakpoint)breakpoint;
+ pdaBreakpoint.install(this);
+ }
+ } 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 {
+ PDALineBreakpoint pdaBreakpoint = (PDALineBreakpoint)breakpoint;
+ pdaBreakpoint.remove(this);
+ } 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() && getBreakpointManager().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 VM and it has started.
+ * Resume the VM.
+ */
+ private void started() {
+ fireCreationEvent();
+ installDeferredBreakpoints();
+ try {
+ resume();
+ } catch (DebugException e) {
+ }
+ }
+
+ /**
+ * Install breakpoints that are already registered with the breakpoint
+ * manager.
+ */
+ private void installDeferredBreakpoints() {
+ IBreakpoint[] breakpoints = getBreakpointManager().getBreakpoints(getModelIdentifier());
+ for (int i = 0; i < breakpoints.length; i++) {
+ breakpointAdded(breakpoints[i]);
+ }
+ }
+
+ /**
+ * Called when this debug target terminates.
+ */
+ private synchronized void terminated() {
+ fTerminated = true;
+ fThread = null;
+ fThreads = new IThread[0];
+ IBreakpointManager breakpointManager = getBreakpointManager();
+ breakpointManager.removeBreakpointListener(this);
+ breakpointManager.removeBreakpointManagerListener(this);
+ fireTerminateEvent();
+ removeEventListener(this);
+ }
+
+ /**
+ * Returns the values on the data stack (top down)
+ *
+ * @return the values on the data stack (top down)
+ */
+ public IValue[] getDataStack() throws DebugException {
+ String dataStack = sendRequest("data");
+ if (dataStack != null && dataStack.length() > 0) {
+ String[] values = dataStack.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 PDAStackValue(this, value, i);
+ }
+ return theValues;
+ }
+ return new IValue[0];
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.examples.core.pda.model.PDADebugElement#sendRequest(java.lang.String)
+ */
+ public String sendRequest(String request) throws DebugException {
+ synchronized (fRequestSocket) {
+ fRequestWriter.println(request);
+ fRequestWriter.flush();
+ try {
+ // wait for reply
+ return fRequestReader.readLine();
+ } catch (IOException e) {
+ requestFailed("Request failed: " + request, e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * When the breakpoint manager disables, remove all registered breakpoints
+ * requests from the VM. When it enables, reinstall them.
+ */
+ public void breakpointManagerEnablementChanged(boolean enabled) {
+ IBreakpoint[] breakpoints = getBreakpointManager().getBreakpoints(getModelIdentifier());
+ for (int i = 0; i < breakpoints.length; i++) {
+ if (enabled) {
+ breakpointAdded(breakpoints[i]);
+ } else {
+ breakpointRemoved(breakpoints[i], null);
+ }
+ }
+ }
+
+ /**
+ * Returns whether popping the data stack is currently permitted
+ *
+ * @return whether popping the data stack is currently permitted
+ */
+ public boolean canPop() {
+ try {
+ return !isTerminated() && isSuspended() && getDataStack().length > 0;
+ } catch (DebugException e) {
+ }
+ return false;
+ }
+
+ /**
+ * Pops and returns the top of the data stack
+ *
+ * @return the top value on the stack
+ * @throws DebugException if the stack is empty or the request fails
+ */
+ public IValue pop() throws DebugException {
+ IValue[] dataStack = getDataStack();
+ if (dataStack.length > 0) {
+ sendRequest("popdata");
+ return dataStack[0];
+ }
+ requestFailed("Empty stack", null);
+ return null;
+ }
+
+ /**
+ * Returns whether pushing a value is currently supported.
+ *
+ * @return whether pushing a value is currently supported
+ */
+ public boolean canPush() {
+ return !isTerminated() && isSuspended();
+ }
+
+ /**
+ * Pushes a value onto the stack.
+ *
+ * @param value value to push
+ * @throws DebugException on failure
+ */
+ public void push(String value) throws DebugException {
+ sendRequest("pushdata " + value);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
+ */
+ public void handleEvent(String event) {
+ if (event.equals("started")) {
+ started();
+ } else if (event.equals("terminated")) {
+ terminated();
+ }
+ }
+
+ /**
+ * Returns this debug target's single thread, or <code>null</code>
+ * if terminated.
+ *
+ * @return this debug target's single thread, or <code>null</code>
+ * if terminated
+ */
+ public synchronized PDAThread getThread() {
+ return fThread;
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java
new file mode 100644
index 000000000..a3cbe43c8
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackFrame.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+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;
+
+/**
+ * PDA stack frame.
+ */
+public class PDAStackFrame extends PDADebugElement implements IStackFrame {
+
+ private PDAThread fThread;
+ private String fName;
+ private int fPC;
+ private String fFileName;
+ private int fId;
+
+ /**
+ * 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 PDAStackFrame(PDAThread thread, String data, int id) {
+ super(thread.getPDADebugTarget());
+ fId = id;
+ fThread = thread;
+ init(data);
+ }
+
+ /**
+ * Initializes this frame based on its data
+ *
+ * @param data
+ */
+ private void init(String data) {
+ String[] strings = data.split("\\|");
+ String fileName = strings[0];
+ fFileName = (new Path(fileName)).lastSegment();
+ String pc = strings[1];
+ fPC = Integer.parseInt(pc) + 1;
+ fName = strings[2];
+ int numVars = strings.length - 3;
+ IVariable[] vars = new IVariable[numVars];
+ for (int i = 0; i < numVars; i++) {
+ vars[i] = new PDAVariable(this, strings[i + 3]);
+ }
+ fThread.setVariables(this, vars);
+ }
+
+ /* (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 fThread.getVariables(this);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IStackFrame#hasVariables()
+ */
+ public boolean hasVariables() throws DebugException {
+ return getVariables().length > 0;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IStackFrame#getLineNumber()
+ */
+ public int getLineNumber() throws DebugException {
+ return fPC;
+ }
+ /* (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 fName;
+ }
+ /* (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 PDAStackFrame) {
+ PDAStackFrame sf = (PDAStackFrame)obj;
+ return sf.getThread().equals(getThread()) &&
+ sf.getSourceName().equals(getSourceName()) &&
+ sf.fId == fId;
+ }
+ 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/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java
new file mode 100644
index 000000000..2f13211f4
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAStackValue.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+/**
+ * A value on the data stack
+ */
+public class PDAStackValue extends PDAValue {
+
+ private int fIndex;
+
+ /**
+ * Constructs a value that appears on the data stack
+ *
+ * @param target debug target
+ * @param value value on the stack
+ * @param index index on the stack
+ */
+ public PDAStackValue(PDADebugTarget target, String value, int index) {
+ super(target, value);
+ fIndex = index;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ return super.equals(obj) && ((PDAStackValue)obj).fIndex == fIndex;
+ }
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return super.hashCode() + fIndex;
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java
new file mode 100644
index 000000000..6a4102ac3
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAThread.java
@@ -0,0 +1,426 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IVariable;
+
+/**
+ * A PDA thread. A PDA VM is single threaded.
+ */
+public class PDAThread extends PDADebugElement implements IThread, IPDAEventListener {
+
+ /**
+ * Breakpoint this thread is suspended at or <code>null</code>
+ * if none.
+ */
+ private IBreakpoint fBreakpoint;
+
+ /**
+ * Whether this thread is stepping
+ */
+ private boolean fStepping = false;
+
+ /**
+ * Wether this thread is suspended
+ */
+ private boolean fSuspended = false;
+
+ /**
+ * Most recent error event or <code>null</code>
+ */
+ private String fErrorEvent;
+
+ /**
+ * Table mapping stack frames to current variables
+ */
+ private Map fVariables = new HashMap();
+
+ /**
+ * Constructs a new thread for the given target
+ *
+ * @param target VM
+ */
+ public PDAThread(PDADebugTarget target) {
+ super(target);
+ getPDADebugTarget().addEventListener(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IThread#getStackFrames()
+ */
+ public IStackFrame[] getStackFrames() throws DebugException {
+ if (isSuspended()) {
+ String framesData = sendRequest("stack");
+ if (framesData != null) {
+ String[] frames = framesData.split("#");
+ IStackFrame[] theFrames = new IStackFrame[frames.length];
+ for (int i = 0; i < frames.length; i++) {
+ String data = frames[i];
+ theFrames[frames.length - i - 1] = new PDAStackFrame(this, data, i);
+ }
+ return theFrames;
+ }
+ }
+ 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() {
+ return "Main thread";
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IThread#getBreakpoints()
+ */
+ public IBreakpoint[] getBreakpoints() {
+ if (fBreakpoint == null) {
+ return new IBreakpoint[0];
+ }
+ return new IBreakpoint[]{fBreakpoint};
+ }
+
+ /**
+ * Notifies this thread it has been suspended by the given breakpoint.
+ *
+ * @param breakpoint breakpoint
+ */
+ public void suspendedBy(IBreakpoint breakpoint) {
+ fBreakpoint = breakpoint;
+ suspended(DebugEvent.BREAKPOINT);
+ }
+
+ /* (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 fSuspended && !isTerminated();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ISuspendResume#resume()
+ */
+ public void resume() throws DebugException {
+ //#ifdef ex2
+//# // TODO: Exercise 2 - send resume request to interpreter
+ //#else
+ sendRequest("resume");
+ //#endif
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
+ */
+ public void suspend() throws DebugException {
+ //#ifdef ex2
+//# // TODO: Exercise 2 - send suspend request to interpreter
+ //#else
+ sendRequest("suspend");
+ //#endif
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IStep#canStepInto()
+ */
+ public boolean canStepInto() {
+ return false;
+ }
+ /* (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() {
+ 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 {
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IStep#stepOver()
+ */
+ public void stepOver() throws DebugException {
+ sendRequest("step");
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IStep#stepReturn()
+ */
+ public void stepReturn() throws DebugException {
+ }
+ /* (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 {
+ //#ifdef ex2
+//# // TODO: Exercise 2 - send termination request to interpreter
+ //#else
+ sendRequest("exit");
+ //#endif
+ }
+
+ /**
+ * Sets whether this thread is stepping
+ *
+ * @param stepping whether stepping
+ */
+ private void setStepping(boolean stepping) {
+ fStepping = stepping;
+ }
+
+ /**
+ * Sets whether this thread is suspended
+ *
+ * @param suspended whether suspended
+ */
+ private void setSuspended(boolean suspended) {
+ fSuspended = suspended;
+ }
+
+ /**
+ * Sets the most recent error event encountered, or <code>null</code>
+ * to clear the most recent error
+ *
+ * @param event one of 'unimpinstr' or 'nosuchlabel' or <code>null</code>
+ */
+ private void setError(String event) {
+ fErrorEvent = event;
+ }
+
+ /**
+ * Returns the most revent error event encountered since the last
+ * suspend, or <code>null</code> if none.
+ *
+ * @return the most revent error event encountered since the last
+ * suspend, or <code>null</code> if none
+ */
+ public Object getError() {
+ return fErrorEvent;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.examples.core.pda.model.IPDAEventListener#handleEvent(java.lang.String)
+ */
+ public void handleEvent(String event) {
+ // clear previous state
+ fBreakpoint = null;
+ setStepping(false);
+
+ // handle events
+ if (event.startsWith("resumed")) {
+ setSuspended(false);
+ if (event.endsWith("step")) {
+ setStepping(true);
+ resumed(DebugEvent.STEP_OVER);
+ //#ifdef ex2
+//# }
+//# // TODO: Exercise 2 - handle/fire "client" resume event
+ //#else
+ } else if (event.endsWith("client")) {
+ resumed(DebugEvent.CLIENT_REQUEST);
+ }
+ //#endif
+ //#ifdef ex5
+//# // TODO: Exercise 5 - handle start of drop event
+ //#else
+ else if (event.endsWith("drop")) {
+ resumed(DebugEvent.STEP_RETURN);
+ }
+ //#endif
+ } else if (event.startsWith("suspended")) {
+ setSuspended(true);
+ //#ifdef ex2
+//# // TODO: Exercise 2 - handle/fire "client" suspend event
+//# if (event.endsWith("step")) {
+//# suspended(DebugEvent.STEP_END);
+//# } else if (event.startsWith("suspended event") && getError() != null) {
+//# exceptionHit();
+//# }
+ //#else
+ if (event.endsWith("client")) {
+ suspended(DebugEvent.CLIENT_REQUEST);
+ } else if (event.endsWith("step")) {
+ suspended(DebugEvent.STEP_END);
+ } else if (event.startsWith("suspended event") && getError() != null) {
+ exceptionHit();
+ }
+ //#endif
+ //#ifdef ex5
+//# // TODO: Exercise 5 - handle end of drop event
+ //#else
+ else if (event.endsWith("drop")) {
+ suspended(DebugEvent.STEP_END);
+ }
+ //#endif
+ } else if (event.equals("started")) {
+ fireCreationEvent();
+ } else {
+ setError(event);
+ }
+
+ }
+
+ /**
+ * Notification the target has resumed for the given reason.
+ * Clears any error condition that was last encountered and
+ * fires a resume event, and clears all cached variables
+ * for stack frames.
+ *
+ * @param detail reason for the resume
+ */
+ private void resumed(int detail) {
+ setError(null);
+ synchronized (fVariables) {
+ fVariables.clear();
+ }
+ fireResumeEvent(detail);
+ }
+
+ /**
+ * Notification the target has suspended for the given reason
+ *
+ * @param detail reason for the suspend
+ */
+ private void suspended(int detail) {
+ fireSuspendEvent(detail);
+ }
+
+ /**
+ * Notification an error was encountered. Fires a breakpoint
+ * suspend event.
+ */
+ private void exceptionHit() {
+ suspended(DebugEvent.BREAKPOINT);
+ }
+
+ /**
+ * Sets the current variables for the given stack frame. Called
+ * by PDA stack frame when it is created.
+ *
+ * @param frame
+ * @param variables
+ */
+ protected void setVariables(IStackFrame frame, IVariable[] variables) {
+ synchronized (fVariables) {
+ fVariables.put(frame, variables);
+ }
+ }
+
+ /**
+ * Returns the current variables for the given stack frame, or
+ * <code>null</code> if none.
+ *
+ * @param frame stack frame
+ * @return variables or <code>null</code>
+ */
+ protected IVariable[] getVariables(IStackFrame frame) {
+ synchronized (fVariables) {
+ IVariable[] variables = (IVariable[]) fVariables.get(frame);
+ if (variables == null) {
+ return new IVariable[0];
+ }
+ return variables;
+ }
+ }
+
+ /**
+ * Pops the top frame off the callstack.
+ *
+ * @throws DebugException
+ */
+ public void pop() throws DebugException {
+ //#ifdef ex5
+//# // TODO: Exercise 5 - send drop request
+ //#else
+ sendRequest("drop");
+ //#endif
+ }
+
+ /**
+ * Returns whether this thread can pop the top stack frame.
+ *
+ * @return whether this thread can pop the top stack frame
+ */
+ public boolean canPop() {
+ //#ifdef ex5
+//# // TODO: Exercise 5 - allow pop if there is more than 1 frame on the stack
+ //#else
+ try {
+ return getStackFrames().length > 1;
+ } catch (DebugException e) {
+ }
+ //#endif
+ return false;
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java
new file mode 100644
index 000000000..e871004af
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAValue.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IVariable;
+
+/**
+ * Value of a PDA variable.
+ */
+public class PDAValue extends PDADebugElement implements IValue {
+
+ private String fValue;
+
+ public PDAValue(PDADebugTarget target, String value) {
+ super(target);
+ fValue = value;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#getReferenceTypeName()
+ */
+ public String getReferenceTypeName() throws DebugException {
+ try {
+ Integer.parseInt(fValue);
+ } catch (NumberFormatException e) {
+ return "text";
+ }
+ return "integer";
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#getValueString()
+ */
+ public String getValueString() throws DebugException {
+ return fValue;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#isAllocated()
+ */
+ public boolean isAllocated() throws DebugException {
+ return true;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#getVariables()
+ */
+ public IVariable[] getVariables() throws DebugException {
+ return new IVariable[0];
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValue#hasVariables()
+ */
+ public boolean hasVariables() throws DebugException {
+ return fValue.split("\\W+").length > 1;
+ }
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object obj) {
+ return obj instanceof PDAValue && ((PDAValue)obj).fValue.equals(fValue);
+ }
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return fValue.hashCode();
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java
new file mode 100644
index 000000000..c57a9d24a
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/PDAVariable.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+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;
+
+/**
+ * A variable in a PDA stack frame
+ */
+public class PDAVariable extends PDADebugElement implements IVariable {
+
+ // name & stack frmae
+ private String fName;
+ private PDAStackFrame fFrame;
+
+ /**
+ * Constructs a variable contained in the given stack frame
+ * with the given name.
+ *
+ * @param frame owning stack frame
+ * @param name variable name
+ */
+ public PDAVariable(PDAStackFrame frame, String name) {
+ super(frame.getPDADebugTarget());
+ fFrame = frame;
+ fName = name;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IVariable#getValue()
+ */
+ public IValue getValue() throws DebugException {
+ String value = sendRequest("var " + getStackFrame().getIdentifier() + " " + getName());
+ return new PDAValue(this.getPDADebugTarget(), value);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IVariable#getName()
+ */
+ public String getName() throws DebugException {
+ return fName;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IVariable#getReferenceTypeName()
+ */
+ public String getReferenceTypeName() throws DebugException {
+ return "Thing";
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IVariable#hasValueChanged()
+ */
+ public boolean hasValueChanged() throws DebugException {
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValueModification#setValue(java.lang.String)
+ */
+ public void setValue(String expression) throws DebugException {
+ sendRequest("setvar " + getStackFrame().getIdentifier() + " " + getName() + " " + expression);
+ fireChangeEvent(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 true;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.IValueModification#verifyValue(java.lang.String)
+ */
+ public boolean verifyValue(String expression) throws DebugException {
+ return true;
+ }
+ /* (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 PDAStackFrame getStackFrame() {
+ return fFrame;
+ }
+
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/WordStructureDelegate.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/WordStructureDelegate.java
new file mode 100644
index 000000000..dbb06cb22
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/model/WordStructureDelegate.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.model;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.ILogicalStructureTypeDelegate;
+import org.eclipse.debug.core.model.IValue;
+
+/**
+ * Logical stucture to translate a string into its words.
+ */
+public class WordStructureDelegate implements ILogicalStructureTypeDelegate {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ILogicalStructureTypeDelegate#providesLogicalStructure(org.eclipse.debug.core.model.IValue)
+ */
+ public boolean providesLogicalStructure(IValue value) {
+ //#ifdef ex6
+//# // TODO: Exercise 6 - provide logical structures if the value has multiple words
+ //#else
+ try {
+ String string = value.getValueString();
+ String[] words = string.split("\\W+");
+ return words.length > 1;
+ } catch (DebugException e) {
+ }
+ //#endif
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.core.model.ILogicalStructureTypeDelegate#getLogicalStructure(org.eclipse.debug.core.model.IValue)
+ */
+ public IValue getLogicalStructure(IValue value) throws CoreException {
+ //#ifdef ex6
+//# // TODO: Exercise 6 - create an array from the given value
+//# return null;
+ //#else
+ return new PDAArray((PDAValue)value);
+ //#endif
+ }
+
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java
new file mode 100644
index 000000000..f975cf7c3
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupDirector.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.sourcelookup;
+
+import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
+import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
+
+/**
+ * PDA source lookup director. For PDA source lookup there is one source
+ * lookup participant.
+ */
+public class PDASourceLookupDirector extends AbstractSourceLookupDirector {
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupDirector#initializeParticipants()
+ */
+ public void initializeParticipants() {
+ //#ifdef ex4
+//# // TODO: Exercise 4 - add our participant to this director
+ //#else
+ addParticipants(new ISourceLookupParticipant[]{new PDASourceLookupParticipant()});
+ //#endif
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java
new file mode 100644
index 000000000..0d07ce78d
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourceLookupParticipant.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.sourcelookup;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant;
+import org.eclipse.debug.examples.core.pda.model.PDAStackFrame;
+
+
+/**
+ * The PDA source lookup participant knows how to translate a
+ * PDA stack frame into a source file name
+ */
+public class PDASourceLookupParticipant extends AbstractSourceLookupParticipant {
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object)
+ */
+ public String getSourceName(Object object) throws CoreException {
+ //#ifdef ex4
+//# // TODO: Exercise 4 - return the name of the source file for the given stack frame
+//# return null;
+ //#else
+ if (object instanceof PDAStackFrame) {
+ return ((PDAStackFrame)object).getSourceName();
+ }
+ return null;
+ //#endif
+ }
+}
diff --git a/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java
new file mode 100644
index 000000000..d91b3f245
--- /dev/null
+++ b/org.eclipse.debug.examples.core/src/org/eclipse/debug/examples/core/pda/sourcelookup/PDASourcePathComputerDelegate.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Bjorn Freeman-Benson - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.debug.examples.core.pda.sourcelookup;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.sourcelookup.ISourceContainer;
+import org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate;
+import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer;
+import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer;
+import org.eclipse.debug.core.sourcelookup.containers.WorkspaceSourceContainer;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+
+
+/**
+ * Computes the default source lookup path for a PDA launch configuration.
+ * The default source lookup path is the folder or project containing
+ * the PDA program being launched. If the program is not specified, the workspace
+ * is searched by default.
+ */
+public class PDASourcePathComputerDelegate implements ISourcePathComputerDelegate {
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.core.sourcelookup.ISourcePathComputerDelegate#computeSourceContainers(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ public ISourceContainer[] computeSourceContainers(ILaunchConfiguration configuration, IProgressMonitor monitor) throws CoreException {
+ String path = configuration.getAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, (String)null);
+ ISourceContainer sourceContainer = null;
+ if (path != null) {
+ IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(path));
+ if (resource != null) {
+ //#ifdef ex4
+//# // TODO: Exercise 4 - seed the source lookup path
+ //#else
+ IContainer container = resource.getParent();
+ if (container.getType() == IResource.PROJECT) {
+ sourceContainer = new ProjectSourceContainer((IProject)container, false);
+ } else if (container.getType() == IResource.FOLDER) {
+ sourceContainer = new FolderSourceContainer(container, false);
+ }
+ //#endif
+ }
+ }
+ if (sourceContainer == null) {
+ sourceContainer = new WorkspaceSourceContainer();
+ }
+ return new ISourceContainer[]{sourceContainer};
+ }
+}

Back to the top