Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.debug.examples.core/.classpath7
-rw-r--r--org.eclipse.debug.examples.core/.cvsignore1
-rw-r--r--org.eclipse.debug.examples.core/.project28
-rw-r--r--org.eclipse.debug.examples.core/.settings/org.eclipse.jdt.core.prefs47
-rw-r--r--org.eclipse.debug.examples.core/META-INF/MANIFEST.MF17
-rw-r--r--org.eclipse.debug.examples.core/about.html28
-rw-r--r--org.eclipse.debug.examples.core/build.properties18
-rw-r--r--org.eclipse.debug.examples.core/pdavm/pda.pl672
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtest2.pda48
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda11
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtest6.pda31
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtest8.pda14
-rw-r--r--org.eclipse.debug.examples.core/pdavm/tests/vmtests.pl448
-rw-r--r--org.eclipse.debug.examples.core/plugin.xml84
-rw-r--r--org.eclipse.debug.examples.core/samples/counter.pda11
-rw-r--r--org.eclipse.debug.examples.core/samples/drop.pda12
-rw-r--r--org.eclipse.debug.examples.core/samples/example.pda35
-rw-r--r--org.eclipse.debug.examples.core/samples/fibonacci.pda32
-rw-r--r--org.eclipse.debug.examples.core/samples/structures.pda8
-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
-rw-r--r--org.eclipse.debug.examples.ui/.classpath7
-rw-r--r--org.eclipse.debug.examples.ui/.cvsignore1
-rw-r--r--org.eclipse.debug.examples.ui/.project28
-rw-r--r--org.eclipse.debug.examples.ui/.settings/org.eclipse.jdt.core.prefs37
-rw-r--r--org.eclipse.debug.examples.ui/META-INF/MANIFEST.MF25
-rw-r--r--org.eclipse.debug.examples.ui/about.html28
-rw-r--r--org.eclipse.debug.examples.ui/build.properties8
-rw-r--r--org.eclipse.debug.examples.ui/icons/full/dlcl16/pop.gifbin0 -> 159 bytes
-rw-r--r--org.eclipse.debug.examples.ui/icons/full/dlcl16/push.gifbin0 -> 361 bytes
-rw-r--r--org.eclipse.debug.examples.ui/icons/full/elcl16/pop.gifbin0 -> 163 bytes
-rw-r--r--org.eclipse.debug.examples.ui/icons/full/elcl16/push.gifbin0 -> 590 bytes
-rw-r--r--org.eclipse.debug.examples.ui/icons/full/obj16/pda.gifbin0 -> 182 bytes
-rw-r--r--org.eclipse.debug.examples.ui/plugin.xml174
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/DebugUIPlugin.java182
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/AdapterFactory.java48
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/ModelProxyFactory.java32
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.java70
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetProxy.java38
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAThreadEventHandler.java147
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDABreakpointAdapter.java220
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAEditorAdapterFactory.java57
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDARunToLineAdapter.java76
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/AnnotationHover.java45
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAContentAssistProcessor.java102
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAContentAssistant.java42
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAEditor.java48
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAEditorMessages.properties15
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAScanner.java92
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDASourceViewerConfiguration.java63
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java95
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/TextHover.java91
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/WordFinder.java79
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDALaunchShortcut.java75
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDAMainTab.java185
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDATabGroup.java39
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/presentation/PDAModelPresentation.java192
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java177
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopAction.java99
-rw-r--r--org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushAction.java61
77 files changed, 6953 insertions, 0 deletions
diff --git a/org.eclipse.debug.examples.core/.classpath b/org.eclipse.debug.examples.core/.classpath
new file mode 100644
index 000000000..b7464f3ca
--- /dev/null
+++ b/org.eclipse.debug.examples.core/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.debug.examples.core/.cvsignore b/org.eclipse.debug.examples.core/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/org.eclipse.debug.examples.core/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/org.eclipse.debug.examples.core/.project b/org.eclipse.debug.examples.core/.project
new file mode 100644
index 000000000..99d835c1a
--- /dev/null
+++ b/org.eclipse.debug.examples.core/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>example.debug.core</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.debug.examples.core/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.debug.examples.core/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..d6de6c150
--- /dev/null
+++ b/org.eclipse.debug.examples.core/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,47 @@
+#Mon Jan 24 20:23:34 CST 2005
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.4
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.3
diff --git a/org.eclipse.debug.examples.core/META-INF/MANIFEST.MF b/org.eclipse.debug.examples.core/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..0de72ed97
--- /dev/null
+++ b/org.eclipse.debug.examples.core/META-INF/MANIFEST.MF
@@ -0,0 +1,17 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Example Debug Core Plug-in
+Bundle-SymbolicName: org.eclipse.debug.examples.core;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.debug.examples.core.pda.DebugCorePlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.core.variables,
+ org.eclipse.debug.core
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.debug.examples.core.pda,
+ org.eclipse.debug.examples.core.pda.breakpoints,
+ org.eclipse.debug.examples.core.pda.launcher,
+ org.eclipse.debug.examples.core.pda.model,
+ org.eclipse.debug.examples.core.pda.sourcelookup
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
diff --git a/org.eclipse.debug.examples.core/about.html b/org.eclipse.debug.examples.core/about.html
new file mode 100644
index 000000000..460233046
--- /dev/null
+++ b/org.eclipse.debug.examples.core/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 2, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/build.properties b/org.eclipse.debug.examples.core/build.properties
new file mode 100644
index 000000000..bc583f953
--- /dev/null
+++ b/org.eclipse.debug.examples.core/build.properties
@@ -0,0 +1,18 @@
+###############################################################################
+# 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
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+ pdavm/,\
+ examples/,\
+ META-INF/,\
+ about.html,\
+ .
diff --git a/org.eclipse.debug.examples.core/pdavm/pda.pl b/org.eclipse.debug.examples.core/pdavm/pda.pl
new file mode 100644
index 000000000..82829e460
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/pda.pl
@@ -0,0 +1,672 @@
+#!perl.exe
+
+use strict;
+use warnings;
+use IO::Socket;
+
+#####################################################################
+# Copyright (c) 2005 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:
+# Bjorn Freeman-Benson - initial API and implementation
+#####################################################################
+
+#####################################################################
+# #
+# I N I T I A L I Z A T I O N A N D V A R I A B L E S #
+# #
+#####################################################################
+#
+# The push down automata stack (the data stack)
+#
+my @stack;
+#
+# Load all the code into memory
+# The code is stored as an array of strings, each line of
+# the source file being one entry in the array.
+#
+my $filename = shift;
+open INFILE, $filename or die $!;
+my @code = <INFILE>;
+close INFILE;
+
+my %labels;
+sub map_labels {
+ #
+ # A mapping of labels to indicies in the code array
+ #
+ %labels = ( );
+ my $idx = 0;
+ while( $idx <= $#code ) {
+ if( length $code[$idx] > 0 ) {
+ $code[$idx] =~ /^\s*(.+?)\s*$/;
+ $code[$idx] = $1;
+ $labels{$1} = $idx if( $code[$idx] =~ /^:(\S+)/ );
+ } else {
+ $code[$idx] = "\n";
+ }
+ $idx ++;
+ }
+}
+map_labels();
+#
+# The stack of stack frames (the control stack)
+# Each stack frame is a mapping of variable names to values.
+# There are a number of special variable names:
+# _pc_ is the current program counter in the frame
+# the pc points to the next instruction to be executed
+# _func_ is the name of the function in this frame
+#
+my @frames;
+my $currentframe;
+$currentframe = {
+ _pc_ => 0,
+ _func_ => 'main'
+ };
+
+#
+# The command line argument to start a debug session.
+#
+my $debugflag = shift;
+#
+# The port to listen for debug commands on
+# and the port to send debug events to
+#
+my $debugport;
+my $debugport2;
+#
+# The socket to listen for debug commands on
+# and the socket to send debug events on
+#
+my $debugsock;
+my $debugsock2;
+#
+# An input buffer
+#
+my $debugbuf;
+#
+# Breakpoint array
+# breakpoints are stored as a boolean for each line of code
+# if the boolean is true, there is a breakpoint on that line
+#
+my @breakpoints;
+#
+# Mapping of debugger commands to functions that evaluate them
+#
+my %debug_commands = (
+ clear => \&debug_clear_breakpoint,
+ data => \&debug_data,
+ drop => \&debug_drop_frame,
+ eval => \&debug_eval,
+ eventstop => \&debug_event_stop,
+ exit => \&debug_exit,
+ popdata => \&debug_pop,
+ pushdata => \&debug_push,
+ resume => \&debug_resume,
+ set => \&debug_set_breakpoint,
+ setdata => \&debug_set_data,
+ setvar => \&debug_set_variable,
+ stack => \&debug_stack,
+ step => \&debug_step,
+ stepreturn => \&debug_step_return,
+ suspend => \&debug_suspend,
+ var => \&debug_var,
+ watch => \&debug_watch
+);
+
+#
+# The run flag is true if the VM is running.
+# If the run flag is false, the VM exits the
+# next time the main instruction loop runs.
+#
+my $run = 1;
+#
+# The suspend flag is true if the VM should suspend
+# running the program and just listen for debug commands.
+#
+my $suspend = 0;
+my $started = 1;
+$suspend = "client" if( $debugflag );
+#
+# The step flag is used to control single-stepping.
+# See the implementation of the "step" debug command.
+# The stepreturn flag is used to control step-return.
+# The eventstops table holds which events cause suspends and which do not.
+# The watchpoints table holds watchpoint information.
+# variablename_stackframedepth => N
+# N = 0 is no watch
+# N = 1 is read watch
+# N = 2 is write watch
+# N = 3 is both, etc.
+#
+my $step = 0;
+my $stepreturn = 0;
+my %eventstops = ( "unimpinstr" => 0,
+ "nosuchlabel" => 0,
+ );
+my %watchpoints = ( );
+
+#
+# Mapping of the names of the instructions to the functions that evaluate them
+#
+my %instructions = (
+ add => \&add,
+ branch_not_zero => \&branch_not_zero,
+ call => \&call,
+ dec => \&dec,
+ dup => \&dup,
+ halt => \&halt,
+ output => \&output,
+ pop => \&ipop,
+ push => \&ipush,
+ return => \&ireturn,
+ var => \&var,
+ xyzzy => \&internal_end_eval,
+);
+
+#####################################################################
+# #
+# M A I N I N T E R P R E T E R #
+# #
+#####################################################################
+#
+# Open a debug session if the command line argument is given.
+#
+start_debugger();
+send_debug_event( "started", 0 );
+debug_ui() if( $suspend );
+#
+# The main run loop
+#
+while( $run ) {
+ check_for_breakpoint();
+ debug_ui() if( $suspend );
+ yield_to_debug();
+ my $instruction = fetch_instruction();
+ increment_pc();
+ do_one_instruction($instruction);
+ if( $$currentframe{_pc_} > $#code ) {
+ $run = 0;
+ } elsif( $stepreturn ) {
+ $instruction = fetch_instruction();
+ $suspend = "step" if( is_return_instruction($instruction) );
+ }
+}
+send_debug_event( "terminated", 0 );
+
+sub fetch_instruction {
+ my $pc = $$currentframe{_pc_};
+ my $theinstruction = $code[$pc];
+ return $theinstruction;
+}
+sub is_return_instruction {
+ my $theinstruction = shift;
+ if( $theinstruction =~ /^:/ ) {
+ return 0;
+ } elsif( $theinstruction =~ /^#/ ) {
+ return 0;
+ } else {
+ $theinstruction =~ /^(\S+)\s*(.*)/;
+ return $1 eq "return";
+ }
+}
+sub increment_pc {
+ my $pc = $$currentframe{_pc_};
+ $pc++;
+ $$currentframe{_pc_} = $pc;
+}
+sub decrement_pc {
+ my $pc = $$currentframe{_pc_};
+ $pc--;
+ $$currentframe{_pc_} = $pc;
+}
+sub do_one_instruction {
+ my $theinstruction = shift;
+ if( $theinstruction =~ /^:/ ) {
+ # label
+ $suspend = "step" if( $step );
+ } elsif( $theinstruction =~ /^#/ ) {
+ # comment
+ } else {
+ $theinstruction =~ /^(\S+)\s*(.*)/;
+ my $op = $1;
+ my $instr = $instructions{$op};
+ if( $instr ) {
+ &$instr( $theinstruction, $2 );
+ $suspend = "step" if( $step );
+ } else {
+ send_debug_event( "unimplemented instruction $op", 1 );
+ if( $eventstops{"unimpinstr"} ) {
+ $suspend = "event unimpinstr";
+ decrement_pc();
+ }
+ }
+ }
+}
+
+#####################################################################
+# #
+# I N S T R U C T I O N S #
+# #
+#####################################################################
+sub add {
+ my $val1 = pop @stack;
+ my $val2 = pop @stack;
+ my $val = $val1 + $val2;
+ push @stack, $val;
+}
+
+sub branch_not_zero {
+ my $val = pop @stack;
+ if( $val ) {
+ shift;
+ my $label = shift;
+ my $dest = $labels{$label};
+ if( !defined $dest ) {
+ send_debug_event( "no such label $label", 1 );
+ if( $eventstops{"nosuchlabel"} ) {
+ $suspend = "event nosuchlabel";
+ push @stack, $val;
+ decrement_pc();
+ }
+ } else {
+ $$currentframe{_pc_} = $dest;
+ }
+ }
+}
+
+sub call {
+ shift;
+ my $label = shift;
+ my $dest = $labels{$label};
+ if( !defined $dest ) {
+ send_debug_event( "no such label $label", 1 );
+ if( $eventstops{"nosuchlabel"} ) {
+ $suspend = "event nosuchlabel";
+ decrement_pc();
+ }
+ } else {
+ push @frames, $currentframe;
+ $currentframe = {
+ _pc_ => $dest,
+ _func_ => $label
+ };
+ }
+}
+
+sub dec {
+ my $val = pop @stack;
+ $val--;
+ push @stack, $val;
+}
+
+sub dup {
+ my $val = pop @stack;
+ push @stack, $val;
+ push @stack, $val;
+}
+
+sub halt {
+ $run = 0;
+}
+
+sub output {
+ my $val = pop @stack;
+ print "$val\n";
+}
+
+sub ipop {
+ shift;
+ my $arg = shift;
+ if( $arg =~ /^\$(.*)/ ) {
+ $$currentframe{$1} = pop @stack;
+ my $key = "$$currentframe{_func_}\:\:$1";
+ if( defined $watchpoints{$key} ) {
+ if( $watchpoints{$key} & 2 ) {
+ $suspend = "watch write $key";
+ }
+ }
+ } else {
+ pop @stack;
+ }
+}
+
+sub ipush {
+ shift;
+ my $arg = shift;
+ if( $arg =~ /^\$(.*)/ ) {
+ my $val = $$currentframe{$1};
+ push @stack, $val;
+ my $key = "$$currentframe{_func_}\:\:$1";
+ if( defined $watchpoints{$key} ) {
+ if( $watchpoints{$key} & 1 ) {
+ $suspend = "watch read $key";
+ }
+ }
+ } else {
+ push @stack, $arg;
+ }
+}
+
+sub ireturn {
+ $currentframe = pop @frames;
+}
+
+sub var {
+ shift;
+ my $name = shift;
+ $$currentframe{$name} = 0;
+}
+
+#####################################################################
+# #
+# D E B U G G E R I N T E R F A C E #
+# #
+#####################################################################
+
+sub check_for_breakpoint {
+ if( $debugflag ) {
+ my $pc = $$currentframe{_pc_};
+ if( $breakpoints[$pc] ) {
+ $suspend = "breakpoint $pc" unless $suspend eq "eval";
+ }
+ }
+}
+#
+# For each instruction, we check the debug co-routine for
+# control input. If there is input, we process it.
+#
+sub yield_to_debug {
+ if( $debugflag ) {
+ my $bytes_to_read = 1024;
+ my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read);
+ if( defined($bytes_read) ) {
+ #print "read $bytes_to_read\n";
+ my $rin = '';
+ my $win = '';
+ my $ein = '';
+ vec($rin,fileno($debugsock),1) = 1;
+ $ein = $rin | $win;
+ my $debugline = $debugbuf;
+ while( !($debugline =~ /\n/) ) {
+ select($rin, undef, undef, undef);
+ my $bytes_to_read = 1024;
+ my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read);
+ $debugline .= $debugbuf;
+ }
+ #print "read: $debugline";
+ process_debug_command($debugline);
+ $debugline = '';
+ } else {
+ # no bytes read
+ }
+ }
+}
+
+#
+# If the execution is suspended, then we go into the debug
+# ui loop, reading and processing instructions.
+#
+sub debug_ui {
+ return unless( $suspend );
+ my $pc = $$currentframe{_pc_};
+ if (!$started) {
+ send_debug_event( "suspended $suspend", 0 );
+ } else {
+ $started = 0;
+ }
+ $step = 0;
+ $stepreturn = 0;
+ my $rin = '';
+ my $win = '';
+ my $ein = '';
+ vec($rin,fileno($debugsock),1) = 1;
+ $ein = $rin | $win;
+ my $debugline = '';
+ while( $suspend ) {
+ select($rin, undef, undef, undef);
+ my $bytes_to_read = 1024;
+ my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read);
+ $debugline .= $debugbuf;
+ if( $debugline =~ /\n/ ) {
+ #print "read: $debugline";
+ process_debug_command($debugline);
+ $debugline = '';
+ }
+ }
+ send_debug_event( "resumed step", 0 ) if( $step );
+ send_debug_event( "resumed client", 0 ) unless( $step );
+}
+
+sub process_debug_command {
+ my $line = shift;
+ return if( length $line < 2 );
+ my @words = split /\s/, $line;
+ my $command = lc($words[0]);
+ my $dfunc = $debug_commands{$words[0]};
+ if( $dfunc ) {
+ &$dfunc( @words );
+ }
+}
+
+sub debug_clear_breakpoint {
+ shift;
+ my $line = shift;
+ $breakpoints[$line] = 0;
+ print $debugsock "ok\n";
+}
+my @saved_code;
+my %saved_labels;
+my $saved_pc;
+sub debug_eval {
+ shift;
+ my $code = shift;
+ my @lines = split /\|/, $code;
+ my $newpc = scalar @code;
+ @saved_code = @code;
+ %saved_labels = %labels;
+ foreach my $line ( @lines ) {
+ $line =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
+ push @code, $line;
+ }
+ push @code, "xyzzy";
+ map_labels();
+ $saved_pc = $$currentframe{_pc_};
+ $$currentframe{_pc_} = $newpc;
+ print $debugsock "ok\n";
+ $suspend = 0;
+}
+sub internal_end_eval {
+ my $result = pop @stack;
+ @code = @saved_code;
+ %labels = %saved_labels;
+ $$currentframe{_pc_} = $saved_pc;
+ send_debug_event( "evalresult $result", 0 );
+ $suspend = "eval";
+}
+
+sub debug_data {
+ my $result = '';
+ foreach my $d ( @stack ) {
+ $result .= $d . '|';
+ }
+ print $debugsock "$result\n";
+}
+sub debug_drop_frame {
+ ireturn();
+ decrement_pc();
+ print $debugsock "ok\n";
+ send_debug_event( "resumed drop", 0 );
+ send_debug_event( "suspended drop", 0 );
+}
+sub debug_event_stop {
+ shift;
+ my $event = shift;
+ my $bool = shift;
+ $eventstops{$event} = $bool;
+ print $debugsock "ok\n";
+}
+sub debug_exit {
+ print $debugsock "ok\n";
+ send_debug_event( "terminated", 0 );
+ exit 0;
+}
+sub debug_pop {
+ pop @stack;
+ print $debugsock "ok\n";
+}
+sub debug_push {
+ shift;
+ my $value = shift;
+ push @stack, $value;
+ print $debugsock "ok\n";
+}
+sub debug_resume {
+ $suspend = 0;
+ print $debugsock "ok\n";
+}
+sub debug_set_breakpoint {
+ shift;
+ my $line = shift;
+ $breakpoints[$line] = 1;
+ print $debugsock "ok\n";
+}
+sub debug_set_data {
+ shift;
+ my $offset = shift;
+ my $value = shift;
+ $stack[$offset] = $value;
+ print $debugsock "ok\n";
+}
+sub debug_set_variable {
+ shift;
+ my $sfnumber = shift;
+ my $var = shift;
+ my $value = shift;
+ if( $sfnumber > $#frames ) {
+ $$currentframe{$var} = $value;
+ } else {
+ my $theframe = $frames[$sfnumber];
+ $$theframe{$var} = $value;
+ }
+ print $debugsock "ok\n";
+}
+sub debug_stack {
+ my $result = '';
+ foreach my $frame ( @frames ) {
+ $result .= print_frame($frame);
+ $result .= '#';
+ }
+ $result .= print_frame($currentframe);
+ print $debugsock "$result\n";
+}
+sub debug_step {
+ # set suspend to 0 to allow the debug loop to exit back to
+ # the instruction loop and thus run an instruction. However,
+ # we want to come back to the debug loop right away, so the
+ # step flag is set to true which will cause the suspend flag
+ # to get set to true when we get to the next instruction.
+ $step = 1;
+ $suspend = 0;
+ print $debugsock "ok\n";
+}
+sub debug_step_return {
+ $stepreturn = 1;
+ $suspend = 0;
+ print $debugsock "ok\n";
+}
+sub debug_suspend {
+ $suspend = "client";
+ print $debugsock "ok\n";
+}
+sub debug_var {
+ shift;
+ my $sfnumber = shift;
+ my $var = shift;
+ if( $sfnumber > $#frames ) {
+ print $debugsock "$$currentframe{$var}\n";
+ } else {
+ my $theframe = $frames[$sfnumber];
+ print $debugsock "$$theframe{$var}\n";
+ }
+}
+sub debug_watch {
+ shift;
+ my $key = shift;
+ my $value = shift;
+ $watchpoints{$key} = $value;
+ print $debugsock "ok\n";
+}
+#
+# Some event has happened so notify the debugger.
+# If there is no debugger, we may still want to report the
+# event (such as if it is an error).
+#
+sub send_debug_event {
+ my $event = shift;
+ if( $debugflag ) {
+ print $debugsock2 "$event\n";
+ } else {
+ my $use_stderr = shift;
+ print "Error: $event\n" if $use_stderr;
+ }
+}
+#
+# The stack frame output is:
+# frame # frame # frame ...
+# where each frame is:
+# filename | line number | function name | var | var | var | var ...
+#
+sub print_frame {
+ my $frame = shift;
+ my $result = $filename;
+ $result .= '|' . $$frame{_pc_};
+ $result .= '|' . $$frame{_func_};
+ for my $var ( keys %$frame ) {
+ $result .= '|' . $var unless( substr($var,0,1) eq '_');
+ }
+ return $result;
+}
+
+sub start_debugger {
+ if( defined($debugflag) ) {
+ if( $debugflag eq "-debug" ) {
+ { # make STDOUT unbuffered
+ my $ofh = select STDOUT;
+ $| = 1;
+ select $ofh;
+ }
+ $debugflag = 1;
+ $debugport = shift @ARGV;
+ $debugport2 = shift @ARGV;
+ print "-debug $debugport $debugport2\n";
+
+ my $mainsock = new IO::Socket::INET (LocalHost => '127.0.0.1',
+ LocalPort => $debugport,
+ Listen => 1,
+ Proto => 'tcp',
+ Reuse => 1,
+ );
+ $debugsock = $mainsock->accept();
+ my $set_it = "1";
+ my $ioctl_val = 0x80000000 | (4 << 16) | (ord('f') << 8) | 126;
+ ioctl($debugsock, $ioctl_val, $set_it) or die "couldn't set nonblocking: $^E";
+
+ my $mainsock2 = new IO::Socket::INET (LocalHost => '127.0.0.1',
+ LocalPort => $debugport2,
+ Listen => 1,
+ Proto => 'tcp',
+ Reuse => 1,
+ );
+ $debugsock2 = $mainsock2->accept();
+
+ print "debug connection accepted\n";
+ } else {
+ $debugflag = 0;
+ }
+ }
+}
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtest2.pda b/org.eclipse.debug.examples.core/pdavm/tests/vmtest2.pda
new file mode 100644
index 000000000..95a35f04f
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtest2.pda
@@ -0,0 +1,48 @@
+push 6
+push 7
+push 8
+push 9
+push 10
+call sub1
+output
+call sub3
+call sub5
+push 3
+halt
+:sub2
+push 27
+return
+:sub1
+var m
+var n
+call sub2
+pop $n
+pop $m
+push $n
+push $m
+return
+# zero-based line 23
+:sub3
+push 1
+call sub4
+push 2
+call sub4
+push 3
+return
+:sub4
+push 4
+return
+# zero-based line 34
+:sub5
+var a
+var b
+var c
+pop $c
+pop $b
+call sub6
+push $a
+return
+:sub6
+var b
+pop $b
+return
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda b/org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda
new file mode 100644
index 000000000..a9fcfc2a8
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtest3.pda
@@ -0,0 +1,11 @@
+push 1
+push 2
+push 3
+foobar swish
+push 4
+add
+add
+call zippy
+add
+output
+halt
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtest6.pda b/org.eclipse.debug.examples.core/pdavm/tests/vmtest6.pda
new file mode 100644
index 000000000..d90a960cf
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtest6.pda
@@ -0,0 +1,31 @@
+var a
+var b
+push 1
+pop $a
+push 2
+pop $b
+push 3
+push 4
+#
+call inner
+#
+push $a
+push 2
+add
+pop $b
+output
+#
+halt
+#
+:inner
+var a
+var c
+pop $a
+pop $c
+push $a
+push $a
+add
+return
+:other
+push 15
+return \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtest8.pda b/org.eclipse.debug.examples.core/pdavm/tests/vmtest8.pda
new file mode 100644
index 000000000..7729409c2
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtest8.pda
@@ -0,0 +1,14 @@
+var a
+call inner
+push 1
+output
+halt
+:inner
+var b
+call inner2
+push 2
+return
+:inner2
+var c
+push 3
+return
diff --git a/org.eclipse.debug.examples.core/pdavm/tests/vmtests.pl b/org.eclipse.debug.examples.core/pdavm/tests/vmtests.pl
new file mode 100644
index 000000000..0e2f8a358
--- /dev/null
+++ b/org.eclipse.debug.examples.core/pdavm/tests/vmtests.pl
@@ -0,0 +1,448 @@
+#!perl.exe
+
+use strict;
+use warnings;
+use IO::Socket;
+
+#####################################################################
+# Copyright (c) 2004-2005 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:
+# Bjorn Freeman-Benson - initial API and implementation
+#####################################################################
+#
+# This test is designed to run on Windows:
+#
+# cd c:\eclipse\workspace\org.eclipse.debug.examples.core
+# perl pdavm\tests\vmtests.pl
+#
+# If the tests fail, they often indicate that by hanging in an
+# infinite loop. Additionally, the vm under test often becomes
+# a 100% CPU usage zombie. Use the task manager to kill them.
+#
+my $socket1;
+my $socket2;
+
+sub expect_output {
+ my $expect = shift;
+ my $line = <PROGRAM_OUTPUT>;
+ chomp($line);
+ return if( $line eq $expect );
+ die "expected output: $expect\nSaw output: $line";
+}
+sub expect_output_eof {
+ my $line = <PROGRAM_OUTPUT>;
+ return if( !defined $line );
+ die "expected: EOF on output";
+}
+sub send_command {
+ my $string = shift;
+ my $expect = shift;
+ $expect = "ok" if( !defined $expect );
+ #print STDERR "SEND: $string\n";
+ print $socket1 "$string\n";
+ my $result = <$socket1>;
+ chomp($result);
+ #print STDERR "RESULT: $result\n";
+ die "sent: $string\nexpected: $expect\nsaw: $result" if( !($result eq $expect) );
+}
+sub expect_event {
+ my $string = shift;
+ my $event = <$socket2>;
+ chomp($event);
+ #print STDERR "EVENT: $event\n";
+ die "expected event: $string\nsaw event: $event" if( !($string eq $event) );
+}
+sub setup_sockets {
+ #print STDERR "calling socket 12345\n";
+ $socket1 = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "localhost",
+ PeerPort => "12345",
+ Timeout => 10,
+ )
+ or die "cannot connect to debug socket 12345";
+ #print STDERR "calling socket 12346\n";
+ $socket2 = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "localhost",
+ PeerPort => "12346",
+ Timeout => 10,
+ )
+ or die "cannot connect to debug socket 12346";
+ #print STDERR "done calling sockets\n";
+}
+
+sub test2 {
+ print "test2 (common debug commands)..\n";
+
+ my $kidpid;
+ die "can't fork: $!" unless defined($kidpid = fork());
+ if( $kidpid ) {
+ #print STDERR "starting program\n";
+ open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest2.pda -debug 12345 12346 |";
+ #print STDERR "done starting program\n";
+ expect_output("-debug 12345 12346");
+ expect_output("debug connection accepted");
+ expect_output("10");
+ expect_output_eof();
+ exit 0;
+ } else {
+ setup_sockets();
+ expect_event("started");
+ # test step
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ # test breakpoint
+ send_command("set 4");
+ send_command("data", "6|");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("suspended breakpoint 4");
+ # test data stack
+ send_command("data", "6|7|8|9|");
+ send_command("popdata");
+ send_command("data", "6|7|8|");
+ send_command("pushdata 11");
+ send_command("data", "6|7|8|11|");
+ send_command("setdata 1 2");
+ send_command("data", "6|2|8|11|");
+ # test call stack
+ send_command("set 12");
+ send_command("set 19");
+ send_command("stepreturn");
+ expect_event("resumed client");
+ expect_event("suspended breakpoint 12");
+ send_command("clear 19");
+ send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|18|sub1|m|n#pdavm\\tests\\vmtest2.pda|12|sub2" );
+ send_command("stepreturn");
+ expect_event("resumed client");
+ expect_event("suspended step");
+ send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|18|sub1|m|n#pdavm\\tests\\vmtest2.pda|13|sub2" );
+ send_command("stepreturn");
+ expect_event("resumed client");
+ expect_event("suspended step");
+ send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|22|sub1|m|n" );
+ send_command("set 6");
+ send_command("stepreturn");
+ expect_event("resumed client");
+ expect_event("suspended breakpoint 6");
+ # test set and clear
+ send_command("set 27");
+ send_command("set 29");
+ send_command("set 33");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("suspended breakpoint 33");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("suspended breakpoint 27");
+ send_command("clear 33");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("suspended breakpoint 29");
+ # test var and setvar
+ send_command("set 47");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("suspended breakpoint 47");
+ send_command("var 1 b", "4");
+ send_command("var 2 b", "2");
+ send_command("var 1 a", "0");
+ send_command("setvar 1 a 99");
+ send_command("data", "6|2|8|11|27|1|4|");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("var 1 a", "99");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("data", "6|2|8|11|27|1|4|99|");
+ # test exit
+ send_command("exit");
+ expect_event("terminated");
+ }
+ #print STDERR "waiting for child\n";
+ wait();
+ #print STDERR "child joined\n";
+ close PROGRAM_OUTPUT;
+ print "test2..SUCCESS\n";
+}
+
+sub test3 {
+ print "test3 (uncaught events)..\n";
+
+ my $kidpid;
+ die "can't fork: $!" unless defined($kidpid = fork());
+ if( $kidpid ) {
+ #print STDERR "starting program\n";
+ open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |";
+ #print STDERR "done starting program\n";
+ expect_output("-debug 12345 12346");
+ expect_output("debug connection accepted");
+ expect_output("10");
+ expect_output_eof();
+ exit 0;
+ } else {
+ setup_sockets();
+ expect_event("started");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("unimplemented instruction foobar");
+ expect_event("no such label zippy");
+ expect_event("terminated");
+ }
+ #print STDERR "waiting for child\n";
+ wait();
+ #print STDERR "child joined\n";
+ close PROGRAM_OUTPUT;
+ print "test3..SUCCESS\n";
+}
+sub test4 {
+ print "test4 (caught events)..\n";
+
+ my $kidpid;
+ die "can't fork: $!" unless defined($kidpid = fork());
+ if( $kidpid ) {
+ #print STDERR "starting program\n";
+ open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |";
+ #print STDERR "done starting program\n";
+ expect_output("-debug 12345 12346");
+ expect_output("debug connection accepted");
+ expect_output("10");
+ expect_output_eof();
+ exit 0;
+ } else {
+ setup_sockets();
+ expect_event("started");
+ send_command("eventstop unimpinstr 1");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("unimplemented instruction foobar");
+ expect_event("suspended event unimpinstr");
+ send_command("eventstop unimpinstr 0");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("unimplemented instruction foobar");
+ expect_event("no such label zippy");
+ expect_event("terminated");
+ }
+ #print STDERR "waiting for child\n";
+ wait();
+ #print STDERR "child joined\n";
+ close PROGRAM_OUTPUT;
+ print "test4..SUCCESS\n";
+}
+sub test5 {
+ print "test5 (caught events)..\n";
+
+ my $kidpid;
+ die "can't fork: $!" unless defined($kidpid = fork());
+ if( $kidpid ) {
+ #print STDERR "starting program\n";
+ open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |";
+ #print STDERR "done starting program\n";
+ expect_output("-debug 12345 12346");
+ expect_output("debug connection accepted");
+ expect_output("10");
+ expect_output_eof();
+ exit 0;
+ } else {
+ setup_sockets();
+ expect_event("started");
+ send_command("eventstop nosuchlabel 1");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("unimplemented instruction foobar");
+ expect_event("no such label zippy");
+ expect_event("suspended event nosuchlabel");
+ send_command("eventstop nosuchlabel 0");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("no such label zippy");
+ expect_event("terminated");
+ }
+ #print STDERR "waiting for child\n";
+ wait();
+ #print STDERR "child joined\n";
+ close PROGRAM_OUTPUT;
+ print "test5..SUCCESS\n";
+}
+sub test6 {
+ print "test6 (watch points)..\n";
+
+ my $kidpid;
+ die "can't fork: $!" unless defined($kidpid = fork());
+ if( $kidpid ) {
+ #print STDERR "starting program\n";
+ open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest6.pda -debug 12345 12346 |";
+ #print STDERR "done starting program\n";
+ expect_output("-debug 12345 12346");
+ expect_output("debug connection accepted");
+ expect_output("8");
+ expect_output_eof();
+ exit 0;
+ } else {
+ setup_sockets();
+ expect_event("started");
+ send_command("watch inner::a 1");
+ send_command("watch main::a 2");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("suspended watch write main::a");
+ send_command("stack", "pdavm\\tests\\vmtest6.pda|4|main|a|b");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("suspended watch read inner::a");
+ send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|25|inner|a|c");
+ send_command("watch inner::a 0");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("terminated");
+ }
+ #print STDERR "waiting for child\n";
+ wait();
+ #print STDERR "child joined\n";
+ close PROGRAM_OUTPUT;
+ print "test6..SUCCESS\n";
+}
+sub test7 {
+ print "test7 (eval)..\n";
+
+ my $kidpid;
+ die "can't fork: $!" unless defined($kidpid = fork());
+ if( $kidpid ) {
+ #print STDERR "starting program\n";
+ open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest6.pda -debug 12345 12346 |";
+ #print STDERR "done starting program\n";
+ expect_output("-debug 12345 12346");
+ expect_output("debug connection accepted");
+ expect_output("8");
+ expect_output_eof();
+ exit 0;
+ } else {
+ setup_sockets();
+ expect_event("started");
+ send_command("set 25");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("suspended breakpoint 25");
+ #
+ send_command("eval push%204|push%205|add");
+ expect_event("resumed client");
+ expect_event("evalresult 9");
+ expect_event("suspended eval");
+ #
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|26|inner|a|c");
+ send_command("data", "4|4|");
+ send_command("eval call%20other");
+ expect_event("resumed client");
+ expect_event("evalresult 15");
+ expect_event("suspended eval");
+ send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|26|inner|a|c");
+ send_command("data", "4|4|");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("terminated");
+ }
+ #print STDERR "waiting for child\n";
+ wait();
+ #print STDERR "child joined\n";
+ close PROGRAM_OUTPUT;
+ print "test7..SUCCESS\n";
+}
+sub test1 {
+ print "test1 (normal run mode)..\n";
+ open PROGRAM_OUTPUT, "perl pdavm\\pda.pl examples\\example.pda |" or die $!;
+ expect_output("\"hello\"");
+ expect_output("\"barfoo\"");
+ expect_output("\"first\"");
+ expect_output("\"second\"");
+ expect_output("12");
+ expect_output("11");
+ expect_output("10");
+ expect_output("\"barfoo\"");
+ expect_output("\"first\"");
+ expect_output("\"second\"");
+ expect_output("\"end\"");
+ expect_output_eof();
+ print "test1..SUCCESS\n";
+}
+sub test8 {
+ print "test8 (drop to frame)..\n";
+
+ my $kidpid;
+ die "can't fork: $!" unless defined($kidpid = fork());
+ if( $kidpid ) {
+ #print STDERR "starting program\n";
+ open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest8.pda -debug 12345 12346 |";
+ #print STDERR "done starting program\n";
+ expect_output("-debug 12345 12346");
+ expect_output("debug connection accepted");
+ expect_output("1");
+ expect_output_eof();
+ exit 0;
+ } else {
+ setup_sockets();
+ expect_event("started");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|8|inner|b#pdavm\\tests\\vmtest8.pda|12|inner2|c");
+ send_command("drop");
+ expect_event("suspended drop");
+ send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|7|inner|b");
+ send_command("step");
+ expect_event("resumed step");
+ expect_event("suspended step");
+ send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|8|inner|b#pdavm\\tests\\vmtest8.pda|10|inner2");
+ send_command("resume");
+ expect_event("resumed client");
+ expect_event("terminated");
+ }
+ #print STDERR "waiting for child\n";
+ wait();
+ #print STDERR "child joined\n";
+ close PROGRAM_OUTPUT;
+ print "test8..SUCCESS\n";
+}
+
+#
+# Run the tests
+#
+test1();
+test2();
+test3();
+test4();
+test5();
+test6();
+test7();
+test8();
+print "All tests complete\n"; \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/plugin.xml b/org.eclipse.debug.examples.core/plugin.xml
new file mode 100644
index 000000000..0133be329
--- /dev/null
+++ b/org.eclipse.debug.examples.core/plugin.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+ <extension
+ point="org.eclipse.core.variables.valueVariables">
+ <variable
+ description="Path to Perl executable in the local file system"
+ name="perlExecutable"
+ initialValue="c:\perl\bin\perl.exe"/>
+ </extension>
+<!--#ifdef ex1-->
+<!--#else-->
+ <extension
+ point="org.eclipse.debug.core.launchConfigurationTypes">
+ <launchConfigurationType
+ sourceLocatorId="pda.sourceLocator"
+ delegate="org.eclipse.debug.examples.core.pda.launcher.PDALaunchDelegate"
+ sourcePathComputerId="pda.sourcePathComputer"
+ name="PDA Application"
+ id="pda.launchType"
+ modes="run, debug"/>
+ </extension>
+<!--#endif-->
+
+<!--#ifdef ex4-->
+<!--#else-->
+ <extension
+ point="org.eclipse.debug.core.sourceLocators">
+ <sourceLocator
+ class="org.eclipse.debug.examples.core.pda.sourcelookup.PDASourceLookupDirector"
+ name="PDA Source Locator"
+ id="pda.sourceLocator"/>
+ </extension>
+ <extension
+ point="org.eclipse.debug.core.sourcePathComputers">
+ <sourcePathComputer
+ class="org.eclipse.debug.examples.core.pda.sourcelookup.PDASourcePathComputerDelegate"
+ id="pda.sourcePathComputer"/>
+ </extension>
+<!--#endif-->
+
+<!--#ifdef ex3-->
+<!--#else-->
+ <extension
+ point="org.eclipse.debug.core.breakpoints">
+ <breakpoint
+ class="org.eclipse.debug.examples.core.pda.breakpoints.PDALineBreakpoint"
+ name="PDA Line Breakpoints"
+ markerType="org.eclipse.debug.examples.core.pda.markerType.lineBreakpoint"
+ id="pda.lineBreakpoint"/>
+ <breakpoint
+ class="org.eclipse.debug.examples.core.pda.breakpoints.PDAWatchpoint"
+ name="PDA Watchpoints"
+ markerType="org.eclipse.debug.examples.core.pda.markerType.watchpoint"
+ id="pda.watchpoint"/>
+ </extension>
+ <extension
+ id="pda.markerType.lineBreakpoint"
+ name="PDA Line Breakpoint Marker"
+ point="org.eclipse.core.resources.markers">
+ <super type="org.eclipse.debug.core.lineBreakpointMarker"/>
+ <persistent value="true"/>
+ </extension>
+ <extension
+ id="pda.markerType.watchpoint"
+ name="PDA Watchpoint Marker"
+ point="org.eclipse.core.resources.markers">
+ <super type="org.eclipse.debug.examples.core.pda.markerType.lineBreakpoint"/>
+ <persistent value="true"/>
+ </extension>
+<!--#endif-->
+
+<!--#ifdef ex6-->
+<!--#else-->
+ <extension
+ point="org.eclipse.debug.core.logicalStructureTypes">
+ <logicalStructureType
+ class="org.eclipse.debug.examples.core.pda.model.WordStructureDelegate"
+ description="Words"
+ id="pda.wordStructure"
+ modelIdentifier="pda.debugModel"/>
+ </extension>
+<!--#endif-->
+</plugin>
diff --git a/org.eclipse.debug.examples.core/samples/counter.pda b/org.eclipse.debug.examples.core/samples/counter.pda
new file mode 100644
index 000000000..9b2b73100
--- /dev/null
+++ b/org.eclipse.debug.examples.core/samples/counter.pda
@@ -0,0 +1,11 @@
+push 0
+:main
+var n
+pop $n
+push $n
+push 1
+add
+dup
+push $n
+output
+branch_not_zero main \ No newline at end of file
diff --git a/org.eclipse.debug.examples.core/samples/drop.pda b/org.eclipse.debug.examples.core/samples/drop.pda
new file mode 100644
index 000000000..84f60fee0
--- /dev/null
+++ b/org.eclipse.debug.examples.core/samples/drop.pda
@@ -0,0 +1,12 @@
+call one
+:one
+call two
+:two
+call three
+:three
+call four
+:four
+push DONE
+output
+
+
diff --git a/org.eclipse.debug.examples.core/samples/example.pda b/org.eclipse.debug.examples.core/samples/example.pda
new file mode 100644
index 000000000..a95886358
--- /dev/null
+++ b/org.eclipse.debug.examples.core/samples/example.pda
@@ -0,0 +1,35 @@
+push "hello"
+output
+call foobar
+push 3
+:label
+dup
+push 4
+push 5
+add
+add
+output
+dec
+dup
+branch_not_zero label
+call foobar
+push "end"
+output
+halt
+:foobar
+var a
+var b
+call barfoo
+push "first"
+push "second"
+pop $a
+pop $b
+push $a
+push $b
+output
+output
+return
+:barfoo
+push "barfoo"
+output
+return
diff --git a/org.eclipse.debug.examples.core/samples/fibonacci.pda b/org.eclipse.debug.examples.core/samples/fibonacci.pda
new file mode 100644
index 000000000..e39595a98
--- /dev/null
+++ b/org.eclipse.debug.examples.core/samples/fibonacci.pda
@@ -0,0 +1,32 @@
+push 6
+call fibonacci
+output
+halt
+#
+# f(n) = f(n-1) + f(n-2)
+# f(0) = 1
+# f(1) = 1
+#
+:fibonacci
+var n
+pop $n
+push $n
+branch_not_zero gt0
+push 1
+return
+:gt0
+push $n
+dec
+branch_not_zero gt1
+push 1
+return
+:gt1
+push $n
+dec
+call fibonacci
+push $n
+dec
+dec
+call fibonacci
+add
+return
diff --git a/org.eclipse.debug.examples.core/samples/structures.pda b/org.eclipse.debug.examples.core/samples/structures.pda
new file mode 100644
index 000000000..97858b079
--- /dev/null
+++ b/org.eclipse.debug.examples.core/samples/structures.pda
@@ -0,0 +1,8 @@
+push one two three
+push 1 2 3
+var x
+var y
+pop $x
+pop $y
+push Done
+output \ No newline at end of file
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};
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/.classpath b/org.eclipse.debug.examples.ui/.classpath
new file mode 100644
index 000000000..b7464f3ca
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.debug.examples.ui/.cvsignore b/org.eclipse.debug.examples.ui/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/org.eclipse.debug.examples.ui/.project b/org.eclipse.debug.examples.ui/.project
new file mode 100644
index 000000000..6b2c66f6d
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>example.debug.ui</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.debug.examples.ui/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.debug.examples.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..14a594160
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,37 @@
+#Mon Jan 24 20:23:44 CST 2005
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
diff --git a/org.eclipse.debug.examples.ui/META-INF/MANIFEST.MF b/org.eclipse.debug.examples.ui/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..0b61b2dbd
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Example Debug UI Plug-in
+Bundle-SymbolicName: org.eclipse.debug.examples.ui;singleton:=true
+Bundle-Version: 1.0.0
+Bundle-Activator: org.eclipse.debug.examples.ui.pda.DebugUIPlugin
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.debug.core,
+ org.eclipse.ui,
+ org.eclipse.debug.ui,
+ org.eclipse.jface.text,
+ org.eclipse.ui.editors,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.ui.ide,
+ org.eclipse.debug.examples.core
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.debug.examples.ui.pda,
+ org.eclipse.debug.examples.ui.pda.adapters,
+ org.eclipse.debug.examples.ui.pda.breakpoints,
+ org.eclipse.debug.examples.ui.pda.editor,
+ org.eclipse.debug.examples.ui.pda.launcher,
+ org.eclipse.debug.examples.ui.pda.presentation,
+ org.eclipse.debug.examples.ui.pda.views
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
diff --git a/org.eclipse.debug.examples.ui/about.html b/org.eclipse.debug.examples.ui/about.html
new file mode 100644
index 000000000..460233046
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 2, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/org.eclipse.debug.examples.ui/build.properties b/org.eclipse.debug.examples.ui/build.properties
new file mode 100644
index 000000000..3b3d36c80
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/build.properties
@@ -0,0 +1,8 @@
+source.. = src/
+output.. = bin/
+bin.includes = plugin.xml,\
+ bin/,\
+ about.html,\
+ META-INF/,\
+ .
+src.includes = src/
diff --git a/org.eclipse.debug.examples.ui/icons/full/dlcl16/pop.gif b/org.eclipse.debug.examples.ui/icons/full/dlcl16/pop.gif
new file mode 100644
index 000000000..559e46298
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/icons/full/dlcl16/pop.gif
Binary files differ
diff --git a/org.eclipse.debug.examples.ui/icons/full/dlcl16/push.gif b/org.eclipse.debug.examples.ui/icons/full/dlcl16/push.gif
new file mode 100644
index 000000000..f7e6cc089
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/icons/full/dlcl16/push.gif
Binary files differ
diff --git a/org.eclipse.debug.examples.ui/icons/full/elcl16/pop.gif b/org.eclipse.debug.examples.ui/icons/full/elcl16/pop.gif
new file mode 100644
index 000000000..2cd9c5444
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/icons/full/elcl16/pop.gif
Binary files differ
diff --git a/org.eclipse.debug.examples.ui/icons/full/elcl16/push.gif b/org.eclipse.debug.examples.ui/icons/full/elcl16/push.gif
new file mode 100644
index 000000000..a5ac28d4c
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/icons/full/elcl16/push.gif
Binary files differ
diff --git a/org.eclipse.debug.examples.ui/icons/full/obj16/pda.gif b/org.eclipse.debug.examples.ui/icons/full/obj16/pda.gif
new file mode 100644
index 000000000..04c5052b2
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/icons/full/obj16/pda.gif
Binary files differ
diff --git a/org.eclipse.debug.examples.ui/plugin.xml b/org.eclipse.debug.examples.ui/plugin.xml
new file mode 100644
index 000000000..3cc918c18
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/plugin.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+<plugin>
+<!--#ifdef ex1 -->
+<!--#else -->
+ <extension
+ point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+ <launchConfigurationTabGroup
+ class="org.eclipse.debug.examples.ui.pda.launcher.PDATabGroup"
+ description="Specify and launch a PDA program"
+ id="pda.tabGroup"
+ type="pda.launchType"/>
+ </extension>
+ <extension
+ point="org.eclipse.debug.ui.launchConfigurationTypeImages">
+ <launchConfigurationTypeImage
+ icon="icons/full/obj16/pda.gif"
+ configTypeID="pda.launchType"
+ id="pda.typeImage"/>
+ </extension>
+ <extension
+ point="org.eclipse.debug.ui.launchShortcuts">
+ <shortcut
+ label="PDA Application"
+ icon="icons/full/obj16/pda.gif"
+ class="org.eclipse.debug.examples.ui.pda.launcher.PDALaunchShortcut"
+ modes="run, debug"
+ id="pda.launchShortcut">
+ <contextualLaunch>
+ <enablement>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <instanceof value="org.eclipse.core.resources.IFile"/>
+ <test
+ value="*.pda"
+ property="org.eclipse.debug.ui.matchesPattern"/>
+ </iterate>
+ </with>
+ </enablement>
+ </contextualLaunch>
+ </shortcut>
+ </extension>
+<!--#endif -->
+ <extension
+ point="org.eclipse.debug.ui.debugModelPresentations">
+ <debugModelPresentation
+ class="org.eclipse.debug.examples.ui.pda.presentation.PDAModelPresentation"
+ id="pda.debugModel"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editors">
+ <editor
+ filenames="*.pda"
+ class="org.eclipse.debug.examples.ui.pda.editor.PDAEditor"
+ icon="icons/full/obj16/pda.gif"
+ default="true"
+ name="PDA Editor"
+ id="pda.editor"
+ extensions="pda"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.editorActions">
+ <editorContribution
+ targetID="pda.editor"
+ id="pda.rulerActions">
+ <action
+ label="Not Used"
+ class="org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate"
+ style="push"
+ actionID="RulerDoubleClick"
+ id="pda.doubleClickBreakpointAction"/>
+ </editorContribution>
+ </extension>
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ icon="icons/full/obj16/pda.gif"
+ class="org.eclipse.debug.examples.ui.pda.views.DataStackView"
+ name="PDA Data Stack"
+ id="pda.dataStackView"/>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.perspectiveExtensions">
+ <perspectiveExtension targetID="org.eclipse.debug.ui.DebugPerspective">
+ <view
+ visible="false"
+ relative="org.eclipse.debug.ui.VariableView"
+ relationship="stack"
+ id="pda.dataStackView"/>
+ </perspectiveExtension>
+ </extension>
+ <extension
+ point="org.eclipse.ui.contexts">
+ <context
+ parentId="org.eclipse.debug.ui.debugging"
+ description="Debugging PDA Programs"
+ name="Debugging PDA Programs"
+ id="pda.debugging"/>
+ </extension>
+ <extension
+ point="org.eclipse.debug.ui.debugModelContextBindings">
+ <modelContextBinding
+ contextId="pda.debugging"
+ debugModelId="pda.debugModel"/>
+ </extension>
+ <extension
+ point="org.eclipse.debug.ui.contextViewBindings">
+ <contextViewBinding
+ contextId="pda.debugging"
+ viewId="pda.dataStackView"/>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.popupMenus">
+ <viewerContribution
+ targetID="pda.editor.rulerMenu"
+ id="pda.editor.rulerActions">
+ <action
+ label="Toggle Breakpoint"
+ class="org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate"
+ menubarPath="debug"
+ id="pda.editor.ruler.toggleBreakpointAction"/>
+ </viewerContribution>
+ <viewerContribution
+ targetID="pda.editor.contextMenu"
+ id="pda.editor.menuActions">
+ <action
+ label="Run to Line"
+ definitionId="org.eclipse.debug.ui.commands.RunToLine"
+ class="org.eclipse.debug.ui.actions.RunToLineActionDelegate"
+ menubarPath="additions"
+ id="pda.editor.context.runToLineAction"/>
+ </viewerContribution>
+<!--#ifdef ex5 -->
+<!--#else -->
+ <objectContribution
+ adaptable="false"
+ id="pda.dropToFrame"
+ objectClass="org.eclipse.debug.examples.core.pda.model.PDAStackFrame">
+ <action
+ class="org.eclipse.debug.examples.ui.pda.editor.PopFrameActionDelegate"
+ id="pda.dropToFrame"
+ label="Pop Frame"/>
+ </objectContribution>
+<!--#endif -->
+ </extension>
+
+ <extension
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ class="org.eclipse.debug.examples.ui.pda.breakpoints.PDAEditorAdapterFactory"
+ adaptableType="org.eclipse.debug.examples.ui.pda.editor.PDAEditor">
+ <adapter type="org.eclipse.debug.ui.actions.IToggleBreakpointsTarget"/>
+<!--#ifdef ex7 -->
+<!--#else -->
+ <adapter type="org.eclipse.debug.ui.actions.IRunToLineTarget"/>
+<!--#endif -->
+ </factory>
+<!-- FLEXIBLE HIERARCHY EXAMPLE
+ <factory
+ adaptableType="org.eclipse.debug.examples.core.pda.model.PDADebugTarget"
+ class="example.debug.ui.adapters.AdapterFactory">
+ <adapter
+ type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider">
+ </adapter>
+ <adapter
+ type="org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory">
+ </adapter>
+ </factory>
+-->
+ </extension>
+</plugin>
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/DebugUIPlugin.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/DebugUIPlugin.java
new file mode 100644
index 000000000..ba635acb7
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/DebugUIPlugin.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * 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.ui.pda;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.Map.Entry;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.internal.util.BundleUtility;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class DebugUIPlugin extends AbstractUIPlugin {
+ //The shared instance.
+ private static DebugUIPlugin plugin;
+ //Resource bundle.
+ private ResourceBundle resourceBundle;
+
+ private final static String ICONS_PATH = "icons/full/";//$NON-NLS-1$
+ private final static String PATH_OBJECT = ICONS_PATH + "obj16/"; //Model object icons //$NON-NLS-1$
+ private final static String PATH_ELOCALTOOL = ICONS_PATH + "elcl16/"; //Enabled local toolbar icons //$NON-NLS-1$
+ private final static String PATH_DLOCALTOOL = ICONS_PATH + "dlcl16/"; //Disabled local toolbar icons //$NON-NLS-1$
+
+ /**
+ * Toolbar action to pop data stack
+ */
+ public final static String IMG_ELCL_POP = "IMG_ELCL_POP";
+ public final static String IMG_DLCL_POP = "IMG_DLCL_POP";
+
+ /**
+ * Toolbar action to push onto data stack
+ */
+ public final static String IMG_ELCL_PUSH = "IMG_ELCL_PUSH";
+ public final static String IMG_DLCL_PUSH = "IMG_DLCL_PUSH";
+
+ /**
+ * PDA program image
+ */
+ public final static String IMG_OBJ_PDA = "IMB_OBJ_PDA";
+
+ /**
+ * Keyword color
+ */
+ public final static RGB KEYWORD = new RGB(0,0,255);
+ public final static RGB LABEL = new RGB(128, 128, 0);
+
+ /**
+ * Managed colors
+ */
+ private Map fColors = new HashMap();
+
+ /**
+ * The constructor.
+ */
+ public DebugUIPlugin() {
+ super();
+ plugin = this;
+ }
+
+ /**
+ * This method is called upon plug-in activation
+ */
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+// Toggles single threaded adapter example
+// IAdapterManager adapterManager = Platform.getAdapterManager();
+// IAdapterFactory factory = new AdapterFactory();
+// adapterManager.registerAdapters(factory, PDADebugTarget.class);
+ }
+
+ /**
+ * This method is called when the plug-in is stopped
+ */
+ public void stop(BundleContext context) throws Exception {
+ super.stop(context);
+ plugin = null;
+ resourceBundle = null;
+ Iterator colors = fColors.entrySet().iterator();
+ while (colors.hasNext()) {
+ Map.Entry entry = (Entry) colors.next();
+ ((Color)entry.getValue()).dispose();
+ }
+ }
+
+ /**
+ * Returns the shared instance.
+ */
+ public static DebugUIPlugin 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 = DebugUIPlugin.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.ui.pda.DebugUIPluginResources");
+ } catch (MissingResourceException x) {
+ resourceBundle = null;
+ }
+ return resourceBundle;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#initializeImageRegistry(org.eclipse.jface.resource.ImageRegistry)
+ */
+ protected void initializeImageRegistry(ImageRegistry reg) {
+ declareImage(IMG_OBJ_PDA, PATH_OBJECT + "pda.gif");
+ declareImage(IMG_ELCL_POP, PATH_ELOCALTOOL + "pop.gif");
+ declareImage(IMG_DLCL_POP, PATH_DLOCALTOOL + "pop.gif");
+ declareImage(IMG_ELCL_PUSH, PATH_ELOCALTOOL + "push.gif");
+ declareImage(IMG_DLCL_PUSH, PATH_DLOCALTOOL + "push.gif");
+ }
+
+ /**
+ * Declares a workbench image given the path of the image file (relative to
+ * the workbench plug-in). This is a helper method that creates the image
+ * descriptor and passes it to the main <code>declareImage</code> method.
+ *
+ * @param symbolicName the symbolic name of the image
+ * @param path the path of the image file relative to the base of the workbench
+ * plug-ins install directory
+ * <code>false</code> if this is not a shared image
+ */
+ private void declareImage(String key, String path) {
+ URL url = BundleUtility.find("org.eclipse.debug.examples.ui.pda", path);
+ ImageDescriptor desc = ImageDescriptor.createFromURL(url);
+ getImageRegistry().put(key, desc);
+ }
+
+ /**
+ * Returns the color described by the given RGB.
+ *
+ * @param rgb
+ * @return color
+ */
+ public Color getColor(RGB rgb) {
+ Color color = (Color) fColors.get(rgb);
+ if (color == null) {
+ color= new Color(Display.getCurrent(), rgb);
+ fColors.put(rgb, color);
+ }
+ return color;
+ }
+
+ }
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/AdapterFactory.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/AdapterFactory.java
new file mode 100644
index 000000000..3e4153fd5
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/AdapterFactory.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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.ui.pda.adapters;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
+
+
+/**
+ *
+ * @since 3.2
+ *
+ */
+public class AdapterFactory implements IAdapterFactory {
+
+ private static IElementContentProvider fgTargetAdapter = new PDADebugTargetContentProvider();
+ private static IModelProxyFactory fgFactory = new ModelProxyFactory();
+
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (IElementContentProvider.class.equals(adapterType)) {
+ if (adaptableObject instanceof PDADebugTarget) {
+ return fgTargetAdapter;
+ }
+ }
+ if (IModelProxyFactory.class.equals(adapterType)) {
+ if (adaptableObject instanceof PDADebugTarget) {
+ return fgFactory;
+ }
+ }
+ return null;
+ }
+
+ public Class[] getAdapterList() {
+ return new Class[]{IElementContentProvider.class, IModelProxyFactory.class};
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/ModelProxyFactory.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/ModelProxyFactory.java
new file mode 100644
index 000000000..a8e5959f1
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/ModelProxyFactory.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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
+ *******************************************************************************/
+package org.eclipse.debug.examples.ui.pda.adapters;
+
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.debug.ui.IDebugUIConstants;
+
+
+public class ModelProxyFactory implements IModelProxyFactory {
+
+ public IModelProxy createModelProxy(Object element, IPresentationContext context) {
+ if (IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId())) {
+ if (element instanceof PDADebugTarget){
+ return new PDADebugTargetProxy((IDebugTarget) element);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.java
new file mode 100644
index 000000000..ab33ae4f2
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetContentProvider.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
+ *******************************************************************************/
+
+package org.eclipse.debug.examples.ui.pda.adapters;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
+import org.eclipse.debug.internal.ui.model.elements.ElementContentProvider;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
+import org.eclipse.debug.ui.IDebugUIConstants;
+
+
+public class PDADebugTargetContentProvider extends ElementContentProvider {
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
+ */
+ protected int getChildCount(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
+ PDAThread thread = ((PDADebugTarget) element).getThread();
+ if (thread != null) {
+ if (thread.hasStackFrames()) {
+ return thread.getStackFrames().length;
+ }
+ }
+ return 0;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#hasChildren(java.lang.Object, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
+ */
+ protected boolean hasChildren(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
+ PDAThread thread = ((PDADebugTarget) element).getThread();
+ if (thread != null) {
+ return thread.hasStackFrames();
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
+ */
+ protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
+ if (context.getId().equals(IDebugUIConstants.ID_DEBUG_VIEW)) {
+ PDAThread thread = ((PDADebugTarget) parent).getThread();
+ if (thread != null) {
+ return getElements(thread.getStackFrames(), index, length);
+ }
+ }
+ return EMPTY;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#supportsContextId(java.lang.String)
+ */
+ protected boolean supportsContextId(String id) {
+ return IDebugUIConstants.ID_DEBUG_VIEW.equals(id);
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetProxy.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetProxy.java
new file mode 100644
index 000000000..e905e12fe
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDADebugTargetProxy.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 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
+ *******************************************************************************/
+package org.eclipse.debug.examples.ui.pda.adapters;
+
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.internal.ui.viewers.update.DebugEventHandler;
+import org.eclipse.debug.internal.ui.viewers.update.DebugTargetEventHandler;
+import org.eclipse.debug.internal.ui.viewers.update.DebugTargetProxy;
+
+/**
+ * @since 3.2
+ *
+ */
+public class PDADebugTargetProxy extends DebugTargetProxy {
+
+ /**
+ * @param target
+ */
+ public PDADebugTargetProxy(IDebugTarget target) {
+ super(target);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.internal.ui.viewers.update.DebugTargetProxy#createEventHandlers()
+ */
+ protected DebugEventHandler[] createEventHandlers() {
+ return new DebugEventHandler[] { new DebugTargetEventHandler(this), new PDAThreadEventHandler(this) };
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAThreadEventHandler.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAThreadEventHandler.java
new file mode 100644
index 000000000..2af58c7e6
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/adapters/PDAThreadEventHandler.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+package org.eclipse.debug.examples.ui.pda.adapters;
+
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
+import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy;
+import org.eclipse.debug.internal.ui.viewers.update.DebugEventHandler;
+
+
+/**
+ * @since 3.2
+ */
+public class PDAThreadEventHandler extends DebugEventHandler {
+
+ private IStackFrame fPrev = null;
+
+ /**
+ * Constructs and event handler for a threads in the given viewer.
+ *
+ * @param viewer
+ */
+ public PDAThreadEventHandler(AbstractModelProxy proxy) {
+ super(proxy);
+ }
+
+ protected void handleSuspend(DebugEvent event) {
+ IThread thread = (IThread) event.getSource();
+ int extras = IModelDelta.STATE;
+ if (event.getDetail() == DebugEvent.BREAKPOINT | event.getDetail() == DebugEvent.CLIENT_REQUEST) {
+ extras = IModelDelta.EXPAND;
+ }
+ fireDeltaUpdatingTopFrame(thread, IModelDelta.NO_CHANGE | extras);
+ }
+
+ private boolean isEqual(Object o1, Object o2) {
+ if (o1 == o2) {
+ return true;
+ }
+ if (o1 == null) {
+ return false;
+ }
+ return o1.equals(o2);
+ }
+
+ protected void handleResume(DebugEvent event) {
+ IThread thread = (IThread) event.getSource();
+ fireDeltaAndClearTopFrame(thread, IModelDelta.STATE | IModelDelta.CONTENT);
+ }
+
+ protected void handleCreate(DebugEvent event) {
+ fireDeltaAndClearTopFrame((IThread) event.getSource(), IModelDelta.ADDED);
+ }
+
+ protected void handleTerminate(DebugEvent event) {
+ fireDeltaAndClearTopFrame((IThread) event.getSource(), IModelDelta.REMOVED);
+ }
+
+ protected void handleChange(DebugEvent event) {
+ fireDeltaUpdatingTopFrame((IThread) event.getSource(), IModelDelta.STATE);
+ }
+
+ protected void handleLateSuspend(DebugEvent suspend, DebugEvent resume) {
+ IThread thread = (IThread) suspend.getSource();
+ fireDeltaUpdatingTopFrame(thread, IModelDelta.CONTENT | IModelDelta.EXPAND);
+ }
+
+ protected void handleSuspendTimeout(DebugEvent event) {
+ IThread thread = (IThread) event.getSource();
+ fireDeltaAndClearTopFrame(thread, IModelDelta.CONTENT);
+ }
+
+ private ModelDelta buildRootDelta() {
+ return new ModelDelta(getLaunchManager(), IModelDelta.NO_CHANGE);
+ }
+
+ private ILaunchManager getLaunchManager() {
+ return DebugPlugin.getDefault().getLaunchManager();
+ }
+
+ protected ModelDelta addTarget(ModelDelta delta, IThread thread) {
+ ILaunch launch = thread.getLaunch();
+ Object[] children = launch.getChildren();
+ delta = delta.addNode(launch, indexOf(getLaunchManager().getLaunches(), launch), IModelDelta.NO_CHANGE, children.length);
+ IDebugTarget debugTarget = thread.getDebugTarget();
+ int numFrames = -1;
+ try {
+ numFrames = thread.getStackFrames().length;
+ } catch (DebugException e) {
+ }
+ return delta.addNode(debugTarget, indexOf(children, debugTarget), IModelDelta.NO_CHANGE, numFrames);
+ }
+
+ private void fireDeltaAndClearTopFrame(IThread thread, int flags) {
+ ModelDelta delta = buildRootDelta();
+ ModelDelta node = addTarget(delta, thread);
+ synchronized (this) {
+ fPrev = null;
+ }
+ fireDelta(delta);
+ }
+
+ private void fireDeltaUpdatingTopFrame(IThread thread, int flags) {
+ ModelDelta delta = buildRootDelta();
+ ModelDelta node = addTarget(delta, thread);
+ synchronized (this) {
+ IStackFrame prev = fPrev;
+ IStackFrame frame = null;
+ try {
+ frame = thread.getTopStackFrame();
+ } catch (DebugException e) {
+ }
+ if (isEqual(frame, prev)) {
+ node.setFlags(flags);
+ } else {
+ node.setFlags(flags | IModelDelta.CONTENT);
+ }
+ if (frame != null) {
+ node.addNode(frame, 0, IModelDelta.STATE | IModelDelta.SELECT, 0);
+ }
+ fPrev = frame;
+ }
+ fireDelta(delta);
+ }
+
+ protected boolean handlesEvent(DebugEvent event) {
+ return event.getSource() instanceof PDAThread;
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDABreakpointAdapter.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDABreakpointAdapter.java
new file mode 100644
index 000000000..38e8f8525
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDABreakpointAdapter.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * 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.ui.pda.breakpoints;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+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.PDAWatchpoint;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+
+/**
+ * Adapter to create breakpoints in PDA files.
+ */
+public class PDABreakpointAdapter implements IToggleBreakpointsTargetExtension {
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ ITextEditor textEditor = getEditor(part);
+ if (textEditor != null) {
+ IResource resource = (IResource) textEditor.getEditorInput().getAdapter(IResource.class);
+ ITextSelection textSelection = (ITextSelection) selection;
+ int lineNumber = textSelection.getStartLine();
+ IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(DebugCorePlugin.ID_PDA_DEBUG_MODEL);
+ for (int i = 0; i < breakpoints.length; i++) {
+ IBreakpoint breakpoint = breakpoints[i];
+ if (breakpoint instanceof ILineBreakpoint && resource.equals(breakpoint.getMarker().getResource())) {
+ if (((ILineBreakpoint)breakpoint).getLineNumber() == (lineNumber + 1)) {
+ // remove
+ breakpoint.delete();
+ return;
+ }
+ }
+ }
+ // create line breakpoint (doc line numbers start at 0)
+ PDALineBreakpoint lineBreakpoint = new PDALineBreakpoint(resource, lineNumber + 1);
+ DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(lineBreakpoint);
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleLineBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return getEditor(part) != null;
+ }
+
+ /**
+ * Returns the editor being used to edit a PDA file, associated with the
+ * given part, or <code>null</code> if none.
+ *
+ * @param part workbench part
+ * @return the editor being used to edit a PDA file, associated with the
+ * given part, or <code>null</code> if none
+ */
+ private ITextEditor getEditor(IWorkbenchPart part) {
+ if (part instanceof ITextEditor) {
+ ITextEditor editorPart = (ITextEditor) part;
+ IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class);
+ if (resource != null) {
+ String extension = resource.getFileExtension();
+ if (extension != null && extension.equals("pda")) {
+ return editorPart;
+ }
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleMethodBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return false;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#toggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ String[] variableAndFunctionName = getVariableAndFunctionName(part, selection);
+ if (variableAndFunctionName != null && part instanceof ITextEditor && selection instanceof ITextSelection) {
+ ITextEditor editorPart = (ITextEditor)part;
+ int lineNumber = ((ITextSelection)selection).getStartLine();
+ IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class);
+ String var = variableAndFunctionName[0];
+ String fcn = variableAndFunctionName[1];
+ // look for existing watchpoint to delete
+ IBreakpoint[] breakpoints = DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(DebugCorePlugin.ID_PDA_DEBUG_MODEL);
+ for (int i = 0; i < breakpoints.length; i++) {
+ IBreakpoint breakpoint = breakpoints[i];
+ if (breakpoint instanceof PDAWatchpoint && resource.equals(breakpoint.getMarker().getResource())) {
+ PDAWatchpoint watchpoint = (PDAWatchpoint)breakpoint;
+ String otherVar = watchpoint.getVariableName();
+ String otherFcn = watchpoint.getFunctionName();
+ if (otherVar.equals(var) && otherFcn.equals(fcn)) {
+ breakpoint.delete();
+ return;
+ }
+ }
+ }
+ // create watchpoint
+ PDAWatchpoint watchpoint = new PDAWatchpoint(resource, lineNumber + 1, fcn, var, true, true);
+ DebugPlugin.getDefault().getBreakpointManager().addBreakpoint(watchpoint);
+ }
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTarget#canToggleWatchpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
+ return getVariableAndFunctionName(part, selection) != null;
+ }
+
+ /**
+ * Returns the variable and function names at the current line, or <code>null</code> if none.
+ *
+ * @param part text editor
+ * @param selection text selection
+ * @return the variable and function names at the current line, or <code>null</code> if none.
+ * The array has two elements, the first is the variable name, the second is the function name.
+ */
+ private String[] getVariableAndFunctionName(IWorkbenchPart part, ISelection selection) {
+ ITextEditor editor = getEditor(part);
+ if (editor != null && selection instanceof ITextSelection) {
+ ITextSelection textSelection = (ITextSelection) selection;
+ IDocumentProvider documentProvider = editor.getDocumentProvider();
+ try {
+ documentProvider.connect(this);
+ IDocument document = documentProvider.getDocument(editor.getEditorInput());
+ IRegion region = document.getLineInformationOfOffset(textSelection.getOffset());
+ String string = document.get(region.getOffset(), region.getLength()).trim();
+ if (string.startsWith("var ")) {
+ String varName = string.substring(4).trim();
+ String fcnName = getFunctionName(document, varName, document.getLineOfOffset(textSelection.getOffset()));
+ return new String[] {varName, fcnName};
+ }
+ } catch (CoreException e) {
+ } catch (BadLocationException e) {
+ } finally {
+ documentProvider.disconnect(this);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the name of the function containing the given variable defined at the given
+ * line number in the specified document.
+ *
+ * @param document PDA source file
+ * @param varName variable name
+ * @param line line numbner at which the variable is defined
+ * @return name of function defining the variable
+ */
+ private String getFunctionName(IDocument document, String varName, int line) {
+ // This is a simple guess at the function name - look for the labels preceeding
+ // the variable definition, and then see if there are any 'calls' to that
+ // label. If none, assumet the variable is in the "_main_" function
+ String source = document.get();
+ int lineIndex = line - 1;
+ while (lineIndex >= 0) {
+ try {
+ IRegion information = document.getLineInformation(lineIndex);
+ String lineText = document.get(information.getOffset(), information.getLength());
+ if (lineText.startsWith(":")) {
+ String label = lineText.substring(1);
+ if (source.indexOf("call " + label) >= 0) {
+ return label;
+ }
+ }
+ lineIndex--;
+ } catch (BadLocationException e) {
+ }
+ }
+ return "_main_";
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#toggleBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ if (canToggleWatchpoints(part, selection)) {
+ toggleWatchpoints(part, selection);
+ } else {
+ toggleLineBreakpoints(part, selection);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension#canToggleBreakpoints(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return canToggleLineBreakpoints(part, selection) || canToggleWatchpoints(part, selection);
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAEditorAdapterFactory.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAEditorAdapterFactory.java
new file mode 100644
index 000000000..c67200a40
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDAEditorAdapterFactory.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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.ui.pda.breakpoints;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.debug.examples.ui.pda.editor.PDAEditor;
+import org.eclipse.debug.ui.actions.IRunToLineTarget;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+
+/**
+ * Creates a toggle breakpoint adapter
+ */
+public class PDAEditorAdapterFactory implements IAdapterFactory {
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+ */
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ if (adaptableObject instanceof PDAEditor) {
+ ITextEditor editorPart = (ITextEditor) adaptableObject;
+ IResource resource = (IResource) editorPart.getEditorInput().getAdapter(IResource.class);
+ if (resource != null) {
+ String extension = resource.getFileExtension();
+ if (extension != null && extension.equals("pda")) {
+ if (adapterType.equals(IToggleBreakpointsTarget.class)) {
+ return new PDABreakpointAdapter();
+ }
+ //#ifdef ex7
+//# // TODO: Exercise 7 - create run to line adapter
+ //#else
+ if (adapterType.equals(IRunToLineTarget.class)) {
+ return new PDARunToLineAdapter();
+ }
+ //#endif
+ }
+ }
+ }
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+ */
+ public Class[] getAdapterList() {
+ return new Class[]{IToggleBreakpointsTarget.class};
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDARunToLineAdapter.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDARunToLineAdapter.java
new file mode 100644
index 000000000..3d5fa42d0
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/breakpoints/PDARunToLineAdapter.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * 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.ui.pda.breakpoints;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.IDebugElement;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.ISuspendResume;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.examples.core.pda.breakpoints.PDARunToLineBreakpoint;
+import org.eclipse.debug.ui.actions.IRunToLineTarget;
+import org.eclipse.debug.ui.actions.RunToLineHandler;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+
+/**
+ * Run to line target for the Java debugger
+ */
+public class PDARunToLineAdapter implements IRunToLineTarget {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IRunToLineTarget#runToLine(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.debug.core.model.ISuspendResume)
+ */
+ public void runToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) throws CoreException {
+ IEditorPart editorPart = (IEditorPart)part;
+ ITextEditor textEditor = (ITextEditor)editorPart;
+ ITextSelection textSelection = (ITextSelection) selection;
+ int lineNumber = textSelection.getStartLine() + 1;
+ if (lineNumber > 0) {
+ if (target instanceof IAdaptable) {
+ IDebugTarget debugTarget = (IDebugTarget) ((IAdaptable)target).getAdapter(IDebugTarget.class);
+ if (debugTarget != null) {
+ //#ifdef ex7
+//# // TODO: Exercise 7 - perform the run-to-line with a run-to-line breakpoint and handler
+ //#else
+ IFile resource = (IFile) textEditor.getEditorInput().getAdapter(IResource.class);
+ IBreakpoint breakpoint= new PDARunToLineBreakpoint(resource, lineNumber);
+ RunToLineHandler handler = new RunToLineHandler(debugTarget, target, breakpoint);
+ handler.run(new NullProgressMonitor());
+ //#endif
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.actions.IRunToLineTarget#canRunToLine(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection, org.eclipse.debug.core.model.ISuspendResume)
+ */
+ public boolean canRunToLine(IWorkbenchPart part, ISelection selection, ISuspendResume target) {
+ //#ifdef ex7
+//# // TODO: Exercise 7 - ensure the target is a PDA target
+//# return false;
+ //#else
+ return target instanceof IDebugElement &&
+ ((IDebugElement)target).getModelIdentifier().equals(DebugCorePlugin.ID_PDA_DEBUG_MODEL);
+ //#endif
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/AnnotationHover.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/AnnotationHover.java
new file mode 100644
index 000000000..6b79056b7
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/AnnotationHover.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * 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.ui.pda.editor;
+
+import java.util.Iterator;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+
+/**
+ * Returns hover for breakpoints.
+ */
+public class AnnotationHover implements IAnnotationHover {
+
+ public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+ IAnnotationModel annotationModel = sourceViewer.getAnnotationModel();
+ Iterator iterator = annotationModel.getAnnotationIterator();
+ while (iterator.hasNext()) {
+ Annotation annotation = (Annotation) iterator.next();
+ Position position = annotationModel.getPosition(annotation);
+ try {
+ int lineOfAnnotation = sourceViewer.getDocument().getLineOfOffset(position.getOffset());
+ if (lineNumber == lineOfAnnotation) {
+ return annotation.getText();
+ }
+ } catch (BadLocationException e) {
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAContentAssistProcessor.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAContentAssistProcessor.java
new file mode 100644
index 000000000..5d7089472
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAContentAssistProcessor.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * 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.ui.pda.editor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.contentassist.CompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.contentassist.IContextInformationValidator;
+
+public class PDAContentAssistProcessor implements IContentAssistProcessor {
+
+ public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+ int index = offset - 1;
+ StringBuffer prefix = new StringBuffer();
+ IDocument document = viewer.getDocument();
+ while (index > 0) {
+ try {
+ char prev = document.getChar(index);
+ if (Character.isWhitespace(prev)) {
+ break;
+ }
+ prefix.insert(0, prev);
+ index--;
+ } catch (BadLocationException e) {
+ }
+ }
+
+ List proposals = new ArrayList();
+ String[] keywords = PDAScanner.fgKeywords;
+ if (prefix.length() > 0) {
+ String word = prefix.toString();
+ for (int i = 0; i < keywords.length; i++) {
+ String keyword = keywords[i];
+ if (keyword.startsWith(word) && word.length() < keyword.length()) {
+ proposals.add(new CompletionProposal(keyword + " ", index + 1, offset - (index + 1), keyword.length() + 1));
+ }
+ }
+ } else {
+ // propose all keywords
+ for (int i = 0; i < keywords.length; i++) {
+ String keyword = keywords[i];
+ proposals.add(new CompletionProposal(keyword + " ", offset, 0, keyword.length() + 1));
+ }
+ }
+ if (!proposals.isEmpty()) {
+ return (ICompletionProposal[]) proposals.toArray(new ICompletionProposal[proposals.size()]);
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer, int)
+ */
+ public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+ */
+ public char[] getCompletionProposalAutoActivationCharacters() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+ */
+ public char[] getContextInformationAutoActivationCharacters() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
+ */
+ public String getErrorMessage() {
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
+ */
+ public IContextInformationValidator getContextInformationValidator() {
+ return null;
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAContentAssistant.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAContentAssistant.java
new file mode 100644
index 000000000..01f71928e
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAContentAssistant.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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.ui.pda.editor;
+
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.contentassist.ContentAssistant;
+import org.eclipse.swt.widgets.Shell;
+
+public class PDAContentAssistant extends ContentAssistant {
+
+ public PDAContentAssistant() {
+ super();
+
+ PDAContentAssistProcessor processor= new PDAContentAssistProcessor();
+ setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
+
+ enableAutoActivation(false);
+ enableAutoInsert(false);
+
+ setInformationControlCreator(getInformationControlCreator());
+ }
+
+ private IInformationControlCreator getInformationControlCreator() {
+ return new IInformationControlCreator() {
+ public IInformationControl createInformationControl(Shell parent) {
+ return new DefaultInformationControl(parent);
+ }
+ };
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAEditor.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAEditor.java
new file mode 100644
index 000000000..3617cb172
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAEditor.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.ui.pda.editor;
+
+import java.util.ResourceBundle;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.ui.texteditor.AbstractDecoratedTextEditor;
+import org.eclipse.ui.texteditor.ContentAssistAction;
+import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
+
+/**
+ * PDA editor
+ */
+public class PDAEditor extends AbstractDecoratedTextEditor {
+
+ /**
+ * Creates a PDE editor
+ */
+ public PDAEditor() {
+ super();
+ setSourceViewerConfiguration(new PDASourceViewerConfiguration());
+ setRulerContextMenuId("pda.editor.rulerMenu");
+ setEditorContextMenuId("pda.editor.editorMenu");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor#createActions()
+ */
+ protected void createActions() {
+ super.createActions();
+ ResourceBundle bundle = ResourceBundle.getBundle("org.eclipse.debug.examples.ui.pda.editor.PDAEditorMessages"); //$NON-NLS-1$
+ IAction action = new ContentAssistAction(bundle, "ContentAssistProposal.", this); //$NON-NLS-1$
+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
+ setAction("ContentAssistProposal", action); //$NON-NLS-1$
+ }
+
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAEditorMessages.properties b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAEditorMessages.properties
new file mode 100644
index 000000000..3215e8892
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAEditorMessages.properties
@@ -0,0 +1,15 @@
+###############################################################################
+# Copyright (c) 2000, 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
+###############################################################################
+
+ContentAssistProposal.label=Content &Assist
+ContentAssistProposal.tooltip=Content Assist
+ContentAssistProposal.image=
+ContentAssistProposal.description=Content Assist \ No newline at end of file
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAScanner.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAScanner.java
new file mode 100644
index 000000000..b62d0ba45
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDAScanner.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * 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.ui.pda.editor;
+
+import org.eclipse.debug.examples.ui.pda.DebugUIPlugin;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
+import org.eclipse.jface.text.rules.IRule;
+import org.eclipse.jface.text.rules.IWordDetector;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
+
+
+/**
+ * PDA editor keyword scanner.
+ */
+public class PDAScanner extends BufferedRuleBasedScanner {
+
+ /**
+ * PDA keywods
+ */
+ public static final String[] fgKeywords = new String[] {
+ "add", "branch_not_zero", "call", "dec", "dup",
+ "halt", "output", "pop", "push", "return", "var"
+ };
+
+ /**
+ * Detects potential keywords
+ */
+ class PDAWordDetector implements IWordDetector {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.rules.IWordDetector#isWordStart(char)
+ */
+ public boolean isWordStart(char c) {
+ return Character.isLetter(c);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.rules.IWordDetector#isWordPart(char)
+ */
+ public boolean isWordPart(char c) {
+ return Character.isLetter(c) || c == '_';
+ }
+ }
+
+ /**
+ * Detects PDA branch labels
+ */
+ class PDALabelDetector extends PDAWordDetector {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.rules.IWordDetector#isWordStart(char)
+ */
+ public boolean isWordStart(char c) {
+ return c == ':';
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.rules.IWordDetector#isWordPart(char)
+ */
+ public boolean isWordPart(char c) {
+ return super.isWordPart(c) || Character.isDigit(c);
+ }
+ }
+
+ /**
+ * Constructs a scanner that identifies PDA keywords.
+ */
+ public PDAScanner() {
+ // keywords
+ Token token = new Token(new TextAttribute(DebugUIPlugin.getDefault().getColor(DebugUIPlugin.KEYWORD)));
+ WordRule keywords = new WordRule(new PDAWordDetector());
+ for (int i = 0; i < fgKeywords.length; i++) {
+ String keyword = fgKeywords[i];
+ keywords.addWord(keyword, token);
+ }
+ // labels
+ token = new Token(new TextAttribute(DebugUIPlugin.getDefault().getColor(DebugUIPlugin.LABEL)));
+ WordRule labels = new WordRule(new PDALabelDetector(), token);
+ setRules(new IRule[]{keywords, labels});
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDASourceViewerConfiguration.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDASourceViewerConfiguration.java
new file mode 100644
index 000000000..6c24c36a0
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PDASourceViewerConfiguration.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * 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.ui.pda.editor;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.contentassist.IContentAssistant;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
+
+/**
+ * Source view configuration for the PDA editor
+ */
+public class PDASourceViewerConfiguration extends TextSourceViewerConfiguration {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTextHover(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
+ */
+ public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+ return new TextHover();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getAnnotationHover(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+ return new AnnotationHover();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+ PresentationReconciler reconciler = new PresentationReconciler();
+ reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+ DefaultDamagerRepairer dr = new DefaultDamagerRepairer(new PDAScanner());
+ reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+ return reconciler;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentAssistant(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+ return new PDAContentAssistant();
+ }
+
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java
new file mode 100644
index 000000000..1c13bac19
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/PopFrameActionDelegate.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * 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.ui.pda.editor;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.examples.core.pda.model.PDAStackFrame;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.IActionDelegate2;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+
+public class PopFrameActionDelegate implements IObjectActionDelegate, IActionDelegate2 {
+
+ private PDAThread fThread = null;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
+ */
+ public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ */
+ public void run(IAction action) {
+ //#ifdef ex5
+//# // TODO: Exercise 5 - pop the top frame
+ //#else
+ try {
+ fThread.pop();
+ } catch (DebugException e) {
+ }
+ //#endif
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
+ */
+ public void selectionChanged(IAction action, ISelection selection) {
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection) selection;
+ Object element = ss.getFirstElement();
+ if (element instanceof PDAStackFrame) {
+ PDAStackFrame frame = (PDAStackFrame) element;
+ //#ifdef ex5
+//# // TODO: Exercise 5 - enable the action if the frame's thread supports it
+ //#else
+ fThread = (PDAThread) frame.getThread();
+ try {
+ action.setEnabled(fThread.canPop() && fThread.getTopStackFrame().equals(frame));
+ } catch (DebugException e) {
+ }
+ return;
+ //#endif
+ }
+
+ }
+ action.setEnabled(false);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IActionDelegate2#init(org.eclipse.jface.action.IAction)
+ */
+ public void init(IAction action) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IActionDelegate2#dispose()
+ */
+ public void dispose() {
+ fThread = null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IActionDelegate2#runWithEvent(org.eclipse.jface.action.IAction, org.eclipse.swt.widgets.Event)
+ */
+ public void runWithEvent(IAction action, Event event) {
+ run(action);
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/TextHover.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/TextHover.java
new file mode 100644
index 000000000..6b14e4c74
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/TextHover.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * 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.ui.pda.editor;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IVariable;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAStackFrame;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextViewer;
+
+
+/**
+ * Produces debug hover for the PDA debugger.
+ */
+public class TextHover implements ITextHover {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
+ */
+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+ String varName = null;
+ try {
+ varName = textViewer.getDocument().get(hoverRegion.getOffset(), hoverRegion.getLength());
+ } catch (BadLocationException e) {
+ return null;
+ }
+ if (varName.startsWith("$") && varName.length() > 1) {
+ varName = varName.substring(1);
+ }
+
+ PDAStackFrame frame = null;
+ IAdaptable debugContext = DebugUITools.getDebugContext();
+ if (debugContext instanceof PDAStackFrame) {
+ frame = (PDAStackFrame) debugContext;
+ } else if (debugContext instanceof PDAThread) {
+ PDAThread thread = (PDAThread) debugContext;
+ try {
+ frame = (PDAStackFrame) thread.getTopStackFrame();
+ } catch (DebugException e) {
+ return null;
+ }
+ } else if (debugContext instanceof PDADebugTarget) {
+ PDADebugTarget target = (PDADebugTarget) debugContext;
+ try {
+ IThread[] threads = target.getThreads();
+ if (threads.length > 0) {
+ frame = (PDAStackFrame) threads[0].getTopStackFrame();
+ }
+ } catch (DebugException e) {
+ return null;
+ }
+ }
+ if (frame != null) {
+ try {
+ IVariable[] variables = frame.getVariables();
+ for (int i = 0; i < variables.length; i++) {
+ IVariable variable = variables[i];
+ if (variable.getName().equals(varName)) {
+ return varName + " = " + variable.getValue().getValueString();
+ }
+ }
+ } catch (DebugException e) {
+ }
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
+ */
+ public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+ return WordFinder.findWord(textViewer.getDocument(), offset);
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/WordFinder.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/WordFinder.java
new file mode 100644
index 000000000..e60d98203
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/editor/WordFinder.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.ui.pda.editor;
+
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Region;
+
+/**
+ * Looks for an identifier in a source file
+ */
+public class WordFinder {
+
+ /**
+ * Returns the region in the given document that contains an identifier, or
+ * <code>null</code> if none.
+ *
+ * @param document document to search
+ * @param offset offset at which to look for an identifier
+ * @return region containing an identifier, or <code>null</code>
+ */
+ public static IRegion findWord(IDocument document, int offset) {
+
+ int start= -1;
+ int end= -1;
+
+
+ try {
+
+ int pos= offset;
+ char c;
+
+ while (pos >= 0) {
+ c= document.getChar(pos);
+ if (!Character.isJavaIdentifierPart(c))
+ break;
+ --pos;
+ }
+
+ start= pos;
+
+ pos= offset;
+ int length= document.getLength();
+
+ while (pos < length) {
+ c= document.getChar(pos);
+ if (!Character.isJavaIdentifierPart(c))
+ break;
+ ++pos;
+ }
+
+ end= pos;
+
+ } catch (BadLocationException x) {
+ }
+
+ if (start > -1 && end > -1) {
+ if (start == offset && end == offset)
+ return new Region(offset, 0);
+ else if (start == offset)
+ return new Region(start, end - start);
+ else
+ return new Region(start + 1, end - start - 1);
+ }
+
+ return null;
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDALaunchShortcut.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDALaunchShortcut.java
new file mode 100644
index 000000000..2bbf75ee2
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDALaunchShortcut.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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.ui.pda.launcher;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.ILaunchShortcut;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.ui.IEditorPart;
+
+
+/**
+ * Launches a PDA file
+ */
+public class PDALaunchShortcut implements ILaunchShortcut {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.jface.viewers.ISelection, java.lang.String)
+ */
+ public void launch(ISelection selection, String mode) {
+ // must be a structured selection with one file selected
+ IFile file = (IFile) ((IStructuredSelection)selection).getFirstElement();
+
+ // check for an existing launch config for the pda file
+ String path = file.getFullPath().toString();
+ ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
+ ILaunchConfigurationType type = launchManager.getLaunchConfigurationType(DebugCorePlugin.ID_PDA_LAUNCH_CONFIGURATION_TYPE);
+ try {
+ ILaunchConfiguration[] configurations = launchManager.getLaunchConfigurations(type);
+ for (int i = 0; i < configurations.length; i++) {
+ ILaunchConfiguration configuration = configurations[i];
+ String attribute = configuration.getAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, (String)null);
+ if (path.equals(attribute)) {
+ DebugUITools.launch(configuration, mode);
+ return;
+ }
+ }
+ } catch (CoreException e) {
+ return;
+ }
+
+ try {
+ // create a new configuration for the pda file
+ ILaunchConfigurationWorkingCopy workingCopy = type.newInstance(null, file.getName());
+ workingCopy.setAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, path);
+ ILaunchConfiguration configuration = workingCopy.doSave();
+ DebugUITools.launch(configuration, mode);
+ } catch (CoreException e1) {
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.ui.IEditorPart, java.lang.String)
+ */
+ public void launch(IEditorPart editor, String mode) {
+ }
+
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDAMainTab.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDAMainTab.java
new file mode 100644
index 000000000..59217fb54
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDAMainTab.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * 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.ui.pda.launcher;
+
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.examples.ui.pda.DebugUIPlugin;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ResourceListSelectionDialog;
+
+
+/**
+ * Tab to specify the PDA program to run/debug.
+ */
+public class PDAMainTab extends AbstractLaunchConfigurationTab {
+
+ private Text fProgramText;
+ private Button fProgramButton;
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+ Font font = parent.getFont();
+
+ Composite comp = new Composite(parent, SWT.NONE);
+ setControl(comp);
+ GridLayout topLayout = new GridLayout();
+ topLayout.verticalSpacing = 0;
+ topLayout.numColumns = 3;
+ comp.setLayout(topLayout);
+ comp.setFont(font);
+
+ createVerticalSpacer(comp, 3);
+
+ Label programLabel = new Label(comp, SWT.NONE);
+ programLabel.setText("&Program:");
+ GridData gd = new GridData(GridData.BEGINNING);
+ programLabel.setLayoutData(gd);
+ programLabel.setFont(font);
+
+ fProgramText = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ fProgramText.setLayoutData(gd);
+ fProgramText.setFont(font);
+ fProgramText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ fProgramButton = createPushButton(comp, "&Browse...", null); //$NON-NLS-1$
+ fProgramButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ browsePDAFiles();
+ }
+ });
+ }
+
+ /**
+ * Open a resource chooser to select a PDA program
+ */
+ protected void browsePDAFiles() {
+ ResourceListSelectionDialog dialog = new ResourceListSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE);
+ dialog.setTitle("PDA Program");
+ dialog.setMessage("Select PDA Program");
+ if (dialog.open() == Window.OK) {
+ Object[] files = dialog.getResult();
+ IFile file = (IFile) files[0];
+ fProgramText.setText(file.getFullPath().toString());
+ }
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+ */
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ //#ifdef ex1
+//# // TODO: Exercise 1 - retrieve the program path attribute from the launch configuration
+//# String program = null;
+//# if (program != null) {
+//# fProgramText.setText(program);
+//# }
+ //#else
+ try {
+ String program = null;
+ program = configuration.getAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, (String)null);
+ if (program != null) {
+ fProgramText.setText(program);
+ }
+ } catch (CoreException e) {
+ setErrorMessage(e.getMessage());
+ }
+ //#endif
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
+ */
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ String program = fProgramText.getText().trim();
+ if (program.length() == 0) {
+ program = null;
+ }
+ //#ifdef ex1
+//# // TODO: Exercise 1 - update the launch configuration with the path to
+//# // currently specified program
+ //#else
+ configuration.setAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, program);
+ //#endif
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
+ */
+ public String getName() {
+ return "Main";
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
+ */
+ public boolean isValid(ILaunchConfiguration launchConfig) {
+ setErrorMessage(null);
+ setMessage(null);
+ String text = fProgramText.getText();
+ //#ifdef ex1
+//# // TODO: Exercise 1 - validate the currently specified program exists and is not
+//# // empty, providing the user with feedback.
+ //#else
+ if (text.length() > 0) {
+ IPath path = new Path(text);
+ if (ResourcesPlugin.getWorkspace().getRoot().findMember(path) == null) {
+ setErrorMessage("Specified program does not exist");
+ return false;
+ }
+ } else {
+ setMessage("Specify a program");
+ }
+ //#endif
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
+ */
+ public Image getImage() {
+ return DebugUIPlugin.getDefault().getImageRegistry().get(DebugUIPlugin.IMG_OBJ_PDA);
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDATabGroup.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDATabGroup.java
new file mode 100644
index 000000000..6f1753c45
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/launcher/PDATabGroup.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.ui.pda.launcher;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
+
+/**
+ * Tab group for a PDA application
+ */
+public class PDATabGroup extends AbstractLaunchConfigurationTabGroup {
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ILaunchConfigurationTabGroup#createTabs(org.eclipse.debug.ui.ILaunchConfigurationDialog, java.lang.String)
+ */
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ //#ifdef ex1
+//# // TODO: Exercise 1 - add the PDA main tab, source lookup tab and common
+//# // tab to the tab group
+ //#else
+ setTabs(new ILaunchConfigurationTab[] {
+ new PDAMainTab(),
+ new SourceLookupTab(),
+ new CommonTab()
+ });
+ //#endif
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/presentation/PDAModelPresentation.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/presentation/PDAModelPresentation.java
new file mode 100644
index 000000000..7d5d3ba91
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/presentation/PDAModelPresentation.java
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * 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.ui.pda.presentation;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ILineBreakpoint;
+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.PDAWatchpoint;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.core.pda.model.PDAStackFrame;
+import org.eclipse.debug.examples.core.pda.model.PDAThread;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.debug.ui.IValueDetailListener;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.part.FileEditorInput;
+
+
+/**
+ * Renders PDA debug elements
+ */
+public class PDAModelPresentation extends LabelProvider implements IDebugModelPresentation {
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.IDebugModelPresentation#setAttribute(java.lang.String, java.lang.Object)
+ */
+ public void setAttribute(String attribute, Object value) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+ */
+ public String getText(Object element) {
+ if (element instanceof PDADebugTarget) {
+ return getTargetText((PDADebugTarget)element);
+ } else if (element instanceof PDAThread) {
+ return getThreadText((PDAThread)element);
+ } else if (element instanceof PDAStackFrame) {
+ return getStackFrameText((PDAStackFrame)element);
+ } else if (element instanceof PDAWatchpoint) {
+ return getWatchpointText((PDAWatchpoint)element);
+ }
+ return null;
+ }
+
+ /**
+ * Returns a label for the given watchpoint.
+ *
+ * @param watchpoint
+ * @return a label for the given watchpoint
+ */
+ private String getWatchpointText(PDAWatchpoint watchpoint) {
+ try {
+ String label = watchpoint.getVariableName() + " (" + watchpoint.getFunctionName() + ")";
+ if (watchpoint.isAccess()) {
+ label += " [read]";
+ }
+ if (watchpoint.isModification()) {
+ label += " [write]";
+ }
+ return label;
+ } catch (CoreException e) {
+ return null;
+ }
+ }
+ /**
+ * Returns a label for the given debug target
+ *
+ * @param target debug target
+ * @return a label for the given debug target
+ */
+ private String getTargetText(PDADebugTarget target) {
+ try {
+ String pgmPath = target.getLaunch().getLaunchConfiguration().getAttribute(DebugCorePlugin.ATTR_PDA_PROGRAM, (String)null);
+ if (pgmPath != null) {
+ IPath path = new Path(pgmPath);
+ String label = "";
+ if (target.isTerminated()) {
+ label = "<terminated>";
+ }
+ return label + "PDA [" + path.lastSegment() + "]";
+ }
+ } catch (CoreException e) {
+ }
+ return "PDA";
+
+ }
+
+ /**
+ * Returns a label for the given stack frame
+ *
+ * @param frame a stack frame
+ * @return a label for the given stack frame
+ */
+ private String getStackFrameText(PDAStackFrame frame) {
+ try {
+ return frame.getName() + " (line: " + frame.getLineNumber() + ")";
+ } catch (DebugException e) {
+ }
+ return null;
+
+ }
+
+ /**
+ * Returns a label for the given thread
+ *
+ * @param thread a thread
+ * @return a label for the given thread
+ */
+ private String getThreadText(PDAThread thread) {
+ String label = thread.getName();
+ if (thread.isStepping()) {
+ label += " (stepping)";
+ } else if (thread.isSuspended()) {
+ IBreakpoint[] breakpoints = thread.getBreakpoints();
+ if (breakpoints.length == 0) {
+ if (thread.getError() == null) {
+ label += " (suspended)";
+ } else {
+ label += " (" + thread.getError() + ")";
+ }
+ } else {
+ IBreakpoint breakpoint = breakpoints[0]; // there can only be one in PDA
+ if (breakpoint instanceof PDALineBreakpoint) {
+ PDALineBreakpoint pdaBreakpoint = (PDALineBreakpoint) breakpoint;
+ if (pdaBreakpoint instanceof PDAWatchpoint) {
+ try {
+ PDAWatchpoint watchpoint = (PDAWatchpoint)pdaBreakpoint;
+ label += " (watchpoint: " + watchpoint.getSuspendType() + " " + watchpoint.getVariableName() + ")";
+ } catch (CoreException e) {
+ }
+ } else if (pdaBreakpoint.isRunToLineBreakpoint()) {
+ label += " (run to line)";
+ } else {
+ label += " (suspended at line breakpoint)";
+ }
+ }
+ }
+ } else if (thread.isTerminated()) {
+ label = "<terminated> " + label;
+ }
+ return label;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.IDebugModelPresentation#computeDetail(org.eclipse.debug.core.model.IValue, org.eclipse.debug.ui.IValueDetailListener)
+ */
+ public void computeDetail(IValue value, IValueDetailListener listener) {
+ String detail = "";
+ try {
+ detail = value.getValueString();
+ } catch (DebugException e) {
+ }
+ listener.detailComputed(value, detail);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ISourcePresentation#getEditorInput(java.lang.Object)
+ */
+ public IEditorInput getEditorInput(Object element) {
+ if (element instanceof IFile) {
+ return new FileEditorInput((IFile)element);
+ }
+ if (element instanceof ILineBreakpoint) {
+ return new FileEditorInput((IFile)((ILineBreakpoint)element).getMarker().getResource());
+ }
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.ISourcePresentation#getEditorId(org.eclipse.ui.IEditorInput, java.lang.Object)
+ */
+ public String getEditorId(IEditorInput input, Object element) {
+ if (element instanceof IFile || element instanceof ILineBreakpoint) {
+ return "pda.editor";
+ }
+ return null;
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java
new file mode 100644
index 000000000..234fe30ec
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/DataStackView.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * 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.ui.pda.views;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IDebugElement;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.examples.core.pda.DebugCorePlugin;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.ui.AbstractDebugView;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPart;
+
+
+/**
+ * View of the PDA VM data stack
+ */
+public class DataStackView extends AbstractDebugView implements ISelectionListener {
+
+ private PDADebugTarget fTarget;
+ private PopAction fPopAction;
+ private PushAction fPushAction;
+
+ class StackViewContentProvider implements ITreeContentProvider {
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ */
+ public Object[] getChildren(Object parentElement) {
+ if (parentElement instanceof PDADebugTarget) {
+ try {
+ return ((PDADebugTarget)parentElement).getDataStack();
+ } catch (DebugException e) {
+ }
+ }
+ return new Object[0];
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ */
+ public Object getParent(Object element) {
+ if (element instanceof IDebugTarget) {
+ return null;
+ } else {
+ return ((IDebugElement)element).getDebugTarget();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ */
+ public boolean hasChildren(Object element) {
+ if (element instanceof IDebugElement) {
+ return getChildren(element).length > 0;
+ }
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ */
+ public Object[] getElements(Object inputElement) {
+ return getChildren(inputElement);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ */
+ public void dispose() {
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.AbstractDebugView#createViewer(org.eclipse.swt.widgets.Composite)
+ */
+ protected Viewer createViewer(Composite parent) {
+ TreeViewer viewer = new TreeViewer(parent);
+ viewer.setLabelProvider(DebugUITools.newDebugModelPresentation());
+ viewer.setContentProvider(new StackViewContentProvider());
+ getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
+ getSite().setSelectionProvider(viewer);
+ return viewer;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.AbstractDebugView#createActions()
+ */
+ protected void createActions() {
+ fPopAction = new PopAction(this);
+ fPushAction = new PushAction(this);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.AbstractDebugView#getHelpContextId()
+ */
+ protected String getHelpContextId() {
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.AbstractDebugView#fillContextMenu(org.eclipse.jface.action.IMenuManager)
+ */
+ protected void fillContextMenu(IMenuManager menu) {
+ menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
+ menu.add(fPopAction);
+ menu.add(fPushAction);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.debug.ui.AbstractDebugView#configureToolBar(org.eclipse.jface.action.IToolBarManager)
+ */
+ protected void configureToolBar(IToolBarManager tbm) {
+ tbm.add(fPopAction);
+ tbm.add(fPushAction);
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.IWorkbenchPart#dispose()
+ */
+ public void dispose() {
+ getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, this);
+ super.dispose();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
+ */
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ update();
+ }
+
+ /**
+ * Updates the view for the selected target (if suspended)
+ */
+ private synchronized void update() {
+ IAdaptable adaptable = DebugUITools.getDebugContext();
+ fTarget = null;
+ if (adaptable != null) {
+ IDebugElement element = (IDebugElement) adaptable.getAdapter(IDebugElement.class);
+ if (element != null) {
+ if (element.getModelIdentifier().equals(DebugCorePlugin.ID_PDA_DEBUG_MODEL)) {
+ fTarget = (PDADebugTarget) element.getDebugTarget();
+ }
+ }
+ }
+ Object input = null;
+ if (fTarget != null && fTarget.isSuspended()) {
+ input = fTarget;
+ }
+ getViewer().setInput(input);
+ fPushAction.setDebugTarget(fTarget);
+ getViewer().refresh();
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopAction.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopAction.java
new file mode 100644
index 000000000..af21fbcc6
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PopAction.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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.ui.pda.views;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.ui.pda.DebugUIPlugin;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+
+
+/**
+ * Pops a selected value off the data stack. The selection does <b>not</b> have to be
+ * the top element on the stack.
+ */
+public class PopAction extends Action implements ISelectionChangedListener {
+
+ private DataStackView fView;
+
+ /**
+ * Constructs an action to pop values off the stack
+ */
+ protected PopAction(DataStackView view) {
+ super("Pop");
+ ImageRegistry imageRegistry = DebugUIPlugin.getDefault().getImageRegistry();
+ setImageDescriptor(imageRegistry.getDescriptor(DebugUIPlugin.IMG_ELCL_POP));
+ setDisabledImageDescriptor(imageRegistry.getDescriptor(DebugUIPlugin.IMG_DLCL_POP));
+ setToolTipText("Pop");
+ setEnabled(false);
+ view.getSite().getSelectionProvider().addSelectionChangedListener(this);
+ fView = view;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ */
+ public void selectionChanged(SelectionChangedEvent event) {
+ if (event.getSelection().isEmpty()) {
+ setEnabled(false);
+ } else {
+ setEnabled(getDebugTarget().canPop());
+ }
+ }
+
+ public void run() {
+ TreeViewer viewer = (TreeViewer)fView.getViewer();
+ IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+ Object popee = selection.getFirstElement();
+ try {
+ PDADebugTarget target = getDebugTarget();
+ IValue[] stack = target.getDataStack();
+ List restore = new ArrayList();
+ for (int i = 0; i < stack.length; i++) {
+ Object value = stack[i];
+ if (popee.equals(value)) {
+ // pop & stop
+ target.pop();
+ break;
+ } else {
+ // remember value to push back on
+ restore.add(target.pop());
+ }
+ }
+ while (!restore.isEmpty()) {
+ IValue value = (IValue) restore.remove(restore.size() - 1);
+ target.push(value.getValueString());
+ }
+ } catch (DebugException e) {
+ }
+ viewer.refresh();
+ }
+
+ /**
+ * Returns the debug target assocaited with the data view.
+ *
+ * @return the debug target assocaited with the data view
+ */
+ protected PDADebugTarget getDebugTarget() {
+ TreeViewer viewer = (TreeViewer)fView.getViewer();
+ return (PDADebugTarget) viewer.getInput();
+ }
+}
diff --git a/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushAction.java b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushAction.java
new file mode 100644
index 000000000..8764cf3bc
--- /dev/null
+++ b/org.eclipse.debug.examples.ui/src/org/eclipse/debug/examples/ui/pda/views/PushAction.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * 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.ui.pda.views;
+
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.examples.core.pda.model.PDADebugTarget;
+import org.eclipse.debug.examples.ui.pda.DebugUIPlugin;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.window.Window;
+
+
+/**
+ * Pushes a value onto the data stack.
+ */
+public class PushAction extends Action {
+
+ private PDADebugTarget fTarget;
+ private DataStackView fView;
+
+ /**
+ * Constructs an action to pop values off the stack
+ */
+ protected PushAction(DataStackView view) {
+ super("Push");
+ ImageRegistry imageRegistry = DebugUIPlugin.getDefault().getImageRegistry();
+ setImageDescriptor(imageRegistry.getDescriptor(DebugUIPlugin.IMG_ELCL_PUSH));
+ setDisabledImageDescriptor(imageRegistry.getDescriptor(DebugUIPlugin.IMG_DLCL_PUSH));
+ setToolTipText("Push");
+ setEnabled(false);
+ fView = view;
+ }
+
+ public void run() {
+ InputDialog dialog = new InputDialog(fView.getSite().getShell(), "Specify Value", "Enter value to push", null, null);
+ if (dialog.open() == Window.OK) {
+ try {
+ fTarget.push(dialog.getValue());
+ } catch (DebugException e) {
+ }
+ }
+ fView.getViewer().refresh();
+ }
+
+ protected void setDebugTarget(PDADebugTarget target) {
+ fTarget = target;
+ setEnabled(fTarget != null && fTarget.canPush());
+ }
+
+
+}

Back to the top