Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2011-11-11 18:51:51 +0000
committerEugene Tarassov2011-11-11 18:51:51 +0000
commit9587c5ddf0b78aa00883d5cac15ce23dd116df9e (patch)
treed1f1e47b0fb5950ba40881d82f2c4a5f3bb1cfca /plugins/org.eclipse.tcf.debug.ui
parentf8bdfbc8174a8255d41b8e03183aab2205304243 (diff)
downloadorg.eclipse.tcf-9587c5ddf0b78aa00883d5cac15ce23dd116df9e.tar.gz
org.eclipse.tcf-9587c5ddf0b78aa00883d5cac15ce23dd116df9e.tar.xz
org.eclipse.tcf-9587c5ddf0b78aa00883d5cac15ce23dd116df9e.zip
TCF Java package names changed: org.eclipse.tm.tcf.* -> org.eclipse.tcf.*
Diffstat (limited to 'plugins/org.eclipse.tcf.debug.ui')
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/.classpath11
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/.project39
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/.settings/org.eclipse.jdt.core.prefs299
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/.settings/org.eclipse.jdt.ui.prefs4
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/META-INF/MANIFEST.MF35
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/about.html28
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/agent/get-os-tag19
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/build.properties20
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/arguments_tab.gifbin0 -> 95 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/attribute.gifbin0 -> 207 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/brkp_ovr.gifbin0 -> 893 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/casttotype_co.gifbin0 -> 214 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/memory-map.gifbin0 -> 922 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/path.gifbin0 -> 310 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/refresh.gifbin0 -> 368 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/showasarray_co.gifbin0 -> 96 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/signals.gifbin0 -> 323 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/target_tab.gifbin0 -> 567 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/tcf.gifbin0 -> 165 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/thread_not_active.gifbin0 -> 159 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/var_aggr.gifbin0 -> 361 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/var_pointer.gifbin0 -> 82 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/icons/var_simple.gifbin0 -> 95 bytes
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/plugin.properties55
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/plugin.xml631
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/pom.xml17
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/schema/launch_context.exsd72
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/Activator.java127
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java150
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFLaunchAdapterFactory.java58
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFLaunchLabelProvider.java81
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFNodeAdapterFactory.java45
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFNodePropertySource.java191
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/AbstractActionDelegate.java164
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackIntoCommand.java90
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackOverCommand.java109
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackResumeCommand.java64
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackReturnCommand.java100
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BreakpointCommand.java96
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/CastToArrayCommand.java142
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/CastToTypeCommand.java76
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DisconnectCommand.java55
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DropToFrameCommand.java197
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapCommand.java86
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapDialog.java78
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapItemDialog.java303
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapWidget.java632
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RefreshCommand.java87
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RefreshHandler.java87
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RestoreDefaultTypeCommand.java41
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/ResumeCommand.java66
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SignalsCommand.java55
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SignalsDialog.java438
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepCommand.java127
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepIntoCommand.java92
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepOverCommand.java110
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepReturnCommand.java102
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SuspendCommand.java138
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/TerminateCommand.java134
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/UpdatePolicyMenu.java121
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/ViewMemoryCommand.java95
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/WatchInExpressionsCommand.java78
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ITCFLaunchContext.java93
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/PeerPropsDialog.java73
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFArgumentsTab.java162
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFLaunchContext.java69
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFLaunchShortcut.java132
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java476
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMemoryMapTab.java77
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java285
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPropertyTester.java53
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java37
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java1051
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TestErrorsDialog.java89
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/AbstractRemoteShell.java113
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/IRemoteShell.java53
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/PeerPropsControl.java333
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/SSHClient.java70
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/SetupWizardDialog.java60
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TelnetClient.java80
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TelnetInputStream.java328
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TimeOutInputStream.java157
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardFirstPage.java69
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLocalPage.java48
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLogPage.java400
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLoginPage.java209
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardPropsPage.java58
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ICastToType.java21
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/IDetailsProvider.java16
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ISourceNotFoundPresentation.java47
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ISymbolOwner.java18
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/IWatchInExpressions.java18
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/StyledStringBuffer.java110
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFAnnotationImageProvider.java31
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFAnnotationManager.java624
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildren.java226
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenExecContext.java157
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenExpressions.java63
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenHoverExpressions.java68
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenLocalVariables.java80
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenLogExpressions.java67
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenModules.java58
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenRegisters.java87
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenStackTrace.java161
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenSubExpressions.java249
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationExpression.java82
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationModules.java91
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationRegister.java108
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFConsole.java197
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDebugTask.java59
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDetailPane.java158
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDetailPaneFactory.java49
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFMemoryBlockRetrieval.java508
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java1785
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelManager.java156
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelPresentation.java171
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelProxy.java506
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModelSelectionPolicy.java129
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNode.java470
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNodeArrayPartition.java107
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNodeExecContext.java1487
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNodeExpression.java1601
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNodeLaunch.java139
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNodeModule.java99
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNodeRegister.java629
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNodeStackFrame.java550
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNodeSymbol.java173
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNumberFormat.java230
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFRunnable.java33
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFSnapshot.java353
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/preferences/DecoratingIntegerFieldEditor.java106
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/preferences/IntegerWithBooleanFieldEditor.java146
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/preferences/TCFDebugPreferencePage.java166
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/preferences/TCFPreferences.java36
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/preferences/TCFPreferencesInitializer.java36
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/properties/TCFPropertyPage.java46
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/trace/TraceView.java466
137 files changed, 23393 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tcf.debug.ui/.classpath b/plugins/org.eclipse.tcf.debug.ui/.classpath
new file mode 100644
index 000000000..8e321c38f
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/.classpath
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry excluding="**/.svn/**" kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins">
+ <accessrules>
+ <accessrule kind="accessible" pattern="org/eclipse/debug/**/provisional/**"/>
+ </accessrules>
+ </classpathentry>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.tcf.debug.ui/.project b/plugins/org.eclipse.tcf.debug.ui/.project
new file mode 100644
index 000000000..5ea738022
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/.project
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.tm.tcf.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>
+ <filteredResources>
+ <filter>
+ <id>1311579666882</id>
+ <name></name>
+ <type>10</type>
+ <matcher>
+ <id>org.eclipse.ui.ide.multiFilter</id>
+ <arguments>1.0-name-matches-false-false-target</arguments>
+ </matcher>
+ </filter>
+ </filteredResources>
+</projectDescription>
diff --git a/plugins/org.eclipse.tcf.debug.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.tcf.debug.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 000000000..35fc6d403
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,299 @@
+#Wed Oct 05 10:00:20 PDT 2011
+eclipse.preferences.version=1
+org.eclipse.jdt.core.builder.cleanOutputFolder=clean
+org.eclipse.jdt.core.builder.duplicateResourceTask=warning
+org.eclipse.jdt.core.builder.invalidClasspath=abort
+org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
+org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch,.svn/
+org.eclipse.jdt.core.circularClasspath=error
+org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
+org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=1
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=false
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
+org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
+org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
+org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
+org.eclipse.jdt.core.formatter.indentation.size=8
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.join_lines_in_comments=true
+org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=true
+org.eclipse.jdt.core.formatter.lineSplit=180
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=4
+org.eclipse.jdt.core.formatter.use_on_off_tags=false
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.incompatibleJDKLevel=ignore
+org.eclipse.jdt.core.incompleteClasspath=error
diff --git a/plugins/org.eclipse.tcf.debug.ui/.settings/org.eclipse.jdt.ui.prefs b/plugins/org.eclipse.tcf.debug.ui/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 000000000..903e1082e
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,4 @@
+#Wed Oct 05 09:55:18 PDT 2011
+eclipse.preferences.version=1
+formatter_profile=_Java STD
+formatter_settings_version=12
diff --git a/plugins/org.eclipse.tcf.debug.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.tcf.debug.ui/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..493ed16fa
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,35 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %pluginName
+Bundle-SymbolicName: org.eclipse.tm.tcf.debug.ui;singleton:=true
+Bundle-Version: 0.5.0.qualifier
+Bundle-Activator: org.eclipse.tm.internal.tcf.debug.ui.Activator
+Bundle-Vendor: %providerName
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.ide,
+ org.eclipse.ui.console,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.text,
+ org.eclipse.jface.text,
+ org.eclipse.debug.core,
+ org.eclipse.debug.ui,
+ org.eclipse.tm.tcf.debug,
+ com.jcraft.jsch;bundle-version="0.1.37",
+ org.eclipse.jsch.core;bundle-version="1.1.100",
+ org.eclipse.jsch.ui;bundle-version="1.1.100",
+ org.eclipse.core.filesystem;bundle-version="1.3.0"
+Import-Package: org.eclipse.core.expressions,
+ org.eclipse.tm.tcf.core;version="0.4.0",
+ org.eclipse.tm.tcf.protocol;version="0.5.0",
+ org.eclipse.tm.tcf.services;version="0.5.0",
+ org.eclipse.tm.tcf.ssl;version="0.4.0",
+ org.eclipse.tm.tcf.util;version="0.4.0"
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+Bundle-ActivationPolicy: lazy
+Eclipse-LazyStart: true
+Export-Package: org.eclipse.tm.internal.tcf.debug.ui.adapters,
+ org.eclipse.tm.internal.tcf.debug.ui.commands;x-friends:="org.eclipse.tm.tcf.cdt.ui",
+ org.eclipse.tm.internal.tcf.debug.ui.launch,
+ org.eclipse.tm.internal.tcf.debug.ui.model;x-friends:="org.eclipse.tm.tcf.cdt.ui"
diff --git a/plugins/org.eclipse.tcf.debug.ui/about.html b/plugins/org.eclipse.tcf.debug.ui/about.html
new file mode 100644
index 000000000..6c5b3615b
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.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>January 10, 2008</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/plugins/org.eclipse.tcf.debug.ui/agent/get-os-tag b/plugins/org.eclipse.tcf.debug.ui/agent/get-os-tag
new file mode 100644
index 000000000..3ab5d23fe
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/agent/get-os-tag
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+OPSYS=`uname -o 2>/dev/null || uname -s`
+
+if [ $OPSYS = Cygwin ] ; then
+ echo cygwin
+elif [ $OPSYS = GNU/Linux ] ; then
+ if [ -e /etc/fedora-release ] ; then
+ echo fc`rpm -q --queryformat='%{VERSION}\n' fedora-release 2>/dev/null`
+ elif [ -e /etc/redhat-release ] ; then
+ echo rh`sed -e 's/^.*release //' -e 's/ .*$//' -e 's/\\./_/g' </etc/redhat-release`
+ elif [ -e /etc/mandrake-release ] ; then
+ echo mdk
+ elif [ -e /etc/SuSE-release ] ; then
+ echo suse
+ fi
+fi
+
+
diff --git a/plugins/org.eclipse.tcf.debug.ui/build.properties b/plugins/org.eclipse.tcf.debug.ui/build.properties
new file mode 100644
index 000000000..39c4c9da1
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/build.properties
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2010 Wind River Systems, Inc. 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:
+# Wind River Systems - initial API and implementation
+###############################################################################
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ about.html,\
+ plugin.properties,\
+ icons/,\
+ agent/
+src.includes = about.html
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/arguments_tab.gif b/plugins/org.eclipse.tcf.debug.ui/icons/arguments_tab.gif
new file mode 100644
index 000000000..44660b5f0
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/arguments_tab.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/attribute.gif b/plugins/org.eclipse.tcf.debug.ui/icons/attribute.gif
new file mode 100644
index 000000000..0f0769269
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/attribute.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/brkp_ovr.gif b/plugins/org.eclipse.tcf.debug.ui/icons/brkp_ovr.gif
new file mode 100644
index 000000000..5f5f0ab99
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/brkp_ovr.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/casttotype_co.gif b/plugins/org.eclipse.tcf.debug.ui/icons/casttotype_co.gif
new file mode 100644
index 000000000..b04de7e29
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/casttotype_co.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/memory-map.gif b/plugins/org.eclipse.tcf.debug.ui/icons/memory-map.gif
new file mode 100644
index 000000000..b48083118
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/memory-map.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/path.gif b/plugins/org.eclipse.tcf.debug.ui/icons/path.gif
new file mode 100644
index 000000000..13ce11b14
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/path.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/refresh.gif b/plugins/org.eclipse.tcf.debug.ui/icons/refresh.gif
new file mode 100644
index 000000000..049cac696
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/refresh.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/showasarray_co.gif b/plugins/org.eclipse.tcf.debug.ui/icons/showasarray_co.gif
new file mode 100644
index 000000000..233e52a4a
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/showasarray_co.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/signals.gif b/plugins/org.eclipse.tcf.debug.ui/icons/signals.gif
new file mode 100644
index 000000000..34823ea7b
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/signals.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/target_tab.gif b/plugins/org.eclipse.tcf.debug.ui/icons/target_tab.gif
new file mode 100644
index 000000000..e9df7b871
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/target_tab.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/tcf.gif b/plugins/org.eclipse.tcf.debug.ui/icons/tcf.gif
new file mode 100644
index 000000000..3198679ae
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/tcf.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/thread_not_active.gif b/plugins/org.eclipse.tcf.debug.ui/icons/thread_not_active.gif
new file mode 100644
index 000000000..d1a859622
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/thread_not_active.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/var_aggr.gif b/plugins/org.eclipse.tcf.debug.ui/icons/var_aggr.gif
new file mode 100644
index 000000000..d261b6887
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/var_aggr.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/var_pointer.gif b/plugins/org.eclipse.tcf.debug.ui/icons/var_pointer.gif
new file mode 100644
index 000000000..961873ea9
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/var_pointer.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/icons/var_simple.gif b/plugins/org.eclipse.tcf.debug.ui/icons/var_simple.gif
new file mode 100644
index 000000000..9ea61ad1f
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/icons/var_simple.gif
Binary files differ
diff --git a/plugins/org.eclipse.tcf.debug.ui/plugin.properties b/plugins/org.eclipse.tcf.debug.ui/plugin.properties
new file mode 100644
index 000000000..693faaef4
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/plugin.properties
@@ -0,0 +1,55 @@
+###############################################################################
+# Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+# Wind River Systems - initial implementation
+###############################################################################
+pluginName = TCF/Eclipse Debugger Integration UI (Incubation)
+providerName = Eclipse CDT
+
+preferencePage.name = Target Communication
+
+debugCurrentInstructionPointer = Debug Current Instruction Pointer
+debugCallStack = Debug Call Stack
+debugBreakpointInstance = Breakpoint
+
+DebuggerActionSet.label = TCF Debugger
+
+commands.category.name = TCF Debugger
+commands.category.desc = TCF Debugger Commands
+
+Signals.label = Signals...
+MemoryMap.label = Symbol Files...
+ViewMemory.label = View Memory
+WatchInExpressions.label = Watch In Expressions
+Refresh.label = Refresh
+UpdatePolicy.label = Update Policy
+
+CastToType.label=Cast To Type...
+CastToType.tooltip=Cast Expression To Type
+RestoreDefaultType.label=Restore Original Type
+RestoreDefaultType.tooltip=Restore Original Type Of Expression
+CastToArray.label=Display As Array...
+CastToArray.tooltip=Display Expression As Array
+
+ReverseExecutionCategory.name=Reverse execution
+ReverseExecutionCategory.description=Reverse execution control commands
+
+BackInto.label=Back Into
+BackInto.tooltip=Back Into
+BackInto.description=Step back into
+BackOver.label=Back Over
+BackOver.tooltip=Back Over
+BackOver.description=Step back over
+BackReturn.label=Back Return
+BackReturn.tooltip=Back Return
+BackReturn.description=Run backwards until return
+BackResume.label=Run Backwards
+BackResume.tooltip=Run Backwards
+BackResume.description=Run backwards
+
+propertyPage.name = Debug Element
diff --git a/plugins/org.eclipse.tcf.debug.ui/plugin.xml b/plugins/org.eclipse.tcf.debug.ui/plugin.xml
new file mode 100644
index 000000000..3927a0dc4
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/plugin.xml
@@ -0,0 +1,631 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<!--
+ Copyright (c) 2010, 2011 Wind River Systems, Inc. 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:
+ Wind River Systems - initial API and implementation
+ -->
+
+<plugin>
+
+ <extension-point id="launch_context" name="TCF Launch Context" schema="schema/launch_context.exsd"/>
+
+ <extension point="org.eclipse.tm.tcf.startup"/>
+
+ <extension
+ id="org.eclipse.tm.tcf.debug.ui.adapters"
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ class="org.eclipse.tm.internal.tcf.debug.ui.adapters.TCFLaunchAdapterFactory"
+ adaptableType="org.eclipse.tm.internal.tcf.debug.model.TCFLaunch">
+ <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider"/>
+ <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider"/>
+ <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory"/>
+ <adapter type="org.eclipse.debug.ui.contexts.ISuspendTrigger"/>
+ </factory>
+ <factory
+ class="org.eclipse.tm.internal.tcf.debug.ui.adapters.TCFNodeAdapterFactory"
+ adaptableType="org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode">
+ <adapter type="org.eclipse.debug.ui.actions.IToggleBreakpointsTarget"/>
+ <adapter type="org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension"/>
+ <adapter type="org.eclipse.ui.views.properties.IPropertySource"/>
+ </factory>
+ </extension>
+
+ <extension point="org.eclipse.debug.ui.debugModelPresentations">
+ <debugModelPresentation
+ class = "org.eclipse.tm.internal.tcf.debug.ui.model.TCFModelPresentation"
+ id = "org.eclipse.tm.tcf.debug">
+ </debugModelPresentation>
+ </extension>
+
+ <extension point="org.eclipse.debug.ui.launchConfigurationTypeImages">
+ <launchConfigurationTypeImage
+ icon="icons/tcf.gif"
+ configTypeID="org.eclipse.tm.tcf.debug.LaunchConfigurationType"
+ id="org.eclipse.tm.tcf.debug.LaunchConfigurationTypeImage">
+ </launchConfigurationTypeImage>
+ </extension>
+
+ <extension point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+ <launchConfigurationTabGroup
+ type="org.eclipse.tm.tcf.debug.LaunchConfigurationType"
+ description="Run or debug a program using Target Communication Framework"
+ class="org.eclipse.tm.internal.tcf.debug.ui.launch.TCFTabGroup"
+ id="org.eclipse.tm.tcf.debug.LaunchConfigurationTabGroup">
+ </launchConfigurationTabGroup>
+ </extension>
+
+ <extension point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ namespace="org.eclipse.tm.tcf.launch"
+ properties="isExecutable,areUpdatePoliciesSupported"
+ type="org.eclipse.core.runtime.IAdaptable"
+ class="org.eclipse.tm.internal.tcf.debug.ui.launch.TCFPropertyTester"
+ id="org.eclipse.tm.tcf.launch.PropertyTester">
+ </propertyTester>
+ </extension>
+
+ <extension point="org.eclipse.debug.ui.launchShortcuts">
+ <shortcut
+ label="TCF Application"
+ icon="icons/tcf.gif"
+ helpContextId="org.eclipse.tm.tcf.debug.ui.shortcut_tcf_application"
+ modes="run, debug"
+ class="org.eclipse.tm.internal.tcf.debug.ui.launch.TCFLaunchShortcut"
+ description="Launch an application using Target Communication Framework (TCF)"
+ id="org.eclipse.tm.tcf.debug.ui.TCFShortcut">
+ <description
+ description="Runs an application using Target Communication Framework (TCF)"
+ mode="run">
+ </description>
+ <description
+ description="Debugs an application using Target Communication Framework (TCF)"
+ mode="debug">
+ </description>
+ <contextualLaunch>
+ <enablement>
+ <with variable="selection">
+ <count value="1"/>
+ <iterate>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.tm.tcf.launch.isExecutable"/>
+ </iterate>
+ </with>
+ </enablement>
+ </contextualLaunch>
+ <configurationType
+ id="org.eclipse.tm.tcf.debug.LaunchConfigurationType">
+ </configurationType>
+ </shortcut>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.contexts">
+ <context
+ name="Debugging using Target Communication Framework"
+ description="Debugging using Target Communication Framework"
+ id="org.eclipse.tm.tcf.debug.ui.debugging"
+ parentId="org.eclipse.debug.ui.debugging">
+ </context>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.views">
+ <view
+ name="TCF Trace"
+ icon="icons/tcf.gif"
+ category="org.eclipse.debug.ui"
+ class="org.eclipse.tm.internal.tcf.debug.ui.trace.TraceView"
+ id="org.eclipse.tm.tcf.TraceView">
+ </view>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.perspectiveExtensions">
+ <perspectiveExtension
+ targetID="org.eclipse.debug.ui.DebugPerspective">
+ <view
+ relative="org.eclipse.ui.console.ConsoleView"
+ relationship="stack"
+ visible="false"
+ id="org.eclipse.tm.tcf.TraceView">
+ </view>
+ </perspectiveExtension>
+ </extension>
+
+ <extension point="org.eclipse.ui.editors.annotationTypes">
+ <type
+ name="org.eclipse.tm.tcf.debug.top_frame">
+ </type>
+ <type
+ name="org.eclipse.tm.tcf.debug.stack_frame">
+ </type>
+ <type
+ name="org.eclipse.tm.tcf.debug.breakpoint_instance">
+ </type>
+ </extension>
+
+ <extension point="org.eclipse.ui.editors.markerAnnotationSpecification">
+ <specification
+ annotationImageProvider="org.eclipse.tm.internal.tcf.debug.ui.model.TCFAnnotationImageProvider"
+ annotationType="org.eclipse.tm.tcf.debug.top_frame"
+ colorPreferenceKey="currentIPColor"
+ colorPreferenceValue="198,219,174"
+ highlightPreferenceKey="currentIPHighlight"
+ highlightPreferenceValue="true"
+ label="%debugCurrentInstructionPointer"
+ overviewRulerPreferenceKey="currentIPOverviewRuler"
+ overviewRulerPreferenceValue="true"
+ presentationLayer="6"
+ textPreferenceKey="currentIPIndication"
+ textPreferenceValue="false"
+ verticalRulerPreferenceKey="currentIPVerticalRuler"
+ verticalRulerPreferenceValue="true">
+ </specification>
+ <specification
+ annotationImageProvider="org.eclipse.tm.internal.tcf.debug.ui.model.TCFAnnotationImageProvider"
+ annotationType="org.eclipse.tm.tcf.debug.stack_frame"
+ colorPreferenceKey="secondaryIPColor"
+ colorPreferenceValue="219,235,204"
+ highlightPreferenceKey="secondaryIPHighlight"
+ highlightPreferenceValue="true"
+ label="%debugCallStack"
+ overviewRulerPreferenceKey="secondaryIPOverviewRuler"
+ overviewRulerPreferenceValue="true"
+ presentationLayer="6"
+ textPreferenceKey="secondaryIPIndication"
+ textPreferenceValue="false"
+ verticalRulerPreferenceKey="secondaryIPVerticalRuler"
+ verticalRulerPreferenceValue="true">
+ </specification>
+ <specification
+ annotationImageProvider="org.eclipse.tm.internal.tcf.debug.ui.model.TCFAnnotationImageProvider"
+ annotationType="org.eclipse.tm.tcf.debug.breakpoint_instance"
+ colorPreferenceKey="breakpointInstanceColor"
+ colorPreferenceValue="100,200,204"
+ highlightPreferenceKey="breakpointInstanceHighlight"
+ highlightPreferenceValue="false"
+ label="%debugBreakpointInstance"
+ overviewRulerPreferenceKey="breakpointInstanceRuler"
+ overviewRulerPreferenceValue="true"
+ presentationLayer="5"
+ textPreferenceKey="breakpointInstanceIndication"
+ textPreferenceValue="false"
+ verticalRulerPreferenceKey="breakpointInstanceVerticalRuler"
+ verticalRulerPreferenceValue="true">
+ </specification>
+ </extension>
+
+ <extension point="org.eclipse.debug.ui.detailPaneFactories">
+ <detailFactories
+ class="org.eclipse.tm.internal.tcf.debug.ui.model.TCFDetailPaneFactory"
+ id="org.eclipse.tm.tcf.debug.DetailPaneFactory">
+ <enablement>
+ <with variable="selection">
+ <iterate>
+ <or>
+ <instanceof value="org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode"/>
+ </or>
+ </iterate>
+ </with>
+ </enablement>
+ </detailFactories>
+ </extension>
+
+ <extension point="org.eclipse.ui.popupMenus">
+ <!-- TCFLaunch popup menu contributions -->
+ <objectContribution
+ id="org.eclipse.tm.tcf.debug.ui.TCFLaunch"
+ objectClass="org.eclipse.tm.internal.tcf.debug.model.TCFLaunch">
+ <action
+ id="org.eclipse.tm.tcf.debug.ui.actions.Signals"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.SignalsCommand"
+ icon="icons/signals.gif"
+ label="%Signals.label"
+ menubarPath="additions">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ </objectContribution>
+
+ <!-- TCFNode popup menu contributions -->
+ <objectContribution
+ id="org.eclipse.tm.tcf.debug.ui.TCFNode"
+ objectClass="org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode">
+ <action
+ id="org.eclipse.tm.tcf.debug.ui.actions.Signals"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.SignalsCommand"
+ icon="icons/signals.gif"
+ label="%Signals.label"
+ menubarPath="additions">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ <action
+ id="org.eclipse.tm.tcf.debug.ui.actions.MemoryMap"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.MemoryMapCommand"
+ icon="icons/memory-map.gif"
+ label="%MemoryMap.label"
+ menubarPath="additions">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ <action
+ id="org.eclipse.tm.tcf.debug.ui.actions.Refresh"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.RefreshCommand"
+ icon="icons/refresh.gif"
+ label="%Refresh.label"
+ menubarPath="additions">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ </objectContribution>
+
+ <!-- TCFNodeExpression popup menu contributions -->
+ <objectContribution
+ id="org.eclipse.tm.tcf.debug.ui.TCFNodeExpression"
+ objectClass="org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExpression">
+ <action
+ id="org.eclipse.tm.tcf.debug.ui.actions.ViewMemory"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.ViewMemoryCommand"
+ label="%ViewMemory.label"
+ menubarPath="variableGroup">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ </objectContribution>
+
+ <!-- ICastToType popup menu contributions -->
+ <objectContribution
+ id="org.eclipse.tm.tcf.debug.ui.CastToType"
+ objectClass="org.eclipse.tm.internal.tcf.debug.ui.model.ICastToType">
+ <action
+ label="%RestoreDefaultType.label"
+ helpContextId="restore_default_type_action_context"
+ tooltip="%RestoreDefaultType.tooltip"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.RestoreDefaultTypeCommand"
+ menubarPath="variableGroup"
+ enablesFor="1"
+ id="org.eclipse.tm.tcf.debug.ui.commands.RestoreDefaultType">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ <action
+ label="%CastToType.label"
+ icon="icons/casttotype_co.gif"
+ helpContextId="cast_to_type_action_context"
+ tooltip="%CastToType.tooltip"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.CastToTypeCommand"
+ menubarPath="variableGroup"
+ enablesFor="1"
+ id="org.eclipse.tm.tcf.debug.ui.commands.CastToType">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ <action
+ label="%CastToArray.label"
+ icon="icons/showasarray_co.gif"
+ helpContextId="cast_to_array_action_context"
+ tooltip="%CastToArray.tooltip"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.CastToArrayCommand"
+ menubarPath="variableGroup"
+ enablesFor="1"
+ id="org.eclipse.tm.tcf.debug.ui.commands.CastToArray">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ </objectContribution>
+
+ <!-- IWatchInExpressions -->
+ <objectContribution
+ id="org.eclipse.tm.tcf.debug.ui.WatchInExpressions"
+ objectClass="org.eclipse.tm.internal.tcf.debug.ui.model.IWatchInExpressions">
+ <action
+ id="org.eclipse.tm.tcf.debug.ui.actions.WatchInExpressions"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.WatchInExpressionsCommand"
+ label="%WatchInExpressions.label"
+ menubarPath="additions">
+ <enablement>
+ <pluginState
+ value="activated"
+ id="org.eclipse.tm.tcf.debug.ui">
+ </pluginState>
+ </enablement>
+ </action>
+ </objectContribution>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.commands">
+ <category
+ name="%commands.category.name"
+ description="%commands.category.desc"
+ id="org.eclipse.tm.tcf.debug.ui.commands">
+ </category>
+ <command
+ categoryId="org.eclipse.tm.tcf.debug.ui.commands"
+ defaultHandler="org.eclipse.tm.internal.tcf.debug.ui.commands.RefreshHandler"
+ id="org.eclipse.tm.tcf.debug.ui.commands.refresh"
+ name="%Refresh.label"/>
+ </extension>
+
+ <extension point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.RefreshHandler"
+ commandId="org.eclipse.ui.file.refresh">
+ <activeWhen>
+ <and>
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ <with variable="activePart">
+ <test property="org.eclipse.tm.tcf.launch.areUpdatePoliciesSupported"/>
+ </with>
+ </and>
+ </activeWhen>
+ </handler>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.menus">
+ <!-- Registers View -->
+ <menuContribution
+ locationURI="toolbar:org.eclipse.debug.ui.RegisterView?after=additions">
+ <command
+ commandId="org.eclipse.tm.tcf.debug.ui.commands.refresh"
+ icon="icons/refresh.gif"
+ id="org.eclipse.tm.tcf.debug.ui.commands.refresh.registers"
+ label="%Refresh.label"
+ style="push">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="menu:org.eclipse.debug.ui.RegisterView?after=additions">
+ <menu
+ label="%UpdatePolicy.label"
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.registers">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ <dynamic
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.registers.menu"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.UpdatePolicyMenu"/>
+ </menu>
+ </menuContribution>
+ <!-- Variables View -->
+ <menuContribution
+ locationURI="toolbar:org.eclipse.debug.ui.VariableView?after=additions">
+ <command
+ commandId="org.eclipse.tm.tcf.debug.ui.commands.refresh"
+ icon="icons/refresh.gif"
+ id="org.eclipse.tm.tcf.debug.ui.commands.refresh.variables"
+ label="%Refresh.label"
+ style="push">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="menu:org.eclipse.debug.ui.VariableView?after=additions">
+ <menu
+ label="%UpdatePolicy.label"
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.variables">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ <dynamic
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.variables.menu"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.UpdatePolicyMenu"/>
+ </menu>
+ </menuContribution>
+ <!-- Expressions View -->
+ <menuContribution
+ locationURI="toolbar:org.eclipse.debug.ui.ExpressionView?after=additions">
+ <command
+ commandId="org.eclipse.tm.tcf.debug.ui.commands.refresh"
+ icon="icons/refresh.gif"
+ id="org.eclipse.tm.tcf.debug.ui.commands.refresh.expressions"
+ label="%Refresh.label"
+ style="push">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="menu:org.eclipse.debug.ui.ExpressionView?after=additions">
+ <menu
+ label="%UpdatePolicy.label"
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.expressions">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ <dynamic
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.expressions.menu"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.UpdatePolicyMenu"/>
+ </menu>
+ </menuContribution>
+ <!-- Modules View -->
+ <menuContribution
+ locationURI="toolbar:org.eclipse.debug.ui.ModuleView?after=additions">
+ <command
+ commandId="org.eclipse.tm.tcf.debug.ui.commands.refresh"
+ icon="icons/refresh.gif"
+ id="org.eclipse.tm.tcf.debug.ui.commands.refresh.modules"
+ label="%Refresh.label"
+ style="push">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="menu:org.eclipse.debug.ui.ModuleView?after=additions">
+ <menu
+ label="%UpdatePolicy.label"
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.modules">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ <dynamic
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.modules.menu"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.UpdatePolicyMenu"/>
+ </menu>
+ </menuContribution>
+ <!-- Memory View -->
+ <menuContribution
+ locationURI="toolbar:org.eclipse.debug.ui.MemoryView?after=additions">
+ <command
+ commandId="org.eclipse.tm.tcf.debug.ui.commands.refresh"
+ icon="icons/refresh.gif"
+ id="org.eclipse.tm.tcf.debug.ui.commands.refresh.memory"
+ label="%Refresh.label"
+ style="push">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+ <menuContribution
+ locationURI="menu:org.eclipse.debug.ui.MemoryView?after=additions">
+ <menu
+ label="%UpdatePolicy.label"
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.memory">
+ <visibleWhen checkEnabled="false">
+ <with variable="activeContexts">
+ <iterate ifEmpty="false" operator="or">
+ <equals value="org.eclipse.tm.tcf.debug.ui.debugging"/>
+ </iterate>
+ </with>
+ </visibleWhen>
+ <dynamic
+ id="org.eclipse.tm.tcf.debug.ui.commands.update.policy.memory.menu"
+ class="org.eclipse.tm.internal.tcf.debug.ui.commands.UpdatePolicyMenu"/>
+ </menu>
+ </menuContribution>
+ </extension>
+
+ <extension
+ point="org.eclipse.debug.ui.memoryRenderings">
+ <renderingBindings
+ defaultIds="org.eclipse.debug.ui.rendering.raw_memory"
+ primaryId="org.eclipse.debug.ui.rendering.raw_memory"
+ renderingIds="org.eclipse.debug.ui.rendering.raw_memory,org.eclipse.debug.ui.rendering.ascii,org.eclipse.debug.ui.rendering.signedint,org.eclipse.debug.ui.rendering.unsignedint,org.eclipse.debug.ui.rendering.hexint">
+ <enablement>
+ <instanceof value="org.eclipse.tm.internal.tcf.debug.ui.model.TCFMemoryBlockRetrieval$MemoryBlock"/>
+ </enablement>
+ </renderingBindings>
+ </extension>
+
+ <extension point="org.eclipse.debug.ui.debugModelContextBindings">
+ <modelContextBinding
+ contextId="org.eclipse.tm.tcf.debug.ui.debugging"
+ debugModelId="org.eclipse.tm.tcf.debug"/>
+ </extension>
+
+ <extension point="org.eclipse.ui.propertyPages">
+ <page class="org.eclipse.tm.internal.tcf.debug.ui.properties.TCFPropertyPage"
+ id="org.eclipse.tcf.debug.node.propertyPage"
+ name="%propertyPage.name">
+ <filter name="debugModelId" value="org.eclipse.tm.tcf.debug"/>
+ <enabledWhen>
+ <instanceof value="org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode"/>
+ </enabledWhen>
+ </page>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ category="org.eclipse.debug.ui.DebugPreferencePage"
+ class="org.eclipse.tm.internal.tcf.debug.ui.preferences.TCFDebugPreferencePage"
+ id="org.eclipse.tm.internal.tcf.debug.ui.preferences"
+ name="%preferencePage.name">
+ </page>
+ </extension>
+
+ <extension point="org.eclipse.core.runtime.preferences">
+ <initializer class="org.eclipse.tm.internal.tcf.debug.ui.preferences.TCFPreferencesInitializer"/>
+ </extension>
+</plugin>
diff --git a/plugins/org.eclipse.tcf.debug.ui/pom.xml b/plugins/org.eclipse.tcf.debug.ui/pom.xml
new file mode 100644
index 000000000..b38e7fcf3
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.tcf</groupId>
+ <artifactId>tcf-parent</artifactId>
+ <version>0.5.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+
+ <version>0.5.0-SNAPSHOT</version>
+ <artifactId>org.eclipse.tm.tcf.debug.ui</artifactId>
+ <packaging>eclipse-plugin</packaging>
+</project>
diff --git a/plugins/org.eclipse.tcf.debug.ui/schema/launch_context.exsd b/plugins/org.eclipse.tcf.debug.ui/schema/launch_context.exsd
new file mode 100644
index 000000000..473255026
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/schema/launch_context.exsd
@@ -0,0 +1,72 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.tm.tcf">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.tm.tcf.debug.ui" id="launch_context" name="TCF Launch Context"/>
+ </appInfo>
+ <documentation>
+ This extension point is used to register plugins
+ that want to extends TCF Launch Configuration functionality.
+ </documentation>
+
+</annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="class" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="class">
+ <complexType>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ Class should implement ILaunchContext interface
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/Activator.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/Activator.java
new file mode 100644
index 000000000..ae58135e7
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/Activator.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFAnnotationManager;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModelManager;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ public static final String PLUGIN_ID = "org.eclipse.tm.tcf.debug.ui";
+
+ private static final Object lock = new Object();
+
+ private static Activator plugin;
+ private static TCFModelManager model_manager;
+ private static TCFAnnotationManager annotation_manager;
+
+ public void start(BundleContext context) throws Exception {
+ synchronized (lock) {
+ super.start(context);
+ plugin = this;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (model_manager == null) {
+ model_manager = new TCFModelManager();
+ }
+ }
+ });
+ }
+ }
+
+ public void stop(BundleContext context) throws Exception {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ if (model_manager != null) {
+ model_manager.dispose();
+ model_manager = null;
+ }
+ if (annotation_manager != null) {
+ annotation_manager.dispose();
+ annotation_manager = null;
+ }
+ }
+ });
+ synchronized (lock) {
+ plugin = null;
+ super.stop(context);
+ }
+ }
+
+ /**
+ * Returns the shared instance
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ /**
+ * Returns the shared TCFModelManager instance
+ * @return the shared TCFModelManager instance
+ */
+ public static TCFModelManager getModelManager() {
+ assert Protocol.isDispatchThread();
+ if (model_manager == null) model_manager = new TCFModelManager();
+ return model_manager;
+ }
+
+ /**
+ * Returns the shared TCFAnnotationManager instance
+ * @return the shared TCFAnnotationManager instance
+ */
+ public static TCFAnnotationManager getAnnotationManager() {
+ assert Protocol.isDispatchThread();
+ if (annotation_manager == null) annotation_manager = new TCFAnnotationManager();
+ return annotation_manager;
+ }
+
+ /**
+ * Send error message into Eclipse log.
+ * @param msg - error message test
+ * @param err - exception
+ */
+ public static void log(String msg, Throwable err) {
+ synchronized (lock) {
+ if (plugin == null || plugin.getLog() == null) {
+ err.printStackTrace();
+ }
+ else {
+ plugin.getLog().log(new Status(IStatus.ERROR,
+ plugin.getBundle().getSymbolicName(), IStatus.OK, msg, err));
+ }
+ }
+ }
+
+ /**
+ * Send error message into Eclipse log.
+ * @param err - exception
+ */
+ public static void log(Throwable err) {
+ synchronized (lock) {
+ if (plugin == null || plugin.getLog() == null) {
+ err.printStackTrace();
+ }
+ else {
+ plugin.getLog().log(new Status(IStatus.ERROR,
+ plugin.getBundle().getSymbolicName(), IStatus.OK, "Unhandled exception in TCF UI", err));
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java
new file mode 100644
index 000000000..76d445be0
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/ImageCache.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.PlatformUI;
+import org.osgi.framework.Bundle;
+
+public class ImageCache {
+
+ public static final String
+ IMG_TCF = "icons/tcf.gif",
+ IMG_TARGET_TAB = "icons/target_tab.gif",
+ IMG_TARGET_WIZARD = "icons/full/wizban/debug_wiz.png",
+ IMG_ARGUMENTS_TAB = "icons/arguments_tab.gif",
+ IMG_ATTRIBUTE = "icons/attribute.gif",
+ IMG_PATH = "icons/path.gif",
+
+ IMG_THREAD_TERMINATED = "icons/full/obj16/threadt_obj.gif",
+ IMG_THREAD_SUSPENDED = "icons/full/obj16/threads_obj.gif",
+ IMG_THREAD_RUNNNIG = "icons/full/obj16/thread_obj.gif",
+ IMG_THREAD_NOT_ACTIVE = "icons/thread_not_active.gif",
+ IMG_THREAD_UNKNOWN_STATE = "icons/thread_not_active.gif",
+
+ IMG_PROCESS_TERMINATED = "icons/full/obj16/debugtt_obj.gif",
+ IMG_PROCESS_SUSPENDED = "icons/full/obj16/debugts_obj.gif",
+ IMG_PROCESS_RUNNING = "icons/full/obj16/debugt_obj.gif",
+
+ IMG_REGISTER = "icons/full/obj16/genericregister_obj.gif",
+
+ IMG_VARIABLE = "icons/var_simple.gif",
+ IMG_VARIABLE_POINTER = "icons/var_pointer.gif",
+ IMG_VARIABLE_AGGREGATE = "icons/var_aggr.gif",
+
+ IMG_SIGNALS = "icons/signals.gif",
+ IMG_MEMORY_MAP = "icons/memory-map.gif",
+
+ IMG_ARRAY_PARTITION = "icons/full/obj16/arraypartition_obj.gif",
+
+ IMG_STACK_FRAME_SUSPENDED = "icons/full/obj16/stckframe_obj.gif",
+ IMG_STACK_FRAME_RUNNING = "icons/full/obj16/stckframe_running_obj.gif",
+
+ IMG_BREAKPOINT_ENABLED = "icons/full/obj16/brkp_obj.gif",
+ IMG_BREAKPOINT_DISABLED = "icons/full/obj16/brkpd_obj.gif",
+ IMG_BREAKPOINT_INSTALLED = "icons/ovr16/installed_ovr.gif",
+ IMG_BREAKPOINT_CONDITIONAL = "icons/ovr16/conditional_ovr.gif",
+ IMG_BREAKPOINT_WARNING = "icons/ovr16/warning_ovr.gif",
+ IMG_BREAKPOINT_ERROR = "icons/ovr16/error_ovr.gif",
+ IMG_BREAKPOINT_OVERLAY = "icons/brkp_ovr.gif";
+
+ private static final Map<String,ImageDescriptor> desc_cache = new HashMap<String,ImageDescriptor>();
+ private static final Map<ImageDescriptor,Image> image_cache = new HashMap<ImageDescriptor,Image>();
+ private static final Map<String,Map<ImageDescriptor,ImageDescriptor>> overlay_cache =
+ new HashMap<String,Map<ImageDescriptor,ImageDescriptor>>();
+
+ public static synchronized ImageDescriptor getImageDescriptor(String name) {
+ if (name == null) return null;
+ ImageDescriptor descriptor = desc_cache.get(name);
+ if (descriptor == null) {
+ Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
+ if (bundle != null){
+ URL url = FileLocator.find(bundle, new Path(name), null);
+ if (url != null) descriptor = ImageDescriptor.createFromURL(url);
+ }
+ if (descriptor == null) {
+ bundle = Platform.getBundle("org.eclipse.debug.ui");
+ if (bundle != null){
+ URL url = FileLocator.find(bundle, new Path(name), null);
+ if (url != null) descriptor = ImageDescriptor.createFromURL(url);
+ }
+ }
+ if (descriptor == null) {
+ bundle = Platform.getBundle("org.eclipse.cdt.debug.ui");
+ if (bundle != null){
+ URL url = FileLocator.find(bundle, new Path(name), null);
+ if (url != null) descriptor = ImageDescriptor.createFromURL(url);
+ }
+ }
+ if (descriptor == null) {
+ descriptor = PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(name);
+ }
+ if (descriptor == null) {
+ descriptor = ImageDescriptor.getMissingImageDescriptor();
+ }
+ desc_cache.put(name, descriptor);
+ }
+ return descriptor;
+ }
+
+ public static synchronized ImageDescriptor addOverlay(ImageDescriptor descriptor, String name) {
+ return addOverlay(descriptor, name, 0, 0);
+ }
+
+ public static synchronized ImageDescriptor addOverlay(
+ ImageDescriptor descriptor, String name, final int x, final int y) {
+ if (descriptor == null || name == null) return descriptor;
+ String key = name + ':' + x + ':' + y;
+ Map<ImageDescriptor,ImageDescriptor> map = overlay_cache.get(key);
+ if (map == null) overlay_cache.put(key, map = new HashMap<ImageDescriptor,ImageDescriptor>());
+ ImageDescriptor res = map.get(descriptor);
+ if (res != null) return res;
+ final ImageData base = descriptor.getImageData();
+ final ImageData overlay = getImageDescriptor(name).getImageData();
+ res = new CompositeImageDescriptor() {
+ @Override
+ protected void drawCompositeImage(int width, int height) {
+ drawImage(base, 0, 0);
+ drawImage(overlay, x, y);
+ }
+ @Override
+ protected Point getSize() {
+ return new Point(base.width, base.height);
+ }
+ };
+ map.put(descriptor, res);
+ return res;
+ }
+
+ public static synchronized Image getImage(ImageDescriptor desc) {
+ Image image = image_cache.get(desc);
+ if (image == null) {
+ image = desc.createImage();
+ image_cache.put(desc, image);
+ }
+ return image;
+ }
+
+ public static synchronized Image getImage(String name) {
+ return getImage(getImageDescriptor(name));
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFLaunchAdapterFactory.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFLaunchAdapterFactory.java
new file mode 100644
index 000000000..7bb5dc9b9
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFLaunchAdapterFactory.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.adapters;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory;
+import org.eclipse.debug.ui.contexts.ISuspendTrigger;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+
+public class TCFLaunchAdapterFactory implements IAdapterFactory {
+
+ private static final Class<?>[] adapter_list = {
+ IElementLabelProvider.class,
+ IElementContentProvider.class,
+ IModelProxyFactory.class,
+ ISuspendTrigger.class,
+ };
+
+ private static final IElementLabelProvider launch_label_provider = new TCFLaunchLabelProvider();
+
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter(final Object from, final Class to) {
+ if (from instanceof TCFLaunch) {
+ if (to == IElementLabelProvider.class) return launch_label_provider;
+ return new TCFTask<Object>() {
+ public void run() {
+ TCFLaunch launch = (TCFLaunch)from;
+ TCFModel model = Activator.getModelManager().getModel(launch);
+ if (model != null && to.isInstance(model)) {
+ done(model);
+ return;
+ }
+ done(null);
+ }
+ }.getE();
+ }
+ return null;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Class[] getAdapterList() {
+ return adapter_list;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFLaunchLabelProvider.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFLaunchLabelProvider.java
new file mode 100644
index 000000000..701cfecfc
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFLaunchLabelProvider.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.adapters;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.tcf.services.IProcesses;
+
+class TCFLaunchLabelProvider implements IElementLabelProvider {
+
+ public void update(ILabelUpdate[] updates) {
+ for (int i = 0; i < updates.length; i++) {
+ ILabelUpdate result = updates[i];
+ final TCFLaunch launch = (TCFLaunch)result.getElement();
+ ImageDescriptor image = DebugUITools.getDefaultImageDescriptor(launch);
+ if (image == null) image = ImageCache.getImageDescriptor(ImageCache.IMG_TCF);
+ result.setImageDescriptor(image, 0);
+ String status = "";
+ if (launch.isConnecting()) {
+ status = "Connecting";
+ }
+ else if (launch.isDisconnected()) {
+ status = "Disconnected";
+ }
+ String peer_name = launch.getPeerName();
+ if (peer_name != null) {
+ if (status.length() == 0) status = peer_name;
+ else status = peer_name + ": " + status;
+ }
+ if (status.length() > 0) status = " (" + status + ")";
+ Throwable error = launch.getError();
+ if (error != null) {
+ status += ": " + TCFModel.getErrorMessage(error, false);
+ result.setForeground(new RGB(255, 0, 0), 0);
+ }
+ else if (launch.isExited()) {
+ status += ": Exited";
+ int code = launch.getExitCode();
+ if (code > 0) status += ", exit code " + code;
+ if (code < 0) {
+ status += ", signal " + (-code);
+ Collection<Map<String,Object>> sigs = launch.getSignalList();
+ if (sigs != null) {
+ for (Map<String,Object> m : sigs) {
+ Number num = (Number)m.get(IProcesses.SIG_CODE);
+ if (num == null) continue;
+ if (num.intValue() != -code) continue;
+ String s = (String)m.get(IProcesses.SIG_NAME);
+ if (s == null) continue;
+ status += " (" + s + ")";
+ break;
+ }
+ }
+ }
+ }
+ String name = "?";
+ ILaunchConfiguration cfg = launch.getLaunchConfiguration();
+ if (cfg != null) name = cfg.getName();
+ result.setLabel(name + status, 0);
+ result.done();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFNodeAdapterFactory.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFNodeAdapterFactory.java
new file mode 100644
index 000000000..e426c6174
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFNodeAdapterFactory.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.adapters;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension;
+import org.eclipse.tm.internal.tcf.debug.ui.commands.BreakpointCommand;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.ui.views.properties.IPropertySource;
+
+
+public class TCFNodeAdapterFactory implements IAdapterFactory {
+
+ private static final Class<?>[] adapter_list = {
+ IToggleBreakpointsTarget.class,
+ IToggleBreakpointsTargetExtension.class,
+ IPropertySource.class,
+ };
+
+ private final BreakpointCommand breakpoint_command = new BreakpointCommand();
+
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter(Object obj, Class cls) {
+ if (obj instanceof TCFNode) {
+ if (cls == IToggleBreakpointsTarget.class) return breakpoint_command;
+ if (cls == IToggleBreakpointsTargetExtension.class) return breakpoint_command;
+ if (cls == IPropertySource.class) return new TCFNodePropertySource((TCFNode) obj);
+ }
+ return null;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Class[] getAdapterList() {
+ return adapter_list;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFNodePropertySource.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFNodePropertySource.java
new file mode 100644
index 000000000..918090087
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/adapters/TCFNodePropertySource.java
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.adapters;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext.MemoryRegion;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.IStackTrace;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.ui.views.properties.PropertyDescriptor;
+
+/**
+ * Adapts TCFNode to IPropertySource.
+ */
+public class TCFNodePropertySource implements IPropertySource {
+
+ private final TCFNode fNode;
+ private final Map<String, Object> fProperties = new HashMap<String, Object>();
+ private IPropertyDescriptor[] fDescriptors;
+
+ public TCFNodePropertySource(TCFNode node) {
+ fNode = node;
+ }
+
+ public Object getEditableValue() {
+ return null;
+ }
+
+ public IPropertyDescriptor[] getPropertyDescriptors() {
+ if (fDescriptors == null) {
+ try {
+ final List<IPropertyDescriptor> descriptors = new ArrayList<IPropertyDescriptor>();
+ fDescriptors = new TCFTask<IPropertyDescriptor[]>(fNode.getChannel()) {
+ public void run() {
+ if (fNode instanceof TCFNodeExecContext) {
+ getExecContextDescriptors((TCFNodeExecContext) fNode);
+ } else if (fNode instanceof TCFNodeStackFrame) {
+ getFrameDescriptors((TCFNodeStackFrame) fNode);
+ } else {
+ done(descriptors.toArray(new IPropertyDescriptor[descriptors.size()]));
+ }
+ }
+
+ private void getFrameDescriptors(TCFNodeStackFrame frameNode) {
+ TCFDataCache<IStackTrace.StackTraceContext> ctx_cache = frameNode.getStackTraceContext();
+ TCFDataCache<TCFSourceRef> line_info_cache = frameNode.getLineInfo();
+ if (!validateAll(ctx_cache, line_info_cache)) return;
+ IStackTrace.StackTraceContext ctx = ctx_cache.getData();
+ if (ctx != null) {
+ Map<String, Object> props = ctx.getProperties();
+ for (String key : props.keySet()) {
+ Object value = props.get(key);
+ if (value instanceof Number) {
+ value = toHexAddrString((Number) value);
+ }
+ addDescriptor("Context", key, value);
+ }
+ }
+ TCFSourceRef sourceRef = line_info_cache.getData();
+ if (sourceRef != null) {
+ if (sourceRef.area != null) {
+ addDescriptor("Source", "Directory", sourceRef.area.directory);
+ addDescriptor("Source", "File", sourceRef.area.file);
+ addDescriptor("Source", "Line", sourceRef.area.start_line);
+ }
+ if (sourceRef.error != null) {
+ addDescriptor("Source", "Error", sourceRef.error);
+ }
+ }
+ done(descriptors.toArray(new IPropertyDescriptor[descriptors.size()]));
+ }
+ private void getExecContextDescriptors(TCFNodeExecContext exeNode) {
+ TCFDataCache<IRunControl.RunControlContext> ctx_cache = exeNode.getRunContext();
+ TCFDataCache<TCFContextState> state_cache = exeNode.getState();
+ TCFDataCache<MemoryRegion[]> mem_map_cache = exeNode.getMemoryMap();
+ if (!validateAll(ctx_cache, state_cache, mem_map_cache)) return;
+ IRunControl.RunControlContext ctx = ctx_cache.getData();
+ if (ctx != null) {
+ Map<String, Object> props = ctx.getProperties();
+ for (String key : props.keySet()) {
+ Object value = props.get(key);
+ if (value instanceof Number) {
+ value = toHexAddrString((Number) value);
+ }
+ addDescriptor("Context", key, value);
+ }
+ }
+ TCFContextState state = state_cache.getData();
+ if (state != null) {
+ addDescriptor("State", "Suspended", state.is_suspended);
+ if (state.is_suspended) {
+ addDescriptor("State", "Suspend reason", state.suspend_reason);
+ addDescriptor("State", "PC", toHexAddrString(new BigInteger(state.suspend_pc)));
+ }
+ addDescriptor("State", "Active", !exeNode.isNotActive());
+ }
+ MemoryRegion[] mem_map = mem_map_cache.getData();
+ if (mem_map != null && mem_map.length > 0) {
+ int idx = 0;
+ for (MemoryRegion region : mem_map) {
+ Map<String, Object> props = region.region.getProperties();
+ for (String key : props.keySet()) {
+ Object value = props.get(key);
+ if (value instanceof Number) {
+ value = toHexAddrString((Number) value);
+ }
+ addDescriptor("MemoryRegion["+idx+']', key, value);
+ }
+ idx++;
+ }
+ }
+ done(descriptors.toArray(new IPropertyDescriptor[descriptors.size()]));
+ }
+ private void addDescriptor(String category, String key, Object value) {
+ String id = category + '.' + key;
+ PropertyDescriptor desc = new PropertyDescriptor(id, key);
+ desc.setCategory(category);
+ descriptors.add(desc);
+ fProperties.put(id, value);
+ }
+ boolean validateAll(TCFDataCache<?> ... caches) {
+ TCFDataCache<?> pending = null;
+ for (TCFDataCache<?> cache : caches) {
+ if (!cache.validate()) {
+ pending = cache;
+ }
+ }
+ if (pending != null) {
+ pending.wait(this);
+ return false;
+ }
+ return true;
+ }
+ }.get(5, TimeUnit.SECONDS);
+ }
+ catch (Exception e) {
+ Activator.log("Error retrieving property data", e);
+ fDescriptors = new IPropertyDescriptor[0];
+ }
+ }
+ return fDescriptors;
+ }
+
+ public Object getPropertyValue(final Object id) {
+ return fProperties.get(id);
+ }
+
+ public boolean isPropertySet(Object id) {
+ return false;
+ }
+
+ public void resetPropertyValue(Object id) {
+ }
+
+ public void setPropertyValue(Object id, Object value) {
+ }
+
+ private static String toHexAddrString(Number num) {
+ BigInteger n = JSON.toBigInteger(num);
+ String s = n.toString(16);
+ int sz = s.length() > 8 ? 16 : 8;
+ int l = sz - s.length();
+ if (l < 0) l = 0;
+ if (l > 16) l = 16;
+ return "0x0000000000000000".substring(0, 2 + l) + s;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/AbstractActionDelegate.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/AbstractActionDelegate.java
new file mode 100644
index 000000000..d46939ca3
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/AbstractActionDelegate.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.util.ArrayList;
+
+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.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IActionDelegate2;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IViewActionDelegate;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.IWorkbenchWindowActionDelegate;
+
+public abstract class AbstractActionDelegate
+implements IViewActionDelegate, IActionDelegate2, IWorkbenchWindowActionDelegate, IObjectActionDelegate {
+
+ private IAction action;
+ private IViewPart view;
+ private IWorkbenchWindow window;
+ private ISelection selection;
+
+ public void init(IAction action) {
+ this.action = action;
+ }
+
+ public void init(IViewPart view) {
+ this.view = view;
+ }
+
+ public void init(IWorkbenchWindow window) {
+ this.window = window;
+ }
+
+ public void dispose() {
+ action = null;
+ view = null;
+ window = null;
+ }
+
+ public void setActivePart(IAction action, IWorkbenchPart part) {
+ this.action = action;
+ view = null;
+ if (part instanceof IViewPart) view = (IViewPart)part;
+ window = part.getSite().getWorkbenchWindow();
+ }
+
+ public void run(IAction action) {
+ IAction action0 = this.action;
+ try {
+ this.action = action;
+ run();
+ }
+ finally {
+ this.action = action0;
+ }
+ }
+
+ public void runWithEvent(IAction action, Event event) {
+ run(action);
+ }
+
+ public void selectionChanged(IAction action, ISelection selection) {
+ this.selection = selection;
+ IAction action0 = this.action;
+ try {
+ this.action = action;
+ selectionChanged();
+ }
+ finally {
+ this.action = action0;
+ }
+ }
+
+ public IAction getAction() {
+ return action;
+ }
+
+ public IViewPart getView() {
+ return view;
+ }
+
+ public IWorkbenchWindow getWindow() {
+ if (view != null) return view.getSite().getWorkbenchWindow();
+ if (window != null) return window;
+ return null;
+ }
+
+ public ISelection getSelection() {
+ return selection;
+ }
+
+ public TCFNode getSelectedNode() {
+ if (selection instanceof IStructuredSelection) {
+ final Object o = ((IStructuredSelection)selection).getFirstElement();
+ if (o instanceof TCFNode) return (TCFNode)o;
+ if (o instanceof TCFLaunch) {
+ return new TCFTask<TCFNode>() {
+ public void run() {
+ TCFLaunch launch = (TCFLaunch)o;
+ TCFModel model = Activator.getModelManager().getModel(launch);
+ if (model != null) {
+ done(model.getRootNode());
+ }
+ else {
+ done(null);
+ }
+ }
+ }.getE();
+ }
+ }
+ return null;
+ }
+
+ public TCFNode[] getSelectedNodes() {
+ ArrayList<TCFNode> list = new ArrayList<TCFNode>();
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection s = (IStructuredSelection)selection;
+ if (s.size() > 0) {
+ for (final Object o : s.toArray()) {
+ if (o instanceof TCFNode) {
+ list.add((TCFNode)o);
+ }
+ else if (o instanceof TCFLaunch) {
+ list.add(new TCFTask<TCFNode>() {
+ public void run() {
+ TCFLaunch launch = (TCFLaunch)o;
+ TCFModel model = Activator.getModelManager().getModel(launch);
+ if (model != null) {
+ done(model.getRootNode());
+ }
+ else {
+ done(null);
+ }
+ }
+ }.getE());
+ }
+ }
+ }
+ }
+ return list.toArray(new TCFNode[list.size()]);
+ }
+
+ protected abstract void selectionChanged();
+
+ protected abstract void run();
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackIntoCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackIntoCommand.java
new file mode 100644
index 000000000..15bbe73c3
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackIntoCommand.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFActionStepInto;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+public class BackIntoCommand extends StepCommand {
+
+ private static class StepStateMachine extends TCFActionStepInto {
+
+ private final IDebugCommandRequest monitor;
+ private final Runnable done;
+ private final TCFNodeExecContext node;
+
+ StepStateMachine(TCFModel model, IDebugCommandRequest monitor,
+ IRunControl.RunControlContext ctx, boolean src_step, Runnable done) {
+ super(model.getLaunch(), ctx, src_step, true);
+ this.monitor = monitor;
+ this.done = done;
+ node = (TCFNodeExecContext)model.getNode(ctx.getID());
+ }
+
+ @Override
+ protected TCFDataCache<TCFContextState> getContextState() {
+ if (node == null) return null;
+ return node.getState();
+ }
+
+ @Override
+ protected TCFDataCache<TCFSourceRef> getLineInfo() {
+ TCFNodeStackFrame frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return null;
+ return frame.getLineInfo();
+ }
+
+ @Override
+ protected TCFDataCache<?> getStackTrace() {
+ return node.getStackTrace();
+ }
+
+ @Override
+ protected void exit(Throwable error) {
+ if (exited) return;
+ super.exit(error);
+ if (error != null && node.getChannel().getState() == IChannel.STATE_OPEN) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, 0, "Cannot step: " + error.getLocalizedMessage(), error));
+ }
+ done.run();
+ }
+ }
+
+ public BackIntoCommand(TCFModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean canExecute(IRunControl.RunControlContext ctx) {
+ if (ctx == null) return false;
+ if (ctx.canResume(IRunControl.RM_REVERSE_STEP_INTO_LINE)) return true;
+ if (ctx.canResume(IRunControl.RM_REVERSE_STEP_INTO)) return true;
+ return false;
+ }
+
+ @Override
+ protected void execute(final IDebugCommandRequest monitor, final IRunControl.RunControlContext ctx,
+ boolean src_step, final Runnable done) {
+ new StepStateMachine(model, monitor, ctx, src_step, done);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackOverCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackOverCommand.java
new file mode 100644
index 000000000..35e4af1e8
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackOverCommand.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFActionStepOver;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.IStackTrace.StackTraceContext;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+public class BackOverCommand extends StepCommand {
+
+ private static class StepStateMachine extends TCFActionStepOver {
+
+ private final IDebugCommandRequest monitor;
+ private final Runnable done;
+ private final TCFNodeExecContext node;
+ private TCFNodeStackFrame frame;
+
+ StepStateMachine(TCFModel model, IDebugCommandRequest monitor,
+ IRunControl.RunControlContext ctx,
+ boolean src_step, Runnable done) {
+ super(model.getLaunch(), ctx, src_step, true);
+ this.monitor = monitor;
+ this.done = done;
+ node = (TCFNodeExecContext)model.getNode(ctx.getID());
+ }
+
+ @Override
+ protected TCFDataCache<TCFContextState> getContextState() {
+ if (node == null) return null;
+ return node.getState();
+ }
+
+ @Override
+ protected TCFDataCache<TCFSourceRef> getLineInfo() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return null;
+ return frame.getLineInfo();
+ }
+
+ @Override
+ protected TCFDataCache<StackTraceContext> getStackFrame() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return null;
+ return frame.getStackTraceContext();
+ }
+
+ @Override
+ protected int getStackFrameIndex() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return 0;
+ return frame.getFrameNo();
+ }
+
+ @Override
+ protected TCFDataCache<?> getStackTrace() {
+ return node.getStackTrace();
+ }
+
+ @Override
+ protected void exit(Throwable error) {
+ if (exited) return;
+ super.exit(error);
+ if (error != null && node.getChannel().getState() == IChannel.STATE_OPEN) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, 0, "Cannot step: " + error.getLocalizedMessage(), error));
+ }
+ done.run();
+ }
+ }
+
+ public BackOverCommand(TCFModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean canExecute(IRunControl.RunControlContext ctx) {
+ if (ctx == null) return false;
+ if (ctx.canResume(IRunControl.RM_REVERSE_STEP_OVER_LINE)) return true;
+ if (ctx.canResume(IRunControl.RM_REVERSE_STEP_OVER)) return true;
+ if (ctx.canResume(IRunControl.RM_REVERSE_STEP_INTO) && model.getLaunch().getService(IBreakpoints.class) != null) return true;
+ return false;
+ }
+
+ @Override
+ protected void execute(final IDebugCommandRequest monitor, final IRunControl.RunControlContext ctx,
+ boolean src_step, final Runnable done) {
+ new StepStateMachine(model, monitor, ctx, src_step, done);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackResumeCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackResumeCommand.java
new file mode 100644
index 000000000..051883bc8
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackResumeCommand.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFAction;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IRunControl;
+
+public class BackResumeCommand extends StepCommand {
+
+ public BackResumeCommand(TCFModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean canExecute(IRunControl.RunControlContext ctx) {
+ return ctx.canResume(IRunControl.RM_REVERSE_RESUME);
+ }
+
+ @Override
+ protected void execute(final IDebugCommandRequest monitor,
+ final IRunControl.RunControlContext ctx, boolean src_step, final Runnable done) {
+ new TCFAction(model.getLaunch(), ctx.getID()) {
+ public void run() {
+ ctx.resume(IRunControl.RM_REVERSE_RESUME, 1, new IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null && model.getChannel().getState() == IChannel.STATE_OPEN) {
+ if (error instanceof IErrorReport) {
+ IErrorReport r = (IErrorReport)error;
+ if (r.getErrorCode() == IErrorReport.TCF_ERROR_ALREADY_RUNNING) {
+ done();
+ return;
+ }
+ }
+ launch.removeContextActions(getContextID());
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, IStatus.OK, "Cannot resume: " + error.getLocalizedMessage(), error));
+ }
+ done();
+ }
+ });
+ }
+ public void done() {
+ super.done();
+ done.run();
+ }
+ };
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackReturnCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackReturnCommand.java
new file mode 100644
index 000000000..604a131f0
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BackReturnCommand.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFActionStepOut;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.IStackTrace.StackTraceContext;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+public class BackReturnCommand extends StepCommand {
+
+ private static class StepStateMachine extends TCFActionStepOut {
+
+ private final IDebugCommandRequest monitor;
+ private final Runnable done;
+ private final TCFNodeExecContext node;
+ private TCFNodeStackFrame frame;
+
+ StepStateMachine(TCFModel model, IDebugCommandRequest monitor,
+ IRunControl.RunControlContext ctx, Runnable done) {
+ super(model.getLaunch(), ctx, true);
+ this.monitor = monitor;
+ this.done = done;
+ node = (TCFNodeExecContext)model.getNode(ctx.getID());
+ }
+
+ @Override
+ protected TCFDataCache<TCFContextState> getContextState() {
+ if (node == null) return null;
+ return node.getState();
+ }
+
+ @Override
+ protected TCFDataCache<StackTraceContext> getStackFrame() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return null;
+ return frame.getStackTraceContext();
+ }
+
+ @Override
+ protected int getStackFrameIndex() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return 0;
+ return frame.getFrameNo();
+ }
+
+ @Override
+ protected TCFDataCache<?> getStackTrace() {
+ return node.getStackTrace();
+ }
+
+ @Override
+ protected void exit(Throwable error) {
+ if (exited) return;
+ super.exit(error);
+ if (error != null && node.getChannel().getState() == IChannel.STATE_OPEN) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, 0, "Cannot step: " + error.getLocalizedMessage(), error));
+ }
+ done.run();
+ }
+ }
+
+ public BackReturnCommand(TCFModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean canExecute(IRunControl.RunControlContext ctx) {
+ if (ctx == null) return false;
+ if (ctx.canResume(IRunControl.RM_REVERSE_STEP_OUT)) return true;
+ if (!ctx.hasState()) return false;
+ if (ctx.canResume(IRunControl.RM_REVERSE_RESUME) && model.getLaunch().getService(IBreakpoints.class) != null) return true;
+ return false;
+ }
+
+ @Override
+ protected void execute(final IDebugCommandRequest monitor, final IRunControl.RunControlContext ctx,
+ boolean src_step, final Runnable done) {
+ new StepStateMachine(model, monitor, ctx, done);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BreakpointCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BreakpointCommand.java
new file mode 100644
index 000000000..83fd1ffe8
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/BreakpointCommand.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpoint;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IWorkbenchPart;
+
+
+public class BreakpointCommand implements IToggleBreakpointsTargetExtension {
+
+ public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) {
+ if (selection.isEmpty()) return false;
+ final Object obj = ((IStructuredSelection)selection).getFirstElement();
+ return new TCFTask<Boolean>() {
+ public void run() {
+ TCFDataCache<BigInteger> addr_cache = null;
+ if (obj instanceof TCFNodeExecContext) addr_cache = ((TCFNodeExecContext)obj).getAddress();
+ if (obj instanceof TCFNodeStackFrame) addr_cache = ((TCFNodeStackFrame)obj).getAddress();
+ if (addr_cache != null) {
+ if (!addr_cache.validate(this)) return;
+ done(addr_cache.getData() != null);
+ }
+ else {
+ done(false);
+ }
+ }
+ }.getE();
+ }
+
+ public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) {
+ if (selection.isEmpty()) return;
+ final Object obj = ((IStructuredSelection)selection).getFirstElement();
+ new TCFTask<Object>() {
+ public void run() {
+ TCFDataCache<BigInteger> addr_cache = null;
+ if (obj instanceof TCFNodeExecContext) addr_cache = ((TCFNodeExecContext)obj).getAddress();
+ if (obj instanceof TCFNodeStackFrame) addr_cache = ((TCFNodeStackFrame)obj).getAddress();
+ if (addr_cache != null) {
+ if (!addr_cache.validate(this)) return;
+ BigInteger addr = addr_cache.getData();
+ if (addr != null) {
+ Map<String,Object> m = new HashMap<String,Object>();
+ m.put(IBreakpoints.PROP_ENABLED, Boolean.TRUE);
+ m.put(IBreakpoints.PROP_LOCATION, addr.toString());
+ TCFBreakpoint.createFromTCFProperties(m);
+ }
+ }
+ done(null);
+ }
+ }.getE();
+ }
+
+ public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return false;
+ }
+
+ public void toggleLineBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ // TODO: breakpoint command: toggle line breakpoint
+ }
+
+ public boolean canToggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) {
+ return false;
+ }
+
+ public void toggleMethodBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ }
+
+ public boolean canToggleWatchpoints(IWorkbenchPart part, ISelection selection) {
+ return false;
+ }
+
+ public void toggleWatchpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
+ // TODO: breakpoint command: toggle watchpoint
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/CastToArrayCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/CastToArrayCommand.java
new file mode 100644
index 000000000..3f2e9db95
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/CastToArrayCommand.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.internal.tcf.debug.ui.model.ICastToType;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ISymbols;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IWorkbenchWindow;
+
+public class CastToArrayCommand extends AbstractActionDelegate {
+
+ private class CastToTypeInputValidator implements IInputValidator {
+
+ public CastToTypeInputValidator() {
+ }
+
+ public String isValid(String new_text) {
+ try {
+ if (new_text.length() == 0) return "";
+ int i = Integer.parseInt(new_text);
+ if (i < 1) return "Array length must be >= 1";
+ }
+ catch (Exception x) {
+ return "Invalid number";
+ }
+ return null;
+ }
+ }
+
+ private class CastToTypeDialog extends InputDialog {
+
+ public CastToTypeDialog(Shell shell, String initial_value) {
+ super(shell, "Cast To Array", "Enter array length",
+ initial_value, new CastToTypeInputValidator() );
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setImage(ImageCache.getImage(ImageCache.IMG_TCF));
+ }
+ }
+
+ @Override
+ protected void run() {
+ final TCFNode node = getCastToTypeNode();
+ if (node == null) return;
+ IWorkbenchWindow window = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow();
+ if (window == null) return;
+ final String base_type_name = getBaseTypeName();
+ if (base_type_name == null) return;
+ CastToTypeDialog dialog = new CastToTypeDialog(window.getShell(), node.getModel().getCastToType(node.getID()));
+ if (dialog.open() != Window.OK) return;
+ final String new_type = dialog.getValue().trim();
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ node.getModel().setCastToType(node.getID(), base_type_name + "[" + new_type + "]");
+ }
+ });
+ }
+
+ private String getBaseTypeName() {
+ final TCFNode node = getCastToTypeNode();
+ if (node == null) return null;
+ return new TCFTask<String>(node.getChannel()) {
+ public void run() {
+ TCFDataCache<ISymbols.Symbol> type_cache = ((ICastToType)node).getType();
+ if (!type_cache.validate(this)) return;
+ ISymbols.Symbol type_data = type_cache.getData();
+ if (type_data == null || type_data.getTypeClass() != ISymbols.TypeClass.pointer) {
+ done(null);
+ }
+ else {
+ String ptrs = "****";
+ for (int i = 0; i <= ptrs.length(); i++) {
+ TCFDataCache<ISymbols.Symbol> base_type_cache = node.getModel().getSymbolInfoCache(type_data.getBaseTypeID());
+ if (!base_type_cache.validate(this)) return;
+ ISymbols.Symbol base_type_data = base_type_cache.getData();
+ if (base_type_data == null) {
+ done(null);
+ return;
+ }
+ else {
+ if (base_type_data.getName() != null) {
+ done(base_type_data.getName() + ptrs.substring(0, i));
+ return;
+ }
+ else if (base_type_data.getTypeClass() == ISymbols.TypeClass.pointer) {
+ type_data = base_type_data;
+ }
+ else if (!base_type_data.getID().equals(base_type_data.getTypeID())) {
+ // modified type without name, like "volatile int"
+ base_type_cache = node.getModel().getSymbolInfoCache(base_type_data.getTypeID());
+ if (!base_type_cache.validate(this)) return;
+ base_type_data = base_type_cache.getData();
+ if (base_type_data != null && base_type_data.getName() != null) {
+ done(base_type_data.getName() + ptrs.substring(0, i));
+ }
+ else {
+ done(null);
+ }
+ return;
+ }
+ else {
+ done(null);
+ return;
+ }
+ }
+ }
+ }
+ }
+ }.getE();
+ }
+
+ @Override
+ protected void selectionChanged() {
+ getAction().setEnabled(getBaseTypeName() != null);
+ }
+
+ private TCFNode getCastToTypeNode() {
+ TCFNode node = getSelectedNode();
+ if (node instanceof ICastToType) return node;
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/CastToTypeCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/CastToTypeCommand.java
new file mode 100644
index 000000000..48e7bdb98
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/CastToTypeCommand.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.internal.tcf.debug.ui.model.ICastToType;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.ui.IWorkbenchWindow;
+
+public class CastToTypeCommand extends AbstractActionDelegate {
+
+ private class CastToTypeInputValidator implements IInputValidator {
+
+ public CastToTypeInputValidator() {
+ }
+
+ public String isValid(String new_text) {
+ return null;
+ }
+ }
+
+ private class CastToTypeDialog extends InputDialog {
+
+ public CastToTypeDialog(Shell shell, String initial_value) {
+ super(shell, "Cast To Type", "Enter type name",
+ initial_value, new CastToTypeInputValidator() );
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setImage(ImageCache.getImage(ImageCache.IMG_TCF));
+ }
+ }
+
+ @Override
+ protected void run() {
+ final TCFNode node = getCastToTypeNode();
+ if (node == null) return;
+ IWorkbenchWindow window = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow();
+ if (window == null) return;
+ CastToTypeDialog dialog = new CastToTypeDialog(window.getShell(), node.getModel().getCastToType(node.getID()));
+ if (dialog.open() != Window.OK) return;
+ final String new_type = dialog.getValue().trim();
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ node.getModel().setCastToType(node.getID(), new_type);
+ }
+ });
+ }
+
+ @Override
+ protected void selectionChanged() {
+ getAction().setEnabled(getCastToTypeNode() != null);
+ }
+
+ private TCFNode getCastToTypeNode() {
+ TCFNode node = getSelectedNode();
+ if (node instanceof ICastToType) return node;
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DisconnectCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DisconnectCommand.java
new file mode 100644
index 000000000..eb79092f8
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DisconnectCommand.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IDisconnectHandler;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.tm.internal.tcf.debug.model.TCFError;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
+
+
+public class DisconnectCommand implements IDisconnectHandler {
+
+ private final TCFModel model;
+
+ public DisconnectCommand(TCFModel model) {
+ this.model = model;
+ }
+
+ public void canExecute(final IEnabledStateRequest monitor) {
+ new TCFRunnable(monitor) {
+ public void run() {
+ monitor.setEnabled(model.getLaunch().canDisconnect());
+ monitor.setStatus(Status.OK_STATUS);
+ done();
+ }
+ };
+ }
+
+ public boolean execute(final IDebugCommandRequest monitor) {
+ new TCFRunnable(monitor) {
+ public void run() {
+ try {
+ model.getLaunch().closeChannel();
+ monitor.setStatus(Status.OK_STATUS);
+ }
+ catch (Throwable x) {
+ monitor.setStatus(new TCFError(x).getStatus());
+ }
+ done();
+ }
+ };
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DropToFrameCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DropToFrameCommand.java
new file mode 100644
index 000000000..b4efec179
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/DropToFrameCommand.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.util.Map;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IDropToFrameHandler;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFActionStepOut;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.IRunControl.RunControlContext;
+import org.eclipse.tm.tcf.services.IStackTrace.StackTraceContext;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+/**
+ * Drop-to-frame command handler for TCF.
+ */
+public class DropToFrameCommand implements IDropToFrameHandler {
+
+ private static class StepStateMachine extends TCFActionStepOut {
+
+ private final IDebugCommandRequest monitor;
+ private final Runnable done;
+ private final TCFNodeExecContext node;
+ private final TCFNodeStackFrame frame;
+
+ StepStateMachine(TCFModel model, IDebugCommandRequest monitor,
+ IRunControl.RunControlContext ctx, TCFNodeStackFrame frame, Runnable done) {
+ super(model.getLaunch(), ctx, false);
+ this.monitor = monitor;
+ this.done = done;
+ this.frame = frame;
+ this.node = (TCFNodeExecContext)frame.getParent();
+ }
+
+ @Override
+ protected TCFDataCache<TCFContextState> getContextState() {
+ return node.getState();
+ }
+
+ @Override
+ protected TCFDataCache<StackTraceContext> getStackFrame() {
+ return frame.getStackTraceContext();
+ }
+
+ @Override
+ protected int getStackFrameIndex() {
+ return frame.getFrameNo();
+ }
+
+ @Override
+ protected TCFDataCache<?> getStackTrace() {
+ return node.getStackTrace();
+ }
+
+ protected void exit(Throwable error) {
+ exit(error, "Drop To Frame");
+ }
+
+ @Override
+ protected void exit(Throwable error, String reason) {
+ if (exited) return;
+ super.exit(error, reason);
+ if (error != null && node.getChannel().getState() == IChannel.STATE_OPEN) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, 0, "Cannot drop to frame: " + error.getLocalizedMessage(), error));
+ }
+ if (aborted) {
+ monitor.setStatus(Status.CANCEL_STATUS);
+ }
+ done.run();
+ }
+ }
+
+ private final TCFModel model;
+
+ public DropToFrameCommand(TCFModel tcfModel) {
+ model = tcfModel;
+ }
+
+ public void canExecute(final IEnabledStateRequest request) {
+ final Object[] elements = request.getElements();
+ if (elements.length != 1 || !(elements[0] instanceof TCFNodeStackFrame)) {
+ request.setEnabled(false);
+ request.done();
+ return;
+ }
+ final TCFNodeStackFrame frameNode = (TCFNodeStackFrame) elements[0];
+ new TCFRunnable(request) {
+ public void run() {
+ if (frameNode.getFrameNo() < 1) {
+ request.setEnabled(false);
+ done();
+ return;
+ }
+ TCFNodeExecContext exeNode = (TCFNodeExecContext) frameNode.getParent();
+ TCFDataCache<IRunControl.RunControlContext> ctx_cache = exeNode.getRunContext();
+ if (!ctx_cache.validate(this)) {
+ return;
+ }
+ IRunControl.RunControlContext ctx = ctx_cache.getData();
+ if (!canStepOut(ctx)) {
+ request.setEnabled(false);
+ done();
+ return;
+ }
+ int action_cnt = model.getLaunch().getContextActionsCount(ctx.getID());
+ if (action_cnt > 0 || !canStepOut(ctx)) {
+ request.setEnabled(false);
+ done();
+ return;
+ }
+ TCFDataCache<TCFContextState> state_cache = exeNode.getState();
+ if (!state_cache.validate(this)) {
+ return;
+ }
+ TCFContextState state_data = state_cache.getData();
+ request.setEnabled(state_data != null && state_data.is_suspended);
+ done();
+ }
+
+ private boolean canStepOut(RunControlContext ctx) {
+ if (ctx == null) return false;
+ if (ctx.canResume(IRunControl.RM_STEP_OUT)) return true;
+ if (!ctx.hasState()) return false;
+ if (ctx.canResume(IRunControl.RM_RESUME) && model.getLaunch().getService(IBreakpoints.class) != null) return true;
+ return false;
+ }
+ };
+ }
+
+ public boolean execute(final IDebugCommandRequest request) {
+ final Object[] elements = request.getElements();
+ if (elements.length != 1 || !(elements[0] instanceof TCFNodeStackFrame)) {
+ request.setStatus(Status.CANCEL_STATUS);
+ request.done();
+ return false;
+ }
+ final TCFNodeStackFrame frameNode = (TCFNodeStackFrame) elements[0];
+ new TCFRunnable(request) {
+ public void run() {
+ int frameNo = frameNode.getFrameNo();
+ if (frameNo < 1) {
+ request.setStatus(Status.CANCEL_STATUS);
+ done();
+ return;
+ }
+ TCFNodeExecContext exeNode = (TCFNodeExecContext) frameNode.getParent();
+ TCFDataCache<IRunControl.RunControlContext> ctx_cache = exeNode.getRunContext();
+ if (!ctx_cache.validate(this)) return;
+ TCFDataCache<TCFContextState> state_cache = exeNode.getState();
+ if (!state_cache.validate(this)) return;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data == null || !state_data.is_suspended) {
+ request.setStatus(Status.CANCEL_STATUS);
+ done();
+ }
+ if (!exeNode.getStackTrace().validate(this)) return;
+ Map<String, TCFNode> stack = exeNode.getStackTrace().getData();
+ for (TCFNode node : stack.values()) {
+ TCFNodeStackFrame frame_to_step_out = (TCFNodeStackFrame) node;
+ if (frame_to_step_out.getFrameNo() == frameNo - 1) {
+ new StepStateMachine(model, request, ctx_cache.getData(), frame_to_step_out, new Runnable() {
+ public void run() {
+ request.done();
+ }
+ });
+ return;
+ }
+ }
+ request.setStatus(Status.CANCEL_STATUS);
+ done();
+ }
+ };
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapCommand.java
new file mode 100644
index 000000000..098eb50dd
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapCommand.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeArrayPartition;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExpression;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeModule;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeRegister;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.services.IMemory;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+public class MemoryMapCommand extends AbstractActionDelegate {
+
+ private static boolean isValidNode(final TCFNode n) {
+ if (n instanceof TCFNodeLaunch) return true;
+ if (n instanceof TCFNodeExecContext) {
+ return new TCFTask<Boolean>(n.getChannel()) {
+ public void run() {
+ TCFDataCache<TCFNodeExecContext> mem_cache = n.getModel().searchMemoryContext(n);
+ if (mem_cache == null) {
+ done(false);
+ return;
+ }
+ if (!mem_cache.validate(this)) return;
+ TCFNodeExecContext mem_node = mem_cache.getData();
+ if (mem_node == null) {
+ done(false);
+ return;
+ }
+ TCFDataCache<TCFNodeExecContext> syms_cache = mem_node.getSymbolsNode();
+ if (!syms_cache.validate(this)) return;
+ TCFNodeExecContext syms_node = syms_cache.getData();
+ if (syms_node == null) {
+ done(false);
+ return;
+ }
+ TCFDataCache<IMemory.MemoryContext> ctx_cache = syms_node.getMemoryContext();
+ if (!ctx_cache.validate(this)) return;
+ done(ctx_cache.getData() != null);
+ }
+ }.getE();
+ }
+ if (n instanceof TCFNodeStackFrame) return true;
+ if (n instanceof TCFNodeExpression) return true;
+ if (n instanceof TCFNodeArrayPartition) return true;
+ if (n instanceof TCFNodeRegister) return true;
+ if (n instanceof TCFNodeModule) return true;
+ return false;
+ }
+
+ protected void selectionChanged() {
+ getAction().setEnabled(isValidNode(getSelectedNode()));
+ }
+
+ protected void run() {
+ TCFNode node = getSelectedNode();
+ if (!isValidNode(node)) return;
+ Shell shell = getWindow().getShell();
+ try {
+ new MemoryMapDialog(shell, node).open();
+ }
+ catch (Throwable x) {
+ MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
+ mb.setText("Cannot open Symbol Files dialog");
+ mb.setMessage(TCFModel.getErrorMessage(x, true));
+ mb.open();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapDialog.java
new file mode 100644
index 000000000..c8e450a7e
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapDialog.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+
+class MemoryMapDialog extends Dialog {
+
+ private final TCFNode node;
+ private final ILaunchConfiguration cfg;
+ private MemoryMapWidget widget;
+ private Button ok_button;
+
+ MemoryMapDialog(Shell parent, TCFNode node) {
+ super(parent);
+ this.node = node;
+ cfg = node.getModel().getLaunch().getLaunchConfiguration();
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Symbol Files");
+ shell.setImage(ImageCache.getImage(ImageCache.IMG_MEMORY_MAP));
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ ok_button = createButton(parent, IDialogConstants.OK_ID, "&OK", true);
+ ok_button.setEnabled(widget != null && widget.getMemoryMapID() != null);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+ widget = new MemoryMapWidget(composite, node);
+ widget.loadData(cfg);
+ if (ok_button != null) ok_button.setEnabled(widget.getMemoryMapID() != null);
+ composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ return composite;
+ }
+
+ @Override
+ protected void okPressed() {
+ try {
+ ILaunchConfigurationWorkingCopy copy = cfg.getWorkingCopy();
+ if (widget.saveData(copy)) copy.doSave();
+ super.okPressed();
+ }
+ catch (Throwable x) {
+ MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
+ mb.setText("Cannot update memory map");
+ mb.setMessage(TCFModel.getErrorMessage(x, true));
+ mb.open();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapItemDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapItemDialog.java
new file mode 100644
index 000000000..39a314963
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapItemDialog.java
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.math.BigInteger;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+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.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IMemoryMap;
+
+class MemoryMapItemDialog extends Dialog {
+
+ private final Map<String,Object> props;
+ private final boolean enable_editing;
+ private final Image image;
+
+ private Text addr_text;
+ private Text size_text;
+ private Text offset_text;
+ private Text file_text;
+ private Button rd_button;
+ private Button wr_button;
+ private Button ex_button;
+
+ MemoryMapItemDialog(Shell parent, Image image, Map<String,Object> props, boolean enable_editing) {
+ super(parent);
+ this.image = image;
+ this.props = props;
+ this.enable_editing = enable_editing;
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Symbol File");
+ shell.setImage(image);
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, "&OK", true);
+ updateButtons();
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+ createFileNameFields(composite);
+ createPropsFields(composite);
+ setData();
+ composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ return composite;
+ }
+
+ private void createFileNameFields(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(3, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label file_label = new Label(composite, SWT.WRAP);
+ file_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ file_label.setFont(font);
+ file_label.setText("File name:");
+
+ file_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ file_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ file_text.setFont(font);
+ file_text.setEditable(enable_editing);
+
+ file_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ updateButtons();
+ }
+ });
+
+ Button button = new Button(composite, SWT.PUSH);
+ button.setFont(font);
+ button.setText("...");
+ button.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ button.setEnabled(enable_editing);
+ button.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ FileDialog file_dialog = new FileDialog(getShell(), SWT.NONE);
+ file_dialog.setFileName(file_text.getText());
+ String path = file_dialog.open();
+ if (path != null) file_text.setText(path);
+ }
+ });
+ }
+
+ private void createPropsFields(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ createTextFields(composite);
+ createFlagsGroup(composite);
+ }
+
+ private void createTextFields(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.widthHint = 250;
+ composite.setLayoutData(gd);
+
+ Label addr_label = new Label(composite, SWT.WRAP);
+ addr_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ addr_label.setFont(font);
+ addr_label.setText("Address:");
+
+ addr_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ addr_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ addr_text.setFont(font);
+ addr_text.setEditable(enable_editing);
+
+ Label size_label = new Label(composite, SWT.WRAP);
+ size_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ size_label.setFont(font);
+ size_label.setText("Size:");
+
+ size_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ size_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ size_text.setFont(font);
+ size_text.setEditable(enable_editing);
+
+ Label offset_label = new Label(composite, SWT.WRAP);
+ offset_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ offset_label.setFont(font);
+ offset_label.setText("File offset:");
+
+ offset_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ offset_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ offset_text.setFont(font);
+ offset_text.setEditable(enable_editing);
+ }
+
+ private void createFlagsGroup(Composite parent) {
+ Font font = parent.getFont();
+
+ Group group = new Group(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.verticalSpacing = 0;
+ layout.numColumns = 1;
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_BOTH));
+ group.setFont(font);
+ group.setText("Flags");
+
+ rd_button = new Button(group, SWT.CHECK);
+ rd_button.setFont(font);
+ rd_button.setText("Data read");
+ rd_button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ rd_button.setEnabled(enable_editing);
+
+ wr_button = new Button(group, SWT.CHECK);
+ wr_button.setFont(font);
+ wr_button.setText("Data write");
+ wr_button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ wr_button.setEnabled(enable_editing);
+
+ ex_button = new Button(group, SWT.CHECK);
+ ex_button.setFont(font);
+ ex_button.setText("Instructions read");
+ ex_button.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ ex_button.setEnabled(enable_editing);
+ }
+
+ private String toHex(Number n) {
+ if (n == null) return null;
+ BigInteger x = JSON.toBigInteger(n);
+ String s = x.toString(16);
+ int l = 16 - s.length();
+ if (l < 0) l = 0;
+ if (l > 16) l = 16;
+ return "0x0000000000000000".substring(0, 2 + l) + s;
+ }
+
+ private void setText(Text text, String str) {
+ if (str == null) str = "";
+ text.setText(str);
+ }
+
+ private void setData() {
+ setText(addr_text, toHex((Number)props.get(IMemoryMap.PROP_ADDRESS)));
+ setText(size_text, toHex((Number)props.get(IMemoryMap.PROP_SIZE)));
+ if (props.get(IMemoryMap.PROP_SECTION_NAME) != null) {
+ setText(offset_text, (String)props.get(IMemoryMap.PROP_SECTION_NAME));
+ }
+ else {
+ setText(offset_text, toHex((Number)props.get(IMemoryMap.PROP_OFFSET)));
+ }
+ setText(file_text, (String)props.get(IMemoryMap.PROP_FILE_NAME));
+ int flags = 0;
+ Number n = (Number)props.get(IMemoryMap.PROP_FLAGS);
+ if (n != null) flags = n.intValue();
+ rd_button.setSelection((flags & IMemoryMap.FLAG_READ) != 0);
+ wr_button.setSelection((flags & IMemoryMap.FLAG_WRITE) != 0);
+ ex_button.setSelection((flags & IMemoryMap.FLAG_EXECUTE) != 0);
+ updateButtons();
+ }
+
+ private void getNumber(Text text, String key) {
+ String s = text.getText().trim();
+ if (s == null || s.length() == 0) {
+ props.remove(key);
+ }
+ else if (s.startsWith("0x")) {
+ props.put(key, new BigInteger(s.substring(2), 16));
+ }
+ else {
+ props.put(key, new BigInteger(s));
+ }
+ }
+
+ private void getText(Text text, String key) {
+ String s = text.getText().trim();
+ if (s == null || s.length() == 0) {
+ props.remove(key);
+ }
+ else {
+ props.put(key, s);
+ }
+ }
+
+ private void getData() {
+ getNumber(addr_text, IMemoryMap.PROP_ADDRESS);
+ getNumber(size_text, IMemoryMap.PROP_SIZE);
+ if (offset_text.getText().startsWith(".")) {
+ props.put(IMemoryMap.PROP_SECTION_NAME, offset_text.getText());
+ props.remove(IMemoryMap.PROP_OFFSET);
+ }
+ else {
+ getNumber(offset_text, IMemoryMap.PROP_OFFSET);
+ props.remove(IMemoryMap.PROP_SECTION_NAME);
+ }
+ getText(file_text, IMemoryMap.PROP_FILE_NAME);
+ int flags = 0;
+ if (rd_button.getSelection()) flags |= IMemoryMap.FLAG_READ;
+ if (wr_button.getSelection()) flags |= IMemoryMap.FLAG_WRITE;
+ if (ex_button.getSelection()) flags |= IMemoryMap.FLAG_EXECUTE;
+ props.put(IMemoryMap.PROP_FLAGS, flags);
+ }
+
+ private void updateButtons() {
+ Button btn = getButton(IDialogConstants.OK_ID);
+ if (btn != null && file_text != null) btn.setEnabled(!enable_editing || file_text.getText().trim().length() > 0);
+ }
+
+ @Override
+ protected void okPressed() {
+ if (enable_editing) {
+ try {
+ getData();
+ }
+ catch (Throwable x) {
+ MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
+ mb.setText("Invalid data");
+ mb.setMessage(TCFModel.getErrorMessage(x, true));
+ mb.open();
+ return;
+ }
+ }
+ super.okPressed();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapWidget.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapWidget.java
new file mode 100644
index 000000000..7db194fde
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/MemoryMapWidget.java
@@ -0,0 +1,632 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableColorProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+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.Color;
+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.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.model.TCFMemoryRegion;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFChildren;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeLaunch;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.services.IMemory;
+import org.eclipse.tm.tcf.services.IMemoryMap;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+public class MemoryMapWidget {
+
+
+ private static final int
+ SIZING_TABLE_WIDTH = 700,
+ SIZING_TABLE_HEIGHT = 300;
+
+ private static final String[] column_names = {
+ "File",
+ "Address",
+ "Size",
+ "Flags",
+ "File offset/section",
+ };
+
+ private final TCFModel model;
+ private final IChannel channel;
+ private final TCFNode selection;
+
+ private Combo ctx_text;
+ private Table map_table;
+ private TableViewer table_viewer;
+ private Runnable update_map_buttons;
+ private final Map<String,ArrayList<IMemoryMap.MemoryRegion>> org_maps =
+ new HashMap<String,ArrayList<IMemoryMap.MemoryRegion>>();
+ private final Map<String,ArrayList<IMemoryMap.MemoryRegion>> cur_maps =
+ new HashMap<String,ArrayList<IMemoryMap.MemoryRegion>>();
+ private final ArrayList<IMemoryMap.MemoryRegion> target_map =
+ new ArrayList<IMemoryMap.MemoryRegion>();
+ private final HashMap<String,TCFNodeExecContext> target_map_nodes =
+ new HashMap<String,TCFNodeExecContext>();
+ private TCFNodeExecContext selected_mem_map_node;
+ private IMemory.MemoryContext mem_ctx;
+ private ILaunchConfiguration cfg;
+ private final HashSet<String> loaded_files = new HashSet<String>();
+ private String selected_mem_map_id;
+
+ private final IStructuredContentProvider content_provider = new IStructuredContentProvider() {
+
+ public Object[] getElements(Object input) {
+ ArrayList<IMemoryMap.MemoryRegion> res = new ArrayList<IMemoryMap.MemoryRegion>();
+ ArrayList<IMemoryMap.MemoryRegion> lst = cur_maps.get((String)input);
+ if (lst != null) res.addAll(lst);
+ res.addAll(target_map);
+ return res.toArray();
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+ };
+
+ private class MapLabelProvider extends LabelProvider implements ITableLabelProvider, ITableColorProvider {
+
+ public Image getColumnImage(Object element, int column) {
+ return null;
+ }
+
+ public String getColumnText(Object element, int column) {
+ TCFMemoryRegion r = (TCFMemoryRegion)element;
+ switch (column) {
+ case 0:
+ return r.getFileName();
+ case 1:
+ case 2:
+ {
+ BigInteger x = column == 1 ? r.addr : r.size;
+ if (x == null) return "";
+ String s = x.toString(16);
+ int sz = 0;
+ if (mem_ctx != null) sz = mem_ctx.getAddressSize() * 2;
+ int l = sz - s.length();
+ if (l < 0) l = 0;
+ if (l > 16) l = 16;
+ return "0x0000000000000000".substring(0, 2 + l) + s;
+ }
+ case 3:
+ {
+ int n = r.getFlags();
+ StringBuffer bf = new StringBuffer();
+ if ((n & IMemoryMap.FLAG_READ) != 0) bf.append('r');
+ if ((n & IMemoryMap.FLAG_WRITE) != 0) bf.append('w');
+ if ((n & IMemoryMap.FLAG_EXECUTE) != 0) bf.append('x');
+ return bf.toString();
+ }
+ case 4:
+ {
+ Number n = r.getOffset();
+ if (n != null) {
+ BigInteger x = JSON.toBigInteger(n);
+ String s = x.toString(16);
+ int l = 16 - s.length();
+ if (l < 0) l = 0;
+ if (l > 16) l = 16;
+ return "0x0000000000000000".substring(0, 2 + l) + s;
+ }
+ String s = r.getSectionName();
+ if (s != null) return s;
+ return "";
+ }
+ }
+ return "";
+ }
+
+ public Color getBackground(Object element, int columnIndex) {
+ return map_table.getBackground();
+ }
+
+ public Color getForeground(Object element, int columnIndex) {
+ TCFMemoryRegion r = (TCFMemoryRegion)element;
+ if (r.getProperties().get(IMemoryMap.PROP_ID) != null) {
+ String fnm = r.getFileName();
+ if (fnm != null && loaded_files.contains(fnm)) {
+ return map_table.getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN);
+ }
+ return map_table.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE);
+ }
+ return map_table.getForeground();
+ }
+
+ public String getText(Object element) {
+ return element.toString();
+ }
+ }
+
+ public MemoryMapWidget(Composite composite, TCFNode node) {
+ if (node != null) {
+ model = node.getModel();
+ channel = node.getChannel();
+ selection = node;
+ }
+ else {
+ model = null;
+ channel = null;
+ selection = null;
+ }
+ createContextText(composite);
+ createMemoryMapTable(composite);
+ }
+
+ public String getMemoryMapID() {
+ return selected_mem_map_id;
+ }
+
+ private void createContextText(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label props_label = new Label(composite, SWT.WRAP);
+ props_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ props_label.setFont(font);
+ props_label.setText("&Debug context:");
+
+ ctx_text = new Combo(composite, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY);
+ ctx_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ ctx_text.setFont(font);
+ ctx_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e) {
+ selected_mem_map_id = ctx_text.getText();
+ selected_mem_map_node = target_map_nodes.get(selected_mem_map_id);
+ loadTargetMemoryMap();
+ table_viewer.setInput(selected_mem_map_id);
+ if (selected_mem_map_id.length() == 0) selected_mem_map_id = null;
+ update_map_buttons.run();
+ }
+ });
+ }
+
+ private void createMemoryMapTable(Composite parent) {
+ Font font = parent.getFont();
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ map_table = new Table(composite,
+ SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION |
+ SWT.H_SCROLL | SWT.V_SCROLL);
+ map_table.setFont(font);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = SIZING_TABLE_WIDTH;
+ data.heightHint = SIZING_TABLE_HEIGHT;
+ map_table.setLayoutData(data);
+
+ int w = SIZING_TABLE_WIDTH / (column_names.length + 12);
+ for (int i = 0; i < column_names.length; i++) {
+ final TableColumn column = new TableColumn(map_table, SWT.LEAD, i);
+ column.setMoveable(false);
+ column.setText(column_names[i]);
+ switch (i) {
+ case 0:
+ column.setWidth(w * 10);
+ break;
+ case 1:
+ case 2:
+ case 4:
+ column.setWidth(w * 2);
+ break;
+ default:
+ column.setWidth(w);
+ break;
+ }
+ }
+ map_table.setHeaderVisible(true);
+ map_table.setLinesVisible(true);
+ map_table.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ IMemoryMap.MemoryRegion r = (IMemoryMap.MemoryRegion)((IStructuredSelection)
+ table_viewer.getSelection()).getFirstElement();
+ if (r == null) return;
+ editRegion(r);
+ }
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ update_map_buttons.run();
+ }
+ });
+
+ table_viewer = new TableViewer(map_table);
+ table_viewer.setUseHashlookup(true);
+ table_viewer.setColumnProperties(column_names);
+
+ table_viewer.setContentProvider(content_provider);
+
+ table_viewer.setLabelProvider(new MapLabelProvider());
+
+ createMapButtons(composite);
+ }
+
+ private void createMapButtons(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+ Menu menu = new Menu(map_table);
+ SelectionAdapter sel_adapter = null;
+
+ final Button button_add = new Button(composite, SWT.PUSH);
+ button_add.setText("&Add...");
+ button_add.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_add.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ String id = ctx_text.getText();
+ if (id == null || id.length() == 0) return;
+ Map<String,Object> props = new HashMap<String,Object>();
+ Image image = ImageCache.getImage(ImageCache.IMG_MEMORY_MAP);
+ if (new MemoryMapItemDialog(map_table.getShell(), image, props, true).open() == Window.OK) {
+ props.put(IMemoryMap.PROP_ID, id);
+ ArrayList<IMemoryMap.MemoryRegion> lst = cur_maps.get(id);
+ if (lst == null) cur_maps.put(id, lst = new ArrayList<IMemoryMap.MemoryRegion>());
+ lst.add(new TCFMemoryRegion(props));
+ table_viewer.refresh();
+ }
+ }
+ });
+ final MenuItem item_add = new MenuItem(menu, SWT.PUSH);
+ item_add.setText("&Add...");
+ item_add.addSelectionListener(sel_adapter);
+
+ final Button button_edit = new Button(composite, SWT.PUSH);
+ button_edit.setText("E&dit...");
+ button_edit.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_edit.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ IMemoryMap.MemoryRegion r = (IMemoryMap.MemoryRegion)((IStructuredSelection)
+ table_viewer.getSelection()).getFirstElement();
+ if (r == null) return;
+ editRegion(r);
+ }
+ });
+ final MenuItem item_edit = new MenuItem(menu, SWT.PUSH);
+ item_edit.setText("E&dit...");
+ item_edit.addSelectionListener(sel_adapter);
+
+ final Button button_remove = new Button(composite, SWT.PUSH);
+ button_remove.setText("&Remove");
+ button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_remove.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ String id = ctx_text.getText();
+ if (id == null || id.length() == 0) return;
+ IMemoryMap.MemoryRegion r = (IMemoryMap.MemoryRegion)((IStructuredSelection)
+ table_viewer.getSelection()).getFirstElement();
+ if (r == null) return;
+ ArrayList<IMemoryMap.MemoryRegion> lst = cur_maps.get(id);
+ if (lst != null && lst.remove(r)) table_viewer.refresh();
+ }
+ });
+ final MenuItem item_remove = new MenuItem(menu, SWT.PUSH);
+ item_remove.setText("&Remove");
+ item_remove.addSelectionListener(sel_adapter);
+
+ map_table.setMenu(menu);
+
+ update_map_buttons = new Runnable() {
+ public void run() {
+ IMemoryMap.MemoryRegion r = (IMemoryMap.MemoryRegion)((IStructuredSelection)
+ table_viewer.getSelection()).getFirstElement();
+ boolean manual = r != null && r.getProperties().get(IMemoryMap.PROP_ID) != null;
+ button_add.setEnabled(selected_mem_map_id != null);
+ button_edit.setEnabled(r != null);
+ button_remove.setEnabled(manual);
+ item_add.setEnabled(selected_mem_map_id != null);
+ item_edit.setEnabled(r != null);
+ item_remove.setEnabled(manual);
+ }
+ };
+ update_map_buttons.run();
+ }
+
+ private void editRegion(IMemoryMap.MemoryRegion r) {
+ String id = ctx_text.getText();
+ if (id == null || id.length() == 0) return;
+ Map<String,Object> props = r.getProperties();
+ boolean enable_editing = props.get(IMemoryMap.PROP_ID) != null;
+ if (enable_editing) props = new HashMap<String,Object>(props);
+ Image image = ImageCache.getImage(ImageCache.IMG_MEMORY_MAP);
+ if (new MemoryMapItemDialog(map_table.getShell(), image, props, enable_editing).open() == Window.OK && enable_editing) {
+ ArrayList<IMemoryMap.MemoryRegion> lst = cur_maps.get(id);
+ if (lst != null) {
+ int n = lst.indexOf(r);
+ if (n >= 0) {
+ lst.set(n, new TCFMemoryRegion(props));
+ table_viewer.refresh();
+ }
+ }
+ }
+ }
+
+ private void readMemoryMapAttribute() {
+ cur_maps.clear();
+ try {
+ new TCFTask<Boolean>() {
+ public void run() {
+ try {
+ TCFLaunchDelegate.getMemMapsAttribute(cur_maps, cfg);
+ done(true);
+ }
+ catch (Exception e) {
+ error(e);
+ }
+ }
+ }.get();
+ }
+ catch (Exception x) {
+ Activator.log("Invalid launch cofiguration attribute", x);
+ }
+ }
+
+ private void writeMemoryMapAttribute(ILaunchConfigurationWorkingCopy copy) throws Exception {
+ String s = null;
+ final ArrayList<IMemoryMap.MemoryRegion> lst = new ArrayList<IMemoryMap.MemoryRegion>();
+ for (ArrayList<IMemoryMap.MemoryRegion> x : cur_maps.values()) lst.addAll(x);
+ if (lst.size() > 0) {
+ s = new TCFTask<String>() {
+ public void run() {
+ try {
+ done(JSON.toJSON(lst));
+ }
+ catch (IOException e) {
+ error(e);
+ }
+ }
+ }.getIO();
+ }
+ copy.setAttribute(TCFLaunchDelegate.ATTR_MEMORY_MAP, s);
+ }
+
+ public void loadData(ILaunchConfiguration cfg) {
+ this.cfg = cfg;
+ cur_maps.clear();
+ org_maps.clear();
+ loadTargetMemoryNodes();
+ readMemoryMapAttribute();
+ for (String id : cur_maps.keySet()) {
+ org_maps.put(id, new ArrayList<IMemoryMap.MemoryRegion>(cur_maps.get(id)));
+ }
+ // Update controls
+ String map_id = getSelectedMemoryNode();
+ HashSet<String> ids = new HashSet<String>(target_map_nodes.keySet());
+ if (map_id != null) ids.add(map_id);
+ ids.addAll(cur_maps.keySet());
+ String[] arr = ids.toArray(new String[ids.size()]);
+ Arrays.sort(arr);
+ ctx_text.removeAll();
+ for (String id : arr) ctx_text.add(id);
+ if (map_id == null && arr.length > 0) map_id = arr[0];
+ if (map_id == null) map_id = "";
+ ctx_text.setText(map_id);
+ }
+
+ private String getSelectedMemoryNode() {
+ if (channel == null || channel.getState() != IChannel.STATE_OPEN) return null;
+ try {
+ return new TCFTask<String>(channel) {
+ public void run() {
+ TCFDataCache<TCFNodeExecContext> mem_cache = model.searchMemoryContext(selection);
+ if (mem_cache == null) {
+ error(new Exception("Context does not provide memory access"));
+ return;
+ }
+ if (!mem_cache.validate(this)) return;
+ if (mem_cache.getError() != null) {
+ error(mem_cache.getError());
+ return;
+ }
+ String id = null;
+ TCFNodeExecContext mem_node = mem_cache.getData();
+ if (mem_node != null) {
+ TCFDataCache<TCFNodeExecContext> syms_cache = mem_node.getSymbolsNode();
+ if (!syms_cache.validate(this)) return;
+ TCFNodeExecContext syms_node = syms_cache.getData();
+ if (syms_node != null) {
+ TCFDataCache<IMemory.MemoryContext> mem_ctx = syms_node.getMemoryContext();
+ if (!mem_ctx.validate(this)) return;
+ if (mem_ctx.getData() != null) {
+ if (syms_node.getModel().getLaunch().isMemoryMapPreloadingSupported()) {
+ TCFDataCache<String> name_cache = syms_node.getFullName();
+ if (!name_cache.validate(this)) return;
+ id = name_cache.getData();
+ }
+ else {
+ id = mem_ctx.getData().getName();
+ }
+ if (id == null) id = syms_node.getID();
+ }
+ }
+ }
+ done(id);
+ }
+ }.get();
+ }
+ catch (Exception x) {
+ if (channel.getState() != IChannel.STATE_OPEN) return null;
+ Activator.log("Cannot get selected memory node", x);
+ return null;
+ }
+ }
+
+ private void loadTargetMemoryNodes() {
+ target_map_nodes.clear();
+ if (channel == null || channel.getState() != IChannel.STATE_OPEN) return;
+ try {
+ new TCFTask<Boolean>(channel) {
+ public void run() {
+ TCFNodeLaunch n = model.getRootNode();
+ if (!collectMemoryNodes(n.getFilteredChildren())) return;
+ done(true);
+ }
+ private boolean collectMemoryNodes(TCFChildren children) {
+ if (!children.validate(this)) return false;
+ Map<String,TCFNode> m = children.getData();
+ if (m != null) {
+ for (TCFNode n : m.values()) {
+ if (n instanceof TCFNodeExecContext) {
+ TCFNodeExecContext exe = (TCFNodeExecContext)n;
+ if (!collectMemoryNodes(exe.getChildren())) return false;
+ TCFDataCache<TCFNodeExecContext> syms_cache = exe.getSymbolsNode();
+ if (!syms_cache.validate(this)) return false;
+ TCFNodeExecContext syms_node = syms_cache.getData();
+ if (syms_node != null) {
+ TCFDataCache<IMemory.MemoryContext> mem_ctx = syms_node.getMemoryContext();
+ if (!mem_ctx.validate(this)) return false;
+ if (mem_ctx.getData() != null) {
+ String id = null;
+ if (syms_node.getModel().getLaunch().isMemoryMapPreloadingSupported()) {
+ TCFDataCache<String> name_cache = syms_node.getFullName();
+ if (!name_cache.validate(this)) return false;
+ id = name_cache.getData();
+ }
+ else {
+ id = mem_ctx.getData().getName();
+ }
+ if (id == null) id = syms_node.getID();
+ target_map_nodes.put(id, syms_node);
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }.get();
+ }
+ catch (Exception x) {
+ if (channel.getState() != IChannel.STATE_OPEN) return;
+ Activator.log("Cannot load target memory context info", x);
+ }
+ }
+
+ private void loadTargetMemoryMap() {
+ loaded_files.clear();
+ target_map.clear();
+ mem_ctx = null;
+ if (channel == null || channel.getState() != IChannel.STATE_OPEN) return;
+ try {
+ new TCFTask<Boolean>(channel) {
+ public void run() {
+ if (selected_mem_map_node != null && !selected_mem_map_node.isDisposed()) {
+ TCFDataCache<IMemory.MemoryContext> mem_cache = selected_mem_map_node.getMemoryContext();
+ if (!mem_cache.validate(this)) return;
+ if (mem_cache.getError() != null) {
+ error(mem_cache.getError());
+ return;
+ }
+ mem_ctx = mem_cache.getData();
+ TCFDataCache<TCFNodeExecContext.MemoryRegion[]> map_cache = selected_mem_map_node.getMemoryMap();
+ if (!map_cache.validate(this)) return;
+ if (map_cache.getError() != null) {
+ error(map_cache.getError());
+ return;
+ }
+ if (map_cache.getData() != null) {
+ for (TCFNodeExecContext.MemoryRegion m : map_cache.getData()) {
+ Map<String,Object> props = m.region.getProperties();
+ if (props.get(IMemoryMap.PROP_ID) != null) {
+ String fnm = m.region.getFileName();
+ if (fnm != null) loaded_files.add(fnm);
+ }
+ else {
+ target_map.add(new TCFMemoryRegion(props));
+ }
+ }
+ }
+ }
+ done(true);
+ }
+ }.get();
+ }
+ catch (Exception x) {
+ if (channel.getState() != IChannel.STATE_OPEN) return;
+ Activator.log("Cannot load target memory map", x);
+ }
+ }
+
+ public boolean saveData(ILaunchConfigurationWorkingCopy copy) throws Exception {
+ boolean loaded_files_ok = true;
+ if (selected_mem_map_id != null) {
+ ArrayList<IMemoryMap.MemoryRegion> lst = cur_maps.get(selected_mem_map_id);
+ if (lst != null) {
+ for (IMemoryMap.MemoryRegion r : lst) {
+ String fnm = r.getFileName();
+ if (fnm != null && !loaded_files.contains(fnm)) loaded_files_ok = false;
+ }
+ if (lst.size() == 0) cur_maps.remove(selected_mem_map_id);
+ }
+ }
+ if (!loaded_files_ok || !org_maps.equals(cur_maps)) {
+ writeMemoryMapAttribute(copy);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RefreshCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RefreshCommand.java
new file mode 100644
index 000000000..ac52e4fa2
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RefreshCommand.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.debug.ui.memory.IMemoryRenderingSite;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+
+public class RefreshCommand extends AbstractActionDelegate {
+
+ @Override
+ protected void selectionChanged() {
+ getAction().setEnabled(getRootNode() != null);
+ }
+
+ @Override
+ protected void run() {
+ final TCFNode node = getRootNode();
+ if (node == null) return;
+ new TCFTask<Object>(node.getChannel()) {
+ public void run() {
+ IViewPart part = getView();
+ TCFModel model = node.getModel();
+ TCFNode ref_node = node;
+ if (part instanceof IMemoryRenderingSite) {
+ // Search memory node
+ TCFDataCache<TCFNodeExecContext> mem_cache = model.searchMemoryContext(node);
+ if (mem_cache == null) {
+ done(null);
+ return;
+ }
+ if (!mem_cache.validate(this)) return;
+ ref_node = mem_cache.getData();
+ }
+ if (ref_node != null) {
+ ref_node.refresh(part);
+ if (model.clearLock(part)) {
+ model.setLock(part);
+ }
+ }
+ done(null);
+ }
+ }.getE();
+ }
+
+ private TCFNode getRootNode() {
+ IViewPart view = getView();
+ if (view == null) return null;
+ IWorkbenchPartSite site = view.getSite();
+ if (site != null && IDebugUIConstants.ID_DEBUG_VIEW.equals(site.getId())) {
+ TCFNode n = getSelectedNode();
+ if (n == null) return null;
+ return n.getModel().getRootNode();
+ }
+ if (site != null && IDebugUIConstants.ID_MEMORY_VIEW.equals(site.getId())) {
+ ISelection selection = DebugUITools.getDebugContextManager().getContextService(
+ site.getWorkbenchWindow()).getActiveContext();
+ if (selection instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection)selection).getFirstElement();
+ if (obj instanceof TCFNode) return (TCFNode)obj;
+ }
+ }
+ if (view instanceof IDebugView) {
+ Object input = ((IDebugView)view).getViewer().getInput();
+ if (input instanceof TCFNode) return (TCFNode)input;
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RefreshHandler.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RefreshHandler.java
new file mode 100644
index 000000000..6658ec5da
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RefreshHandler.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.debug.ui.memory.IMemoryRenderingSite;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+public class RefreshHandler extends AbstractHandler {
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ Object input = null;
+ final IWorkbenchPart part = HandlerUtil.getActivePart(event);
+ if (part instanceof IMemoryRenderingSite) {
+ IWorkbenchPartSite site = part.getSite();
+ if (site != null) {
+ ISelection selection = DebugUITools.getDebugContextManager().getContextService(
+ site.getWorkbenchWindow()).getActiveContext();
+ if (selection instanceof IStructuredSelection) {
+ input = ((IStructuredSelection)selection).getFirstElement();
+ }
+ }
+ }
+ else if (part instanceof IDebugView) {
+ IWorkbenchPartSite site = part.getSite();
+ if (site != null && IDebugUIConstants.ID_DEBUG_VIEW.equals(site.getId())) {
+ ISelection selection = HandlerUtil.getCurrentSelection(event);
+ if (selection instanceof IStructuredSelection) {
+ Object obj = ((IStructuredSelection)selection).getFirstElement();
+ if (obj instanceof TCFNode) input = ((TCFNode)obj).getModel().getRootNode();
+ }
+ }
+ else {
+ input = ((IDebugView)part).getViewer().getInput();
+ }
+ }
+ if (input instanceof TCFNode) {
+ final TCFNode node = (TCFNode)input;
+ return new TCFTask<Object>(node.getChannel()) {
+ public void run() {
+ TCFModel model = node.getModel();
+ TCFNode ref_node = node;
+ if (part instanceof IMemoryRenderingSite) {
+ // Search memory node
+ TCFDataCache<TCFNodeExecContext> mem_cache = model.searchMemoryContext(node);
+ if (mem_cache == null) {
+ done(null);
+ return;
+ }
+ if (!mem_cache.validate(this)) return;
+ ref_node = mem_cache.getData();
+ }
+ if (ref_node != null) {
+ ref_node.refresh(part);
+ if (model.clearLock(part)) {
+ model.setLock(part);
+ }
+ }
+ done(null);
+ }
+ }.getE();
+ }
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RestoreDefaultTypeCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RestoreDefaultTypeCommand.java
new file mode 100644
index 000000000..6be58e590
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/RestoreDefaultTypeCommand.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.tm.internal.tcf.debug.ui.model.ICastToType;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.tcf.protocol.Protocol;
+
+public class RestoreDefaultTypeCommand extends AbstractActionDelegate {
+
+ @Override
+ protected void run() {
+ final TCFNode node = getCastToTypeNode();
+ if (node == null) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ node.getModel().setCastToType(node.getID(), null);
+ }
+ });
+ }
+
+ @Override
+ protected void selectionChanged() {
+ TCFNode node = getCastToTypeNode();
+ getAction().setEnabled(node != null && node.getModel().getCastToType(node.getID()) != null);
+ }
+
+ private TCFNode getCastToTypeNode() {
+ TCFNode node = getSelectedNode();
+ if (node instanceof ICastToType) return node;
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/ResumeCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/ResumeCommand.java
new file mode 100644
index 000000000..5400baae8
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/ResumeCommand.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IResumeHandler;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFAction;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IRunControl;
+
+
+public class ResumeCommand extends StepCommand implements IResumeHandler {
+
+ public ResumeCommand(TCFModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean canExecute(IRunControl.RunControlContext ctx) {
+ return ctx.canResume(IRunControl.RM_RESUME);
+ }
+
+ @Override
+ protected void execute(final IDebugCommandRequest monitor,
+ final IRunControl.RunControlContext ctx, boolean src_step, final Runnable done) {
+ new TCFAction(model.getLaunch(), ctx.getID()) {
+ public void run() {
+ ctx.resume(IRunControl.RM_RESUME, 1, new IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null && model.getChannel().getState() == IChannel.STATE_OPEN) {
+ if (error instanceof IErrorReport) {
+ IErrorReport r = (IErrorReport)error;
+ if (r.getErrorCode() == IErrorReport.TCF_ERROR_ALREADY_RUNNING) {
+ done();
+ return;
+ }
+ }
+ launch.removeContextActions(getContextID());
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, IStatus.OK, "Cannot resume: " + error.getLocalizedMessage(), error));
+ }
+ done();
+ }
+ });
+ }
+ public void done() {
+ super.done();
+ done.run();
+ }
+ };
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SignalsCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SignalsCommand.java
new file mode 100644
index 000000000..05dc7a6c3
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SignalsCommand.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExpression;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeModule;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+
+public class SignalsCommand extends AbstractActionDelegate {
+
+ private static boolean isValidNode(TCFNode n) {
+ if (n instanceof TCFNodeLaunch) return true;
+ if (n instanceof TCFNodeExecContext) return true;
+ if (n instanceof TCFNodeStackFrame) return true;
+ if (n instanceof TCFNodeExpression) return true;
+ if (n instanceof TCFNodeModule) return true;
+ return false;
+ }
+
+ protected void selectionChanged() {
+ TCFNode n = getSelectedNode();
+ getAction().setEnabled(isValidNode(n));
+ }
+
+ protected void run() {
+ TCFNode n = getSelectedNode();
+ if (isValidNode(n)) {
+ Shell shell = getWindow().getShell();
+ try {
+ new SignalsDialog(shell, n).open();
+ }
+ catch (Throwable x) {
+ MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
+ mb.setText("Cannot open Signals dialog");
+ mb.setMessage(TCFModel.getErrorMessage(x, true));
+ mb.open();
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SignalsDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SignalsDialog.java
new file mode 100644
index 000000000..eae7a5e9d
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SignalsDialog.java
@@ -0,0 +1,438 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+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.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFChildren;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext.SignalMask;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IProcesses;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+class SignalsDialog extends Dialog {
+
+ private static final int
+ SIZING_TABLE_WIDTH = 800,
+ SIZING_TABLE_HEIGHT = 300;
+
+ private static final String[] column_names = {
+ "Code",
+ "Name",
+ "Description",
+ "Don't stop",
+ "Don't pass",
+ "Pending"
+ };
+
+ private static class Signal extends SignalMask {
+
+ Signal(Map<String,Object> m) {
+ props = m;
+ }
+
+ Signal(SignalMask m) {
+ props = m.getProperties();
+ dont_stop = m.isDontStop();
+ dont_pass = m.isDontPass();
+ pending = m.isPending();
+ }
+
+ void setDontStop(boolean b) {
+ dont_stop = b;
+ }
+
+ void setDontPass(boolean b) {
+ dont_pass = b;
+ }
+
+ void setPending(boolean b) {
+ pending = b;
+ }
+ }
+
+ private Table signal_table;
+ private TableViewer table_viewer;
+ private Map<Number,Signal> org_signals;
+ private Signal[] cur_signals;
+
+ private final TCFModel model;
+ private final IChannel channel;
+ private final TCFNode selection;
+
+ private TCFNodeExecContext node;
+
+ private final IStructuredContentProvider content_provider = new IStructuredContentProvider() {
+
+ public Object[] getElements(Object input) {
+ return cur_signals;
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+ };
+
+ private static class SignalLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+ final Image img_rs = ImageCache.getImage("icons/full/elcl16/resume_co.gif");
+ final Image img_dl = ImageCache.getImage("icons/full/elcl16/rem_co.gif");
+ final Image img_en = ImageCache.getImage("icons/full/elcl16/enabled_co.gif");
+ final Image img_ds = ImageCache.getImage("icons/full/elcl16/disabled_co.gif");
+
+ public Image getColumnImage(Object element, int column) {
+ SignalMask s = (SignalMask)element;
+ switch (column) {
+ case 3:
+ return s.isDontStop() ? img_rs : img_ds;
+ case 4:
+ return s.isDontPass() ? img_dl : img_ds;
+ case 5:
+ return s.isPending() ? img_en : img_ds;
+ }
+ return null;
+ }
+
+ public String getColumnText(Object element, int column) {
+ SignalMask s = (SignalMask)element;
+ switch (column) {
+ case 0:
+ long n = s.getCode().longValue();
+ if (n < 32) return Long.toString(n);
+ String q = Long.toHexString(n);
+ if (q.length() < 8) q = "00000000".substring(q.length()) + q;
+ return "0x" + q;
+ case 1:
+ return (String)s.getProperties().get(IProcesses.SIG_NAME);
+ case 2:
+ return (String)s.getProperties().get(IProcesses.SIG_DESCRIPTION);
+ }
+ return "";
+ }
+
+ public String getText(Object element) {
+ return element.toString();
+ }
+ }
+
+ SignalsDialog(Shell parent, TCFNode node) {
+ super(parent);
+ model = node.getModel();
+ channel = node.getChannel();
+ selection = node;
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Signals");
+ shell.setImage(ImageCache.getImage(ImageCache.IMG_SIGNALS));
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, "&OK", true);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+
+ createSignalTable(composite);
+
+ composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ return composite;
+ }
+
+ private void createSignalTable(Composite parent) {
+ Font font = parent.getFont();
+ Label props_label = new Label(parent, SWT.WRAP);
+ props_label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ props_label.setFont(font);
+ props_label.setText("&Signals:");
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
+
+ signal_table = new Table(composite,
+ SWT.SINGLE | SWT.BORDER |
+ SWT.H_SCROLL | SWT.V_SCROLL);
+ signal_table.setFont(font);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = SIZING_TABLE_WIDTH;
+ data.heightHint = SIZING_TABLE_HEIGHT;
+ signal_table.setLayoutData(data);
+
+ int w = SIZING_TABLE_WIDTH / (column_names.length + 5);
+ for (int i = 0; i < column_names.length; i++) {
+ final TableColumn column = new TableColumn(signal_table, SWT.LEAD, i);
+ column.setMoveable(false);
+ column.setText(column_names[i]);
+ switch (i) {
+ case 0:
+ column.setWidth(w * 2);
+ break;
+ case 1:
+ case 2:
+ column.setWidth(w * 3);
+ break;
+ default:
+ column.setWidth(w);
+ break;
+ }
+ }
+ signal_table.setHeaderVisible(true);
+ signal_table.setLinesVisible(true);
+ signal_table.addMouseListener(new MouseListener() {
+
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+
+ public void mouseDown(MouseEvent e) {
+ int count = signal_table.getColumnCount();
+ for (int row = 0; row < signal_table.getItemCount(); row++) {
+ for (int col = 0; col < count; col++) {
+ TableItem item = signal_table.getItem(row);
+ if (item.getBounds(col).contains(e.x, e.y)) {
+ if (row < 0 || row >= cur_signals.length) break;
+ Signal s = cur_signals[row];
+ switch (col) {
+ case 3:
+ s.setDontStop(!s.isDontStop());
+ break;
+ case 4:
+ s.setDontPass(!s.isDontPass());
+ break;
+ case 5:
+ if (node == null) break;
+ if (s.isPending()) {
+ // Cannot clear a signal that is already generated
+ Signal x = org_signals.get(s.getIndex());
+ if (x != null && x.isPending()) break;
+ }
+ s.setPending(!s.isPending());
+ break;
+ }
+ table_viewer.refresh(s);
+ break;
+ }
+ }
+ }
+ }
+
+ public void mouseUp(MouseEvent e) {
+ }
+ });
+
+ table_viewer = new TableViewer(signal_table);
+ table_viewer.setUseHashlookup(true);
+ table_viewer.setColumnProperties(column_names);
+
+ cur_signals = new TCFTask<Signal[]>(channel) {
+ public void run() {
+ TCFNode n = selection;
+ while (n != null && !(n instanceof TCFNodeExecContext)) n = n.getParent();
+ node = (TCFNodeExecContext)n;
+ if (node == null) {
+ TCFLaunch launch = model.getLaunch();
+ Collection<Map<String,Object>> sigs = launch.getSignalList();
+ if (sigs == null) {
+ done(new Signal[0]);
+ }
+ else {
+ int i = 0;
+ int no_stop = 0;
+ int no_pass = 0;
+ Signal[] arr = new Signal[sigs.size()];
+ try {
+ ILaunchConfiguration cfg = launch.getLaunchConfiguration();
+ String dont_stop = cfg.getAttribute(TCFLaunchDelegate.ATTR_SIGNALS_DONT_STOP, "");
+ String dont_pass = cfg.getAttribute(TCFLaunchDelegate.ATTR_SIGNALS_DONT_PASS, "");
+ if (dont_stop.length() > 0) no_stop = Integer.parseInt(dont_stop, 16);
+ if (dont_pass.length() > 0) no_pass = Integer.parseInt(dont_pass, 16);
+ }
+ catch (Exception x) {
+ Activator.log("Invalid launch cofiguration attribute", x);
+ }
+ for (Map<String,Object> m : sigs) {
+ Signal s = arr[i++] = new Signal(m);
+ Number num = s.getIndex();
+ int j = num == null ? 0 : 1 << num.intValue();
+ s.setDontStop((no_stop & j) != 0);
+ s.setDontPass((no_pass & j) != 0);
+ }
+ done(arr);
+ }
+ }
+ else {
+ TCFDataCache<SignalMask[]> dc = node.getSignalMask();
+ if (!dc.validate(this)) return;
+ if (dc.getError() != null) {
+ error(dc.getError());
+ }
+ else if (dc.getData() == null) {
+ done(new Signal[0]);
+ }
+ else {
+ int i = 0;
+ Signal[] arr = new Signal[dc.getData().length];
+ for (SignalMask m : dc.getData()) arr[i++] = new Signal(m);
+ done(arr);
+ }
+ }
+ }
+ }.getE();
+ org_signals = new HashMap<Number,Signal>();
+ for (Signal m : cur_signals) org_signals.put(m.getIndex(), new Signal(m));
+ table_viewer.setContentProvider(content_provider);
+
+ table_viewer.setLabelProvider(new SignalLabelProvider());
+ table_viewer.setInput(this);
+ }
+
+ @Override
+ protected void okPressed() {
+ try {
+ boolean set_mask = false;
+ int dont_stop_set = 0;
+ int dont_pass_set = 0;
+ final LinkedList<Number> send_list = new LinkedList<Number>();
+ for (Signal s : cur_signals) {
+ Number index = s.getIndex();
+ Signal x = org_signals.get(index);
+ if (!set_mask) set_mask = x == null || x.isDontStop() != s.isDontStop() || x.isDontPass() != s.isDontPass();
+ if (s.isDontStop()) dont_stop_set |= 1 << index.intValue();
+ if (s.isDontPass()) dont_pass_set |= 1 << index.intValue();
+ if ((x == null || !x.isPending()) && s.isPending()) send_list.add(s.getCode());
+ }
+ if (set_mask) {
+ TCFLaunch launch = model.getLaunch();
+ ILaunchConfigurationWorkingCopy cfg = launch.getLaunchConfiguration().getWorkingCopy();
+ cfg.setAttribute(TCFLaunchDelegate.ATTR_SIGNALS_DONT_STOP, Integer.toHexString(dont_stop_set));
+ cfg.setAttribute(TCFLaunchDelegate.ATTR_SIGNALS_DONT_PASS, Integer.toHexString(dont_pass_set));
+ cfg.doSave();
+ final int dont_stop = dont_stop_set;
+ final int dont_pass = dont_pass_set;
+ new TCFTask<Boolean>(channel) {
+ final HashSet<IToken> cmds = new HashSet<IToken>();
+ final LinkedList<TCFNodeExecContext> nodes = new LinkedList<TCFNodeExecContext>();
+ TCFDataCache<?> pending;
+ public void run() {
+ nodes.clear();
+ pending = null;
+ addNodes(model.getRootNode().getChildren());
+ if (pending != null) {
+ pending.wait(this);
+ }
+ else {
+ while (nodes.size() > 0) {
+ TCFNodeExecContext exe = nodes.removeFirst();
+ exe.getSignalMask().reset();
+ IProcesses prs = channel.getRemoteService(IProcesses.class);
+ cmds.add(prs.setSignalMask(exe.getID(), dont_stop, dont_pass, new IProcesses.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ cmds.remove(token);
+ if (isDone()) return;
+ if (error != null) error(error);
+ if (cmds.size() == 0) done(Boolean.TRUE);
+ }
+ }));
+ }
+ }
+ }
+ private void addNodes(TCFChildren children) {
+ if (!children.validate()) {
+ pending = children;
+ }
+ else {
+ Map<String,TCFNode> map = children.getData();
+ if (map != null) {
+ for (TCFNode n : map.values()) {
+ TCFNodeExecContext exe = (TCFNodeExecContext)n;
+ addNodes(exe.getChildren());
+ nodes.add(exe);
+ }
+ }
+ }
+ }
+ }.getE();
+ }
+ if (send_list.size() > 0 && node != null) {
+ new TCFTask<Boolean>(channel) {
+ public void run() {
+ node.getSignalMask().reset();
+ final IProcesses prs = channel.getRemoteService(IProcesses.class);
+ prs.signal(node.getID(), send_list.removeFirst().longValue(), new IProcesses.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ if (error != null) {
+ error(error);
+ }
+ else if (send_list.isEmpty()) {
+ done(Boolean.TRUE);
+ }
+ else {
+ node.getSignalMask().reset();
+ prs.signal(node.getID(), send_list.removeFirst().longValue(), this);
+ }
+ }
+ });
+ }
+ }.getE();
+ }
+ }
+ catch (Throwable x) {
+ model.showMessageBox("Cannot update signals state", x);
+ return;
+ }
+ super.okPressed();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepCommand.java
new file mode 100644
index 000000000..824b6ea7b
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepCommand.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandHandler;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+abstract class StepCommand implements IDebugCommandHandler {
+
+ private static final int MAX_ACTION_CNT = 4;
+
+ protected final TCFModel model;
+
+ public StepCommand(TCFModel model) {
+ this.model = model;
+ }
+
+ protected abstract boolean canExecute(IRunControl.RunControlContext ctx);
+
+ protected abstract void execute(IDebugCommandRequest monitor,
+ IRunControl.RunControlContext ctx, boolean src_step, Runnable done);
+
+ private boolean getContextSet(boolean exec, Object[] elements, Set<IRunControl.RunControlContext> set, Runnable done) {
+ for (int i = 0; i < elements.length; i++) {
+ TCFNode node = null;
+ if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
+ else node = model.getRootNode();
+ while (node != null && !node.isDisposed()) {
+ IRunControl.RunControlContext ctx = null;
+ if (node instanceof TCFNodeExecContext) {
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(done)) return false;
+ ctx = cache.getData();
+ }
+ if (ctx == null) {
+ node = node.getParent();
+ }
+ else {
+ if (!canExecute(ctx)) break;
+ int action_cnt = model.getLaunch().getContextActionsCount(ctx.getID());
+ if (exec && action_cnt >= MAX_ACTION_CNT) break;
+ if (action_cnt > 0) {
+ set.add(ctx);
+ }
+ else {
+ if (ctx.isContainer()) {
+ TCFNodeExecContext.ChildrenStateInfo s = new TCFNodeExecContext.ChildrenStateInfo();
+ if (!((TCFNodeExecContext)node).hasSuspendedChildren(s, done)) return false;
+ if (s.suspended || s.not_active) set.add(ctx);
+ }
+ if (ctx.hasState()) {
+ TCFDataCache<TCFContextState> state_cache = ((TCFNodeExecContext)node).getState();
+ if (!state_cache.validate(done)) return false;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data != null && state_data.is_suspended) set.add(ctx);
+ }
+ }
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ public final void canExecute(final IEnabledStateRequest monitor) {
+ new TCFRunnable(monitor) {
+ public void run() {
+ if (done) return;
+ if (!monitor.isCanceled()) {
+ Set<IRunControl.RunControlContext> set = new HashSet<IRunControl.RunControlContext>();
+ if (!getContextSet(false, monitor.getElements(), set, this)) return;
+ monitor.setEnabled(set.size() > 0);
+ monitor.setStatus(Status.OK_STATUS);
+ }
+ done();
+ }
+ };
+ }
+
+ public final boolean execute(final IDebugCommandRequest monitor) {
+ new TCFRunnable(monitor) {
+ public void run() {
+ if (done) return;
+ Set<IRunControl.RunControlContext> set = new HashSet<IRunControl.RunControlContext>();
+ if (!getContextSet(true, monitor.getElements(), set, this)) return;
+ if (set.size() == 0) {
+ monitor.setStatus(Status.OK_STATUS);
+ monitor.done();
+ }
+ else {
+ final Set<Runnable> wait_list = new HashSet<Runnable>();
+ for (IRunControl.RunControlContext ctx : set) {
+ Runnable done = new Runnable() {
+ public void run() {
+ wait_list.remove(this);
+ if (wait_list.isEmpty()) monitor.done();
+ }
+ };
+ wait_list.add(done);
+ execute(monitor, ctx, !model.isInstructionSteppingEnabled(), done);
+ }
+ }
+ }
+ };
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepIntoCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepIntoCommand.java
new file mode 100644
index 000000000..4f6c98a67
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepIntoCommand.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IStepIntoHandler;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFActionStepInto;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+
+public class StepIntoCommand extends StepCommand implements IStepIntoHandler {
+
+ private static class StepStateMachine extends TCFActionStepInto {
+
+ private final IDebugCommandRequest monitor;
+ private final Runnable done;
+ private final TCFNodeExecContext node;
+
+ StepStateMachine(TCFModel model, IDebugCommandRequest monitor,
+ IRunControl.RunControlContext ctx, boolean src_step, Runnable done) {
+ super(model.getLaunch(), ctx, src_step, false);
+ this.monitor = monitor;
+ this.done = done;
+ node = (TCFNodeExecContext)model.getNode(ctx.getID());
+ }
+
+ @Override
+ protected TCFDataCache<TCFContextState> getContextState() {
+ if (node == null) return null;
+ return node.getState();
+ }
+
+ @Override
+ protected TCFDataCache<TCFSourceRef> getLineInfo() {
+ TCFNodeStackFrame frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return null;
+ return frame.getLineInfo();
+ }
+
+ @Override
+ protected TCFDataCache<?> getStackTrace() {
+ return node.getStackTrace();
+ }
+
+ @Override
+ protected void exit(Throwable error) {
+ if (exited) return;
+ super.exit(error);
+ if (error != null && node.getChannel().getState() == IChannel.STATE_OPEN) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, 0, "Cannot step: " + error.getLocalizedMessage(), error));
+ }
+ done.run();
+ }
+ }
+
+ public StepIntoCommand(TCFModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean canExecute(IRunControl.RunControlContext ctx) {
+ if (ctx == null) return false;
+ if (ctx.canResume(IRunControl.RM_STEP_INTO_LINE)) return true;
+ if (ctx.canResume(IRunControl.RM_STEP_INTO)) return true;
+ return false;
+ }
+
+ @Override
+ protected void execute(final IDebugCommandRequest monitor, final IRunControl.RunControlContext ctx,
+ boolean src_step, final Runnable done) {
+ new StepStateMachine(model, monitor, ctx, src_step, done);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepOverCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepOverCommand.java
new file mode 100644
index 000000000..cda698a99
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepOverCommand.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IStepOverHandler;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFActionStepOver;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.IStackTrace.StackTraceContext;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+public class StepOverCommand extends StepCommand implements IStepOverHandler {
+
+ private static class StepStateMachine extends TCFActionStepOver {
+
+ private final IDebugCommandRequest monitor;
+ private final Runnable done;
+ private final TCFNodeExecContext node;
+ private TCFNodeStackFrame frame;
+
+ StepStateMachine(TCFModel model, IDebugCommandRequest monitor,
+ IRunControl.RunControlContext ctx,
+ boolean src_step, Runnable done) {
+ super(model.getLaunch(), ctx, src_step, false);
+ this.monitor = monitor;
+ this.done = done;
+ node = (TCFNodeExecContext)model.getNode(ctx.getID());
+ }
+
+ @Override
+ protected TCFDataCache<TCFContextState> getContextState() {
+ if (node == null) return null;
+ return node.getState();
+ }
+
+ @Override
+ protected TCFDataCache<TCFSourceRef> getLineInfo() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return null;
+ return frame.getLineInfo();
+ }
+
+ @Override
+ protected TCFDataCache<StackTraceContext> getStackFrame() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return null;
+ return frame.getStackTraceContext();
+ }
+
+ @Override
+ protected int getStackFrameIndex() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return 0;
+ return frame.getFrameNo();
+ }
+
+ @Override
+ protected TCFDataCache<?> getStackTrace() {
+ return node.getStackTrace();
+ }
+
+ @Override
+ protected void exit(Throwable error) {
+ if (exited) return;
+ super.exit(error);
+ if (error != null && node.getChannel().getState() == IChannel.STATE_OPEN) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, 0, "Cannot step: " + error.getLocalizedMessage(), error));
+ }
+ done.run();
+ }
+ }
+
+ public StepOverCommand(TCFModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean canExecute(IRunControl.RunControlContext ctx) {
+ if (ctx == null) return false;
+ if (ctx.canResume(IRunControl.RM_STEP_OVER_LINE)) return true;
+ if (ctx.canResume(IRunControl.RM_STEP_OVER)) return true;
+ if (ctx.canResume(IRunControl.RM_STEP_INTO) && model.getLaunch().getService(IBreakpoints.class) != null) return true;
+ return false;
+ }
+
+ @Override
+ protected void execute(final IDebugCommandRequest monitor, final IRunControl.RunControlContext ctx,
+ boolean src_step, final Runnable done) {
+ new StepStateMachine(model, monitor, ctx, src_step, done);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepReturnCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepReturnCommand.java
new file mode 100644
index 000000000..638be3559
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/StepReturnCommand.java
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IStepReturnHandler;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFActionStepOut;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.services.IStackTrace.StackTraceContext;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+
+public class StepReturnCommand extends StepCommand implements IStepReturnHandler {
+
+ private static class StepStateMachine extends TCFActionStepOut {
+
+ private final IDebugCommandRequest monitor;
+ private final Runnable done;
+ private final TCFNodeExecContext node;
+ private TCFNodeStackFrame frame;
+
+ StepStateMachine(TCFModel model, IDebugCommandRequest monitor,
+ IRunControl.RunControlContext ctx, Runnable done) {
+ super(model.getLaunch(), ctx, false);
+ this.monitor = monitor;
+ this.done = done;
+ node = (TCFNodeExecContext)model.getNode(ctx.getID());
+ }
+
+ @Override
+ protected TCFDataCache<TCFContextState> getContextState() {
+ if (node == null) return null;
+ return node.getState();
+ }
+
+ @Override
+ protected TCFDataCache<StackTraceContext> getStackFrame() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return null;
+ return frame.getStackTraceContext();
+ }
+
+ @Override
+ protected int getStackFrameIndex() {
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
+ if (frame == null) return 0;
+ return frame.getFrameNo();
+ }
+
+ @Override
+ protected TCFDataCache<?> getStackTrace() {
+ return node.getStackTrace();
+ }
+
+ @Override
+ protected void exit(Throwable error) {
+ if (exited) return;
+ super.exit(error);
+ if (error != null && node.getChannel().getState() == IChannel.STATE_OPEN) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, 0, "Cannot step: " + error.getLocalizedMessage(), error));
+ }
+ done.run();
+ }
+ }
+
+ public StepReturnCommand(TCFModel model) {
+ super(model);
+ }
+
+ @Override
+ protected boolean canExecute(IRunControl.RunControlContext ctx) {
+ if (ctx == null) return false;
+ if (ctx.canResume(IRunControl.RM_STEP_OUT)) return true;
+ if (!ctx.hasState()) return false;
+ if (ctx.canResume(IRunControl.RM_RESUME) && model.getLaunch().getService(IBreakpoints.class) != null) return true;
+ return false;
+ }
+
+ @Override
+ protected void execute(final IDebugCommandRequest monitor, final IRunControl.RunControlContext ctx,
+ boolean src_step, final Runnable done) {
+ new StepStateMachine(model, monitor, ctx, done);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SuspendCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SuspendCommand.java
new file mode 100644
index 000000000..133daf61f
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/SuspendCommand.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.core.commands.ISuspendHandler;
+import org.eclipse.tm.internal.tcf.debug.actions.TCFAction;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+
+public class SuspendCommand implements ISuspendHandler {
+
+ private final TCFModel model;
+
+ public SuspendCommand(TCFModel model) {
+ this.model = model;
+ }
+
+ public void canExecute(final IEnabledStateRequest monitor) {
+ new TCFRunnable(monitor) {
+ public void run() {
+ if (done) return;
+ Object[] elements = monitor.getElements();
+ boolean res = false;
+ for (int i = 0; i < elements.length; i++) {
+ TCFNode node = null;
+ if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
+ else node = model.getRootNode();
+ while (node != null && !node.isDisposed()) {
+ IRunControl.RunControlContext ctx = null;
+ if (node instanceof TCFNodeExecContext) {
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
+ }
+ if (ctx == null) {
+ node = node.getParent();
+ }
+ else if (model.getActiveAction(ctx.getID()) != null) {
+ res = true;
+ break;
+ }
+ else {
+ if (!ctx.canSuspend()) break;
+ if (ctx.isContainer()) {
+ TCFNodeExecContext.ChildrenStateInfo s = new TCFNodeExecContext.ChildrenStateInfo();
+ if (!((TCFNodeExecContext)node).hasSuspendedChildren(s, this)) return;
+ if (s.running) res = true;
+ }
+ if (ctx.hasState()) {
+ TCFDataCache<TCFContextState> state_cache = ((TCFNodeExecContext)node).getState();
+ if (!state_cache.validate(this)) return;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data != null && !state_data.is_suspended && ctx.canSuspend()) res = true;
+ }
+ break;
+ }
+ }
+ }
+ monitor.setEnabled(res);
+ monitor.setStatus(Status.OK_STATUS);
+ done();
+ }
+ };
+ }
+
+ public boolean execute(final IDebugCommandRequest monitor) {
+ new TCFRunnable(monitor) {
+ public void run() {
+ if (done) return;
+ Object[] elements = monitor.getElements();
+ Set<IRunControl.RunControlContext> set = new HashSet<IRunControl.RunControlContext>();
+ for (int i = 0; i < elements.length; i++) {
+ TCFNode node = null;
+ if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
+ else node = model.getRootNode();
+ while (node != null && !node.isDisposed()) {
+ IRunControl.RunControlContext ctx = null;
+ if (node instanceof TCFNodeExecContext) {
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
+ }
+ if (ctx == null) {
+ node = node.getParent();
+ }
+ else {
+ set.add(ctx);
+ break;
+ }
+ }
+ }
+ final Set<IToken> cmds = new HashSet<IToken>();
+ for (Iterator<IRunControl.RunControlContext> i = set.iterator(); i.hasNext();) {
+ IRunControl.RunControlContext ctx = i.next();
+ model.getLaunch().removeContextActions(ctx.getID());
+ final TCFAction action = model.getActiveAction(ctx.getID());
+ if (action != null) action.abort();
+ cmds.add(ctx.suspend(new IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ assert cmds.contains(token);
+ cmds.remove(token);
+ if (error != null && action == null) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, IStatus.OK, "Cannot suspend: " + error.getLocalizedMessage(), error));
+ }
+ if (cmds.isEmpty()) done();
+ }
+ }));
+ }
+ }
+ };
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/TerminateCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/TerminateCommand.java
new file mode 100644
index 000000000..b4cdebc5c
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/TerminateCommand.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.commands.IDebugCommandRequest;
+import org.eclipse.debug.core.commands.IEnabledStateRequest;
+import org.eclipse.debug.core.commands.ITerminateHandler;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFChildren;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+
+public class TerminateCommand implements ITerminateHandler {
+
+ public TerminateCommand(TCFModel model) {
+ }
+
+ public void canExecute(final IEnabledStateRequest monitor) {
+ new TCFRunnable(monitor) {
+ public void run() {
+ if (done) return;
+ Object[] elements = monitor.getElements();
+ boolean res = false;
+ for (int i = 0; i < elements.length; i++) {
+ TCFNode node = null;
+ if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
+ while (node != null && !node.isDisposed()) {
+ if (node instanceof TCFNodeExecContext) {
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ IRunControl.RunControlContext ctx = cache.getData();
+ if (ctx != null && ctx.canTerminate()) {
+ res = true;
+ }
+ else {
+ TCFChildren children_cache = ((TCFNodeExecContext)node).getChildren();
+ if (!children_cache.validate(this)) return;
+ for (TCFNode child : children_cache.toArray()) {
+ cache = ((TCFNodeExecContext)child).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
+ if (ctx != null && ctx.canTerminate()) {
+ res = true;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ node = node.getParent();
+ }
+ }
+ monitor.setEnabled(res);
+ monitor.setStatus(Status.OK_STATUS);
+ done();
+ }
+ };
+ }
+
+ public boolean execute(final IDebugCommandRequest monitor) {
+ new TCFRunnable(monitor) {
+ public void run() {
+ if (done) return;
+ Object[] elements = monitor.getElements();
+ Set<IRunControl.RunControlContext> set = new HashSet<IRunControl.RunControlContext>();
+ for (int i = 0; i < elements.length; i++) {
+ TCFNode node = null;
+ if (elements[i] instanceof TCFNode) node = (TCFNode)elements[i];
+ while (node != null && !node.isDisposed()) {
+ if (node instanceof TCFNodeExecContext) {
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ IRunControl.RunControlContext ctx = cache.getData();
+ if (ctx != null && ctx.canTerminate()) {
+ set.add(ctx);
+ }
+ else {
+ TCFChildren children_cache = ((TCFNodeExecContext)node).getChildren();
+ if (!children_cache.validate(this)) return;
+ for (TCFNode child : children_cache.toArray()) {
+ cache = ((TCFNodeExecContext)child).getRunContext();
+ if (!cache.validate(this)) return;
+ IRunControl.RunControlContext child_ctx = cache.getData();
+ if (child_ctx != null && child_ctx.canTerminate()) {
+ if (ctx != null) set.add(ctx);
+ else set.add(child_ctx);
+ }
+ }
+ }
+ break;
+ }
+ node = node.getParent();
+ }
+ }
+ final Set<IToken> cmds = new HashSet<IToken>();
+ for (Iterator<IRunControl.RunControlContext> i = set.iterator(); i.hasNext();) {
+ IRunControl.RunControlContext ctx = i.next();
+ cmds.add(ctx.terminate(new IRunControl.DoneCommand() {
+ public void doneCommand(IToken token, Exception error) {
+ assert cmds.contains(token);
+ cmds.remove(token);
+ if (error != null) {
+ monitor.setStatus(new Status(IStatus.ERROR,
+ Activator.PLUGIN_ID, IStatus.OK, "Cannot resume: " + error.getLocalizedMessage(), error));
+ }
+ if (cmds.isEmpty()) done();
+ }
+ }));
+ }
+ }
+ };
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/UpdatePolicyMenu.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/UpdatePolicyMenu.java
new file mode 100644
index 000000000..80a1d8a78
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/UpdatePolicyMenu.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.jface.action.ContributionItem;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.MenuListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.CompoundContributionItem;
+
+public class UpdatePolicyMenu extends CompoundContributionItem {
+
+ private static final String[] policy_names = {
+ "Automatic",
+ "Manual",
+ "Breakpoint Hit",
+ };
+
+ @Override
+ protected IContributionItem[] getContributionItems() {
+ IContributionItem[] items = new IContributionItem[policy_names.length];
+ for (int i = 0; i < items.length; i++) {
+ final int n = i;
+ items[i] = new ContributionItem() {
+ @Override
+ public void fill(final Menu menu, int index) {
+ final MenuItem item = new MenuItem(menu, SWT.RADIO);
+ item.setText(policy_names[n]);
+ final MenuListener menu_listener = new MenuListener() {
+ public void menuShown(MenuEvent e) {
+ item.setSelection(getPolicy() == n);
+ }
+ public void menuHidden(MenuEvent e) {
+ }
+ };
+ menu.addMenuListener(menu_listener);
+ item.addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ menu.removeMenuListener(menu_listener);
+ }
+ });
+ item.addSelectionListener(new SelectionListener() {
+ public void widgetSelected(SelectionEvent e) {
+ if (item.getSelection()) setPolicy(n);
+ }
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+ }
+ };
+ }
+ return items;
+ }
+
+ private IWorkbenchPart getPart() {
+ return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart();
+ }
+
+ private TCFNode getRootNode(IWorkbenchPart part) {
+ IWorkbenchPartSite site = part.getSite();
+ if (site == null || IDebugUIConstants.ID_DEBUG_VIEW.equals(site.getId())) {
+ return null;
+ }
+ if (part instanceof IDebugView) {
+ Object input = ((IDebugView)part).getViewer().getInput();
+ if (input instanceof TCFNode) return (TCFNode)input;
+ }
+ return null;
+ }
+
+ private int getPolicy() {
+ final IWorkbenchPart part = getPart();
+ if (part == null) return 0;
+ final TCFNode node = getRootNode(part);
+ if (node == null) return 0;
+ return new TCFTask<Integer>(node.getChannel()) {
+ public void run() {
+ TCFModel model = node.getModel();
+ if (!model.isLocked(part)) done(TCFModel.UPDATE_POLICY_AUTOMATIC);
+ else done(model.getLockPolicy(part));
+ }
+ }.getE();
+ }
+
+ private void setPolicy(final int n) {
+ final IWorkbenchPart part = getPart();
+ if (part == null) return;
+ final TCFNode node = getRootNode(part);
+ if (node == null) return;
+ new TCFTask<Object>(node.getChannel()) {
+ public void run() {
+ TCFModel model = node.getModel();
+ model.setLockPolicy(part, n);
+ done(null);
+ }
+ }.getE();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/ViewMemoryCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/ViewMemoryCommand.java
new file mode 100644
index 000000000..aa189e831
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/ViewMemoryCommand.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import java.util.ArrayList;
+
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExpression;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNumberFormat;
+import org.eclipse.tm.tcf.services.IExpressions;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IWorkbenchPage;
+
+public class ViewMemoryCommand extends AbstractActionDelegate {
+
+ private static class Block {
+ long addr;
+ long size;
+ }
+
+ @Override
+ protected void run() {
+ try {
+ IWorkbenchPage page = getWindow().getActivePage();
+ page.showView(IDebugUIConstants.ID_MEMORY_VIEW, null, IWorkbenchPage.VIEW_ACTIVATE);
+ final ArrayList<IMemoryBlock> list = new ArrayList<IMemoryBlock>();
+ for (final TCFNode node : getSelectedNodes()) {
+ final IMemoryBlockRetrievalExtension mem_retrieval = (IMemoryBlockRetrievalExtension)
+ node.getAdapter(IMemoryBlockRetrievalExtension.class);
+ if (mem_retrieval == null) continue;
+ Block b = new TCFTask<Block>(node.getChannel()) {
+ public void run() {
+ try {
+ Number addr = null;
+ long size = -1;
+ if (node instanceof TCFNodeExpression) {
+ TCFDataCache<IExpressions.Value> val_cache = ((TCFNodeExpression)node).getValue();
+ if (!val_cache.validate(this)) return;
+ IExpressions.Value val_data = val_cache.getData();
+ if (val_data != null) {
+ addr = val_data.getAddress();
+ if (addr != null) {
+ byte[] bytes = val_data.getValue();
+ if (bytes != null) size = bytes.length;
+ }
+ else if (val_data.getRegisterID() != null) {
+ byte[] bytes = val_data.getValue();
+ if (bytes != null) {
+ addr = TCFNumberFormat.toBigInteger(bytes, 0, bytes.length,
+ val_data.isBigEndian(), false);
+ }
+ }
+ }
+ }
+ Block b = null;
+ if (addr != null) {
+ b = new Block();
+ b.addr = addr.longValue();
+ b.size = size;
+ }
+ done(b);
+ }
+ catch (Exception x) {
+ error(x);
+ }
+ }
+ }.get();
+ if (b != null) list.add(mem_retrieval.getMemoryBlock(b.addr, b.size));
+ }
+ DebugPlugin.getDefault().getMemoryBlockManager().addMemoryBlocks(list.toArray(new IMemoryBlock[list.size()]));
+ }
+ catch (Exception x) {
+ Activator.log("Cannot open memory view", x);
+ }
+ }
+
+ @Override
+ protected void selectionChanged() {
+ getAction().setEnabled(getSelectedNodes().length > 0);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/WatchInExpressionsCommand.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/WatchInExpressionsCommand.java
new file mode 100644
index 000000000..931ac3fa1
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/commands/WatchInExpressionsCommand.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.commands;
+
+import org.eclipse.debug.core.IExpressionManager;
+import org.eclipse.debug.core.model.IExpression;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.model.IWatchInExpressions;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IWorkbenchPage;
+
+public class WatchInExpressionsCommand extends AbstractActionDelegate {
+
+ @Override
+ protected void selectionChanged() {
+ getAction().setEnabled(getNodes().length > 0);
+ }
+
+ @Override
+ protected void run() {
+ try {
+ IWorkbenchPage page = getWindow().getActivePage();
+ page.showView(IDebugUIConstants.ID_EXPRESSION_VIEW, null, IWorkbenchPage.VIEW_ACTIVATE);
+ for (final TCFNode node : getNodes()) {
+ final IExpressionManager manager = node.getModel().getExpressionManager();
+ IExpression e = new TCFTask<IExpression>(node.getChannel()) {
+ public void run() {
+ try {
+ IExpression e = null;
+ if (node instanceof IWatchInExpressions) {
+ TCFDataCache<String> text_cache = ((IWatchInExpressions)node).getExpressionText();
+ if (!text_cache.validate(this)) return;
+ String text_data = text_cache.getData();
+ if (text_data != null) {
+ for (final IExpression x : manager.getExpressions()) {
+ if (text_data.equals(x.getExpressionText())) {
+ done(null);
+ return;
+ }
+ }
+ e = manager.newWatchExpression(text_data);
+ }
+ }
+ done(e);
+ }
+ catch (Exception x) {
+ error(x);
+ }
+ }
+ }.get();
+ if (e != null) manager.addExpression(e);
+ }
+ }
+ catch (Exception x) {
+ Activator.log("Cannot open expressions view", x);
+ }
+ }
+
+ private TCFNode[] getNodes() {
+ TCFNode[] arr = getSelectedNodes();
+ for (TCFNode n : arr) {
+ if (n instanceof IWatchInExpressions) continue;
+ return new TCFNode[0];
+ }
+ return arr;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ITCFLaunchContext.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ITCFLaunchContext.java
new file mode 100644
index 000000000..a63183ffa
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/ITCFLaunchContext.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * TCF clients can implement ITCFLaunchContext to provide information about
+ * workspace projects to TCF Launch Configuration.
+ *
+ * The information includes default values for launch configuration attributes,
+ * list of executable binary files, etc.
+ *
+ * Since each project type can have its own methods to retrieve relevant information,
+ * there should be implementation of this interface for each project type that support TCF.
+ *
+ * Implementation should be able to examine current IDE state (like active editor input source,
+ * project explorer selection, etc.) and figure out an "active project".
+ */
+public interface ITCFLaunchContext {
+
+ /**
+ * Check if this context is currently active.
+ * @return true if active.
+ */
+ boolean isActive();
+
+ /**
+ * Check if this context recognizes type of a selection.
+ * @param selection
+ * @return true if the selection is supported by this context.
+ */
+ boolean isSupportedSelection(Object selection);
+
+ /**
+ * Get selection project.
+ * @param selection
+ * @return selection project or null if selection is not part of a project
+ */
+ IProject getProject(Object selection);
+
+ /**
+ * Get selection file path.
+ * @param selection
+ * @return selection file path or null if selection is not a file
+ */
+ IPath getPath(Object selection);
+
+ /**
+ * Set launch configuration attributes to default values best suited for current context.
+ * @param dlg - currently open launch configuration dialog
+ * @param config - currently open launch configuration
+ */
+ void setDefaults(ILaunchConfigurationDialog dlg, ILaunchConfigurationWorkingCopy config);
+
+ /**
+ * Get project build configuration ID.
+ * @param project
+ * @return build configuration ID.
+ */
+ String getBuildConfigID(IProject project);
+
+ /**
+ * Show a dialog box that allows user to select executable binary file from a list
+ * of available file in this context.
+ * @param project_name
+ * @param shell
+ * @return binary file path
+ */
+ String chooseBinary(Shell shell, IProject project);
+
+ /**
+ * Check if a path represents an executable binary file.
+ * @param project
+ * @param path - full path to a file in the project
+ * @return
+ * @throws CoreException
+ */
+ boolean isBinary(IProject project, IPath path) throws CoreException;
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/PeerPropsDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/PeerPropsDialog.java
new file mode 100644
index 000000000..36b41479d
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/PeerPropsDialog.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.ui.launch.setup.PeerPropsControl;
+
+class PeerPropsDialog extends Dialog {
+
+ private final Map<String,String> attrs;
+ private final boolean enable_editing;
+ private final Image image;
+
+ private PeerPropsControl props;
+
+ PeerPropsDialog(Shell parent, Image image, Map<String,String> attrs, boolean enable_editing) {
+ super(parent);
+ this.image = image;
+ this.attrs = attrs;
+ this.enable_editing = enable_editing;
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("TCF Peer Properties");
+ shell.setImage(image);
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, "&OK", true);
+ updateButtons();
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+ props = new PeerPropsControl(composite, attrs, enable_editing, new Runnable() {
+ public void run() {
+ updateButtons();
+ }
+ });
+ composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+ return composite;
+ }
+
+ private void updateButtons() {
+ getButton(IDialogConstants.OK_ID).setEnabled(props.isComplete());
+ }
+
+ @Override
+ protected void okPressed() {
+ props.okPressed();
+ super.okPressed();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFArgumentsTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFArgumentsTab.java
new file mode 100644
index 000000000..71baba1d7
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFArgumentsTab.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.StringVariableSelectionDialog;
+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.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+
+
+public class TCFArgumentsTab extends AbstractLaunchConfigurationTab {
+
+ private Text text_arguments;
+ private Button button_variables;
+ private Exception init_error;
+
+ public void createControl(Composite parent) {
+ Font font = parent.getFont();
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, true);
+ comp.setLayout(layout);
+ comp.setFont(font);
+
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ comp.setLayoutData(gd);
+ setControl(comp);
+
+ createArgumentsGroup(comp);
+ }
+
+ private void createArgumentsGroup(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ comp.setLayoutData(gd);
+
+ Label label = new Label(comp, SWT.NONE);
+ label.setText("Program Arguments:");
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ label.setLayoutData(gd);
+
+ text_arguments = new Text(comp, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL);
+ gd = new GridData(GridData.FILL_BOTH);
+ gd.heightHint = 40;
+ gd.widthHint = 100;
+ text_arguments.setLayoutData(gd);
+ text_arguments.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ button_variables = createPushButton(comp, "Variables", null);
+ gd = new GridData(GridData.HORIZONTAL_ALIGN_END);
+ button_variables.setLayoutData(gd);
+ button_variables.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent arg0) {
+ handleVariablesButtonSelected(text_arguments);
+ }
+ });
+ }
+
+ /**
+ * A variable entry button has been pressed for the given text
+ * field. Prompt the user for a variable and enter the result
+ * in the given field.
+ */
+ private void handleVariablesButtonSelected(Text textField) {
+ String variable = getVariable();
+ if (variable != null) textField.append(variable);
+ }
+
+ /**
+ * Prompts the user to choose and configure a variable and returns
+ * the resulting string, suitable to be used as an attribute.
+ */
+ private String getVariable() {
+ StringVariableSelectionDialog dialog = new StringVariableSelectionDialog(getShell());
+ dialog.open();
+ return dialog.getVariableExpression();
+ }
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+ config.setAttribute(TCFLaunchDelegate.ATTR_PROGRAM_ARGUMENTS, (String)null);
+ }
+
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ setErrorMessage(null);
+ setMessage(null);
+ try {
+ text_arguments.setText(configuration.getAttribute(TCFLaunchDelegate.ATTR_PROGRAM_ARGUMENTS, "")); //$NON-NLS-1$
+ }
+ catch (CoreException e) {
+ init_error = e;
+ setErrorMessage("Cannot read launch configuration: " + e);
+ Activator.log(e);
+ }
+ }
+
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(
+ TCFLaunchDelegate.ATTR_PROGRAM_ARGUMENTS,
+ getAttributeValueFrom(text_arguments));
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration config) {
+ setErrorMessage(null);
+ setMessage(null);
+
+ if (init_error != null) {
+ setErrorMessage("Cannot read launch configuration: " + init_error);
+ return false;
+ }
+
+ return true;
+ }
+
+ protected String getAttributeValueFrom(Text text) {
+ String content = text.getText().trim();
+ content = content.replaceAll("\r\n", "\n"); // eliminate Windows \r line delimiter
+ if (content.length() > 0) return content;
+ return null;
+ }
+
+ public String getName() {
+ return "Arguments";
+ }
+
+ @Override
+ public Image getImage() {
+ return ImageCache.getImageDescriptor(ImageCache.IMG_ARGUMENTS_TAB).createImage();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFLaunchContext.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFLaunchContext.java
new file mode 100644
index 000000000..ab0910489
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFLaunchContext.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.osgi.framework.Bundle;
+
+/**
+ * TCF clients can implement ITCFLaunchContext to provide information about
+ * workspace projects to TCF Launch Configuration.
+ *
+ * The information includes default values for launch configuration attributes,
+ * list of executable binary files, etc.
+ *
+ * Since each project type can have its own methods to retrieve relevant information,
+ * there should be implementation of this interface for each project type that support TCF.
+ *
+ * Implementation should be able to examine current IDE state (like active editor input source,
+ * project explorer selection, etc.) and figure out an "active project".
+ */
+public class TCFLaunchContext {
+
+ public static ITCFLaunchContext getLaunchContext(Object selection) {
+ try {
+ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.PLUGIN_ID, "launch_context");
+ IExtension[] extensions = point.getExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ try {
+ Bundle bundle = Platform.getBundle(extensions[i].getNamespaceIdentifier());
+ bundle.start(Bundle.START_TRANSIENT);
+ IConfigurationElement[] e = extensions[i].getConfigurationElements();
+ for (int j = 0; j < e.length; j++) {
+ String nm = e[j].getName();
+ if (nm.equals("class")) { //$NON-NLS-1$
+ Class<?> c = bundle.loadClass(e[j].getAttribute("name")); //$NON-NLS-1$
+ ITCFLaunchContext launch_context = (ITCFLaunchContext)c.newInstance();
+ if (selection != null) {
+ if (launch_context.isSupportedSelection(selection)) return launch_context;
+ }
+ else {
+ if (launch_context.isActive()) return launch_context;
+ }
+ }
+ }
+ }
+ catch (Throwable x) {
+ Activator.log("Cannot access launch context extension points", x);
+ }
+ }
+ }
+ catch (Exception x) {
+ Activator.log("Cannot access launch context extension points", x);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFLaunchShortcut.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFLaunchShortcut.java
new file mode 100644
index 000000000..c0f2ad8fc
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFLaunchShortcut.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+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.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugModelPresentation;
+import org.eclipse.debug.ui.ILaunchShortcut;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+/**
+ * This class implements extension point that provides support for selection sensitive launching using TCF.
+ * Extensions register a shortcut which appears in the run and/or debug cascade menus to launch
+ * the workbench selection or active editor.
+ */
+public class TCFLaunchShortcut implements ILaunchShortcut {
+
+ private static final String LAUNCH_CONFIGURATION_TYPE_ID = "org.eclipse.tm.tcf.debug.LaunchConfigurationType"; //$NON-NLS-1$
+
+ public void launch(ISelection selection, String mode) {
+ if (selection instanceof IStructuredSelection) {
+ IStructuredSelection ss = (IStructuredSelection)selection;
+ Object obj = ss.getFirstElement();
+ ITCFLaunchContext context = TCFLaunchContext.getLaunchContext(obj);
+ IProject project = context.getProject(obj);
+ IPath path = context.getPath(obj);
+ ILaunchConfiguration config = null;
+ List<ILaunchConfiguration> list = searchConfigurations(project, path);
+ if (list != null) {
+ int count = list.size();
+ if (count == 0) {
+ config = createConfiguration(project, path);
+ }
+ else if (count == 1) {
+ config = list.get(0);
+ }
+ else {
+ config = chooseConfiguration(list);
+ }
+ if (config != null) DebugUITools.launch(config, mode);
+ }
+ }
+ }
+
+ public void launch(IEditorPart editor, String mode) {
+ }
+
+ private List<ILaunchConfiguration> searchConfigurations(IProject project, IPath path) {
+ try {
+ List<ILaunchConfiguration> list = new ArrayList<ILaunchConfiguration>();
+ ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
+ ILaunchConfigurationType type = manager.getLaunchConfigurationType(LAUNCH_CONFIGURATION_TYPE_ID);
+ ILaunchConfiguration[] configs = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations(type);
+ for (ILaunchConfiguration config : configs) {
+ if (config.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, "").equals(path.toOSString()) && //$NON-NLS-1$
+ config.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "").equals(project.getName())) { //$NON-NLS-1$
+ list.add(config);
+ }
+ }
+ return list;
+ }
+ catch (CoreException x) {
+ MessageDialog.openError(getShell(), "Error searching available launch configurations", x.getStatus().getMessage());
+ return null;
+ }
+ }
+
+ private ILaunchConfiguration chooseConfiguration(List<ILaunchConfiguration> list) {
+ IDebugModelPresentation labelProvider = DebugUITools.newDebugModelPresentation();
+ ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), labelProvider);
+ dialog.setElements(list.toArray());
+ dialog.setTitle("TCF Launch Configuration");
+ dialog.setMessage("&Select existing configuration:");
+ dialog.setMultipleSelection(false);
+ int result = dialog.open();
+ labelProvider.dispose();
+ if (result == Window.OK) return (ILaunchConfiguration) dialog.getFirstResult();
+ return null;
+ }
+
+ private ILaunchConfiguration createConfiguration(IProject project, IPath path) {
+ ILaunchConfiguration config = null;
+ ILaunchConfigurationWorkingCopy wc = null;
+ try {
+ ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
+ ILaunchConfigurationType type = manager.getLaunchConfigurationType(LAUNCH_CONFIGURATION_TYPE_ID);
+ wc = type.newInstance(null, manager.generateUniqueLaunchConfigurationNameFrom("TCF Local Host " + path.lastSegment()));
+ wc.setAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, path.toOSString());
+ wc.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, project.getName());
+ // wc.setMappedResources(new IResource[] { });
+ config = wc.doSave();
+ }
+ catch (CoreException x) {
+ MessageDialog.openError(getShell(), "Cannot create launch configuration", x.getStatus().getMessage());
+ }
+ return config;
+ }
+
+ private Shell getShell() {
+ Shell shell = null;
+ IWorkbenchWindow window = Activator.getDefault().getWorkbench().getActiveWorkbenchWindow();
+ if (window != null) shell = window.getShell();
+ return shell;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java
new file mode 100644
index 000000000..4a2cfce21
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMainTab.java
@@ -0,0 +1,476 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IProject;
+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.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+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.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.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+public class TCFMainTab extends AbstractLaunchConfigurationTab {
+
+ private Text project_text;
+ private Text local_program_text;
+ private Text remote_program_text;
+ private Text working_dir_text;
+ private Button default_dir_button;
+ private Button attach_children_button;
+ private Button disconnect_on_ctx_exit;
+ private Button terminal_button;
+ private Exception init_error;
+
+ public void createControl(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ setControl(comp);
+
+ GridLayout topLayout = new GridLayout();
+ comp.setLayout(topLayout);
+
+ createVerticalSpacer(comp, 1);
+ createProjectGroup(comp);
+ createApplicationGroup(comp);
+ createWorkingDirGroup(comp);
+ createVerticalSpacer(comp, 1);
+ createOptionButtons(comp, 1);
+ }
+
+ private void createProjectGroup(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ group.setText("Project");
+
+ Label label = new Label(group, SWT.NONE);
+ label.setText("Project Name:");
+ GridData gd = new GridData();
+ gd.horizontalSpan = 2;
+ label.setLayoutData(gd);
+
+ project_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ gd = new GridData(GridData.FILL_HORIZONTAL);
+ project_text.setLayoutData(gd);
+ project_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ Button project_button = createPushButton(group, "Browse...", null);
+ project_button.addSelectionListener(new SelectionAdapter() {
+
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ handleProjectButtonSelected();
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ private void createApplicationGroup(Composite parent) {
+ Group group = new Group(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ group.setText("Application");
+
+ createLocalExeFileGroup(group);
+ createRemoteExeFileGroup(group);
+ }
+
+ private void createLocalExeFileGroup(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 3;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ comp.setLayoutData(gd);
+
+ Label program_label = new Label(comp, SWT.NONE);
+ program_label.setText("Local File Path:");
+ gd = new GridData();
+ gd.horizontalSpan = 3;
+ program_label.setLayoutData(gd);
+
+ local_program_text = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ local_program_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ local_program_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ Button search_button = createPushButton(comp, "Search...", null);
+ search_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ handleSearchButtonSelected();
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ Button browse_button = createPushButton(comp, "Browse...", null);
+ browse_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ handleBinaryBrowseButtonSelected();
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ private void createRemoteExeFileGroup(Composite parent) {
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ comp.setLayoutData(gd);
+
+ Label program_label = new Label(comp, SWT.NONE);
+ program_label.setText("Remote File Path:");
+ gd = new GridData();
+ gd.horizontalSpan = 3;
+ program_label.setLayoutData(gd);
+
+ remote_program_text = new Text(comp, SWT.SINGLE | SWT.BORDER);
+ remote_program_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ remote_program_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ private void createWorkingDirGroup(Composite comp) {
+ Group group = new Group(comp, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ group.setText("Working directory");
+
+ working_dir_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ working_dir_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ working_dir_text.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ default_dir_button = new Button(group, SWT.CHECK);
+ default_dir_button.setText("Use default");
+ default_dir_button.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
+ default_dir_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ @Override
+ protected void updateLaunchConfigurationDialog() {
+ super.updateLaunchConfigurationDialog();
+ working_dir_text.setEnabled(!default_dir_button.getSelection());
+ }
+
+ private void createOptionButtons(Composite parent, int col_span) {
+ Composite terminal_comp = new Composite(parent, SWT.NONE);
+ GridLayout terminal_layout = new GridLayout();
+ terminal_layout.numColumns = 1;
+ terminal_layout.marginHeight = 0;
+ terminal_layout.marginWidth = 0;
+ terminal_comp.setLayout(terminal_layout);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ gd.horizontalSpan = col_span;
+ terminal_comp.setLayoutData(gd);
+
+ attach_children_button = createCheckButton(terminal_comp, "Auto-attach process children");
+ attach_children_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ attach_children_button.setEnabled(true);
+
+ disconnect_on_ctx_exit = createCheckButton(terminal_comp, "Disconnect when last debug context exits");
+ disconnect_on_ctx_exit.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ disconnect_on_ctx_exit.setEnabled(true);
+
+ terminal_button = createCheckButton(terminal_comp, "Use pseudo-terminal for process standard I/O");
+ terminal_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ terminal_button.setEnabled(true);
+ }
+
+ public void initializeFrom(ILaunchConfiguration config) {
+ setErrorMessage(null);
+ setMessage(null);
+ try {
+ project_text.setText(config.getAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, ""));
+ local_program_text.setText(config.getAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, ""));
+ remote_program_text.setText(config.getAttribute(TCFLaunchDelegate.ATTR_REMOTE_PROGRAM_FILE, ""));
+ working_dir_text.setText(config.getAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, ""));
+ default_dir_button.setSelection(!config.hasAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY));
+ attach_children_button.setSelection(config.getAttribute(TCFLaunchDelegate.ATTR_ATTACH_CHILDREN, true));
+ disconnect_on_ctx_exit.setSelection(config.getAttribute(TCFLaunchDelegate.ATTR_DISCONNECT_ON_CTX_EXIT, true));
+ terminal_button.setSelection(config.getAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, true));
+ working_dir_text.setEnabled(!default_dir_button.getSelection());
+ }
+ catch (Exception e) {
+ init_error = e;
+ setErrorMessage("Cannot read launch configuration: " + e);
+ Activator.log(e);
+ }
+ }
+
+ private IProject getProject() {
+ String name = project_text.getText().trim();
+ if (name.length() == 0) return null;
+ return ResourcesPlugin.getWorkspace().getRoot().getProject(name);
+ }
+
+ public void performApply(ILaunchConfigurationWorkingCopy config) {
+ config.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, project_text.getText());
+ config.setAttribute(TCFLaunchDelegate.ATTR_LOCAL_PROGRAM_FILE, local_program_text.getText());
+ config.setAttribute(TCFLaunchDelegate.ATTR_REMOTE_PROGRAM_FILE, remote_program_text.getText());
+ if (default_dir_button.getSelection()) {
+ config.removeAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY);
+ }
+ else {
+ config.setAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, working_dir_text.getText());
+ }
+ config.setAttribute(TCFLaunchDelegate.ATTR_ATTACH_CHILDREN, attach_children_button.getSelection());
+ config.setAttribute(TCFLaunchDelegate.ATTR_DISCONNECT_ON_CTX_EXIT, disconnect_on_ctx_exit.getSelection());
+ config.setAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, terminal_button.getSelection());
+ }
+
+ /**
+ * Show a dialog that lists all executable files in currently selected project.
+ */
+ private void handleSearchButtonSelected() {
+ IProject project = getProject();
+ if (project == null) {
+ MessageDialog.openInformation(getShell(),
+ "Project required",
+ "Enter project before searching for program");
+ return;
+ }
+ ITCFLaunchContext launch_context = TCFLaunchContext.getLaunchContext(project);
+ if (launch_context == null) return;
+ String path = launch_context.chooseBinary(getShell(), project);
+ if (path != null) local_program_text.setText(path);
+ }
+
+ /**
+ * Show a dialog that lets the user select a project. This in turn provides context for the main
+ * type, allowing the user to key a main type name, or constraining the search for main types to
+ * the specified project.
+ */
+ private void handleBinaryBrowseButtonSelected() {
+ FileDialog file_dialog = new FileDialog(getShell(), SWT.NONE);
+ file_dialog.setFileName(local_program_text.getText());
+ String path = file_dialog.open();
+ if (path != null) local_program_text.setText(path);
+ }
+
+ /**
+ * Show a dialog that lets the user select a project. This in turn provides context for the main
+ * type, allowing the user to key a main type name, or constraining the search for main types to
+ * the specified project.
+ */
+ private void handleProjectButtonSelected() {
+ try {
+ IProject project = chooseProject();
+ if (project == null) return;
+ project_text.setText(project.getName());
+ }
+ catch (Exception e) {
+ Activator.log("Cannot get project description", e);
+ }
+ }
+
+ /**
+ * Show project list dialog and return the first selected project, or null.
+ */
+ private IProject chooseProject() {
+ try {
+ IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ ILabelProvider label_provider = new LabelProvider() {
+
+ @Override
+ public String getText(Object element) {
+ if (element == null) return "";
+ return ((IProject)element).getName();
+ }
+ };
+ ElementListSelectionDialog dialog = new ElementListSelectionDialog(getShell(), label_provider);
+ dialog.setTitle("Project Selection");
+ dialog.setMessage("Choose project to constrain search for program");
+ dialog.setElements(projects);
+
+ IProject cProject = getProject();
+ if (cProject != null) dialog.setInitialSelections(new Object[]{cProject});
+ if (dialog.open() == Window.OK) return (IProject)dialog.getFirstResult();
+ }
+ catch (Exception e) {
+ Activator.log("Cannot show project list dialog", e);
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration config) {
+ setErrorMessage(null);
+ setMessage(null);
+
+ if (init_error != null) {
+ setErrorMessage("Cannot read launch configuration: " + init_error);
+ return false;
+ }
+
+ String project_name = project_text.getText().trim();
+ if (project_name.length() != 0) {
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(project_name);
+ if (!project.exists()) {
+ setErrorMessage("Project does not exist");
+ return false;
+ }
+ if (!project.isOpen()) {
+ setErrorMessage("Project must be opened");
+ return false;
+ }
+ }
+ String local_name = local_program_text.getText().trim();
+ if (local_name.equals(".") || local_name.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
+ setErrorMessage("Invalid local program name");
+ return false;
+ }
+ String remote_name = remote_program_text.getText().trim();
+ if (remote_name.equals(".") || remote_name.equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
+ setErrorMessage("Invalid remote program name");
+ return false;
+ }
+ if (local_name.length() > 0) {
+ IProject project = getProject();
+ IPath program_path = new Path(local_name);
+ if (!program_path.isAbsolute()) {
+ if (project == null) {
+ File ws = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile();
+ File file = new File(ws, local_name);
+ if (!file.exists()) {
+ setErrorMessage("File not found: " + file);
+ return false;
+ }
+ if (file.isDirectory()) {
+ setErrorMessage("Program path is directory name: " + file);
+ return false;
+ }
+ program_path = new Path(file.getAbsolutePath());
+ }
+ else if (!project.getFile(local_name).exists()) {
+ setErrorMessage("Program does not exist");
+ return false;
+ }
+ else {
+ program_path = project.getFile(local_name).getLocation();
+ }
+ }
+ else {
+ File file = program_path.toFile();
+ if (!file.exists()) {
+ setErrorMessage("Program file does not exist");
+ return false;
+ }
+ if (file.isDirectory()) {
+ setErrorMessage("Program path is directory name");
+ return false;
+ }
+ }
+ if (project != null) {
+ try {
+ ITCFLaunchContext launch_context = TCFLaunchContext.getLaunchContext(project);
+ if (launch_context != null && !launch_context.isBinary(project, program_path)) {
+ setErrorMessage("Program is not a recongnized executable");
+ return false;
+ }
+ }
+ catch (CoreException e) {
+ Activator.log(e);
+ setErrorMessage(e.getLocalizedMessage());
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+ config.setAttribute(TCFLaunchDelegate.ATTR_PROJECT_NAME, "");
+ config.setAttribute(TCFLaunchDelegate.ATTR_ATTACH_CHILDREN, true);
+ config.setAttribute(TCFLaunchDelegate.ATTR_DISCONNECT_ON_CTX_EXIT, true);
+ config.setAttribute(TCFLaunchDelegate.ATTR_USE_TERMINAL, true);
+ config.setAttribute(TCFLaunchDelegate.ATTR_WORKING_DIRECTORY, (String)null);
+ ITCFLaunchContext launch_context = TCFLaunchContext.getLaunchContext(null);
+ if (launch_context != null) launch_context.setDefaults(getLaunchConfigurationDialog(), config);
+ }
+
+ public String getName() {
+ return "Main";
+ }
+
+ @Override
+ public Image getImage() {
+ return ImageCache.getImage(ImageCache.IMG_TCF);
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMemoryMapTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMemoryMapTab.java
new file mode 100644
index 000000000..0654678f1
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFMemoryMapTab.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.internal.tcf.debug.ui.commands.MemoryMapWidget;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
+
+public class TCFMemoryMapTab extends AbstractLaunchConfigurationTab {
+
+ private static final String TAB_ID = "org.eclipse.tm.tcf.launch.memoryMapTab";
+
+ private MemoryMapWidget widget;
+
+ public void createControl(Composite parent) {
+ TCFNode node = null;
+ IAdaptable adaptable = DebugUITools.getDebugContext();
+ if (adaptable != null) node = (TCFNode)adaptable.getAdapter(TCFNode.class);
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, false);
+ composite.setFont(parent.getFont());
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1));
+ widget = new MemoryMapWidget(composite, node);
+ setControl(composite);
+ }
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy cfg) {
+ }
+
+ public void initializeFrom(ILaunchConfiguration cfg) {
+ setErrorMessage(null);
+ setMessage(null);
+ widget.loadData(cfg);
+ }
+
+ public void performApply(ILaunchConfigurationWorkingCopy cfg) {
+ try {
+ widget.saveData(cfg);
+ }
+ catch (Throwable x) {
+ setErrorMessage("Cannot update memory map: " + x);
+ }
+ }
+
+ public String getName() {
+ return "Symbol Files";
+ }
+
+ @Override
+ public Image getImage() {
+ return ImageCache.getImage(ImageCache.IMG_MEMORY_MAP);
+ }
+
+ @Override
+ public String getId() {
+ return TAB_ID;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java
new file mode 100644
index 000000000..f0e0b638c
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPathMapTab.java
@@ -0,0 +1,285 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+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.Item;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate.PathMapRule;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.tcf.services.IPathMap;
+
+// TODO: add source lookup container that represents ATTR_PATH_MAP
+public class TCFPathMapTab extends AbstractLaunchConfigurationTab {
+
+ private TableViewer viewer;
+ private Button button_remove;
+ private Button button_new;
+
+ private static final String[] column_ids = {
+ IPathMap.PROP_SOURCE,
+ IPathMap.PROP_DESTINATION,
+ IPathMap.PROP_CONTEXT,
+ };
+
+ private static final int[] column_size = {
+ 300,
+ 300,
+ 50,
+ };
+
+ private static final String TAB_ID = "org.eclipse.tm.tcf.launch.pathMapTab";
+
+ private ArrayList<PathMapRule> map;
+
+ private class FileMapContentProvider implements IStructuredContentProvider {
+
+ public Object[] getElements(Object input) {
+ return map.toArray(new PathMapRule[map.size()]);
+ }
+
+ public void inputChanged(Viewer viewer, Object old_input, Object new_input) {
+ }
+
+ public void dispose() {
+ }
+ }
+
+ private class FileMapLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+ public Image getColumnImage(Object element, int column) {
+ if (column == 0) return ImageCache.getImage(ImageCache.IMG_ATTRIBUTE);
+ return null;
+ }
+
+ public String getColumnText(Object element, int column) {
+ PathMapRule e = (PathMapRule)element;
+ Object o = e.getProperties().get(column_ids[column]);
+ if (o == null) return "";
+ return o.toString();
+ }
+ }
+
+ private class FileMapCellModifier implements ICellModifier {
+
+ public boolean canModify(Object element, String property) {
+ return true;
+ }
+
+ public Object getValue(Object element, String property) {
+ if (element instanceof Item) element = ((Item)element).getData();
+ PathMapRule a = (PathMapRule)element;
+ Object o = a.getProperties().get(property);
+ if (o == null) return "";
+ return o.toString();
+ }
+
+ public void modify(Object element, String property, Object value) {
+ if (element instanceof Item) element = ((Item)element).getData();
+ PathMapRule a = (PathMapRule)element;
+ if ("".equals(value)) a.getProperties().remove(property);
+ else a.getProperties().put(property, value);
+ viewer.update(element, new String[] { property });
+ updateLaunchConfigurationDialog();
+ }
+ }
+
+ private Exception init_error;
+
+ public String getName() {
+ return "Path Map";
+ }
+
+ @Override
+ public Image getImage() {
+ return ImageCache.getImage(ImageCache.IMG_PATH);
+ }
+
+ @Override
+ public String getId() {
+ return TAB_ID;
+ }
+
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, false);
+ composite.setFont(parent.getFont());
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1));
+ createTable(composite);
+ setControl(composite);
+ }
+
+ private void createTable(Composite parent) {
+ Font font = parent.getFont();
+ Label map_label = new Label(parent, SWT.WRAP);
+ map_label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ map_label.setFont(font);
+ map_label.setText("File path &map rules:");
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 1, 1));
+
+ viewer = new TableViewer(composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
+ Table table = viewer.getTable();
+ table.setLayoutData(new GridData(GridData.FILL_BOTH));
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+ table.setFont(font);
+ viewer.setContentProvider(new FileMapContentProvider());
+ viewer.setLabelProvider(new FileMapLabelProvider());
+ viewer.setColumnProperties(column_ids);
+
+ CellEditor[] editors = new CellEditor[column_ids.length];
+ for (int i = 0; i < column_ids.length; i++) {
+ TableColumn c = new TableColumn(table, SWT.NONE, i);
+ c.setText(column_ids[i]);
+ c.setWidth(column_size[i]);
+ editors[i] = new TextCellEditor(table);
+ }
+ viewer.setCellEditors(editors);
+ viewer.setCellModifier(new FileMapCellModifier());
+ createTableButtons(composite);
+ viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ public void selectionChanged(SelectionChangedEvent event) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ private void createTableButtons(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+
+ button_new = new Button(composite, SWT.PUSH);
+ button_new.setText("&Add");
+ button_new.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_new.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ PathMapRule a = new PathMapRule(new HashMap<String,Object>());
+ a.getProperties().put(IPathMap.PROP_ID, "PR" + System.currentTimeMillis());
+ map.add(a);
+ viewer.add(a);
+ viewer.setSelection(new StructuredSelection(a), true);
+ viewer.getTable().setFocus();
+ updateLaunchConfigurationDialog();
+ }
+ });
+
+ button_remove = new Button(composite, SWT.PUSH);
+ button_remove.setText("&Remove");
+ button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_remove.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ for (Iterator<?> i = ((IStructuredSelection)viewer.getSelection()).iterator(); i.hasNext();) {
+ PathMapRule a = (PathMapRule)i.next();
+ map.remove(a);
+ viewer.remove(a);
+ }
+ updateLaunchConfigurationDialog();
+ }
+ });
+ }
+
+ List<IPathMap.PathMapRule> getPathMap() {
+ List<IPathMap.PathMapRule> l = new ArrayList<IPathMap.PathMapRule>();
+ for (PathMapRule r : map) l.add(r);
+ return Collections.unmodifiableList(l);
+ }
+
+ public void initializeFrom(ILaunchConfiguration config) {
+ setErrorMessage(null);
+ setMessage(null);
+ try {
+ String s = config.getAttribute(TCFLaunchDelegate.ATTR_PATH_MAP, "");
+ map = TCFLaunchDelegate.parsePathMapAttribute(s);
+ viewer.setInput(config);
+ button_remove.setEnabled(!viewer.getSelection().isEmpty());
+ }
+ catch (Exception e) {
+ init_error = e;
+ setErrorMessage("Cannot read launch configuration: " + e);
+ Activator.log(e);
+ }
+ }
+
+ public void performApply(ILaunchConfigurationWorkingCopy config) {
+ StringBuffer bf = new StringBuffer();
+ for (PathMapRule m : map) bf.append(m.toString());
+ if (bf.length() == 0) config.removeAttribute(TCFLaunchDelegate.ATTR_PATH_MAP);
+ else config.setAttribute(TCFLaunchDelegate.ATTR_PATH_MAP, bf.toString());
+ }
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy config) {
+ config.removeAttribute(TCFLaunchDelegate.ATTR_PATH_MAP);
+ }
+
+ @Override
+ protected void updateLaunchConfigurationDialog() {
+ super.updateLaunchConfigurationDialog();
+ button_remove.setEnabled(!viewer.getSelection().isEmpty());
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration config) {
+ setMessage(null);
+
+ if (init_error != null) {
+ setErrorMessage("Cannot read launch configuration: " + init_error);
+ return false;
+ }
+
+ setErrorMessage(null);
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPropertyTester.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPropertyTester.java
new file mode 100644
index 000000000..c70096067
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFPropertyTester.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.debug.ui.IDebugView;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+
+public class TCFPropertyTester extends PropertyTester {
+
+ public boolean test(Object receiver, String property, Object[] args, Object expected_value) {
+ if (property.equals("areUpdatePoliciesSupported")) return testUpdatePoliciesSupported(receiver);
+ if (property.equals("isExecutable")) return testIsExecutable(receiver, expected_value);
+ return false;
+ }
+
+ private boolean testUpdatePoliciesSupported(Object receiver) {
+ return receiver instanceof IDebugView;
+ }
+
+ private boolean testIsExecutable(Object receiver, Object expected_value) {
+ Object value = null;
+ try {
+ if (receiver instanceof IAdaptable) {
+ IAdaptable selection = (IAdaptable)receiver;
+ ITCFLaunchContext context = TCFLaunchContext.getLaunchContext(selection);
+ if (context != null) {
+ IProject project = context.getProject(selection);
+ IPath path = context.getPath(selection);
+ if (project != null && path != null) {
+ value = context.isBinary(project, path);
+ }
+ }
+ }
+ }
+ catch (Throwable x) {
+ Activator.log(x);
+ }
+ if (expected_value != null) return expected_value.equals(value);
+ return (value instanceof Boolean) && ((Boolean)value).booleanValue();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java
new file mode 100644
index 000000000..1db24c9fd
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTabGroup.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
+import org.eclipse.debug.ui.CommonTab;
+import org.eclipse.debug.ui.EnvironmentTab;
+import org.eclipse.debug.ui.ILaunchConfigurationDialog;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.debug.ui.sourcelookup.SourceLookupTab;
+
+/**
+ * Launch configuration dialog tab group for Target Communication Framework
+ */
+public class TCFTabGroup extends AbstractLaunchConfigurationTabGroup {
+
+ public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
+ setTabs(new ILaunchConfigurationTab[] {
+ new TCFMainTab(),
+ new TCFTargetTab(),
+ new TCFArgumentsTab(),
+ new EnvironmentTab(),
+ new TCFMemoryMapTab(),
+ new TCFPathMapTab(),
+ new SourceLookupTab(),
+ new CommonTab()
+ });
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java
new file mode 100644
index 000000000..9796f06eb
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TCFTargetTab.java
@@ -0,0 +1,1051 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
+import org.eclipse.debug.ui.ILaunchConfigurationTab;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.TreeEvent;
+import org.eclipse.swt.events.TreeListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+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.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.ProgressBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFLocalAgent;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFUserDefPeer;
+import org.eclipse.tm.internal.tcf.debug.tests.TCFTestSuite;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.internal.tcf.debug.ui.launch.setup.SetupWizardDialog;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IPeer;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.ILocator;
+import org.eclipse.tm.tcf.services.IMemoryMap;
+import org.eclipse.tm.tcf.services.IPathMap;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+
+/**
+ * Launch configuration dialog tab to specify the Target Communication Framework
+ * configuration.
+ */
+public class TCFTargetTab extends AbstractLaunchConfigurationTab {
+
+ private static final String TAB_ID = "org.eclipse.tm.tcf.launch.targetTab";
+
+ private Button run_local_agent_button;
+ private Button use_local_agent_button;
+ private Text peer_id_text;
+ private Tree peer_tree;
+ private Runnable update_peer_buttons;
+ private final PeerInfo peer_info = new PeerInfo();
+ private Display display;
+ private Exception init_error;
+ private String mem_map_cfg;
+
+ private static class PeerInfo {
+ PeerInfo parent;
+ int index;
+ String id;
+ Map<String,String> attrs;
+ PeerInfo[] children;
+ boolean children_pending;
+ Throwable children_error;
+ IPeer peer;
+ IChannel channel;
+ ILocator locator;
+ LocatorListener listener;
+ }
+
+ private class LocatorListener implements ILocator.LocatorListener {
+
+ private final PeerInfo parent;
+
+ LocatorListener(PeerInfo parent) {
+ this.parent = parent;
+ }
+
+ public void peerAdded(final IPeer peer) {
+ if (display == null) return;
+ final String id = peer.getID();
+ final HashMap<String,String> attrs = new HashMap<String,String>(peer.getAttributes());
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_error != null) return;
+ PeerInfo[] arr = parent.children;
+ for (PeerInfo p : arr) assert !p.id.equals(id);
+ PeerInfo[] buf = new PeerInfo[arr.length + 1];
+ System.arraycopy(arr, 0, buf, 0, arr.length);
+ PeerInfo info = new PeerInfo();
+ info.parent = parent;
+ info.index = arr.length;
+ info.id = id;
+ info.attrs = attrs;
+ info.peer = peer;
+ buf[arr.length] = info;
+ parent.children = buf;
+ updateItems(parent);
+ }
+ });
+ }
+
+ public void peerChanged(final IPeer peer) {
+ if (display == null) return;
+ final String id = peer.getID();
+ final HashMap<String,String> attrs = new HashMap<String,String>(peer.getAttributes());
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_error != null) return;
+ PeerInfo[] arr = parent.children;
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i].id.equals(id)) {
+ arr[i].attrs = attrs;
+ arr[i].peer = peer;
+ updateItems(parent);
+ }
+ }
+ }
+ });
+ }
+
+ public void peerRemoved(final String id) {
+ if (display == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_error != null) return;
+ PeerInfo[] arr = parent.children;
+ PeerInfo[] buf = new PeerInfo[arr.length - 1];
+ int j = 0;
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i].id.equals(id)) {
+ final PeerInfo info = arr[i];
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ disconnectPeer(info);
+ }
+ });
+ }
+ else {
+ arr[i].index = j;
+ buf[j++] = arr[i];
+ }
+ }
+ parent.children = buf;
+ updateItems(parent);
+ }
+ });
+ }
+
+ public void peerHeartBeat(final String id) {
+ if (display == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_error != null) return;
+ PeerInfo[] arr = parent.children;
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i].id.equals(id)) {
+ if (arr[i].children_error != null) {
+ TreeItem item = findItem(arr[i]);
+ boolean visible = item != null;
+ while (visible && item != null) {
+ if (!item.getExpanded()) visible = false;
+ item = item.getParentItem();
+ }
+ if (visible) loadChildren(arr[i]);
+ }
+ break;
+ }
+ }
+ }
+ });
+ }
+ }
+
+ public void createControl(Composite parent) {
+ display = parent.getDisplay();
+ assert display != null;
+
+ Font font = parent.getFont();
+ Composite comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(1, true);
+ comp.setLayout(layout);
+ comp.setFont(font);
+
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ comp.setLayoutData(gd);
+ setControl(comp);
+ createVerticalSpacer(comp, 1);
+ createLocalAgentButtons(comp);
+ createVerticalSpacer(comp, 1);
+ createTargetGroup(comp);
+ }
+
+ private void createLocalAgentButtons(Composite parent) {
+ Composite local_agent_comp = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ local_agent_comp.setLayout(layout);
+ GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+ local_agent_comp.setLayoutData(gd);
+
+ run_local_agent_button = createCheckButton(local_agent_comp, "Run instance of TCF agent on the local host");
+ run_local_agent_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ run_local_agent_button.setEnabled(true);
+
+ use_local_agent_button = createCheckButton(local_agent_comp, "Use local host as a target");
+ use_local_agent_button.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent evt) {
+ updateLaunchConfigurationDialog();
+ }
+ });
+ use_local_agent_button.setEnabled(true);
+ }
+
+ private void createTargetGroup(Composite parent) {
+ Font font = parent.getFont();
+
+ Group group = new Group(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.verticalSpacing = 0;
+ layout.numColumns = 2;
+ group.setLayout(layout);
+ group.setLayoutData(new GridData(GridData.FILL_BOTH));
+ group.setFont(font);
+ group.setText("Target");
+
+ createVerticalSpacer(group, layout.numColumns);
+
+ Label host_label = new Label(group, SWT.NONE);
+ host_label.setText("Target ID:");
+ host_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ host_label.setFont(font);
+
+ peer_id_text = new Text(group, SWT.SINGLE | SWT.BORDER);
+ peer_id_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ peer_id_text.setFont(font);
+ peer_id_text.setEditable(false);
+
+ createVerticalSpacer(group, layout.numColumns);
+
+ Label peer_label = new Label(group, SWT.NONE);
+ peer_label.setText("&Available targets:");
+ peer_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ peer_label.setFont(font);
+
+ loadChildren(peer_info);
+ createPeerListArea(group);
+ }
+
+ private void createPeerListArea(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
+
+ peer_tree = new Tree(composite, SWT.VIRTUAL | SWT.BORDER | SWT.SINGLE);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ gd.minimumHeight = 150;
+ gd.minimumWidth = 470;
+ peer_tree.setLayoutData(gd);
+
+ for (int i = 0; i < 5; i++) {
+ TreeColumn column = new TreeColumn(peer_tree, SWT.LEAD, i);
+ column.setMoveable(true);
+ switch (i) {
+ case 0:
+ column.setText("Name");
+ column.setWidth(160);
+ break;
+ case 1:
+ column.setText("OS");
+ column.setWidth(100);
+ break;
+ case 2:
+ column.setText("Transport");
+ column.setWidth(60);
+ break;
+ case 3:
+ column.setText("Host");
+ column.setWidth(100);
+ break;
+ case 4:
+ column.setText("Port");
+ column.setWidth(40);
+ break;
+ }
+ }
+
+ peer_tree.setHeaderVisible(true);
+ peer_tree.setFont(font);
+ peer_tree.addListener(SWT.SetData, new Listener() {
+ public void handleEvent(Event event) {
+ TreeItem item = (TreeItem)event.item;
+ PeerInfo info = findPeerInfo(item);
+ if (info == null) {
+ updateItems(item.getParentItem(), false);
+ }
+ else {
+ fillItem(item, info);
+ updateLaunchConfigurationDialog();
+ }
+ }
+ });
+ peer_tree.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ final PeerInfo info = findPeerInfo(peer_id_text.getText());
+ if (info == null) return;
+ new PeerPropsDialog(getShell(), getImage(), info.attrs,
+ info.peer instanceof TCFUserDefPeer).open();
+ if (!(info.peer instanceof TCFUserDefPeer)) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs);
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ TreeItem[] selections = peer_tree.getSelection();
+ if (selections.length > 0) {
+ assert selections.length == 1;
+ PeerInfo info = findPeerInfo(selections[0]);
+ if (info != null) peer_id_text.setText(getPath(info));
+ }
+ updateLaunchConfigurationDialog();
+ }
+ });
+ peer_tree.addTreeListener(new TreeListener() {
+
+ public void treeCollapsed(TreeEvent e) {
+ updateItems((TreeItem)e.item, false);
+ }
+
+ public void treeExpanded(TreeEvent e) {
+ updateItems((TreeItem)e.item, true);
+ }
+ });
+
+ createPeerButtons(composite);
+ }
+
+ private void createPeerButtons(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+ Menu menu = new Menu(peer_tree);
+ SelectionAdapter sel_adapter = null;
+
+ final Button button_new = new Button(composite, SWT.PUSH);
+ button_new.setText("N&ew...");
+ button_new.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_new.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final Map<String,String> attrs = new HashMap<String,String>();
+ SetupWizardDialog wizard = new SetupWizardDialog(attrs);
+ WizardDialog dialog = new WizardDialog(getShell(), wizard);
+ dialog.create();
+ if (dialog.open() != Window.OK) return;
+ if (attrs.isEmpty()) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ new TCFUserDefPeer(attrs);
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ });
+ final MenuItem item_new = new MenuItem(menu, SWT.PUSH);
+ item_new.setText("N&ew...");
+ item_new.addSelectionListener(sel_adapter);
+
+ final Button button_edit = new Button(composite, SWT.PUSH);
+ button_edit.setText("E&dit...");
+ button_edit.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_edit.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final PeerInfo info = findPeerInfo(peer_id_text.getText());
+ if (info == null) return;
+ if (new PeerPropsDialog(getShell(), getImage(), info.attrs,
+ info.peer instanceof TCFUserDefPeer).open() != Window.OK) return;
+ if (!(info.peer instanceof TCFUserDefPeer)) return;
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ ((TCFUserDefPeer)info.peer).updateAttributes(info.attrs);
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ });
+ final MenuItem item_edit = new MenuItem(menu, SWT.PUSH);
+ item_edit.setText("E&dit...");
+ item_edit.addSelectionListener(sel_adapter);
+
+ final Button button_remove = new Button(composite, SWT.PUSH);
+ button_remove.setText("&Remove");
+ button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_remove.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ final PeerInfo info = findPeerInfo(peer_id_text.getText());
+ if (info == null) return;
+ if (!(info.peer instanceof TCFUserDefPeer)) return;
+ peer_id_text.setText("");
+ updateLaunchConfigurationDialog();
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ ((TCFUserDefPeer)info.peer).dispose();
+ TCFUserDefPeer.savePeers();
+ }
+ });
+ }
+ });
+ final MenuItem item_remove = new MenuItem(menu, SWT.PUSH);
+ item_remove.setText("&Remove");
+ item_remove.addSelectionListener(sel_adapter);
+
+ createVerticalSpacer(composite, 20);
+ new MenuItem(menu, SWT.SEPARATOR);
+
+ final Button button_test = new Button(composite, SWT.PUSH);
+ button_test.setText("Run &Tests");
+ button_test.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_test.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ runDiagnostics(false);
+ }
+ });
+ final MenuItem item_test = new MenuItem(menu, SWT.PUSH);
+ item_test.setText("Run &Tests");
+ item_test.addSelectionListener(sel_adapter);
+
+ final Button button_loop = new Button(composite, SWT.PUSH);
+ button_loop.setText("Tests &Loop");
+ button_loop.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_loop.addSelectionListener(sel_adapter = new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ runDiagnostics(true);
+ }
+ });
+ final MenuItem item_loop = new MenuItem(menu, SWT.PUSH);
+ item_loop.setText("Tests &Loop");
+ item_loop.addSelectionListener(sel_adapter);
+
+ peer_tree.setMenu(menu);
+
+ update_peer_buttons = new Runnable() {
+
+ public void run() {
+ boolean local = use_local_agent_button.getSelection();
+ PeerInfo info = findPeerInfo(peer_id_text.getText());
+ button_new.setEnabled(!local);
+ button_edit.setEnabled(info != null && !local);
+ button_remove.setEnabled(info != null && info.peer instanceof TCFUserDefPeer && !local);
+ button_test.setEnabled(local || info != null);
+ button_loop.setEnabled(local || info != null);
+ item_new.setEnabled(!local);
+ item_edit.setEnabled(info != null && !local);
+ item_remove.setEnabled(info != null && info.peer instanceof TCFUserDefPeer && !local);
+ item_test.setEnabled(info != null);
+ item_loop.setEnabled(info != null);
+ }
+ };
+ update_peer_buttons.run();
+ }
+
+ @Override
+ protected void updateLaunchConfigurationDialog() {
+ if (use_local_agent_button.getSelection()) {
+ peer_tree.setEnabled(false);
+ peer_tree.deselectAll();
+ String id = TCFLocalAgent.getLocalAgentID();
+ if (id == null) id = "";
+ peer_id_text.setText(id);
+ peer_id_text.setEnabled(false);
+ }
+ else {
+ peer_tree.setEnabled(true);
+ peer_id_text.setEnabled(true);
+ String id = peer_id_text.getText();
+ TreeItem item = findItem(findPeerInfo(id));
+ if (item != null) peer_tree.setSelection(item);
+ else peer_tree.deselectAll();
+ }
+ update_peer_buttons.run();
+ super.updateLaunchConfigurationDialog();
+ }
+
+ @Override
+ public void dispose() {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ disconnectPeer(peer_info);
+ display = null;
+ }
+ });
+ super.dispose();
+ }
+
+ public String getName() {
+ return "Target";
+ }
+
+ @Override
+ public Image getImage() {
+ return ImageCache.getImage(ImageCache.IMG_TARGET_TAB);
+ }
+
+ @Override
+ public String getId() {
+ return TAB_ID;
+ }
+
+ public void initializeFrom(ILaunchConfiguration configuration) {
+ setErrorMessage(null);
+ setMessage(null);
+ try {
+ String id = configuration.getAttribute(TCFLaunchDelegate.ATTR_PEER_ID, "");
+ TreeItem item = findItem(findPeerInfo(id));
+ if (item != null) peer_tree.setSelection(item);
+ peer_id_text.setText(id);
+ run_local_agent_button.setSelection(configuration.getAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, false));
+ use_local_agent_button.setSelection(configuration.getAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, true));
+ mem_map_cfg = configuration.getAttribute(TCFLaunchDelegate.ATTR_MEMORY_MAP, "null");
+ }
+ catch (CoreException e) {
+ init_error = e;
+ setErrorMessage("Cannot read launch configuration: " + e);
+ Activator.log(e);
+ }
+ updateLaunchConfigurationDialog();
+ }
+
+ public void performApply(ILaunchConfigurationWorkingCopy configuration) {
+ if (use_local_agent_button.getSelection()) {
+ configuration.removeAttribute(TCFLaunchDelegate.ATTR_PEER_ID);
+ }
+ else {
+ configuration.setAttribute(TCFLaunchDelegate.ATTR_PEER_ID, peer_id_text.getText());
+ }
+ configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, run_local_agent_button.getSelection());
+ configuration.setAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, use_local_agent_button.getSelection());
+ }
+
+ public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
+ configuration.setAttribute(TCFLaunchDelegate.ATTR_RUN_LOCAL_AGENT, false);
+ configuration.setAttribute(TCFLaunchDelegate.ATTR_USE_LOCAL_AGENT, true);
+ configuration.removeAttribute(TCFLaunchDelegate.ATTR_PEER_ID);
+ }
+
+ @Override
+ public boolean isValid(ILaunchConfiguration config) {
+ setErrorMessage(null);
+ setMessage(null);
+
+ if (init_error != null) {
+ setErrorMessage("Cannot read launch configuration: " + init_error);
+ return false;
+ }
+
+ return true;
+ }
+
+ private void disconnectPeer(final PeerInfo info) {
+ assert Protocol.isDispatchThread();
+ if (info.children != null) {
+ for (PeerInfo p : info.children) disconnectPeer(p);
+ }
+ if (info.listener != null) {
+ info.locator.removeListener(info.listener);
+ info.listener = null;
+ info.locator = null;
+ }
+ if (info.channel != null) {
+ info.channel.close();
+ }
+ }
+
+ private boolean canHaveChildren(PeerInfo parent) {
+ return parent == peer_info || parent.attrs.get(IPeer.ATTR_PROXY) != null;
+ }
+
+ private void loadChildren(final PeerInfo parent) {
+ assert Thread.currentThread() == display.getThread();
+ if (parent.children_pending) return;
+ assert parent.children == null;
+ parent.children_pending = true;
+ parent.children_error = null;
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ assert parent.listener == null;
+ assert parent.channel == null;
+ if (!canHaveChildren(parent)) {
+ doneLoadChildren(parent, null, new PeerInfo[0]);
+ }
+ else if (parent == peer_info) {
+ peer_info.locator = Protocol.getLocator();
+ doneLoadChildren(parent, null, createLocatorListener(peer_info));
+ }
+ else {
+ final IChannel channel = parent.peer.openChannel();
+ parent.channel = channel;
+ parent.channel.addChannelListener(new IChannel.IChannelListener() {
+ boolean opened = false;
+ boolean closed = false;
+ public void congestionLevel(int level) {
+ }
+ public void onChannelClosed(final Throwable error) {
+ assert !closed;
+ if (parent.channel != channel) return;
+ if (!opened) {
+ doneLoadChildren(parent, error, null);
+ }
+ else {
+ if (display != null) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (parent.children_pending) return;
+ parent.children = null;
+ parent.children_error = error;
+ updateItems(parent);
+ }
+ });
+ }
+ }
+ closed = true;
+ parent.channel = null;
+ parent.locator = null;
+ parent.listener = null;
+ }
+ public void onChannelOpened() {
+ assert !opened;
+ assert !closed;
+ if (parent.channel != channel) return;
+ opened = true;
+ parent.locator = parent.channel.getRemoteService(ILocator.class);
+ if (parent.locator == null) {
+ parent.channel.terminate(new Exception("Service not supported: " + ILocator.NAME));
+ }
+ else {
+ doneLoadChildren(parent, null, createLocatorListener(parent));
+ }
+ }
+ });
+ }
+ }
+ });
+ }
+
+ private PeerInfo[] createLocatorListener(PeerInfo peer) {
+ assert Protocol.isDispatchThread();
+ Map<String,IPeer> map = peer.locator.getPeers();
+ PeerInfo[] buf = new PeerInfo[map.size()];
+ int n = 0;
+ for (IPeer p : map.values()) {
+ PeerInfo info = new PeerInfo();
+ info.parent = peer;
+ info.index = n;
+ info.id = p.getID();
+ info.attrs = new HashMap<String,String>(p.getAttributes());
+ info.peer = p;
+ buf[n++] = info;
+ }
+ peer.listener = new LocatorListener(peer);
+ peer.locator.addListener(peer.listener);
+ return buf;
+ }
+
+ private void doneLoadChildren(final PeerInfo parent, final Throwable error, final PeerInfo[] children) {
+ assert Protocol.isDispatchThread();
+ assert error == null || children == null;
+ if (display == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ assert parent.children_pending;
+ assert parent.children == null;
+ parent.children_pending = false;
+ parent.children = children;
+ parent.children_error = error;
+ updateItems(parent);
+ }
+ });
+ }
+
+ private void updateItems(TreeItem parent_item, boolean reload) {
+ final PeerInfo parent_info = findPeerInfo(parent_item);
+ if (parent_info == null) {
+ parent_item.setText("Invalid");
+ }
+ else {
+ if (reload && parent_info.children_error != null) {
+ loadChildren(parent_info);
+ }
+ display.asyncExec(new Runnable() {
+ public void run() {
+ updateItems(parent_info);
+ }
+ });
+ }
+ }
+
+ private void updateItems(final PeerInfo parent) {
+ if (display == null) return;
+ assert Thread.currentThread() == display.getThread();
+ TreeItem[] items = null;
+ boolean expanded = true;
+ if (parent.children == null || parent.children_error != null) {
+ if (parent == peer_info) {
+ peer_tree.setItemCount(1);
+ items = peer_tree.getItems();
+ }
+ else {
+ TreeItem item = findItem(parent);
+ if (item == null) return;
+ expanded = item.getExpanded();
+ item.setItemCount(1);
+ items = item.getItems();
+ }
+ assert items.length == 1;
+ items[0].removeAll();
+ if (parent.children_pending) {
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ items[0].setText("Connecting...");
+ }
+ else if (parent.children_error != null) {
+ String msg = parent.children_error.getMessage();
+ if (msg == null) msg = parent.children_error.getClass().getName();
+ else msg = msg.replace('\n', ' ');
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_RED));
+ items[0].setText(msg);
+ }
+ else if (expanded) {
+ loadChildren(parent);
+ items[0].setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ items[0].setText("Connecting...");
+ }
+ else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ disconnectPeer(parent);
+ }
+ });
+ items[0].setText("");
+ }
+ int n = peer_tree.getColumnCount();
+ for (int i = 1; i < n; i++) items[0].setText(i, "");
+ items[0].setImage((Image)null);
+ }
+ else {
+ PeerInfo[] arr = parent.children;
+ if (parent == peer_info) {
+ peer_tree.setItemCount(arr.length);
+ items = peer_tree.getItems();
+ }
+ else {
+ TreeItem item = findItem(parent);
+ if (item == null) return;
+ expanded = item.getExpanded();
+ item.setItemCount(expanded ? arr.length : 1);
+ items = item.getItems();
+ }
+ if (expanded) {
+ assert items.length == arr.length;
+ for (int i = 0; i < items.length; i++) fillItem(items[i], arr[i]);
+ }
+ else {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ disconnectPeer(parent);
+ }
+ });
+ items[0].setText("");
+ int n = peer_tree.getColumnCount();
+ for (int i = 1; i < n; i++) items[0].setText(i, "");
+ }
+ }
+ updateLaunchConfigurationDialog();
+ }
+
+ private PeerInfo findPeerInfo(TreeItem item) {
+ assert Thread.currentThread() == display.getThread();
+ if (item == null) return peer_info;
+ TreeItem parent = item.getParentItem();
+ PeerInfo info = findPeerInfo(parent);
+ if (info == null) return null;
+ if (info.children == null) return null;
+ if (info.children_error != null) return null;
+ int i = parent == null ? peer_tree.indexOf(item) : parent.indexOf(item);
+ if (i < 0 || i >= info.children.length) return null;
+ assert info.children[i].index == i;
+ return info.children[i];
+ }
+
+ private PeerInfo findPeerInfo(String path) {
+ assert Thread.currentThread() == display.getThread();
+ if (path == null) return null;
+ int i = path.lastIndexOf('/');
+ String id = null;
+ PeerInfo[] arr = null;
+ if (i < 0) {
+ arr = peer_info.children;
+ if (arr == null) return null;
+ id = path;
+ }
+ else {
+ PeerInfo p = findPeerInfo(path.substring(0, i));
+ if (p == null) return null;
+ arr = p.children;
+ if (arr == null) {
+ TreeItem item = findItem(p);
+ item.setExpanded(true);
+ return null;
+ }
+ id = path.substring(i + 1);
+ }
+ for (int n = 0; n < arr.length; n++) {
+ if (arr[n].id.equals(id)) return arr[n];
+ }
+ return null;
+ }
+
+ private TreeItem findItem(PeerInfo info) {
+ if (info == null) return null;
+ assert info.parent != null;
+ if (info.parent == peer_info) {
+ int n = peer_tree.getItemCount();
+ if (info.index >= n) return null;
+ return peer_tree.getItem(info.index);
+ }
+ TreeItem i = findItem(info.parent);
+ if (i == null) return null;
+ int n = i.getItemCount();
+ if (info.index >= n) return null;
+ return i.getItem(info.index);
+ }
+
+ private void runDiagnostics(boolean loop) {
+ IPeer peer = null;
+ if (use_local_agent_button.getSelection()) {
+ try {
+ if (run_local_agent_button.getSelection()) TCFLocalAgent.runLocalAgent();
+ final String id = TCFLocalAgent.getLocalAgentID();
+ peer = new TCFTask<IPeer>() {
+ public void run() {
+ done(Protocol.getLocator().getPeers().get(id));
+ }
+ }.get();
+ }
+ catch (Throwable err) {
+ String msg = err.getLocalizedMessage();
+ if (msg == null || msg.length() == 0) msg = err.getClass().getName();
+ MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
+ mb.setText("Error");
+ mb.setMessage("Cannot start agent:\n" + msg);
+ mb.open();
+ }
+ }
+ else {
+ PeerInfo info = findPeerInfo(peer_id_text.getText());
+ if (info == null) return;
+ peer = info.peer;
+ }
+ if (peer == null) return;
+ final Shell shell = new Shell(getShell(), SWT.TITLE | SWT.PRIMARY_MODAL);
+ GridLayout layout = new GridLayout();
+ layout.verticalSpacing = 0;
+ layout.numColumns = 2;
+ shell.setLayout(layout);
+ shell.setText("Running Diagnostics...");
+ CLabel label = new CLabel(shell, SWT.NONE);
+ label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false));
+ label.setText("Running Diagnostics...");
+ final TCFTestSuite[] test = new TCFTestSuite[1];
+ Button button_cancel = new Button(shell, SWT.PUSH);
+ button_cancel.setText("&Cancel");
+ button_cancel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false));
+ button_cancel.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (test[0] != null) test[0].cancel();
+ }
+ });
+ }
+ });
+ createVerticalSpacer(shell, 0);
+ ProgressBar bar = new ProgressBar(shell, SWT.HORIZONTAL);
+ bar.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 2, 1));
+ shell.setDefaultButton(button_cancel);
+ shell.pack();
+ shell.setSize(483, shell.getSize().y);
+ Rectangle rc0 = getShell().getBounds();
+ Rectangle rc1 = shell.getBounds();
+ shell.setLocation(rc0.x + (rc0.width - rc1.width) / 2, rc0.y + (rc0.height - rc1.height) / 2);
+ shell.setVisible(true);
+ runDiagnostics(peer, loop, test, shell, label, bar);
+ }
+
+ private void runDiagnostics(final IPeer peer, final boolean loop, final TCFTestSuite[] test,
+ final Shell shell, final CLabel label, final ProgressBar bar) {
+ final TCFTestSuite.TestListener done = new TCFTestSuite.TestListener() {
+ private String last_text = "";
+ private int last_count = 0;
+ private int last_total = 0;
+ public void progress(final String label_text, final int count_done, final int count_total) {
+ assert test[0] != null;
+ if ((label_text == null || last_text.equals(label_text)) &&
+ last_total == count_total &&
+ (count_done - last_count) / (float)count_total < 0.02f) return;
+ if (label_text != null) last_text = label_text;
+ last_total = count_total;
+ last_count = count_done;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ label.setText(last_text);
+ bar.setMinimum(0);
+ bar.setMaximum(last_total);
+ bar.setSelection(last_count);
+ }
+ });
+ }
+ public void done(final Collection<Throwable> errors) {
+ assert test[0] != null;
+ final boolean b = test[0].isCanceled();
+ test[0] = null;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (errors.size() > 0) {
+ shell.dispose();
+ new TestErrorsDialog(getControl().getShell(),
+ ImageCache.getImage(ImageCache.IMG_TCF), errors).open();
+ }
+ else if (loop && !b && display != null) {
+ runDiagnostics(peer, true, test, shell, label, bar);
+ }
+ else {
+ shell.dispose();
+ }
+ }
+ });
+ }
+ };
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ List<IPathMap.PathMapRule> path_map = null;
+ for (ILaunchConfigurationTab t : getLaunchConfigurationDialog().getTabs()) {
+ if (t instanceof TCFPathMapTab) path_map = ((TCFPathMapTab)t).getPathMap();
+ }
+ HashMap<String,ArrayList<IMemoryMap.MemoryRegion>> mem_map = null;
+ if (mem_map_cfg != null) {
+ mem_map = new HashMap<String,ArrayList<IMemoryMap.MemoryRegion>>();
+ TCFLaunchDelegate.parseMemMapsAttribute(mem_map, mem_map_cfg);
+ }
+ boolean enable_tracing =
+ "true".equals(Platform.getDebugOption("org.eclipse.tm.tcf.debug/debug")) &&
+ "true".equals(Platform.getDebugOption("org.eclipse.tm.tcf.debug/debug/tests/runcontrol"));
+ if (enable_tracing) System.setProperty("org.eclipse.tm.tcf.debug.tracing.tests.runcontrol", "true");
+ test[0] = new TCFTestSuite(peer, done, path_map, mem_map);
+ }
+ catch (Throwable x) {
+ ArrayList<Throwable> errors = new ArrayList<Throwable>();
+ errors.add(x);
+ done.done(errors);
+ }
+ }
+ });
+ }
+
+ private void fillItem(TreeItem item, PeerInfo info) {
+ assert Thread.currentThread() == display.getThread();
+ Object data = item.getData("TCFPeerInfo");
+ if (data != null && data != info) item.removeAll();
+ item.setData("TCFPeerInfo", info);
+ String text[] = new String[5];
+ text[0] = info.attrs.get(IPeer.ATTR_NAME);
+ text[1] = info.attrs.get(IPeer.ATTR_OS_NAME);
+ text[2] = info.attrs.get(IPeer.ATTR_TRANSPORT_NAME);
+ text[3] = info.attrs.get(IPeer.ATTR_IP_HOST);
+ text[4] = info.attrs.get(IPeer.ATTR_IP_PORT);
+ for (int i = 0; i < text.length; i++) {
+ if (text[i] == null) text[i] = "";
+ }
+ item.setText(text);
+ item.setForeground(display.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
+ item.setImage(ImageCache.getImage(getImageName(info)));
+ if (!canHaveChildren(info)) item.setItemCount(0);
+ else if (info.children == null || info.children_error != null) item.setItemCount(1);
+ else item.setItemCount(info.children.length);
+ }
+
+ private String getPath(PeerInfo info) {
+ if (info == peer_info) return "";
+ if (info.parent == peer_info) return info.id;
+ return getPath(info.parent) + "/" + info.id;
+ }
+
+ private String getImageName(PeerInfo info) {
+ return ImageCache.IMG_TARGET_TAB;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TestErrorsDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TestErrorsDialog.java
new file mode 100644
index 000000000..e1b0ac463
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/TestErrorsDialog.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+class TestErrorsDialog extends Dialog {
+
+ private static final int
+ SIZING_TEXT_WIDTH = 600,
+ SIZING_TEXT_HEIGHT = 400;
+
+ private Collection<Throwable> errors;
+ private Image image;
+ private Text text;
+
+ TestErrorsDialog(Shell parent, Image image, Collection<Throwable> errors) {
+ super(parent);
+ this.image = image;
+ this.errors = errors;
+ }
+
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setText("Connection Diagnostic errors");
+ shell.setImage(image);
+ }
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createButton(parent, IDialogConstants.OK_ID, "&OK", true);
+ }
+
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+ composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+
+ Label label = new Label(composite, SWT.WRAP);
+ label.setFont(JFaceResources.getFontRegistry().get(JFaceResources.BANNER_FONT));
+ label.setText("Connection diagnostics ended with errors:");
+
+ text = new Text(composite, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
+ text.setFont(JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT));
+ text.setEditable(false);
+ text.setText(createText());
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = SIZING_TEXT_WIDTH;
+ data.heightHint = SIZING_TEXT_HEIGHT;
+ text.setLayoutData(data);
+
+ return composite;
+ }
+
+ private String createText() {
+ StringWriter buf = new StringWriter();
+ PrintWriter pwr = new PrintWriter(buf);
+ for (Iterator<Throwable> i = errors.iterator(); i.hasNext();) {
+ i.next().printStackTrace(pwr);
+ pwr.println();
+ }
+ pwr.flush();
+ return buf.toString();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/AbstractRemoteShell.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/AbstractRemoteShell.java
new file mode 100644
index 000000000..066ab0630
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/AbstractRemoteShell.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+abstract class AbstractRemoteShell implements IRemoteShell {
+
+ protected boolean debug;
+ protected BufferedReader inp;
+ protected PrintWriter out;
+
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ public synchronized void write(String s) {
+ out.write(s);
+ }
+
+ public synchronized void expect(String s) throws IOException {
+ expect(new String[]{ s });
+ }
+
+ public synchronized int expect(String s[]) throws IOException {
+ out.flush();
+ int[] pos = new int[s.length];
+ for (int i = 0; i < pos.length; i++) pos[i] = 0;
+ StringBuffer buf = new StringBuffer();
+ try {
+ for (;;) {
+ int ch = inp.read();
+ if (ch < 0) throw new IOException("Unexpected EOF");
+ if (ch == '\r') continue;
+ if (debug) System.out.write(ch);
+ for (int i = 0; i < pos.length; i++) {
+ String p = s[i];
+ if (ch == p.charAt(pos[i])) {
+ pos[i]++;
+ if (pos[i] == p.length()) return i;
+ }
+ else {
+ int nps = pos[i];
+ while (nps > 0) {
+ if (ch == p.charAt(nps - 1)) {
+ int j = nps - 2;
+ int k = pos[i] - 1;
+ while (j >= 0 && p.charAt(j) == p.charAt(k)) {
+ j--;
+ k--;
+ }
+ if (j < 0) break;
+ }
+ nps--;
+ }
+ pos[i] = nps;
+ }
+ }
+ buf.append((char)ch);
+ if (ch == '\n') buf.setLength(0);
+ }
+ }
+ catch (IOException x) {
+ if (buf.length() == 0) throw x;
+ IOException y = new IOException("I/O error, last text received: " + buf);
+ y.initCause(x);
+ throw y;
+ }
+ finally {
+ if (debug) System.out.flush();
+ }
+ }
+
+ public synchronized String waitPrompt() throws IOException {
+ StringBuffer res = new StringBuffer();
+ StringBuffer buf = new StringBuffer();
+ out.flush();
+ try {
+ for (;;) {
+ int ch = inp.read();
+ if (ch < 0) throw new IOException("Unexpected EOF");
+ if (ch == '\r') continue;
+ if (debug) System.out.write(ch);
+ buf.append((char)ch);
+ if (buf.length() == PROMPT.length() && buf.toString().equals(PROMPT)) break;
+ if (ch == '\n') {
+ res.append(buf);
+ buf.setLength(0);
+ }
+ }
+ return res.toString();
+ }
+ catch (IOException x) {
+ if (buf.length() == 0) throw x;
+ IOException y = new IOException("I/O error, last text received: " + buf);
+ y.initCause(x);
+ throw y;
+ }
+ finally {
+ if (debug) System.out.flush();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/IRemoteShell.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/IRemoteShell.java
new file mode 100644
index 000000000..4e052a6b4
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/IRemoteShell.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.io.IOException;
+
+interface IRemoteShell {
+
+ /**
+ * String that is used as shell prompt.
+ */
+ static final String PROMPT = "***SHELL***>";
+
+ /**
+ * Send text to remote shell.
+ * @param s - a string for shell input.
+ * @throws IOException
+ */
+ void write(String s) throws IOException;
+
+ /**
+ * Read shell output until given string if found.
+ * @param s - a string to search in shell output.
+ * @throws IOException
+ */
+ void expect(String s) throws IOException;
+
+ /**
+ * Read and collect shell output until shell prompt is found.
+ * @return shell output, not including the prompt.
+ * @throws IOException
+ */
+ String waitPrompt() throws IOException;
+
+ /**
+ * Exit shell and close communication channel.
+ * @throws IOException
+ */
+ void close() throws IOException;
+
+ /**
+ * Enable/disable debug output to System.out.
+ */
+ void setDebug(boolean debug);
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/PeerPropsControl.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/PeerPropsControl.java
new file mode 100644
index 000000000..ad4fee038
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/PeerPropsControl.java
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ICellModifier;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+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.Event;
+import org.eclipse.swt.widgets.Item;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.tcf.protocol.IPeer;
+
+public class PeerPropsControl {
+
+ private static final int
+ SIZING_TABLE_WIDTH = 400,
+ SIZING_TABLE_HEIGHT = 200;
+
+ private static final String[] column_names = { "Name", "Value" };
+
+ private final Map<String,String> attrs;
+ private final ArrayList<Attribute> attr_table_data;
+ private final boolean create_new;
+ private final boolean enable_editing;
+ private final Runnable listener;
+
+ private Text id_text;
+ private Text name_text;
+ private Table attr_table;
+ private TableViewer table_viewer;
+ private Image attr_image;
+
+ private class Attribute {
+ String name;
+ String value;
+ }
+
+ private class AttributeLabelProvider extends LabelProvider implements ITableLabelProvider {
+
+ public Image getColumnImage(Object element, int column) {
+ if (column == 0) return attr_image;
+ return null;
+ }
+
+ public String getColumnText(Object element, int column) {
+ Attribute a = (Attribute)element;
+ return column == 0 ? a.name : a.value;
+ }
+
+ public String getText(Object element) {
+ TableColumn column = attr_table.getSortColumn();
+ if (column == null) return "";
+ return getColumnText(element, attr_table.indexOf(column));
+ }
+ }
+
+ public PeerPropsControl(Composite parent, Map<String,String> attrs, boolean enable_editing, Runnable listener) {
+ this.attrs = attrs;
+ this.enable_editing = enable_editing;
+ this.listener = listener;
+ create_new = attrs.isEmpty();
+ attr_table_data = new ArrayList<Attribute>();
+
+ createTextFields(parent);
+ createAttrTable(parent);
+ }
+
+ private void createTextFields(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ Label id_label = new Label(composite, SWT.WRAP);
+ id_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ id_label.setFont(font);
+ id_label.setText("Peer &ID:");
+
+ id_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ id_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ id_text.setFont(font);
+ id_text.setEditable(false);
+
+ Label name_label = new Label(composite, SWT.WRAP);
+ name_label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+ name_label.setFont(font);
+ name_label.setText("Peer &name:");
+
+ name_text = new Text(composite, SWT.SINGLE | SWT.BORDER);
+ name_text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ name_text.setFont(font);
+ name_text.setEditable(enable_editing);
+ name_text.addListener(SWT.KeyUp, new Listener() {
+ public void handleEvent(Event event) {
+ listener.run();
+ }
+ });
+ }
+
+ private void createAttrTable(Composite parent) {
+ Font font = parent.getFont();
+ Label props_label = new Label(parent, SWT.WRAP);
+ props_label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ props_label.setFont(font);
+ props_label.setText("Peer &properties:");
+
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout(2, false);
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true, 2, 1));
+
+ attr_table = new Table(composite, SWT.SINGLE | SWT.BORDER |
+ SWT.H_SCROLL | SWT.V_SCROLL |
+ SWT.FULL_SELECTION | SWT.HIDE_SELECTION);
+ attr_table.setFont(font);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ data.widthHint = SIZING_TABLE_WIDTH;
+ data.heightHint = SIZING_TABLE_HEIGHT;
+ attr_table.setLayoutData(data);
+
+ for (int i = 0; i < column_names.length; i++) {
+ final TableColumn column = new TableColumn(attr_table, SWT.LEAD, i);
+ column.setMoveable(false);
+ column.setText(column_names[i]);
+ column.setWidth(SIZING_TABLE_WIDTH / column_names.length);
+ column.addSelectionListener(new SelectionAdapter() {
+
+ public void widgetSelected(SelectionEvent e) {
+ if (column == attr_table.getSortColumn()) {
+ switch (attr_table.getSortDirection()) {
+ case SWT.NONE:
+ attr_table.setSortDirection(SWT.DOWN);
+ break;
+ case SWT.DOWN:
+ attr_table.setSortDirection(SWT.UP);
+ break;
+ case SWT.UP:
+ attr_table.setSortDirection(SWT.NONE);
+ break;
+ }
+ }
+ else {
+ attr_table.setSortColumn(column);
+ attr_table.setSortDirection(SWT.DOWN);
+ }
+ table_viewer.refresh();
+ }
+ });
+ }
+ attr_table.setHeaderVisible(true);
+ attr_table.setLinesVisible(true);
+
+ attr_image = ImageCache.getImage(ImageCache.IMG_ATTRIBUTE);
+
+ table_viewer = new TableViewer(attr_table);
+ table_viewer.setUseHashlookup(true);
+ table_viewer.setColumnProperties(column_names);
+
+ CellEditor[] editors = new CellEditor[column_names.length];
+ for (int i = 0; i < column_names.length; i++) {
+ TextCellEditor editor = new TextCellEditor(attr_table);
+ ((Text)editor.getControl()).setTextLimit(250);
+ editors[i] = editor;
+ }
+ table_viewer.setCellEditors(editors);
+
+ table_viewer.setCellModifier(new ICellModifier() {
+
+ public boolean canModify(Object element, String property) {
+ return enable_editing;
+ }
+
+ public Object getValue(Object element, String property) {
+ if (element instanceof Item) element = ((Item)element).getData();
+ Attribute a = (Attribute)element;
+ return property.equals(column_names[0]) ? a.name : a.value;
+ }
+
+ public void modify(Object element, String property, Object value) {
+ if (element instanceof Item) element = ((Item)element).getData();
+ Attribute a = (Attribute)element;
+ if (property.equals(column_names[0])) {
+ a.name = (String)value;
+ }
+ else {
+ a.value = (String)value;
+ }
+ table_viewer.update(element, new String[] { property });
+ }
+ });
+
+ String[] keys = attrs.keySet().toArray(new String[attrs.size()]);
+ Arrays.sort(keys);
+ for (String key : keys) {
+ if (key.equals(IPeer.ATTR_ID)) {
+ id_text.setText(attrs.get(key));
+ }
+ else if (key.equals(IPeer.ATTR_NAME)) {
+ name_text.setText(attrs.get(key));
+ }
+ else {
+ Attribute a = new Attribute();
+ a.name = key;
+ a.value = attrs.get(key);
+ attr_table_data.add(a);
+ }
+ }
+ if (create_new) id_text.setText("USR:" + System.currentTimeMillis());
+
+ table_viewer.setContentProvider(new IStructuredContentProvider() {
+
+ public Object[] getElements(Object input) {
+ assert input == attr_table_data;
+ return attr_table_data.toArray();
+ }
+
+ public void dispose() {
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ }
+ });
+
+ table_viewer.setLabelProvider(new AttributeLabelProvider());
+ table_viewer.setInput(attr_table_data);
+ table_viewer.setComparator(new ViewerComparator() {
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2) {
+ switch (attr_table.getSortDirection()) {
+ case SWT.UP : return -super.compare(viewer, e1, e2);
+ case SWT.DOWN: return +super.compare(viewer, e1, e2);
+ }
+ return 0;
+ }
+ });
+
+ createTableButtons(composite);
+ }
+
+ private void createTableButtons(Composite parent) {
+ Font font = parent.getFont();
+ Composite composite = new Composite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ composite.setFont(font);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL));
+
+ final Button button_new = new Button(composite, SWT.PUSH);
+ button_new.setText("&Add");
+ button_new.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_new.setEnabled(enable_editing);
+ button_new.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Attribute a = new Attribute();
+ a.name = "";
+ a.value = "";
+ attr_table_data.add(a);
+ table_viewer.add(a);
+ table_viewer.setSelection(new StructuredSelection(a), true);
+ attr_table.setFocus();
+ }
+ });
+
+ final Button button_remove = new Button(composite, SWT.PUSH);
+ button_remove.setText("&Remove");
+ button_remove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+ button_remove.setEnabled(enable_editing);
+ button_remove.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Attribute a = (Attribute) ((IStructuredSelection)
+ table_viewer.getSelection()).getFirstElement();
+ if (a == null) return;
+ attr_table_data.remove(a);
+ table_viewer.remove(a);
+ }
+ });
+ }
+
+ public boolean isComplete() {
+ return name_text.getText().length() > 0;
+ }
+
+ public void okPressed() {
+ if (enable_editing) {
+ if (create_new) attrs.put(IPeer.ATTR_ID, id_text.getText());
+ String id = attrs.get(IPeer.ATTR_ID);
+ String nm = name_text.getText();
+ attrs.clear();
+ for (Attribute a : attr_table_data) attrs.put(a.name, a.value);
+ attrs.put(IPeer.ATTR_ID, id);
+ attrs.put(IPeer.ATTR_NAME, nm);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/SSHClient.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/SSHClient.java
new file mode 100644
index 000000000..3b5427f91
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/SSHClient.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintWriter;
+
+import org.eclipse.jsch.core.IJSchService;
+import org.eclipse.jsch.ui.UserInfoPrompter;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.Session;
+
+class SSHClient extends AbstractRemoteShell {
+
+ private final Session session;
+ private final Channel channel;
+
+ private static class Pipe {
+
+ final PipedOutputStream out = new PipedOutputStream();
+ final PipedInputStream inp = new PipedInputStream();
+
+ Pipe() throws IOException {
+ inp.connect(out);
+ }
+ }
+
+ SSHClient(final Shell parent, String host, String user, final String password) throws Exception {
+ BundleContext ctx = Activator.getDefault().getBundle().getBundleContext();
+ ServiceReference ref = ctx.getServiceReference(IJSchService.class.getName());
+ IJSchService s = (IJSchService)ctx.getService(ref);
+ session = s.createSession(host, 22, user);
+ session.setPassword(password);
+ new UserInfoPrompter(session);
+ session.connect(30000);
+ channel = session.openChannel("shell");
+ Pipe inp = new Pipe();
+ Pipe out = new Pipe();
+ channel.setInputStream(inp.inp);
+ channel.setOutputStream(out.out);
+ this.out = new PrintWriter(inp.out, true);
+ this.inp = new BufferedReader(new InputStreamReader(new TimeOutInputStream(out.inp, 512, 60000), "UTF-8"));
+ channel.connect(30000);
+ write("export PS1=\"" + PROMPT + "\"\n");
+ expect(PROMPT + "\"\n");
+ waitPrompt();
+ }
+
+ public void close() throws IOException {
+ channel.disconnect();
+ session.disconnect();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/SetupWizardDialog.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/SetupWizardDialog.java
new file mode 100644
index 000000000..04facc944
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/SetupWizardDialog.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.util.Map;
+
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+
+public class SetupWizardDialog extends Wizard {
+
+ private final Map<String,String> peer_attrs;
+
+ public SetupWizardDialog(Map<String,String> peer_attrs) {
+ this.peer_attrs = peer_attrs;
+ setWindowTitle("TCF Debug Target Setup");
+ }
+
+ @Override
+ public void addPages() {
+ addPage(new WizardFirstPage(this));
+ addPage(new WizardLoginPage(this));
+ addPage(new WizardLogPage(this));
+ addPage(new WizardLocalPage(this));
+ addPage(new WizardPropsPage(this, peer_attrs));
+ }
+
+ @Override
+ public Image getDefaultPageImage() {
+ return ImageCache.getImage(ImageCache.IMG_TARGET_WIZARD);
+ }
+
+ @Override
+ public boolean canFinish() {
+ IWizardPage page = getContainer().getCurrentPage();
+ if (page instanceof WizardLogPage) return ((WizardLogPage)page).canFinish();
+ if (page instanceof WizardPropsPage) return ((WizardPropsPage)page).canFinish();
+ return false;
+ }
+
+ @Override
+ public boolean performFinish() {
+ if (!canFinish()) return false;
+ IWizardPage page = getContainer().getCurrentPage();
+ if (page instanceof WizardPropsPage) {
+ if (!((WizardPropsPage)page).performFinish()) return false;;
+ }
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TelnetClient.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TelnetClient.java
new file mode 100644
index 000000000..3c31506b5
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TelnetClient.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.SocketException;
+
+class TelnetClient extends AbstractRemoteShell {
+
+ private Socket socket;
+ private boolean logged;
+
+ TelnetClient(InetAddress address, int port,
+ String user, String password) throws Exception {
+ socket = new Socket(address, port);
+ socket.setTcpNoDelay(true);
+ InputStream ist = new BufferedInputStream(socket.getInputStream());
+ OutputStream ost = new BufferedOutputStream(socket.getOutputStream());
+ ist = new TelnetInputStream(ist, ost, true, PROMPT);
+ ist = new TimeOutInputStream(ist, 512, 30000);
+ out = new PrintWriter(ost, true);
+ inp = new BufferedReader(new InputStreamReader(ist, "UTF-8"));
+ expect("ogin: ");
+ write(user + "\n");
+ expect("assword: ");
+ write(password + "\n");
+ int i = expect(new String[]{"incorrect", PROMPT, "$ ", "# ", "> "});
+ if (i == 0) {
+ close();
+ throw new Exception("Login incorrect");
+ }
+ logged = true;
+ write("export PS1=\"" + PROMPT + "\"\n");
+ expect(PROMPT + "\"\n");
+ waitPrompt();
+ }
+
+ public synchronized void close() throws IOException {
+ if (socket == null) return;
+ if (logged) {
+ write("exit\n");
+ logged = false;
+ }
+ out.close();
+ try {
+ char[] buf = new char[0x100];
+ while (inp.read(buf) >= 0) {}
+ }
+ catch (SocketException x) {
+ if (!x.getMessage().startsWith("Socket closed")) throw x;
+ }
+ inp.close();
+ socket.close();
+ socket = null;
+ inp = null;
+ out = null;
+ }
+
+ public void finalize() throws Throwable {
+ close();
+ super.finalize();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TelnetInputStream.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TelnetInputStream.java
new file mode 100644
index 000000000..6554dd9e0
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TelnetInputStream.java
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+
+class TelnetInputStream extends FilterInputStream {
+
+ public interface TelnetTraceListener {
+ void command(String s);
+ }
+
+ private final boolean echo;
+ private final String prompt;
+
+ private final InputStream inp;
+ private final OutputStream out;
+ private final boolean mode_rem[] = new boolean[256];
+ private final int mode_cnt[] = new int[256];
+ private final Reader reader = new Reader();
+ private final byte buf[] = new byte[512];
+ private int buf_inp = 0;
+ private int buf_out = 0;
+ private boolean eof;
+ private IOException err;
+ private boolean closed;
+
+ private final ArrayList<TelnetTraceListener> trace_listeners = new ArrayList<TelnetTraceListener>();
+
+ private static final int
+ cm_IAC = 255,
+ cm_WILL = 251,
+ cm_WONT = 252,
+ cm_DO = 253,
+ cm_DONT = 254,
+ cm_SB = 250,
+ cm_SE = 240,
+ cm_DataMark = 242;
+
+ private static final int
+ co_ECHO = 1,
+ co_SUPPRESS_GO_AHEAD = 3,
+ co_STATUS = 5,
+ co_TERMINAL_TYPE = 24,
+ co_NAWS = 31, // Negotiate About Window Size
+ co_TERMINAL_SPEED = 32,
+ co_TOGGLE_FLOW_CONTROL = 33,
+ co_X_DISPLAY_LOCATION = 35,
+ co_ENVIRON = 36,
+ co_NEW_ENVIRON = 39;
+
+ @SuppressWarnings("unused")
+ private static final int
+ sp_VAR = 0,
+ sp_VALUE = 1,
+ sp_ESC = 2,
+ sp_USERVAR = 3;
+
+ @SuppressWarnings("unused")
+ private static final int
+ ac_IS = 0,
+ ac_SEND = 1,
+ ac_INFO = 2;
+
+ private class Reader extends Thread {
+
+ private void logCommand(int cmd, int opt) {
+ String s = "" + cmd;
+ switch (cmd) {
+ case cm_WILL:
+ s = "WILL";
+ break;
+ case cm_WONT:
+ s = "WONT";
+ break;
+ case cm_DO:
+ s = "DO";
+ break;
+ case cm_DONT:
+ s = "DONT";
+ break;
+ case cm_SB:
+ s = "SB";
+ break;
+ }
+ s += " ";
+ switch (opt) {
+ case co_ECHO:
+ s += "ECHO";
+ break;
+ case co_SUPPRESS_GO_AHEAD:
+ s += "SUPPRESS_GO_AHEAD";
+ break;
+ case co_STATUS:
+ s += "STATUS";
+ break;
+ case co_TERMINAL_TYPE:
+ s += "TERMINAL_TYPE";
+ break;
+ case co_NAWS:
+ s += "NAWS";
+ break;
+ case co_TERMINAL_SPEED:
+ s += "TERMINAL_SPEED";
+ break;
+ case co_TOGGLE_FLOW_CONTROL:
+ s += "TOGGLE_FLOW_CONTROL";
+ break;
+ case co_X_DISPLAY_LOCATION:
+ s += "X_DISPLAY_LOCATION";
+ break;
+ case co_ENVIRON:
+ s += "ENVIRON";
+ break;
+ case co_NEW_ENVIRON:
+ s += "NEW_ENVIRON";
+ break;
+ default:
+ s += opt;
+ break;
+ }
+ for (TelnetTraceListener l : trace_listeners) l.command(s);
+ }
+
+ private int read_ch() throws IOException {
+ try {
+ return inp.read();
+ }
+ catch (SocketException x) {
+ String s = x.getMessage();
+ if (s.startsWith("Socket closed")) return -1;
+ if (s.startsWith("socket closed")) return -1;
+ throw x;
+ }
+ }
+
+ public void run() {
+ try {
+ synchronized (out) {
+ out.write(cm_IAC);
+ out.write(echo ? cm_DO : cm_DONT);
+ out.write(co_ECHO);
+ out.flush();
+ }
+ for (;;) {
+ int rd = read_ch();
+ if (rd < 0) break;
+ if (rd == cm_IAC) {
+ int cm = read_ch();
+ if (cm < 0) break;
+ if (cm != cm_IAC) {
+ int co = read_ch();
+ if (co < 0) break;
+ if (co == cm_DataMark) continue;
+ logCommand(cm, co);
+ synchronized (out) {
+ if (mode_cnt[co] >= 5) continue;
+ switch (cm) {
+ case cm_WILL:
+ mode_rem[co] = true;
+ break;
+ case cm_WONT:
+ mode_rem[co] = false;
+ break;
+ case cm_DO:
+ out.write(cm_IAC);
+ if (co == co_SUPPRESS_GO_AHEAD) {
+ out.write(cm_WILL);
+ }
+ else if (co == co_NEW_ENVIRON && prompt != null) {
+ out.write(cm_WILL);
+ }
+ else {
+ out.write(cm_WONT);
+ }
+ out.write(co);
+ break;
+ case cm_DONT:
+ out.write(cm_IAC);
+ out.write(cm_WONT);
+ out.write(co);
+ break;
+ case cm_SB:
+ int ac = read_ch();
+ if (ac < 0) break;
+ if (ac == ac_SEND) {
+ if (co == co_NEW_ENVIRON) {
+ out.write(cm_IAC);
+ out.write(cm_SB);
+ out.write(co_NEW_ENVIRON);
+ out.write(ac_IS);
+ if (prompt != null) {
+ out.write(sp_VAR);
+ out.write('P');
+ out.write('S');
+ out.write('1');
+ out.write(sp_VALUE);
+ for (int k = 0; k < prompt.length(); k++) out.write(prompt.charAt(k));
+ }
+ out.write(cm_IAC);
+ out.write(cm_SE);
+ }
+ }
+ int c0 = 0;
+ for (;;) {
+ int c1 = read_ch();
+ if (c0 == cm_IAC && c1 == cm_SE) break;
+ if (c0 == cm_IAC && c1 == cm_IAC) c1 = 0;
+ c0 = c1;
+ }
+ break;
+ default:
+ throw new IOException("Invalid command: " + cm);
+ }
+ out.flush();
+ mode_cnt[co]++;
+ }
+ continue;
+ }
+ }
+ synchronized (TelnetInputStream.this) {
+ int new_inp = (buf_inp + 1) % buf.length;
+ while (new_inp == buf_out) TelnetInputStream.this.wait();
+ buf[buf_inp] = (byte)rd;
+ buf_inp = new_inp;
+ TelnetInputStream.this.notify();
+ }
+ }
+ }
+ catch (InterruptedException x) {
+ err = new InterruptedIOException();
+ }
+ catch (IOException x) {
+ if (!closed) err = x;
+ }
+ finally {
+ synchronized (TelnetInputStream.this) {
+ eof = true;
+ TelnetInputStream.this.notify();
+ }
+ }
+ }
+ }
+
+ TelnetInputStream(InputStream inp, OutputStream out, boolean echo, String prompt) {
+ super(inp);
+ if (!(inp instanceof BufferedInputStream)) inp = new BufferedInputStream(inp);
+ this.inp = inp;
+ this.out = out;
+ this.echo = echo;
+ this.prompt = prompt;
+ reader.start();
+ }
+
+ public synchronized void addTraceListener(TelnetTraceListener l) {
+ trace_listeners.add(l);
+ }
+
+ public synchronized void removeTraceListener(TelnetTraceListener l) {
+ trace_listeners.remove(l);
+ }
+
+ public synchronized int read() throws IOException {
+ try {
+ while (buf_out == buf_inp) {
+ if (err != null) throw new IOException(err.getMessage());
+ if (eof) return -1;
+ wait();
+ }
+ int res = buf[buf_out] & 0xff;
+ buf_out = (buf_out + 1) % buf.length;
+ notify();
+ return res;
+ }
+ catch (InterruptedException x) {
+ throw new InterruptedIOException();
+ }
+ }
+
+ public synchronized int read(byte b[], int off, int len) throws IOException {
+ boolean nfy = false;
+ try {
+ int cnt = 0;
+ while (cnt < len) {
+ while (buf_out == buf_inp) {
+ if (cnt > 0) return cnt;
+ if (err != null) throw new IOException(err.getMessage());
+ if (eof) return -1;
+ if (nfy) {
+ notify();
+ nfy = false;
+ }
+ wait();
+ }
+ b[off++] = buf[buf_out];
+ buf_out = (buf_out + 1) % buf.length;
+ nfy = true;
+ cnt++;
+ }
+ return cnt;
+ }
+ catch (InterruptedException x) {
+ throw new InterruptedIOException();
+ }
+ finally {
+ if (nfy) notify();
+ }
+ }
+
+ public synchronized int available() throws IOException {
+ return (buf_inp + buf.length - buf_out) % buf.length;
+ }
+
+ public synchronized void close() throws IOException {
+ closed = true;
+ super.close();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TimeOutInputStream.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TimeOutInputStream.java
new file mode 100644
index 000000000..e8bb3ab4f
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/TimeOutInputStream.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.io.*;
+
+class TimeOutInputStream extends FilterInputStream {
+
+ private byte buf[];
+ private int buf_inp = 0;
+ private int buf_out = 0;
+ private boolean eof = false;
+ private IOException err;
+ private InputStream inp;
+ private long time = 0;
+ private Thread thread;
+
+ private class Prefetch extends Thread {
+
+ public void run() {
+ try {
+ for (;;) {
+ int rd = inp.read();
+ if (rd < 0) break;
+ synchronized (TimeOutInputStream.this) {
+ int new_inp = (buf_inp + 1) % buf.length;
+ while (new_inp == buf_out) TimeOutInputStream.this.wait();
+ buf[buf_inp] = (byte)rd;
+ buf_inp = new_inp;
+ TimeOutInputStream.this.notify();
+ }
+ }
+ }
+ catch (InterruptedException x) {
+ err = new InterruptedIOException();
+ }
+ catch (InterruptedIOException x) {
+ err = x;
+ }
+ catch (IOException x) {
+ err = x;
+ }
+ finally {
+ synchronized (TimeOutInputStream.this) {
+ eof = true;
+ TimeOutInputStream.this.notify();
+ }
+ }
+ }
+ }
+
+ TimeOutInputStream(InputStream in, long time) {
+ this(in, 0x1000, time);
+ }
+
+ TimeOutInputStream(InputStream in, int size, long time) {
+ super(in);
+ inp = in;
+ buf = new byte[size];
+ this.time = time;
+ thread = new Prefetch();
+ thread.start();
+ }
+
+ public void setTimeOut(long time) {
+ this.time = time;
+ }
+
+ public synchronized int read() throws IOException {
+ try {
+ int cnt = 0;
+ while (buf_inp == buf_out) {
+ if (err != null) throw new IOException(err.getMessage());
+ if (eof) return -1;
+ if (time != 0) {
+ if (cnt > 0) throw new IOException("Time Out");
+ wait(time);
+ cnt++;
+ }
+ else {
+ wait();
+ }
+ }
+ int res = buf[buf_out] & 0xff;
+ buf_out = (buf_out + 1) % buf.length;
+ notify();
+ return res;
+ }
+ catch (InterruptedException x) {
+ throw new InterruptedIOException();
+ }
+ }
+
+ public synchronized int read(byte b[], int off, int len) throws IOException {
+ boolean nfy = false;
+ try {
+ int res = 0;
+ while (res < len) {
+ int cnt = 0;
+ while (buf_inp == buf_out) {
+ if (res > 0) return res;
+ if (err != null) throw new IOException(err.getMessage());
+ if (eof) return -1;
+ if (nfy) {
+ notify();
+ nfy = false;
+ }
+ if (time != 0) {
+ if (cnt > 0) throw new IOException("Time Out");
+ wait(time);
+ cnt++;
+ }
+ else {
+ wait();
+ }
+ }
+ b[off++] = buf[buf_out];
+ buf_out = (buf_out + 1) % buf.length;
+ nfy = true;
+ res++;
+ }
+ return res;
+ }
+ catch (InterruptedException x) {
+ throw new InterruptedIOException();
+ }
+ finally {
+ if (nfy) notify();
+ }
+ }
+
+ public synchronized int available() throws IOException {
+ return (buf_inp - buf_out + buf.length) % buf.length;
+ }
+
+ public synchronized void close() throws IOException {
+ super.close();
+ if (thread != null) {
+ try {
+ thread.interrupt();
+ while (!eof) wait();
+ thread = null;
+ }
+ catch (InterruptedException x) {
+ throw new InterruptedIOException();
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardFirstPage.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardFirstPage.java
new file mode 100644
index 000000000..c83842cb1
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardFirstPage.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+class WizardFirstPage extends WizardPage implements Listener {
+
+ private final SetupWizardDialog wizard;
+
+ private Button button_props;
+ private Button button_local;
+ private Button button_login;
+
+ WizardFirstPage(SetupWizardDialog wizard) {
+ super("FirstPage");
+ this.wizard = wizard;
+ setTitle("Select a task");
+ setDescription("Select an option that describes the task you want the wizard to perform");
+ }
+
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NULL);
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 1;
+ composite.setLayout(gl);
+
+ button_props = new Button(composite, SWT.RADIO | SWT.WRAP | SWT.MULTI);
+ button_props.addListener(SWT.Selection, this);
+ button_props.setText("Manual setup of TCF connection properties.");
+
+ button_local = new Button(composite, SWT.RADIO | SWT.WRAP | SWT.MULTI);
+ button_local.addListener(SWT.Selection, this);
+ button_local.setText("Setup TCF agent on local host.");
+
+ button_login = new Button(composite, SWT.RADIO | SWT.WRAP | SWT.MULTI);
+ button_login.addListener(SWT.Selection, this);
+ button_login.setText("Setup TCF agent on remote host over Telnet or SSH.");
+
+ setControl(composite);
+ }
+
+ public void handleEvent(Event event) {
+ getContainer().updateButtons();
+ }
+
+ @Override
+ public IWizardPage getNextPage() {
+ if (button_props.getSelection()) return wizard.getPage("PropsPage");
+ if (button_local.getSelection()) return wizard.getPage("LocalPage");
+ if (button_login.getSelection()) return wizard.getPage("LoginPage");
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLocalPage.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLocalPage.java
new file mode 100644
index 000000000..1ec8cadff
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLocalPage.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+
+class WizardLocalPage extends WizardPage implements Listener {
+
+ WizardLocalPage(SetupWizardDialog wizard) {
+ super("LocalPage");
+ setTitle("Local TCF agent configuration");
+ }
+
+ public void handleEvent(Event event) {
+ getContainer().updateButtons();
+ }
+
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NULL);
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 1;
+ composite.setLayout(gl);
+
+ new Label(composite, SWT.WRAP).setText("Under construction...");
+
+ setControl(composite);
+ }
+
+ @Override
+ public IWizardPage getNextPage() {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLogPage.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLogPage.java
new file mode 100644
index 000000000..9d9ee9b62
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLogPage.java
@@ -0,0 +1,400 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.dialogs.IPageChangingListener;
+import org.eclipse.jface.dialogs.PageChangingEvent;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.tcf.core.Base64;
+import org.eclipse.tm.tcf.ssl.TCFSecurityManager;
+import org.osgi.framework.Bundle;
+
+class WizardLogPage extends WizardPage implements Runnable {
+
+ private final SetupWizardDialog wizard;
+
+ private Thread thread;
+ private String protocol;
+ private String host;
+ private String user;
+ private String user_password;
+ private String root_password;
+
+ private Text log_text;
+
+ private Display display;
+ private Shell parent;
+ private IRemoteShell shell;
+
+ WizardLogPage(SetupWizardDialog wizard) {
+ super("LogPage");
+ this.wizard = wizard;
+ setTitle("Remote host login");
+ setDescription("");
+ }
+
+ public void createControl(Composite parent) {
+ display = parent.getDisplay();
+ this.parent = parent.getShell();
+ ((WizardDialog)getContainer()).addPageChangingListener(new IPageChangingListener() {
+ public void handlePageChanging(PageChangingEvent event) {
+ if (event.getCurrentPage() instanceof WizardLoginPage && event.getTargetPage() == WizardLogPage.this) {
+ runSetupJob((WizardLoginPage)event.getCurrentPage());
+ }
+ }
+ });
+
+ Composite composite = new Composite(parent, SWT.NULL);
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 1;
+ composite.setLayout(gl);
+
+ new Label(composite, SWT.WRAP).setText("Agent installation log:");
+
+ log_text = new Text(composite, SWT.BORDER | SWT.MULTI | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL);
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ log_text.setLayoutData(gd);
+
+ setControl(composite);
+ }
+
+ private void runSetupJob(WizardLoginPage login) {
+ assert display != null;
+ assert display.getThread() == Thread.currentThread();
+ if (thread != null) return;
+ setErrorMessage(null);
+ protocol = login.protocol.getText();
+ host = login.host.getText();
+ user = login.user.getText();
+ user_password = login.user_password.getText();
+ root_password = login.root_password.getText();
+ log_text.setText("Connect to " + host + "\n");
+ thread = new Thread(this);
+ thread.start();
+ }
+
+ public void run() {
+ Throwable error = null;
+ try {
+ if ("Telnet".equals(protocol)) {
+ shell = new TelnetClient(InetAddress.getByName(host), 23, user, user_password);
+ }
+ else if ("SSH".equals(protocol)) {
+ shell = new SSHClient(parent, host, user, user_password);
+ }
+ else {
+ throw new Exception("Invalid protocol name: " + protocol);
+ }
+
+ String s;
+
+ if (!user.equals("root")) {
+ send("su", true);
+ expect("Password: ", true);
+ send(root_password, false);
+ s = waitPrompt();
+ if (s.length() > 0) throw new Exception(s);
+ }
+ exec("cd /tmp");
+ send("uname -o", true);
+ String os = waitPrompt().replace('\n', ' ').trim();
+ send("uname -m", true);
+ String machine = waitPrompt().replace('\n', ' ').trim();
+ String version = "0.5.0";
+ Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
+
+ URL url = FileLocator.find(bundle, new Path("agent/get-os-tag"), null);
+ if (url == null) throw new Exception("Cannot find get-os-tag script");
+ send("cat >get-os-tag", true);
+ InputStream inp = url.openStream();
+ byte[] buf = new byte[0x100];
+ for (;;) {
+ int len = inp.read(buf);
+ if (len < 0) break;
+ shell.write(new String(buf, 0, len, "ASCII"));
+ for (int i = 0; i < len; i++) {
+ if (buf[i] == '\n') shell.expect("\n");
+ }
+ }
+ inp.close();
+ shell.write("\004");
+ s = waitPrompt();
+ if (s.length() > 0) throw new Exception(s);
+
+ exec("chmod u+x get-os-tag");
+
+ send("./get-os-tag", true);
+ String os_tag = waitPrompt().replace('\n', ' ').trim();
+
+ exec("rm -f get-os-tag");
+
+ url = null;
+ String fnm = null;
+ String machine0 = machine;
+ for (;;) {
+ for (int release = 16; url == null && release > 0; release--) {
+ fnm = "tcf-agent-" + version + "-" + release + "." + os_tag + "." + machine + ".rpm";
+ url = FileLocator.find(bundle, new Path("agent/" + os + "/" + machine + "/" + fnm), null);
+ }
+ if (url != null) break;
+ if (machine.equals("i686")) machine = "i586";
+ else if (machine.equals("i586")) machine = "i486";
+ else if (machine.equals("i486")) machine = "i386";
+ else {
+ machine = machine0;
+ if (os_tag.startsWith("fc")) {
+ int n = Integer.parseInt(os_tag.substring(2)) - 1;
+ if (n <= 0) break;
+ os_tag = "fc" + n;
+ }
+ else if (os_tag.startsWith("rh")) {
+ int n = Integer.parseInt(os_tag.substring(2)) - 1;
+ if (n <= 0) break;
+ os_tag = "rh" + n;
+ }
+ else break;
+ }
+ }
+ if (url == null) throw new Exception("Unsupported target OS or CPU");
+
+ inp = url.openStream();
+ send("which base64", true);
+ s = waitPrompt();
+ if (s.indexOf(':') < 0) {
+ send("base64 -di >" + fnm, true);
+ sendBase64(inp);
+ shell.write("\004");
+ s = waitPrompt();
+ if (s.length() > 0) throw new Exception(s);
+ }
+ else {
+ send("which uudecode", true);
+ s = waitPrompt();
+ if (s.indexOf(':') < 0) {
+ send("uudecode", true);
+ send("begin-base64 644 " + fnm, true);
+ sendBase64(inp);
+ send("====", true);
+ s = waitPrompt();
+ if (s.length() > 0) throw new Exception(s);
+ }
+ else {
+ throw new Exception("No base64 or uudecode commands available");
+ }
+ }
+ inp.close();
+
+ send("rpm -e --quiet tcf-agent", true);
+ waitPrompt();
+ exec("rm -f /etc/init.d/tcf-agent*");
+ exec("rpm -i --quiet " + fnm);
+ exec("rm -f " + fnm);
+
+ File certs = TCFSecurityManager.getCertificatesDirectory();
+
+ File local_cert = new File(certs, "local.cert");
+ File local_priv = new File(certs, "local.priv");
+
+ if (!local_cert.exists() || !local_priv.exists()) {
+ copyRemoteSecret("local.cert", local_cert);
+ copyRemoteSecret("local.priv", local_priv);
+ exec("/usr/sbin/tcf-agent -c");
+ }
+
+ copyRemoteSecret("local.cert", new File(certs, host + ".cert"));
+ copyLocalSecret(local_cert, InetAddress.getLocalHost().getHostName() + ".cert");
+
+ if (!user.equals("root")) {
+ send("exit", true);
+ waitPrompt();
+ }
+ }
+ catch (Throwable x) {
+ error = x;
+ }
+ if (shell != null) {
+ try {
+ shell.close();
+ shell = null;
+ }
+ catch (Throwable x) {
+ if (error != null) error = x;
+ }
+ }
+ done(error);
+ }
+
+ private void sendBase64(InputStream inp) throws Exception {
+ byte[] buf = new byte[0x100 * 3];
+ for (;;) {
+ int len = 0;
+ while (len < buf.length) {
+ int rd = inp.read(buf, len, buf.length - len);
+ if (rd < 0) break;
+ len += rd;
+ }
+ if (len == 0) break;
+ send(new String(Base64.toBase64(buf, 0, len)), false);
+ }
+ }
+
+ private void copyRemoteSecret(String from, File to) throws Exception {
+ send("cat /etc/tcf/ssl/" + from, true);
+ String s = waitPrompt();
+ if (s.indexOf("-----BEGIN ") != 0) throw new Exception(s);
+ BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(to), "ASCII"));
+ wr.write(s);
+ wr.close();
+ }
+
+ private void copyLocalSecret(File from, String to) throws Exception {
+ send("cat >/etc/tcf/ssl/" + to, true);
+ BufferedReader rd = new BufferedReader(new InputStreamReader(
+ new FileInputStream(from), "ASCII"));
+ for (;;) {
+ String s = rd.readLine();
+ if (s == null) break;
+ send(s, true);
+ }
+ shell.write("\004");
+ String s = waitPrompt();
+ if (s.length() > 0) throw new Exception(s);
+ }
+
+ private void send(final String s, boolean log) throws IOException {
+ if (log) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (log_text.isDisposed()) return;
+ log_text.append("Send: ");
+ log_text.append(s);
+ if (!s.endsWith("\n")) log_text.append("\n");
+ }
+ });
+ }
+ shell.write(s);
+ shell.write("\n");
+ if (log) shell.expect(s);
+ shell.expect("\n");
+ }
+
+ private void expect(final String s, boolean log) throws IOException {
+ if (log) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (log_text.isDisposed()) return;
+ log_text.append("Expect: ");
+ log_text.append(s);
+ if (!s.endsWith("\n")) log_text.append("\n");
+ }
+ });
+ }
+ shell.expect(s);
+ }
+
+ private String waitPrompt() throws IOException {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (log_text.isDisposed()) return;
+ log_text.append("Wait for shell prompt\n");
+ }
+ });
+ final String s = shell.waitPrompt();
+ if (s.length() > 0) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (log_text.isDisposed()) return;
+ log_text.append("Got: ");
+ log_text.append(s);
+ if (!s.endsWith("\n")) log_text.append("\n");
+ }
+ });
+ }
+ return s;
+ }
+
+ private void exec(String cmd) throws Exception {
+ send(cmd, true);
+ String s = waitPrompt();
+ if (s.length() > 0) throw new Exception(s);
+ }
+
+ private void done(final Throwable error) {
+ display.asyncExec(new Runnable() {
+ public void run() {
+ thread = null;
+ protocol = null;
+ host = null;
+ user = null;
+ user_password = null;
+ root_password = null;
+ if (log_text.isDisposed()) return;
+ if (error != null) {
+ StringWriter buf = new StringWriter();
+ PrintWriter pwr = new PrintWriter(buf);
+ error.printStackTrace(pwr);
+ pwr.flush();
+ log_text.append(buf.toString());
+ setErrorMessage(error.getClass().getName() + ": " + error.getLocalizedMessage());
+ }
+ else {
+ log_text.append("Done\n");
+ setErrorMessage(null);
+ }
+ getContainer().updateButtons();
+ }
+ });
+ }
+
+ @Override
+ public IWizardPage getPreviousPage() {
+ if (thread != null) return null;
+ return wizard.getPage("LoginPage");
+ }
+
+ @Override
+ public IWizardPage getNextPage() {
+ return null;
+ }
+
+ public boolean canFinish() {
+ return thread == null && getErrorMessage() == null;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLoginPage.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLoginPage.java
new file mode 100644
index 000000000..313ef8389
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardLoginPage.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IPreferencesService;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.preference.IPreferencePage;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.preference.PreferenceNode;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.osgi.framework.Bundle;
+
+class WizardLoginPage extends WizardPage implements Listener {
+
+ private static final String
+ PREF_PROTOCOL = "setup.login.protocol",
+ PREF_HOST = "setup.login.host",
+ PREF_USER = "setup.login.user";
+
+ private final SetupWizardDialog wizard;
+
+ final String[] protocols = { "Telnet", "SSH" };
+
+ Combo protocol;
+ Button prefs;
+ Text host;
+ Text user;
+ Text user_password;
+ Text root_password;
+
+ WizardLoginPage(SetupWizardDialog wizard) {
+ super("LoginPage");
+ this.wizard = wizard;
+ setTitle("Remote TCF agent configuration");
+ setDescription("Enter remote host login data");
+ }
+
+ public void handleEvent(Event event) {
+ getContainer().updateButtons();
+
+ IEclipsePreferences n = new InstanceScope().getNode(Activator.PLUGIN_ID);
+ n.put(PREF_PROTOCOL, protocol.getText());
+ n.put(PREF_HOST, host.getText());
+ n.put(PREF_USER, user.getText());
+
+ root_password.setEnabled(!user.getText().equals("root"));
+ prefs.setEnabled(protocol.getText().equals(protocols[1]));
+ }
+
+ public void createControl(final Composite parent) {
+ GridData gd;
+ Composite composite = new Composite(parent, SWT.NULL);
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 3;
+ composite.setLayout(gl);
+
+ new Label(composite, SWT.NONE).setText("Protocol:");
+ protocol = new Combo(composite, SWT.BORDER | SWT.READ_ONLY);
+ gd = new GridData();
+ gd.horizontalAlignment = GridData.BEGINNING;
+ protocol.setLayoutData(gd);
+ protocol.setItems(protocols);
+ protocol.addListener(SWT.Selection, this);
+
+ prefs = new Button(composite, SWT.PUSH);
+ prefs.setText("Preferences");
+ gd = new GridData();
+ gd.horizontalAlignment = GridData.BEGINNING;
+ gd.widthHint = 100;
+ prefs.setLayoutData(gd);
+ prefs.addSelectionListener(new SelectionListener() {
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ public void widgetSelected(SelectionEvent n) {
+ openProtocolPreferences(parent.getShell(), prefs.getText());
+ }
+ });
+
+ new Label(composite, SWT.NONE).setText("Host:");
+ host = new Text(composite, SWT.BORDER);
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ gd.horizontalAlignment = GridData.BEGINNING;
+ gd.widthHint = 200;
+ host.setLayoutData(gd);
+ host.addListener(SWT.KeyUp, this);
+
+ new Label(composite, SWT.NONE).setText("User:");
+ user = new Text(composite, SWT.BORDER);
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ gd.horizontalAlignment = GridData.BEGINNING;
+ gd.widthHint = 200;
+ user.setLayoutData(gd);
+ user.addListener(SWT.KeyUp, this);
+
+ new Label(composite, SWT.NONE).setText("Password:");
+ user_password = new Text(composite, SWT.BORDER | SWT.PASSWORD);
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ gd.horizontalAlignment = GridData.BEGINNING;
+ gd.widthHint = 200;
+ user_password.setLayoutData(gd);
+ user_password.addListener(SWT.KeyUp, this);
+
+ new Label(composite, SWT.NONE).setText("Root password:");
+ root_password = new Text(composite, SWT.BORDER | SWT.PASSWORD);
+ gd = new GridData();
+ gd.horizontalSpan = 2;
+ gd.horizontalAlignment = GridData.BEGINNING;
+ gd.widthHint = 200;
+ root_password.setLayoutData(gd);
+ root_password.addListener(SWT.KeyUp, this);
+
+ IEclipsePreferences d = new DefaultScope().getNode(Activator.PLUGIN_ID);
+ d.put(PREF_PROTOCOL, protocols[0]);
+
+ IEclipsePreferences[] n = { new InstanceScope().getNode(Activator.PLUGIN_ID) };
+ IPreferencesService s = Platform.getPreferencesService();
+ protocol.setText(s.get(PREF_PROTOCOL, "", n));
+ host.setText(s.get(PREF_HOST, "", n));
+ user.setText(s.get(PREF_USER, "", n));
+
+ root_password.setEnabled(!user.getText().equals("root"));
+ prefs.setEnabled(protocol.getText().equals(protocols[1]));
+
+ setControl(composite);
+ }
+
+ private void openProtocolPreferences(Shell shell, String title) {
+ try {
+ PreferenceManager mgr = new PreferenceManager();
+ IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint("org.eclipse.ui", "preferencePages");
+ IExtension[] extensions = point.getExtensions();
+ for (int i = 0; i < extensions.length; i++) {
+ IConfigurationElement[] e = extensions[i].getConfigurationElements();
+ for (int j = 0; j < e.length; j++) {
+ String nm = e[j].getName();
+ if (nm.equals("page")) { //$NON-NLS-1$
+ String cnm = e[j].getAttribute("class"); //$NON-NLS-1$
+ if (cnm == null) continue;
+ if (!cnm.startsWith("org.eclipse.jsch.")) continue;
+ String id = e[j].getAttribute("id"); //$NON-NLS-1$
+ if (id == null) id = cnm;
+ Bundle bundle = Platform.getBundle(extensions[i].getNamespaceIdentifier());
+ Class<?> c = bundle.loadClass(cnm);
+ IPreferencePage page = (IPreferencePage)c.newInstance();
+ String pnm = e[j].getAttribute("name"); //$NON-NLS-1$
+ if (pnm != null) page.setTitle(pnm);
+ mgr.addToRoot(new PreferenceNode(id, page));
+ }
+ }
+ }
+ PreferenceDialog dialog = new PreferenceDialog(shell, mgr);
+ dialog.create();
+ dialog.setMessage(title);
+ dialog.open();
+ }
+ catch (Throwable err) {
+ String msg = err.getLocalizedMessage();
+ if (msg == null || msg.length() == 0) msg = err.getClass().getName();
+ MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
+ mb.setText("Error");
+ mb.setMessage("Cannot open preferences dialog:\n" + msg);
+ mb.open();
+ }
+ }
+
+ @Override
+ public IWizardPage getNextPage() {
+ if (host.getText().length() > 0 &&
+ user.getText().length() > 0 &&
+ (user_password.getText().length() > 0 || protocol.getText().equals("SSH")) &&
+ (!root_password.isEnabled() || root_password.getText().length() > 0))
+ return wizard.getPage("LogPage");
+ return null;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardPropsPage.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardPropsPage.java
new file mode 100644
index 000000000..af1ab7711
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/launch/setup/WizardPropsPage.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.launch.setup;
+
+import java.util.Map;
+
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+class WizardPropsPage extends WizardPage {
+
+ private final Map<String,String> attrs;
+
+ private PeerPropsControl props;
+
+ protected WizardPropsPage(SetupWizardDialog wizard, Map<String,String> attrs) {
+ super("PropsPage");
+ this.attrs = attrs;
+ setTitle("Manual client configuration");
+ }
+
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NULL);
+ GridLayout gl = new GridLayout();
+ gl.numColumns = 1;
+ composite.setLayout(gl);
+ props = new PeerPropsControl(composite, attrs, true, new Runnable() {
+ public void run() {
+ getContainer().updateButtons();
+ }
+ });
+ setControl(composite);
+ }
+
+ public IWizardPage getNextPage() {
+ return null;
+ }
+
+ public boolean canFinish() {
+ return props.isComplete();
+ }
+
+ public boolean performFinish() {
+ props.okPressed();
+ return true;
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ICastToType.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ICastToType.java
new file mode 100644
index 000000000..5d79636f0
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ICastToType.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.tm.tcf.services.ISymbols;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+public interface ICastToType {
+
+ void onCastToTypeChanged();
+
+ TCFDataCache<ISymbols.Symbol> getType();
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/IDetailsProvider.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/IDetailsProvider.java
new file mode 100644
index 000000000..24104eb1d
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/IDetailsProvider.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+public interface IDetailsProvider {
+
+ boolean getDetailText(StyledStringBuffer buf, Runnable done);
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ISourceNotFoundPresentation.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ISourceNotFoundPresentation.java
new file mode 100644
index 000000000..ce0a7aac8
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ISourceNotFoundPresentation.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.ui.IEditorInput;
+
+/**
+ * Adapter to customize source presentation for the source-not-found case.
+ */
+public interface ISourceNotFoundPresentation {
+
+ /**
+ * Returns an editor input that should be used to display a source-not-found editor
+ * for the given object or <code>null</code> if unable to provide an editor input
+ * for the given object.
+ *
+ * @param element a debug model element
+ * @param cfg the launch configuration of the debug element
+ * @param file unresolved source file path
+ * @return an editor input, or <code>null</code> if none
+ */
+ public IEditorInput getEditorInput(Object element, ILaunchConfiguration cfg, String file);
+
+ /**
+ * Returns the id of the source-not-found editor to use to display the
+ * given editor input and object, or <code>null</code> if
+ * unable to provide an editor id.
+ *
+ * @param input an editor input that was previously retrieved from this
+ * presentation's <code>getEditorInput</code> method
+ * @param element the object that was used in the call to
+ * <code>getEditorInput</code>, that corresponds to the given editor
+ * input
+ * @return an editor id, or <code>null</code> if none
+ */
+ public String getEditorId(IEditorInput input, Object element);
+
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ISymbolOwner.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ISymbolOwner.java
new file mode 100644
index 000000000..2d3a6100c
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/ISymbolOwner.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+public interface ISymbolOwner {
+
+ void addSymbol(TCFNodeSymbol s);
+
+ void removeSymbol(TCFNodeSymbol s);
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/IWatchInExpressions.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/IWatchInExpressions.java
new file mode 100644
index 000000000..9fee2ceb9
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/IWatchInExpressions.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+public interface IWatchInExpressions {
+
+ TCFDataCache<String> getExpressionText();
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/StyledStringBuffer.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/StyledStringBuffer.java
new file mode 100644
index 000000000..7be54744f
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/StyledStringBuffer.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.swt.graphics.RGB;
+
+class StyledStringBuffer {
+
+ private final StringBuffer bf = new StringBuffer();
+ private final ArrayList<Style> styles = new ArrayList<Style>();
+
+ static class Style {
+ int pos;
+ int len;
+ int font;
+ RGB bg;
+ RGB fg;
+ }
+
+ StyledStringBuffer append(int pos, int font, RGB bg, RGB fg) {
+ Style x = new Style();
+ x.pos = pos;
+ x.len = bf.length() - pos;
+ x.font = font;
+ x.bg = bg;
+ x.fg = fg;
+ styles.add(x);
+ return this;
+ }
+
+ StyledStringBuffer append(String s) {
+ bf.append(s);
+ return this;
+ }
+
+ StyledStringBuffer append(char ch) {
+ bf.append(ch);
+ return this;
+ }
+
+ StyledStringBuffer append(int i) {
+ bf.append(i);
+ return this;
+ }
+
+ StyledStringBuffer append(String s, int font) {
+ Style x = new Style();
+ x.pos = bf.length();
+ x.len = s.length();
+ x.font = font;
+ styles.add(x);
+ bf.append(s);
+ return this;
+ }
+
+ StyledStringBuffer append(String s, int font, RGB bg, RGB fg) {
+ Style x = new Style();
+ x.pos = bf.length();
+ x.len = s.length();
+ x.font = font;
+ x.bg = bg;
+ x.fg = fg;
+ styles.add(x);
+ bf.append(s);
+ return this;
+ }
+
+ StyledStringBuffer append(StyledStringBuffer s) {
+ int offs = bf.length();
+ for (Style y : s.styles) {
+ Style x = new Style();
+ x.pos = y.pos + offs;
+ x.len = y.len;
+ x.font = y.font;
+ x.bg = y.bg;
+ x.fg = y.fg;
+ styles.add(x);
+ }
+ bf.append(s.bf);
+ return this;
+ }
+
+ StringBuffer getStringBuffer() {
+ return bf;
+ }
+
+ Collection<Style> getStyle() {
+ return styles;
+ }
+
+ int length() {
+ return bf.length();
+ }
+
+ @Override
+ public String toString() {
+ return bf.toString();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFAnnotationImageProvider.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFAnnotationImageProvider.java
new file mode 100644
index 000000000..486d70222
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFAnnotationImageProvider.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.texteditor.IAnnotationImageProvider;
+
+public class TCFAnnotationImageProvider implements IAnnotationImageProvider {
+
+ public Image getManagedImage(Annotation annotation) {
+ return ((TCFAnnotationManager.TCFAnnotation)annotation).image;
+ }
+
+ public String getImageDescriptorId(Annotation annotation) {
+ return null;
+ }
+
+ public ImageDescriptor getImageDescriptor(String imageDescritporId) {
+ return null;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFAnnotationManager.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFAnnotationManager.java
new file mode 100644
index 000000000..21c09020d
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFAnnotationManager.java
@@ -0,0 +1,624 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationListener;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.debug.core.model.ISourceLocator;
+import org.eclipse.debug.ui.DebugUITools;
+import org.eclipse.debug.ui.IDebugUIConstants;
+import org.eclipse.debug.ui.ISourcePresentation;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tm.internal.tcf.debug.launch.TCFSourceLookupDirector;
+import org.eclipse.tm.internal.tcf.debug.model.ITCFBreakpointListener;
+import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpointsStatus;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.tcf.protocol.JSON;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.services.ILineNumbers;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.ISelectionListener;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+public class TCFAnnotationManager {
+
+ private static final String
+ TYPE_BP_INSTANCE = "org.eclipse.tm.tcf.debug.breakpoint_instance",
+ TYPE_TOP_FRAME = "org.eclipse.tm.tcf.debug.top_frame",
+ TYPE_STACK_FRAME = "org.eclipse.tm.tcf.debug.stack_frame";
+
+ class TCFAnnotation extends Annotation {
+
+ final ILineNumbers.CodeArea area;
+ final Image image;
+ final String text;
+ final String type;
+ final int hash_code;
+
+ IAnnotationModel model;
+
+ TCFAnnotation(ILineNumbers.CodeArea area, Image image, String text, String type) {
+ this.area = area;
+ this.image = image;
+ this.text = text;
+ this.type = type;
+ hash_code = area.hashCode() + image.hashCode() + text.hashCode() + type.hashCode();
+ setText(text);
+ setType(type);
+ }
+
+ protected Image getImage() {
+ return image;
+ }
+
+ void dispose() {
+ assert Thread.currentThread() == display.getThread();
+ if (model != null) {
+ model.removeAnnotation(this);
+ model = null;
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof TCFAnnotation)) return false;
+ TCFAnnotation a = (TCFAnnotation)o;
+ if (!area.equals(a.area)) return false;
+ if (!image.equals(a.image)) return false;
+ if (!text.equals(a.text)) return false;
+ if (!type.equals(a.type)) return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return hash_code;
+ }
+ }
+
+ private class WorkbenchWindowInfo {
+ final LinkedList<TCFAnnotation> annotations = new LinkedList<TCFAnnotation>();
+
+ void dispose() {
+ for (TCFAnnotation a : annotations) a.dispose();
+ annotations.clear();
+ }
+ }
+
+ private final HashMap<IWorkbenchWindow,WorkbenchWindowInfo> windows =
+ new HashMap<IWorkbenchWindow,WorkbenchWindowInfo>();
+
+ private final HashSet<IWorkbenchWindow> dirty_windows = new HashSet<IWorkbenchWindow>();
+ private final HashSet<TCFLaunch> dirty_launches = new HashSet<TCFLaunch>();
+ private final HashSet<TCFLaunch> changed_launch_cfgs = new HashSet<TCFLaunch>();
+
+ private final TCFLaunch.LaunchListener launch_listener = new TCFLaunch.LaunchListener() {
+
+ public void onCreated(TCFLaunch launch) {
+ }
+
+ public void onConnected(final TCFLaunch launch) {
+ updateAnnotations(null, launch);
+ TCFBreakpointsStatus bps = launch.getBreakpointsStatus();
+ if (bps == null) return;
+ bps.addListener(new ITCFBreakpointListener() {
+
+ public void breakpointStatusChanged(String id) {
+ updateAnnotations(null, launch);
+ }
+
+ public void breakpointRemoved(String id) {
+ updateAnnotations(null, launch);
+ }
+
+ public void breakpointChanged(String id) {
+ }
+ });
+ }
+
+ public void onDisconnected(final TCFLaunch launch) {
+ assert Protocol.isDispatchThread();
+ updateAnnotations(null, launch);
+ }
+
+ public void onProcessOutput(TCFLaunch launch, String process_id, int stream_id, byte[] data) {
+ }
+
+ public void onProcessStreamError(TCFLaunch launch, String process_id,
+ int stream_id, Exception error, int lost_size) {
+ }
+ };
+
+ private final ISelectionListener selection_listener = new ISelectionListener() {
+
+ public void selectionChanged(IWorkbenchPart part, ISelection selection) {
+ updateAnnotations(part.getSite().getWorkbenchWindow(), (TCFLaunch)null);
+ if (selection instanceof IStructuredSelection) {
+ final Object obj = ((IStructuredSelection)selection).getFirstElement();
+ if (obj instanceof TCFNodeStackFrame && ((TCFNodeStackFrame)obj).isTraceLimit()) {
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ ((TCFNodeStackFrame)obj).riseTraceLimit();
+ }
+ });
+ }
+ }
+ }
+ };
+
+ private final IWindowListener window_listener = new IWindowListener() {
+
+ public void windowActivated(IWorkbenchWindow window) {
+ }
+
+ public void windowClosed(IWorkbenchWindow window) {
+ assert windows.get(window) != null;
+ window.getSelectionService().removeSelectionListener(
+ IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
+ windows.remove(window).dispose();
+ }
+
+ public void windowDeactivated(IWorkbenchWindow window) {
+ }
+
+ public void windowOpened(IWorkbenchWindow window) {
+ if (windows.get(window) != null) return;
+ window.getSelectionService().addSelectionListener(
+ IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
+ windows.put(window, new WorkbenchWindowInfo());
+ updateAnnotations(window, (TCFLaunch)null);
+ }
+ };
+
+ private final ILaunchConfigurationListener launch_conf_listener = new ILaunchConfigurationListener() {
+
+ public void launchConfigurationAdded(ILaunchConfiguration cfg) {
+ }
+
+ public void launchConfigurationChanged(final ILaunchConfiguration cfg) {
+ displayExec(new Runnable() {
+ public void run() {
+ ILaunch[] arr = launch_manager.getLaunches();
+ for (ILaunch l : arr) {
+ if (l instanceof TCFLaunch) {
+ TCFLaunch t = (TCFLaunch)l;
+ if (cfg.equals(t.getLaunchConfiguration())) {
+ changed_launch_cfgs.add(t);
+ updateAnnotations(null, t);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ public void launchConfigurationRemoved(ILaunchConfiguration cfg) {
+ }
+ };
+
+ private final Display display = Display.getDefault();
+ private final ILaunchManager launch_manager = DebugPlugin.getDefault().getLaunchManager();
+ private int update_unnotations_cnt = 0;
+ private boolean started;
+ private boolean disposed;
+
+ public TCFAnnotationManager() {
+ assert Protocol.isDispatchThread();
+ TCFLaunch.addListener(launch_listener);
+ launch_manager.addLaunchConfigurationListener(launch_conf_listener);
+ displayExec(new Runnable() {
+ public void run() {
+ if (!PlatformUI.isWorkbenchRunning() || PlatformUI.getWorkbench().isStarting()) {
+ display.timerExec(200, this);
+ }
+ else if (!PlatformUI.getWorkbench().isClosing()) {
+ started = true;
+ PlatformUI.getWorkbench().addWindowListener(window_listener);
+ for (IWorkbenchWindow window : PlatformUI.getWorkbench().getWorkbenchWindows()) {
+ window_listener.windowOpened(window);
+ }
+ IWorkbenchWindow w = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (w != null) window_listener.windowActivated(w);
+ }
+ }
+ });
+ }
+
+ public void dispose() {
+ if (disposed) return;
+ assert Protocol.isDispatchThread();
+ disposed = true;
+ launch_manager.removeLaunchConfigurationListener(launch_conf_listener);
+ TCFLaunch.removeListener(launch_listener);
+ displayExec(new Runnable() {
+ public void run() {
+ if (!started) return;
+ PlatformUI.getWorkbench().removeWindowListener(window_listener);
+ for (IWorkbenchWindow window : windows.keySet()) {
+ window.getSelectionService().removeSelectionListener(
+ IDebugUIConstants.ID_DEBUG_VIEW, selection_listener);
+ windows.get(window).dispose();
+ }
+ windows.clear();
+ }
+ });
+ }
+
+ private void displayExec(Runnable r) {
+ synchronized (Device.class) {
+ if (!display.isDisposed()) {
+ display.asyncExec(r);
+ }
+ }
+ }
+
+ /**
+ * Return breakpoint status info for all active TCF debug sessions.
+ * @param breakpoint
+ * @return breakpoint status as defined by TCF Breakpoints service.
+ */
+ Map<TCFLaunch,Map<String,Object>> getBreakpointStatus(IBreakpoint breakpoint) {
+ assert Protocol.isDispatchThread();
+ Map<TCFLaunch,Map<String,Object>> map = new HashMap<TCFLaunch,Map<String,Object>>();
+ if (disposed) return null;
+ ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches();
+ for (ILaunch l : launches) {
+ if (l instanceof TCFLaunch) {
+ TCFLaunch launch = (TCFLaunch)l;
+ TCFBreakpointsStatus bs = launch.getBreakpointsStatus();
+ if (bs != null) map.put(launch, bs.getStatus(breakpoint));
+ }
+ }
+ return map;
+ }
+
+ /**
+ * Return breakpoint status text for all active TCF debug sessions.
+ * @param breakpoint
+ * @return breakpoint status as a string.
+ */
+ @SuppressWarnings("unchecked")
+ String getBreakpointStatusText(IBreakpoint breakpoint) {
+ assert Protocol.isDispatchThread();
+ String error = null;
+ for (Map<String,Object> map : getBreakpointStatus(breakpoint).values()) {
+ if (map != null) {
+ String s = (String)map.get(IBreakpoints.STATUS_ERROR);
+ if (s != null && error == null) error = s;
+ Object planted = map.get(IBreakpoints.STATUS_INSTANCES);
+ if (planted != null) {
+ Collection<Map<String,Object>> list = (Collection<Map<String,Object>>)planted;
+ for (Map<String,Object> m : list) {
+ if (m.get(IBreakpoints.INSTANCE_ERROR) == null) {
+ return "Planted";
+ }
+ }
+ }
+ }
+ }
+ return error;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Object[] toObjectArray(Object o) {
+ if (o == null) return null;
+ Collection<Object> c = (Collection<Object>)o;
+ return (Object[])c.toArray(new Object[c.size()]);
+ }
+
+ @SuppressWarnings("unchecked")
+ private Map<String,Object> toObjectMap(Object o) {
+ return (Map<String,Object>)o;
+ }
+
+ private void addBreakpointErrorAnnotation(List<TCFAnnotation> set, TCFLaunch launch, String id, String error) {
+ Map<String,Object> props = launch.getBreakpointsStatus().getProperties(id);
+ if (props != null) {
+ String file = (String)props.get(IBreakpoints.PROP_FILE);
+ Number line = (Number)props.get(IBreakpoints.PROP_LINE);
+ if (file != null && line != null) {
+ ILineNumbers.CodeArea area = new ILineNumbers.CodeArea(null, file,
+ line.intValue(), 0, line.intValue() + 1, 0,
+ null, null, 0, false, false, false, false);
+ TCFAnnotation a = new TCFAnnotation(area,
+ ImageCache.getImage(ImageCache.IMG_BREAKPOINT_ERROR),
+ "Cannot plant breakpoint: " + error,
+ TYPE_BP_INSTANCE);
+ set.add(a);
+ }
+ }
+ }
+
+ private void updateAnnotations(IWorkbenchWindow window, final TCFNode node) {
+ if (disposed) return;
+ assert Thread.currentThread() == display.getThread();
+ final WorkbenchWindowInfo win_info = windows.get(window);
+ if (win_info == null) return;
+ List<TCFAnnotation> set = null;
+ if (node != null) {
+ set = new TCFTask<List<TCFAnnotation>>(node.getChannel()) {
+ public void run() {
+ if (node.isDisposed()) {
+ done(null);
+ return;
+ }
+ TCFNodeExecContext thread = null;
+ TCFNodeExecContext memory = null;
+ TCFNodeStackFrame frame = null;
+ TCFNodeStackFrame last_top_frame = null;
+ String bp_group = null;
+ boolean suspended = false;
+ if (node instanceof TCFNodeStackFrame) {
+ thread = (TCFNodeExecContext)node.parent;
+ frame = (TCFNodeStackFrame)node;
+ }
+ else if (node instanceof TCFNodeExecContext) {
+ thread = (TCFNodeExecContext)node;
+ TCFChildrenStackTrace trace = thread.getStackTrace();
+ if (!trace.validate(this)) return;
+ frame = trace.getTopFrame();
+ }
+ if (thread != null) {
+ TCFDataCache<IRunControl.RunControlContext> rc_ctx_cache = thread.getRunContext();
+ if (!rc_ctx_cache.validate(this)) return;
+ IRunControl.RunControlContext rc_ctx_data = rc_ctx_cache.getData();
+ if (rc_ctx_data != null) bp_group = rc_ctx_data.getBPGroup();
+ TCFDataCache<TCFNodeExecContext> mem_cache = thread.getMemoryNode();
+ if (!mem_cache.validate(this)) return;
+ memory = mem_cache.getData();
+ if (bp_group == null && memory != null && rc_ctx_data != null && rc_ctx_data.hasState()) bp_group = memory.id;
+ last_top_frame = thread.getLastTopFrame();
+ TCFDataCache<TCFContextState> state_cache = thread.getState();
+ if (!state_cache.validate(this)) return;
+ suspended = state_cache.getData() != null && state_cache.getData().is_suspended;
+ }
+ List<TCFAnnotation> set = new ArrayList<TCFAnnotation>();
+ if (memory != null) {
+ TCFLaunch launch = node.launch;
+ TCFBreakpointsStatus bs = launch.getBreakpointsStatus();
+ if (bs != null) {
+ for (String id : bs.getStatusIDs()) {
+ Map<String,Object> map = bs.getStatus(id);
+ if (map == null) continue;
+ String error = (String)map.get(IBreakpoints.STATUS_ERROR);
+ if (error != null) addBreakpointErrorAnnotation(set, launch, id, error);
+ Object[] arr = toObjectArray(map.get(IBreakpoints.STATUS_INSTANCES));
+ if (arr == null) continue;
+ for (Object o : arr) {
+ Map<String,Object> m = toObjectMap(o);
+ String ctx_id = (String)m.get(IBreakpoints.INSTANCE_CONTEXT);
+ if (ctx_id == null) continue;
+ if (!ctx_id.equals(node.id) && !ctx_id.equals(bp_group)) continue;
+ error = (String)m.get(IBreakpoints.INSTANCE_ERROR);
+ BigInteger addr = JSON.toBigInteger((Number)m.get(IBreakpoints.INSTANCE_ADDRESS));
+ if (addr != null) {
+ ILineNumbers.CodeArea area = null;
+ TCFDataCache<TCFSourceRef> line_cache = memory.getLineInfo(addr);
+ if (line_cache != null) {
+ if (!line_cache.validate(this)) return;
+ TCFSourceRef line_data = line_cache.getData();
+ if (line_data != null && line_data.area != null) area = line_data.area;
+ }
+ if (area == null) {
+ Map<String,Object> props = bs.getProperties(id);
+ if (props != null) {
+ String file = (String)props.get(IBreakpoints.PROP_FILE);
+ Number line = (Number)props.get(IBreakpoints.PROP_LINE);
+ if (file != null && line != null) {
+ area = new ILineNumbers.CodeArea(null, file,
+ line.intValue(), 0, line.intValue() + 1, 0,
+ null, null, 0, false, false, false, false);
+ }
+ }
+ }
+ if (area != null) {
+ if (error != null) {
+ TCFAnnotation a = new TCFAnnotation(area,
+ ImageCache.getImage(ImageCache.IMG_BREAKPOINT_ERROR),
+ "Cannot plant breakpoint at 0x" + addr.toString(16) + ": " + error,
+ TYPE_BP_INSTANCE);
+ set.add(a);
+ error = null;
+ }
+ else {
+ TCFAnnotation a = new TCFAnnotation(area,
+ ImageCache.getImage(ImageCache.IMG_BREAKPOINT_INSTALLED),
+ "Breakpoint planted at 0x" + addr.toString(16),
+ TYPE_BP_INSTANCE);
+ set.add(a);
+ }
+ }
+ }
+ if (error != null) addBreakpointErrorAnnotation(set, launch, id, error);
+ }
+ }
+ }
+ }
+ if (suspended && frame != null && frame.getFrameNo() >= 0) {
+ TCFDataCache<TCFSourceRef> line_cache = frame.getLineInfo();
+ if (!line_cache.validate(this)) return;
+ TCFSourceRef line_data = line_cache.getData();
+ if (line_data != null && line_data.area != null) {
+ TCFAnnotation a = null;
+ if (frame.getFrameNo() == 0) {
+ a = new TCFAnnotation(line_data.area,
+ DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP),
+ "Current Instruction Pointer",
+ TYPE_TOP_FRAME);
+ }
+ else {
+ a = new TCFAnnotation(line_data.area,
+ DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER),
+ "Stack Frame",
+ TYPE_STACK_FRAME);
+ }
+ set.add(a);
+ }
+ }
+ if (!suspended && last_top_frame != null) {
+ TCFDataCache<TCFSourceRef> line_cache = last_top_frame.getLineInfo();
+ if (!line_cache.validate(this)) return;
+ TCFSourceRef line_data = line_cache.getData();
+ if (line_data != null && line_data.area != null) {
+ TCFAnnotation a = new TCFAnnotation(line_data.area,
+ DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER),
+ "Last Instruction Pointer position",
+ TYPE_STACK_FRAME);
+ set.add(a);
+ }
+ }
+ done(set);
+ }
+ }.getE();
+ }
+ boolean flush_all = node == null || changed_launch_cfgs.contains(node.launch);
+ Iterator<TCFAnnotation> i = win_info.annotations.iterator();
+ while (i.hasNext()) {
+ TCFAnnotation a = i.next();
+ if (!flush_all && set != null && set.remove(a)) continue;
+ a.dispose();
+ i.remove();
+ }
+ if (set == null || set.size() == 0) return;
+ Map<IEditorInput,ITextEditor> editors = new HashMap<IEditorInput,ITextEditor>();
+ for (IEditorReference ref : window.getActivePage().getEditorReferences()) {
+ IEditorPart part = ref.getEditor(false);
+ if (!(part instanceof ITextEditor)) continue;
+ ITextEditor editor = (ITextEditor)part;
+ editors.put(editor.getEditorInput(), editor);
+ }
+ ISourceLocator locator = node.launch.getSourceLocator();
+ ISourcePresentation presentation = TCFModelPresentation.getDefault();
+ for (TCFAnnotation a : set) {
+ Object source_element = TCFSourceLookupDirector.lookup(locator, a.area);
+ if (source_element == null) continue;
+ IEditorInput editor_input = presentation.getEditorInput(source_element);
+ ITextEditor editor = editors.get(editor_input);
+ if (editor == null) continue;
+ IDocumentProvider doc_provider = editor.getDocumentProvider();
+ IAnnotationModel ann_model = doc_provider.getAnnotationModel(editor_input);
+ if (ann_model == null) continue;
+ IRegion region = null;
+ try {
+ doc_provider.connect(editor_input);
+ }
+ catch (CoreException e) {
+ }
+ try {
+ IDocument document = doc_provider.getDocument(editor_input);
+ if (document != null) region = document.getLineInformation(a.area.start_line - 1);
+ }
+ catch (BadLocationException e) {
+ }
+ finally {
+ doc_provider.disconnect(editor_input);
+ }
+ if (region == null) continue;
+ ann_model.addAnnotation(a, new Position(region.getOffset(), region.getLength()));
+ a.model = ann_model;
+ win_info.annotations.add(a);
+ }
+ }
+
+ private void updateAnnotations(final int cnt) {
+ displayExec(new Runnable() {
+ public void run() {
+ synchronized (TCFAnnotationManager.this) {
+ if (cnt != update_unnotations_cnt) return;
+ }
+ for (IWorkbenchWindow window : windows.keySet()) {
+ if (dirty_windows.contains(null) || dirty_windows.contains(window)) {
+ TCFNode node = null;
+ try {
+ ISelection active_context = DebugUITools.getDebugContextManager()
+ .getContextService(window).getActiveContext();
+ if (active_context instanceof IStructuredSelection) {
+ IStructuredSelection selection = (IStructuredSelection)active_context;
+ if (!selection.isEmpty()) {
+ Object first_element = selection.getFirstElement();
+ if (first_element instanceof IAdaptable) {
+ node = (TCFNode)((IAdaptable)first_element).getAdapter(TCFNode.class);
+ }
+ }
+ }
+ if (dirty_launches.contains(null) || node != null && dirty_launches.contains(node.launch)) {
+ updateAnnotations(window, node);
+ }
+ }
+ catch (Throwable x) {
+ if (node == null || !node.isDisposed()) {
+ Activator.log("Cannot update editor annotations", x);
+ }
+ }
+ }
+ }
+ for (TCFLaunch launch : dirty_launches) {
+ if (launch != null) launch.removePendingClient(TCFAnnotationManager.this);
+ }
+ changed_launch_cfgs.clear();
+ dirty_windows.clear();
+ dirty_launches.clear();
+ }
+ });
+ }
+
+ synchronized void updateAnnotations(final IWorkbenchWindow window, final TCFLaunch launch) {
+ final int cnt = ++update_unnotations_cnt;
+ displayExec(new Runnable() {
+ public void run() {
+ dirty_windows.add(window);
+ dirty_launches.add(launch);
+ updateAnnotations(cnt);
+ }
+ });
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildren.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildren.java
new file mode 100644
index 000000000..1953566d3
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildren.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+/**
+ * TCFChildren is a concrete type of TCF data cache that is used to cache a list of children.
+ */
+public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
+
+ private final int pool_margin;
+ private final Map<String,TCFNode> node_pool = new LinkedHashMap<String,TCFNode>(32, 0.75f, true);
+
+ protected final TCFNode node;
+
+ private static final TCFNode[] EMPTY_NODE_ARRAY = new TCFNode[0];
+
+ private TCFNode[] array;
+
+ TCFChildren(TCFNode node) {
+ super(node.channel);
+ this.node = node;
+ pool_margin = 0;
+ node.addDataCache(this);
+ }
+
+ TCFChildren(TCFNode node, int pool_margin) {
+ super(node.channel);
+ this.node = node;
+ this.pool_margin = pool_margin;
+ node.addDataCache(this);
+ }
+
+ /**
+ * Dispose the cache and all nodes in the nodes pool.
+ */
+ @Override
+ public void dispose() {
+ assert !isDisposed();
+ node.removeDataCache(this);
+ for (TCFNode n : node_pool.values()) n.dispose();
+ node_pool.clear();
+ super.dispose();
+ }
+
+ /**
+ * Remove a node from cache.
+ * The method is called every time a node is disposed.
+ * @param id - node ID
+ */
+ void onNodeDisposed(String id) {
+ node_pool.remove(id);
+ if (isValid()) {
+ array = null;
+ Map<String,TCFNode> data = getData();
+ if (data != null) data.remove(id);
+ }
+ }
+
+ private void addToPool(Map<String,TCFNode> data) {
+ assert !isDisposed();
+ for (TCFNode n : data.values()) {
+ assert data.get(n.id) == n;
+ assert n.parent == node;
+ node_pool.put(n.id, n);
+ }
+ if (node_pool.size() > data.size() + pool_margin) {
+ String[] arr = node_pool.keySet().toArray(new String[node_pool.size()]);
+ for (String id : arr) {
+ if (data.get(id) == null) {
+ node_pool.get(id).dispose();
+ if (node_pool.size() <= data.size() + pool_margin) break;
+ }
+ }
+ }
+ }
+
+ /**
+ * End cache pending state.
+ * @param token - pending command handle.
+ * @param error - data retrieval error or null
+ * @param data - up-to-date map of children nodes
+ */
+ @Override
+ public void set(IToken token, Throwable error, Map<String,TCFNode> data) {
+ array = null;
+ if (isDisposed()) {
+ // A command can return data after the cache element has been disposed.
+ // Just ignore the data in such case.
+ super.set(token, null, null);
+ assert node_pool.isEmpty();
+ }
+ else if (data != null) {
+ super.set(token, error, data);
+ addToPool(data);
+ }
+ else {
+ super.set(token, error, new HashMap<String,TCFNode>());
+ }
+ }
+
+ /**
+ * Set given data to the cache, mark cache as valid, cancel any pending data retrieval.
+ * @param data - up-to-date data to store in the cache, null means empty collection of nodes.
+ */
+ @Override
+ public void reset(Map<String,TCFNode> data) {
+ assert !isDisposed();
+ array = null;
+ if (data != null) {
+ super.reset(data);
+ addToPool(data);
+ }
+ else {
+ super.reset(new HashMap<String,TCFNode>());
+ }
+ }
+
+ /**
+ * Invalidate the cache. If retrieval is in progress - let it continue.
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ array = null;
+ }
+
+ /**
+ * Force cache to invalid state, cancel pending data retrieval if any.
+ */
+ @Override
+ public void cancel() {
+ super.cancel();
+ array = null;
+ }
+
+ /**
+ * Add a node to collection of children.
+ * @param n - a node.
+ */
+ void add(TCFNode n) {
+ assert !isDisposed();
+ assert !n.isDisposed();
+ assert node_pool.get(n.id) == null;
+ assert n.parent == node;
+ node_pool.put(n.id, n);
+ if (isValid()) {
+ array = null;
+ Map<String,TCFNode> data = getData();
+ if (data != null) data.put(n.id, n);
+ }
+ }
+
+ /**
+ * Return collection of all nodes, including current children as well as
+ * currently unused nodes from the pool.
+ * To get only current children use getData() method.
+ * @return Collection of nodes.
+ */
+ Collection<TCFNode> getNodes() {
+ return node_pool.values();
+ }
+
+ /**
+ * Return current number of children.
+ * The cache must be valid for the method to work.
+ * @return number of children.
+ */
+ public int size() {
+ assert isValid();
+ Map<String,TCFNode> data = getData();
+ return data == null ? 0 : data.size();
+ }
+
+ /**
+ * Return current children nodes as a sorted array.
+ * @return array of nodes.
+ */
+ public TCFNode[] toArray() {
+ assert isValid();
+ if (array != null) return array;
+ Map<String,TCFNode> data = getData();
+ if (data == null || data.size() == 0) return array = EMPTY_NODE_ARRAY;
+ array = data.values().toArray(new TCFNode[data.size()]);
+ Arrays.sort(array);
+ return array;
+ }
+
+ /**
+ * Return current children nodes in IChildrenUpdate object.
+ * @param update - children update request object.
+ * @param done - a call-back object, it is called when cache state changes.
+ * @return true if all done, false if data request is pending.
+ */
+ boolean getData(IChildrenUpdate update, Runnable done) {
+ if (!validate(done)) return false;
+ TCFNode[] arr = toArray();
+ int offset = 0;
+ int r_offset = update.getOffset();
+ int r_length = update.getLength();
+ for (TCFNode n : arr) {
+ if (offset >= r_offset && offset < r_offset + r_length) {
+ update.setChild(n, offset);
+ }
+ offset++;
+ }
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenExecContext.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenExecContext.java
new file mode 100644
index 000000000..459cd16a2
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenExecContext.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IMemory;
+import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+
+/**
+ * This class is used to maintain a dynamic list of both executable contexts and memory spaces
+ * that are children of a given parent context. The job is slightly complicated by necessity
+ * to merge results from two independent services.
+ */
+public class TCFChildrenExecContext extends TCFChildren {
+
+ private final TCFChildren mem_children;
+ private final TCFChildren run_children;
+
+ TCFChildrenExecContext(final TCFNode node) {
+ super(node);
+ mem_children = new TCFChildren(node) {
+ @Override
+ protected boolean startDataRetrieval() {
+ IMemory mem = node.model.getLaunch().getService(IMemory.class);
+ if (mem == null) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ assert command == null;
+ command = mem.getChildren(node.id, new IMemory.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] contexts) {
+ Map<String,TCFNode> data = null;
+ if (command == token && error == null) {
+ int cnt = 0;
+ data = new HashMap<String,TCFNode>();
+ for (String id : contexts) {
+ TCFNode n = node.model.getNode(id);
+ if (n == null) n = new TCFNodeExecContext(node, id);
+ ((TCFNodeExecContext)n).setMemSeqNo(cnt++);
+ assert n.parent == node;
+ data.put(id, n);
+ }
+ }
+ set(token, error, data);
+ }
+ });
+ return false;
+ }
+ };
+ run_children = new TCFChildren(node) {
+ @Override
+ protected boolean startDataRetrieval() {
+ IRunControl run = node.model.getLaunch().getService(IRunControl.class);
+ if (run == null) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ assert command == null;
+ command = run.getChildren(node.id, new IRunControl.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] contexts) {
+ Map<String,TCFNode> data = null;
+ if (command == token && error == null) {
+ int cnt = 0;
+ data = new HashMap<String,TCFNode>();
+ for (String id : contexts) {
+ TCFNode n = node.model.getNode(id);
+ if (n == null) n = new TCFNodeExecContext(node, id);
+ ((TCFNodeExecContext)n).setExeSeqNo(cnt++);
+ assert n.parent == node;
+ data.put(id, n);
+ }
+ }
+ set(token, error, data);
+ }
+ });
+ return false;
+ }
+ };
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ TCFDataCache<?> pending = null;
+ if (!mem_children.validate()) pending = mem_children;
+ if (!run_children.validate()) pending = run_children;
+ if (pending != null) {
+ pending.wait(this);
+ return false;
+ }
+ Throwable error = mem_children.getError();
+ if (error == null) error = run_children.getError();
+ Map<String,TCFNode> data = new HashMap<String,TCFNode>();
+ Map<String,TCFNode> m1 = mem_children.getData();
+ Map<String,TCFNode> m2 = run_children.getData();
+ if (m1 != null) data.putAll(m1);
+ if (m2 != null) data.putAll(m2);
+ set(null, error, data);
+ return true;
+ }
+
+ void onContextAdded(IRunControl.RunControlContext context) {
+ // To preserve children order need to reset children list.
+ reset();
+ run_children.reset();
+ mem_children.reset();
+ assert !node.isDisposed();
+ String id = context.getID();
+ TCFNodeExecContext n = (TCFNodeExecContext)node.model.getNode(id);
+ if (n == null) {
+ n = new TCFNodeExecContext(node, id);
+ n.postContextAddedDelta();
+ add(n);
+ }
+ else {
+ n.postAllChangedDelta();
+ }
+ run_children.add(n);
+ n.setRunContext(context);
+ }
+
+ void onContextAdded(IMemory.MemoryContext context) {
+ // To preserve children order need to reset children list.
+ reset();
+ run_children.reset();
+ mem_children.reset();
+ assert !node.isDisposed();
+ String id = context.getID();
+ TCFNodeExecContext n = (TCFNodeExecContext)node.model.getNode(id);
+ if (n == null) {
+ n = new TCFNodeExecContext(node, id);
+ n.postContextAddedDelta();
+ add(n);
+ }
+ else {
+ n.postAllChangedDelta();
+ }
+ mem_children.add(n);
+ n.setMemoryContext(context);
+ }
+
+ void onAncestorContextChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExecContext)n).onAncestorContextChanged();
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenExpressions.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenExpressions.java
new file mode 100644
index 000000000..d3b9339d9
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenExpressions.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+
+import org.eclipse.debug.core.model.IExpression;
+import org.eclipse.debug.core.model.IWatchExpression;
+
+public class TCFChildrenExpressions extends TCFChildren {
+
+ TCFChildrenExpressions(TCFNode node) {
+ super(node, 128);
+ }
+
+ void onSuspended() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onSuspended();
+ }
+
+ void onRegisterValueChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onRegisterValueChanged();
+ }
+
+ void onMemoryChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onMemoryChanged();
+ }
+
+ void onMemoryMapChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onMemoryMapChanged();
+ }
+
+ private TCFNodeExpression findScript(String text) {
+ for (TCFNode n : getNodes()) {
+ TCFNodeExpression e = (TCFNodeExpression)n;
+ if (text.equals(e.getScript())) return e;
+ }
+ return null;
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ int cnt = 0;
+ HashMap<String,TCFNode> data = new HashMap<String,TCFNode>();
+ for (final IExpression e : node.model.getExpressionManager().getExpressions()) {
+ String text = e.getExpressionText();
+ TCFNodeExpression n = findScript(text);
+ if (n == null) add(n = new TCFNodeExpression(node, text, null, null, null, -1, false));
+ n.setSortPosition(cnt++);
+ if (e instanceof IWatchExpression) n.setEnabled(((IWatchExpression)e).isEnabled());
+ data.put(n.id, n);
+ }
+ set(null, null, data);
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenHoverExpressions.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenHoverExpressions.java
new file mode 100644
index 000000000..705044bd2
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenHoverExpressions.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+
+/**
+ * Provides the cache of root nodes for the expression hover.
+ */
+class TCFChildrenHoverExpressions extends TCFChildren {
+
+ TCFChildrenHoverExpressions(TCFNode parent) {
+ super(parent, 16);
+ }
+
+ void onSuspended() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onSuspended();
+ }
+
+ void onRegisterValueChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onRegisterValueChanged();
+ }
+
+ void onMemoryChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onMemoryChanged();
+ }
+
+ void onMemoryMapChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onMemoryMapChanged();
+ }
+
+ private TCFNodeExpression findScript(String text) {
+ for (TCFNode n : getNodes()) {
+ TCFNodeExpression e = (TCFNodeExpression)n;
+ if (text.equals(e.getScript())) return e;
+ }
+ return null;
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ HashMap<String,TCFNode> data = new HashMap<String,TCFNode>();
+ String expression_script = null;
+ if (node instanceof TCFNodeExecContext) {
+ expression_script = ((TCFNodeExecContext)node).getHoverExpression();
+ }
+ else if (node instanceof TCFNodeStackFrame) {
+ expression_script = ((TCFNodeStackFrame)node).getHoverExpression();
+ }
+ if (expression_script != null) {
+ TCFNodeExpression expression_node = findScript(expression_script);
+ if (expression_node == null) {
+ add(expression_node = new TCFNodeExpression(node, expression_script, null, null, null, -1, false));
+ }
+ data.put(expression_node.id, expression_node);
+ }
+ set(null, null, data);
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenLocalVariables.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenLocalVariables.java
new file mode 100644
index 000000000..2320cd4b3
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenLocalVariables.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IExpressions;
+
+public class TCFChildrenLocalVariables extends TCFChildren {
+
+ private final TCFNodeStackFrame node;
+
+ TCFChildrenLocalVariables(TCFNodeStackFrame node) {
+ super(node, 128);
+ this.node = node;
+ }
+
+ void onSuspended() {
+ reset();
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onSuspended();
+ }
+
+ void onRegisterValueChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onRegisterValueChanged();
+ }
+
+ void onMemoryChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onMemoryChanged();
+ }
+
+ void onMemoryMapChanged() {
+ reset();
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onMemoryMapChanged();
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ IExpressions exps = node.model.getLaunch().getService(IExpressions.class);
+ if (exps == null || node.isEmulated()) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ TCFChildrenStackTrace stack_trace_cache = ((TCFNodeExecContext)node.parent).getStackTrace();
+ if (!stack_trace_cache.validate(this)) return false; // node.getFrameNo() is not valid
+ if (node.getFrameNo() < 0) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ assert command == null;
+ command = exps.getChildren(node.id, new IExpressions.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] contexts) {
+ Map<String,TCFNode> data = null;
+ if (command == token && error == null) {
+ int cnt = 0;
+ data = new HashMap<String,TCFNode>();
+ for (String id : contexts) {
+ TCFNodeExpression n = (TCFNodeExpression)node.model.getNode(id);
+ if (n == null) n = new TCFNodeExpression(node, null, null, id, null, -1, false);
+ assert n.id.equals(id);
+ assert n.parent == node;
+ n.setSortPosition(cnt++);
+ data.put(n.id, n);
+ }
+ }
+ set(token, error, data);
+ }
+ });
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenLogExpressions.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenLogExpressions.java
new file mode 100644
index 000000000..90286a53e
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenLogExpressions.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class TCFChildrenLogExpressions extends TCFChildren {
+
+ private final HashSet<String> scripts = new HashSet<String>();
+
+ TCFChildrenLogExpressions(TCFNodeExecContext node) {
+ super(node, 16);
+ }
+
+ void onSuspended() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onSuspended();
+ scripts.clear();
+ reset();
+ }
+
+ void onRegisterValueChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onRegisterValueChanged();
+ }
+
+ void onMemoryChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onMemoryChanged();
+ }
+
+ void onMemoryMapChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeExpression)n).onMemoryMapChanged();
+ }
+
+ public TCFNodeExpression findScript(String script) {
+ for (TCFNode n : getNodes()) {
+ TCFNodeExpression e = (TCFNodeExpression)n;
+ if (script.equals(e.getScript())) return e;
+ }
+ return null;
+ }
+
+ public void addScript(String script) {
+ if (scripts.add(script)) reset();
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ HashMap<String,TCFNode> data = new HashMap<String,TCFNode>();
+ for (String script : scripts) {
+ TCFNodeExpression expression_node = findScript(script);
+ if (expression_node == null) {
+ add(expression_node = new TCFNodeExpression(node, script, null, null, null, -1, false));
+ }
+ data.put(expression_node.id, expression_node);
+ }
+ set(null, null, data);
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenModules.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenModules.java
new file mode 100644
index 000000000..c5fd30e26
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenModules.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IMemoryMap;
+
+/**
+ * Provides and caches memory regions (modules) for a context.
+ */
+public class TCFChildrenModules extends TCFChildren {
+
+ public TCFChildrenModules(TCFNode node) {
+ super(node, 128);
+ }
+
+ void onMemoryMapChanged() {
+ reset();
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ assert command == null;
+ IMemoryMap mmap = node.model.getLaunch().getService(IMemoryMap.class);
+ if (mmap == null) {
+ set(null, null, null);
+ return true;
+ }
+ command = mmap.get(node.id, new IMemoryMap.DoneGet() {
+ public void doneGet(IToken token, Exception error, IMemoryMap.MemoryRegion[] map) {
+ Map<String, TCFNode> data = new HashMap<String, TCFNode>();
+ if (map != null) {
+ for (IMemoryMap.MemoryRegion region : map) {
+ String id = node.id + ".Module-" + region.getFileName() + '@' + region.getAddress();
+ TCFNodeModule module = (TCFNodeModule) node.model.getNode(id);
+ if (module == null) {
+ module = new TCFNodeModule(node, id, region);
+ }
+ data.put(id, module);
+ }
+ }
+ set(token, error, data);
+ }
+ });
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenRegisters.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenRegisters.java
new file mode 100644
index 000000000..86dc0a30c
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenRegisters.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IRegisters;
+
+
+public class TCFChildrenRegisters extends TCFChildren {
+
+ TCFChildrenRegisters(TCFNode node) {
+ super(node, 128);
+ }
+
+ void onSuspended() {
+ for (TCFNode n : getNodes()) ((TCFNodeRegister)n).onSuspended();
+ }
+
+ void onParentValueChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeRegister)n).onParentValueChanged();
+ }
+
+ void onRegistersChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeRegister)n).onRegistersChanged();
+ reset();
+ }
+
+ @Override
+ void onNodeDisposed(String id) {
+ super.onNodeDisposed(id);
+ if (node instanceof TCFNodeExecContext) {
+ // CPU register nodes are special case:
+ // they have executable node as parent,
+ // but they are also referenced as children of stack frames
+ for (TCFNode n : ((TCFNodeExecContext)node).getStackTrace().getNodes()) {
+ ((TCFNodeStackFrame)n).getRegisters().onNodeDisposed(id);
+ }
+ }
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ IRegisters regs = node.model.getLaunch().getService(IRegisters.class);
+ if (regs == null) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ if (node instanceof TCFNodeStackFrame) {
+ TCFChildrenStackTrace stack_trace_cache = ((TCFNodeExecContext)node.parent).getStackTrace();
+ if (!stack_trace_cache.validate(this)) return false; // node.getFrameNo() is not valid
+ final int frame_no = ((TCFNodeStackFrame)node).getFrameNo();
+ if (frame_no < 0) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ }
+ assert command == null;
+ command = regs.getChildren(node.id, new IRegisters.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] contexts) {
+ Map<String,TCFNode> data = null;
+ if (command == token && error == null) {
+ int index = 0;
+ data = new HashMap<String,TCFNode>();
+ for (String id : contexts) {
+ TCFNodeRegister n = (TCFNodeRegister)node.model.getNode(id);
+ if (n == null) n = new TCFNodeRegister(node, id);
+ n.setIndex(index++);
+ data.put(id, n);
+ }
+ }
+ set(token, error, data);
+ }
+ });
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenStackTrace.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenStackTrace.java
new file mode 100644
index 000000000..5ebfe41ab
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenStackTrace.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.services.IStackTrace;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+
+public class TCFChildrenStackTrace extends TCFChildren {
+
+ private final TCFNodeExecContext node;
+
+ private String top_frame_id;
+ private int limit_factor = 1;
+
+ TCFChildrenStackTrace(TCFNodeExecContext node) {
+ super(node, 16);
+ this.node = node;
+ }
+
+ void onSourceMappingChange() {
+ for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onSourceMappingChange();
+ }
+
+ void onExpressionAddedOrRemoved() {
+ for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onExpressionAddedOrRemoved();
+ }
+
+ void onSuspended() {
+ limit_factor = 1;
+ for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onSuspended();
+ reset();
+ }
+
+ void onRegistersChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onRegistersChanged();
+ reset();
+ }
+
+ void onMemoryMapChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onMemoryMapChanged();
+ reset();
+ }
+
+ void onMemoryChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onMemoryChanged();
+ reset();
+ }
+
+ void onRegisterValueChanged() {
+ for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).onRegisterValueChanged();
+ reset();
+ }
+
+ void onResumed() {
+ reset(null);
+ }
+
+ void onPreferencesChanged() {
+ reset();
+ }
+
+ void riseTraceLimit() {
+ limit_factor++;
+ reset();
+ }
+
+ void postAllChangedDelta() {
+ for (TCFNode n : getNodes()) ((TCFNodeStackFrame)n).postAllChangedDelta();
+ }
+
+ public TCFNodeStackFrame getTopFrame() {
+ assert isValid();
+ return (TCFNodeStackFrame)node.model.getNode(top_frame_id);
+ }
+
+ @Override
+ public void set(IToken token, Throwable error, Map<String,TCFNode> data) {
+ for (TCFNode n : getNodes()) {
+ if (data == null || data.get(n.id) == null) ((TCFNodeStackFrame)n).setFrameNo(-1);
+ }
+ super.set(token, error, data);
+ }
+
+ private void addEmulatedTopFrame(HashMap<String,TCFNode> data) {
+ top_frame_id = node.id + "-TF";
+ TCFNodeStackFrame n = (TCFNodeStackFrame)node.model.getNode(top_frame_id);
+ if (n == null) n = new TCFNodeStackFrame(node, top_frame_id, true);
+ n.setFrameNo(0);
+ n.setTraceLimit(false);
+ data.put(n.id, n);
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ TCFDataCache<TCFContextState> state = node.getState();
+ if (!state.validate(this)) return false;
+ if (node.isNotActive()) {
+ top_frame_id = null;
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ Throwable state_error = state.getError();
+ TCFContextState state_data = state.getData();
+ if (state_error != null || state_data == null || !state_data.is_suspended) {
+ set(null, state_error, null);
+ return true;
+ }
+ final HashMap<String,TCFNode> data = new HashMap<String,TCFNode>();
+ IStackTrace st = node.model.getLaunch().getService(IStackTrace.class);
+ if (st == null) {
+ addEmulatedTopFrame(data);
+ set(null, null, data);
+ return true;
+ }
+ assert command == null;
+ command = st.getChildren(node.id, new IStackTrace.DoneGetChildren() {
+ public void doneGetChildren(IToken token, Exception error, String[] contexts) {
+ if (command == token) {
+ if (error == null && contexts != null) {
+ int limit_value = 0;
+ boolean limit_enabled = node.model.getStackFramesLimitEnabled();
+ if (limit_enabled) {
+ limit_value = node.model.getStackFramesLimitValue() * limit_factor;
+ if (limit_value <= 0) limit_value = limit_factor;
+ }
+ int cnt = contexts.length;
+ for (String id : contexts) {
+ cnt--;
+ if (!limit_enabled || cnt <= limit_value) {
+ TCFNodeStackFrame n = (TCFNodeStackFrame)node.model.getNode(id);
+ if (n == null) n = new TCFNodeStackFrame(node, id, false);
+ assert n.parent == node;
+ n.setFrameNo(cnt);
+ n.setTraceLimit(limit_enabled && cnt == limit_value);
+ data.put(id, n);
+ if (cnt == 0) top_frame_id = id;
+ }
+ }
+ }
+ if (data.size() == 0) addEmulatedTopFrame(data);
+ }
+ set(token, error, data);
+ }
+ });
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenSubExpressions.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenSubExpressions.java
new file mode 100644
index 000000000..993e5101c
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFChildrenSubExpressions.java
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.tm.tcf.services.IExpressions;
+import org.eclipse.tm.tcf.services.ISymbols;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+public class TCFChildrenSubExpressions extends TCFChildren {
+
+ private final int par_level;
+ private final int par_offs;
+ private final int par_size;
+
+ TCFChildrenSubExpressions(TCFNode node, int par_level, int par_offs, int par_size) {
+ super(node, 128);
+ this.par_level = par_level;
+ this.par_offs = par_offs;
+ this.par_size = par_size;
+ }
+
+ void onSuspended() {
+ reset();
+ for (TCFNode n : getNodes()) {
+ if (n instanceof TCFNodeExpression) ((TCFNodeExpression)n).onSuspended();
+ if (n instanceof TCFNodeArrayPartition) ((TCFNodeArrayPartition)n).onSuspended();
+ }
+ }
+
+ void onValueChanged() {
+ reset();
+ for (TCFNode n : getNodes()) {
+ if (n instanceof TCFNodeExpression) ((TCFNodeExpression)n).onValueChanged();
+ if (n instanceof TCFNodeArrayPartition) ((TCFNodeArrayPartition)n).onValueChanged();
+ }
+ }
+
+ void onRegisterValueChanged() {
+ reset();
+ for (TCFNode n : getNodes()) {
+ if (n instanceof TCFNodeExpression) ((TCFNodeExpression)n).onRegisterValueChanged();
+ if (n instanceof TCFNodeArrayPartition) ((TCFNodeArrayPartition)n).onRegisterValueChanged();
+ }
+ }
+
+ void onMemoryChanged() {
+ reset();
+ for (TCFNode n : getNodes()) {
+ if (n instanceof TCFNodeExpression) ((TCFNodeExpression)n).onMemoryChanged();
+ if (n instanceof TCFNodeArrayPartition) ((TCFNodeArrayPartition)n).onMemoryChanged();
+ }
+ }
+
+ void onMemoryMapChanged() {
+ reset();
+ for (TCFNode n : getNodes()) {
+ if (n instanceof TCFNodeExpression) ((TCFNodeExpression)n).onMemoryMapChanged();
+ if (n instanceof TCFNodeArrayPartition) ((TCFNodeArrayPartition)n).onMemoryMapChanged();
+ }
+ }
+
+ void onCastToTypeChanged() {
+ cancel();
+ TCFNode a[] = getNodes().toArray(new TCFNode[getNodes().size()]);
+ for (int i = 0; i < a.length; i++) a[i].dispose();
+ }
+
+ private TCFNodeExpression findField(String field_id, boolean deref) {
+ assert field_id != null;
+ for (TCFNode n : getNodes()) {
+ TCFNodeExpression e = (TCFNodeExpression)n;
+ if (field_id.equals(e.getFieldID()) && e.isDeref() == deref) return e;
+ }
+ return null;
+ }
+
+ private boolean findFields(ISymbols.Symbol type, Map<String,TCFNode> map, boolean deref) {
+ TCFDataCache<String[]> children_cache = node.model.getSymbolChildrenCache(type.getID());
+ if (children_cache == null) return true;
+ if (!children_cache.validate(this)) return false;
+ String[] children = children_cache.getData();
+ if (children == null) return true;
+ TCFDataCache<?> pending = null;
+ for (String id : children) {
+ TCFDataCache<ISymbols.Symbol> sym_cache = node.model.getSymbolInfoCache(id);
+ if (!sym_cache.validate()) {
+ pending = sym_cache;
+ }
+ else {
+ ISymbols.Symbol sym_data = sym_cache.getData();
+ if (sym_data == null) continue;
+ if (sym_data.getSymbolClass() != ISymbols.SymbolClass.reference) continue;
+ if (sym_data.getName() == null) {
+ if (!findFields(sym_data, map, deref)) return false;
+ }
+ else {
+ TCFNodeExpression n = findField(id, deref);
+ if (n == null) add(n = new TCFNodeExpression(node, null, id, null, null, -1, deref));
+ n.setSortPosition(map.size());
+ map.put(n.id, n);
+ }
+ }
+ }
+ if (pending == null) return true;
+ pending.wait(this);
+ return false;
+ }
+
+ private TCFNodeExpression findReg(String reg_id) {
+ assert reg_id != null;
+ for (TCFNode n : getNodes()) {
+ TCFNodeExpression e = (TCFNodeExpression)n;
+ if (reg_id.equals(e.getRegisterID())) return e;
+ }
+ return null;
+ }
+
+ private boolean findRegs(TCFNodeRegister reg_node, Map<String,TCFNode> map) {
+ TCFChildren reg_children = reg_node.getChildren();
+ if (!reg_children.validate(this)) return false;
+ for (TCFNode subnode : reg_children.toArray()) {
+ TCFNodeExpression n = findReg(subnode.id);
+ if (n == null) add(n = new TCFNodeExpression(node, null, null, null, subnode.id, -1, false));
+ n.setSortPosition(map.size());
+ map.put(n.id, n);
+ }
+ return true;
+ }
+
+ private TCFNodeExpression findIndex(int index, boolean deref) {
+ assert index >= 0;
+ for (TCFNode n : getNodes()) {
+ TCFNodeExpression e = (TCFNodeExpression)n;
+ if (e.getIndex() == index && e.isDeref() == deref) return e;
+ }
+ return null;
+ }
+
+ private TCFNodeArrayPartition findPartition(int offs, int size) {
+ assert offs >= 0;
+ for (TCFNode n : getNodes()) {
+ TCFNodeArrayPartition e = (TCFNodeArrayPartition)n;
+ if (e.getOffset() == offs && e.getSize() == size) return e;
+ }
+ return null;
+ }
+
+ @Override
+ protected boolean startDataRetrieval() {
+ assert !isDisposed();
+ TCFNode exp = node;
+ while (!(exp instanceof TCFNodeExpression)) exp = exp.parent;
+ TCFDataCache<ISymbols.Symbol> type_cache = ((TCFNodeExpression)exp).getType();
+ if (!type_cache.validate(this)) return false;
+ ISymbols.Symbol type_data = type_cache.getData();
+ if (type_data == null) {
+ HashMap<String,TCFNode> data = new HashMap<String,TCFNode>();
+ TCFDataCache<IExpressions.Value> val_cache = ((TCFNodeExpression)exp).getValue();
+ if (!val_cache.validate(this)) return false;
+ IExpressions.Value val_data = val_cache.getData();
+ if (val_data != null) {
+ String reg_id = val_data.getRegisterID();
+ if (reg_id != null) {
+ if (!node.model.createNode(reg_id, this)) return false;
+ if (isValid()) return true;
+ TCFNodeRegister reg_node = (TCFNodeRegister)node.model.getNode(reg_id);
+ if (!findRegs(reg_node, data)) return false;
+ }
+ }
+ set(null, null, data);
+ return true;
+ }
+ ISymbols.TypeClass type_class = type_data.getTypeClass();
+ Map<String,TCFNode> data = new HashMap<String,TCFNode>();
+ if (par_level > 0 && type_class != ISymbols.TypeClass.array) {
+ // Nothing
+ }
+ else if (type_class == ISymbols.TypeClass.composite) {
+ if (!findFields(type_data, data, false)) return false;
+ }
+ else if (type_class == ISymbols.TypeClass.array) {
+ int offs = par_level > 0 ? par_offs : 0;
+ int size = par_level > 0 ? par_size : type_data.getLength();
+ if (size <= 100) {
+ for (int i = offs; i < offs + size; i++) {
+ TCFNodeExpression n = findIndex(i, false);
+ if (n == null) n = new TCFNodeExpression(node, null, null, null, null, i, false);
+ n.setSortPosition(i);
+ data.put(n.id, n);
+ }
+ }
+ else {
+ int next_size = 100;
+ while (size / next_size > 100) next_size *= 100;
+ for (int i = offs; i < offs + size; i += next_size) {
+ int sz = next_size;
+ if (i + sz > offs + size) sz = offs + size - i;
+ TCFNodeArrayPartition n = findPartition(i, sz);
+ if (n == null) n = new TCFNodeArrayPartition(node, par_level + 1, i, sz);
+ data.put(n.id, n);
+ }
+ }
+ }
+ else if (type_class == ISymbols.TypeClass.pointer) {
+ TCFDataCache<IExpressions.Value> val_cache = ((TCFNodeExpression)exp).getValue();
+ if (!val_cache.validate(this)) return false;
+ IExpressions.Value val_data = val_cache.getData();
+ if (val_data != null && !isNull(val_data.getValue())) {
+ TCFDataCache<ISymbols.Symbol> base_type_cache = node.model.getSymbolInfoCache(type_data.getBaseTypeID());
+ if (base_type_cache != null) {
+ if (!base_type_cache.validate(this)) return false;
+ ISymbols.Symbol base_type_data = base_type_cache.getData();
+ if (base_type_data != null && base_type_data.getTypeClass() != ISymbols.TypeClass.function && base_type_data.getSize() > 0) {
+ if (base_type_data.getTypeClass() == ISymbols.TypeClass.composite) {
+ if (!findFields(base_type_data, data, true)) return false;
+ }
+ else {
+ TCFNodeExpression n = findIndex(0, true);
+ if (n == null) n = new TCFNodeExpression(node, null, null, null, null, 0, true);
+ n.setSortPosition(0);
+ data.put(n.id, n);
+ }
+ }
+ }
+ }
+ }
+ set(null, null, data);
+ return true;
+ }
+
+ private boolean isNull(byte[] data) {
+ if (data == null) return true;
+ for (byte b : data) {
+ if (b != 0) return false;
+ }
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationExpression.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationExpression.java
new file mode 100644
index 000000000..47264d233
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationExpression.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+public class TCFColumnPresentationExpression implements IColumnPresentation {
+
+ public static final String PRESENTATION_ID = "Expressions";
+
+ /**
+ * Presentation column IDs.
+ */
+ public static final String
+ COL_NAME = "Name",
+ COL_TYPE = "Type",
+ COL_HEX_VALUE = "HexValue",
+ COL_DEC_VALUE = "DecValue";
+
+ private static String[] cols_all = {
+ COL_NAME,
+ COL_TYPE,
+ COL_DEC_VALUE,
+ COL_HEX_VALUE,
+ };
+
+ private static String[] headers = {
+ "Name",
+ "Type",
+ "Decimal",
+ "Hex",
+ };
+
+ private static String[] cols_ini = {
+ COL_NAME,
+ COL_DEC_VALUE,
+ COL_HEX_VALUE,
+ };
+
+ public void dispose() {
+ }
+
+ public String[] getAvailableColumns() {
+ return cols_all;
+ }
+
+ public String getHeader(String id) {
+ for (int i = 0; i < cols_all.length; i++) {
+ if (id.equals(cols_all[i])) return headers[i];
+ }
+ return null;
+ }
+
+ public String getId() {
+ return PRESENTATION_ID;
+ }
+
+ public ImageDescriptor getImageDescriptor(String id) {
+ return null;
+ }
+
+ public String[] getInitialColumns() {
+ return cols_ini;
+ }
+
+ public void init(IPresentationContext context) {
+ }
+
+ public boolean isOptional() {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationModules.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationModules.java
new file mode 100644
index 000000000..43fd626ce
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationModules.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * Column presentation for the Modules view.
+ */
+public class TCFColumnPresentationModules implements IColumnPresentation {
+
+ public static final String PRESENTATION_ID = "Modules";
+
+ /**
+ * Presentation column IDs.
+ */
+ public static final String
+ COL_NAME = "Name",
+ COL_ADDRESS = "Address",
+ COL_SIZE = "Size",
+ COL_FLAGS = "Flags",
+ COL_OFFSET = "Offset",
+ COL_SECTION = "Section";
+
+ private static String[] cols_all = {
+ COL_NAME,
+ COL_ADDRESS,
+ COL_SIZE,
+ COL_FLAGS,
+ COL_OFFSET,
+ COL_SECTION
+ };
+
+ private static String[] headers = {
+ "File Name",
+ "Address",
+ "Size",
+ "Flags",
+ "Offset",
+ "Section"
+ };
+
+ private static String[] cols_ini = {
+ COL_NAME,
+ COL_ADDRESS,
+ COL_SIZE
+ };
+
+ public void dispose() {
+ }
+
+ public String[] getAvailableColumns() {
+ return cols_all;
+ }
+
+ public String getHeader(String id) {
+ for (int i = 0; i < cols_all.length; i++) {
+ if (id.equals(cols_all[i])) return headers[i];
+ }
+ return null;
+ }
+
+ public String getId() {
+ return PRESENTATION_ID;
+ }
+
+ public ImageDescriptor getImageDescriptor(String id) {
+ return null;
+ }
+
+ public String[] getInitialColumns() {
+ return cols_ini;
+ }
+
+ public void init(IPresentationContext context) {
+ }
+
+ public boolean isOptional() {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationRegister.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationRegister.java
new file mode 100644
index 000000000..929987145
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFColumnPresentationRegister.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentation;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+public class TCFColumnPresentationRegister implements IColumnPresentation {
+
+ public static final String PRESENTATION_ID = "Registers";
+
+ /**
+ * Presentation column IDs.
+ */
+ public static final String
+ COL_NAME = "Name",
+ COL_HEX_VALUE = "HexValue",
+ COL_DEC_VALUE = "DecValue",
+ COL_DESCRIPTION = "Description",
+ COL_READBLE = "Readable",
+ COL_READ_ONCE = "ReadOnce",
+ COL_WRITEABLE = "Writeable",
+ COL_WRITE_ONCE = "WriteOnce",
+ COL_SIDE_EFFECTS = "SideEffects",
+ COL_VOLATILE = "Volatile",
+ COL_FLOAT = "Float",
+ COL_MNEMONIC = "Menimonic";
+
+ private static String[] cols_all = {
+ COL_NAME,
+ COL_HEX_VALUE,
+ COL_DEC_VALUE,
+ COL_DESCRIPTION,
+ COL_READBLE,
+ COL_READ_ONCE,
+ COL_WRITEABLE,
+ COL_WRITE_ONCE,
+ COL_SIDE_EFFECTS,
+ COL_VOLATILE,
+ COL_FLOAT,
+ COL_MNEMONIC
+ };
+
+ private static String[] headers = {
+ "Name",
+ "Hex",
+ "Decimal",
+ "Description",
+ "Readable",
+ "Read Once",
+ "Writable",
+ "Write Once",
+ "Side Effects",
+ "Volatile",
+ "Float",
+ "Mnemonic"
+ };
+
+ private static String[] cols_ini = {
+ COL_NAME,
+ COL_HEX_VALUE,
+ COL_DEC_VALUE,
+ COL_DESCRIPTION,
+ COL_MNEMONIC
+ };
+
+ public void dispose() {
+ }
+
+ public String[] getAvailableColumns() {
+ return cols_all;
+ }
+
+ public String getHeader(String id) {
+ for (int i = 0; i < cols_all.length; i++) {
+ if (id.equals(cols_all[i])) return headers[i];
+ }
+ return null;
+ }
+
+ public String getId() {
+ return PRESENTATION_ID;
+ }
+
+ public ImageDescriptor getImageDescriptor(String id) {
+ return null;
+ }
+
+ public String[] getInitialColumns() {
+ return cols_ini;
+ }
+
+ public void init(IPresentationContext context) {
+ }
+
+ public boolean isOptional() {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFConsole.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFConsole.java
new file mode 100644
index 000000000..225f737f7
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFConsole.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.IConsoleView;
+import org.eclipse.ui.console.IOConsole;
+import org.eclipse.ui.console.IOConsoleInputStream;
+import org.eclipse.ui.console.IOConsoleOutputStream;
+
+class TCFConsole {
+ private final TCFModel model;
+ private final IOConsole console;
+ private final Display display;
+
+ private final LinkedList<Message> out_queue;
+
+ private static class Message {
+ int stream_id;
+ byte[] data;
+ }
+
+ private final Thread inp_thread = new Thread() {
+ public void run() {
+ try {
+ IOConsoleInputStream inp = console.getInputStream();
+ final byte[] buf = new byte[0x100];
+ for (;;) {
+ int len = inp.read(buf);
+ if (len < 0) break;
+ // TODO: Eclipse Console view has a bad habit of replacing CR with CR/LF
+ if (len == 2 && buf[0] == '\r' && buf[1] == '\n') len = 1;
+ final int n = len;
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ try {
+ model.getLaunch().writeProcessInputStream(buf, 0, n);
+ }
+ catch (Exception x) {
+ model.onProcessStreamError(null, 0, x, 0);
+ }
+ }
+ });
+ }
+ }
+ catch (Throwable x) {
+ Activator.log("Cannot read console input", x);
+ }
+ }
+ };
+
+ private final Thread out_thread = new Thread() {
+ public void run() {
+ Map<Integer,IOConsoleOutputStream> out_streams =
+ new HashMap<Integer,IOConsoleOutputStream>();
+ try {
+ for (;;) {
+ Message m = null;
+ synchronized (out_queue) {
+ while (out_queue.size() == 0) out_queue.wait();
+ m = out_queue.removeFirst();
+ }
+ if (m.data == null) break;
+ IOConsoleOutputStream stream = out_streams.get(m.stream_id);
+ if (stream == null) {
+ final int id = m.stream_id;
+ final IOConsoleOutputStream s = stream = console.newOutputStream();
+ display.syncExec(new Runnable() {
+ public void run() {
+ try {
+ int color_id = SWT.COLOR_BLACK;
+ switch (id) {
+ case 1: color_id = SWT.COLOR_RED; break;
+ case 2: color_id = SWT.COLOR_BLUE; break;
+ case 3: color_id = SWT.COLOR_GREEN; break;
+ }
+ s.setColor(display.getSystemColor(color_id));
+ }
+ catch (Throwable x) {
+ Activator.log("Cannot open console view", x);
+ }
+ }
+ });
+ out_streams.put(m.stream_id, stream);
+ }
+ stream.write(m.data, 0, m.data.length);
+ }
+ }
+ catch (Throwable x) {
+ Activator.log("Cannot write console output", x);
+ }
+ for (IOConsoleOutputStream stream : out_streams.values()) {
+ try {
+ stream.close();
+ }
+ catch (IOException x) {
+ Activator.log("Cannot close console stream", x);
+ }
+ }
+ try {
+ console.getInputStream().close();
+ }
+ catch (IOException x) {
+ Activator.log("Cannot close console stream", x);
+ }
+ try {
+ display.syncExec(new Runnable() {
+ public void run() {
+ IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
+ manager.removeConsoles(new IOConsole[]{ console });
+ }
+ });
+ }
+ catch (SWTException x) {
+ if (x.code == SWT.ERROR_DEVICE_DISPOSED) return;
+ Activator.log("Cannot remove console", x);
+ }
+ }
+ };
+
+ TCFConsole(final TCFModel model, String process_id) {
+ this.model = model;
+ display = model.getDisplay();
+ out_queue = new LinkedList<Message>();
+ console = new IOConsole("TCF " + process_id, null,
+ ImageCache.getImageDescriptor(ImageCache.IMG_TCF), "UTF-8", true);
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (!PlatformUI.isWorkbenchRunning() || PlatformUI.getWorkbench().isStarting()) {
+ display.timerExec(200, this);
+ }
+ else if (!PlatformUI.getWorkbench().isClosing()) {
+ try {
+ IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
+ manager.addConsoles(new IConsole[]{ console });
+ IWorkbenchWindow w = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (w == null) return;
+ IWorkbenchPage page = w.getActivePage();
+ if (page == null) return;
+ IConsoleView view = (IConsoleView)page.showView(IConsoleConstants.ID_CONSOLE_VIEW);
+ view.display(console);
+ }
+ catch (Throwable x) {
+ Activator.log("Cannot open console view", x);
+ }
+ }
+ }
+ });
+ inp_thread.setName("TCF Launch Console Input");
+ out_thread.setName("TCF Launch Console Output");
+ inp_thread.start();
+ out_thread.start();
+ }
+
+ void write(final int stream_id, byte[] data) {
+ if (data == null || data.length == 0) return;
+ synchronized (out_queue) {
+ Message m = new Message();
+ m.stream_id = stream_id;
+ m.data = data;
+ out_queue.add(m);
+ out_queue.notify();
+ }
+ }
+
+ void close() {
+ synchronized (out_queue) {
+ out_queue.add(new Message());
+ out_queue.notify();
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDebugTask.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDebugTask.java
new file mode 100644
index 000000000..4a4bf37e6
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDebugTask.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.util.TCFTask;
+
+/**
+ * An extension of TCFTask class that adds support for throwing DebugException.
+ */
+public abstract class TCFDebugTask<V> extends TCFTask<V> {
+
+ public TCFDebugTask() {
+ }
+
+ public TCFDebugTask(IChannel channel) {
+ super(channel);
+ }
+
+ public synchronized V getD() throws DebugException {
+ assert !Protocol.isDispatchThread();
+ while (!isDone()) {
+ try {
+ wait();
+ }
+ catch (InterruptedException x) {
+ throw new DebugException(new Status(
+ IStatus.ERROR, Activator.PLUGIN_ID, DebugException.REQUEST_FAILED,
+ "Debugger requiest interrupted", x));
+ }
+ }
+ assert isDone();
+ Throwable x = getError();
+ if (x instanceof DebugException) throw (DebugException)x;
+ if (x != null) throw new DebugException(new Status(
+ IStatus.ERROR, Activator.PLUGIN_ID, DebugException.REQUEST_FAILED,
+ "Debugger requiest failed", x));
+ return getResult();
+ }
+
+ public void error(String msg) {
+ error(new DebugException(new Status(
+ IStatus.ERROR, Activator.PLUGIN_ID, DebugException.REQUEST_FAILED,
+ msg, null)));
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDetailPane.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDetailPane.java
new file mode 100644
index 000000000..114ac6907
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDetailPane.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.debug.ui.IDetailPane;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.ITextPresentationListener;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.ui.IWorkbenchPartSite;
+
+/**
+ * This detail pane uses a source viewer to display detailed information about the current
+ * selection.
+ */
+public class TCFDetailPane implements IDetailPane {
+
+ public static final String ID = "org.eclipse.tm.tcf.debug.DetailPaneFactory";
+ public static final String NAME = "TCF Detail Pane";
+ public static final String DESC = "TCF Detail Pane";
+
+ private SourceViewer source_viewer;
+ private Display display;
+ private int generation;
+ @SuppressWarnings("unused")
+ private IWorkbenchPartSite part_site;
+ private final Document document = new Document();
+ private final ArrayList<StyleRange> style_ranges = new ArrayList<StyleRange>();
+ private final HashMap<RGB,Color> colors = new HashMap<RGB,Color>();
+
+ private final ITextPresentationListener presentation_listener = new ITextPresentationListener() {
+ public void applyTextPresentation(TextPresentation presentation) {
+ for (StyleRange r : style_ranges) presentation.addStyleRange(r);
+ }
+ };
+
+ public Control createControl(Composite parent) {
+ assert source_viewer == null;
+ source_viewer = new SourceViewer(parent, null, SWT.V_SCROLL | SWT.H_SCROLL);
+ source_viewer.configure(new SourceViewerConfiguration());
+ source_viewer.setDocument(document);
+ source_viewer.setEditable(false);
+ source_viewer.addTextPresentationListener(presentation_listener);
+ Control control = source_viewer.getControl();
+ GridData gd = new GridData(GridData.FILL_BOTH);
+ control.setLayoutData(gd);
+ display = control.getDisplay();
+ return control;
+ }
+
+ public void display(IStructuredSelection selection) {
+ if (source_viewer == null) return;
+ generation++;
+ final int g = generation;
+ final ArrayList<TCFNode> nodes = new ArrayList<TCFNode>();
+ if (selection != null) {
+ Iterator<?> iterator = selection.iterator();
+ while (iterator.hasNext()) {
+ Object next = iterator.next();
+ if (next instanceof TCFNode) nodes.add((TCFNode)next);
+ }
+ }
+ Protocol.invokeLater(new Runnable() {
+ public void run() {
+ if (g != generation) return;
+ final StyledStringBuffer s = getDetailText(nodes, this);
+ if (s == null) return;
+ display.asyncExec(new Runnable() {
+ public void run() {
+ if (g != generation) return;
+ document.set(getStyleRanges(s));
+ }
+ });
+ }
+ });
+ }
+
+ private StyledStringBuffer getDetailText(ArrayList<TCFNode> nodes, Runnable done) {
+ StyledStringBuffer bf = new StyledStringBuffer();
+ for (TCFNode n : nodes) {
+ if (n instanceof IDetailsProvider) {
+ if (!((IDetailsProvider)n).getDetailText(bf, done)) return null;
+ }
+ }
+ return bf;
+ }
+
+ private String getStyleRanges(StyledStringBuffer s) {
+ style_ranges.clear();
+ for (StyledStringBuffer.Style x : s.getStyle()) {
+ style_ranges.add(new StyleRange(x.pos, x.len, getColor(x.fg), getColor(x.bg), x.font));
+ }
+ return s.toString();
+ }
+
+ private Color getColor(RGB rgb) {
+ if (rgb == null) return null;
+ Color c = colors.get(rgb);
+ if (c == null) colors.put(rgb, c = new Color(display, rgb));
+ return c;
+ }
+
+ public void dispose() {
+ for (Color c : colors.values()) c.dispose();
+ colors.clear();
+ if (source_viewer == null) return;
+ generation++;
+ if (source_viewer.getControl() != null) {
+ source_viewer.getControl().dispose();
+ }
+ source_viewer = null;
+ }
+
+ public String getDescription() {
+ return DESC;
+ }
+
+ public String getID() {
+ return ID;
+ }
+
+ public String getName() {
+ return NAME;
+ }
+
+ public void init(IWorkbenchPartSite part_site) {
+ this.part_site = part_site;
+ }
+
+ public boolean setFocus() {
+ if (source_viewer == null) return false;
+ source_viewer.getTextWidget().setFocus();
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDetailPaneFactory.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDetailPaneFactory.java
new file mode 100644
index 000000000..e7a6d4fc5
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFDetailPaneFactory.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.debug.ui.IDetailPane;
+import org.eclipse.debug.ui.IDetailPaneFactory;
+import org.eclipse.jface.viewers.IStructuredSelection;
+
+/**
+ * The TCF detail pane factory is contributed to the <code>org.eclipse.debug.ui.detailPaneFactories</code>
+ * extension. For any selection that contains TCFNode the factory can produce a <code>IDetailPane</code> object.
+ */
+public class TCFDetailPaneFactory implements IDetailPaneFactory {
+
+ public IDetailPane createDetailPane(String paneID) {
+ assert paneID.equals(TCFDetailPane.ID);
+ return new TCFDetailPane();
+ }
+
+ public String getDefaultDetailPane(IStructuredSelection selection) {
+ return TCFDetailPane.ID;
+ }
+
+ public String getDetailPaneDescription(String paneID) {
+ return TCFDetailPane.NAME;
+ }
+
+ public String getDetailPaneName(String paneID) {
+ return TCFDetailPane.DESC;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public Set getDetailPaneTypes(IStructuredSelection selection) {
+ HashSet<String> set = new HashSet<String>();
+ set.add(TCFDetailPane.ID);
+ return set;
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFMemoryBlockRetrieval.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFMemoryBlockRetrieval.java
new file mode 100644
index 000000000..18a3f5704
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFMemoryBlockRetrieval.java
@@ -0,0 +1,508 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.PlatformObject;
+import org.eclipse.debug.core.DebugEvent;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.core.model.IMemoryBlock;
+import org.eclipse.debug.core.model.IMemoryBlockExtension;
+import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
+import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
+import org.eclipse.debug.core.model.MemoryByte;
+import org.eclipse.tm.internal.tcf.debug.model.ITCFConstants;
+import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
+import org.eclipse.tm.internal.tcf.debug.ui.Activator;
+import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IToken;
+import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.tcf.services.IExpressions;
+import org.eclipse.tm.tcf.services.IMemory;
+import org.eclipse.tm.tcf.services.ISymbols;
+import org.eclipse.tm.tcf.services.IMemory.MemoryError;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+
+/**
+ * A memory block retrieval allows the user interface to request a memory block from a debugger when needed.
+ * TCF memory block retrieval is based on TCF Memory service.
+ */
+class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
+
+ private final TCFNodeExecContext exec_ctx;
+ private final HashSet<MemoryBlock> mem_blocks = new HashSet<MemoryBlock>();
+
+ private static class MemData {
+ final BigInteger addr;
+ final MemoryByte[] data;
+ final byte[] bytes;
+
+ MemData(BigInteger addr, MemoryByte[] data) {
+ int i = 0;
+ this.addr = addr;
+ this.data = data;
+ this.bytes = new byte[data.length];
+ for (MemoryByte b : data) bytes[i++] = b.getValue();
+ }
+ }
+
+ private class MemoryBlock extends PlatformObject implements IMemoryBlockExtension {
+
+ private final String expression;
+ private final long length;
+ private final Set<Object> connections = new HashSet<Object>();
+ private final TCFDataCache<IExpressions.Expression> remote_expression;
+ private final TCFDataCache<IExpressions.Value> expression_value;
+ private final TCFDataCache<ISymbols.Symbol> expression_type;
+
+ private boolean disposed;
+
+ private MemData mem_data; // current memory block data
+ private MemData mem_prev; // previous data - before last suspend
+ private MemData mem_last; // last retrieved memory block data
+
+ MemoryBlock(final String expression, long length) {
+ this.expression = expression;
+ this.length = length;
+ mem_blocks.add(this);
+ final TCFLaunch launch = exec_ctx.model.getLaunch();
+ final IChannel channel = launch.getChannel();
+ remote_expression = new TCFDataCache<IExpressions.Expression>(channel) {
+ @Override
+ protected boolean startDataRetrieval() {
+ IExpressions exps = launch.getService(IExpressions.class);
+ if (exps == null) {
+ set(null, new Exception("Expressions service not available"), null);
+ return true;
+ }
+ command = exps.create(exec_ctx.id, null, expression, new IExpressions.DoneCreate() {
+ public void doneCreate(IToken token, Exception error, IExpressions.Expression context) {
+ if (disposed) {
+ IExpressions exps = channel.getRemoteService(IExpressions.class);
+ exps.dispose(context.getID(), new IExpressions.DoneDispose() {
+ public void doneDispose(IToken token, Exception error) {
+ if (error == null) return;
+ if (channel.getState() != IChannel.STATE_OPEN) return;
+ Activator.log("Error disposing remote expression evaluator", error);
+ }
+ });
+ return;
+ }
+ set(token, error, context);
+ }
+ });
+ return false;
+ }
+ };
+ expression_value = new TCFDataCache<IExpressions.Value>(channel) {
+ @Override
+ protected boolean startDataRetrieval() {
+ if (!remote_expression.validate(this)) return false;
+ final IExpressions.Expression ctx = remote_expression.getData();
+ if (ctx == null) {
+ set(null, null, null);
+ return true;
+ }
+ IExpressions exps = launch.getService(IExpressions.class);
+ command = exps.evaluate(ctx.getID(), new IExpressions.DoneEvaluate() {
+ public void doneEvaluate(IToken token, Exception error, IExpressions.Value value) {
+ set(token, error, value);
+ }
+ });
+ return false;
+ }
+ };
+ expression_type = new TCFDataCache<ISymbols.Symbol>(channel) {
+ @Override
+ protected boolean startDataRetrieval() {
+ if (!expression_value.validate(this)) return false;
+ IExpressions.Value val = expression_value.getData();
+ if (val == null) {
+ set(null, expression_value.getError(), null);
+ return true;
+ }
+ TCFDataCache<ISymbols.Symbol> type_cache = exec_ctx.model.getSymbolInfoCache(val.getTypeID());
+ if (type_cache == null) {
+ set(null, null, null);
+ return true;
+ }
+ if (!type_cache.validate(this)) return false;
+ set(null, type_cache.getError(), type_cache.getData());
+ return true;
+ }
+ };
+ }
+
+ public synchronized void connect(Object client) {
+ connections.add(client);
+ }
+
+ public synchronized void disconnect(Object client) {
+ connections.remove(client);
+ }
+
+ public synchronized Object[] getConnections() {
+ return connections.toArray(new Object[connections.size()]);
+ }
+
+ public void dispose() throws DebugException {
+ new TCFDebugTask<Boolean>(exec_ctx.getChannel()) {
+ public void run() {
+ disposed = true;
+ expression_value.dispose();
+ expression_type.dispose();
+ if (remote_expression.isValid() && remote_expression.getData() != null) {
+ final IChannel channel = exec_ctx.channel;
+ if (channel.getState() == IChannel.STATE_OPEN) {
+ IExpressions exps = channel.getRemoteService(IExpressions.class);
+ exps.dispose(remote_expression.getData().getID(), new IExpressions.DoneDispose() {
+ public void doneDispose(IToken token, Exception error) {
+ if (error == null) return;
+ if (channel.getState() != IChannel.STATE_OPEN) return;
+ Activator.log("Error disposing remote expression evaluator", error);
+ }
+ });
+ }
+ }
+ remote_expression.dispose();
+ mem_blocks.remove(MemoryBlock.this);
+ done(Boolean.TRUE);
+ }
+ }.getD();
+ }
+
+ public int getAddressSize() throws DebugException {
+ return new TCFDebugTask<Integer>(exec_ctx.getChannel()) {
+ public void run() {
+ if (exec_ctx.isDisposed()) {
+ error("Context is disposed");
+ }
+ else {
+ TCFDataCache<IMemory.MemoryContext> cache = exec_ctx.getMemoryContext();
+ if (!cache.validate(this)) return;
+ if (cache.getError() != null) {
+ error(cache.getError());
+ }
+ else {
+ IMemory.MemoryContext mem = cache.getData();
+ if (mem == null) {
+ error("Context does not provide memory access");
+ }
+ else {
+ done(mem.getAddressSize());
+ }
+ }
+ }
+ }
+ }.getD();
+ }
+
+ public int getAddressableSize() throws DebugException {
+ // TODO: support for addressable size other then 1 byte
+ return 1;
+ }
+
+ public BigInteger getBigBaseAddress() throws DebugException {
+ return new TCFDebugTask<BigInteger>(exec_ctx.getChannel()) {
+ public void run() {
+ if (!expression_value.validate()) {
+ expression_value.wait(this);
+ }
+ else if (expression_value.getError() != null) {
+ error(expression_value.getError());
+ }
+ else if (expression_value.getData() == null) {
+ error("Address expression evaluation failed");
+ }
+ else if (!expression_type.validate()) {
+ expression_type.wait(this);
+ }
+ else if (expression_type.getError() != null) {
+ error(expression_type.getError());
+ }
+ else {
+ IExpressions.Value value = expression_value.getData();
+ byte[] data = value.getValue();
+ if (data == null || data.length == 0) {
+ error("Address expression value is empty (void)");
+ }
+ else {
+ ISymbols.Symbol type = expression_type.getData();
+ boolean signed = type != null && type.getTypeClass() == ISymbols.TypeClass.integer;
+ done(TCFNumberFormat.toBigInteger(data, 0, data.length, value.isBigEndian(), signed));
+ }
+ }
+ }
+ }.getD();
+ }
+
+ public MemoryByte[] getBytesFromAddress(final BigInteger address, final long units) throws DebugException {
+ return new TCFDebugTask<MemoryByte[]>(exec_ctx.getChannel()) {
+ int offs = 0;
+ public void run() {
+ if (mem_data != null &&
+ address.compareTo(mem_data.addr) >= 0 &&
+ address.add(BigInteger.valueOf(units)).compareTo(
+ mem_data.addr.add(BigInteger.valueOf(mem_data.data.length))) <= 0) {
+ offs = address.subtract(mem_data.addr).intValue();
+ MemoryByte[] res = mem_data.data;
+ if (units < mem_data.data.length) {
+ res = new MemoryByte[(int)units];
+ System.arraycopy(mem_data, offs, res, 0, res.length);
+ }
+ setHistoryFlags();
+ done(res);
+ return;
+ }
+ if (exec_ctx.isDisposed()) {
+ error("Context is disposed");
+ return;
+ }
+ TCFDataCache<IMemory.MemoryContext> cache = exec_ctx.getMemoryContext();
+ if (!cache.validate(this)) return;
+ if (cache.getError() != null) {
+ error(cache.getError());
+ return;
+ }
+ final IMemory.MemoryContext mem = cache.getData();
+ if (mem == null) {
+ error("Context does not provide memory access");
+ return;
+ }
+ final int size = (int)units;
+ final int mode = IMemory.MODE_CONTINUEONERROR | IMemory.MODE_VERIFY;
+ final byte[] buf = new byte[size];
+ final MemoryByte[] res = new MemoryByte[size];
+ mem.get(address, 1, buf, 0, size, mode, new IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ int big_endian = 0;
+ if (mem.getProperties().get(IMemory.PROP_BIG_ENDIAN) != null) {
+ big_endian |= MemoryByte.ENDIANESS_KNOWN;
+ if (mem.isBigEndian()) big_endian |= MemoryByte.BIG_ENDIAN;
+ }
+ int cnt = 0;
+ while (offs < size) {
+ int flags = big_endian;
+ if (error instanceof IMemory.ErrorOffset) {
+ IMemory.ErrorOffset ofs = (IMemory.ErrorOffset)error;
+ int status = ofs.getStatus(cnt);
+ if (status == IMemory.ErrorOffset.BYTE_VALID) {
+ flags |= MemoryByte.READABLE | MemoryByte.WRITABLE;
+ }
+ else if ((status & IMemory.ErrorOffset.BYTE_UNKNOWN) != 0) {
+ if (cnt > 0) break;
+ }
+ }
+ else if (error == null) {
+ flags |= MemoryByte.READABLE | MemoryByte.WRITABLE;
+ }
+ res[offs] = new MemoryByte(buf[offs], (byte)flags);
+ offs++;
+ cnt++;
+ }
+ if (offs < size) {
+ mem.get(address.add(BigInteger.valueOf(offs)), 1, buf, offs, size - offs, mode, this);
+ }
+ else {
+ mem_last = mem_data = new MemData(address, res);
+ setHistoryFlags();
+ done(res);
+ }
+ }
+ });
+ }
+ }.getD();
+ }
+
+ private void setHistoryFlags() {
+ if (mem_data == null) return;
+ BigInteger addr = mem_data.addr;
+ BigInteger his_start = null;
+ BigInteger his_end = null;
+ if (mem_prev != null) {
+ his_start = mem_prev.addr;
+ his_end = mem_prev.addr.add(BigInteger.valueOf(mem_prev.data.length));
+ }
+ for (MemoryByte b : mem_data.data) {
+ int flags = b.getFlags();
+ if (mem_prev != null && addr.compareTo(his_start) >= 0 && addr.compareTo(his_end) < 0) {
+ flags |= MemoryByte.HISTORY_KNOWN;
+ int offs = addr.subtract(his_start).intValue();
+ if (b.getValue() != mem_prev.data[offs].getValue()) {
+ flags |= MemoryByte.CHANGED;
+ }
+ }
+ else {
+ flags &= ~(MemoryByte.HISTORY_KNOWN | MemoryByte.CHANGED);
+ }
+ b.setFlags((byte)flags);
+ addr = addr.add(BigInteger.valueOf(1));
+ }
+ }
+
+ public MemoryByte[] getBytesFromOffset(BigInteger offset, long units) throws DebugException {
+ return getBytesFromAddress(getBigBaseAddress().add(offset), units);
+ }
+
+ public String getExpression() {
+ return expression;
+ }
+
+ public IMemoryBlockRetrieval getMemoryBlockRetrieval() {
+ return TCFMemoryBlockRetrieval.this;
+ }
+
+ public long getStartAddress() {
+ return 0; // Unbounded
+ }
+
+ public long getLength() {
+ return length;
+ }
+
+ public BigInteger getMemoryBlockStartAddress() throws DebugException {
+ return null; // Unbounded
+ }
+
+ public BigInteger getMemoryBlockEndAddress() throws DebugException {
+ return null; // Unbounded
+ }
+
+ public BigInteger getBigLength() throws DebugException {
+ return BigInteger.valueOf(length);
+ }
+
+ public void setBaseAddress(BigInteger address) throws DebugException {
+ }
+
+ public void setValue(BigInteger offset, final byte[] bytes) throws DebugException {
+ final BigInteger address = getBigBaseAddress().add(offset);
+ new TCFDebugTask<Object>(exec_ctx.getChannel()) {
+ public void run() {
+ if (exec_ctx.isDisposed()) {
+ error("Context is disposed");
+ return;
+ }
+ TCFDataCache<IMemory.MemoryContext> cache = exec_ctx.getMemoryContext();
+ if (!cache.validate(this)) return;
+ if (cache.getError() != null) {
+ error(cache.getError());
+ return;
+ }
+ final IMemory.MemoryContext mem = cache.getData();
+ if (mem == null) {
+ error("Context does not provide memory access");
+ return;
+ }
+ final int mode = IMemory.MODE_CONTINUEONERROR | IMemory.MODE_VERIFY;
+ mem.set(address, 1, bytes, 0, bytes.length, mode, new IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (error != null) {
+ error(error);
+ }
+ else {
+ done(null);
+ }
+ }
+ });
+ }
+ }.getD();
+ }
+
+ public boolean supportBaseAddressModification() throws DebugException {
+ return false;
+ }
+
+ public boolean supportsChangeManagement() {
+ return true;
+ }
+
+ public byte[] getBytes() throws DebugException {
+ if (mem_data == null) return null;
+ return mem_data.bytes;
+ }
+
+ public void setValue(long offset, byte[] bytes) throws DebugException {
+ setValue(BigInteger.valueOf(offset), bytes);
+ }
+
+ public boolean supportsValueModification() {
+ return true;
+ }
+
+ public IDebugTarget getDebugTarget() {
+ return null;
+ }
+
+ public ILaunch getLaunch() {
+ return exec_ctx.model.getLaunch();
+ }
+
+ public String getModelIdentifier() {
+ return ITCFConstants.ID_TCF_DEBUG_MODEL;
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter(Class adapter) {
+ if (adapter == IMemoryBlockRetrieval.class) return TCFMemoryBlockRetrieval.this;
+ if (adapter == IMemoryBlockRetrievalExtension.class) return TCFMemoryBlockRetrieval.this;
+ return super.getAdapter(adapter);
+ }
+ }
+
+ TCFMemoryBlockRetrieval(TCFNodeExecContext exec_ctx) {
+ this.exec_ctx = exec_ctx;
+ }
+
+ public IMemoryBlockExtension getExtendedMemoryBlock(final String expression, Object context) throws DebugException {
+ return new TCFDebugTask<IMemoryBlockExtension>() {
+ public void run() {
+ done(new MemoryBlock(expression, -1));
+ }
+ }.getD();
+ }
+
+ public IMemoryBlock getMemoryBlock(final long address, final long length) throws DebugException {
+ return new TCFDebugTask<IMemoryBlockExtension>() {
+ public void run() {
+ done(new MemoryBlock("0x" + Long.toHexString(address), length));
+ }
+ }.getD();
+ }
+
+ public boolean supportsStorageRetrieval() {
+ return true;
+ }
+
+ public String getMemoryID() {
+ return exec_ctx.id;
+ }
+
+ void onMemoryChanged(boolean suspended) {
+ assert Protocol.isDispatchThread();
+ if (mem_blocks.size() == 0) return;
+ ArrayList<DebugEvent> list = new ArrayList<DebugEvent>();
+ for (MemoryBlock b : mem_blocks) {
+ if (suspended) b.mem_prev = b.mem_last;
+ b.mem_data = null;
+ list.add(new DebugEvent(b, DebugEvent.CHANGE, DebugEvent.CONTENT));
+ }
+ DebugPlugin.getDefault().fireDebugEventSet(list.toArray(new DebugEvent[list.size()]));
+ }
+}
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
new file mode 100644
index 000000000..1f8787bd4
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFModel.java
@@ -0,0 +1,1785 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial AP