diff options
author | Randy Rohrbach | 2012-11-16 23:55:17 +0000 |
---|---|---|
committer | Randy Rohrbach | 2012-11-16 23:55:17 +0000 |
commit | 2dbe81588e6e58bd1f859dccb595fb5d76d2740b (patch) | |
tree | e6f5d1a028083de5db34ceba86d0a6c384818783 /memory | |
parent | 9194376ff4c21bcbd7062150e2bfc97c6844ebd6 (diff) | |
download | org.eclipse.cdt-2dbe81588e6e58bd1f859dccb595fb5d76d2740b.tar.gz org.eclipse.cdt-2dbe81588e6e58bd1f859dccb595fb5d76d2740b.tar.xz org.eclipse.cdt-2dbe81588e6e58bd1f859dccb595fb5d76d2740b.zip |
BUG 394509 : Adding floating point renderer to the memory Browser
This is Wind Rivers floating point renderer we are moving in to Open
SOurce.
Diffstat (limited to 'memory')
36 files changed, 6907 insertions, 2 deletions
diff --git a/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.properties b/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.properties index 827e75627cc..58974a665b6 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.properties +++ b/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.properties @@ -29,7 +29,7 @@ providerName=Eclipse CDT updateSiteName=Eclipse CDT Update Site # "description" property - description of the feature -description=Additional features for debug Memory View - traditional rendering, Find/Replace, Import/Export. +description=Additional features for debug Memory View - traditional rendering, floating-point rendering, Find/Replace, Import/Export. # "licenseURL" property - URL of the "Feature License" # do not translate value - just change to point to a locale-specific HTML page diff --git a/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.xml b/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.xml index 27fbf4a0fb8..334d34a8d3b 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.xml +++ b/memory/org.eclipse.cdt.debug.ui.memory-feature/feature.xml @@ -30,6 +30,13 @@ install-size="0" version="0.0.0" unpack="false"/> + + <plugin + id="org.eclipse.cdt.debug.ui.memory.floatingpoint" + download-size="0" + install-size="0" + version="0.0.0" + unpack="false"/> <plugin id="org.eclipse.cdt.debug.ui.memory.transport" diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.classpath b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.classpath new file mode 100644 index 00000000000..ad32c83a788 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.gitignore b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.gitignore new file mode 100644 index 00000000000..ea8c4bf7f35 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.gitignore @@ -0,0 +1 @@ +/target diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.project b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.project new file mode 100644 index 00000000000..91d6dff85c8 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.cdt.debug.ui.memory.floatingpoint</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.core.prefs b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..40227fe6c21 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,95 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore +org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull +org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault +org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable +org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=warning +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=warning +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error +org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning +org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error +org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=enabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.ui.prefs b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 00000000000..56613a2a55a --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.ui.javadoc=true +org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\r\n * @return the ${bare_field_name}\r\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\r\n * @param ${param} the ${bare_field_name} to set\r\n */</template><template autoinsert\="false" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\r\n * Constructor.\r\n * ${tags}\r\n */</template><template autoinsert\="false" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\r\n * ${file_name}\r\n * Created on ${date}\r\n *\r\n * Copyright (c) ${year} Wind River Systems Inc and others. \r\n * All rights reserved. This program and the accompanying materials \r\n * are made available under the terms of the Eclipse Public License v1.0 \r\n * which accompanies this dsitribution, and is available at \r\n * http://www.eclipse.org/legal/epl-v10.html */</template><template autoinsert\="false" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\r\n *\r\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\r\n * \r\n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\r\n * ${tags}\r\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\r\n * ${see_to_overridden}\r\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\r\n * ${tags}\r\n * ${see_to_target}\r\n */</template><template autoinsert\="true" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">${filecomment}\r\n${package_declaration}\r\n\r\n${typecomment}\r\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\r\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\r\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\r\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\r\n</template><template autoinsert\="false" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">${exception_var}.printStackTrace();</template><template autoinsert\="false" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">${body_statement}</template><template autoinsert\="false" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\r\n</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates> diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.pde.prefs b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.pde.prefs new file mode 100644 index 00000000000..cf80c8bc5b8 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/.settings/org.eclipse.pde.prefs @@ -0,0 +1,32 @@ +compilers.f.unresolved-features=1 +compilers.f.unresolved-plugins=1 +compilers.incompatible-environment=1 +compilers.p.build=1 +compilers.p.build.bin.includes=1 +compilers.p.build.encodings=2 +compilers.p.build.java.compiler=2 +compilers.p.build.java.compliance=1 +compilers.p.build.missing.output=2 +compilers.p.build.output.library=1 +compilers.p.build.source.library=1 +compilers.p.build.src.includes=1 +compilers.p.deprecated=1 +compilers.p.discouraged-class=1 +compilers.p.internal=1 +compilers.p.missing-packages=1 +compilers.p.missing-version-export-package=2 +compilers.p.missing-version-import-package=1 +compilers.p.missing-version-require-bundle=1 +compilers.p.no-required-att=0 +compilers.p.not-externalized-att=2 +compilers.p.unknown-attribute=1 +compilers.p.unknown-class=1 +compilers.p.unknown-element=1 +compilers.p.unknown-identifier=1 +compilers.p.unknown-resource=1 +compilers.p.unresolved-ex-points=0 +compilers.p.unresolved-import=0 +compilers.s.create-docs=false +compilers.s.doc-folder=doc +compilers.s.open-tags=1 +eclipse.preferences.version=1 diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/META-INF/MANIFEST.MF b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..edfa244b84d --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: org.eclipse.cdt.debug.ui.memory.floatingpoint;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Localization: plugin +Require-Bundle: org.eclipse.debug.core;bundle-version="3.7.100", + org.eclipse.debug.ui;bundle-version="3.8.1", + org.eclipse.core.runtime;bundle-version="3.8.0", + org.eclipse.ui;bundle-version="3.8.0", + org.eclipse.search;bundle-version="3.8.0", + org.eclipse.cdt.debug.core;bundle-version="7.2.0" +Bundle-ActivationPolicy: lazy +Bundle-Activator: org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingPlugin +Bundle-Vendor: %providerName +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Export-Package: org.eclipse.cdt.debug.ui.memory.floatingpoint diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/build.properties b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/build.properties new file mode 100644 index 00000000000..a8d25594f6e --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/build.properties @@ -0,0 +1,12 @@ +source.. = src/ +bin.includes = .classpath,\ + .gitignore,\ + .project,\ + .settings/,\ + bin/,\ + build.properties,\ + META-INF/,\ + plugin.properties,\ + plugin.xml,\ + pom.xml,\ + . diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.properties b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.properties new file mode 100644 index 00000000000..fa0cd17819e --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.properties @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2012 Wind River Systems 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: +# Randy Rohrbach (Wind River) - Initial implementation +# IBM Corporation +############################################################################### +# +# Plugin information +# +pluginName = Floating Point Memory Renderer +providerName = Eclipse CDT +renderingType.name = Floating Point +page.name = Floating Point Memory Renderer +# +# Action preference text +# +FPRenderingPreferenceActionName=Floating Point Rendering Preferences ... diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.xml b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.xml new file mode 100644 index 00000000000..0f687ebde07 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/plugin.xml @@ -0,0 +1,51 @@ +<?eclipse version="3.0"?> +<plugin> + + <extension point="org.eclipse.debug.ui.memoryRenderings"> + <renderingType + name="%renderingType.name" + id="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRendering" + class="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingTypeDelegate"> + </renderingType> + <renderingBindings + renderingIds="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRendering" + defaultIds="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRendering"> + <enablement> + <instanceof value="org.eclipse.debug.core.model.IMemoryBlockExtension"/> + </enablement> + </renderingBindings> + </extension> + + <extension point="org.eclipse.ui.preferencePages"> + <page + category="org.eclipse.cdt.debug.ui.CDebugPreferencePage" + class="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingPreferencePage" + id="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingPreferencePage" + name="%page.name"/> + </extension> + + <extension point="org.eclipse.core.runtime.preferences"> + <initializer class="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingPreferenceInitializer"/> + </extension> + + <extension point="org.eclipse.ui.viewActions"> + <viewContribution + targetID="org.eclipse.debug.ui.MemoryView" + id="org.eclipse.debug.ui.memoryView.toolbar"> + <action + class="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingPreferenceAction" + helpContextId="FPRenderingPreferenceAction_context" + id="org.eclipse.cdt.debug.ui.memory.floatingpoint.preferenceaction" + label="%FPRenderingPreferenceActionName" + menubarPath="additions" + style="push" + tooltip="%FPRenderingPreferenceActionName"/> + </viewContribution> + </extension> + + <extension point="org.eclipse.core.runtime.preferences"> + <!-- preferences initialization for Floating Point Renderer persistant storage --> + <initializer class="org.eclipse.cdt.debug.ui.memory.floatingpoint.FPPreferenceConstants$Initializer"/> + </extension> + +</plugin> diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/pom.xml b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/pom.xml new file mode 100644 index 00000000000..b6255b76271 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/pom.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project + xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.eclipse.cdt</groupId> + <artifactId>cdt-parent</artifactId> + <version>8.1.0-SNAPSHOT</version> + <relativePath>../../../../pom/pom-all.xml</relativePath> + </parent> + + <artifactId>org.eclipse.cdt.debug.ui.memory.floatingpoint</artifactId> + <version>1.0.0.qualifier</version> + <packaging>eclipse-plugin</packaging> +</project> diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAbstractPane.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAbstractPane.java new file mode 100644 index 00000000000..c8da9cf9c48 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAbstractPane.java @@ -0,0 +1,903 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseListener; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Caret; + +public abstract class FPAbstractPane extends Canvas +{ + protected Rendering fRendering; + + // Selection state + + protected boolean fSelectionStarted = false; + protected boolean fSelectionInProgress = false; + protected BigInteger fSelectionStartAddress = null; + protected int fSelectionStartAddressSubPosition; + + // Caret + + protected Caret fCaret = null; + + // Character may not fall on byte boundary + + protected int fSubCellCaretPosition = 0; + protected int fOldSubCellCaretPosition = 0; + protected boolean fCaretEnabled = false; + protected BigInteger fCaretAddress = null; + + // Storage + + protected int fRowCount = 0; + protected boolean fPaneVisible = true; + + // Mouse listener class + + class AbstractPaneMouseListener implements MouseListener + { + @Override + public void mouseUp(MouseEvent me) + { + // Move the caret + + positionCaret(me.x, me.y); + + fCaret.setVisible(true); + + if (fSelectionInProgress && me.button == 1) + endSelection(me.x, me.y); + + fSelectionInProgress = fSelectionStarted = false; + } + + // Mouse down click + + @Override + public void mouseDown(MouseEvent me) + { + // Any click, whether inside this cell or elsewhere, terminates the edit and acts the same as a carriage return would. + + handleCarriageReturn(); + + // Switch focus and check for selection + + FPAbstractPane.this.forceFocus(); + positionCaret(me.x, me.y); + fCaret.setVisible(false); + + if (me.button == 1) + { + // If shift is down and we have an existing start address, append selection + + if ((me.stateMask & SWT.SHIFT) != 0 && fRendering.getSelection().getStart() != null) + { + // If the pane doesn't have a selection start (the selection was created in a different + // pane) then initialize the pane's selection start to the rendering's selection start. + + if (FPAbstractPane.this.fSelectionStartAddress == null) + FPAbstractPane.this.fSelectionStartAddress = fRendering.getSelection().getStart(); + + FPAbstractPane.this.fSelectionStarted = true; + FPAbstractPane.this.appendSelection(me.x, me.y); + + } + else + { + // Start a new selection + + FPAbstractPane.this.startSelection(me.x, me.y); + } + } + + } + + // Double click + + @Override + public void mouseDoubleClick(MouseEvent me) + { + handleMouseDoubleClick(me); + } + } + + // Mouse move listener class + + class AbstractPaneMouseMoveListener implements MouseMoveListener + { + @Override + public void mouseMove(MouseEvent me) + { + if (fSelectionStarted) + { + fSelectionInProgress = true; + appendSelection(me.x, me.y); + } + } + } + + // Focus listener class + + class AbstractPaneFocusListener implements FocusListener + { + @Override + public void focusLost(FocusEvent fe) + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + if (FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY.equals(store.getString(FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE))) + fRendering.getViewportCache().clearEditBuffer(); + else + fRendering.getViewportCache().writeEditBuffer(); + + // clear the pane local selection start + FPAbstractPane.this.fSelectionStartAddress = null; + } + + @Override + public void focusGained(FocusEvent fe) + { + // Set the floating point edit mode indicator if the user clicked in the Data Pane; otherwise clear it + + if (FPAbstractPane.this instanceof FPDataPane) + fRendering.displayEditModeIndicator(true); + else + fRendering.displayEditModeIndicator(false); + } + } + + // Key listener class + + class AbstractPaneKeyListener implements KeyListener + { + @Override + public void keyPressed(KeyEvent ke) + { + fOldSubCellCaretPosition = fSubCellCaretPosition; + + // Shift + + if ((ke.stateMask & SWT.SHIFT) != 0) + { + switch (ke.keyCode) + { + case SWT.ARROW_RIGHT: + case SWT.ARROW_LEFT: + case SWT.ARROW_UP: + case SWT.ARROW_DOWN: + case SWT.PAGE_DOWN: + case SWT.PAGE_UP: + { + if (fRendering.getSelection().getStart() == null) + fRendering.getSelection().setStart(fCaretAddress.add(BigInteger.valueOf(fRendering.getAddressesPerColumn())), fCaretAddress); + break; + } + } + } + + // Arrow, Page, Insert, Escape and standard characters + + if (ke.keyCode == SWT.ARROW_RIGHT) + { + handleRightArrowKey(); + } + else if (ke.keyCode == SWT.ARROW_LEFT || ke.keyCode == SWT.BS) + { + handleLeftArrowKey(); + } + else if (ke.keyCode == SWT.ARROW_DOWN) + { + handleDownArrowKey(); + } + else if (ke.keyCode == SWT.ARROW_UP) + { + handleUpArrowKey(); + } + else if (ke.keyCode == SWT.PAGE_DOWN) + { + handlePageDownKey(); + } + else if (ke.keyCode == SWT.PAGE_UP) + { + handlePageUpKey(); + } + else if (ke.keyCode == SWT.INSERT) + { + handleInsertKey(); + } + else if (ke.keyCode == SWT.ESC) + { + fRendering.getViewportCache().clearEditBuffer(); + handleCTRLZ(); + } + else if (ke.character == '\r') + { + fRendering.getViewportCache().writeEditBuffer(); + handleCarriageReturn(); + } + else if (FPutilities.validEditCharacter(ke.character)) + { + // Check for selection + + if (fRendering.getSelection().hasSelection()) + { + setCaretAddress(fRendering.getSelection().getLow()); + fSubCellCaretPosition = 0; + } + + // Add the chatacter to the cell + + editCell(fCaretAddress, fSubCellCaretPosition, ke.character); + } + + // Control + + if ((ke.stateMask & SWT.CTRL) != 0) + { + // CTRL/Z + + if (ke.keyCode == 'z' || ke.keyCode == 'Z') + handleCTRLZ(); + } + + // Alt + + if ((ke.stateMask & SWT.ALT) != 0) + { + // Future use + } + + // Shift + + if ((ke.stateMask & SWT.SHIFT) != 0) + { + switch (ke.keyCode) + { + case SWT.ARROW_RIGHT: + case SWT.ARROW_LEFT: + case SWT.ARROW_UP: + case SWT.ARROW_DOWN: + case SWT.PAGE_DOWN: + case SWT.PAGE_UP: + fRendering.getSelection().setEnd(fCaretAddress.add(BigInteger.valueOf(fRendering.getAddressesPerColumn())), fCaretAddress); + break; + } + } + else if (ke.keyCode != SWT.SHIFT) + { + // If it's a SHIFT key, keep the selection since we may add to it + fRendering.getSelection().clear(); + } + } + + @Override + public void keyReleased(KeyEvent ke) + { + // do nothing + } + } + + class AbstractPanePaintListener implements PaintListener + { + @Override + public void paintControl(PaintEvent pe) + { + FPAbstractPane.this.paint(pe); + } + } + + public FPAbstractPane(Rendering rendering) + { + super(rendering, SWT.DOUBLE_BUFFERED); + + fRendering = rendering; + + try + { + fCaretAddress = rendering.getBigBaseAddress(); + } + catch (Exception e) + { + // do nothing + } + + // pref + + this.setFont(fRendering.getFont()); + + GC gc = new GC(this); + gc.setFont(this.getFont()); + fCaret = new Caret(this, SWT.NONE); + fCaret.setSize(1, gc.stringExtent("|").y); //$NON-NLS-1$ + gc.dispose(); + + this.addPaintListener(createPaintListener()); + this.addMouseListener(createMouseListener()); + this.addMouseMoveListener(createMouseMoveListener()); + this.addKeyListener(createKeyListener()); + this.addFocusListener(createFocusListener()); + } + + // Listener methods + + protected MouseListener createMouseListener() + { + return new AbstractPaneMouseListener(); + } + + protected MouseMoveListener createMouseMoveListener() + { + return new AbstractPaneMouseMoveListener(); + } + + protected FocusListener createFocusListener() + { + return new AbstractPaneFocusListener(); + } + + protected KeyListener createKeyListener() + { + return new AbstractPaneKeyListener(); + } + + protected PaintListener createPaintListener() + { + return new AbstractPanePaintListener(); + } + + // Right arrow + + protected void handleRightArrowKey() + { + fSubCellCaretPosition++; + + if (fSubCellCaretPosition >= getCellCharacterCount()) + { + // We've moved beyond the end of the cell: End the edit to the previous cell. + + handleCarriageReturn(); + + // Move to the next cell; ensure that caret is within the addressable range + + fSubCellCaretPosition = 0; + BigInteger newCaretAddress = fCaretAddress.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())); + + if (newCaretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) > 0) + fSubCellCaretPosition = getCellCharacterCount(); + else + setCaretAddress(newCaretAddress); + } + + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Left arrow + + protected void handleLeftArrowKey() + { + fSubCellCaretPosition--; + + if (fSubCellCaretPosition < 0) + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Move to the previous cell; ensure that caret is within the addressable range + + fSubCellCaretPosition = getCellCharacterCount() - 1; + BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())); + + if (newCaretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) < 0) + fSubCellCaretPosition = 0; + else + setCaretAddress(newCaretAddress); + } + + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Down arrow + + protected void handleDownArrowKey() + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Ensure that caret is within the addressable range + + BigInteger newCaretAddress = fCaretAddress.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength() * fRendering.getColumnCount())); + setCaretAddress(newCaretAddress); + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Up arrow + + protected void handleUpArrowKey() + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Ensure that caret is within the addressable range + + BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger.valueOf(fRendering.getFPDataType().getByteLength() * fRendering.getColumnCount())); + setCaretAddress(newCaretAddress); + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Page down + + protected void handlePageDownKey() + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Ensure that caret is within the addressable range + + BigInteger newCaretAddress = fCaretAddress.add(BigInteger.valueOf(fRendering.getAddressableCellsPerRow() * (fRendering.getRowCount() - 1))); + setCaretAddress(newCaretAddress); + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Page up + + protected void handlePageUpKey() + { + // We've moved beyond the beginning of the cell: This action ends the edit to the previous cell. + + handleCarriageReturn(); + + // Ensure that caret is within the addressable range + + BigInteger newCaretAddress = fCaretAddress.subtract(BigInteger.valueOf(fRendering.getAddressableCellsPerRow() * (fRendering.getRowCount() - 1))); + setCaretAddress(newCaretAddress); + updateTheCaret(); + ensureCaretWithinViewport(); + } + + // Insert key + + protected void handleInsertKey() + { + // If focus is in the Data Pane, toggle Insert/Overwrite mode and make sure the cell edit + // status line indicator is displayed. Otherwise, make clear the status line indicator. + + if (FPAbstractPane.this instanceof FPDataPane) + { + if (!fRendering.isEditingCell()) fRendering.setInsertMode(!fRendering.insertMode()); + fRendering.displayEditModeIndicator(true); + } + else + fRendering.displayEditModeIndicator(false); + } + + // Double-click + + protected void handleMouseDoubleClick(MouseEvent me) + { + try + { + BigInteger address = getViewportAddress(me.x / getCellWidth(), me.y / getCellHeight()); + + fRendering.getSelection().clear(); + fRendering.getSelection().setStart(address.add(BigInteger.valueOf(fRendering.getAddressesPerColumn())), address); + fRendering.getSelection().setEnd(address.add(BigInteger.valueOf(fRendering.getAddressesPerColumn())), address); + } + catch (DebugException de) + { + // do nothing + } + } + + // Carriage return + + protected void handleCarriageReturn() + { + // If we're not editing a cell or there is no string buffer to use, nothing to do: Exit edit mode and return. + + if (!fRendering.isEditingCell() || fRendering.getEditBuffer() == null) + { + fRendering.endCellEditing(); + return; + } + + // Remove all whitespace from the string buffer. + + fRendering.setEditBuffer(new StringBuffer(fRendering.getEditBuffer().toString().trim().replaceAll(" ", ""))); //$NON-NLS-1$ //$NON-NLS-2$ + + // Check the string to make sure it's in valid, acceptable form. + + if (FPutilities.isValidFormat(fRendering.getEditBuffer().toString())) + { + // Valid string: Convert it to a byte array and write the buffer back to memory; + // a subsequent re-draw/paint converts it to normalized scientific notation. + + fRendering.convertAndUpdateCell(fRendering.getCellEditAddress(), fRendering.getEditBuffer().toString()); + } + else + { + // Invalid string: Create the error text and restore the previous value + + String errorText = NLS.bind(FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_POPUP_TEXT"), fRendering.getEditBuffer().toString()); //$NON-NLS-1$ + + try + { + fRendering.setEditBuffer(new StringBuffer(fRendering.fDataPane.bytesToSciNotation(fRendering.getBytes(fCaretAddress, fRendering.getFPDataType().getByteLength())))); + } + catch (DebugException e) + { + e.printStackTrace(); + } + + // Put together the pop-up window components and show the user the error + + String statusString = FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_STATUS"); //$NON-NLS-1$ + Status status = new Status(IStatus.ERROR, FPRenderingPlugin.getUniqueIdentifier(), statusString); + FPutilities.popupMessage(FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_POPUP_TITLE"), errorText, status); //$NON-NLS-1$ + } + + // Exit cell-edit mode + + fRendering.endCellEditing(); + } + + // CTRL/Z handling + + protected void handleCTRLZ() + { + // CTRL/Z: Replace the cell contents with the original value and exit "number edit mode" + + try + { + fRendering.setEditBuffer(new StringBuffer(fRendering.fDataPane.bytesToSciNotation(fRendering.getBytes(fCaretAddress, fRendering.getFPDataType().getByteLength())))); + } + catch (DebugException e) + { + e.printStackTrace(); + } + + fRendering.endCellEditing(); + } + + // Other getter/setters + + protected boolean isPaneVisible() + { + return fPaneVisible; + } + + protected void setPaneVisible(boolean visible) + { + fPaneVisible = visible; + this.setVisible(visible); + } + + protected int getNumberOfBytesRepresentedByColumn() + { + return fRendering.getCharsPerColumn(); + } + + protected void editCell(BigInteger cellAddress, int subCellPosition, char character) + { + // Do nothing; overridden in subclass FPDataPane + } + + // Set the caret address + + protected void setCaretAddress(BigInteger caretAddress) + { + // Ensure that caret is within the addressable range + + if ((caretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) >= 0) && (caretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) <= 0)) + { + fCaretAddress = caretAddress; + } + else if (caretAddress.compareTo(fRendering.getMemoryBlockStartAddress()) < 0) + { + // Calculate offset from the beginning of the row + + int cellOffset = fCaretAddress.subtract(fRendering.getViewportStartAddress()).intValue(); + int row = cellOffset / (fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter()); + + cellOffset -= row * fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter(); + + fCaretAddress = fRendering.getMemoryBlockStartAddress().add(BigInteger.valueOf(cellOffset / fRendering.getAddressableSize())); + } + else if (caretAddress.compareTo(fRendering.getMemoryBlockEndAddress()) > 0) + { + // Calculate offset from the end of the row + + int cellOffset = fCaretAddress.subtract(fRendering.getViewportEndAddress()).intValue() + 1; + int row = cellOffset / (fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter()); + + cellOffset -= row * fRendering.getBytesPerRow() / fRendering.getBytesPerCharacter(); + + fCaretAddress = fRendering.getMemoryBlockEndAddress().add(BigInteger.valueOf(cellOffset / fRendering.getAddressableSize())); + } + + fRendering.setCaretAddress(fCaretAddress); + } + + protected boolean isOdd(int value) + { + return (value / 2) * 2 == value; + } + + protected void updateTheCaret() + { + try + { + if (fCaretAddress != null) + { + Point cellPosition = getCellLocation(fCaretAddress); + + if (cellPosition != null) + fCaret.setLocation(cellPosition.x + fSubCellCaretPosition * getCellCharacterWidth(), cellPosition.y); + } + } + catch (Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$ + } + } + + // This method scrolls the viewport to insure that the caret is within the viewable area + + protected void ensureCaretWithinViewport() // TODO getAddressableSize() > 1 ? + { + // If the caret is before the viewport start if so, scroll viewport up by several rows + + BigInteger rowCount = BigInteger.valueOf(getRowCount()); + BigInteger rowMemBytes = BigInteger.valueOf(fRendering.getFPDataType().getByteLength() * fRendering.getColumnCount()); + BigInteger viewableBytes = rowCount.multiply(rowMemBytes); + BigInteger viewableEnd = fRendering.getViewportStartAddress().add(viewableBytes); + + if (fCaretAddress.compareTo(fRendering.getViewportStartAddress()) < 0) + { + fRendering.setViewportStartAddress(fRendering.getViewportStartAddress().subtract(rowMemBytes)); + fRendering.ensureViewportAddressDisplayable(); + fRendering.gotoAddress(fRendering.getViewportStartAddress()); + } + + // If the caret is after the viewport end if so, scroll viewport down by appropriate rows + + else if (fCaretAddress.compareTo(viewableEnd) >= 0) + { + fRendering.setViewportStartAddress(fRendering.getViewportStartAddress().add(rowMemBytes)); + fRendering.ensureViewportAddressDisplayable(); + fRendering.gotoAddress(fRendering.getViewportStartAddress()); + } + + fRendering.setCaretAddress(fCaretAddress); + } + + protected void advanceCursor() + { + handleRightArrowKey(); + } + + protected void positionCaret(int x, int y) + { + // do nothing + } + + protected int getRowCount() + { + return fRowCount; + } + + protected void setRowCount() + { + fRowCount = getBounds().height / getCellHeight(); + } + + protected void settingsChanged() + { + fSubCellCaretPosition = 0; + } + + // Start selection + + protected void startSelection(int x, int y) + { + try + { + BigInteger address = getViewportAddress(x / getCellWidth(), y / getCellHeight()); + + if (address != null) + { + this.fSelectionStartAddress = address; + Point cellPosition = getCellLocation(address); + + if (cellPosition != null) + { + int offset = x - cellPosition.x; + fSelectionStartAddressSubPosition = offset / getCellCharacterWidth(); + } + + fRendering.getSelection().clear(); + fRendering.getSelection().setStart(address.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())), address); + fSelectionStarted = true; + + new CopyAction(fRendering, DND.SELECTION_CLIPBOARD).run(); + } + } + catch (DebugException e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_START_SELECTION"), e); //$NON-NLS-1$ + } + } + + // End selection + + protected void endSelection(int x, int y) + { + appendSelection(x, y); + fSelectionInProgress = false; + } + + protected void appendSelection(int x, int y) + { + try + { + if (this.fSelectionStartAddress == null) return; + + BigInteger address = getViewportAddress(x / getCellWidth(), y / getCellHeight()); + + if (address.compareTo(this.fSelectionStartAddress) == 0) + { + // Sub-cell selection + + Point cellPosition = getCellLocation(address); + int offset = x - cellPosition.x; + int subCellCharacterPosition = offset / getCellCharacterWidth(); + + if (Math.abs(subCellCharacterPosition - this.fSelectionStartAddressSubPosition) > this.getCellCharacterCount() / 4) + { + fRendering.getSelection().setEnd(address.add(BigInteger.valueOf((fRendering.getFPDataType().getByteLength()))), address); + } + else + { + fRendering.getSelection().setEnd(null, null); + } + } + else + { + fRendering.getSelection().setEnd(address.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())), address); + } + + if (fRendering.getSelection().getEnd() != null) + { + this.fCaretAddress = fRendering.getSelection().getEnd(); + this.fSubCellCaretPosition = 0; + } + + updateTheCaret(); + + new CopyAction(fRendering, DND.SELECTION_CLIPBOARD).run(); + } + catch (Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_APPEND_SELECTION"), e); //$NON-NLS-1$ + } + } + + protected void paint(PaintEvent pe) + { + fRowCount = getBounds().height / getCellHeight(); + + if (fRendering.isDirty()) + { + fRendering.setDirty(false); + fRendering.refresh(); + } + } + + abstract protected BigInteger getViewportAddress(int col, int row) throws DebugException; + + protected Point getCellLocation(BigInteger address) + { + return null; + } + + protected String getCellText(MemoryByte bytes[]) + { + return null; + } + + abstract protected int getCellWidth(); + + abstract protected int getCellCharacterCount(); + + @Override + public void setFont(Font font) + { + super.setFont(font); + fCharacterWidth = -1; + fCellHeight = -1; + fTextHeight = -1; + } + + private int fCellHeight = -1; // called often, cache + + protected int getCellHeight() + { + if (fCellHeight == -1) + { + fCellHeight = getCellTextHeight() + (fRendering.getCellPadding() * 2); + } + + return fCellHeight; + } + + private int fCharacterWidth = -1; // called often, cache + + protected int getCellCharacterWidth() + { + if (fCharacterWidth == -1) + { + GC gc = new GC(this); + gc.setFont(fRendering.getFont()); + fCharacterWidth = gc.getAdvanceWidth('F'); + gc.dispose(); + } + + return fCharacterWidth; + } + + private int fTextHeight = -1; // called often, cache + + protected int getCellTextHeight() + { + if (fTextHeight == -1) + { + GC gc = new GC(this); + gc.setFont(fRendering.getFont()); + FontMetrics fontMetrics = gc.getFontMetrics(); + fTextHeight = fontMetrics.getHeight(); + gc.dispose(); + } + return fTextHeight; + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAddressPane.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAddressPane.java new file mode 100644 index 00000000000..3e7ff179772 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPAddressPane.java @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +import org.eclipse.debug.core.DebugException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.FontMetrics; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +public class FPAddressPane extends FPAbstractPane +{ + final int bytesPerColumn = fRendering.getFPDataType().getByteLength(); + + public FPAddressPane(Rendering parent) + { + super(parent); + } + + @Override + protected BigInteger getViewportAddress(int col, int row) throws DebugException + { + BigInteger address = fRendering.getViewportStartAddress(); +// address = address.add(BigInteger.valueOf((row * fRendering.getColumnCount() + col) * fRendering.getAddressesPerColumn())); + address = address.add(BigInteger.valueOf((row * fRendering.getColumnCount() + col) * fRendering.getFPDataType().getByteLength())); + return address; + } + + @Override + protected void appendSelection(int x, int y) + { + try + { + if (this.fSelectionStartAddress == null) return; + + BigInteger address = getViewportAddress(x / getCellWidth(), y / getCellHeight()); + + if (address.compareTo(this.fSelectionStartAddress) == 0) + { + // The address hasn't changed + + fRendering.getSelection().setEnd(null, null); + } + else + { + // The address has changed + + fRendering.getSelection().setEnd(address.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength() * fRendering.getColumnCount())), address); + } + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_APPEND_SELECTION"), e); //$NON-NLS-1$ + } + } + + @Override + public Point computeSize(int wHint, int hHint) + { + return new Point(getCellWidth() + fRendering.getRenderSpacing(), 100); + } + + @Override + protected int getCellCharacterCount() + { + // Two characters per byte of HEX address + + return fRendering.getAddressBytes() * 2 + 2; // 0x + } + + @Override + protected int getCellWidth() + { + GC gc = new GC(this); + StringBuffer buf = new StringBuffer(); + for(int index = 0; index < getCellCharacterCount(); index++) + buf.append("0"); //$NON-NLS-1$ + int width = gc.textExtent(buf.toString()).x; + gc.dispose(); + return width; + } + + private int getColumnCount() + { + return 0; + } + + private BigInteger getCellAddressAt(int x, int y) throws DebugException + { + BigInteger address = fRendering.getViewportStartAddress(); + + int col = x / getCellWidth(); + int row = y / getCellHeight(); + + if(col > getColumnCount()) + return null; + + address = address.add(BigInteger.valueOf(row * fRendering.getColumnCount() * fRendering.getAddressesPerColumn() / fRendering.getBytesPerCharacter())); + address = address.add(BigInteger.valueOf(col * fRendering.getAddressesPerColumn())); + + return address; + } + + @Override + protected Point getCellLocation(BigInteger cellAddress) + { + try + { + BigInteger address = fRendering.getViewportStartAddress(); + + int cellOffset = cellAddress.subtract(address).intValue(); + + cellOffset *= fRendering.getAddressableSize(); + + if(fRendering.getColumnCount() == 0) // avoid divide by zero + return new Point(0,0); + + int row = cellOffset / (fRendering.getColumnCount() * fRendering.getCharsPerColumn() / fRendering.getBytesPerCharacter()); + cellOffset -= row * fRendering.getColumnCount() * fRendering.getCharsPerColumn() / fRendering.getBytesPerCharacter(); + int col = cellOffset / fRendering.getCharsPerColumn() / fRendering.getBytesPerCharacter(); + + int x = col * getCellWidth() + fRendering.getCellPadding(); + int y = row * getCellHeight() + fRendering.getCellPadding(); + + return new Point(x, y); + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_DETERMINE_CELL_LOCATION"), e); //$NON-NLS-1$ + return null; + } + } + + @Override + protected int getNumberOfBytesRepresentedByColumn() + { + return fRendering.getBytesPerRow(); + } + + @Override + protected void positionCaret(int x, int y) + { + try + { + BigInteger cellAddress = getCellAddressAt(x, y); + if(cellAddress != null) + { + Point cellPosition = getCellLocation(cellAddress); + + int offset = x - cellPosition.x; + int x2 = offset / getCellCharacterWidth(); + + if(x2 >= this.getCellCharacterCount()) + { + cellAddress = cellAddress.add(BigInteger.valueOf(this.getNumberOfBytesRepresentedByColumn())); + x2 = 0; + cellPosition = getCellLocation(cellAddress); + } + + fCaret.setLocation(cellPosition.x + x2 * getCellCharacterWidth(), cellPosition.y); + + this.fCaretAddress = cellAddress; + this.fSubCellCaretPosition = x2; + setCaretAddress(fCaretAddress); + } + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$ + } + } + + @Override + protected void paint(PaintEvent pe) + { + super.paint(pe); + + GC gc = pe.gc; + + FontMetrics fontMetrics = gc.getFontMetrics(); + int textHeight = fontMetrics.getHeight(); + int cellHeight = textHeight + (fRendering.getCellPadding() * 2); + final int memBytesPerCol = fRendering.getFPDataType().getByteLength(); + + try + { + BigInteger start = fRendering.getViewportStartAddress(); + + for(int index = 0; index < this.getBounds().height / cellHeight; index++) + { + BigInteger memAddress = start.add(BigInteger.valueOf(index * fRendering.getColumnCount() * memBytesPerCol)); + gc.setForeground(fRendering.getFPRendering().getColorText()); + + // Highlight the selected addresses if necessary; otherwise use the standard foreground/background colors + + if (fRendering.getSelection().isSelected(memAddress)) + { + gc.setBackground(fRendering.getFPRendering().getColorSelection()); + gc.fillRectangle(fRendering.getCellPadding() * 2, cellHeight * index, getCellWidth(), cellHeight); + gc.setForeground(fRendering.getFPRendering().getColorBackground()); + } + else + { + gc.setBackground(fRendering.getFPRendering().getColorBackground()); + gc.fillRectangle(fRendering.getCellPadding() * 2, cellHeight * index, getCellWidth(), cellHeight); + // Allow subclass to override this method to do its own coloring + applyCustomColor(gc); + } + + gc.drawText(fRendering.getAddressString(memAddress), + fRendering.getCellPadding() * 2, cellHeight * index + fRendering.getCellPadding()); + } + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_PAINT"), e); //$NON-NLS-1$ + } + } + + // Allow subclass to override this method to do its own coloring + protected void applyCustomColor(GC gc) + { + gc.setForeground(fRendering.getFPRendering().getColorText()); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDataPane.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDataPane.java new file mode 100644 index 00000000000..2ee7bce1ced --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDataPane.java @@ -0,0 +1,399 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +import org.eclipse.debug.core.DebugException; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Point; + +public class FPDataPane extends FPAbstractPane +{ + public FPDataPane(Rendering parent) + { + super(parent); + } + + // Returns the representation of the given memory bytes as a scientific notation string + + protected String bytesToSciNotation(FPMemoryByte[] bytes) + { + return fRendering.sciNotationString(bytes, fRendering.getFPDataType(), fRendering.isDisplayLittleEndian()); + } + + // Cell editing: Accumulate text entry characters, replacing or inserting them at the current cursor position + + @Override + protected void editCell(BigInteger cellAddress, int subCellPosition, char character) + { + try + { + // Switch to cell edit mode if not we're not currently in the middle of an edit + + if (!fRendering.isEditingCell()) + { + // Calculate the memory address from the cell address + + BigInteger vpStart = fRendering.getViewportStartAddress(); + BigInteger colChars = BigInteger.valueOf(fRendering.getCharsPerColumn()); + BigInteger dtBytes = BigInteger.valueOf(fRendering.getFPDataType().getByteLength()); + BigInteger memoryAddress = vpStart.add(((cellAddress.subtract(vpStart)).divide(colChars)).multiply(dtBytes)); + + if (!fRendering.insertMode()) + { + // Overstrike/overwrite mode: Enter cell-edit mode; start with the current cell contents. + + fRendering.startCellEditing(cellAddress, memoryAddress, bytesToSciNotation(fRendering.getBytes(cellAddress, fRendering.getFPDataType().getByteLength()))); + } + else + { + // Insert/Replace mode: Clear the current cell contents; start + // with a blank string. Move the caret to the start of the cell. + + fRendering.startCellEditing(cellAddress, memoryAddress, FPutilities.fillString(fRendering.getCharsPerColumn(), ' ')); + + subCellPosition = 0; + Point cellCoordinates = getCellLocation(cellAddress); + positionCaret(cellCoordinates.x, cellCoordinates.y); + fCaret.setVisible(true); + } + } + + // Validate the current string: Only one decimal point and exponent character ('e' or 'E') is allowed. Number + // signs may be present up to two times - once for the number and once for the exponent, and may occur at the + // very beginning of a number or immediately after the exponent character. If an entry violates a rule, do not + // echo the character (implicitly, through replacement and re-paint) and do not advance the cursor. + + String cellString = fRendering.getEditBuffer().toString().toLowerCase(); + + // Check to see if a second decimal point or exponent was entered + + if ((character == '.' && FPutilities.countMatches(cellString, ".") > 0 && cellString.indexOf('.') != subCellPosition) || //$NON-NLS-1$ + (character == 'e' && FPutilities.countMatches(cellString, "e") > 0 && cellString.indexOf('e') != subCellPosition)) //$NON-NLS-1$ + return; + + // Check to see if more than two number signs have been entered + + if ((character == '+' && FPutilities.countMatches(cellString, "+") > 1) || //$NON-NLS-1$ + (character == '-' && FPutilities.countMatches(cellString, "-") > 1)) //$NON-NLS-1$ + return; + + // We've passed the previous checks: Make the character substitution, if possible. + // Advance the cursor as long as we're inside the column. Re-paint the view. + + if (subCellPosition < fRendering.getEditBuffer().length()) + fRendering.getEditBuffer().setCharAt(subCellPosition, character); + + if (subCellPosition < fRendering.getCharsPerColumn()) + advanceCursor(); + + redraw(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + // Returns cell width, in pixels + + @Override + protected int getCellWidth() + { + return getCellCharacterCount() * getCellCharacterWidth() + (fRendering.getCellPadding() * 2); + } + + @Override + protected int getCellCharacterCount() + { + return fRendering.getCharsPerColumn(); + } + + @Override + public Point computeSize(int wHint, int hHint) + { + return new Point(fRendering.getColumnCount() * getCellWidth() + fRendering.getRenderSpacing(), 100); + } + + private BigInteger getCellAddressAt(int x, int y) throws DebugException + { + BigInteger address = fRendering.getViewportStartAddress(); + + int col = x / getCellWidth(); + int row = y / getCellHeight(); + + if (col >= fRendering.getColumnCount()) + return null; + + address = address.add(BigInteger.valueOf(row * fRendering.getColumnCount() * fRendering.getFPDataType().getByteLength())); + address = address.add(BigInteger.valueOf(col * fRendering.getFPDataType().getByteLength())); + + return address; + } + + // Return a Point representing the cell address + + @Override + protected Point getCellLocation(BigInteger cellAddress) + { + try + { + BigInteger address = fRendering.getViewportStartAddress(); + + int cellOffset = cellAddress.subtract(address).intValue(); + cellOffset *= fRendering.getAddressableSize(); + + int row = cellOffset / (fRendering.getColumnCount() * fRendering.getFPDataType().getByteLength()); + cellOffset -= row * fRendering.getColumnCount() * fRendering.getFPDataType().getByteLength(); + int col = cellOffset / fRendering.getFPDataType().getByteLength(); + + int x = col * getCellWidth() + fRendering.getCellPadding(); + int y = row * getCellHeight() + fRendering.getCellPadding(); + + return new Point(x, y); + } + catch (Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_DETERMINE_CELL_LOCATION"), e); //$NON-NLS-1$ + return null; + } + } + + @Override + protected void positionCaret(int x, int y) + { + try + { + BigInteger cellAddress = getCellAddressAt(x, y); + + if (cellAddress != null) + { + Point cellPosition = getCellLocation(cellAddress); + int offset = x - cellPosition.x; + int subCellCharacterPosition = offset / getCellCharacterWidth(); + + if (subCellCharacterPosition == this.getCellCharacterCount()) + { + cellAddress = cellAddress.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())); + subCellCharacterPosition = 0; + cellPosition = getCellLocation(cellAddress); + } + + fCaret.setLocation(cellPosition.x + subCellCharacterPosition * getCellCharacterWidth(), cellPosition.y); + + this.fCaretAddress = cellAddress; + this.fSubCellCaretPosition = subCellCharacterPosition; + setCaretAddress(fCaretAddress); + } + } + catch (Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_POSITION_CURSOR"), e); //$NON-NLS-1$ + } + } + + @Override + protected BigInteger getViewportAddress(int col, int row) throws DebugException + { + BigInteger address = fRendering.getViewportStartAddress(); + address = address.add(BigInteger.valueOf((row * fRendering.getColumnCount() + col) * fRendering.getFPDataType().getByteLength())); + + return address; + } + + @Override + protected void paint(PaintEvent pe) + { + super.paint(pe); + // Allow subclasses to override this method to do their own painting + doPaintData(pe); + } + + // Display text in the cell + + + protected void doPaintData(PaintEvent pe) + { + GC gc = pe.gc; + gc.setFont(fRendering.getFont()); + + int cellHeight = getCellHeight(); + int cellWidth = getCellWidth(); + int boundsHeight = this.getBounds().height; + int columns = fRendering.getColumnCount(); + + int cellX = 0; + int cellY = 0; + + String displayString = FPutilities.fillString(fRendering.getCharsPerColumn(), '.'); + + try + { + BigInteger vpStart = fRendering.getViewportStartAddress(); + BigInteger cellStartAddr = vpStart; + BigInteger memoryAddr = vpStart; + BigInteger cellEndAddr; + + for(int row = 0; row < boundsHeight / cellHeight; row++) + { + for (int column = 0; column < columns; column++) + { + // Set alternating colors for every other column and display the text + // FIXME: There is duplicate code in applyCustomColor() in this class + + if (isOdd(column)) + gc.setForeground(fRendering.getFPRendering().getColorText()); + else + gc.setForeground(fRendering.getFPRendering().getColorTextAlternate()); + + // Calculate the cell starting address and X/Y coordinates + + cellStartAddr = vpStart.add(BigInteger.valueOf((row * fRendering.getColumnCount() + column) * fRendering.getFPDataType().getByteLength())); + cellEndAddr = cellStartAddr.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength()).subtract(BigInteger.ONE)); + + cellX = (cellWidth * column) + fRendering.getCellPadding(); + cellY = (cellHeight * row ) + fRendering.getCellPadding(); + + // Cell editing: If we're in edit mode, change the cell color and then set the + // edit buffer as the string to display. Otherwise, just use the memory contents. + + if (fRendering.isEditingCell() && cellStartAddr.equals(fRendering.getCellEditAddress())) + { + gc.setForeground(fRendering.getFPRendering().getColorEdit()); + FPMemoryByte[] memoryBytes = fRendering.getBytes(cellStartAddr, fRendering.getFPDataType().getByteLength()); + for (FPMemoryByte memoryByte : memoryBytes) + memoryByte.setEdited(true); + applyCustomColor(gc, memoryBytes, column); + displayString = fRendering.getEditBuffer().toString(); + } + else + displayString = bytesToSciNotation(fRendering.getBytes(memoryAddr, fRendering.getFPDataType().getByteLength())); + + // Cell selection + + if (fRendering.getSelection().isSelected(cellStartAddr)) + { + gc.setBackground(fRendering.getFPRendering().getColorSelection()); + gc.fillRectangle(cellX, row * cellHeight, cellWidth, cellHeight); + gc.setForeground(fRendering.getFPRendering().getColorBackground()); + } + else + { + gc.setBackground(fRendering.getFPRendering().getColorBackground()); + gc.fillRectangle(cellX, row * cellHeight, cellWidth, cellHeight); + // Allow subclasses to override this method to do their own coloring + applyCustomColor(gc, fRendering.getBytes(cellStartAddr, fRendering.getFPDataType().getByteLength()), column); + } + + gc.drawText(displayString, cellX, cellY); + + // Move the caret if appropriate + + if (fCaretEnabled) + { + if(cellStartAddr.compareTo(fCaretAddress) <= 0 && cellEndAddr.compareTo(fCaretAddress) >= 0) + { + int x = cellWidth * column + fRendering.getCellPadding() + fSubCellCaretPosition * this.getCellCharacterWidth(); + int y = cellHeight * row + fRendering.getCellPadding(); + fCaret.setLocation(x, y); + } + } + + // For debugging + + if (fRendering.isDebug()) + gc.drawRectangle(cellX, cellY, cellWidth, cellHeight); + + // Increment the memory address by the length of the data type + + memoryAddr = memoryAddr.add(BigInteger.valueOf(fRendering.getFPDataType().getByteLength())); + } + } + } + catch(Exception e) + { + fRendering.logError(FPRenderingMessages.getString("FPRendering.FAILURE_PAINT"), e); //$NON-NLS-1$ + e.printStackTrace(); + } + } + + // Allow subclasses to override this method to do their own coloring + + protected void applyCustomColor(GC gc, FPMemoryByte bytes[], int col) + { + // Check to see if any byte has been changed and whether we're actually in edit mode + + boolean anyByteEditing = false; + + for (int n = 0; n < bytes.length && !anyByteEditing; n++) + if (bytes[n].isEdited()) anyByteEditing = true; + + anyByteEditing = anyByteEditing && fRendering.isEditingCell(); + + // Even/odd column coloring + + if (isOdd(col)) + gc.setForeground(fRendering.getFPRendering().getColorText()); + else + gc.setForeground(fRendering.getFPRendering().getColorTextAlternate()); + + // Background + + gc.setBackground(fRendering.getFPRendering().getColorBackground()); + + if (anyByteEditing) + { + gc.setForeground(fRendering.getFPRendering().getColorEdit()); + } + else + { + boolean isColored = false; + + for (int index = 0; index < fRendering.getHistoryDepth() && !isColored; index++) + { + // TODO consider adding finer granularity? + + for (int n = 0; n < bytes.length; n++) + { + if (bytes[n].isChanged(index)) + { + if (index == 0) + gc.setForeground(fRendering.getFPRendering().getColorsChanged()[index]); + else + gc.setBackground(fRendering.getFPRendering().getColorsChanged()[index]); + + isColored = true; + break; + } + } + } + } + } + + // Draw a box around the specified cell + + public void highCellBox(BigInteger memoryAddress) + { +// if (fRendering.isDebug()) +// gc.drawRectangle(cellX, cellY, cellWidth, cellHeight); + } + + // Clear the box around the specified cell + + public void clearCellBox(BigInteger memoryAddress) + { + + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDisplayCharacteristics.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDisplayCharacteristics.java new file mode 100644 index 00000000000..4fc155ee9a5 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPDisplayCharacteristics.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.Endian; +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.FPDataType; +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.Justification; + +public class FPDisplayCharacteristics +{ + private FPDataType dataType; + private Endian endian; + private int displayedPrecision; + private Justification justification; + + // Constructors + + FPDisplayCharacteristics() + { + // Default values + + this.dataType = FPDataType.FLOAT; + this.endian = Endian.LITTLE; + this.displayedPrecision = FPDataType.FLOAT.getDisplayedPrecision(); + this.justification = Justification.LEFT; + } + + public FPDisplayCharacteristics(FPDataType dataType, Endian endian, Justification justification) + { + this.dataType = dataType; + this.endian = endian; + this.justification = justification; + } + + // Getters and Setters + + public FPDataType getDataType() + { + return dataType; + } + + public void setDataType(FPDataType dataType) + { + this.dataType = dataType; + } + + public Endian getEndian() + { + return endian; + } + + public void setEndian(Endian endian) + { + this.endian = endian; + } + + public int getDisplayedPrecision() + { + return displayedPrecision; + } + + public void setDisplayedPrecision(int displayedPrecision) + { + this.displayedPrecision = displayedPrecision; + } + + public Justification getJustification() + { + return justification; + } + + public void setJustification(Justification justification) + { + this.justification = justification; + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemoryByte.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemoryByte.java new file mode 100644 index 00000000000..7810d41023f --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemoryByte.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +public interface FPIMemoryByte +{ + public boolean isEdited(); + public void setEdited(boolean edited); +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemorySelection.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemorySelection.java new file mode 100644 index 00000000000..aa3767917ca --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIMemorySelection.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +public interface FPIMemorySelection +{ + public boolean hasSelection(); + public boolean isSelected(BigInteger address); + public BigInteger getStart(); + public BigInteger getEnd(); + public BigInteger getStartLow(); + public void setStart(BigInteger high, BigInteger low); + public void setEnd(BigInteger high, BigInteger low); + public BigInteger getHigh(); + public BigInteger getLow(); + public void clear(); +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIViewportCache.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIViewportCache.java new file mode 100644 index 00000000000..41846f275b7 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPIViewportCache.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; + +import org.eclipse.debug.core.DebugException; + +public interface FPIViewportCache { + + public void dispose(); + public void refresh(); + public FPMemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException; + public void archiveDeltas(); + public void setEditedValue(BigInteger address, FPMemoryByte[] bytes); + public void clearEditBuffer(); + public void writeEditBuffer(); + public boolean containsEditedCell(BigInteger address); + // private void queueRequest(BigInteger startAddress, BigInteger endAddress); +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPMemoryByte.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPMemoryByte.java new file mode 100644 index 00000000000..9c5a18ede5a --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPMemoryByte.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.debug.core.model.MemoryByte; + +public class FPMemoryByte extends MemoryByte implements FPIMemoryByte +{ + private boolean isEdited = false; + + private boolean[] changeHistory = new boolean[0]; + + public FPMemoryByte() + { + super(); + } + + public FPMemoryByte(byte byteValue) + { + super(byteValue); + } + + public FPMemoryByte(byte byteValue, byte byteFlags) + { + super(byteValue, byteFlags); + } + + @Override + public boolean isEdited() + { + return isEdited; + } + + @Override + public void setEdited(boolean edited) + { + isEdited = edited; + } + + public boolean isChanged(int historyDepth) + { + return changeHistory.length > historyDepth && changeHistory[historyDepth]; + } + + public void setChanged(int historyDepth, boolean changed) + { + if(historyDepth >= changeHistory.length) + { + boolean newChangeHistory[] = new boolean[historyDepth + 1]; + System.arraycopy(changeHistory, 0, newChangeHistory, 0, changeHistory.length); + changeHistory = newChangeHistory; + } + + changeHistory[historyDepth] = changed; + + if(historyDepth == 0) + this.setChanged(changed); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPPreferenceConstants.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPPreferenceConstants.java new file mode 100644 index 00000000000..661837597d5 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPPreferenceConstants.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.FPDataType; +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.jface.preference.IPreferenceStore; + + +public class FPPreferenceConstants +{ + private FPPreferenceConstants() + { + // Prevent subclassing or instantiation + } + + /** + * Initialize preference default values. + * + * @param store + */ + public static void initializeDefaults(IPreferenceStore store) + { + // Set default values + + store.setDefault(IFPRConstants.ENDIAN_KEY, -1); // -1 = No default set + store.setDefault(IFPRConstants.DATATYPE_KEY, FPDataType.FLOAT.getValue()); + store.setDefault(IFPRConstants.FLOAT_DISP_KEY, 8); + store.setDefault(IFPRConstants.DOUBLE_DISP_KEY, 8); + store.setDefault(IFPRConstants.COLUMN_COUNT_KEY, Rendering.COLUMNS_AUTO_SIZE_TO_FIT); + store.setDefault(IFPRConstants.UPDATEMODE_KEY, Rendering.UPDATE_ALWAYS); + } + + public static class Initializer extends AbstractPreferenceInitializer + { + @Override + public void initializeDefaultPreferences() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + initializeDefaults(store); + } + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRendering.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRendering.java new file mode 100644 index 00000000000..cd4ebafc542 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRendering.java @@ -0,0 +1,1494 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.lang.reflect.Method; +import java.math.BigInteger; + +import org.eclipse.cdt.debug.core.model.provisional.IMemoryRenderingViewportProvider; +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.Endian; +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.FPDataType; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.debug.internal.ui.DebugPluginImages; +import org.eclipse.debug.internal.ui.DebugUIMessages; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.memory.IMemoryBlockConnection; +import org.eclipse.debug.internal.ui.memory.provisional.MemoryViewPresentationContext; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.debug.ui.memory.AbstractMemoryRendering; +import org.eclipse.debug.ui.memory.AbstractTableRendering; +import org.eclipse.debug.ui.memory.IMemoryRendering; +import org.eclipse.debug.ui.memory.IMemoryRenderingContainer; +import org.eclipse.debug.ui.memory.IMemoryRenderingSite; +import org.eclipse.debug.ui.memory.IRepositionableMemoryRendering; +import org.eclipse.debug.ui.memory.IResettableMemoryRendering; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.IInputValidator; +import org.eclipse.jface.dialogs.InputDialog; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.IBasicPropertyConstants; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.eclipse.ui.progress.UIJob; + + +/** + * A memory rendering displaying memory in a floating point memory view look and + * feel, optimized for minimal IO traffic. + * <p> + * requirements of the debug model implementation: - An IMemoryBlockExtension is + * required. + * + * Since it is not possible to size the memory block to match the size of the + * viewport, memory block change notification is not useful. Such events are + * ignored by this rendering. + */ + +@SuppressWarnings({ "restriction" }) +public class FPRendering extends AbstractMemoryRendering + implements IRepositionableMemoryRendering, IResettableMemoryRendering, IMemoryRenderingViewportProvider, IModelChangedListener +{ + protected Rendering fRendering; + protected Action actionDisplayBigEndian; + protected Action actionDisplayLittleEndian; + protected Action actionDisplayFloatingPoint; + + private IWorkbenchAdapter fWorkbenchAdapter; + private IMemoryBlockConnection fConnection; + + private final static int MAX_MENU_COLUMN_COUNT = 8; + + Action actionFloatingPoint32 = null; + Action actionFloatingPoint64 = null; + + Action actionDisplay4Digits = null; + Action actionDisplay8Digits = null; + Action actionDisplay16Digits = null; + + // Constructor + + public FPRendering(String id) + { + super(id); + + JFaceResources.getFontRegistry().addListener(new IPropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent event) + { + if (event.getProperty().equals(IInternalDebugUIConstants.FONT_NAME)) + { + FPRendering.this.fRendering.handleFontPreferenceChange(JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME)); + } + } + }); + + this.addPropertyChangeListener(new IPropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent event) + { + IMemoryRendering sourceRendering = (IMemoryRendering) event.getSource(); + if (!sourceRendering.getMemoryBlock().equals(getMemoryBlock())) + return; + + Object address = event.getNewValue(); + + if (event.getProperty().equals(AbstractTableRendering.PROPERTY_SELECTED_ADDRESS) && address instanceof BigInteger) + { + FPRendering.this.fRendering.ensureVisible((BigInteger) address); + } + } + }); + + FPRenderingPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent event) + { + disposeColors(); + allocateColors(); + applyPreferences(); + } + }); + + DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(new IPropertyChangeListener() + { + @Override + public void propertyChange(PropertyChangeEvent event) + { + if (event.getProperty().equals(IDebugUIConstants.PREF_PADDED_STR)) + { + if (FPRendering.this.fRendering != null) + { + setRenderingPadding((String) event.getNewValue()); + FPRendering.this.fRendering.redrawPanes(); + } + } + } + }); + } + + static int paddingCounter = 0; + + void setRenderingPadding(String padding) + { + if (padding == null || padding.length() == 0) padding = " "; //$NON-NLS-1$ + FPRendering.this.fRendering.setPaddingString(padding); + } + + protected void logError(String message, Exception e) + { + Status status = new Status(IStatus.ERROR, getRenderingId(), DebugException.INTERNAL_ERROR, message, e); + FPRenderingPlugin.getDefault().getLog().log(status); + } + + BigInteger fBigBaseAddress; // Memory base address + private BigInteger fStartAddress; // Starting address + private BigInteger fEndAddress; // Ending address + private int fAddressableSize; // Memory block size + private int fAddressSize; // Size of address + + /* + * @see org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener#modelChanged(org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta, org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy) + */ + @Override + public void modelChanged(IModelDelta delta, IModelProxy proxy) + { + /* + * The event model in the traditional renderer is written to expect a suspend first + * which will cause it to save its current data set away in an archive. Then when + * the state change comes through it will compare and refresh showing a difference. + */ + int flags = delta.getFlags(); + if ( ( flags & IModelDelta.STATE ) != 0 ) { + fRendering.handleSuspend(false); + } + + fRendering.handleChange(); + } + + /* + * We use the model proxy which is supplied by the TCF implementation to provide the knowledge of memory + * change notifications. The older backends ( the reference model, Wind River Systems Inc. ) are written + * to generate the Debug Model events. TCF follows the "ModelDelta/IModelProxy" implementation that the + * platform renderers use. So this implementation acts as a shim. If the older Debug Events come in then + * fine. If the newer model deltas come in fine also. + */ + IModelProxy fModel; + + @Override + public void dispose() + { + /* + * We use the UI dispatch thread to protect the proxy information. Even though I believe the + * dispose routine is always called in the UI dispatch thread. I am going to make sure. + */ + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + if ( fModel != null ) { + fModel.removeModelChangedListener(FPRendering.this); + fModel.dispose(); + } + }}); + + if(this.fRendering != null) + this.fRendering.dispose(); + disposeColors(); + super.dispose(); + } + + @Override + public void init(final IMemoryRenderingContainer container, final IMemoryBlock block) + { + super.init(container, block); + + /* + * Working with the model proxy must be done on the UI dispatch thread. + */ + final IModelProxyFactory factory = (IModelProxyFactory) DebugPlugin.getAdapter(block, IModelProxyFactory.class ); + if ( factory != null ) { + Display.getDefault().asyncExec(new Runnable() { + @Override + public void run() { + + /* + * The asynchronous model assumes we have an asynchronous viewer that has an IPresentationContext + * to represent it. The Platform memory subsystem provides a way to create one without a viewewr. + */ + IMemoryRenderingSite site = container.getMemoryRenderingSite(); + MemoryViewPresentationContext context = new MemoryViewPresentationContext(site, container, FPRendering.this); + + /* + * Get a new proxy and perform the initialization sequence so we are known the + * the model provider. + */ + fModel = factory.createModelProxy(block, context); + fModel.installed(null); + fModel.addModelChangedListener(FPRendering.this); + + }}); + } + + try + { + fBigBaseAddress = ((IMemoryBlockExtension) block).getBigBaseAddress(); + } + catch (DebugException de) + { + logError(FPRenderingMessages.getString("FPRendering.FAILURE_RETRIEVE_BASE_ADDRESS"), de); //$NON-NLS-1$ + } + + try + { + fAddressableSize = ((IMemoryBlockExtension) block).getAddressableSize(); + } + catch (DebugException de) + { + fAddressableSize = 1; + } + + try + { + fStartAddress = ((IMemoryBlockExtension) block).getMemoryBlockStartAddress(); + } + catch (DebugException de) + { + fStartAddress = null; + logError(FPRenderingMessages.getString("FPRendering.FAILURE_RETRIEVE_START_ADDRESS"), de); //$NON-NLS-1$ + } + + try + { + fAddressSize = ((IMemoryBlockExtension) block).getAddressSize(); + } + catch (DebugException e) + { + fAddressSize = 0; + } + + BigInteger endAddress; + try + { + endAddress = ((IMemoryBlockExtension) block).getMemoryBlockEndAddress(); + if (endAddress != null) + fEndAddress = endAddress; + } + catch (DebugException e) + { + fEndAddress = null; + } + + if (fEndAddress == null) + { + int addressSize; + try + { + addressSize = ((IMemoryBlockExtension) block).getAddressSize(); + } + catch (DebugException e) + { + addressSize = 4; + } + + endAddress = BigInteger.valueOf(2); + endAddress = endAddress.pow(addressSize * 8); + endAddress = endAddress.subtract(BigInteger.ONE); + fEndAddress = endAddress; + } + + // default to MAX_VALUE if we have trouble getting the end address + if (fEndAddress == null) + fEndAddress = BigInteger.valueOf(Integer.MAX_VALUE); + } + + public BigInteger getBigBaseAddress() + { + return fBigBaseAddress; + } + + public BigInteger getMemoryBlockStartAddress() + { + return fStartAddress; + } + + public BigInteger getMemoryBlockEndAddress() + { + return fEndAddress; + } + + public int getAddressableSize() + { + return fAddressableSize; + } + + public int getAddressSize() + { + return fAddressSize; + } + + @Override + public Control createControl(Composite parent) + { + allocateColors(); + + this.fRendering = new Rendering(parent, this); + + applyPreferences(); + + createMenus(); + + if (actionFloatingPoint32.isChecked()) + actionDisplay16Digits.setEnabled(false); + else + actionDisplay16Digits.setEnabled(true); + + return this.fRendering; + } + + /* + * We are duplicating the reference to the GoToAddress command because it is private in the platform. + * This is not going to change at this point so just live with it. + */ + private static final String ID_GO_TO_ADDRESS_COMMAND = "org.eclipse.debug.ui.command.gotoaddress"; //$NON-NLS-1$ + private AbstractHandler fGoToAddressHandler; + + @Override + public void activated() + { + super.activated(); + + IWorkbench workbench = PlatformUI.getWorkbench(); + ICommandService commandSupport = (ICommandService) workbench.getAdapter(ICommandService.class); + + if (commandSupport != null) + { + Command gotoCommand = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND); + + if (fGoToAddressHandler == null) + { + fGoToAddressHandler = new AbstractHandler() + { + @Override + public Object execute(ExecutionEvent event) throws ExecutionException + { + return null; + } + }; + } + gotoCommand.setHandler(fGoToAddressHandler); + } + } + + @Override + public void deactivated() + { + IWorkbench workbench = PlatformUI.getWorkbench(); + ICommandService commandSupport = (ICommandService) workbench.getAdapter(ICommandService.class); + + if (commandSupport != null) + { + // remove handler + Command command = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND); + command.setHandler(null); + } + + super.deactivated(); + } + + public void setSelection(BigInteger start, BigInteger end) + { + fRendering.getSelection().setStart(start, start); + fRendering.getSelection().setEnd(end, end); + } + + public void gotoAddress(final BigInteger address) + { + this.fRendering.gotoAddress(address); + } + + public void updateRenderingLabels() + { + UIJob job = new UIJob("updateLabels") { //$NON-NLS-1$ + @SuppressWarnings("synthetic-access") + @Override + public IStatus runInUIThread(IProgressMonitor monitor) + { + + // Update tab labels + String fLabel = getLabel(); + firePropertyChangedEvent(new PropertyChangeEvent(FPRendering.this, IBasicPropertyConstants.P_TEXT, null, fLabel)); + return Status.OK_STATUS; + } + }; + job.setSystem(true); + job.schedule(); + } + + private Color colorBackground; + private Color colorChanged; + private Color colorsChanged[] = null; + private Color colorEdit; + private Color colorSelection; + private Color colorText; + private Color colorTextAlternate; + + public void allocateColors() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + colorBackground = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_BACKGROUND)); + colorChanged = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_CHANGED)); + colorEdit = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_EDIT)); + colorSelection = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_SELECTION)); + colorText = new Color(Display.getDefault(), PreferenceConverter.getColor(store, FPRenderingPreferenceConstants.MEM_COLOR_TEXT)); + + // alternate cell color + Color textColor = getColorText(); + int red = textColor.getRed(); + int green = textColor.getGreen(); + int blue = textColor.getBlue(); + + float scale = store.getInt(FPRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS); + + red = (int) Math.min(red + ((255 - red) / 10) * scale, 255); + green = (int) Math.min(green + ((255 - green) / 10) * scale, 255); + blue = (int) Math.min(blue + ((255 - blue) / 10) * scale, 255); + + colorTextAlternate = new Color(Display.getDefault(), new RGB(red, green, blue)); + } + + public void disposeColors() + { + if (colorBackground != null) colorBackground.dispose(); + colorBackground = null; + + if (colorChanged != null) colorChanged.dispose(); + colorChanged = null; + + if (colorEdit != null) colorEdit.dispose(); + colorEdit = null; + + if (colorSelection != null) colorSelection.dispose(); + colorSelection = null; + + if (colorText != null) colorText.dispose(); + colorText = null; + + if (colorTextAlternate != null) colorTextAlternate.dispose(); + colorTextAlternate = null; + + disposeChangedColors(); + } + + public void applyPreferences() + { + if (fRendering != null && !fRendering.isDisposed()) + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + fRendering.setHistoryDepth(store.getInt(FPRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT)); + fRendering.setBackground(getColorBackground()); + + FPAbstractPane panes[] = fRendering.getRenderingPanes(); + for (int index = 0; index < panes.length; index++) + panes[index].setBackground(getColorBackground()); + + setRenderingPadding(FPRenderingPlugin.getDefault().getPreferenceStore().getString(IDebugUIConstants.PREF_PADDED_STR)); + + fRendering.redrawPanes(); + } + } + + public Color getColorBackground() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + if (store.getBoolean(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND)) + return Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + + return colorBackground; + } + + public Color getColorChanged() + { + return colorChanged; + } + + private void disposeChangedColors() + { + if (colorsChanged != null) + for (int index = 0; index < colorsChanged.length; index++) + colorsChanged[index].dispose(); + colorsChanged = null; + } + + public Color[] getColorsChanged() + { + if (colorsChanged != null && colorsChanged.length != fRendering.getHistoryDepth()) + { + disposeChangedColors(); + } + + if (colorsChanged == null) + { + colorsChanged = new Color[fRendering.getHistoryDepth()]; + colorsChanged[0] = colorChanged; + int shades = fRendering.getHistoryDepth() + 4; + int red = (255 - colorChanged.getRed()) / shades; + int green = (255 - colorChanged.getGreen()) / shades; + int blue = (255 - colorChanged.getBlue()) / shades; + for (int index = 1; index < fRendering.getHistoryDepth(); index++) + { + colorsChanged[index] = new Color(colorChanged.getDevice(), colorChanged.getRed() + ((shades - index) * red), colorChanged.getGreen() + + ((shades - index) * green), colorChanged.getBlue() + ((shades - index) * blue)); + } + } + + return colorsChanged; + } + + public Color getColorEdit() + { + return colorEdit; + } + + public Color getColorSelection() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + if (store.getBoolean(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION)) + return Display.getDefault().getSystemColor(SWT.COLOR_LIST_SELECTION); + + return colorSelection; + } + + public Color getColorText() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + if (store.getBoolean(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT)) + return Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND); + + return colorText; + } + + public Color getColorTextAlternate() + { + return colorTextAlternate; + } + + // Menu creation + + public void createMenus() + { + // Add the menu to each of the rendering panes + + Control[] renderingControls = this.fRendering.getRenderingPanes(); + + for (int index = 0; index < renderingControls.length; index++) + super.createPopupMenu(renderingControls[index]); + + super.createPopupMenu(this.fRendering); + + // Copy + + final Action copyAction = new CopyAction(this.fRendering); + + // Copy address + + final Action copyAddressAction = new Action(FPRenderingMessages.getString("FPRendering.COPY_ADDRESS")) //$NON-NLS-1$ + { + @Override + public void run() + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + FPRendering.this.fRendering.copyAddressToClipboard(); + } + }); + } + }; + + // Reset to base address + + final Action gotoBaseAddressAction = new Action(FPRenderingMessages.getString("FPRendering.RESET_TO_BASE_ADDRESS")) //$NON-NLS-1$ + { + @Override + public void run() + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + FPRendering.this.fRendering.gotoAddress(FPRendering.this.fRendering.fBaseAddress); + } + }); + } + }; + + // Refresh + + final Action refreshAction = new Action(FPRenderingMessages.getString("FPRendering.REFRESH")) //$NON-NLS-1$ + { + @Override + public void run() + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + // For compatibility with DSF update modes (hopefully this will either be replaced + // by an enhanced platform interface or the caching will move out of the data layer) + + try + { + Method m = fRendering.getMemoryBlock().getClass().getMethod("clearCache", new Class[0]); //$NON-NLS-1$ + if (m != null) + m.invoke(fRendering.getMemoryBlock(), new Object[0]); + } + catch (Exception e) + { + } + + FPRendering.this.fRendering.refresh(); + } + }); + } + }; + + // Little Endian + + actionDisplayLittleEndian = new Action(FPRenderingMessages.getString("FPRendering.ENDIAN_LITTLE"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setDisplayLittleEndian(true); + setRMCvalue(IFPRConstants.ENDIAN_KEY, Endian.LITTLE.getValue()); + } + }; + + // Big Endian + + actionDisplayBigEndian = new Action(FPRenderingMessages.getString("FPRendering.ENDIAN_BIG"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setDisplayLittleEndian(false); + setRMCvalue(IFPRConstants.ENDIAN_KEY, Endian.BIG.getValue()); + } + }; + + // Endian settings + + int endian = getRMCvalue(IFPRConstants.ENDIAN_KEY); + + endian = endian != -1 ? endian : (fRendering.isDisplayLittleEndian() ? Endian.LITTLE.getValue() : Endian.BIG.getValue()); + boolean le = (endian == Endian.LITTLE.getValue()); + + fRendering.setDisplayLittleEndian(le); + actionDisplayLittleEndian.setChecked(le); + actionDisplayBigEndian.setChecked(!le); + + // Float + + boolean dtFloat = getRMCvalue(IFPRConstants.DATATYPE_KEY) == FPDataType.FLOAT.getValue(); + this.fRendering.setFPDataType(dtFloat ? FPDataType.FLOAT : FPDataType.DOUBLE); + + actionFloatingPoint32 = new Action(FPRenderingMessages.getString("FPRendering.FLOATING_POINT_32"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setDisplayedPrecision(getRMCvalue(IFPRConstants.FLOAT_DISP_KEY)); + fRendering.setFPDataType(FPDataType.FLOAT); + setRMCvalue(IFPRConstants.DATATYPE_KEY, FPDataType.FLOAT.getValue()); + setSelections(); + } + }; + + // Double + + actionFloatingPoint64 = new Action(FPRenderingMessages.getString("FPRendering.FLOATING_POINT_64"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setDisplayedPrecision(getRMCvalue(IFPRConstants.DOUBLE_DISP_KEY)); + fRendering.setFPDataType(FPDataType.DOUBLE); + setRMCvalue(IFPRConstants.DATATYPE_KEY, FPDataType.DOUBLE.getValue()); + setSelections(); + } + }; + + // Displayed precision: 4 digits + + int savedPrecision = getDisplayedPrecision(); + + actionDisplay4Digits = new Action(FPRenderingMessages.getString("FPRendering.DISPLAYED_PRECISION_4"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setDisplayedPrecision(4); + setDisplayedPrecision(4); + } + }; + + if (savedPrecision == 4) + { + FPRendering.this.fRendering.setDisplayedPrecision(4); + actionDisplay4Digits.setChecked(savedPrecision == 4); + } + + // Displayed precision: 8 digits + + actionDisplay8Digits = new Action(FPRenderingMessages.getString("FPRendering.DISPLAYED_PRECISION_8"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setDisplayedPrecision(8); + setDisplayedPrecision(8); + } + }; + + if (savedPrecision == 8) + { + FPRendering.this.fRendering.setDisplayedPrecision(8); + actionDisplay8Digits.setChecked(savedPrecision == 8); + } + + // Displayed precision: 16 digits (doubles only) + + actionDisplay16Digits = new Action(FPRenderingMessages.getString("FPRendering.DISPLAYED_PRECISION_16"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setDisplayedPrecision(16); + setDisplayedPrecision(16); + } + }; + + if (savedPrecision == 16) + { + FPRendering.this.fRendering.setDisplayedPrecision(16); + actionDisplay16Digits.setChecked(savedPrecision == 16); + } + + // Set RMC selections based on datatype and displayed precision settings in effect + + setSelections(); + + // Columns + + int savedColumnCount = getRMCvalue(IFPRConstants.COLUMN_COUNT_KEY); + + final Action displayColumnCountAuto = new Action(FPRenderingMessages.getString("FPRendering.COLUMN_COUNT_AUTO"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setColumnsSetting(Rendering.COLUMNS_AUTO_SIZE_TO_FIT); + setRMCvalue(IFPRConstants.COLUMN_COUNT_KEY, Rendering.COLUMNS_AUTO_SIZE_TO_FIT); + } + }; + + boolean autoMode = savedColumnCount == Rendering.COLUMNS_AUTO_SIZE_TO_FIT; + displayColumnCountAuto.setChecked(autoMode); + + final Action[] displayColumnCounts = new Action[MAX_MENU_COLUMN_COUNT]; + + for (int index = 0, j = 1; index < MAX_MENU_COLUMN_COUNT; index++, j *= 2) + { + final int finali = j; + displayColumnCounts[index] = new Action(FPRenderingMessages.getString("FPRendering.COLUMN_COUNT_" + finali), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + FPRendering.this.fRendering.setColumnsSetting(finali); + setRMCvalue(IFPRConstants.COLUMN_COUNT_KEY, finali); + } + }; + displayColumnCounts[index].setChecked(fRendering.getColumnsSetting() == finali); + } + + // Set/clear column count selections as appropriate + + int countValue = getRMCvalue(IFPRConstants.COLUMN_COUNT_KEY); + + for (int index = 0; index < MAX_MENU_COLUMN_COUNT; index++) + displayColumnCounts[index].setChecked(countValue != Rendering.COLUMNS_AUTO_SIZE_TO_FIT && (countValue == (1 << index))); + + fRendering.setColumnsSetting(getRMCvalue(IFPRConstants.COLUMN_COUNT_KEY)); + + final Action displayColumnCountCustomValue = new Action("", IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + } + }; + + final Action displayColumnCountCustom = new Action(FPRenderingMessages.getString("FPRendering.COLUMN_COUNT_CUSTOM"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + InputDialog inputDialog = new InputDialog + ( + fRendering.getShell(), "Set Column Count", "Please enter column count", "", new IInputValidator() //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + { + @Override + public String isValid(String input) + { + try + { + int index = Integer.parseInt(input); + + if (index <= 0) + return "Please enter a positive integer"; //$NON-NLS-1$ + + if (index > 200) + return "Please enter a positive integer not greater than 200"; //$NON-NLS-1$ + } + catch (NumberFormatException x) + { + return "Please enter a positive integer"; //$NON-NLS-1$ + } + + return null; + } + } + ); + + if (inputDialog.open() != Window.OK) + { + this.setChecked(false); + int currentColumnSetting = FPRendering.this.fRendering.getColumnsSetting(); + + if (currentColumnSetting == Rendering.COLUMNS_AUTO_SIZE_TO_FIT) + displayColumnCountAuto.setChecked(true); + else + { + boolean currentCountIsCustom = true; + + for (int index = 0, j = 1; index < MAX_MENU_COLUMN_COUNT && currentCountIsCustom; index++, j *= 2) + { + currentCountIsCustom = (j != fRendering.getColumnsSetting()); + if (j == fRendering.getColumnsSetting()) + displayColumnCounts[index].setChecked(true); + } + + if (currentCountIsCustom) + displayColumnCountCustomValue.setChecked(true); + } + + return; + } + + int newColumnCount = -1; + + try + { + newColumnCount = Integer.parseInt(inputDialog.getValue()); + } + catch (NumberFormatException x) + { + assert false; + } + + boolean customIsOneOfStandardListChoices = false; + + for (int index = 0, j = 1; index < MAX_MENU_COLUMN_COUNT; index++, j *= 2) + { + if (newColumnCount == j) + { + customIsOneOfStandardListChoices = true; + FPRendering.this.fRendering.setColumnsSetting(newColumnCount); + setRMCvalue(IFPRConstants.COLUMN_COUNT_KEY, newColumnCount); + this.setChecked(false); + displayColumnCountCustomValue.setChecked(false); + displayColumnCounts[index].setChecked(true); + break; + } + } + + if (!customIsOneOfStandardListChoices) + { + FPRendering.this.fRendering.setColumnsSetting(newColumnCount); + setRMCvalue(IFPRConstants.COLUMN_COUNT_KEY, newColumnCount); + this.setChecked(false); + + displayColumnCountCustomValue.setChecked(true); + displayColumnCountCustomValue.setText(Integer.valueOf(fRendering.getColumnsSetting()).toString()); + } + } + }; + + // Check for a custom value: If we're not in "Auto Fill" mode, check for standard column sizes. + // If none of the standard sizes were entered, then it's a custom value; set it and display it. + + boolean customColumnCountSet = true; + countValue = getRMCvalue(IFPRConstants.COLUMN_COUNT_KEY); + + if (countValue != Rendering.COLUMNS_AUTO_SIZE_TO_FIT) + { + for (int index = 0; index < MAX_MENU_COLUMN_COUNT; index++) + { + // If the column count is one of the standard values, set flag to false and exit the loop + + if (countValue == (1 << index)) + { + customColumnCountSet = false; + break; + } + } + + if (customColumnCountSet) + { + FPRendering.this.fRendering.setColumnsSetting(countValue); + displayColumnCountCustomValue.setChecked(true); + displayColumnCountCustomValue.setText(Integer.valueOf(fRendering.getColumnsSetting()).toString()); + } + } + + // Add the right-mouse-click (RMC) context menu items + + getPopupMenuManager().addMenuListener(new IMenuListener() + { + @Override + public void menuAboutToShow(IMenuManager manager) + { + manager.add(new Separator()); + + MenuManager sub = new MenuManager(FPRenderingMessages.getString("FPRendering.PANES")); //$NON-NLS-1$ + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.ENDIAN")); //$NON-NLS-1$ + sub.add(actionDisplayBigEndian); + sub.add(actionDisplayLittleEndian); + manager.add(sub); + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.NUMBER_TYPE")); //$NON-NLS-1$ + sub.add(actionFloatingPoint32); + sub.add(actionFloatingPoint64); + manager.add(sub); + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.PRECISION")); //$NON-NLS-1$ + sub.add(actionDisplay4Digits); + sub.add(actionDisplay8Digits); + sub.add(actionDisplay16Digits); + manager.add(sub); + +// TODO: Add separator for FP group here: manager.add(new Separator()); + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.COLUMN_COUNT")); //$NON-NLS-1$ + sub.add(displayColumnCountAuto); + + for (int index = 0; index < displayColumnCounts.length; index++) + sub.add(displayColumnCounts[index]); + + boolean currentCountIsCustom = fRendering.getColumnsSetting() != 0; + + for (int index = 0, j = 1; index < MAX_MENU_COLUMN_COUNT && currentCountIsCustom; index++, j *= 2) + currentCountIsCustom = (j != fRendering.getColumnsSetting()); + + if (currentCountIsCustom) + sub.add(displayColumnCountCustomValue); + + sub.add(displayColumnCountCustom); + manager.add(sub); + + // Update modes + + int updateMode = getRMCvalue(IFPRConstants.UPDATEMODE_KEY); + + final Action updateAlwaysAction = new Action(FPRenderingMessages.getString("FPRendering.UPDATE_ALWAYS"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setUpdateMode(Rendering.UPDATE_ALWAYS); + setRMCvalue(IFPRConstants.UPDATEMODE_KEY, Rendering.UPDATE_ALWAYS); + } + }; + updateAlwaysAction.setChecked(updateMode == Rendering.UPDATE_ALWAYS); + + final Action updateOnBreakpointAction = new Action(FPRenderingMessages.getString("FPRendering.UPDATE_ON_BREAKPOINT"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setUpdateMode(Rendering.UPDATE_ON_BREAKPOINT); + setRMCvalue(IFPRConstants.UPDATEMODE_KEY, Rendering.UPDATE_ON_BREAKPOINT); + } + }; + updateOnBreakpointAction.setChecked(updateMode == Rendering.UPDATE_ON_BREAKPOINT); + + final Action updateManualAction = new Action(FPRenderingMessages.getString("FPRendering.UPDATE_MANUAL"), IAction.AS_RADIO_BUTTON) //$NON-NLS-1$ + { + @Override + public void run() + { + fRendering.setUpdateMode(Rendering.UPDATE_MANUAL); + setRMCvalue(IFPRConstants.UPDATEMODE_KEY, Rendering.UPDATE_MANUAL); + } + }; + updateManualAction.setChecked(updateMode == Rendering.UPDATE_MANUAL); + + // Add menu + + sub = new MenuManager(FPRenderingMessages.getString("FPRendering.UPDATEMODE")); //$NON-NLS-1$ + sub.add(updateAlwaysAction); + sub.add(updateOnBreakpointAction); + sub.add(updateManualAction); + manager.add(sub); + manager.add(new Separator()); + + BigInteger start = fRendering.getSelection().getStart(); + BigInteger end = fRendering.getSelection().getEnd(); + copyAction.setEnabled(start != null && end != null); + + manager.add(copyAction); + manager.add(copyAddressAction); + + manager.add(gotoBaseAddressAction); + manager.add(refreshAction); + manager.add(new Separator()); + manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); + } + }); + } + + // Set/clear selections as appropriate + + public void setSelections() + { + if (actionDisplay4Digits == null || actionDisplay8Digits == null || actionDisplay16Digits == null) return; + + // Enable/disable and set/clear menu RMC elements based on currently selected datatype + + boolean dtFloat = FPRendering.this.fRendering.getFPDataType() == FPDataType.FLOAT; + + actionDisplay16Digits.setEnabled(!dtFloat); + actionFloatingPoint32.setChecked(dtFloat); + actionFloatingPoint64.setChecked(!dtFloat); + + // Set/clear RMC elements based on displayed precision + + int displayedPrecision = getRMCvalue(dtFloat ? IFPRConstants.FLOAT_DISP_KEY : IFPRConstants.DOUBLE_DISP_KEY); + + actionDisplay4Digits.setChecked (displayedPrecision == 4); + actionDisplay8Digits.setChecked (displayedPrecision == 8); + actionDisplay16Digits.setChecked(displayedPrecision == 16); + } + + + @Override + public Control getControl() + { + return this.fRendering; + } + + // Selection is terminology for caret position + + @Override + public BigInteger getSelectedAddress() + { + FPIMemorySelection selection = fRendering.getSelection(); + if (selection == null || selection.getStart() == null) + return fRendering.getCaretAddress(); + + return selection.getStartLow(); + } + + @Override + public MemoryByte[] getSelectedAsBytes() + { + try + { + // default to the caret address and the cell count size + BigInteger startAddr = fRendering.getCaretAddress(); + int byteCount = fRendering.getCharsPerColumn(); + + // Now see if there's a selection + FPIMemorySelection selection = fRendering.getSelection(); + if (selection != null && selection.getStart() != null) + { + // The implementation is such that just having a caret somewhere (without multiple cells + // being selected) constitutes a selection, except for when the rendering is in its initial + // state, i.e. just because we get here doesn't mean the user has selected more than one cell. + + startAddr = getSelectedAddress(); + + if (selection.getHigh() != null) + byteCount = selection.getHigh().subtract(selection.getLow()).intValue() * fRendering.getAddressableSize(); + } + + return fRendering.getViewportCache().getBytes(startAddr, byteCount); + + } + catch (DebugException de) + { + return new MemoryByte[0]; + } + } + + @Override + public void goToAddress(final BigInteger address) throws DebugException + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + fRendering.gotoAddress(address); + } + }); + } + + protected void setTargetMemoryLittleEndian(boolean littleEndian) + { + // Once we actually read memory we can determine the endianess and need to set these actions accordingly. + actionDisplayBigEndian.setChecked(!littleEndian); + actionDisplayLittleEndian.setChecked(littleEndian); + + // When target endian changes, force display endian to track. User can then change display endian if desired. + fRendering.setDisplayLittleEndian(littleEndian); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class) + */ + @Override + public Object getAdapter(Class adapter) + { + if (adapter == IWorkbenchAdapter.class) + { + if (this.fWorkbenchAdapter == null) + { + this.fWorkbenchAdapter = new IWorkbenchAdapter() + { + @Override + public Object[] getChildren(Object o) + { + return new Object[0]; + } + + @Override + public ImageDescriptor getImageDescriptor(Object object) + { + return null; + } + + @Override + public String getLabel(Object o) + { + return FPRenderingMessages.getString("FPRendering.RENDERING_NAME"); //$NON-NLS-1$ + } + + @Override + public Object getParent(Object o) + { + return null; + } + }; + } + return this.fWorkbenchAdapter; + } + + if (adapter == IMemoryBlockConnection.class) + { + if (fConnection == null) + { + fConnection = new IMemoryBlockConnection() + { + @Override + public void update() + { + // update UI asynchronously + Display display = FPRenderingPlugin.getDefault().getWorkbench().getDisplay(); + display.asyncExec(new Runnable() + { + @Override + public void run() + { + try + { + if (fBigBaseAddress != FPRendering.this.fRendering.getMemoryBlock().getBigBaseAddress()) + { + fBigBaseAddress = FPRendering.this.fRendering.getMemoryBlock().getBigBaseAddress(); + FPRendering.this.fRendering.gotoAddress(fBigBaseAddress); + } + FPRendering.this.fRendering.refresh(); + } + catch (DebugException e) + { + } + } + }); + } + }; + } + + return fConnection; + } + + return super.getAdapter(adapter); + } + + @Override + public void resetRendering() throws DebugException + { + fRendering.gotoAddress(fRendering.fBaseAddress); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.debug.internal.core.model.provisional. + * IMemoryRenderingViewportProvider#getViewportAddress() + */ + @Override + public BigInteger getViewportAddress() + { + return fRendering.getViewportStartAddress(); + } + + // Persistence methods + + void setDisplayedPrecision(int precision) + { + // Save the appropriate displayed precision value, based on data type, in the store + + if (FPRendering.this.fRendering.getFPDataType() == FPDataType.FLOAT) + setRMCvalue(IFPRConstants.FLOAT_DISP_KEY, precision); + else + setRMCvalue(IFPRConstants.DOUBLE_DISP_KEY, precision); + } + + private int getDisplayedPrecision() + { + // Retrieve the persisted data value from the store + + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + FPDataType dataType = FPRendering.this.fRendering.getFPDataType(); + + if (store != null) + return store.getInt(dataType == FPDataType.FLOAT ? IFPRConstants.FLOAT_DISP_KEY : IFPRConstants.DOUBLE_DISP_KEY); + + // If there's nothing persisted, return the default precision for data type + + return dataType == FPDataType.FLOAT ? FPDataType.FLOAT.getDisplayedPrecision() : FPDataType.DOUBLE.getDisplayedPrecision(); + } + + void setRMCvalue(String key, int value) + { + // Save the specified key and int value + + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + if (store != null) store.setValue(key, value); + } + + int getRMCvalue(String key) + { + // Return the value for the specified key + + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + return (store != null) ? store.getInt(key) : 0; + } +} + +// Copy class + +class CopyAction extends Action +{ + // TODO for the sake of large copies, this action should probably read in + // blocks on a Job. + + private Rendering fRendering; + private int fType = DND.CLIPBOARD; + + public CopyAction(Rendering rendering) + { + this(rendering, DND.CLIPBOARD); + } + + @SuppressWarnings("restriction") // using platform's labels and images; acceptable build risk + public CopyAction(Rendering rendering, int clipboardType) + { + super(); + fType = clipboardType; + fRendering = rendering; + setText(DebugUIMessages.CopyViewToClipboardAction_title); + setToolTipText(DebugUIMessages.CopyViewToClipboardAction_tooltip); + setImageDescriptor(DebugPluginImages + .getImageDescriptor(IInternalDebugUIConstants.IMG_ELCL_COPY_VIEW_TO_CLIPBOARD)); + setHoverImageDescriptor(DebugPluginImages + .getImageDescriptor(IInternalDebugUIConstants.IMG_LCL_COPY_VIEW_TO_CLIPBOARD)); + setDisabledImageDescriptor(DebugPluginImages + .getImageDescriptor(IInternalDebugUIConstants.IMG_DLCL_COPY_VIEW_TO_CLIPBOARD)); + } + + @Override + public void run() + { + Clipboard clip = null; + final String PANE_SPACING = " "; //$NON-NLS-1$ + + try + { + clip = new Clipboard(fRendering.getDisplay()); + + BigInteger start = fRendering.getSelection().getStart(); + BigInteger end = fRendering.getSelection().getEnd(); + + if (end == null) return; // End will be null when there is nothing selected + + if (start.compareTo(end) > 0) + { + // Swap start and end + + BigInteger bigI = end; + end = start; + start = bigI; + } + + final FPDataType numberType = fRendering.getFPDataType(); + final int bytesPerColumn = numberType.getByteLength(); + final boolean isLittleEndian = fRendering.isTargetLittleEndian(); + final int columns = fRendering.getColumnCount(); + BigInteger lengthToRead = end.subtract(start); + + int rows = lengthToRead.divide(BigInteger.valueOf(columns * (fRendering.getFPDataType().getByteLength()))).intValue(); + + if (rows * columns * bytesPerColumn < lengthToRead.intValue()) rows++; + + StringBuffer buffer = new StringBuffer(); + + for (int row = 0; row < rows; row++) + { + BigInteger rowAddress = start.add(BigInteger.valueOf(row * columns * bytesPerColumn)); + + if (fRendering.getPaneVisible(Rendering.PANE_ADDRESS)) + { + buffer.append(fRendering.getAddressString(rowAddress)); + buffer.append(PANE_SPACING); + } + + if (fRendering.getPaneVisible(Rendering.PANE_DATA)) + { + for(int col = 0; col < columns; col++) + { + BigInteger cellAddress = rowAddress.add(BigInteger.valueOf(col * bytesPerColumn)); + + if (cellAddress.compareTo(end) < 0) + { + try + { + FPMemoryByte bytes[] = fRendering.getBytes(cellAddress, bytesPerColumn); + buffer.append(fRendering.sciNotationString(bytes, numberType, isLittleEndian)); + } + catch(DebugException de) + { + fRendering + .logError( + FPRenderingMessages + .getString("FPRendering.FAILURE_COPY_OPERATION"), de); //$NON-NLS-1$ + return; + } + } + else + { + for(int i = fRendering.getCharsPerColumn(); i > 0; i--) + buffer.append(' '); + } + + if (col != columns - 1) + buffer.append(' '); + } + } + + if (fRendering.getPaneVisible(Rendering.PANE_DATA)) + buffer.append(PANE_SPACING); + + buffer.append("\n"); //$NON-NLS-1$ + } + + if (buffer.length() > 0) + { + TextTransfer plainTextTransfer = TextTransfer.getInstance(); + clip.setContents(new Object[] { buffer.toString() }, new Transfer[] { plainTextTransfer }, fType); + } + } + finally + { + if (clip != null) + { + clip.dispose(); + } + } + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingMessages.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingMessages.java new file mode 100644 index 00000000000..88ab53aa05b --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingMessages.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class FPRenderingMessages +{ + private static final String BUNDLE_NAME = "org.eclipse.cdt.debug.ui.memory.floatingpoint.messages"; //$NON-NLS-1$ + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + private FPRenderingMessages() + { + } + + public static String getString(String key) + { + // TODO Auto-generated method stub + try + { + return RESOURCE_BUNDLE.getString(key); + } + catch(MissingResourceException e) + { + return '!' + key + '!'; + } + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPlugin.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPlugin.java new file mode 100644 index 00000000000..54f6842d8bf --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPlugin.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +public class FPRenderingPlugin extends AbstractUIPlugin +{ + public static final String PLUGIN_ID = "org.eclipse.cdt.debug.ui.memory.floatingpoint"; //$NON-NLS-1$ + + private static FPRenderingPlugin plugin; + + public FPRenderingPlugin() + { + super(); + } + + + @Override + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + + @Override + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + + /** + * Returns the shared instance. + */ + public static FPRenderingPlugin getDefault() + { + return plugin; + } + + /** + * Returns the unique identifier for this plugin. + */ + public static String getUniqueIdentifier() + { + return PLUGIN_ID; + } + + /** + * Returns the workbench's display. + */ + public static Display getStandardDisplay() + { + return PlatformUI.getWorkbench().getDisplay(); + } + + /** + * Returns the currently active workbench window shell or <code>null</code> + * if none. + * + * @return the currently active workbench window shell or <code>null</code> + */ + public static Shell getShell() + { + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + + if (window == null) + { + IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); + if (windows.length > 0) + { + return windows[0].getShell(); + } + } + else + { + return window.getShell(); + } + return null; + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceAction.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceAction.java new file mode 100644 index 00000000000..ac158b1e6d9 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceAction.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.preference.IPreferenceNode; +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.window.Window; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.actions.ActionDelegate; + +public class FPRenderingPreferenceAction extends ActionDelegate implements IViewActionDelegate +{ + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + @Override + public void run(IAction action) + { + IPreferencePage page = new FPRenderingPreferencePage(); + showPreferencePage("org.eclipse.cdt.debug.ui.memory.floatingpoint.FPRenderingPreferencePage", page); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + @Override + public void init(IViewPart view) + { + } + + protected void showPreferencePage(String id, IPreferencePage page) + { + final IPreferenceNode targetNode = new PreferenceNode(id, page); + + PreferenceManager manager = new PreferenceManager(); + manager.addToRoot(targetNode); + final PreferenceDialog dialog = new PreferenceDialog(FPRenderingPlugin.getShell(), manager); + final boolean[] result = new boolean[] { false }; + BusyIndicator.showWhile(FPRenderingPlugin.getStandardDisplay(), new Runnable() + { + @Override + public void run() + { + dialog.create(); + dialog.setMessage(targetNode.getLabelText()); + result[0] = (dialog.open() == Window.OK); + } + }); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceConstants.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceConstants.java new file mode 100644 index 00000000000..1fc4a93670f --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceConstants.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +/** + * Constant definitions for plug-in preferences + */ +public class FPRenderingPreferenceConstants +{ + public static final String MEM_COLOR_CHANGED = "memoryColorChanged"; //$NON-NLS-1$ + public static final String MEM_USE_GLOBAL_BACKGROUND = "memUseGlobalBackground"; //$NON-NLS-1$ + public static final String MEM_COLOR_BACKGROUND = "memoryColorBackground"; //$NON-NLS-1$ + public static final String MEM_COLOR_EDIT = "memoryColorEdit"; //$NON-NLS-1$ + public static final String MEM_COLOR_TEXT = "memoryColorText"; //$NON-NLS-1$ + public static final String MEM_USE_GLOBAL_SELECTION = "memUseGlobalSelection"; //$NON-NLS-1$ + public static final String MEM_COLOR_SELECTION = "memoryColorSelection"; //$NON-NLS-1$ + public static final String MEM_USE_GLOBAL_TEXT = "memUseGlobalText"; //$NON-NLS-1$ + public static final String MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS = "memoryColorScaleTextAlternate"; //$NON-NLS-1$ + public static final String MEM_EDIT_BUFFER_SAVE = "memoryEditBufferSave"; //$NON-NLS-1$ + public static final String MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY = "saveOnEnterCancelOnFocusLost"; //$NON-NLS-1$ + public static final String MEM_EDIT_BUFFER_SAVE_ON_ENTER_OR_FOCUS_LOST = "saveOnEnterOrFocusLost"; //$NON-NLS-1$ + public static final String MEM_HISTORY_TRAILS_COUNT = "memoryHistoryTrailsCount"; //$NON-NLS-1$ +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceInitializer.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceInitializer.java new file mode 100644 index 00000000000..7cbcbed5e3f --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferenceInitializer.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Display; + +/** + * Class used to initialize default preference values. + */ +public class FPRenderingPreferenceInitializer extends AbstractPreferenceInitializer +{ + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer# + * initializeDefaultPreferences() + */ + @Override + public void initializeDefaultPreferences() + { + IPreferenceStore store = FPRenderingPlugin.getDefault().getPreferenceStore(); + + store.setDefault(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT, true); + store.setDefault(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND, true); + store.setDefault(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION, true); + + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_CHANGED, "255,0,0"); //$NON-NLS-1$ + + Color systemSelection = Display.getDefault().getSystemColor(SWT.COLOR_LIST_SELECTION); + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_SELECTION, systemSelection.getRed() + "," + systemSelection.getGreen() + "," //$NON-NLS-1$ //$NON-NLS-2$ + + systemSelection.getBlue()); + + store.setDefault(FPRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS, "5"); //$NON-NLS-1$ + + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_EDIT, "0,255,0"); //$NON-NLS-1$ + + Color systemText = Display.getDefault().getSystemColor(SWT.COLOR_LIST_FOREGROUND); + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_TEXT, systemText.getRed() + "," + systemText.getGreen() + "," + systemText.getBlue()); //$NON-NLS-1$ //$NON-NLS-2$ + + Color systemBackground = Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND); + store.setDefault(FPRenderingPreferenceConstants.MEM_COLOR_BACKGROUND, systemBackground.getRed() + "," + systemBackground.getGreen() + "," //$NON-NLS-1$ //$NON-NLS-2$ + + systemBackground.getBlue()); + + store.setDefault(FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE, FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE_ON_ENTER_ONLY); + + store.setDefault(FPRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT, "1"); //$NON-NLS-1$ + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferencePage.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferencePage.java new file mode 100644 index 00000000000..716596f25a4 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingPreferencePage.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.ColorFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.jface.preference.ScaleFieldEditor; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.PlatformUI; + +/** + * This class represents a preference page that is contributed to the + * Preferences dialog. By subclassing <samp>FieldEditorPreferencePage</samp>, we + * can use the field support built into JFace that allows us to create a page + * that is small and knows how to save, restore and apply itself. + * <p> + * This page is used to modify preferences only. They are stored in the + * preference store that belongs to the main plug-in class. That way, + * preferences can be accessed directly via the preference store. + */ + +public class FPRenderingPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage +{ + public FPRenderingPreferencePage() + { + super(GRID); + setPreferenceStore(FPRenderingPlugin.getDefault().getPreferenceStore()); + setDescription("Floating Point Memory Rendering"); //$NON-NLS-1$ + } + + @Override + public void createControl(Composite parent) + { + super.createControl(parent); + PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), FPRenderingPlugin.getUniqueIdentifier() + ".FPRenderingPreferencePage_context"); //$NON-NLS-1$ + } + + /** + * Creates the field editors. Field editors are abstractions of the common + * GUI blocks needed to manipulate various types of preferences. Each field + * editor knows how to save and restore itself. + */ + @Override + public void createFieldEditors() + { + addField(new BooleanFieldEditor(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_TEXT, "Use Global Te&xt Color", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_TEXT, "&Text Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ScaleFieldEditor(FPRenderingPreferenceConstants.MEM_LIGHTEN_DARKEN_ALTERNATE_CELLS, "Brighten Alternate Cells", getFieldEditorParent(), 0, 8, 1, 1)); //$NON-NLS-1$ + addField(new BooleanFieldEditor(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_BACKGROUND, "Use Global B&ackground Color", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_BACKGROUND, "&Background Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_CHANGED, "&Changed Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_EDIT, "&Edit Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new BooleanFieldEditor(FPRenderingPreferenceConstants.MEM_USE_GLOBAL_SELECTION, "Use Global Se&lection Color", getFieldEditorParent())); //$NON-NLS-1$ + addField(new ColorFieldEditor(FPRenderingPreferenceConstants.MEM_COLOR_SELECTION, "&Selection Color:", getFieldEditorParent())); //$NON-NLS-1$ + addField(new RadioGroupFieldEditor(FPRenderingPreferenceConstants.MEM_EDIT_BUFFER_SAVE, "Edit Buffer", 1, new String[][] //$NON-NLS-1$ + { { "Save on E&nter, Cancel on Focus Lost", "saveOnEnterCancelOnFocusLost" }, //$NON-NLS-1$ //$NON-NLS-2$ + { "Save on Enter or Focus L&ost", "saveOnEnterOrFocusLost" } }, getFieldEditorParent())); //$NON-NLS-1$ //$NON-NLS-2$ + addField(new ScaleFieldEditor(FPRenderingPreferenceConstants.MEM_HISTORY_TRAILS_COUNT, "History &Trail Levels", getFieldEditorParent(), 1, 10, 1, 1)); //$NON-NLS-1$ + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + @Override + public void init(IWorkbench workbench) + { + } + +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingTypeDelegate.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingTypeDelegate.java new file mode 100644 index 00000000000..8a71b83a252 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPRenderingTypeDelegate.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.ui.memory.IMemoryRendering; +import org.eclipse.debug.ui.memory.IMemoryRenderingTypeDelegate; + +public class FPRenderingTypeDelegate implements IMemoryRenderingTypeDelegate +{ + @Override + public IMemoryRendering createRendering(String id) throws CoreException + { + return new FPRendering(id); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPutilities.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPutilities.java new file mode 100644 index 00000000000..c59bd5d5e4b --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/FPutilities.java @@ -0,0 +1,492 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Arrays; +import java.util.regex.Pattern; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.ErrorDialog; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.UIJob; + +public class FPutilities +{ + private static final int BYTE_MASK = 0xFF; + + // ANSI C "Smallest" and "largest" negative and positive float and double values + + public static final float floatNegMax = -3.40282347E+38f; // Largest negative float value; farthest from zero + public static final float floatNegMin = -1.17549435E-38f; // Smallest negative float value; closest to zero + public static final float floatPosMax = 1.17549435E+38f; // Largest positive float value; farthest from zero + public static final float floatPosMin = 3.40282347E-38f; // Smallest positive float value; closest to zero + + public static final double doubleNegMax = -1.7976931348623157E+308; // Largest positive double value + public static final double doubleNegMin = -2.2250738585072014E-308; // Smallest positive double value + public static final double doublePosMax = 1.7976931348623157E+308; // Largest positive double value + public static final double doublePosMin = 2.2250738585072014E-308; // Smallest positive double value + + public enum FPDataType + { + // Value (for persisteance), Bitsize of type, Number of internal precision decimal digits, Default displayed precision + + FLOAT ( 10, 32, 7, 8), // C/C++ single-precision "float" + DOUBLE ( 20, 64, 15, 8), // C/C++ double-precision "double" + FLOAT_80 ( 30, 80, 19, 16), // Extended precision + FLOAT_96 ( 40, 96, 0, 0), // TODO: unknown internal decimal digit precision; C/C++ extended-precision "long double" + + // Future work + + FLOAT_128 (50, 128, 33, 16), // TODO: known values, but not currently implmented + FLOAT_256 (60, 256, 0, 0), // TODO: unknown internal decimal digit precision + FLOAT_512 (70, 512, 0, 0); // TODO: unknown internal decimal digit precision + + // Member variables + + private int value; + private int bitsize; + private int decimalPrecision; + private int displayedPrecision; + + // Constructor + + private FPDataType(int value, int bitSize, int precisionDigits, int defaultDisplayPrecision) + { + this.value = value; + this.bitsize = bitSize; + this.decimalPrecision = precisionDigits; + this.displayedPrecision = defaultDisplayPrecision; + } + + // Getters + + public int getValue() { return value; } + public int getBitsize() { return bitsize; } + public int getDecimalPrecision() { return decimalPrecision; } + public int getDisplayedPrecision() { return displayedPrecision; } + public int getInternalPrecision() { return decimalPrecision; } + + public int getByteLength() + { + return bitsize/Byte.SIZE; + } + } + + // Byte ordering + + public enum Endian + { + // Value + + LITTLE (10), + BIG (20); + + // Member variables + + private int value; + + // Constructor + + private Endian(int value) + { + this.value = value; + } + + // Getters + + public int getValue() { return value; } + } + + // Justification (latent support) + + public enum Justification + { + LEFT, + RIGHT, + CENTER; + } + + // Convert raw float bits to a byte array + + public static byte[] rawFloatBitsToByteArray(int floatBits) + { + int byteCount = Integer.SIZE/Byte.SIZE; + byte[] result = new byte[byteCount]; + + for (int index = 0; index < byteCount; index++) + { + int offset = (result.length - 1 - index) * 8; + result[index] = (byte) ((floatBits >>> offset) & BYTE_MASK); + } + + return result; + } + + // Convert raw double bits to a byte array + + public static byte[] rawDoubleBitsToByteArray(long doubleBits) + { + int byteCount = Long.SIZE/Byte.SIZE; + byte[] result = new byte[byteCount]; + + for (int index = 0; index < byteCount; index++) + { + int offset = (result.length - 1 - index) * 8; + result[index] = (byte) ((doubleBits >>> offset) & BYTE_MASK); + } + + return result; + } + + // Return a byte array that is in reverse order of the passed-in array parameter + + public static byte[] reverseByteOrder(byte[] byteArray) + { + if (byteArray.length == 0) return new byte[0]; + + byte tempByte = 0; + byte[] reversedByteArray = new byte[byteArray.length]; + + // Copy the array that is passed in to the array that will be returned + + System.arraycopy(byteArray, 0, reversedByteArray, 0, byteArray.length); + + // Reverse the bytes + + for(int start = 0, end = reversedByteArray.length - 1; start < end; ++start, --end) + { + tempByte = reversedByteArray[start]; + reversedByteArray[start] = reversedByteArray[end]; + reversedByteArray[end] = tempByte; + } + + return reversedByteArray; + } + + // Convert a representation of a float or double in a byte array to a scientific notation string (Should we use BigDecimal here???) + + public static String byteArrayToSciNotation(FPDataType dt, boolean isLittleEndian, FPMemoryByte[] memByteArray, int maxDisplayDigits) throws ArithmeticException + { + int displayedDigits = 8; + + // If the byte array is not a 32-bit float or 64-bit double, throw an exception. + + if (memByteArray.length != (FPDataType.FLOAT.getByteLength()) && + memByteArray.length != (FPDataType.DOUBLE.getByteLength())) + throw new ArithmeticException("Conversion of the floating point number cannot be performed; invalid data type or byte array length."); //$NON-NLS-1$ + + // Create and initialize a DecimalFormat object for scientific notation. Specify a space + // for the preceding plus-sign, which lines up the first significant digit, decimal point + // and exponent character. Define the symbol strings for "Not a Number" and "Infinity." + + DecimalFormat df = new DecimalFormat("0.0E0"); //$NON-NLS-1$ + df.setPositivePrefix(" "); //$NON-NLS-1$ + + DecimalFormatSymbols dfSymbols = new DecimalFormatSymbols(); + dfSymbols.setNaN(" "+ FPRenderingMessages.getString("FPRendering.NAN")); //$NON-NLS-1$ //$NON-NLS-2$ + dfSymbols.setInfinity(FPRenderingMessages.getString("FPRendering.INFINITY")); //$NON-NLS-1$ + df.setDecimalFormatSymbols(dfSymbols); + + // Set the integer and fraction digits for normalized scientific notation. + + df.setMinimumIntegerDigits(1); + df.setMaximumIntegerDigits(1); + + if (dt == FPDataType.FLOAT) + displayedDigits = Math.min(maxDisplayDigits, FPDataType.FLOAT.getInternalPrecision()); + + if (dt == FPDataType.DOUBLE) + displayedDigits = Math.min(maxDisplayDigits, FPDataType.DOUBLE.getInternalPrecision()); + + df.setMinimumFractionDigits(displayedDigits - 1); + df.setMaximumFractionDigits(displayedDigits - 1); + + // Convert the byte array to a scientific notation floating point number string (only floats and doubles currently supported) + + ByteOrder byteOrder = isLittleEndian ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; + + return df.format(dt == FPDataType.FLOAT ? + ByteBuffer.wrap(memoryBytesToByteArray(memByteArray)).order(byteOrder).getFloat() : + ByteBuffer.wrap(memoryBytesToByteArray(memByteArray)).order(byteOrder).getDouble()); + } + + // Convert a floating point string to a byte array (*** only 'floats' and 'doubles' currently supported ***) + + public static byte[] floatingStringToByteArray(FPDataType dt, String valueString, int dataTypeBitCount) throws NumberFormatException + { + // Remove whitespace and check for non-zero length + valueString = valueString.trim().replaceAll(" ", ""); //$NON-NLS-1$ //$NON-NLS-2$ + + if (valueString.length() != 0) + { + // Float handling + + if (dt == FPDataType.FLOAT || FPDataType.FLOAT.getBitsize() == dataTypeBitCount) + { + // Convert the string to a float. Check the range. Convert to byte array. + + float floatValue = new Float(valueString).floatValue(); + floatValue = floatLimitCheck(floatValue); + return rawFloatBitsToByteArray(Float.floatToRawIntBits(floatValue)); + } + + // Double handling + + if (dt == FPDataType.DOUBLE || FPDataType.DOUBLE.getBitsize() == dataTypeBitCount) + { + // Convert the string to a double. Check the range. Convert to byte array. + + double doubleValue = new Double(valueString).doubleValue(); + doubleValue = doubleLimitCheck(doubleValue); + return rawDoubleBitsToByteArray(Double.doubleToRawLongBits(doubleValue)); + } + } + + return new byte[0]; + } + + // Convert from an FPMemoryByte array to a byte array + + public static byte[] memoryBytesToByteArray(FPMemoryByte[] memoryByteArray) + { + byte[] byteArray = new byte[memoryByteArray.length]; + + for (int index = 0; index < memoryByteArray.length; index++) + byteArray[index] = memoryByteArray[index].getValue(); + + return byteArray; + } + + // Convert from a byte array to a MemoryByte array + + public static FPMemoryByte[] byteArrayToMemoryBytes(Endian endian, byte[] byteArray) + { + FPMemoryByte[] memoryBytes = new FPMemoryByte[byteArray.length]; + + for (int index = 0; index < byteArray.length; index++) + { + memoryBytes[index] = new FPMemoryByte(); + memoryBytes[index].setBigEndian(endian == Endian.BIG); + memoryBytes[index].setValue(byteArray[index]); + } + + return memoryBytes; + } + + // Check the character for being valid for number entry, both standard and scientific notation + + public static boolean validEditCharacter(char character) + { + return (character >= '0' && character <= '9') || + character == '+' || character == '-' || + character == 'e' || character == 'E' || + character == '.' || character == ' '; + } + + // Validate floating point number string + + public static boolean isValidFormat(String string) + { + // Rules: + // - A minimum of one digit preceding the optional exponent character is required. + // - Allowable characters: 0-9, a decimal point, '+' and '-' number + // signs, exponent characters 'e' and 'E', and spaces. + // + // Strings may also have: + // - One [optional] decimal point + // - A maximum of two [optional] number signs (one before the number and one after the exponent character) + // - Only one [optional] exponent character is allowed + + boolean digit = false; + char[] charArray = string.toCharArray(); + + // Phase I check: + + String scientificNotationPattern = "^[-+]??(\\d++[.]\\d*?|[.]?\\d+?|\\d+(?=[eE]))([eE][-+]??\\d++)?$"; //$NON-NLS-1$ + + if (!Pattern.matches(scientificNotationPattern, string)) + return false; + + // Phase II check + + for (int index = 0; index < string.length(); index++) + { + // Check for a digit + + if (charArray[index] >= '0' && charArray[index] <= '9') + digit = true; + + // Make sure it's a valid/allowable character + + if (!validEditCharacter(charArray[index])) + return false; + + // Only one decimal point and exponent character is allowed + + if (FPutilities.countMatches(string.toLowerCase(), ".") > 1 || FPutilities.countMatches(string.toLowerCase(), "e") > 1) //$NON-NLS-1$ //$NON-NLS-2$ + return false; + + // Number signs are only allowed in the first position and following the exponent character. + + if (((charArray[index] == '+' || charArray[index] == '-') && index != 0) && + (charArray[index-1] != 'e' && charArray[index-1] != 'E')) + return false; + + // Decimal points are not allowed after the exponent character + + int eIndex = string.toLowerCase().indexOf('e'); + + if (charArray[index] == '.' && eIndex != -1 && eIndex < index) + return false; + } + + return digit; + } + + // Return a string of the specified length filled with the specified character + + public static String fillString(int length, char character) + { + if (length < 1) return ""; //$NON-NLS-1$ + char[] charArray = new char[length]; + Arrays.fill(charArray, character); + return new String(charArray); + } + + // Count the 'subString' matches in 'string' + + public static int countMatches(String string, String subString) + { + if (string.length() == 0 || subString.length() == 0) return 0; + + int count = 0; + int index = 0; + + while ((index = string.indexOf(subString, index)) != -1) + { + count++; + index += subString.length(); + } + + return count; + } + + // Print out a stack trace; useful for UI operations where stopping at a breakpoint causes button press context to be lost + + public static void stackTrace(int depth) + { + int offset = 3; // Ignore frames contributed to the stack based on call to this method + if (depth == 0) depth = 4; // Default depth if zero supplied + + // Get the stack frames for the current thread; start at the offset + + StackTraceElement[] seArray = Thread.currentThread().getStackTrace(); + + if (seArray.length > offset) + { + System.out.println("Displaying " + depth + " of " + seArray.length + " stack trace elements"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + for (int index = offset; index < Math.min(depth + offset, seArray.length + offset); index++) + System.out.println(" " + seArray[index].getClassName() + "." + seArray[index].getMethodName() + ": line " + seArray[index].getLineNumber()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + else + System.out.println("No stack frames to display"); //$NON-NLS-1$ + } + + // Pop up a message inside the UI thread + + public static void popupMessage(final String title, final String errorText, final Status status) + { + UIJob job = new UIJob("Floating Point Renderer") //$NON-NLS-1$ + { + // Notify the user of some condition via a pop-up box. + + @Override + public IStatus runInUIThread(IProgressMonitor monitor) + { + ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), title, errorText, status); + return Status.OK_STATUS; + } + }; + + job.setSystem(true); + job.schedule(); + } + + // Check float range. Returns -Infinity, the original value or +Infinity + + public static float floatLimitCheck(float floatValue) + { + if (floatValue != 0.0f && floatValue != Float.NEGATIVE_INFINITY && floatValue != Float.POSITIVE_INFINITY) + { + if (floatValue < 0) + { + if (Float.compare(floatValue, floatNegMax) < 0 || Float.compare(floatValue, floatNegMin) > 0) + return Float.NEGATIVE_INFINITY; + } + else + { + if (Float.compare(floatValue, floatPosMin) < 0 || Float.compare(floatValue, floatPosMax) > 0) + return Float.POSITIVE_INFINITY; + } + } + + return floatValue; + } + + // Check double range. Returns a value of RangeCheck + + public static double doubleLimitCheck(double doubleValue) + { + if (doubleValue != 0.0 && doubleValue != Double.NEGATIVE_INFINITY && doubleValue != Double.POSITIVE_INFINITY) + { + if (doubleValue < 0) + { + if (Double.compare(doubleValue, doubleNegMax) < 0 || Double.compare(doubleValue, doubleNegMin) > 0) + return Double.NEGATIVE_INFINITY; + } + else + { + if (Double.compare(doubleValue, doublePosMin) < 0 || Double.compare(doubleValue, doublePosMax) > 0) + return Double.POSITIVE_INFINITY; + } + } + + return doubleValue; + } + + // Convert a BigInteger to a hex String and return only the ending number of specified digits. + + public static String bi2HexStr(BigInteger bi, int lastDigits) + { + final int PAD_LENGTH = 12; + String base16 = bi.toString(16); + base16 = fillString(PAD_LENGTH - base16.length(), '0') + base16; + return "0x" + base16.substring(PAD_LENGTH - lastDigits).toUpperCase(); //$NON-NLS-1$ + } + + // Convert a BigInteger to a decimal String and return only the ending number of + // specified digits. For example: bi2HexStr(239248506, 5) = "48506" + + public static String bi2DecStr(BigInteger bi, int lastDigits) + { + final int PAD_LENGTH = 12; + String base10 = bi.toString(); + base10 = fillString(PAD_LENGTH - base10.length(), '0') + base10; + return base10.substring(PAD_LENGTH - lastDigits); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/IFPRConstants.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/IFPRConstants.java new file mode 100644 index 00000000000..2d65cfead84 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/IFPRConstants.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +public interface IFPRConstants +{ + public final String ENDIAN_KEY = FPRenderingPlugin.PLUGIN_ID + ".endian"; // Endianness key //$NON-NLS-1$ + public final String DATATYPE_KEY = FPRenderingPlugin.PLUGIN_ID + ".dataType"; // Currently-selected data type //$NON-NLS-1$ + public final String FLOAT_DISP_KEY = FPRenderingPlugin.PLUGIN_ID + ".floatDispPrec"; // 32-bit floating point data type displayed precision //$NON-NLS-1$ + public final String DOUBLE_DISP_KEY = FPRenderingPlugin.PLUGIN_ID + ".doubleDispPrec"; // 64-bit floating point data type displayed precision //$NON-NLS-1$ + public final String COLUMN_COUNT_KEY = FPRenderingPlugin.PLUGIN_ID + ".columns"; // Number of columns to display //$NON-NLS-1$ + public final String UPDATEMODE_KEY = FPRenderingPlugin.PLUGIN_ID + ".updateMode"; // Renderer update mode //$NON-NLS-1$ +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/Rendering.java b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/Rendering.java new file mode 100644 index 00000000000..bf6ba9cdecd --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/Rendering.java @@ -0,0 +1,2297 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010, 2012 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: + * Ted R Williams (Wind River Systems, Inc.) - initial implementation + * Randy Rohrbach (Wind River Systems, Inc.) - Copied and modified to create the floating point plugin + *******************************************************************************/ + +package org.eclipse.cdt.debug.ui.memory.floatingpoint; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.math.MathContext; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; + +import org.eclipse.cdt.debug.ui.memory.floatingpoint.FPutilities.FPDataType; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.model.IDebugElement; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.core.model.MemoryByte; +import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; +import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressComposite; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.progress.UIJob; + + +@SuppressWarnings("restriction") +public class Rendering extends Composite implements IDebugEventSetListener +{ + // The IMemoryRendering parent + + private FPRendering fParent; + + // Controls + + protected FPAddressPane fAddressPane; + protected FPDataPane fDataPane; + private GoToAddressComposite fAddressBar; + protected Control fAddressBarControl; + private Selection fSelection = new Selection(); + + // Internal management + + BigInteger fViewportAddress = null; // Default visibility for performance + BigInteger fMemoryBlockStartAddress = null; // Starting address + BigInteger fMemoryBlockEndAddress = null; // Ending address + protected BigInteger fBaseAddress = null; // Base address + protected int fColumnCount = 0; // Auto calculate can be disabled by user, making this user settable + protected int fBytesPerRow = 0; // Number of bytes per row are displayed + int fScrollSelection = 0; // Scroll selection + private BigInteger fCaretAddress = null; // Caret/cursor position + private boolean fCellEditState = false; // Cell editing mode: 'true' = currently editing a cell; 'false' = not editing a cell + private BigInteger cellEditAddress = null; // The address of the cell currently being edited + private BigInteger memoryAddress = null; // The memory address associated with the cell that currently being edited + private StringBuffer fEditBuffer = null; // Character buffer used during editing + static boolean initialDisplayModeSet = false; // Initial display mode been set to the same endianness as the target + + // Constants used to identify the panes + + public final static int PANE_ADDRESS = 1; + public final static int PANE_DATA = 2; + + // Decimal precision used when converting between scroll units and number of memory + // rows. Calculations do not need to be exact; two decimal places is good enough. + + static private final MathContext SCROLL_CONVERSION_PRECISION = new MathContext(2); + + // Constants used to identify text, maybe java should be queried for all available sets + + public final static int TEXT_ISO_8859_1 = 1; + public final static int TEXT_USASCII = 2; + public final static int TEXT_UTF8 = 3; + protected final static int TEXT_UTF16 = 4; + + // Internal constants + + public final static int COLUMNS_AUTO_SIZE_TO_FIT = 0; + + // View internal settings + + private int fCellPadding = 2; + private int fPaneSpacing = 16; + private String fPaddingString = " "; //$NON-NLS-1$ + + // Flag whether the memory cache is dirty + + private boolean fCacheDirty = false; + + // Update modes + + public final static int UPDATE_ALWAYS = 1; + public final static int UPDATE_ON_BREAKPOINT = 2; + public final static int UPDATE_MANUAL = 3; + public int fUpdateMode = UPDATE_ALWAYS; + + // Constants for cell-width calculations + + private static final int DECIMAL_POINT_SIZE = 1; + private static final int SIGN_SIZE = 1; + private static final int EXPONENT_CHARACTER_SIZE = 1; + private static final int EXPONENT_VALUE_SIZE = 3; + + // User settings + + private FPDataType fFPDataType = FPDataType.FLOAT; // Default to float data type + private int fDisplayedPrecision = 8; // The default number of digits of displayed precision + private int fCharsPerColumn = charsPerColumn(); // Figure out the initial cell-width size + private int fColumnsSetting = COLUMNS_AUTO_SIZE_TO_FIT; // Default column setting + private boolean fIsTargetLittleEndian = true; // Default target endian setting + private boolean fIsDisplayLittleEndian = true; // Default display endian setting + private boolean fEditInserMode = false; // Insert mode: true = replace existing number, false = overstrike + + // Constructors + + public Rendering(Composite parent, FPRendering renderingParent) + { + super(parent, SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.H_SCROLL | SWT.V_SCROLL); + this.setFont(JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME)); // TODO: internal? + this.fParent = renderingParent; + + // Initialize the viewport start + + if (fParent.getMemoryBlock() != null) + { + fViewportAddress = fParent.getMemoryBlockStartAddress(); + + // The viewport address will be null if memory may be retrieved at any + // address less than this memory block's base. If so use the base address. + + if (fViewportAddress == null) + fViewportAddress = fParent.getBigBaseAddress(); + + fBaseAddress = fViewportAddress; + } + + // Instantiate the panes, TODO default visibility from state or plugin.xml? + + this.fAddressPane = createAddressPane(); + this.fDataPane = createDataPane(); + + fAddressBar = new GoToAddressComposite(); + fAddressBarControl = fAddressBar.createControl(parent); + Button button = fAddressBar.getButton(IDialogConstants.OK_ID); + + if (button != null) + { + button.addSelectionListener(new SelectionAdapter() + { + + @Override + public void widgetSelected(SelectionEvent e) + { + doGoToAddress(); + } + }); + + button = fAddressBar.getButton(IDialogConstants.CANCEL_ID); + if (button != null) + { + button.addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetSelected(SelectionEvent e) + { + setVisibleAddressBar(false); + } + }); + } + } + + fAddressBar.getExpressionWidget().addSelectionListener(new SelectionAdapter() + { + @Override + public void widgetDefaultSelected(SelectionEvent e) + { + doGoToAddress(); + } + }); + + fAddressBar.getExpressionWidget().addKeyListener(new KeyAdapter() + { + @Override + public void keyPressed(KeyEvent e) + { + if (e.keyCode == SWT.ESC) + setVisibleAddressBar(false); + super.keyPressed(e); + } + }); + + this.fAddressBarControl.setVisible(false); + + getHorizontalBar().addSelectionListener(createHorizontalBarSelectionListener()); + getVerticalBar().addSelectionListener(createVerticalBarSelectinListener()); + + this.addPaintListener(new PaintListener() + { + @Override + public void paintControl(PaintEvent pe) + { + pe.gc.setBackground(Rendering.this.getFPRendering().getColorBackground()); + pe.gc.fillRectangle(0, 0, Rendering.this.getBounds().width, Rendering.this.getBounds().height); + } + }); + + setLayout(); + + this.addControlListener(new ControlListener() + { + @Override + public void controlMoved(ControlEvent ce) + { + } + + @Override + public void controlResized(ControlEvent ce) + { + packColumns(); + } + }); + + DebugPlugin.getDefault().addDebugEventListener(this); + } + + // Determine how many characters are allowed in the column + + private int charsPerColumn() + { + return fDisplayedPrecision + DECIMAL_POINT_SIZE + SIGN_SIZE + EXPONENT_CHARACTER_SIZE + EXPONENT_VALUE_SIZE + fCellPadding; + } + + // Establish the visible layout of the view + + protected void setLayout() + { + this.setLayout(new Layout() + { + @Override + public void layout(Composite composite, boolean changed) + { + int xOffset = 0; + + if (Rendering.this.getHorizontalBar().isVisible()) + xOffset = Rendering.this.getHorizontalBar().getSelection(); + + int x = xOffset * -1; + int y = 0; + + if (fAddressBarControl.isVisible()) + { + fAddressBarControl.setBounds(0, 0, Rendering.this.getBounds().width, fAddressBarControl.computeSize(100, 30).y); // FIXME + // y = fAddressBarControl.getBounds().height; + } + + if (fAddressPane.isPaneVisible()) + { + fAddressPane.setBounds(x, y, fAddressPane.computeSize(0, 0).x, Rendering.this.getBounds().height - y); + x = fAddressPane.getBounds().x + fAddressPane.getBounds().width; + } + + if (fDataPane.isPaneVisible()) + { + fDataPane.setBounds(x, y, fDataPane.computeSize(0, 0).x, Rendering.this.getBounds().height - y); + x = fDataPane.getBounds().x + fDataPane.getBounds().width; + } + + ScrollBar horizontal = Rendering.this.getHorizontalBar(); + + horizontal.setVisible(true); + horizontal.setMinimum(0); + horizontal.setMaximum(fDataPane.getBounds().x + fDataPane.getBounds().width + xOffset); + @SuppressWarnings("unused") + int temp = horizontal.getMaximum(); + horizontal.setThumb(getClientArea().width); + horizontal.setPageIncrement(40); // TODO ? + horizontal.setIncrement(20); // TODO ? + } + + @Override + protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) + { + return new Point(100, 100); // dummy data + } + }); + } + + // Handles for the caret/cursor movement keys + + protected void handleDownArrow() + { + fViewportAddress = fViewportAddress.add(BigInteger.valueOf(getAddressableCellsPerRow())); + ensureViewportAddressDisplayable(); + redrawPanes(); + } + + protected void handleUpArrow() + { + fViewportAddress = fViewportAddress.subtract(BigInteger.valueOf(getAddressableCellsPerRow())); + ensureViewportAddressDisplayable(); + redrawPanes(); + } + + protected void handlePageDown() + { + fViewportAddress = fViewportAddress.add(BigInteger.valueOf(getAddressableCellsPerRow() * (Rendering.this.getRowCount() - 1))); + ensureViewportAddressDisplayable(); + redrawPanes(); + } + + protected void handlePageUp() + { + fViewportAddress = fViewportAddress.subtract(BigInteger.valueOf(getAddressableCellsPerRow() * (Rendering.this.getRowCount() - 1))); + ensureViewportAddressDisplayable(); + redrawPanes(); + } + + protected SelectionListener createHorizontalBarSelectionListener() + { + return new SelectionListener() + { + @Override + public void widgetSelected(SelectionEvent se) + { + Rendering.this.layout(); + } + + @Override + public void widgetDefaultSelected(SelectionEvent se) + { + // Do nothing + } + }; + } + + protected SelectionListener createVerticalBarSelectinListener() + { + return new SelectionListener() + { + @Override + public void widgetSelected(SelectionEvent se) + { + switch (se.detail) + { + case SWT.ARROW_DOWN: + handleDownArrow(); + break; + + case SWT.PAGE_DOWN: + handlePageDown(); + break; + + case SWT.ARROW_UP: + handleUpArrow(); + break; + + case SWT.PAGE_UP: + handlePageUp(); + break; + + case SWT.SCROLL_LINE: + // See: BUG 203068 selection event details broken on GTK < 2.6 + + default: + { + if (getVerticalBar().getSelection() == getVerticalBar().getMinimum()) + { + // Set view port start address to the start address of the Memory Block + fViewportAddress = Rendering.this.getMemoryBlockStartAddress(); + } + else if (getVerticalBar().getSelection() == getVerticalBar().getMaximum()) + { + // The view port end address should be less or equal to the the end address of the Memory Block + // Set view port address to be bigger than the end address of the Memory Block for now + // and let ensureViewportAddressDisplayable() to figure out the correct view port start address + fViewportAddress = Rendering.this.getMemoryBlockEndAddress(); + } + else + { + // Figure out the delta, ignore events with no delta + int deltaScroll = getVerticalBar().getSelection() - fScrollSelection; + if (deltaScroll == 0) break; + BigInteger deltaRows = scrollbar2rows(deltaScroll); + BigInteger newAddress = fViewportAddress.add(BigInteger.valueOf(getAddressableCellsPerRow()).multiply(deltaRows)); + fViewportAddress = newAddress; + } + + ensureViewportAddressDisplayable(); + + // Update tooltip; FIXME conversion from slider to scrollbar + // getVerticalBar().setToolTipText(Rendering.this.getAddressString(fViewportAddress)); + + // Update the addresses in the Address pane. + + if (fAddressPane.isPaneVisible()) + fAddressPane.redraw(); + + redrawPanes(); + + break; + } + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent se) + { + // do nothing + } + }; + } + + protected FPAddressPane createAddressPane() + { + return new FPAddressPane(this); + } + + protected FPDataPane createDataPane() + { + return new FPDataPane(this); + } + + public FPRendering getFPRendering() // TODO rename + { + return fParent; + } + + protected void setCaretAddress(BigInteger address) + { + fCaretAddress = address; + } + + protected BigInteger getCaretAddress() + { + // Return the caret address if it has been set. Otherwise return the viewport address. + // When the rendering is first created, the caret is unset until the user clicks somewhere + // in the rendering. It also reset (unset) when the user gives us a new viewport address + + return (fCaretAddress != null) ? fCaretAddress : fViewportAddress; + } + + void doGoToAddress() + { + try + { + BigInteger address = fAddressBar.getGoToAddress(this.getMemoryBlockStartAddress(), this.getCaretAddress()); + getFPRendering().gotoAddress(address); + setVisibleAddressBar(false); + } + catch (NumberFormatException e1) + { + // FIXME log? + } + } + + // Ensure that all addresses displayed are within the addressable range + protected void ensureViewportAddressDisplayable() + { + if (fViewportAddress.compareTo(Rendering.this.getMemoryBlockStartAddress()) < 0) + { + fViewportAddress = Rendering.this.getMemoryBlockStartAddress(); + } + else if (getViewportEndAddress().compareTo(getMemoryBlockEndAddress().add(BigInteger.ONE)) > 0) + { + fViewportAddress = getMemoryBlockEndAddress().subtract(BigInteger.valueOf(getAddressableCellsPerRow() * getRowCount() - 1)); + } + + setScrollSelection(); + } + + public FPIMemorySelection getSelection() + { + return fSelection; + } + + protected int getHistoryDepth() + { + return fViewportCache.getHistoryDepth(); + } + + protected void setHistoryDepth(int depth) + { + fViewportCache.setHistoryDepth(depth); + } + + public void logError(String message, Exception e) + { + Status status = new Status(IStatus.ERROR, fParent.getRenderingId(), DebugException.INTERNAL_ERROR, message, e); + FPRenderingPlugin.getDefault().getLog().log(status); + } + + public void handleFontPreferenceChange(Font font) + { + setFont(font); + + Control controls[] = this.getRenderingPanes(); + for (int index = 0; index < controls.length; index++) + controls[index].setFont(font); + + packColumns(); + layout(true); + } + + public void setPaddingString(String padding) + { + fPaddingString = padding; + refresh(); + } + + public char getPaddingCharacter() + { + return fPaddingString.charAt(0); // use only the first character + } + + static int suspendCount = 0; + + @Override + public void handleDebugEvents(DebugEvent[] events) + { + if (this.isDisposed()) return; + + boolean isChangeOnly = false; + boolean isSuspend = false; + boolean isBreakpointHit = false; + + for (int index = 0; index < events.length; index++) + { + if (events[0].getSource() instanceof IDebugElement) + { + final int kind = events[index].getKind(); + final int detail = events[index].getDetail(); + final IDebugElement source = (IDebugElement) events[index].getSource(); + + /* + * We have to make sure we are comparing memory blocks here. It pretty much is now the + * case that the IDebugTarget is always null. Almost no one in the Embedded Space is + * using anything but CDT/DSF or CDT/TCF at this point. The older CDI stuff will still + * be using the old Debug Model API. But this will generate the same memory block and + * a legitimate IDebugTarget which will match properly. + */ + if( source.equals( getMemoryBlock() ) && source.getDebugTarget() == getMemoryBlock().getDebugTarget() ) + { + if ((detail & DebugEvent.BREAKPOINT) != 0) isBreakpointHit = true; + + if (kind == DebugEvent.SUSPEND) + { + handleSuspendEvent(detail); + isSuspend = true; + } + else if (kind == DebugEvent.CHANGE) + { + handleChangeEvent(); + isChangeOnly = true; + } + } + } + } + + if (isSuspend) + handleSuspend(isBreakpointHit); + else if (isChangeOnly) + handleChange(); + } + + protected void handleSuspend(boolean isBreakpointHit) + { + if (getUpdateMode() == UPDATE_ALWAYS || (getUpdateMode() == UPDATE_ON_BREAKPOINT && isBreakpointHit)) + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + archiveDeltas(); + refresh(); + } + }); + } + } + + protected void handleChange() + { + if (getUpdateMode() == UPDATE_ALWAYS) + { + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + refresh(); + } + }); + } + } + + protected void handleSuspendEvent(int detail) + { + } + + protected void handleChangeEvent() + { + } + + // Return true to enable development debug print statements + + public boolean isDebug() + { + return false; + } + + protected IMemoryBlockExtension getMemoryBlock() + { + IMemoryBlock block = fParent.getMemoryBlock(); + if (block != null) + return (IMemoryBlockExtension) block.getAdapter(IMemoryBlockExtension.class); + + return null; + } + + public BigInteger getBigBaseAddress() + { + return fParent.getBigBaseAddress(); + } + + public int getAddressableSize() + { + return fParent.getAddressableSize(); + } + + protected FPIViewportCache getViewportCache() + { + return fViewportCache; + } + + public FPMemoryByte[] getBytes(BigInteger address, int bytes) throws DebugException + { + return getViewportCache().getBytes(address, bytes); + } + + // Default visibility for performance + + ViewportCache fViewportCache = new ViewportCache(); + + private interface Request + { + } + + class ViewportCache extends Thread implements FPIViewportCache + { + class ArchiveDeltas implements Request + { + } + + class AddressPair implements Request + { + BigInteger startAddress; + BigInteger endAddress; + + public AddressPair(BigInteger start, BigInteger end) + { + startAddress = start; + endAddress = end; + } + + @Override + public boolean equals(Object obj) + { + if (obj == null) + return false; + if (obj instanceof AddressPair) + { + return ((AddressPair) obj).startAddress.equals(startAddress) && ((AddressPair) obj).endAddress.equals(endAddress); + } + + return false; + } + + @Override + public int hashCode() { + return super.hashCode() + startAddress.hashCode() + endAddress.hashCode(); + } + + } + + class MemoryUnit implements Cloneable + { + BigInteger start; + + BigInteger end; + + FPMemoryByte[] bytes; + + @Override + public MemoryUnit clone() + { + MemoryUnit b = new MemoryUnit(); + + b.start = this.start; + b.end = this.end; + b.bytes = new FPMemoryByte[this.bytes.length]; + for (int index = 0; index < this.bytes.length; index++) + b.bytes[index] = new FPMemoryByte(this.bytes[index].getValue()); + + return b; + } + + public boolean isValid() + { + return this.start != null && this.end != null && this.bytes != null; + } + } + + @SuppressWarnings("hiding") + private HashMap<BigInteger, FPMemoryByte[]> fEditBuffer = new HashMap<BigInteger, FPMemoryByte[]>(); + private boolean fDisposed = false; + private Object fLastQueued = null; + private Vector<Object> fQueue = new Vector<Object>(); + protected MemoryUnit fCache = null; + protected MemoryUnit fHistoryCache[] = new MemoryUnit[0]; + protected int fHistoryDepth = 0; + + public ViewportCache() + { + start(); + } + + @Override + public void dispose() + { + fDisposed = true; + synchronized (fQueue) + { + fQueue.notify(); + } + } + + public int getHistoryDepth() + { + return fHistoryDepth; + } + + public void setHistoryDepth(int depth) + { + fHistoryDepth = depth; + fHistoryCache = new MemoryUnit[fHistoryDepth]; + } + + @Override + public void refresh() + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + + if (fCache != null) + { + queueRequest(fViewportAddress, getViewportEndAddress()); + } + } + + @Override + public void archiveDeltas() + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + + if (fCache != null) + { + queueRequestArchiveDeltas(); + } + } + + private void queueRequest(BigInteger startAddress, BigInteger endAddress) + { + AddressPair pair = new AddressPair(startAddress, endAddress); + queue(pair); + } + + private void queueRequestArchiveDeltas() + { + ArchiveDeltas archive = new ArchiveDeltas(); + queue(archive); + } + + private void queue(Object element) + { + synchronized (fQueue) + { + if (!(fQueue.size() > 0 && element.equals(fLastQueued))) + { + fQueue.addElement(element); + fLastQueued = element; + } + fQueue.notify(); + } + } + + @Override + public void run() + { + while (!fDisposed) + { + AddressPair pair = null; + boolean archiveDeltas = false; + synchronized (fQueue) + { + if (fQueue.size() > 0) + { + Request request = (Request) fQueue.elementAt(0); + Class<?> type = request.getClass(); + + while (fQueue.size() > 0 && type.isInstance(fQueue.elementAt(0))) + { + request = (Request) fQueue.elementAt(0); + fQueue.removeElementAt(0); + } + + if (request instanceof ArchiveDeltas) + archiveDeltas = true; + else if (request instanceof AddressPair) + pair = (AddressPair) request; + } + } + + if (archiveDeltas) + { + for (int i = fViewportCache.getHistoryDepth() - 1; i > 0; i--) + fHistoryCache[i] = fHistoryCache[i - 1]; + + fHistoryCache[0] = fCache.clone(); + } + else if (pair != null) + { + populateCache(pair.startAddress, pair.endAddress); + } + else + { + synchronized (fQueue) + { + try + { + if (fQueue.isEmpty()) + { + fQueue.wait(); + } + } catch (Exception e) + { + // do nothing + } + } + } + } + } + + // Cache memory necessary to paint viewport + // TODO: user setting to buffer +/- x lines + // TODO: reuse existing cache? probably only a minor performance gain + + private void populateCache(final BigInteger startAddress, final BigInteger endAddress) + { + try + { + IMemoryBlockExtension memoryBlock = getMemoryBlock(); + + BigInteger lengthInBytes = endAddress.subtract(startAddress); + BigInteger addressableSize = BigInteger.valueOf(getAddressableSize()); + + long units = lengthInBytes.divide(addressableSize) + .add(lengthInBytes.mod(addressableSize).compareTo(BigInteger.ZERO) > 0 ? BigInteger.ONE : BigInteger.ZERO).longValue(); + + // CDT (and maybe other backends) will call setValue() on these MemoryBlock objects. We + // don't want this to happen, because it interferes with this rendering's own change history. + // Ideally, we should strictly use the back end change notification and history, but it is + // only guaranteed to work for bytes within the address range of the MemoryBlock. + + MemoryByte readBytes[] = memoryBlock.getBytesFromAddress(startAddress, units); + FPMemoryByte cachedBytes[] = new FPMemoryByte[readBytes.length]; + + for (int index = 0; index < readBytes.length; index++) + cachedBytes[index] = new FPMemoryByte(readBytes[index].getValue(), readBytes[index].getFlags()); + + // Derive the target endian from the read MemoryBytes. + + if (cachedBytes.length > 0) + if (cachedBytes[0].isEndianessKnown()) + setTargetLittleEndian(!cachedBytes[0].isBigEndian()); + + // The first time we execute this method, set the display endianness to the target endianness. + + if (!initialDisplayModeSet) + { + setDisplayLittleEndian(isTargetLittleEndian()); + initialDisplayModeSet = true; + } + + // Re-order bytes within unit to be a sequential byte stream if the endian is already little + + if (isTargetLittleEndian()) + { + // There isn't an order when the unit size is one, so skip for performance + + if (addressableSize.compareTo(BigInteger.ONE) != 0) + { + int unitSize = addressableSize.intValue(); + FPMemoryByte cachedBytesAsByteSequence[] = new FPMemoryByte[cachedBytes.length]; + for (int unit = 0; unit < units; unit++) + { + for (int unitbyte = 0; unitbyte < unitSize; unitbyte++) + { + cachedBytesAsByteSequence[unit * unitSize + unitbyte] = cachedBytes[unit * unitSize + unitSize - unitbyte]; + } + } + cachedBytes = cachedBytesAsByteSequence; + } + } + + final FPMemoryByte[] cachedBytesFinal = cachedBytes; + + fCache = new MemoryUnit(); + fCache.start = startAddress; + fCache.end = endAddress; + fCache.bytes = cachedBytesFinal; + + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + // Generate deltas + + for (int historyIndex = 0; historyIndex < getHistoryDepth(); historyIndex++) + { + if (fHistoryCache[historyIndex] != null && fHistoryCache[historyIndex].isValid()) + { + BigInteger maxStart = startAddress.max(fHistoryCache[historyIndex].start); + BigInteger minEnd = endAddress.min(fHistoryCache[historyIndex].end).subtract(BigInteger.ONE); + + BigInteger overlapLength = minEnd.subtract(maxStart); + if (overlapLength.compareTo(BigInteger.valueOf(0)) > 0) + { + // there is overlap + + int offsetIntoOld = maxStart.subtract(fHistoryCache[historyIndex].start).intValue(); + int offsetIntoNew = maxStart.subtract(startAddress).intValue(); + + for (int i = overlapLength.intValue(); i >= 0; i--) + { + cachedBytesFinal[offsetIntoNew + i].setChanged(historyIndex, + cachedBytesFinal[offsetIntoNew + i].getValue() != fHistoryCache[historyIndex].bytes[offsetIntoOld + i] + .getValue()); + } + + // There are several scenarios where the history cache must be updated from the data cache, so that when a + // cell is edited the font color changes appropriately. The following code deals with the different cases. + + if (historyIndex != 0) continue; + + int dataStart = fCache.start.intValue(); + int dataEnd = fCache.end.intValue(); + int dataLength = fCache.bytes.length; + + int historyStart = fHistoryCache[0].start.intValue(); + int historyEnd = fHistoryCache[0].end.intValue(); + int historyLength = fHistoryCache[0].bytes.length; + + // Case 1: The data cache is smaller than the history cache; the data cache's + // address range is fully covered by the history cache. Do nothing. + + if ((dataStart >= historyStart) && (dataEnd <= historyEnd)) + continue; + + // Case 2: The data and history cache's do not overlap at all + + if (((dataStart < historyStart) && (dataEnd < historyStart)) || (dataStart > historyEnd)) + { + // Create a new history cache: Copy the data cache bytes to the history cache + + MemoryUnit newHistoryCache = new MemoryUnit(); + + newHistoryCache.start = fCache.start; + newHistoryCache.end = fCache.end; + int newHistoryCacheSize = fCache.bytes.length; + newHistoryCache.bytes = new FPMemoryByte[newHistoryCacheSize]; + + for (int index = 0; index < newHistoryCacheSize; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + fHistoryCache[0] = newHistoryCache; + + continue; + } + + // Case 3: The data cache starts at a lower address than the history cache, but overlaps the history cache + + if ((dataStart < historyStart) && ((dataEnd >= historyStart) && (dataEnd <= historyEnd))) + { + // Create a new history cache with the missing data from the main cache and append the old history to it. + + int missingDataByteCount = historyStart - dataStart; + int historyCacheSize = historyLength; + int newHistoryCacheSize = missingDataByteCount + historyLength; + + if (missingDataByteCount <= 0 && historyCacheSize <= 0) break; + + MemoryUnit newHistoryCache = new MemoryUnit(); + + newHistoryCache.start = fCache.start; + newHistoryCache.end = fHistoryCache[0].end; + newHistoryCache.bytes = new FPMemoryByte[newHistoryCacheSize]; + + // Copy the missing bytes from the beginning of the main cache to the history cache. + + for (int index = 0; index < missingDataByteCount; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + // Copy the remaining bytes from the old history cache to the new history cache + + for (int index = 0; index < historyCacheSize; index++) + newHistoryCache.bytes[index + missingDataByteCount] = + new FPMemoryByte(fHistoryCache[0].bytes[index].getValue()); + + fHistoryCache[0] = newHistoryCache; + + continue; + } + + // Case 4: The data cache starts at a higher address than the history cache + + if (((dataStart >= historyStart) && (dataStart <= historyEnd)) && (dataEnd > historyEnd)) + { + // Append the missing main cache bytes to the history cache. + + int missingDataByteCount = dataEnd - historyEnd; + int historyCacheSize = historyEnd - historyStart; + int newHistoryCacheSize = missingDataByteCount + historyLength; + + if (missingDataByteCount > 0 && historyCacheSize > 0) + { + MemoryUnit newHistoryCache = new MemoryUnit(); + + newHistoryCache.start = fHistoryCache[0].start; + newHistoryCache.end = fCache.end; + newHistoryCache.bytes = new FPMemoryByte[newHistoryCacheSize]; + + // Copy the old history bytes to the new history cache + + System.arraycopy(fHistoryCache[0].bytes, 0, newHistoryCache.bytes, 0, historyLength); + + // Copy the bytes from the main cache that are not in the history cache to the end of the new history cache. + + for (int index = 0; index < missingDataByteCount; index++) + { + int srcIndex = dataLength - missingDataByteCount + index; + int dstIndex = historyLength + index; + newHistoryCache.bytes[dstIndex] = new FPMemoryByte(fCache.bytes[srcIndex].getValue()); + } + + fHistoryCache[0] = newHistoryCache; + + continue; + } + } + + // Case 5 - The data cache is greater than the history cache and fully covers it + + if (dataStart < historyStart && dataEnd > historyEnd) + { + int start = 0; + int end = 0; + + // Create a new history cache to reflect the entire data cache + + MemoryUnit newHistoryCache = new MemoryUnit(); + + newHistoryCache.start = fCache.start; + newHistoryCache.end = fCache.end; + int newHistoryCacheSize = fCache.bytes.length; + newHistoryCache.bytes = new FPMemoryByte[newHistoryCacheSize]; + + int topByteCount = historyStart - dataStart; + int bottomByteCount = dataEnd - historyEnd; + + // Copy the bytes from the beginning of the data cache to the new history cache + + for (int index = 0; index < topByteCount; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + // Copy the old history cache bytes to the new history cache + + start = topByteCount; + end = topByteCount + historyLength; + + for (int index = start; index < end; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + // Copy the bytes from the end of the data cache to the new history cache + + start = topByteCount + historyLength; + end = topByteCount + historyLength + bottomByteCount; + + for (int index = start; index < end; index++) + newHistoryCache.bytes[index] = new FPMemoryByte(fCache.bytes[index].getValue()); + + fHistoryCache[0] = newHistoryCache; + + continue; + } + } + } + } + + // If the history does not exist, populate the history with the just populated + // cache. This solves the use case of (1) connect to target; (2) edit memory + // before the first suspend debug event; (3) paint differences in changed color. + + if (fHistoryCache[0] == null) + fHistoryCache[0] = fCache.clone(); + + Rendering.this.redrawPanes(); + } + }); + + } + catch (Exception e) + { + // User can scroll to any memory, whether it's valid on the target or not. It doesn't make + // much sense to fill up the Eclipse error log with such "failures." So, comment out for now. + // logError(FPRenderingMessages.getString("FAILURE_READ_MEMORY"), e); //$NON-NLS-1$ + } + } + + // Bytes will be fetched from cache + + @Override + public FPMemoryByte[] getBytes(BigInteger address, int bytesRequested) throws DebugException + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + + if (containsEditedCell(address)) // Cell size cannot be switched during an edit + return getEditedMemory(address); + + boolean contains = false; + if (fCache != null && fCache.start != null) + { + // See if all of the data requested is in the cache + + BigInteger dataEnd = address.add(BigInteger.valueOf(bytesRequested)); + + if (fCache.start.compareTo(address) <= 0 && fCache.end.compareTo(dataEnd) >= 0 && fCache.bytes.length > 0) + contains = true; + } + + if (contains) + { + int offset = address.subtract(fCache.start).intValue(); + FPMemoryByte bytes[] = new FPMemoryByte[bytesRequested]; + + for (int index = 0; index < bytes.length; index++) + bytes[index] = fCache.bytes[offset + index]; + + return bytes; + } + + FPMemoryByte bytes[] = new FPMemoryByte[bytesRequested]; + + for (int index = 0; index < bytes.length; index++) + { + bytes[index] = new FPMemoryByte(); + bytes[index].setReadable(false); + } + + fViewportCache.queueRequest(fViewportAddress, getViewportEndAddress()); + + return bytes; + } + + @Override + public boolean containsEditedCell(BigInteger address) + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + return fEditBuffer.containsKey(address); + } + + public FPMemoryByte[] getEditedMemory(BigInteger address) + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + return fEditBuffer.get(address); + } + + @Override + public void clearEditBuffer() + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + fEditBuffer.clear(); + Rendering.this.redrawPanes(); + } + + @Override + public void writeEditBuffer() + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + + Set<BigInteger> keySet = fEditBuffer.keySet(); + Iterator<BigInteger> iterator = keySet.iterator(); + + while (iterator.hasNext()) + { + BigInteger address = iterator.next(); + FPMemoryByte[] bytes = fEditBuffer.get(address); + + byte byteValue[] = new byte[bytes.length]; + + for (int index = 0; index < bytes.length; index++) + byteValue[index] = bytes[index].getValue(); + + try + { + IMemoryBlockExtension block = getMemoryBlock(); + BigInteger offset = address.subtract(block.getBigBaseAddress()); + block.setValue(offset, byteValue); + } + catch (Exception e) + { + MemoryViewUtil.openError(FPRenderingMessages.getString("FAILURE_WRITE_MEMORY"), "", e); //$NON-NLS-1$ //$NON-NLS-2$ + logError(FPRenderingMessages.getString("FAILURE_WRITE_MEMORY"), e); //$NON-NLS-1$ + } + } + + clearEditBuffer(); + } + + @Override + public void setEditedValue(BigInteger address, FPMemoryByte[] bytes) + { + assert Thread.currentThread().equals(Display.getDefault().getThread()) : FPRenderingMessages.getString("CALLED_ON_NON_DISPATCH_THREAD"); //$NON-NLS-1$ + fEditBuffer.put(address, bytes); + Rendering.this.redrawPanes(); + } + } + + public void setVisibleAddressBar(boolean visible) + { + fAddressBarControl.setVisible(visible); + if (visible) + { + String selectedStr = "0x" + getCaretAddress().toString(16); //$NON-NLS-1$ + Text text = fAddressBar.getExpressionWidget(); + text.setText(selectedStr); + text.setSelection(0, text.getCharCount()); + fAddressBar.getExpressionWidget().setFocus(); + } + + layout(true); + layoutPanes(); + } + + public void setDirty(boolean needRefresh) + { + fCacheDirty = needRefresh; + } + + public boolean isDirty() + { + return fCacheDirty; + } + + @Override + public void dispose() + { + DebugPlugin.getDefault().removeDebugEventListener(this); + if (fViewportCache != null) + { + fViewportCache.dispose(); + fViewportCache = null; + } + super.dispose(); + } + + class Selection implements FPIMemorySelection + { + private BigInteger fStartHigh = null; + private BigInteger fStartLow = null; + + private BigInteger fEndHigh = null; + private BigInteger fEndLow = null; + + @Override + public void clear() + { + fEndHigh = fEndLow = fStartHigh = fStartLow = null; + redrawPanes(); + } + + @Override + public boolean hasSelection() + { + return fStartHigh != null && fStartLow != null && fEndHigh != null && fEndLow != null; + } + + @Override + public boolean isSelected(BigInteger address) + { + // Do we have valid start and end addresses? + + if (getEnd() == null || getStart() == null) return false; + + // If end is greater than start + + if (getEnd().compareTo(getStart()) >= 0) + { + // If address is greater-than-or-equal-to start and less then end, return true + if (address.compareTo(getStart()) >= 0 && address.compareTo(getEnd()) < 0) return true; + } + + // If start is greater than end + + else if (getStart().compareTo(getEnd()) >= 0) + { + // If address is greater-than-or-equal-to zero and less than start, return true + if (address.compareTo(getEnd()) >= 0 && address.compareTo(getStart()) < 0) return true; + } + + return false; + } + + // Set selection start + + @Override + public void setStart(BigInteger high, BigInteger low) + { + if (high == null && low == null) + { + if (fStartHigh != null && fStartLow != null) + { + fStartHigh = null; + fStartLow = null; + redrawPanes(); + } + + return; + } + + boolean changed = false; + + if (fStartHigh == null || !high.equals(fStartHigh)) + { + fStartHigh = high; + changed = true; + } + + if (fStartLow == null || !low.equals(fStartLow)) + { + fStartLow = low; + changed = true; + } + + if (changed) redrawPanes(); + } + + // Set selection end + + @Override + public void setEnd(BigInteger high, BigInteger low) + { + if (high == null && low == null) + { + if (fEndHigh != null && fEndLow != null) + { + fEndHigh = null; + fEndLow = null; + redrawPanes(); + } + + return; + } + + boolean changed = false; + + if (fEndHigh == null || !high.equals(fEndHigh)) + { + fEndHigh = high; + changed = true; + } + + if (fEndLow == null || !low.equals(fEndLow)) + { + fEndLow = low; + changed = true; + } + + if (changed) redrawPanes(); + } + + @Override + public BigInteger getHigh() + { + if (!hasSelection()) return null; + return getStart().max(getEnd()); + } + + @Override + public BigInteger getLow() + { + if (!hasSelection()) return null; + return getStart().min(getEnd()); + } + + @Override + public BigInteger getStart() + { + // If there is no start, return null + if (fStartHigh == null) return null; + + // If there is no end, return the high address of the start + if (fEndHigh == null) return fStartHigh; + + // If Start High/Low equal End High/Low, return a low start and high end + if (fStartHigh.equals(fEndHigh) && fStartLow.equals(fEndLow)) return fStartLow; + + BigInteger differenceEndToStartHigh = fEndHigh.subtract(fStartHigh).abs(); + BigInteger differenceEndToStartLow = fEndHigh.subtract(fStartLow).abs(); + + // Return the start high or start low based on which creates a larger selection + if (differenceEndToStartHigh.compareTo(differenceEndToStartLow) > 0) + return fStartHigh; + + return fStartLow; + } + + @Override + public BigInteger getStartLow() + { + return fStartLow; + } + + @Override + public BigInteger getEnd() + { + // If there is no end, return null + if (fEndHigh == null) return null; + + // *** Temporary for debugging *** + + if (fStartHigh == null || fStartLow == null) + { + return null; + } + + // If Start High/Low equal End High/Low, return a low start and high end + if (fStartHigh.equals(fEndHigh) && fStartLow.equals(fEndLow)) return fStartHigh; + + BigInteger differenceStartToEndHigh = fStartHigh.subtract(fEndHigh).abs(); + BigInteger differenceStartToEndLow = fStartHigh.subtract(fEndLow).abs(); + + // Return the start high or start low based on which creates a larger selection + if (differenceStartToEndHigh.compareTo(differenceStartToEndLow) >= 0) + return fEndHigh; + + return fEndLow; + } + } + + public void setPaneVisible(int pane, boolean visible) + { + switch (pane) + { + case PANE_ADDRESS: + fAddressPane.setPaneVisible(visible); + break; + case PANE_DATA: + fDataPane.setPaneVisible(visible); + break; + } + + fireSettingsChanged(); + layoutPanes(); + } + + public boolean getPaneVisible(int pane) + { + switch (pane) + { + case PANE_ADDRESS: + return fAddressPane.isPaneVisible(); + case PANE_DATA: + return fDataPane.isPaneVisible(); + default: + return false; + } + } + + protected void packColumns() + { + int availableWidth = Rendering.this.getSize().x; + + if (fAddressPane.isPaneVisible()) + { + availableWidth -= fAddressPane.computeSize(0, 0).x; + availableWidth -= Rendering.this.getRenderSpacing() * 2; + } + + int combinedWidth = 0; + + if (fDataPane.isPaneVisible()) combinedWidth += fDataPane.getCellWidth(); + + if (getColumnsSetting() == Rendering.COLUMNS_AUTO_SIZE_TO_FIT) + { + if (combinedWidth == 0) + fColumnCount = 0; + else + { + fColumnCount = availableWidth / combinedWidth; + if (fColumnCount == 0) fColumnCount = 1; // Paint one column even if only part can show in view + } + } + else + fColumnCount = getColumnsSetting(); + + try + { + // Update the number of bytes per row; the max/min scroll range and the current thumbnail position. + + fBytesPerRow = getCharsPerColumn() * getColumnCount(); + getVerticalBar().setMinimum(1); + + // scrollbar maximum range is Integer.MAX_VALUE. + + getVerticalBar().setMaximum(getMaxScrollRange().min(BigInteger.valueOf(Integer.MAX_VALUE)).intValue()); + getVerticalBar().setIncrement(1); + getVerticalBar().setPageIncrement(this.getRowCount() - 1); + + // FIXME: conversion of slider to scrollbar + // fScrollBar.setToolTipText(Rendering.this.getAddressString(fViewportAddress)); + + setScrollSelection(); + } + catch (Exception e) + { + // FIXME precautionary + } + + Rendering.this.redraw(); + Rendering.this.redrawPanes(); + } + + public FPAbstractPane[] getRenderingPanes() + { + return new FPAbstractPane[] { fAddressPane, fDataPane }; + } + + public int getCellPadding() + { + return fCellPadding; + } + + protected int getRenderSpacing() + { + return fPaneSpacing; + } + + public void refresh() + { + if (!this.isDisposed()) + { + if (this.isVisible() && getViewportCache() != null) + { + getViewportCache().refresh(); + } + else + { + setDirty(true); + fParent.updateRenderingLabels(); + } + } + } + + protected void archiveDeltas() + { + this.getViewportCache().archiveDeltas(); + } + + public void gotoAddress(BigInteger address) + { + // Ensure that the GoTo address is within the addressable range + + if ((address.compareTo(this.getMemoryBlockStartAddress()) < 0) || (address.compareTo(this.getMemoryBlockEndAddress()) > 0)) + return; + + fViewportAddress = address; + + // Reset the caret and selection state (no caret and no selection) + + fCaretAddress = null; + fSelection = new Selection(); + + redrawPanes(); + } + + public void setViewportStartAddress(BigInteger newAddress) + { + fViewportAddress = newAddress; + } + + public BigInteger getViewportStartAddress() + { + return fViewportAddress; + } + + public BigInteger getViewportEndAddress() + { + return fViewportAddress.add(BigInteger.valueOf(this.getBytesPerRow() * getRowCount() / getAddressableSize())); + } + + public String getAddressString(BigInteger address) + { + StringBuffer addressString = new StringBuffer(address.toString(16).toUpperCase()); + + for (int chars = getAddressBytes() * 2 - addressString.length(); chars > 0; chars--) + addressString.insert(0, '0'); + + addressString.insert(0, "0x"); //$NON-NLS-1$ + + return addressString.toString(); + } + + protected int getAddressBytes() + { + return fParent.getAddressSize(); + } + + public Control getAddressBarControl() + { + return fAddressBarControl; + } + + public int getColumnCount() + { + return fColumnCount; + } + + public int getColumnsSetting() + { + return fColumnsSetting; + } + + protected void setBytesPerRow(int count) + { + fBytesPerRow = count; + } + + protected void setColumnCount(int count) + { + fColumnCount = count; + } + + public void setColumnsSetting(int columns) + { + if (fColumnsSetting != columns) + { + fColumnsSetting = columns; + fireSettingsChanged(); + layoutPanes(); + } + } + + protected void ensureVisible(BigInteger address) + { + BigInteger viewportStart = this.getViewportStartAddress(); + BigInteger viewportEnd = this.getViewportEndAddress(); + + boolean isAddressBeforeViewportStart = address.compareTo(viewportStart) < 0; + boolean isAddressAfterViewportEnd = address.compareTo(viewportEnd) > 0; + + if (isAddressBeforeViewportStart || isAddressAfterViewportEnd) gotoAddress(address); + } + + protected int getRowCount() + { + int rowCount = 0; + Control panes[] = getRenderingPanes(); + for (int i = 0; i < panes.length; i++) + if (panes[i] instanceof FPAbstractPane) + rowCount = Math.max(rowCount, ((FPAbstractPane) panes[i]).getRowCount()); + + return rowCount; + } + + protected int getBytesPerRow() + { + return fBytesPerRow; + } + + protected int getAddressableCellsPerRow() + { + return getBytesPerRow() / getAddressableSize(); + } + + public int getAddressesPerColumn() + { + return this.getCharsPerColumn() / getAddressableSize(); + } + + /** + * @return Set current scroll selection + */ + protected void setScrollSelection() + { + BigInteger selection = getViewportStartAddress().divide(BigInteger.valueOf(getAddressableCellsPerRow())); + + fScrollSelection = rows2scrollbar(selection); + getVerticalBar().setSelection(fScrollSelection); + } + + /** + * compute the maximum scrolling range. + * + * @return number of lines that rendering can display + */ + private BigInteger getMaxScrollRange() + { + BigInteger difference = getMemoryBlockEndAddress().subtract(getMemoryBlockStartAddress()).add(BigInteger.ONE); + BigInteger maxScrollRange = difference.divide(BigInteger.valueOf(getAddressableCellsPerRow())); + if (maxScrollRange.multiply(BigInteger.valueOf(getAddressableCellsPerRow())).compareTo(difference) != 0) + maxScrollRange = maxScrollRange.add(BigInteger.ONE); + + // Support targets with an addressable size greater than 1 + + maxScrollRange = maxScrollRange.divide(BigInteger.valueOf(getAddressableSize())); + return maxScrollRange; + } + + /** + * The scroll range is limited by SWT. Because it can be less than the number + * of rows (of memory) that we need to display, we need an arithmetic mapping. + * + * @return ratio this function returns how many rows a scroll bar unit + * represents. The number will be some fractional value, up to but + * not exceeding the value 1. I.e., when the scroll range exceeds + * the row range, we use a 1:1 mapping. + */ + private final BigDecimal getScrollRatio() + { + BigInteger maxRange = getMaxScrollRange(); + if (maxRange.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) + { + return new BigDecimal(maxRange).divide(BigDecimal.valueOf(Integer.MAX_VALUE), SCROLL_CONVERSION_PRECISION); + } + + return BigDecimal.ONE; + } + + /** + * Convert memory row units to scroll bar units. The scroll range is limited + * by SWT. Because it can be less than the number of rows (of memory) that + * we need to display, we need an arithmetic mapping. + * + * @param rows + * units of memory + * @return scrollbar units + */ + private int rows2scrollbar(BigInteger rows) + { + return new BigDecimal(rows).divide(getScrollRatio(), SCROLL_CONVERSION_PRECISION).intValue(); + } + + /** + * Convert scroll bar units to memory row units. The scroll range is limited + * by SWT. Because it can be less than the number of rows (of memory) that + * we need to display, we need an arithmetic mapping. + * + * @param scrollbarUnits + * scrollbar units + * @return number of rows of memory + */ + BigInteger scrollbar2rows(int scrollbarUnits) + { + return getScrollRatio().multiply(BigDecimal.valueOf(scrollbarUnits), SCROLL_CONVERSION_PRECISION).toBigInteger(); + } + + /** + * @return start address of the memory block + */ + protected BigInteger getMemoryBlockStartAddress() + { + if (fMemoryBlockStartAddress == null) + fMemoryBlockStartAddress = fParent.getMemoryBlockStartAddress(); + if (fMemoryBlockStartAddress == null) + fMemoryBlockStartAddress = BigInteger.ZERO; + + return fMemoryBlockStartAddress; + } + + /** + * @return end address of the memory block + */ + protected BigInteger getMemoryBlockEndAddress() + { + if (fMemoryBlockEndAddress == null) + fMemoryBlockEndAddress = fParent.getMemoryBlockEndAddress(); + + return fMemoryBlockEndAddress; + } + + public FPDataType getFPDataType() + { + return fFPDataType; + } + + public void setFPDataType(FPDataType numberType) + { + if (fFPDataType == numberType) return; + + fFPDataType = numberType; + fireSettingsChanged(); + layoutPanes(); + } + + public int getUpdateMode() + { + return fUpdateMode; + } + + public void setUpdateMode(int fUpdateMode) + { + this.fUpdateMode = fUpdateMode; + } + + protected String getCharacterSet(int mode) + { + switch (mode) + { + case Rendering.TEXT_UTF8: + return "UTF8"; //$NON-NLS-1$ + + case Rendering.TEXT_UTF16: + return "UTF16"; //$NON-NLS-1$ + + case Rendering.TEXT_USASCII: + return "US-ASCII"; //$NON-NLS-1$ + + case Rendering.TEXT_ISO_8859_1: + default: + return "ISO-8859-1"; //$NON-NLS-1$ + } + } + + public int getBytesPerCharacter() + { + return 1; + } + + public boolean isTargetLittleEndian() + { + return fIsTargetLittleEndian; + } + + public void setTargetLittleEndian(boolean littleEndian) + { + if (fIsTargetLittleEndian == littleEndian) return; + + fParent.setTargetMemoryLittleEndian(littleEndian); + fIsTargetLittleEndian = littleEndian; + + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + fireSettingsChanged(); + layoutPanes(); + } + }); + } + + public boolean isDisplayLittleEndian() + { + return fIsDisplayLittleEndian; + } + + public void setDisplayLittleEndian(boolean isLittleEndian) + { + if (fIsDisplayLittleEndian == isLittleEndian) return; + fIsDisplayLittleEndian = isLittleEndian; + fireSettingsChanged(); + + Display.getDefault().asyncExec(new Runnable() + { + @Override + public void run() + { + layoutPanes(); + } + }); + } + + public int getCharsPerColumn() + { + return fCharsPerColumn; + } + + public int getDisplayedPrecision() + { + return fDisplayedPrecision; + } + + // Set the number of precision digits that are displayed in the view + + public void setDisplayedPrecision(int displayedPrecision) + { + if (fDisplayedPrecision != displayedPrecision) + { + fDisplayedPrecision = displayedPrecision; + fCharsPerColumn = charsPerColumn(); + fireSettingsChanged(); + layoutPanes(); + } + } + + protected void redrawPane(int paneId) + { + if (!isDisposed() && this.isVisible()) + { + FPAbstractPane pane = null; + + if (paneId == Rendering.PANE_ADDRESS) + { + pane = fAddressPane; + } + else if (paneId == Rendering.PANE_DATA) + { + pane = fDataPane; + } + + if (pane != null && pane.isPaneVisible()) + { + pane.redraw(); + pane.setRowCount(); + if (pane.isFocusControl()) pane.updateTheCaret(); + } + } + + fParent.updateRenderingLabels(); + } + + protected void redrawPanes() + { + if (!isDisposed() && this.isVisible()) + { + if (fAddressPane.isPaneVisible()) + { + fAddressPane.redraw(); + fAddressPane.setRowCount(); + if (fAddressPane.isFocusControl()) fAddressPane.updateTheCaret(); + } + + if (fDataPane.isPaneVisible()) + { + fDataPane.redraw(); + fDataPane.setRowCount(); + if (fDataPane.isFocusControl()) fDataPane.updateTheCaret(); + } + } + + fParent.updateRenderingLabels(); + } + + void layoutPanes() + { + packColumns(); + layout(true); + + redraw(); + redrawPanes(); + } + + void fireSettingsChanged() + { + fAddressPane.settingsChanged(); + fDataPane.settingsChanged(); + } + + protected void copyAddressToClipboard() + { + Clipboard clip = null; + + try + { + clip = new Clipboard(getDisplay()); + + String addressString = "0x" + getCaretAddress().toString(16); //$NON-NLS-1$ + + TextTransfer plainTextTransfer = TextTransfer.getInstance(); + clip.setContents(new Object[] { addressString }, new Transfer[] { plainTextTransfer }); + } + finally + { + if (clip != null) + { + clip.dispose(); + } + } + } + + // Given an array of bytes, the data type and endianness, return a scientific notation string representation + + public String sciNotationString(FPMemoryByte byteArray[], FPDataType fpDataType, boolean isLittleEndian) + { + StringBuffer textString = null; + + // Check the byte array for readability + + for (int index = 0; index < byteArray.length; index++) + if (!byteArray[index].isReadable()) + return FPutilities.fillString(fCharsPerColumn, '?'); + + // Convert the byte array to a floating point value and check to see if it's within the range + // of the data type. If the valid range is exceeded, set string to "-Infinity" or "Infinity". + + ByteOrder byteOrder = isLittleEndian ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN; + + if (fpDataType == FPDataType.FLOAT) + { + float floatValue = ByteBuffer.wrap(FPutilities.memoryBytesToByteArray(byteArray)).order(byteOrder).getFloat(); + floatValue = FPutilities.floatLimitCheck(floatValue); + + if (floatValue == Float.NEGATIVE_INFINITY) + textString = new StringBuffer("-Infinity"); //$NON-NLS-1$ + + if (floatValue == Float.POSITIVE_INFINITY) + textString = new StringBuffer(" Infinity"); //$NON-NLS-1$ + } + + if (fpDataType == FPDataType.DOUBLE) + { + double doubleValue = ByteBuffer.wrap(FPutilities.memoryBytesToByteArray(byteArray)).order(byteOrder).getDouble(); + doubleValue = FPutilities.doubleLimitCheck(doubleValue); + + if (doubleValue == Double.NEGATIVE_INFINITY) + textString = new StringBuffer("-Infinity"); //$NON-NLS-1$ + + if (doubleValue == Double.POSITIVE_INFINITY) + textString = new StringBuffer(" Infinity"); //$NON-NLS-1$ + } + + // If we do not already have a StringBuffer value, Convert the value to + // a string. In any case, pad the string with spaces to the cell width. + + if (textString == null) + textString = new StringBuffer(FPutilities.byteArrayToSciNotation(fpDataType, isLittleEndian, byteArray, fDisplayedPrecision)); + + return (textString.append(FPutilities.fillString(fCharsPerColumn - textString.length(), getPaddingCharacter()))).toString(); + } + + // Convert the floating point edit buffer string to a byte array and update memory + + public void convertAndUpdateCell(BigInteger memoryAddress, String editBuffer) + { + if (editBuffer != null && editBuffer.length() > 0) + { + // Convert the edit buffer string to byte arrays + + byte[] targetByteArray = new byte[getFPDataType().getByteLength()]; + + targetByteArray = FPutilities.floatingStringToByteArray(getFPDataType(), editBuffer, getFPDataType().getBitsize()); + + // If we're in little endian mode, reverse the bytes, which is required + // due to lower-level internal conversion when written to memory. + + if (fIsDisplayLittleEndian) + targetByteArray = FPutilities.reverseByteOrder(targetByteArray); + + FPMemoryByte[] newMemoryBytes = new FPMemoryByte[targetByteArray.length]; + + for (int index = 0; index < targetByteArray.length; index++) + { + newMemoryBytes[index] = new FPMemoryByte(targetByteArray[index]); + newMemoryBytes[index].setBigEndian(!isTargetLittleEndian()); + newMemoryBytes[index].setEdited(true); + newMemoryBytes[index].setChanged(true); + } + + // Apply the change and make it visible in the view + + getViewportCache().setEditedValue(memoryAddress, newMemoryBytes); + getViewportCache().writeEditBuffer(); + redraw(); + } + else + { + // The edit buffer string is null or has a zero length. + + final String errorText = NLS.bind(FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_POPUP_TEXT"), "<blanks>"); //$NON-NLS-1$ //$NON-NLS-2$ + + try + { + // Restore the previous value + setEditBuffer(new StringBuffer(fDataPane.bytesToSciNotation(getBytes(fCaretAddress, getFPDataType().getByteLength())))); + } + catch (DebugException e) + { + e.printStackTrace(); + } + + // Put together the pop-up window components and show the user the error + + String statusString = FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_STATUS"); //$NON-NLS-1$ + Status status = new Status(IStatus.ERROR, FPRenderingPlugin.getUniqueIdentifier(), statusString); + FPutilities.popupMessage(FPRenderingMessages.getString("FPRendering.ERROR_FPENTRY_POPUP_TITLE"), errorText, status); //$NON-NLS-1$ + } + } + + // Getter/setter for Insert Mode state + + public void setInsertMode(boolean insertMode) + { + this.fEditInserMode = insertMode; + } + + public boolean insertMode() + { + return fEditInserMode; + } + + // Getter/setter for cell edit state: true = we're in cell edit mode; false = we're not in cell edit mode + + public boolean isEditingCell() + { + return fCellEditState; + } + + public void setEditingCell(boolean state) + { + this.fCellEditState = state; + } + + // Getter/setter for the address of the cell currently being edited + + public BigInteger getCellEditAddress() + { + return cellEditAddress; + } + + public void setCellEditAddress(BigInteger cellEditAddress) + { + this.cellEditAddress = cellEditAddress; + } + + // Getter/Setter for the memory address of the cell currently being edited + + public BigInteger getMemoryAddress() + { + return memoryAddress; + } + + public void setMemoryAddress(BigInteger memoryAddress) + { + this.memoryAddress = memoryAddress; + } + + // Getter/setter for storing the raw/uninterpreted/not-converted-to-scientific-notation text entry string + + public StringBuffer getEditBuffer() + { + return fEditBuffer; + } + + public void setEditBuffer(StringBuffer cellChars) + { + this.fEditBuffer = cellChars; + } + + // Enter cell-edit mode + + public void startCellEditing(BigInteger cellAddress, BigInteger memoryAddress, String editString) + { + setEditBuffer(new StringBuffer(editString)); + setCellEditAddress(cellAddress); + setMemoryAddress(memoryAddress); + setEditingCell(true); + } + + // Exit cell-edit mode + + public void endCellEditing() + { + setEditingCell(false); + setCellEditAddress(null); + setMemoryAddress(null); + setEditBuffer(null); + + } + + // Floating point number edit mode status-line display: 'true' = display edit mode, 'false' clear edit mode + + public void displayEditModeIndicator(final boolean indicatorON) + { + UIJob job = new UIJob("FP Renderer Edit Indicator") //$NON-NLS-1$ + { + @Override + public IStatus runInUIThread(IProgressMonitor monitor) + { + String statusLineMessage; + IViewPart viewInstance = null; + + if (indicatorON) + { + // Construct the edit mode message + statusLineMessage = NLS.bind(FPRenderingMessages.getString("FPRendering.EDIT_MODE"), //$NON-NLS-1$ + (insertMode() ? FPRenderingMessages.getString("FPRendering.EDIT_MODE_INSERT") : //$NON-NLS-1$ + FPRenderingMessages.getString("FPRendering.EDIT_MODE_OVERWRITE"))); //$NON-NLS-1$ + } + else + { + // 'null' = clear the message + statusLineMessage = null; + } + + // Get the window and page references + + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window == null) return Status.OK_STATUS; + + IWorkbenchPage page = window.getActivePage(); + if (page == null) return Status.OK_STATUS; + + // Update (or clear) the Workbench status line when the Memory and Memory Browser views are in focus + + viewInstance = page.findView("org.eclipse.debug.ui.MemoryView"); // TODO: programmatically retrieve ID //$NON-NLS-1$ + + if (viewInstance != null) + viewInstance.getViewSite().getActionBars().getStatusLineManager().setMessage(statusLineMessage); + + viewInstance = page.findView("org.eclipse.cdt.debug.ui.memory.memorybrowser.MemoryBrowser"); // TODO: programmatically retrieve ID //$NON-NLS-1$ + + if (viewInstance != null) + viewInstance.getViewSite().getActionBars().getStatusLineManager().setMessage(statusLineMessage); + + return Status.OK_STATUS; + } + }; + + job.setSystem(true); + job.schedule(); + } + + // Calculate memory address from the cell address + + public BigInteger cellToMemoryAddress(BigInteger cellAddress) + { + BigInteger vpStart = getViewportStartAddress(); + BigInteger colChars = BigInteger.valueOf(getCharsPerColumn()); + BigInteger dtBytes = BigInteger.valueOf(getFPDataType().getByteLength()); + + return vpStart.add(((cellAddress.subtract(vpStart)).divide(colChars)).multiply(dtBytes)); + } +} diff --git a/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/messages.properties b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/messages.properties new file mode 100644 index 00000000000..eba849c7373 --- /dev/null +++ b/memory/org.eclipse.cdt.debug.ui.memory.floatingpoint/src/org/eclipse/cdt/debug/ui/memory/floatingpoint/messages.properties @@ -0,0 +1,68 @@ +############################################################################### +# Copyright (c) 2009, 2012 Wind River Systems 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 +############################################################################### + +FPRendering.ADDRESS=Address +FPRendering.CALLED_ON_NON_DISPATCH_THREAD=Called on non-dispatch thread +FPRendering.COLUMN_COUNT=Columns +FPRendering.COLUMN_COUNT_AUTO=Auto Size to Fill +FPRendering.COLUMN_COUNT_1=1 +FPRendering.COLUMN_COUNT_2=2 +FPRendering.COLUMN_COUNT_4=4 +FPRendering.COLUMN_COUNT_8=8 +FPRendering.COLUMN_COUNT_16=16 +FPRendering.COLUMN_COUNT_32=32 +FPRendering.COLUMN_COUNT_64=64 +FPRendering.COLUMN_COUNT_128=128 +FPRendering.COLUMN_COUNT_CUSTOM=Custom ... +FPRendering.COPY_ADDRESS=Copy Address +FPRendering.DATA=Data +FPRendering.DISPLAYED_PRECISION_4=Four (4) significant digits +FPRendering.DISPLAYED_PRECISION_8=Eight (8) significant digits +FPRendering.DISPLAYED_PRECISION_16=Sixteen (16) significant digits +FPRendering.EDIT_MODE=Editing: {0} +FPRendering.EDIT_MODE_INSERT=Replace existing value +FPRendering.EDIT_MODE_OVERWRITE=Overwrite number (in-place) +FPRendering.ENDIAN=Endian +FPRendering.ENDIAN_BIG=Big +FPRendering.ENDIAN_LITTLE=Little +FPRendering.ERROR_FPENTRY_POPUP_TEXT="{0}" is an invalid floating point number.\rThe previous value has been restored. +FPRendering.ERROR_FPENTRY_POPUP_TITLE=Floating point number error +FPRendering.ERROR_FPENTRY_STATUS=Invalid floating point number +FPRendering.FAILURE_APPEND_SELECTION=Failed to append selection. +FPRendering.FAILURE_COPY_OPERATION=Failed copy operation. +FPRendering.FAILURE_DETERMINE_ADDRESS_SIZE=Failed to determine address size. +FPRendering.FAILURE_DETERMINE_CELL_LOCATION=Failed to determine cell location. +FPRendering.FAILURE_PAINT=Failed to paint. +FPRendering.FAILURE_POSITION_CURSOR=Failed to position cursor. +FPRendering.FAILURE_READ_MEMORY=Failed reading memory. +FPRendering.FAILURE_RETRIEVE_BASE_ADDRESS=Failure in retrieving base address. +FPRendering.FAILURE_RETRIEVE_START_ADDRESS=Failure in retrieving start address. +FPRendering.FAILURE_START_SELECTION=Failed to start selection. +FPRendering.FAILURE_WRITE_MEMORY=Error writing memory. +FPRendering.FLOATING_POINT_32=32-bit Single Precision +FPRendering.FLOATING_POINT_64=64-bit Double Precision +FPRendering.GO_TO_ADDRESS=Go To Address +FPRendering.INFINITY=Infinity +FPRendering.ISO-8859-1=ISO-8859-1 +FPRendering.NUMBER_TYPE=Floating Point Type +FPRendering.NAN=NaN +FPRendering.PANES=Panes +FPRendering.PRECISION=Displayed Precision +FPRendering.REFRESH=Refresh +FPRendering.RENDERING_NAME=Floating Point +FPRendering.RESET_TO_BASE_ADDRESS=Reset To Base Address +FPRendering.UPDATE_ALWAYS=Always +FPRendering.UPDATE_MANUAL=Manual +FPRendering.UPDATE_ON_BREAKPOINT=On Breakpoint +FPRendering.UPDATEMODE=Update Mode +FPRendering.USASCII=US-ASCII +FPRendering.UTF16=UTF-16 +FPRendering.UTF8=UTF-8l
\ No newline at end of file diff --git a/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.properties b/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.properties index b9b90abb371..fe3740d2c43 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.properties +++ b/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.properties @@ -24,7 +24,7 @@ providerName=Eclipse CDT updateSiteName=Eclipse CDT update site # "description" property - description of the feature -description=Additional features for debug Memory View - traditional rendering, Find/Replace, Import/Export. Source code. +description=Additional features for debug Memory View - traditional rendering, floating-point rendering, Find/Replace, Import/Export. Source code. # "licenseURL" property - URL of the "Feature License" # do not translate value - just change to point to a locale-specific HTML page diff --git a/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.xml b/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.xml index e23ed14c442..c64eb902375 100644 --- a/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.xml +++ b/memory/org.eclipse.cdt.debug.ui.memory.source-feature/feature.xml @@ -31,6 +31,13 @@ version="0.0.0"
unpack="false"/>
+ <plugin
+ id="org.eclipse.cdt.debug.ui.memory.floatingpoint.source"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
<plugin
id="org.eclipse.cdt.debug.ui.memory.transport.source"
download-size="0"
|