mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Implementation of the DSF Disassembly View (bug227743)
This commit is contained in:
parent
5474268d37
commit
cc153db8ba
73 changed files with 13585 additions and 11 deletions
1
plugins/org.eclipse.dd.dsf.debug.ui/.options
Normal file
1
plugins/org.eclipse.dd.dsf.debug.ui/.options
Normal file
|
@ -0,0 +1 @@
|
||||||
|
org.eclipse.dd.dsf.debug.ui/debug = false
|
|
@ -1,7 +1,7 @@
|
||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: Debug Services Framework Debug UI
|
Bundle-Name: %pluginName
|
||||||
Bundle-Vendor: Eclipse.org
|
Bundle-Vendor: %providerName
|
||||||
Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui; singleton:=true
|
Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui; singleton:=true
|
||||||
Bundle-Version: 1.0.0.qualifier
|
Bundle-Version: 1.0.0.qualifier
|
||||||
Bundle-Activator: org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin
|
Bundle-Activator: org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin
|
||||||
|
@ -18,7 +18,15 @@ Require-Bundle: org.eclipse.ui,
|
||||||
org.eclipse.dd.dsf.ui,
|
org.eclipse.dd.dsf.ui,
|
||||||
org.eclipse.dd.dsf.debug,
|
org.eclipse.dd.dsf.debug,
|
||||||
org.eclipse.cdt.core,
|
org.eclipse.cdt.core,
|
||||||
org.eclipse.cdt.debug.ui
|
org.eclipse.cdt.debug.core,
|
||||||
|
org.eclipse.cdt.debug.ui,
|
||||||
|
org.eclipse.jface.text;bundle-version="3.4.0",
|
||||||
|
org.eclipse.ui.editors;bundle-version="3.4.0",
|
||||||
|
org.eclipse.ui.workbench.texteditor;bundle-version="3.4.0",
|
||||||
|
org.eclipse.ui.ide;bundle-version="3.4.0",
|
||||||
|
org.eclipse.cdt.ui;bundle-version="5.0.0",
|
||||||
|
org.eclipse.core.expressions;bundle-version="3.4.0",
|
||||||
|
org.eclipse.core.filesystem;bundle-version="1.2.0"
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Export-Package:
|
Export-Package:
|
||||||
org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel,
|
org.eclipse.dd.dsf.debug.internal.provisional.ui.viewmodel,
|
||||||
|
|
BIN
plugins/org.eclipse.dd.dsf.debug.ui/icons/disassembly.gif
Normal file
BIN
plugins/org.eclipse.dd.dsf.debug.ui/icons/disassembly.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 145 B |
|
@ -1,5 +1,5 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Copyright (c) 2006 Wind River Systems and others.
|
# Copyright (c) 2006, 2008 Wind River Systems and others.
|
||||||
# All rights reserved. This program and the accompanying materials
|
# All rights reserved. This program and the accompanying materials
|
||||||
# are made available under the terms of the Eclipse Public License v1.0
|
# are made available under the terms of the Eclipse Public License v1.0
|
||||||
# which accompanies this distribution, and is available at
|
# which accompanies this distribution, and is available at
|
||||||
|
@ -8,6 +8,21 @@
|
||||||
# Contributors:
|
# Contributors:
|
||||||
# Wind River Systems - initial API and implementation
|
# Wind River Systems - initial API and implementation
|
||||||
###############################################################################
|
###############################################################################
|
||||||
pluginName=DSDP/DD Debugger Services Framework (DSF) Debug UI
|
pluginName=Debug Services Framework Debug UI
|
||||||
providerName=Eclipse.org
|
providerName=Eclipse.org
|
||||||
|
|
||||||
|
# disassembly
|
||||||
|
disassemblyPreferencePage.name = DSF Disassembly
|
||||||
|
disassemblyView.name= DSF Disassembly
|
||||||
|
|
||||||
|
command.gotoPC.name=Go to Program Counter
|
||||||
|
command.gotoPC.description=Navigate to current program counter
|
||||||
|
command.gotoAddress.name=Go to Address...
|
||||||
|
command.gotoAddress.description=Navigate to address
|
||||||
|
command.gotoSymbol.name=Go to Symbol...
|
||||||
|
command.gotoSymbol.description=Navigate to symbolic address
|
||||||
|
|
||||||
|
commandContext.name= In DSF Disassembly
|
||||||
|
commandContext.description= When debugging in assembly mode
|
||||||
|
|
||||||
|
action.breakpointProperties.label = Breakpoint Properties...
|
||||||
|
|
|
@ -278,5 +278,86 @@
|
||||||
id="org.eclipse.dd.dsf.debug.ui.viewmodel.moduleDetailPaneFactory">
|
id="org.eclipse.dd.dsf.debug.ui.viewmodel.moduleDetailPaneFactory">
|
||||||
</detailFactories>
|
</detailFactories>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
|
<extension point="org.eclipse.ui.commands">
|
||||||
|
<command
|
||||||
|
categoryId="org.eclipse.debug.ui.category.run"
|
||||||
|
description="%command.gotoPC.description"
|
||||||
|
id="org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoPC"
|
||||||
|
name="%command.gotoPC.name"/>
|
||||||
|
<command
|
||||||
|
categoryId="org.eclipse.debug.ui.category.run"
|
||||||
|
description="%command.gotoAddress.description"
|
||||||
|
id="org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoAddress"
|
||||||
|
name="%command.gotoAddress.name"/>
|
||||||
|
<command
|
||||||
|
categoryId="org.eclipse.debug.ui.category.run"
|
||||||
|
description="%command.gotoSymbol.description"
|
||||||
|
id="org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoSymbol"
|
||||||
|
name="%command.gotoSymbol.name"/>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<extension point="org.eclipse.ui.bindings">
|
||||||
|
<key sequence="HOME"
|
||||||
|
contextId="org.eclipse.dd.dsf.debug.ui.disassembly.context"
|
||||||
|
commandId="org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoPC"
|
||||||
|
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
|
||||||
|
<key sequence="M1+G"
|
||||||
|
contextId="org.eclipse.dd.dsf.debug.ui.disassembly.context"
|
||||||
|
commandId="org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoAddress"
|
||||||
|
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
|
||||||
|
<key sequence="M1+M2+G"
|
||||||
|
contextId="org.eclipse.dd.dsf.debug.ui.disassembly.context"
|
||||||
|
commandId="org.eclipse.dd.dsf.debug.ui.disassembly.commands.gotoSymbol"
|
||||||
|
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.ui.contexts">
|
||||||
|
<context
|
||||||
|
description="%commandContext.description"
|
||||||
|
id="org.eclipse.dd.dsf.debug.ui.disassembly.context"
|
||||||
|
name="%commandContext.name"
|
||||||
|
parentId="org.eclipse.debug.ui.debugging">
|
||||||
|
</context>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.core.runtime.preferences">
|
||||||
|
<initializer class="org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences.DisassemblyPreferenceConstants$Initializer"/>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.ui.views">
|
||||||
|
<view
|
||||||
|
category="org.eclipse.debug.ui"
|
||||||
|
class="org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyView"
|
||||||
|
icon="icons/disassembly.gif"
|
||||||
|
id="org.eclipse.dd.dsf.debug.ui.disassembly.view"
|
||||||
|
name="%disassemblyView.name">
|
||||||
|
</view>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.ui.preferencePages">
|
||||||
|
<page
|
||||||
|
class="org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences.DisassemblyPreferencePage"
|
||||||
|
category="org.eclipse.debug.ui.DebugPreferencePage"
|
||||||
|
name="%disassemblyPreferencePage.name"
|
||||||
|
id="org.eclipse.dd.dsf.debug.ui.disassembly.preferencePage"/>
|
||||||
|
</extension>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.ui.popupMenus">
|
||||||
|
<viewerContribution
|
||||||
|
id="org.eclipse.dd.dsf.debug.ui.disassemblyRulerActions"
|
||||||
|
targetID="#DisassemblyPartRulerContext">
|
||||||
|
<action
|
||||||
|
class="org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.BreakpointPropertiesRulerActionDelegate"
|
||||||
|
id="org.eclipse.dd.dsf.debug.ui.disassembly.breakpointProperties"
|
||||||
|
label="%action.breakpointProperties.label"
|
||||||
|
menubarPath="debug">
|
||||||
|
</action>
|
||||||
|
</viewerContribution>
|
||||||
|
</extension>
|
||||||
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.eclipse.dd.dsf.debug.internal.ui;
|
package org.eclipse.dd.dsf.debug.internal.ui;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceDocumentProvider;
|
||||||
import org.eclipse.jface.resource.ImageDescriptor;
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
@ -17,8 +18,11 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin {
|
||||||
private static DsfDebugUIPlugin plugin;
|
private static DsfDebugUIPlugin plugin;
|
||||||
|
|
||||||
// BundleContext of this plugin
|
// BundleContext of this plugin
|
||||||
private static BundleContext fgBundleContext;
|
private static BundleContext fgBundleContext;
|
||||||
|
|
||||||
|
// The document provider for source documents in the disassembly.
|
||||||
|
private SourceDocumentProvider fSourceDocumentProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor
|
* The constructor
|
||||||
*/
|
*/
|
||||||
|
@ -35,6 +39,7 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin {
|
||||||
plugin = this;
|
plugin = this;
|
||||||
fgBundleContext = context;
|
fgBundleContext = context;
|
||||||
|
|
||||||
|
fSourceDocumentProvider = new SourceDocumentProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -43,6 +48,8 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void stop(BundleContext context) throws Exception {
|
public void stop(BundleContext context) throws Exception {
|
||||||
|
fSourceDocumentProvider.dispose();
|
||||||
|
fSourceDocumentProvider = null;
|
||||||
plugin = null;
|
plugin = null;
|
||||||
super.stop(context);
|
super.stop(context);
|
||||||
}
|
}
|
||||||
|
@ -75,4 +82,8 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin {
|
||||||
public static ImageDescriptor getImageDescriptor(String path) {
|
public static ImageDescriptor getImageDescriptor(String path) {
|
||||||
return imageDescriptorFromPlugin(PLUGIN_ID, path);
|
return imageDescriptorFromPlugin(PLUGIN_ID, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SourceDocumentProvider getSourceDocumentProvider() {
|
||||||
|
return getDefault().fSourceDocumentProvider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.core.runtime.Plugin;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
|
import org.eclipse.jface.resource.ImageRegistry;
|
||||||
|
import org.eclipse.swt.SWTException;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.osgi.framework.Bundle;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract image registry that allows for defining fallback paths for images.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractImageRegistry extends ImageRegistry {
|
||||||
|
private HashMap<String, String> fPlugins = new HashMap<String, String>();
|
||||||
|
private HashMap<String, String[]> fLocations = new HashMap<String, String[]>();
|
||||||
|
private URL fBaseUrl;
|
||||||
|
|
||||||
|
protected AbstractImageRegistry(Plugin plugin) {
|
||||||
|
fBaseUrl = plugin.getBundle().getEntry("/"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the key for a local image, that must be found below the icons directory
|
||||||
|
* in the plugin.
|
||||||
|
* @param key Key by which the image can be referred by.
|
||||||
|
* @param dir Directory relative to icons/
|
||||||
|
* @param name The name of the file defining the icon. The name will be used as
|
||||||
|
* key.
|
||||||
|
*/
|
||||||
|
protected void localImage(String key, String dir, String name) {
|
||||||
|
if (dir== null || dir.equals(""))//$NON-NLS-1$
|
||||||
|
fLocations.put(key, new String[] {"icons/" + name}); //$NON-NLS-1$
|
||||||
|
else
|
||||||
|
fLocations.put(key, new String[] {"icons/" + dir + "/" + name}); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the key for a non-local image, that must be found below the icons directory
|
||||||
|
* of some plugin.
|
||||||
|
* @param key Key by which the image can be referred by.
|
||||||
|
* @param plugin The plugin id, where the icon is searched.
|
||||||
|
* @param dirs A couple of directories below icons/ in the plugin. If loading fails,
|
||||||
|
* the next dir will be taken as fallback.
|
||||||
|
* @param name The name of the file defining the icon. The name will be used as
|
||||||
|
* key.
|
||||||
|
*/
|
||||||
|
protected void externalImage(String key, String plugin, String[] dirs, String name) {
|
||||||
|
if (plugin != null) {
|
||||||
|
fPlugins.put(key, plugin);
|
||||||
|
}
|
||||||
|
String[] locations = new String[dirs.length];
|
||||||
|
for (int i = 0; i < dirs.length; i++) {
|
||||||
|
String dir = dirs[i];
|
||||||
|
if (dir== null || dir.equals(""))//$NON-NLS-1$
|
||||||
|
locations[i] = "icons/" + name; //$NON-NLS-1$
|
||||||
|
else
|
||||||
|
locations[i] = "icons/" + dir + "/" + name; //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
fLocations.put(key, locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
// overrider
|
||||||
|
@Override
|
||||||
|
final public Image get(String key) {
|
||||||
|
Image i = super.get(key);
|
||||||
|
if (i != null) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageDescriptor d = createFileImageDescriptor(key);
|
||||||
|
if (d != null) {
|
||||||
|
put(key, d);
|
||||||
|
return super.get(key);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overrider
|
||||||
|
@Override
|
||||||
|
final public ImageDescriptor getDescriptor(String key) {
|
||||||
|
ImageDescriptor d = super.getDescriptor(key);
|
||||||
|
if (d != null) {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
d = createFileImageDescriptor(key);
|
||||||
|
if (d != null) {
|
||||||
|
put(key, d);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageDescriptor createFileImageDescriptor(String key) {
|
||||||
|
URL url = fBaseUrl;
|
||||||
|
String pluginId = fPlugins.get(key);
|
||||||
|
if (pluginId != null) {
|
||||||
|
Bundle bundle= Platform.getBundle(pluginId);
|
||||||
|
if (bundle != null) {
|
||||||
|
url = bundle.getEntry("/"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String[] locations= fLocations.get(key);
|
||||||
|
if (locations != null) {
|
||||||
|
for (int i = 0; i < locations.length; i++) {
|
||||||
|
String loc = locations[i];
|
||||||
|
URL full;
|
||||||
|
try {
|
||||||
|
full = new URL(url, loc);
|
||||||
|
ImageDescriptor candidate = ImageDescriptor.createFromURL(full);
|
||||||
|
if (candidate != null && candidate.getImageData() != null) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
DsfDebugUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, "Malformed Icon URL", e)); //$NON-NLS-1$
|
||||||
|
} catch (SWTException e) {
|
||||||
|
// try the next one.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.AddressRangePosition;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourcePosition;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.source.IAnnotationHover;
|
||||||
|
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||||
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerInfo;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerInfoExtension;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerListener;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A vertical ruler column to display the instruction address.
|
||||||
|
*/
|
||||||
|
public class AddressRulerColumn extends DisassemblyRulerColumn implements IVerticalRulerInfo, IVerticalRulerInfoExtension, IAnnotationHover {
|
||||||
|
|
||||||
|
private int fRadix;
|
||||||
|
private boolean fShowRadixPrefix;
|
||||||
|
private String fRadixPrefix;
|
||||||
|
private int fNumberOfDigits;
|
||||||
|
private int fAddressSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public AddressRulerColumn() {
|
||||||
|
super(SWT.LEFT);
|
||||||
|
setShowRadixPrefix(true);
|
||||||
|
setAddressSize(32);
|
||||||
|
setRadix(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyRulerColumn#createDisplayString(int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String createDisplayString(int line) {
|
||||||
|
DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument();
|
||||||
|
int offset;
|
||||||
|
try {
|
||||||
|
offset = doc.getLineOffset(line);
|
||||||
|
AddressRangePosition pos = doc.getDisassemblyPosition(offset);
|
||||||
|
if (pos != null && pos.length > 0 && pos.offset == offset) {
|
||||||
|
if (pos.fValid) {
|
||||||
|
return getAddressText(pos.fAddressOffset);
|
||||||
|
} else {
|
||||||
|
return DOTS.substring(0, computeNumberOfCharacters());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SourcePosition srcPos = doc.getSourcePosition(offset);
|
||||||
|
if (srcPos != null && srcPos.fValid && srcPos.length > 0) {
|
||||||
|
int srcLine;
|
||||||
|
int nLines;
|
||||||
|
if (srcPos.fFileInfo.fSource == null) {
|
||||||
|
srcLine = srcPos.fLine;
|
||||||
|
nLines = srcLine+1;
|
||||||
|
} else {
|
||||||
|
int delta = offset-srcPos.offset;
|
||||||
|
int baseOffset = srcPos.fFileInfo.fSource.getLineOffset(srcPos.fLine);
|
||||||
|
srcLine = srcPos.fFileInfo.fSource.getLineOfOffset(baseOffset+delta);
|
||||||
|
nLines = srcPos.fFileInfo.fSource.getNumberOfLines();
|
||||||
|
}
|
||||||
|
String digitStr = Integer.toString(srcLine+1);
|
||||||
|
int maxDigits = (int)(Math.log(nLines)/Math.log(10))+1;
|
||||||
|
return SPACES.substring(0, maxDigits-digitStr.length())+digitStr;
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
// silently ignored
|
||||||
|
}
|
||||||
|
return ""; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyRulerColumn#computeNumberOfCharacters()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected int computeNumberOfCharacters() {
|
||||||
|
return fNumberOfDigits + (fRadixPrefix != null ? fRadixPrefix.length() : 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddressSize(int bits) {
|
||||||
|
fAddressSize= bits;
|
||||||
|
calculateNumberOfDigits();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadix(int radix) {
|
||||||
|
fRadix= radix;
|
||||||
|
calculateNumberOfDigits();
|
||||||
|
setShowRadixPrefix(fShowRadixPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateNumberOfDigits() {
|
||||||
|
fNumberOfDigits= BigInteger.ONE.shiftLeft(fAddressSize).subtract(BigInteger.ONE).toString(fRadix).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setShowRadixPrefix(boolean showRadixPrefix) {
|
||||||
|
fShowRadixPrefix = showRadixPrefix;
|
||||||
|
if (!fShowRadixPrefix) {
|
||||||
|
fRadixPrefix = null;
|
||||||
|
} else if (fRadix == 16) {
|
||||||
|
fRadixPrefix = "0x"; //$NON-NLS-1$
|
||||||
|
} else if (fRadix == 8) {
|
||||||
|
fRadixPrefix = "0"; //$NON-NLS-1$
|
||||||
|
} else {
|
||||||
|
fRadixPrefix = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getAddressText(BigInteger address) {
|
||||||
|
StringBuffer buf = new StringBuffer(fNumberOfDigits + 3);
|
||||||
|
if (fRadixPrefix != null) {
|
||||||
|
buf.append(fRadixPrefix);
|
||||||
|
}
|
||||||
|
String str = address.toString(fRadix);
|
||||||
|
for (int i=str.length(); i<fNumberOfDigits; ++i)
|
||||||
|
buf.append('0');
|
||||||
|
buf.append(str);
|
||||||
|
buf.append(':');
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
|
||||||
|
*/
|
||||||
|
public int getLineOfLastMouseButtonActivity() {
|
||||||
|
return getParentRuler().getLineOfLastMouseButtonActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int)
|
||||||
|
*/
|
||||||
|
public int toDocumentLineNumber(int y_coordinate) {
|
||||||
|
return getParentRuler().toDocumentLineNumber(y_coordinate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#getHover()
|
||||||
|
*/
|
||||||
|
public IAnnotationHover getHover() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#getModel()
|
||||||
|
*/
|
||||||
|
public IAnnotationModel getModel() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(org.eclipse.jface.text.source.IVerticalRulerListener)
|
||||||
|
*/
|
||||||
|
public void addVerticalRulerListener(IVerticalRulerListener listener) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(org.eclipse.jface.text.source.IVerticalRulerListener)
|
||||||
|
*/
|
||||||
|
public void removeVerticalRulerListener(IVerticalRulerListener listener) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IAnnotationHover#getHoverInfo(org.eclipse.jface.text.source.ISourceViewer, int)
|
||||||
|
*/
|
||||||
|
public String getHoverInfo(ISourceViewer sourceViewer, int line) {
|
||||||
|
DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument();
|
||||||
|
BigInteger address = doc.getAddressOfLine(line);
|
||||||
|
SourceFileInfo info = doc.getSourceInfo(address);
|
||||||
|
if (info != null) {
|
||||||
|
return info.fFile.getFullPath().toOSString();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.swt.dnd.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyDropAdapter
|
||||||
|
*/
|
||||||
|
public class DisassemblyDropAdapter extends DropTargetAdapter {
|
||||||
|
|
||||||
|
private DisassemblyPart fDisassembly;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New DisassemblyDropAdapter.
|
||||||
|
*/
|
||||||
|
public DisassemblyDropAdapter(DisassemblyPart disassembly) {
|
||||||
|
super();
|
||||||
|
fDisassembly = disassembly;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.dnd.DropTargetListener#drop(org.eclipse.swt.dnd.DropTargetEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void drop(final DropTargetEvent event) {
|
||||||
|
TransferData dataType = event.currentDataType;
|
||||||
|
if (isFileDataType(dataType)) {
|
||||||
|
// event.data is an array of strings which represent the absolute file pathes
|
||||||
|
assert event.data instanceof String[];
|
||||||
|
String fileNames[] = (String[])event.data;
|
||||||
|
dropFiles(fileNames);
|
||||||
|
} else if (isTextDataType(dataType)) {
|
||||||
|
// event.data is a string
|
||||||
|
assert event.data instanceof String;
|
||||||
|
String text = (String)event.data;
|
||||||
|
if (text.indexOf('/') != -1 || text.indexOf('.') != -1) {
|
||||||
|
dropFiles(new String[] { text });
|
||||||
|
} else {
|
||||||
|
dropText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.dnd.DropTargetListener#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dragEnter(DropTargetEvent event) {
|
||||||
|
event.detail = DND.DROP_COPY;
|
||||||
|
event.feedback = DND.FEEDBACK_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.dnd.DropTargetListener#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dragOver(DropTargetEvent event) {
|
||||||
|
event.detail = DND.DROP_COPY;
|
||||||
|
event.feedback = DND.FEEDBACK_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isFileDataType(TransferData dataType) {
|
||||||
|
return FileTransfer.getInstance().isSupportedType(dataType);
|
||||||
|
}
|
||||||
|
private static boolean isTextDataType(TransferData dataType) {
|
||||||
|
return TextTransfer.getInstance().isSupportedType(dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.dnd.DropTargetListener#dropAccept(org.eclipse.swt.dnd.DropTargetEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dropAccept(DropTargetEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.dnd.DropTargetListener#dragOperationChanged(org.eclipse.swt.dnd.DropTargetEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dragOperationChanged(DropTargetEvent event) {
|
||||||
|
event.detail = DND.DROP_COPY;
|
||||||
|
event.feedback = DND.FEEDBACK_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.dnd.DropTargetListener#dragLeave(org.eclipse.swt.dnd.DropTargetEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dragLeave(DropTargetEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop files.
|
||||||
|
* @param fileNames
|
||||||
|
*/
|
||||||
|
private void dropFiles(String[] fileNames) {
|
||||||
|
// open all the files
|
||||||
|
for (int i = 0; i < fileNames.length; i++) {
|
||||||
|
// get disassembly for file
|
||||||
|
fDisassembly.retrieveDisassembly(fileNames[i], 100, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop text.
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
|
private void dropText(String text) {
|
||||||
|
fDisassembly.gotoSymbol(text.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.ui.IActionBars;
|
||||||
|
import org.eclipse.ui.IEditorInput;
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
|
import org.eclipse.ui.IEditorSite;
|
||||||
|
import org.eclipse.ui.PartInitException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyEditor
|
||||||
|
*/
|
||||||
|
public class DisassemblyEditor extends DisassemblyPart implements IEditorPart {
|
||||||
|
|
||||||
|
private IEditorInput fInput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public DisassemblyEditor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyPart#getActionBars()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected IActionBars getActionBars() {
|
||||||
|
return getEditorSite().getActionBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IEditorPart#getEditorInput()
|
||||||
|
*/
|
||||||
|
public IEditorInput getEditorInput() {
|
||||||
|
return fInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IEditorPart#getEditorSite()
|
||||||
|
*/
|
||||||
|
public IEditorSite getEditorSite() {
|
||||||
|
return (IEditorSite)getSite();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
|
||||||
|
*/
|
||||||
|
public void init(IEditorSite site, IEditorInput input) throws PartInitException {
|
||||||
|
setSite(site);
|
||||||
|
setInput(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
|
||||||
|
*/
|
||||||
|
public void doSave(IProgressMonitor monitor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.ISaveablePart#doSaveAs()
|
||||||
|
*/
|
||||||
|
public void doSaveAs() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.ISaveablePart#isDirty()
|
||||||
|
*/
|
||||||
|
public boolean isDirty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.ISaveablePart#isSaveAsAllowed()
|
||||||
|
*/
|
||||||
|
public boolean isSaveAsAllowed() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.ISaveablePart#isSaveOnCloseNeeded()
|
||||||
|
*/
|
||||||
|
public boolean isSaveOnCloseNeeded() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// IReusableEditor interface
|
||||||
|
//
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IReusableEditor#setInput(org.eclipse.ui.IEditorInput)
|
||||||
|
*/
|
||||||
|
public void setInput(IEditorInput input) {
|
||||||
|
fInput = input;
|
||||||
|
// TLETODO [disassembly] initialization based on input
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyPart#closePart()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void closePart() {
|
||||||
|
getEditorSite().getPage().closeEditor(this, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CWordFinder;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
|
||||||
|
import org.eclipse.jface.text.hyperlink.IHyperlink;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hyperlink detector detecting words and numbers to support navigation
|
||||||
|
* to a symbolic address.
|
||||||
|
*/
|
||||||
|
class DisassemblyHyperlinkDetector extends AbstractHyperlinkDetector {
|
||||||
|
|
||||||
|
public class DisassemblyHyperlink implements IHyperlink {
|
||||||
|
|
||||||
|
private String fSymbol;
|
||||||
|
private IRegion fRegion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param symbol
|
||||||
|
* @param region
|
||||||
|
*/
|
||||||
|
public DisassemblyHyperlink(String symbol, IRegion region) {
|
||||||
|
fSymbol= symbol;
|
||||||
|
fRegion= region;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkRegion()
|
||||||
|
*/
|
||||||
|
public IRegion getHyperlinkRegion() {
|
||||||
|
return fRegion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.hyperlink.IHyperlink#getHyperlinkText()
|
||||||
|
*/
|
||||||
|
public String getHyperlinkText() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.hyperlink.IHyperlink#getTypeLabel()
|
||||||
|
*/
|
||||||
|
public String getTypeLabel() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.hyperlink.IHyperlink#open()
|
||||||
|
*/
|
||||||
|
public void open() {
|
||||||
|
if (fPart != null) {
|
||||||
|
fPart.gotoSymbol(fSymbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private DisassemblyPart fPart;
|
||||||
|
|
||||||
|
public DisassemblyHyperlinkDetector(DisassemblyPart part) {
|
||||||
|
fPart= part;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion, boolean)
|
||||||
|
*/
|
||||||
|
public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
|
||||||
|
IRegion region, boolean canShowMultipleHyperlinks) {
|
||||||
|
IDocument document= textViewer.getDocument();
|
||||||
|
if (document == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
IRegion wordRegion = CWordFinder.findWord(document, region.getOffset());
|
||||||
|
if (wordRegion != null && wordRegion.getLength() != 0) {
|
||||||
|
String word;
|
||||||
|
try {
|
||||||
|
word= document.get(wordRegion.getOffset(), wordRegion.getLength());
|
||||||
|
return new IHyperlink[] { new DisassemblyHyperlink(word, wordRegion) };
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.Plugin;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyImageRegistry
|
||||||
|
*/
|
||||||
|
public class DisassemblyImageRegistry extends AbstractImageRegistry {
|
||||||
|
private static List<Object[]> fStore = new ArrayList<Object[]>();
|
||||||
|
|
||||||
|
private static String add(String plugin, String[] dirs, String name) {
|
||||||
|
String key = plugin+'/'+dirs[0]+'/'+name;
|
||||||
|
fStore.add(new Object[] {key, plugin, dirs, name});
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String ORG_ECLIPSE_DEBUG_UI_PLUGIN_ID = "org.eclipse.debug.ui"; //$NON-NLS-1$
|
||||||
|
private static final String ORG_ECLIPSE_UI_PLUGIN_ID = "org.eclipse.ui"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
public static final String ICON_ToggleBreakpoint = add(ORG_ECLIPSE_DEBUG_UI_PLUGIN_ID, new String[] { "full/obj16"}, "brkp_obj.gif"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
public static final String ICON_Refresh_enabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/elcl16"}, "refresh_nav.gif"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
public static final String ICON_Refresh_disabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/dlcl16"}, "refresh_nav.gif"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
public static final String ICON_Copy_enabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/etool16"}, "copy_edit.gif"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
public static final String ICON_Copy_disabled = add(ORG_ECLIPSE_UI_PLUGIN_ID, new String[] {"full/dtool16"}, "copy_edit.gif"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
|
private static DisassemblyImageRegistry INSTANCE= new DisassemblyImageRegistry(DsfDebugUIPlugin.getDefault());
|
||||||
|
|
||||||
|
DisassemblyImageRegistry(Plugin plugin) {
|
||||||
|
super(plugin);
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize() {
|
||||||
|
for (Iterator<Object[]> iter = fStore.iterator(); iter.hasNext();) {
|
||||||
|
Object[] element = iter.next();
|
||||||
|
if (element.length == 2) {
|
||||||
|
String dir= (String) element[0];
|
||||||
|
String name= (String) element[1];
|
||||||
|
localImage(name, dir, name);
|
||||||
|
} else {
|
||||||
|
String key = (String) element[0];
|
||||||
|
String plugin= (String) element[1];
|
||||||
|
String[] dirs= (String[]) element[2];
|
||||||
|
String name= (String) element[3];
|
||||||
|
externalImage(key, plugin, dirs, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImageDescriptor getImageDescriptor(String key) {
|
||||||
|
return INSTANCE.getDescriptor(key);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
|
||||||
|
public final class DisassemblyMessages extends NLS {
|
||||||
|
|
||||||
|
private static final String BUNDLE_NAME = "org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages";//$NON-NLS-1$
|
||||||
|
|
||||||
|
private DisassemblyMessages() {
|
||||||
|
// Do not instantiate
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String Disassembly_action_ShowAddresses_label;
|
||||||
|
public static String Disassembly_action_ShowFunctionOffsets_label;
|
||||||
|
public static String Disassembly_action_ShowDisassembly_label;
|
||||||
|
public static String Disassembly_action_ShowSource_label;
|
||||||
|
public static String Disassembly_action_ShowSymbols_label;
|
||||||
|
public static String Disassembly_action_ShowSimplified_label;
|
||||||
|
public static String Disassembly_action_SourceSteppingMode_error;
|
||||||
|
public static String Disassembly_action_SourceSteppingMode_label;
|
||||||
|
public static String Disassembly_action_AssemblySteppingMode_label;
|
||||||
|
public static String Disassembly_action_RunToHere_label;
|
||||||
|
public static String Disassembly_action_SetPCToHere_label;
|
||||||
|
public static String Disassembly_action_GotoPC_label;
|
||||||
|
public static String Disassembly_action_GotoPC_tooltip;
|
||||||
|
public static String Disassembly_action_GotoAddress_label;
|
||||||
|
public static String Disassembly_action_GotoSymbol_label;
|
||||||
|
public static String Disassembly_action_Copy_label;
|
||||||
|
public static String Disassembly_action_SelectAll_label;
|
||||||
|
public static String Disassembly_action_BreakpointProperties_label;
|
||||||
|
public static String Disassembly_action_RemoveBreakpoint_label;
|
||||||
|
public static String Disassembly_action_AddBreakpoint_label;
|
||||||
|
public static String Disassembly_action_AddHWBreakpoint_label;
|
||||||
|
public static String Disassembly_action_AddTracepoint_label;
|
||||||
|
public static String Disassembly_action_DisableBreakpoint_label;
|
||||||
|
public static String Disassembly_action_EnableBreakpoint_label;
|
||||||
|
public static String Disassembly_action_WatchExpression_label;
|
||||||
|
public static String Disassembly_action_ShowInMemory_label;
|
||||||
|
public static String Disassembly_action_RefreshView_label;
|
||||||
|
public static String Disassembly_action_OpenPreferences_label;
|
||||||
|
public static String Disassembly_GotoAddressDialog_title;
|
||||||
|
public static String Disassembly_GotoAddressDialog_label;
|
||||||
|
public static String Disassembly_GotoAddressDialog_error_invalid_address;
|
||||||
|
public static String Disassembly_GotoAddressDialog_error_not_a_number;
|
||||||
|
public static String Disassembly_GotoSymbolDialog_title;
|
||||||
|
public static String Disassembly_GotoSymbolDialog_label;
|
||||||
|
public static String Disassembly_message_notConnected;
|
||||||
|
public static String Disassembly_log_error_retrieveFrameAddress;
|
||||||
|
public static String Disassembly_log_error_locateFile;
|
||||||
|
public static String Disassembly_log_error_accessLineInfo;
|
||||||
|
public static String Disassembly_log_error_noFileInfo;
|
||||||
|
public static String Disassembly_log_error_fileTooLarge;
|
||||||
|
public static String Disassembly_log_error_readFile;
|
||||||
|
public static String Disassembly_log_error_createVersion;
|
||||||
|
public static String Disassembly_log_error_retrieveDisassembly;
|
||||||
|
public static String Disassembly_log_error_showDisassembly;
|
||||||
|
public static String Disassembly_log_error_invalidSymbol;
|
||||||
|
public static String DisassemblyPreferencePage_startAddress;
|
||||||
|
public static String DisassemblyPreferencePage_endAddress;
|
||||||
|
public static String DisassemblyPreferencePage_addressRadix;
|
||||||
|
public static String DisassemblyPreferencePage_instructionRadix;
|
||||||
|
public static String DisassemblyPreferencePage_showAddressRadix;
|
||||||
|
public static String DisassemblyPreferencePage_showSource;
|
||||||
|
public static String DisassemblyPreferencePage_showSymbols;
|
||||||
|
public static String DisassemblyPreferencePage_simplifiedMnemonics;
|
||||||
|
public static String DisassemblyPreferencePage_error_not_a_number;
|
||||||
|
public static String DisassemblyPreferencePage_error_negative_number;
|
||||||
|
public static String DisassemblyPreferencePage_radix_octal;
|
||||||
|
public static String DisassemblyPreferencePage_radix_decimal;
|
||||||
|
public static String DisassemblyPreferencePage_radix_hexadecimal;
|
||||||
|
public static String DisassemblyPreferencePage_showFunctionOffsets;
|
||||||
|
public static String DisassemblyPreferencePage_showAddress;
|
||||||
|
public static String DisassemblyPreferencePage_useSourceOnlyMode;
|
||||||
|
public static String DisassemblyPreferencePage_useSourceOnlyMode_noteTtitle;
|
||||||
|
public static String DisassemblyPreferencePage_useSourceOnlyMode_noteMessage;
|
||||||
|
public static String DisassemblyPreferencePage_avoidReadBeforePC;
|
||||||
|
public static String DisassemblyIPAnnotation_primary;
|
||||||
|
public static String DisassemblyIPAnnotation_secondary;
|
||||||
|
public static String SourceReadingJob_name;
|
||||||
|
public static String SourceColorerJob_name;
|
||||||
|
public static String EditionFinderJob_name;
|
||||||
|
public static String EditionFinderJob_task_get_timestamp;
|
||||||
|
public static String EditionFinderJob_task_search_history;
|
||||||
|
|
||||||
|
static {
|
||||||
|
NLS.initializeMessages(BUNDLE_NAME, DisassemblyMessages.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
##########################################################################
|
||||||
|
# Copyright (c) 2007, 2008 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
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
Disassembly_action_ShowAddresses_label=Show Addresses
|
||||||
|
Disassembly_action_ShowFunctionOffsets_label=Show Function Offsets
|
||||||
|
Disassembly_action_ShowDisassembly_label=Show Disassembly of Source
|
||||||
|
Disassembly_action_ShowSource_label=Show Source
|
||||||
|
Disassembly_action_ShowSymbols_label=Show Symbols
|
||||||
|
Disassembly_action_ShowSimplified_label=Show Simplified Instructions
|
||||||
|
Disassembly_action_SourceSteppingMode_error=Cannot open editor for file
|
||||||
|
Disassembly_action_SourceSteppingMode_label=Source Stepping Mode
|
||||||
|
Disassembly_action_AssemblySteppingMode_label=Assembly Stepping Mode
|
||||||
|
Disassembly_action_RunToHere_label=Run to Here
|
||||||
|
Disassembly_action_SetPCToHere_label=Set PC to Here
|
||||||
|
Disassembly_action_GotoPC_label=Go to Program Counter
|
||||||
|
Disassembly_action_GotoPC_tooltip=Go to Current Program Counter
|
||||||
|
Disassembly_action_GotoAddress_label=Go to Address...
|
||||||
|
Disassembly_action_GotoSymbol_label=Go to Symbol...
|
||||||
|
Disassembly_action_Copy_label=&Copy
|
||||||
|
Disassembly_action_SelectAll_label=Select &All
|
||||||
|
Disassembly_action_BreakpointProperties_label=Breakpoint Properties...
|
||||||
|
Disassembly_action_RemoveBreakpoint_label=Remove Breakpoint
|
||||||
|
Disassembly_action_AddBreakpoint_label=Add Breakpoint
|
||||||
|
Disassembly_action_AddHWBreakpoint_label=Add Hardware Breakpoint
|
||||||
|
Disassembly_action_AddTracepoint_label=Add Tracepoint...
|
||||||
|
Disassembly_action_DisableBreakpoint_label=Disable Breakpoint
|
||||||
|
Disassembly_action_EnableBreakpoint_label=Enable Breakpoint
|
||||||
|
Disassembly_action_WatchExpression_label=Watch Expression
|
||||||
|
Disassembly_action_ShowInMemory_label=Show In Memory View
|
||||||
|
Disassembly_action_RefreshView_label=Re&fresh View
|
||||||
|
Disassembly_action_OpenPreferences_label=&Preferences...
|
||||||
|
|
||||||
|
Disassembly_GotoAddressDialog_title=Go to Address
|
||||||
|
Disassembly_GotoAddressDialog_label=Address:
|
||||||
|
Disassembly_GotoAddressDialog_error_invalid_address=Invalid address
|
||||||
|
Disassembly_GotoAddressDialog_error_not_a_number=Not a valid number format
|
||||||
|
|
||||||
|
Disassembly_GotoSymbolDialog_title=Go to Symbol
|
||||||
|
Disassembly_GotoSymbolDialog_label=Symbol:
|
||||||
|
|
||||||
|
Disassembly_message_notConnected=No debug context
|
||||||
|
|
||||||
|
Disassembly_log_error_retrieveFrameAddress=Error retrieving frame address
|
||||||
|
Disassembly_log_error_locateFile=Unable to locate file:\
|
||||||
|
Disassembly_log_error_accessLineInfo=Error accessing line information for:\
|
||||||
|
Disassembly_log_error_noFileInfo=Debug information not found for:\
|
||||||
|
Disassembly_log_error_fileTooLarge=Source file is too large to retrieve line information:\
|
||||||
|
Disassembly_log_error_readFile=Cannot read source file:\
|
||||||
|
Disassembly_log_error_createVersion=Cannot create version
|
||||||
|
Disassembly_log_error_retrieveDisassembly=Cannot retrieve disassembly for:\
|
||||||
|
Disassembly_log_error_showDisassembly=Error opening Disassembly
|
||||||
|
Disassembly_log_error_invalidSymbol=Cannot evaluate symbolic address ''{0}''
|
||||||
|
|
||||||
|
DisassemblyPreferencePage_startAddress=Start address
|
||||||
|
DisassemblyPreferencePage_endAddress=End address
|
||||||
|
DisassemblyPreferencePage_addressRadix=Address display format
|
||||||
|
DisassemblyPreferencePage_instructionRadix=Instruction display format
|
||||||
|
DisassemblyPreferencePage_showAddressRadix=Force radix prefixes
|
||||||
|
DisassemblyPreferencePage_showSource=Show source
|
||||||
|
DisassemblyPreferencePage_showSymbols=Show symbols
|
||||||
|
DisassemblyPreferencePage_simplifiedMnemonics=Use simplified instruction mnemonics
|
||||||
|
DisassemblyPreferencePage_error_not_a_number=Not a valid number format
|
||||||
|
DisassemblyPreferencePage_error_negative_number=Address cannot be negative
|
||||||
|
DisassemblyPreferencePage_radix_octal=Octal
|
||||||
|
DisassemblyPreferencePage_radix_decimal=Decimal
|
||||||
|
DisassemblyPreferencePage_radix_hexadecimal=Hexadecimal
|
||||||
|
DisassemblyPreferencePage_showFunctionOffsets=Show function offsets
|
||||||
|
DisassemblyPreferencePage_showAddress=Show instruction address
|
||||||
|
DisassemblyPreferencePage_useSourceOnlyMode=Use Disassembly Viewer when debugging in source stepping mode
|
||||||
|
DisassemblyPreferencePage_useSourceOnlyMode_noteTtitle=Note:
|
||||||
|
DisassemblyPreferencePage_useSourceOnlyMode_noteMessage=When this option is enabled, the Disassembly Viewer will be used to display source locations in a special "source-only" mode, instead of using the normal Source Editor.
|
||||||
|
DisassemblyPreferencePage_avoidReadBeforePC=Do not disassemble code before current program counter
|
||||||
|
|
||||||
|
DisassemblyIPAnnotation_primary=Debug Current Instruction Pointer
|
||||||
|
DisassemblyIPAnnotation_secondary=Debug Call Stack
|
||||||
|
|
||||||
|
SourceReadingJob_name=Reading source file
|
||||||
|
SourceColorerJob_name=Coloring source file
|
||||||
|
EditionFinderJob_name=Finding best match for source file
|
||||||
|
EditionFinderJob_task_get_timestamp=Retrieving module timestamp
|
||||||
|
EditionFinderJob_task_search_history=Searching local history
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,985 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2008 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextListener;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.jface.text.ITextViewerExtension;
|
||||||
|
import org.eclipse.jface.text.ITextViewerExtension5;
|
||||||
|
import org.eclipse.jface.text.IViewportListener;
|
||||||
|
import org.eclipse.jface.text.TextEvent;
|
||||||
|
import org.eclipse.jface.text.source.CompositeRuler;
|
||||||
|
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerColumn;
|
||||||
|
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||||
|
import org.eclipse.jface.viewers.SelectionChangedEvent;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.StyleRange;
|
||||||
|
import org.eclipse.swt.custom.StyledText;
|
||||||
|
import org.eclipse.swt.events.DisposeEvent;
|
||||||
|
import org.eclipse.swt.events.DisposeListener;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.events.MouseListener;
|
||||||
|
import org.eclipse.swt.events.MouseMoveListener;
|
||||||
|
import org.eclipse.swt.events.MouseTrackListener;
|
||||||
|
import org.eclipse.swt.events.PaintEvent;
|
||||||
|
import org.eclipse.swt.events.PaintListener;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.Font;
|
||||||
|
import org.eclipse.swt.graphics.FontMetrics;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.widgets.Canvas;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertical ruler column for use with disassembly parts.
|
||||||
|
* <p>
|
||||||
|
* Derived from {@link org.eclipse.jface.text.source.LineNumberRulerColumn}.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class DisassemblyRulerColumn implements IVerticalRulerColumn {
|
||||||
|
protected final static String DOTS = "......................................................................"; //$NON-NLS-1$
|
||||||
|
protected final static String SPACES = " "; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal listener class.
|
||||||
|
*/
|
||||||
|
class InternalListener implements IViewportListener, ITextListener, ISelectionChangedListener {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IViewportListener#viewportChanged(int)
|
||||||
|
*/
|
||||||
|
public void viewportChanged(int verticalPosition) {
|
||||||
|
if (verticalPosition != fScrollPos)
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see ITextListener#textChanged(TextEvent)
|
||||||
|
*/
|
||||||
|
public void textChanged(TextEvent event) {
|
||||||
|
|
||||||
|
if (updateNumberOfDigits()) {
|
||||||
|
computeIndentations();
|
||||||
|
layout(event.getViewerRedrawState());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!event.getViewerRedrawState())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fSensitiveToTextChanges || event.getDocumentEvent() == null)
|
||||||
|
postRedraw();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
|
||||||
|
*/
|
||||||
|
public void selectionChanged(SelectionChangedEvent event) {
|
||||||
|
postRedraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles all the mouse interaction in this line number ruler column.
|
||||||
|
*/
|
||||||
|
class MouseHandler implements MouseListener, MouseMoveListener, MouseTrackListener {
|
||||||
|
|
||||||
|
/** The cached view port size */
|
||||||
|
private int fCachedViewportSize;
|
||||||
|
/** The area of the line at which line selection started */
|
||||||
|
private IRegion fStartLine;
|
||||||
|
/** The number of the line at which line selection started */
|
||||||
|
private int fStartLineNumber;
|
||||||
|
/** The auto scroll direction */
|
||||||
|
private int fAutoScrollDirection;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseUp(MouseEvent event) {
|
||||||
|
// see bug 45700
|
||||||
|
if (event.button == 1) {
|
||||||
|
stopSelecting();
|
||||||
|
stopAutoScroll();
|
||||||
|
postRedraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseDown(MouseEvent event) {
|
||||||
|
fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
|
||||||
|
// see bug 45700
|
||||||
|
if (event.button == 1) {
|
||||||
|
startSelecting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseDoubleClick(MouseEvent event) {
|
||||||
|
fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
|
||||||
|
stopSelecting();
|
||||||
|
stopAutoScroll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseMove(MouseEvent event) {
|
||||||
|
if (!autoScroll(event)) {
|
||||||
|
int newLine = fParentRuler.toDocumentLineNumber(event.y);
|
||||||
|
expandSelection(newLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseEnter(MouseEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseExit(MouseEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseHover(MouseEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when line drag selection started. Adds mouse move and track
|
||||||
|
* listeners to this column's control.
|
||||||
|
*/
|
||||||
|
private void startSelecting() {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// select line
|
||||||
|
IDocument document = fCachedTextViewer.getDocument();
|
||||||
|
fStartLineNumber = fParentRuler.getLineOfLastMouseButtonActivity();
|
||||||
|
fStartLine = document.getLineInformation(fStartLineNumber);
|
||||||
|
fCachedTextViewer.setSelectedRange(fStartLine.getOffset(), fStartLine.getLength());
|
||||||
|
fCachedViewportSize = getVisibleLinesInViewport();
|
||||||
|
|
||||||
|
// prepare for drag selection
|
||||||
|
fCanvas.addMouseMoveListener(this);
|
||||||
|
fCanvas.addMouseTrackListener(this);
|
||||||
|
|
||||||
|
} catch (BadLocationException x) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when line drag selection stopped. Removes all previously
|
||||||
|
* installed listeners from this column's control.
|
||||||
|
*/
|
||||||
|
private void stopSelecting() {
|
||||||
|
// drag selection stopped
|
||||||
|
fCanvas.removeMouseMoveListener(this);
|
||||||
|
fCanvas.removeMouseTrackListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expands the line selection from the remembered start line to the
|
||||||
|
* given line.
|
||||||
|
*
|
||||||
|
* @param lineNumber
|
||||||
|
* the line to which to expand the selection
|
||||||
|
*/
|
||||||
|
private void expandSelection(int lineNumber) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
IDocument document = fCachedTextViewer.getDocument();
|
||||||
|
IRegion lineInfo = document.getLineInformation(lineNumber);
|
||||||
|
|
||||||
|
int start = Math.min(fStartLine.getOffset(), lineInfo.getOffset());
|
||||||
|
int end = Math.max(fStartLine.getOffset() + fStartLine.getLength(), lineInfo.getOffset()
|
||||||
|
+ lineInfo.getLength());
|
||||||
|
|
||||||
|
if (lineNumber < fStartLineNumber)
|
||||||
|
fCachedTextViewer.setSelectedRange(end, start - end);
|
||||||
|
else
|
||||||
|
fCachedTextViewer.setSelectedRange(start, end - start);
|
||||||
|
|
||||||
|
} catch (BadLocationException x) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when auto scrolling stopped. Clears the auto scroll direction.
|
||||||
|
*/
|
||||||
|
private void stopAutoScroll() {
|
||||||
|
fAutoScrollDirection = SWT.NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on drag selection.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* the mouse event caught by the mouse move listener
|
||||||
|
* @return <code>true</code> if scrolling happened, <code>false</code>
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
private boolean autoScroll(MouseEvent event) {
|
||||||
|
Rectangle area = fCanvas.getClientArea();
|
||||||
|
|
||||||
|
if (event.y > area.height) {
|
||||||
|
autoScroll(SWT.DOWN);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.y < 0) {
|
||||||
|
autoScroll(SWT.UP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
stopAutoScroll();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scrolls the viewer into the given direction.
|
||||||
|
*
|
||||||
|
* @param direction
|
||||||
|
* the scroll direction
|
||||||
|
*/
|
||||||
|
private void autoScroll(int direction) {
|
||||||
|
|
||||||
|
if (fAutoScrollDirection == direction)
|
||||||
|
return;
|
||||||
|
|
||||||
|
final int TIMER_INTERVAL = 5;
|
||||||
|
final Display display = fCanvas.getDisplay();
|
||||||
|
Runnable timer = null;
|
||||||
|
switch (direction) {
|
||||||
|
case SWT.UP:
|
||||||
|
timer = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (fAutoScrollDirection == SWT.UP) {
|
||||||
|
int top = getInclusiveTopIndex();
|
||||||
|
if (top > 0) {
|
||||||
|
fCachedTextViewer.setTopIndex(top - 1);
|
||||||
|
expandSelection(top - 1);
|
||||||
|
display.timerExec(TIMER_INTERVAL, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case SWT.DOWN:
|
||||||
|
timer = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (fAutoScrollDirection == SWT.DOWN) {
|
||||||
|
int top = getInclusiveTopIndex();
|
||||||
|
fCachedTextViewer.setTopIndex(top + 1);
|
||||||
|
expandSelection(top + 1 + fCachedViewportSize);
|
||||||
|
display.timerExec(TIMER_INTERVAL, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer != null) {
|
||||||
|
fAutoScrollDirection = direction;
|
||||||
|
display.timerExec(TIMER_INTERVAL, timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the viewer's first visible line, even if only partially
|
||||||
|
* visible.
|
||||||
|
*
|
||||||
|
* @return the viewer's first visible line
|
||||||
|
*/
|
||||||
|
private int getInclusiveTopIndex() {
|
||||||
|
if (fCachedTextWidget != null && !fCachedTextWidget.isDisposed()) {
|
||||||
|
int top = fCachedTextViewer.getTopIndex();
|
||||||
|
if ((fCachedTextWidget.getTopPixel() % fCachedTextWidget.getLineHeight()) != 0)
|
||||||
|
--top;
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This column's parent ruler */
|
||||||
|
private CompositeRuler fParentRuler;
|
||||||
|
/** Cached text viewer */
|
||||||
|
private ITextViewer fCachedTextViewer;
|
||||||
|
/** Cached text widget */
|
||||||
|
private StyledText fCachedTextWidget;
|
||||||
|
/** The columns canvas */
|
||||||
|
private Canvas fCanvas;
|
||||||
|
/** Cache for the actual scroll position in pixels */
|
||||||
|
private int fScrollPos;
|
||||||
|
/** The drawable for double buffering */
|
||||||
|
private Image fBuffer;
|
||||||
|
/** The internal listener */
|
||||||
|
private InternalListener fInternalListener = new InternalListener();
|
||||||
|
/** The font of this column */
|
||||||
|
private Font fFont;
|
||||||
|
/** The indentation cache */
|
||||||
|
private int[] fIndentation;
|
||||||
|
/** Indicates whether this column reacts on text change events */
|
||||||
|
private boolean fSensitiveToTextChanges = false;
|
||||||
|
/** The foreground color */
|
||||||
|
private Color fForeground;
|
||||||
|
/** The background color */
|
||||||
|
private Color fBackground;
|
||||||
|
/** Cached number of displayed digits */
|
||||||
|
private int fCachedNumberOfDigits = -1;
|
||||||
|
/** Flag indicating whether a relayout is required */
|
||||||
|
private boolean fRelayoutRequired = false;
|
||||||
|
/**
|
||||||
|
* Redraw runnable lock
|
||||||
|
*/
|
||||||
|
private Object fRunnableLock = new Object();
|
||||||
|
/**
|
||||||
|
* Redraw runnable state
|
||||||
|
*/
|
||||||
|
private boolean fIsRunnablePosted = false;
|
||||||
|
/**
|
||||||
|
* Redraw runnable
|
||||||
|
*/
|
||||||
|
private Runnable fRunnable = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
synchronized (fRunnableLock) {
|
||||||
|
fIsRunnablePosted = false;
|
||||||
|
}
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private boolean fAlignRight;
|
||||||
|
private boolean fPaintStyleBackground;
|
||||||
|
private boolean fPaintSelectionBackground;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new vertical ruler column.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public DisassemblyRulerColumn() {
|
||||||
|
this(SWT.LEFT);
|
||||||
|
// default constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisassemblyRulerColumn(int align) {
|
||||||
|
this(align, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisassemblyRulerColumn(int align, boolean paintSelection, boolean paintStyle) {
|
||||||
|
fAlignRight = (align & SWT.RIGHT) != 0;
|
||||||
|
fPaintSelectionBackground = paintSelection;
|
||||||
|
fPaintStyleBackground = paintStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the foreground color of this column.
|
||||||
|
*
|
||||||
|
* @param foreground
|
||||||
|
* the foreground color
|
||||||
|
*/
|
||||||
|
public void setForeground(Color foreground) {
|
||||||
|
fForeground = foreground;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the foreground color being used to print the line numbers.
|
||||||
|
*
|
||||||
|
* @return the configured foreground color
|
||||||
|
*/
|
||||||
|
protected Color getForeground() {
|
||||||
|
return fForeground;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the background color of this column.
|
||||||
|
*
|
||||||
|
* @param background
|
||||||
|
* the background color
|
||||||
|
*/
|
||||||
|
public void setBackground(Color background) {
|
||||||
|
fBackground = background;
|
||||||
|
if (fCanvas != null && !fCanvas.isDisposed())
|
||||||
|
fCanvas.setBackground(getBackground(fCanvas.getDisplay()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the System background color for list widgets.
|
||||||
|
*
|
||||||
|
* @param display
|
||||||
|
* the display
|
||||||
|
* @return the System background color for list widgets
|
||||||
|
*/
|
||||||
|
protected Color getBackground(Display display) {
|
||||||
|
if (fBackground == null)
|
||||||
|
return display.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
|
||||||
|
return fBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IVerticalRulerColumn#getControl()
|
||||||
|
*/
|
||||||
|
public Control getControl() {
|
||||||
|
return fCanvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IVerticalRuleColumnr#getWidth
|
||||||
|
*/
|
||||||
|
public int getWidth() {
|
||||||
|
return fIndentation[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the number of digits to be displayed. Returns <code>true</code>
|
||||||
|
* if the number of digits changed compared to the previous call of this
|
||||||
|
* method. If the method is called for the first time, the return value is
|
||||||
|
* also <code>true</code>.
|
||||||
|
*
|
||||||
|
* @return whether the number of digits has been changed
|
||||||
|
*/
|
||||||
|
protected boolean updateNumberOfDigits() {
|
||||||
|
if (fCachedTextViewer == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int digits = computeNumberOfCharacters();
|
||||||
|
|
||||||
|
if (fCachedNumberOfDigits != digits) {
|
||||||
|
fCachedNumberOfDigits = digits;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the real computation of the number of characters. The default
|
||||||
|
* implementation computes the number of digits for the line number.
|
||||||
|
* Subclasses may override this method if they need extra space on the ruler.
|
||||||
|
*
|
||||||
|
* @return the number of characters to be displayed on the ruler.
|
||||||
|
*/
|
||||||
|
protected int computeNumberOfCharacters() {
|
||||||
|
IDocument document = fCachedTextViewer.getDocument();
|
||||||
|
int lines= document == null ? 0 : document.getNumberOfLines();
|
||||||
|
|
||||||
|
int digits= 2;
|
||||||
|
while (lines > Math.pow(10, digits) - 1) {
|
||||||
|
++digits;
|
||||||
|
}
|
||||||
|
return digits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layouts the enclosing viewer to adapt the layout to changes of the size
|
||||||
|
* of the individual components.
|
||||||
|
*
|
||||||
|
* @param redraw
|
||||||
|
* <code>true</code> if this column can be redrawn
|
||||||
|
*/
|
||||||
|
protected void layout(boolean redraw) {
|
||||||
|
if (!redraw) {
|
||||||
|
fRelayoutRequired= true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fRelayoutRequired= false;
|
||||||
|
if (fCachedTextViewer instanceof ITextViewerExtension) {
|
||||||
|
ITextViewerExtension extension= (ITextViewerExtension) fCachedTextViewer;
|
||||||
|
Control control= extension.getControl();
|
||||||
|
if (control instanceof Composite && !control.isDisposed()) {
|
||||||
|
Composite composite= (Composite) control;
|
||||||
|
composite.layout(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the indentations for the given font and stores them in
|
||||||
|
* <code>fIndentation</code>.
|
||||||
|
*/
|
||||||
|
protected void computeIndentations() {
|
||||||
|
if (fCanvas == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GC gc= new GC(fCanvas);
|
||||||
|
try {
|
||||||
|
|
||||||
|
gc.setFont(fCanvas.getFont());
|
||||||
|
|
||||||
|
fIndentation= new int[fCachedNumberOfDigits + 1];
|
||||||
|
char[] digitStr= new char[fCachedNumberOfDigits + 1];
|
||||||
|
Arrays.fill(digitStr, '9');
|
||||||
|
Point p= gc.stringExtent(new String(digitStr, 0, fCachedNumberOfDigits + 1));
|
||||||
|
fIndentation[0]= p.x;
|
||||||
|
|
||||||
|
for (int i= 1; i <= fCachedNumberOfDigits; i++) {
|
||||||
|
p= gc.stringExtent(new String(digitStr, 0, i));
|
||||||
|
fIndentation[i]= fIndentation[0] - p.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
gc.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IVerticalRulerColumn#createControl(CompositeRuler, Composite)
|
||||||
|
*/
|
||||||
|
public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
|
||||||
|
|
||||||
|
fParentRuler= parentRuler;
|
||||||
|
fCachedTextViewer= parentRuler.getTextViewer();
|
||||||
|
fCachedTextWidget= fCachedTextViewer.getTextWidget();
|
||||||
|
|
||||||
|
fCanvas= new Canvas(parentControl, SWT.NONE);
|
||||||
|
fCanvas.setBackground(getBackground(fCanvas.getDisplay()));
|
||||||
|
fCanvas.setForeground(fForeground);
|
||||||
|
|
||||||
|
fCanvas.addPaintListener(new PaintListener() {
|
||||||
|
public void paintControl(PaintEvent event) {
|
||||||
|
if (fCachedTextViewer != null)
|
||||||
|
doubleBufferPaint(event.gc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fCanvas.addDisposeListener(new DisposeListener() {
|
||||||
|
public void widgetDisposed(DisposeEvent e) {
|
||||||
|
handleDispose();
|
||||||
|
fCachedTextViewer= null;
|
||||||
|
fCachedTextWidget= null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fCanvas.addMouseListener(new MouseHandler());
|
||||||
|
|
||||||
|
if (fCachedTextViewer != null) {
|
||||||
|
|
||||||
|
fCachedTextViewer.addViewportListener(fInternalListener);
|
||||||
|
fCachedTextViewer.addTextListener(fInternalListener);
|
||||||
|
fCachedTextViewer.getSelectionProvider().addSelectionChangedListener(fInternalListener);
|
||||||
|
|
||||||
|
if (fFont == null) {
|
||||||
|
if (fCachedTextWidget != null && !fCachedTextWidget.isDisposed())
|
||||||
|
fFont= fCachedTextWidget.getFont();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fFont != null)
|
||||||
|
fCanvas.setFont(fFont);
|
||||||
|
|
||||||
|
updateNumberOfDigits();
|
||||||
|
computeIndentations();
|
||||||
|
return fCanvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes the column's resources.
|
||||||
|
*/
|
||||||
|
protected void handleDispose() {
|
||||||
|
|
||||||
|
if (fCachedTextViewer != null) {
|
||||||
|
fCachedTextViewer.removeViewportListener(fInternalListener);
|
||||||
|
fCachedTextViewer.removeTextListener(fInternalListener);
|
||||||
|
fCachedTextViewer.getSelectionProvider().removeSelectionChangedListener(fInternalListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fBuffer != null) {
|
||||||
|
fBuffer.dispose();
|
||||||
|
fBuffer= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Double buffer drawing.
|
||||||
|
*
|
||||||
|
* @param dest
|
||||||
|
* the gc to draw into
|
||||||
|
*/
|
||||||
|
private void doubleBufferPaint(GC dest) {
|
||||||
|
|
||||||
|
Point size= fCanvas.getSize();
|
||||||
|
|
||||||
|
if (size.x <= 0 || size.y <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fBuffer != null) {
|
||||||
|
Rectangle r= fBuffer.getBounds();
|
||||||
|
if (r.width != size.x || r.height != size.y) {
|
||||||
|
fBuffer.dispose();
|
||||||
|
fBuffer= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fBuffer == null)
|
||||||
|
fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
|
||||||
|
|
||||||
|
GC gc= new GC(fBuffer);
|
||||||
|
gc.setFont(fCanvas.getFont());
|
||||||
|
if (fForeground != null)
|
||||||
|
gc.setForeground(fForeground);
|
||||||
|
|
||||||
|
try {
|
||||||
|
gc.setBackground(getBackground(fCanvas.getDisplay()));
|
||||||
|
gc.fillRectangle(0, 0, size.x, size.y);
|
||||||
|
|
||||||
|
if (fCachedTextViewer instanceof ITextViewerExtension5)
|
||||||
|
doPaint1(gc);
|
||||||
|
else
|
||||||
|
doPaint(gc);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
gc.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
dest.drawImage(fBuffer, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the viewport height in lines.
|
||||||
|
*
|
||||||
|
* @return the viewport height in lines
|
||||||
|
*/
|
||||||
|
protected int getVisibleLinesInViewport() {
|
||||||
|
Rectangle clArea= fCachedTextWidget.getClientArea();
|
||||||
|
return clArea.height / fCachedTextWidget.getLineHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the ruler column.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* the gc to draw into
|
||||||
|
*/
|
||||||
|
private void doPaint(GC gc) {
|
||||||
|
|
||||||
|
if (fCachedTextViewer == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fCachedTextWidget == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int firstLine= 0;
|
||||||
|
|
||||||
|
int topLine= fCachedTextWidget.getTopIndex();
|
||||||
|
fScrollPos= fCachedTextWidget.getTopPixel();
|
||||||
|
int lineheight= fCachedTextWidget.getLineHeight();
|
||||||
|
int partialLineHidden= fScrollPos % lineheight;
|
||||||
|
|
||||||
|
if (partialLineHidden > 0 && topLine > 0) // widgetTopLine shows the
|
||||||
|
// first fully visible line
|
||||||
|
--topLine;
|
||||||
|
|
||||||
|
int bottomLine;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
IRegion region= fCachedTextViewer.getVisibleRegion();
|
||||||
|
IDocument doc= fCachedTextViewer.getDocument();
|
||||||
|
|
||||||
|
if (doc == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
firstLine= doc.getLineOfOffset(region.getOffset());
|
||||||
|
if (firstLine > topLine)
|
||||||
|
topLine= firstLine;
|
||||||
|
|
||||||
|
bottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength());
|
||||||
|
|
||||||
|
} catch (BadLocationException x) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fSensitiveToTextChanges= bottomLine - topLine < getVisibleLinesInViewport();
|
||||||
|
|
||||||
|
int baselineBias= getBaselineBias(gc);
|
||||||
|
|
||||||
|
int topInset= fCachedTextViewer.getTopInset();
|
||||||
|
int y= topInset - partialLineHidden;
|
||||||
|
Point canvasSize= fCanvas.getSize();
|
||||||
|
Point selection= fCachedTextWidget.getSelection();
|
||||||
|
boolean selectedLine= false;
|
||||||
|
Color defaultForeground= gc.getForeground();
|
||||||
|
Color defaultBackground= gc.getBackground();
|
||||||
|
|
||||||
|
for (int line= topLine; y < canvasSize.y && line <= bottomLine; line++, y += lineheight) {
|
||||||
|
int widgetOffset= fCachedTextWidget.getOffsetAtLine(line);
|
||||||
|
if (fPaintSelectionBackground && widgetOffset >= selection.x && widgetOffset < selection.y) {
|
||||||
|
if (!selectedLine) {
|
||||||
|
selectedLine= true;
|
||||||
|
gc.setForeground(fCachedTextWidget.getSelectionForeground());
|
||||||
|
gc.setBackground(fCachedTextWidget.getSelectionBackground());
|
||||||
|
}
|
||||||
|
} else if (selectedLine) {
|
||||||
|
selectedLine= false;
|
||||||
|
gc.setForeground(defaultForeground);
|
||||||
|
gc.setBackground(defaultBackground);
|
||||||
|
}
|
||||||
|
if (selectedLine) {
|
||||||
|
gc.fillRectangle(0, y, canvasSize.x, lineheight);
|
||||||
|
} else if (fPaintStyleBackground && widgetOffset >= 0 && widgetOffset < fCachedTextWidget.getCharCount()) {
|
||||||
|
StyleRange style= fCachedTextWidget.getStyleRangeAtOffset(widgetOffset);
|
||||||
|
if (style != null && style.background != null) {
|
||||||
|
gc.setBackground(style.background);
|
||||||
|
gc.fillRectangle(0, y + baselineBias, canvasSize.x, lineheight - baselineBias);
|
||||||
|
gc.setBackground(defaultBackground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paintLine(line, y, lineheight, gc, fCachedTextWidget.getDisplay());
|
||||||
|
String s= createDisplayString(line);
|
||||||
|
int indentation= fAlignRight ? fIndentation[s.length()] : 0;
|
||||||
|
gc.drawString(s, indentation, y + baselineBias, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the string to be printed for <code>line</code>. The default
|
||||||
|
* implementation returns <code>Integer.toString(line + 1)</code>.
|
||||||
|
*
|
||||||
|
* @param line
|
||||||
|
* the line number for which the string is generated
|
||||||
|
* @return the string to be printed on the ruler column for <code>line</code>
|
||||||
|
*/
|
||||||
|
String createDisplayString(int line) {
|
||||||
|
return Integer.toString(line + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the ruler column. Uses <code>ITextViewerExtension5</code> for the
|
||||||
|
* implementation. Will replace <code>doPinat(GC)</code>.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* the gc to draw into
|
||||||
|
*/
|
||||||
|
private void doPaint1(GC gc) {
|
||||||
|
|
||||||
|
if (fCachedTextViewer == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ITextViewerExtension5 extension= (ITextViewerExtension5) fCachedTextViewer;
|
||||||
|
|
||||||
|
int widgetTopLine= fCachedTextWidget.getTopIndex();
|
||||||
|
fScrollPos= fCachedTextWidget.getTopPixel();
|
||||||
|
int lineheight= fCachedTextWidget.getLineHeight();
|
||||||
|
int partialLineHidden= fScrollPos % lineheight;
|
||||||
|
|
||||||
|
if (partialLineHidden > 0 && widgetTopLine > 0) // widgetTopLine shows
|
||||||
|
// the first fully
|
||||||
|
// visible line
|
||||||
|
--widgetTopLine;
|
||||||
|
|
||||||
|
int modelTopLine= extension.widgetLine2ModelLine(widgetTopLine);
|
||||||
|
int modelBottomLine= fCachedTextViewer.getBottomIndex();
|
||||||
|
if (modelBottomLine >= 0)
|
||||||
|
++modelBottomLine;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
IRegion region= extension.getModelCoverage();
|
||||||
|
IDocument doc= fCachedTextViewer.getDocument();
|
||||||
|
|
||||||
|
if (doc == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int coverageTopLine= doc.getLineOfOffset(region.getOffset());
|
||||||
|
if (coverageTopLine > modelTopLine || modelTopLine == -1)
|
||||||
|
modelTopLine= coverageTopLine;
|
||||||
|
|
||||||
|
int coverageBottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength());
|
||||||
|
if (coverageBottomLine < modelBottomLine || modelBottomLine == -1)
|
||||||
|
modelBottomLine= coverageBottomLine;
|
||||||
|
|
||||||
|
} catch (BadLocationException x) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fSensitiveToTextChanges= modelBottomLine - modelTopLine < getVisibleLinesInViewport();
|
||||||
|
|
||||||
|
int baselineBias= getBaselineBias(gc);
|
||||||
|
|
||||||
|
int topInset= fCachedTextViewer.getTopInset();
|
||||||
|
int y= topInset - partialLineHidden;
|
||||||
|
Point canvasSize= fCanvas.getSize();
|
||||||
|
Point selection= fCachedTextWidget.getSelection();
|
||||||
|
boolean selectedLine= false;
|
||||||
|
Color defaultForeground= gc.getForeground();
|
||||||
|
Color defaultBackground= gc.getBackground();
|
||||||
|
|
||||||
|
for (int modelLine= modelTopLine; y < canvasSize.y && modelLine <= modelBottomLine; modelLine++) {
|
||||||
|
|
||||||
|
// don't draw hidden (e.g. folded) lines
|
||||||
|
int widgetLine= extension.modelLine2WidgetLine(modelLine);
|
||||||
|
if (widgetLine == -1)
|
||||||
|
continue;
|
||||||
|
int widgetOffset= fCachedTextWidget.getOffsetAtLine(widgetLine);
|
||||||
|
if (fPaintSelectionBackground && widgetOffset >= selection.x && widgetOffset < selection.y) {
|
||||||
|
if (!selectedLine) {
|
||||||
|
selectedLine= true;
|
||||||
|
gc.setForeground(fCachedTextWidget.getSelectionForeground());
|
||||||
|
gc.setBackground(fCachedTextWidget.getSelectionBackground());
|
||||||
|
}
|
||||||
|
} else if (selectedLine) {
|
||||||
|
selectedLine= false;
|
||||||
|
gc.setForeground(defaultForeground);
|
||||||
|
gc.setBackground(defaultBackground);
|
||||||
|
}
|
||||||
|
if (selectedLine) {
|
||||||
|
gc.fillRectangle(0, y, canvasSize.x, lineheight);
|
||||||
|
} else if (fPaintStyleBackground && widgetOffset >= 0 && widgetOffset < fCachedTextWidget.getCharCount()) {
|
||||||
|
StyleRange style= fCachedTextWidget.getStyleRangeAtOffset(widgetOffset);
|
||||||
|
if (style != null && style.background != null) {
|
||||||
|
gc.setBackground(style.background);
|
||||||
|
gc.fillRectangle(0, y + baselineBias, canvasSize.x, lineheight - baselineBias);
|
||||||
|
gc.setBackground(defaultBackground);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paintLine(modelLine, y, lineheight, gc, fCachedTextWidget.getDisplay());
|
||||||
|
|
||||||
|
String s= createDisplayString(modelLine);
|
||||||
|
int indentation= fAlignRight ? fIndentation[s.length()] : 0;
|
||||||
|
gc.drawString(s, indentation, y + baselineBias, true);
|
||||||
|
y += lineheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the difference between the baseline of the widget and the
|
||||||
|
* baseline as specified by the font for <code>gc</code>. When drawing
|
||||||
|
* text, the returned bias should be added to obtain text line up on
|
||||||
|
* the correct base line of the text widget.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* the <code>GC</code> to get the font metrics from
|
||||||
|
* @return the baseline bias to use when drawing text that is line up with
|
||||||
|
* <code>fCachedTextWidget</code>
|
||||||
|
*/
|
||||||
|
private int getBaselineBias(GC gc) {
|
||||||
|
/*
|
||||||
|
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=62951 widget line
|
||||||
|
* height may be more than the font height used for the text,
|
||||||
|
* since font styles (bold, italics...) can have larger font metrics
|
||||||
|
* than the simple font used for the numbers.
|
||||||
|
*/
|
||||||
|
int widgetBaseline= fCachedTextWidget.getBaseline();
|
||||||
|
FontMetrics fm= gc.getFontMetrics();
|
||||||
|
int fontBaseline= fm.getAscent() + fm.getLeading();
|
||||||
|
Assert.isTrue(widgetBaseline >= fontBaseline);
|
||||||
|
int baselineBias= widgetBaseline - fontBaseline;
|
||||||
|
return baselineBias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paints the line. After this method is called the text is painted
|
||||||
|
* on top of the result of this method.
|
||||||
|
* <p>
|
||||||
|
* This default implementation does nothing.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param line
|
||||||
|
* the line of the document which the ruler is painted for
|
||||||
|
* @param y
|
||||||
|
* the y-coordinate of the box being painted for
|
||||||
|
* <code>line</code>, relative to <code>gc</code>
|
||||||
|
* @param lineheight
|
||||||
|
* the height of one line (and therefore of the box being
|
||||||
|
* painted)
|
||||||
|
* @param gc
|
||||||
|
* the drawing context the client may choose to draw on.
|
||||||
|
* @param display
|
||||||
|
* the display the drawing occurs on
|
||||||
|
*/
|
||||||
|
protected void paintLine(int line, int y, int lineheight, GC gc, Display display) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers a redraw in the display thread.
|
||||||
|
*/
|
||||||
|
protected final void postRedraw() {
|
||||||
|
if (fCanvas != null && !fCanvas.isDisposed()) {
|
||||||
|
Display d= fCanvas.getDisplay();
|
||||||
|
if (d != null) {
|
||||||
|
synchronized (fRunnableLock) {
|
||||||
|
if (fIsRunnablePosted)
|
||||||
|
return;
|
||||||
|
fIsRunnablePosted= true;
|
||||||
|
}
|
||||||
|
d.asyncExec(fRunnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IVerticalRulerColumn#redraw()
|
||||||
|
*/
|
||||||
|
public void redraw() {
|
||||||
|
|
||||||
|
if (fRelayoutRequired) {
|
||||||
|
layout(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fCanvas != null && !fCanvas.isDisposed()) {
|
||||||
|
GC gc= new GC(fCanvas);
|
||||||
|
doubleBufferPaint(gc);
|
||||||
|
gc.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IVerticalRulerColumn#setModel(IAnnotationModel)
|
||||||
|
*/
|
||||||
|
public void setModel(IAnnotationModel model) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IVerticalRulerColumn#setFont(Font)
|
||||||
|
*/
|
||||||
|
public void setFont(Font font) {
|
||||||
|
fFont= font;
|
||||||
|
if (fCanvas != null && !fCanvas.isDisposed()) {
|
||||||
|
fCanvas.setFont(fFont);
|
||||||
|
updateNumberOfDigits();
|
||||||
|
computeIndentations();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the parent (composite) ruler of this ruler column.
|
||||||
|
*
|
||||||
|
* @return the parent ruler
|
||||||
|
*/
|
||||||
|
protected CompositeRuler getParentRuler() {
|
||||||
|
return fParentRuler;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CWordFinder;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.Query;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.AddressRangePosition;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.LabelPosition;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourcePosition;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IExpressions;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IFormattedValues;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IFormattedValues.FormattedValueDMData;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IStack.IFrameDMContext;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextHover;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A text hover to evaluate registers and variables under the cursor.
|
||||||
|
*/
|
||||||
|
public class DisassemblyTextHover implements ITextHover {
|
||||||
|
|
||||||
|
private final DisassemblyPart fDisassemblyPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new disassembly text hover.
|
||||||
|
*/
|
||||||
|
public DisassemblyTextHover(DisassemblyPart part) {
|
||||||
|
fDisassemblyPart= part;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextHover#getHoverRegion(org.eclipse.jface.text.ITextViewer, int)
|
||||||
|
*/
|
||||||
|
public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
|
||||||
|
IDocument doc = textViewer.getDocument();
|
||||||
|
return CWordFinder.findWord(doc, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
|
||||||
|
*/
|
||||||
|
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
||||||
|
DisassemblyDocument doc = (DisassemblyDocument)textViewer.getDocument();
|
||||||
|
int offset = hoverRegion.getOffset();
|
||||||
|
AddressRangePosition pos;
|
||||||
|
try {
|
||||||
|
String ident = doc.get(offset, hoverRegion.getLength());
|
||||||
|
String value = null;
|
||||||
|
pos = doc.getModelPosition(offset);
|
||||||
|
if (pos instanceof SourcePosition) {
|
||||||
|
value = evaluateExpression(ident);
|
||||||
|
} else if (pos instanceof LabelPosition) {
|
||||||
|
value = evaluateExpression(ident);
|
||||||
|
} else if (pos instanceof DisassemblyPosition) {
|
||||||
|
// first, try to evaluate as register
|
||||||
|
value = evaluateRegister(ident);
|
||||||
|
if (value == null) {
|
||||||
|
// if this fails, try expression
|
||||||
|
value = evaluateExpression(ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value != null) {
|
||||||
|
return ident + " = " + value; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
if (DsfDebugUIPlugin.getDefault().isDebugging()) {
|
||||||
|
DsfDebugUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, "Internal Error", e)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate the given register.
|
||||||
|
* @param register
|
||||||
|
* @return register value or <code>null</code>
|
||||||
|
*/
|
||||||
|
private String evaluateRegister(String register) {
|
||||||
|
// TLETODO [disassembly] evaluate register
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate the given expression.
|
||||||
|
* @param expr
|
||||||
|
* @return expression value or <code>null</code>
|
||||||
|
*/
|
||||||
|
private String evaluateExpression(String expr) {
|
||||||
|
final IExpressions expressions= fDisassemblyPart.getService(IExpressions.class);
|
||||||
|
if (expressions == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final IFrameDMContext frameDmc= fDisassemblyPart.getTargetFrameContext();
|
||||||
|
if (frameDmc == null || !fDisassemblyPart.isSuspended()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
IExpressionDMContext exprDmc= expressions.createExpression(frameDmc, expr);
|
||||||
|
final FormattedValueDMContext valueDmc= expressions.getFormattedValueContext(exprDmc, IFormattedValues.NATURAL_FORMAT);
|
||||||
|
final DsfExecutor executor= fDisassemblyPart.getSession().getExecutor();
|
||||||
|
Query<FormattedValueDMData> query= new Query<FormattedValueDMData>() {
|
||||||
|
@Override
|
||||||
|
protected void execute(final DataRequestMonitor<FormattedValueDMData> rm) {
|
||||||
|
expressions.getFormattedExpressionValue(valueDmc, new DataRequestMonitor<FormattedValueDMData>(executor, rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
FormattedValueDMData data= getData();
|
||||||
|
rm.setData(data);
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}};
|
||||||
|
|
||||||
|
executor.execute(query);
|
||||||
|
FormattedValueDMData data= null;
|
||||||
|
try {
|
||||||
|
data= query.get();
|
||||||
|
} catch (InterruptedException exc) {
|
||||||
|
} catch (ExecutionException exc) {
|
||||||
|
}
|
||||||
|
if (data != null) {
|
||||||
|
return data.getFormattedValue();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||||
|
import org.eclipse.jface.action.IMenuManager;
|
||||||
|
import org.eclipse.jface.action.Separator;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.ui.IActionBars;
|
||||||
|
import org.eclipse.ui.IMemento;
|
||||||
|
import org.eclipse.ui.ISelectionListener;
|
||||||
|
import org.eclipse.ui.IViewPart;
|
||||||
|
import org.eclipse.ui.IViewSite;
|
||||||
|
import org.eclipse.ui.IWorkbenchPart;
|
||||||
|
import org.eclipse.ui.PartInitException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyView
|
||||||
|
*/
|
||||||
|
public class DisassemblyView extends DisassemblyPart implements IViewPart {
|
||||||
|
|
||||||
|
private ISelectionListener fDebugViewListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public DisassemblyView() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyPart#getActionBars()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected IActionBars getActionBars() {
|
||||||
|
return getViewSite().getActionBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IViewPart#getViewSite()
|
||||||
|
*/
|
||||||
|
public IViewSite getViewSite() {
|
||||||
|
return (IViewSite)getSite();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite)
|
||||||
|
*/
|
||||||
|
public void init(IViewSite site) throws PartInitException {
|
||||||
|
setSite(site);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IViewPart#init(org.eclipse.ui.IViewSite, org.eclipse.ui.IMemento)
|
||||||
|
*/
|
||||||
|
public void init(IViewSite site, IMemento memento) throws PartInitException {
|
||||||
|
setSite(site);
|
||||||
|
site.getPage().addSelectionListener(IDebugUIConstants.ID_DEBUG_VIEW, fDebugViewListener= new ISelectionListener() {
|
||||||
|
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
|
||||||
|
updateDebugContext();
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IViewPart#saveState(org.eclipse.ui.IMemento)
|
||||||
|
*/
|
||||||
|
public void saveState(IMemento memento) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyPart#contributeToActionBars()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void contributeToActionBars(IActionBars bars) {
|
||||||
|
super.contributeToActionBars(bars);
|
||||||
|
fillLocalPullDown(bars.getMenuManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fillLocalPullDown(IMenuManager manager) {
|
||||||
|
manager.add(fActionGotoPC);
|
||||||
|
manager.add(fActionGotoAddress);
|
||||||
|
manager.add(fActionToggleSource);
|
||||||
|
manager.add(new Separator());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyPart#closePart()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void closePart() {
|
||||||
|
getViewSite().getPage().hideView(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyPart#dispose()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
getSite().getPage().removeSelectionListener(fDebugViewListener);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,283 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.source.CompositeRuler;
|
||||||
|
import org.eclipse.jface.text.source.IOverviewRuler;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRuler;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerColumn;
|
||||||
|
import org.eclipse.jface.text.source.SourceViewer;
|
||||||
|
import org.eclipse.swt.custom.StyledText;
|
||||||
|
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.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyViewer
|
||||||
|
*/
|
||||||
|
public class DisassemblyViewer extends SourceViewer {
|
||||||
|
|
||||||
|
class ResizeListener implements ControlListener {
|
||||||
|
/*
|
||||||
|
* @see ControlListener#controlResized(ControlEvent)
|
||||||
|
*/
|
||||||
|
public void controlResized(ControlEvent e) {
|
||||||
|
updateViewportListeners(RESIZE);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* @see ControlListener#controlMoved(ControlEvent)
|
||||||
|
*/
|
||||||
|
public void controlMoved(ControlEvent e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean fUserTriggeredScrolling;
|
||||||
|
private int fCachedLastTopPixel;
|
||||||
|
|
||||||
|
// extra resize listener to workaround bug 171018
|
||||||
|
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=171018
|
||||||
|
private ResizeListener fResizeListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new DisassemblyViewer.
|
||||||
|
* @param parent
|
||||||
|
* @param ruler
|
||||||
|
* @param overviewRuler
|
||||||
|
* @param showsAnnotationOverview
|
||||||
|
* @param styles
|
||||||
|
*/
|
||||||
|
public DisassemblyViewer(Composite parent, IVerticalRuler ruler, IOverviewRuler overviewRuler, boolean showsAnnotationOverview, int styles) {
|
||||||
|
super(parent, ruler, overviewRuler, showsAnnotationOverview, styles);
|
||||||
|
// always readonly
|
||||||
|
setEditable(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.SourceViewer#createControl(org.eclipse.swt.widgets.Composite, int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void createControl(Composite parent, int styles) {
|
||||||
|
super.createControl(parent, styles);
|
||||||
|
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=171018
|
||||||
|
getTextWidget().addControlListener(fResizeListener= new ResizeListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.SourceViewer#handleDispose()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void handleDispose() {
|
||||||
|
if (fResizeListener != null) {
|
||||||
|
getTextWidget().removeControlListener(fResizeListener);
|
||||||
|
}
|
||||||
|
super.handleDispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.SourceViewer#doOperation(int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void doOperation(int operation) {
|
||||||
|
switch (operation) {
|
||||||
|
case COPY:
|
||||||
|
StyledText textWidget = getTextWidget();
|
||||||
|
if (textWidget == null || !redraws()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (textWidget.getSelectionCount() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String selectedText;
|
||||||
|
try {
|
||||||
|
selectedText = getSelectedText();
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
// should not happend
|
||||||
|
DsfDebugUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, DsfDebugUIPlugin.PLUGIN_ID, e.getLocalizedMessage(), e));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Clipboard clipboard = new Clipboard(textWidget.getDisplay());
|
||||||
|
clipboard.setContents(new Object[] { selectedText }, new Transfer[] { TextTransfer.getInstance() });
|
||||||
|
clipboard.dispose();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
super.doOperation(operation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the selected text together with text displayed in visible
|
||||||
|
* ruler columns.
|
||||||
|
* @return the selected text
|
||||||
|
* @throws BadLocationException
|
||||||
|
*/
|
||||||
|
public String getSelectedText() throws BadLocationException {
|
||||||
|
StringBuffer text = new StringBuffer(200);
|
||||||
|
String lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$
|
||||||
|
DisassemblyDocument doc = (DisassemblyDocument)getDocument();
|
||||||
|
Point selection = getSelectedRange();
|
||||||
|
int startOffset = selection.x;
|
||||||
|
int length = selection.y;
|
||||||
|
int endOffset = startOffset + length;
|
||||||
|
int startLine = doc.getLineOfOffset(startOffset);
|
||||||
|
int endLine = doc.getLineOfOffset(endOffset);
|
||||||
|
int firstLineOffset = startOffset - doc.getLineOffset(startLine);
|
||||||
|
if (firstLineOffset > 0) {
|
||||||
|
// partial first line
|
||||||
|
int lineLength = doc.getLineInformation(startLine).getLength();
|
||||||
|
text.append(doc.get(startOffset, Math.min(lineLength - firstLineOffset, length)));
|
||||||
|
++startLine;
|
||||||
|
if (startLine <= endLine) {
|
||||||
|
text.append(lineSeparator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int line = startLine; line < endLine; ++line) {
|
||||||
|
String lineText = getLineText(line);
|
||||||
|
text.append(lineText);
|
||||||
|
text.append(lineSeparator);
|
||||||
|
}
|
||||||
|
if (doc.getLineOffset(endLine) < endOffset) {
|
||||||
|
// partial last line
|
||||||
|
if (startLine <= endLine) {
|
||||||
|
int lineStart = doc.getLineOffset(endLine);
|
||||||
|
text.append(getLinePrefix(endLine));
|
||||||
|
text.append(doc.get(lineStart, endOffset - lineStart));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return text.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the content of the given line, excluding line separator.
|
||||||
|
* @param line the line number
|
||||||
|
* @return the line content
|
||||||
|
* @throws BadLocationException
|
||||||
|
*/
|
||||||
|
public String getLineText(int line) throws BadLocationException {
|
||||||
|
IDocument doc = getDocument();
|
||||||
|
IRegion lineRegion = doc.getLineInformation(line);
|
||||||
|
return getLinePrefix(line) + doc.get(lineRegion.getOffset(), lineRegion.getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the line prefix by concatenating the text displayed by
|
||||||
|
* the visible ruler columns.
|
||||||
|
* @param line the line number
|
||||||
|
* @return the prefix string with trailing blank or the empty string
|
||||||
|
*/
|
||||||
|
public String getLinePrefix(int line) {
|
||||||
|
StringBuffer prefix = new StringBuffer(10);
|
||||||
|
IVerticalRuler ruler = getVerticalRuler();
|
||||||
|
if (ruler instanceof CompositeRuler) {
|
||||||
|
for (Iterator<?> iter = ((CompositeRuler)ruler).getDecoratorIterator(); iter.hasNext();) {
|
||||||
|
IVerticalRulerColumn column = (IVerticalRulerColumn) iter.next();
|
||||||
|
if (column instanceof DisassemblyRulerColumn) {
|
||||||
|
DisassemblyRulerColumn disassColumn = (DisassemblyRulerColumn)column;
|
||||||
|
String columnText = disassColumn.createDisplayString(line);
|
||||||
|
prefix.append(columnText);
|
||||||
|
int columnWidth = disassColumn.computeNumberOfCharacters();
|
||||||
|
columnWidth -= columnText.length();
|
||||||
|
while(columnWidth-- > 0)
|
||||||
|
prefix.append(' ');
|
||||||
|
prefix.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prefix.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll the given position into the visible area if it is not yet visible.
|
||||||
|
* @param offset
|
||||||
|
* @see org.eclipse.jface.text.TextViewer#revealRange(int, int)
|
||||||
|
*/
|
||||||
|
public void revealOffset(int offset, boolean onTop) {
|
||||||
|
try {
|
||||||
|
IDocument doc = getVisibleDocument();
|
||||||
|
|
||||||
|
int focusLine = doc.getLineOfOffset(offset);
|
||||||
|
|
||||||
|
StyledText textWidget = getTextWidget();
|
||||||
|
int top = textWidget.getTopIndex();
|
||||||
|
if (top > -1) {
|
||||||
|
|
||||||
|
// scroll vertically
|
||||||
|
int lines = getEstimatedVisibleLinesInViewport();
|
||||||
|
int bottom = top + lines;
|
||||||
|
|
||||||
|
int bottomBuffer = Math.max(1, lines / 3);
|
||||||
|
|
||||||
|
if (!onTop && focusLine >= top && focusLine <= bottom - bottomBuffer) {
|
||||||
|
// do not scroll at all as it is already visible
|
||||||
|
} else {
|
||||||
|
if (focusLine > bottom - bottomBuffer && focusLine <= bottom) {
|
||||||
|
// focusLine is already in bottom bufferZone
|
||||||
|
// scroll to top of bottom bufferzone - for smooth down-scrolling
|
||||||
|
int scrollDelta = focusLine - (bottom - bottomBuffer);
|
||||||
|
textWidget.setTopIndex(top + scrollDelta);
|
||||||
|
} else {
|
||||||
|
// scroll to top of visible area minus buffer zone
|
||||||
|
int topBuffer = onTop ? 0 : lines / 3;
|
||||||
|
textWidget.setTopIndex(Math.max(0, focusLine - topBuffer));
|
||||||
|
}
|
||||||
|
updateViewportListeners(INTERNAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (BadLocationException ble) {
|
||||||
|
throw new IllegalArgumentException(ble.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the number of visible lines in the viewport assuming a constant
|
||||||
|
* line height.
|
||||||
|
*/
|
||||||
|
private int getEstimatedVisibleLinesInViewport() {
|
||||||
|
StyledText textWidget = getTextWidget();
|
||||||
|
if (textWidget != null) {
|
||||||
|
Rectangle clArea= textWidget.getClientArea();
|
||||||
|
if (!clArea.isEmpty())
|
||||||
|
return clArea.height / textWidget.getLineHeight();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getLastTopPixel() {
|
||||||
|
return fCachedLastTopPixel;
|
||||||
|
}
|
||||||
|
boolean isUserTriggeredScrolling() {
|
||||||
|
return fUserTriggeredScrolling;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.TextViewer#updateViewportListeners(int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void updateViewportListeners(int origin) {
|
||||||
|
fCachedLastTopPixel = fLastTopPixel;
|
||||||
|
fUserTriggeredScrolling = origin != INTERNAL && origin != RESIZE;
|
||||||
|
super.updateViewportListeners(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.DocumentEvent;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextHover;
|
||||||
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
|
import org.eclipse.jface.text.IUndoManager;
|
||||||
|
import org.eclipse.jface.text.Region;
|
||||||
|
import org.eclipse.jface.text.TextPresentation;
|
||||||
|
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
|
||||||
|
import org.eclipse.jface.text.presentation.IPresentationDamager;
|
||||||
|
import org.eclipse.jface.text.presentation.IPresentationReconciler;
|
||||||
|
import org.eclipse.jface.text.presentation.IPresentationRepairer;
|
||||||
|
import org.eclipse.jface.text.presentation.PresentationReconciler;
|
||||||
|
import org.eclipse.jface.text.reconciler.IReconciler;
|
||||||
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
|
import org.eclipse.ui.editors.text.EditorsUI;
|
||||||
|
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyViewerConfiguration
|
||||||
|
*/
|
||||||
|
public class DisassemblyViewerConfiguration extends TextSourceViewerConfiguration {
|
||||||
|
|
||||||
|
private DisassemblyPart fPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SimpleDamagerRepairer
|
||||||
|
*/
|
||||||
|
public class SimpleDamagerRepairer implements IPresentationDamager, IPresentationRepairer {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.presentation.IPresentationDamager#setDocument(org.eclipse.jface.text.IDocument)
|
||||||
|
*/
|
||||||
|
public void setDocument(IDocument document) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.presentation.IPresentationDamager#getDamageRegion(org.eclipse.jface.text.ITypedRegion, org.eclipse.jface.text.DocumentEvent, boolean)
|
||||||
|
*/
|
||||||
|
public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, boolean documentPartitioningChanged) {
|
||||||
|
int start= e.fOffset;
|
||||||
|
int end= e.getOffset() + (e.getText() == null ? 0 : e.getText().length());
|
||||||
|
return new Region(start, end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.presentation.IPresentationRepairer#createPresentation(org.eclipse.jface.text.TextPresentation, org.eclipse.jface.text.ITypedRegion)
|
||||||
|
*/
|
||||||
|
public void createPresentation(TextPresentation presentation, ITypedRegion damage) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public DisassemblyViewerConfiguration(DisassemblyPart part) {
|
||||||
|
super(EditorsUI.getPreferenceStore());
|
||||||
|
fPart = part;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getPresentationReconciler(org.eclipse.jface.text.source.ISourceViewer)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
|
||||||
|
PresentationReconciler reconciler = new PresentationReconciler();
|
||||||
|
SimpleDamagerRepairer dr = new SimpleDamagerRepairer();
|
||||||
|
reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
|
||||||
|
reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
|
||||||
|
return reconciler;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getUndoManager(org.eclipse.jface.text.source.ISourceViewer)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IUndoManager getUndoManager(ISourceViewer sourceViewer) {
|
||||||
|
// no undo/redo
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.SourceViewerConfiguration#getTextHover(org.eclipse.jface.text.source.ISourceViewer, java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
|
||||||
|
return new DisassemblyTextHover(fPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.editors.text.TextSourceViewerConfiguration#getHyperlinkDetectors(org.eclipse.jface.text.source.ISourceViewer)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
|
||||||
|
IHyperlinkDetector[] inheritedDetectors= super.getHyperlinkDetectors(sourceViewer);
|
||||||
|
|
||||||
|
if (fPart == null)
|
||||||
|
return inheritedDetectors;
|
||||||
|
|
||||||
|
int inheritedDetectorsLength= inheritedDetectors != null ? inheritedDetectors.length : 0;
|
||||||
|
IHyperlinkDetector[] detectors= new IHyperlinkDetector[inheritedDetectorsLength + 1];
|
||||||
|
detectors[0]= new DisassemblyHyperlinkDetector(fPart);
|
||||||
|
for (int i= 0; i < inheritedDetectorsLength; i++) {
|
||||||
|
detectors[i+1]= inheritedDetectors[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return detectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.editors.text.TextSourceViewerConfiguration#getReconciler(org.eclipse.jface.text.source.ISourceViewer)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IReconciler getReconciler(ISourceViewer sourceViewer) {
|
||||||
|
// disable spell checking
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IFileState;
|
||||||
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A job to find a suitable edition from the local history
|
||||||
|
* based on a file and the timestamp of the code module.
|
||||||
|
*/
|
||||||
|
class EditionFinderJob extends Job {
|
||||||
|
|
||||||
|
private final IFile fFile;
|
||||||
|
private final BigInteger fAddress;
|
||||||
|
private final DisassemblyPart fDisassemblyPart;
|
||||||
|
private final SourceFileInfo fSourceInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new edition finder for a file resource and address.
|
||||||
|
*
|
||||||
|
* @param sourceInfo the file info containing the file resource for which to find an edition
|
||||||
|
* @param address address inside the module
|
||||||
|
* @param disassemblyPart the disassembly part where this job originated from
|
||||||
|
*/
|
||||||
|
public EditionFinderJob(SourceFileInfo sourceInfo, BigInteger address, DisassemblyPart disassemblyPart) {
|
||||||
|
super(DisassemblyMessages.EditionFinderJob_name);
|
||||||
|
Assert.isNotNull(sourceInfo);
|
||||||
|
Assert.isLegal(sourceInfo.fFile instanceof IFile);
|
||||||
|
fSourceInfo= sourceInfo;
|
||||||
|
fFile = (IFile)sourceInfo.fFile;
|
||||||
|
fAddress = address;
|
||||||
|
fDisassemblyPart= disassemblyPart;
|
||||||
|
setRule(fFile);
|
||||||
|
setSystem(true);
|
||||||
|
sourceInfo.fEditionJob= this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected IStatus run(IProgressMonitor monitor) {
|
||||||
|
monitor.beginTask(DisassemblyMessages.EditionFinderJob_name, 2);
|
||||||
|
monitor.subTask(DisassemblyMessages.EditionFinderJob_task_get_timestamp);
|
||||||
|
long moduleTime;
|
||||||
|
Object token = fDisassemblyPart.retrieveModuleTimestamp(fAddress);
|
||||||
|
if (token != null && !(token instanceof Long) && !monitor.isCanceled()) {
|
||||||
|
try {
|
||||||
|
synchronized (token) {
|
||||||
|
token.wait(1000);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
DisassemblyPart.internalError(e);
|
||||||
|
}
|
||||||
|
token = fDisassemblyPart.retrieveModuleTimestamp(fAddress);
|
||||||
|
}
|
||||||
|
monitor.worked(1);
|
||||||
|
if (token instanceof Long && !monitor.isCanceled()) {
|
||||||
|
moduleTime = ((Long)token).longValue();
|
||||||
|
long buildTime = moduleTime * 1000;
|
||||||
|
if (fFile.getLocalTimeStamp() > buildTime) {
|
||||||
|
monitor.subTask(DisassemblyMessages.EditionFinderJob_task_search_history);
|
||||||
|
// get history - recent states first
|
||||||
|
IFileState[] states;
|
||||||
|
try {
|
||||||
|
states = fFile.getHistory(new SubProgressMonitor(monitor, 1));
|
||||||
|
} catch (CoreException e) {
|
||||||
|
states = new IFileState[0];
|
||||||
|
}
|
||||||
|
for (int i = 0; i < states.length; i++) {
|
||||||
|
IFileState state = states[i];
|
||||||
|
long saveTime = state.getModificationTime();
|
||||||
|
if (saveTime <= buildTime) {
|
||||||
|
fSourceInfo.fEdition = state;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fSourceInfo.fEditionJob = null;
|
||||||
|
monitor.worked(1);
|
||||||
|
monitor.done();
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.AddressRangePosition;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyPosition;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A vertical ruler column to display the function + offset of instructions.
|
||||||
|
*/
|
||||||
|
public class FunctionOffsetRulerColumn extends DisassemblyRulerColumn {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public FunctionOffsetRulerColumn() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.LineNumberRulerColumn#createDisplayString(int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String createDisplayString(int line) {
|
||||||
|
DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument();
|
||||||
|
int offset;
|
||||||
|
try {
|
||||||
|
offset = doc.getLineOffset(line);
|
||||||
|
AddressRangePosition pos = doc.getDisassemblyPosition(offset);
|
||||||
|
if (pos instanceof DisassemblyPosition && pos.length > 0 && pos.offset == offset && pos.fValid) {
|
||||||
|
DisassemblyPosition disassPos = (DisassemblyPosition)pos;
|
||||||
|
return new String(disassPos.fFunction);
|
||||||
|
} else if (pos != null && !pos.fValid) {
|
||||||
|
return DOTS.substring(0, doc.getMaxFunctionLength());
|
||||||
|
}
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
// silently ignored
|
||||||
|
}
|
||||||
|
return ""; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.views.DisassemblyRulerColumn#computeNumberOfCharacters()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected int computeNumberOfCharacters() {
|
||||||
|
DisassemblyDocument doc = (DisassemblyDocument)getParentRuler().getTextViewer().getDocument();
|
||||||
|
return doc.getMaxFunctionLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IVerticalRulerColumn#getWidth()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getWidth() {
|
||||||
|
return super.getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IDisassemblyHelpContextIds
|
||||||
|
*/
|
||||||
|
public interface IDisassemblyHelpContextIds {
|
||||||
|
|
||||||
|
public final static String PREFIX = DsfDebugUIPlugin.PLUGIN_ID + '.';
|
||||||
|
public final static String DISASSEMBLY_PREFERENCE_PAGE = PREFIX + "disassembly_preference_page"; //$NON-NLS-1$
|
||||||
|
public final static String DISASSEMBLY_VIEW = PREFIX + "disassembly_view"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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:
|
||||||
|
* Anton Leherbauer (Wind River Systems) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.eclipse.jface.action.IMenuListener;
|
||||||
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
|
import org.eclipse.ui.IWorkbenchPart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface which the disassembly view and editor implement.
|
||||||
|
*/
|
||||||
|
public interface IDisassemblyPart extends IWorkbenchPart {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property id for the active state of the part.
|
||||||
|
*/
|
||||||
|
public final int PROP_ACTIVE= 0x505;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property id for the connected state of the part.
|
||||||
|
*/
|
||||||
|
public final int PROP_CONNECTED= 0x506;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property id for the suspended state of the underlying execution context.
|
||||||
|
*/
|
||||||
|
public final int PROP_SUSPENDED= 0x507;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether this part is connected to a debug session and execution context.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the part is connected to a debug session and execution context
|
||||||
|
*/
|
||||||
|
boolean isConnected();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether this part is active. A part is active if it is visible and connected.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the part is active
|
||||||
|
*/
|
||||||
|
boolean isActive();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the underlying execution context is currently suspended.
|
||||||
|
* Implies connected state.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the execution context is currently suspended
|
||||||
|
*/
|
||||||
|
boolean isSuspended();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get access to the text viewer.
|
||||||
|
*
|
||||||
|
* @return the text viewer
|
||||||
|
*/
|
||||||
|
ISourceViewer getTextViewer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to the given address.
|
||||||
|
*
|
||||||
|
* @param address
|
||||||
|
*/
|
||||||
|
void gotoAddress(BigInteger address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to current program counter.
|
||||||
|
*/
|
||||||
|
void gotoProgramCounter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to the address the given expression evaluates to.
|
||||||
|
*
|
||||||
|
* @param expression a symbolic address expression
|
||||||
|
*/
|
||||||
|
void gotoSymbol(String expression);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a ruler context menu listener to the disassembly part.
|
||||||
|
*
|
||||||
|
* @param listener the listener
|
||||||
|
*/
|
||||||
|
void addRulerContextMenuListener(IMenuListener listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a ruler context menu listener from the disassembly part.
|
||||||
|
*
|
||||||
|
* @param listener the listener
|
||||||
|
*/
|
||||||
|
void removeRulerContextMenuListener(IMenuListener listener);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IStorage;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.DisassemblyDocument;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.model.SourceFileInfo;
|
||||||
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
|
||||||
|
import org.eclipse.ui.progress.UIJob;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI job to color source code.
|
||||||
|
*/
|
||||||
|
class SourceColorerJob extends UIJob implements Runnable {
|
||||||
|
|
||||||
|
private final DisassemblyPart fDisassemblyPart;
|
||||||
|
private final ISourceViewer fViewer;
|
||||||
|
private final DisassemblyDocument fDocument;
|
||||||
|
private final IStorage fStorage;
|
||||||
|
|
||||||
|
public SourceColorerJob(Display jobDisplay, IStorage storage, DisassemblyPart disassemblyPart) {
|
||||||
|
super(DisassemblyMessages.SourceColorerJob_name);
|
||||||
|
fDisassemblyPart= disassemblyPart;
|
||||||
|
fViewer= disassemblyPart.getTextViewer();
|
||||||
|
fDocument= (DisassemblyDocument) fViewer.getDocument();
|
||||||
|
fStorage = storage;
|
||||||
|
setDisplay(fDisassemblyPart.getSite().getShell().getDisplay());
|
||||||
|
setSystem(true);
|
||||||
|
setPriority(INTERACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.progress.UIJob#runInUIThread(org.eclipse.core.runtime.IProgressMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||||
|
if (fViewer != null && !monitor.isCanceled()) {
|
||||||
|
monitor.beginTask(DisassemblyMessages.SourceColorerJob_name, IProgressMonitor.UNKNOWN);
|
||||||
|
SourceFileInfo fi = fDocument.getSourceInfo(fStorage);
|
||||||
|
if (fi != null) {
|
||||||
|
fi.initPresentationCreator(fViewer);
|
||||||
|
if (fi.fError != null) {
|
||||||
|
String message= DisassemblyMessages.Disassembly_log_error_readFile + fi.fFileKey;
|
||||||
|
fDisassemblyPart.logWarning(message, fi.fError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fDisassemblyPart.updateInvalidSource();
|
||||||
|
monitor.done();
|
||||||
|
}
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see java.lang.Runnable#run()
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
IWorkbenchSiteProgressService progressService = (IWorkbenchSiteProgressService)fDisassemblyPart.getSite().getAdapter(IWorkbenchSiteProgressService.class);
|
||||||
|
if(progressService != null) {
|
||||||
|
progressService.schedule(this, 0, true);
|
||||||
|
} else {
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
import org.eclipse.jface.action.Action;
|
||||||
|
import org.eclipse.ui.IPropertyListener;
|
||||||
|
import org.eclipse.ui.texteditor.IUpdate;
|
||||||
|
|
||||||
|
public abstract class AbstractDisassemblyAction extends Action implements IUpdate, IPropertyListener {
|
||||||
|
|
||||||
|
protected IDisassemblyPart fDisassemblyPart;
|
||||||
|
|
||||||
|
AbstractDisassemblyAction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a disassembly action.
|
||||||
|
*
|
||||||
|
* @param disassemblyPart
|
||||||
|
*/
|
||||||
|
public AbstractDisassemblyAction(IDisassemblyPart disassemblyPart) {
|
||||||
|
Assert.isLegal(disassemblyPart != null);
|
||||||
|
fDisassemblyPart= disassemblyPart;
|
||||||
|
fDisassemblyPart.addPropertyListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the disassembly part
|
||||||
|
*/
|
||||||
|
public final IDisassemblyPart getDisassemblyPart() {
|
||||||
|
return fDisassemblyPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.action.Action#run()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public abstract void run();
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
boolean enabled= fDisassemblyPart == null || fDisassemblyPart.isConnected();
|
||||||
|
setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IPropertyListener#propertyChanged(java.lang.Object, int)
|
||||||
|
*/
|
||||||
|
public void propertyChanged(Object source, int propId) {
|
||||||
|
if (source == fDisassemblyPart && (propId & 0x500) != 0) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IMarker;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
|
import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.Position;
|
||||||
|
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerInfo;
|
||||||
|
import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract implementation of a breakpoint ruler action.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractDisassemblyBreakpointRulerAction extends AbstractDisassemblyRulerAction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create breakpoint ruler action.
|
||||||
|
*
|
||||||
|
* @param disassemblyPart
|
||||||
|
* @param rulerInfo
|
||||||
|
*/
|
||||||
|
protected AbstractDisassemblyBreakpointRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) {
|
||||||
|
super(disassemblyPart, rulerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the breakpoint at the last line of mouse activity in the ruler
|
||||||
|
* or <code>null</code> if none.
|
||||||
|
*
|
||||||
|
* @return breakpoint associated with activity in the ruler or <code>null</code>
|
||||||
|
*/
|
||||||
|
protected IBreakpoint getBreakpoint() {
|
||||||
|
IAnnotationModel annotationModel = getAnnotationModel();
|
||||||
|
IDocument document = getDocument();
|
||||||
|
if (annotationModel != null) {
|
||||||
|
Iterator<?> iterator = annotationModel.getAnnotationIterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Object object = iterator.next();
|
||||||
|
if (object instanceof SimpleMarkerAnnotation) {
|
||||||
|
SimpleMarkerAnnotation markerAnnotation = (SimpleMarkerAnnotation) object;
|
||||||
|
IMarker marker = markerAnnotation.getMarker();
|
||||||
|
try {
|
||||||
|
if (marker.isSubtypeOf(IBreakpoint.BREAKPOINT_MARKER)) {
|
||||||
|
Position position = annotationModel.getPosition(markerAnnotation);
|
||||||
|
int line = document.getLineOfOffset(position.getOffset());
|
||||||
|
if (line == getRulerInfo().getLineOfLastMouseButtonActivity()) {
|
||||||
|
IBreakpoint breakpoint = DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
|
||||||
|
if (breakpoint != null) {
|
||||||
|
return breakpoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract implementation for disassembly vertical ruler actions.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractDisassemblyRulerAction extends AbstractDisassemblyAction {
|
||||||
|
|
||||||
|
private final IVerticalRulerInfo fRulerInfo;
|
||||||
|
|
||||||
|
protected AbstractDisassemblyRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) {
|
||||||
|
fDisassemblyPart= disassemblyPart;
|
||||||
|
fRulerInfo= rulerInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final IVerticalRulerInfo getRulerInfo() {
|
||||||
|
return fRulerInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final IDocument getDocument() {
|
||||||
|
return getDisassemblyPart().getTextViewer().getDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final IAnnotationModel getAnnotationModel() {
|
||||||
|
return getDisassemblyPart().getTextViewer().getAnnotationModel();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
import org.eclipse.jface.action.IAction;
|
||||||
|
import org.eclipse.jface.action.IMenuListener;
|
||||||
|
import org.eclipse.jface.action.IMenuManager;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerInfo;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.events.MouseListener;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Event;
|
||||||
|
import org.eclipse.ui.IEditorActionDelegate;
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
|
import org.eclipse.ui.IViewActionDelegate;
|
||||||
|
import org.eclipse.ui.IViewPart;
|
||||||
|
import org.eclipse.ui.IWorkbenchPart;
|
||||||
|
import org.eclipse.ui.actions.ActionDelegate;
|
||||||
|
import org.eclipse.ui.texteditor.IUpdate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class serves as an adapter for actions contributed to the vertical ruler's
|
||||||
|
* context menu. This adapter provides the contributed actions access to their disassembly part
|
||||||
|
* and the disassembly part's vertical ruler. These actions gain only limited access to the vertical
|
||||||
|
* ruler as defined by <code>IVerticalRulerInfo</code>. The adapter updates the
|
||||||
|
* adapter (inner) action on menu and mouse action on the vertical ruler.<p>
|
||||||
|
* Extending classes must implement the factory method
|
||||||
|
* <code>createAction(IDisassemblyPart, IVerticalRulerInfo)</code>.
|
||||||
|
*
|
||||||
|
* @see org.eclipse.ui.texteditor.AbstractRulerActionDelegate
|
||||||
|
*/
|
||||||
|
public abstract class AbstractDisassemblyRulerActionDelegate extends ActionDelegate implements IEditorActionDelegate, IViewActionDelegate, MouseListener, IMenuListener {
|
||||||
|
|
||||||
|
/** The disassembly part. */
|
||||||
|
private IDisassemblyPart fDisassemblyPart;
|
||||||
|
/** The action calling the action delegate. */
|
||||||
|
private IAction fCallerAction;
|
||||||
|
/** The underlying action. */
|
||||||
|
private IAction fAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The factory method creating the underlying action.
|
||||||
|
*
|
||||||
|
* @param disassemblyPart the disassembly part the action to be created will work on
|
||||||
|
* @param rulerInfo the vertical ruler the action to be created will work on
|
||||||
|
* @return the created action
|
||||||
|
*/
|
||||||
|
protected abstract IAction createAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IEditorActionDelegate#setActiveEditor(org.eclipse.jface.action.IAction, org.eclipse.ui.IEditorPart)
|
||||||
|
*/
|
||||||
|
public void setActiveEditor(IAction callerAction, IEditorPart targetEditor) {
|
||||||
|
setTargetPart(callerAction, targetEditor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart)
|
||||||
|
*/
|
||||||
|
public void init(IViewPart view) {
|
||||||
|
setTargetPart(fCallerAction, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(IAction action) {
|
||||||
|
fCallerAction= action;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTargetPart(IAction callerAction, IWorkbenchPart targetPart) {
|
||||||
|
if (fDisassemblyPart != null) {
|
||||||
|
IVerticalRulerInfo rulerInfo= (IVerticalRulerInfo) fDisassemblyPart.getAdapter(IVerticalRulerInfo.class);
|
||||||
|
if (rulerInfo != null) {
|
||||||
|
Control control= rulerInfo.getControl();
|
||||||
|
if (control != null && !control.isDisposed())
|
||||||
|
control.removeMouseListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
fDisassemblyPart.removeRulerContextMenuListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
fDisassemblyPart= (IDisassemblyPart)(targetPart == null ? null : targetPart.getAdapter(IDisassemblyPart.class));
|
||||||
|
fCallerAction= callerAction;
|
||||||
|
fAction= null;
|
||||||
|
|
||||||
|
if (fDisassemblyPart != null) {
|
||||||
|
fDisassemblyPart.addRulerContextMenuListener(this);
|
||||||
|
|
||||||
|
IVerticalRulerInfo rulerInfo= (IVerticalRulerInfo) fDisassemblyPart.getAdapter(IVerticalRulerInfo.class);
|
||||||
|
if (rulerInfo != null) {
|
||||||
|
fAction= createAction(fDisassemblyPart, rulerInfo);
|
||||||
|
update();
|
||||||
|
|
||||||
|
Control control= rulerInfo.getControl();
|
||||||
|
if (control != null && !control.isDisposed())
|
||||||
|
control.addMouseListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(IAction callerAction) {
|
||||||
|
if (fAction != null)
|
||||||
|
fAction.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runWithEvent(IAction action, Event event) {
|
||||||
|
if (fAction != null)
|
||||||
|
fAction.runWithEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void selectionChanged(IAction action, ISelection selection) {
|
||||||
|
/*
|
||||||
|
* This is a ruler action - don't update on selection.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates to the current state.
|
||||||
|
*/
|
||||||
|
private void update() {
|
||||||
|
if (fAction instanceof IUpdate) {
|
||||||
|
((IUpdate) fAction).update();
|
||||||
|
if (fCallerAction != null) {
|
||||||
|
fCallerAction.setText(fAction.getText());
|
||||||
|
fCallerAction.setEnabled(fAction.isEnabled());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
|
||||||
|
*/
|
||||||
|
public void menuAboutToShow(IMenuManager manager) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseDoubleClick(MouseEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseDown(MouseEvent e) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
|
||||||
|
*/
|
||||||
|
public void mouseUp(MouseEvent e) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyPart;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||||
|
import org.eclipse.jface.dialogs.IInputValidator;
|
||||||
|
import org.eclipse.jface.dialogs.InputDialog;
|
||||||
|
import org.eclipse.jface.text.ITextSelection;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
|
public final class ActionGotoAddress extends AbstractDisassemblyAction {
|
||||||
|
public ActionGotoAddress(IDisassemblyPart disassemblyPart) {
|
||||||
|
super(disassemblyPart);
|
||||||
|
setText(DisassemblyMessages.Disassembly_action_GotoAddress_label);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
IInputValidator validator = new IInputValidator() {
|
||||||
|
public String isValid(String input) {
|
||||||
|
if (input == null || input.length() == 0)
|
||||||
|
return " "; //$NON-NLS-1$
|
||||||
|
try {
|
||||||
|
BigInteger address= DisassemblyPart.decodeAddress(input);
|
||||||
|
if (address.compareTo(BigInteger.ZERO) < 0) {
|
||||||
|
return DisassemblyMessages.Disassembly_GotoAddressDialog_error_invalid_address;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException x) {
|
||||||
|
return DisassemblyMessages.Disassembly_GotoAddressDialog_error_not_a_number; //;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
String defaultValue = ((ITextSelection)getDisassemblyPart().getSite().getSelectionProvider().getSelection()).getText();
|
||||||
|
if (validator.isValid(defaultValue) != null) {
|
||||||
|
defaultValue = DsfDebugUIPlugin.getDefault().getDialogSettings().get("gotoAddress"); //$NON-NLS-1$
|
||||||
|
if (validator.isValid(defaultValue) != null) {
|
||||||
|
defaultValue = ""; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String dlgTitle = DisassemblyMessages.Disassembly_GotoAddressDialog_title;
|
||||||
|
String dlgLabel = DisassemblyMessages.Disassembly_GotoAddressDialog_label;
|
||||||
|
final Shell shell= getDisassemblyPart().getSite().getShell();
|
||||||
|
InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, validator);
|
||||||
|
if (dlg.open() == IDialogConstants.OK_ID) {
|
||||||
|
String value = dlg.getValue();
|
||||||
|
BigInteger address= DisassemblyPart.decodeAddress(value);
|
||||||
|
DsfDebugUIPlugin.getDefault().getDialogSettings().put("gotoAddress", value); //$NON-NLS-1$
|
||||||
|
getDisassemblyPart().gotoAddress(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
|
||||||
|
public final class ActionGotoProgramCounter extends AbstractDisassemblyAction {
|
||||||
|
public ActionGotoProgramCounter(IDisassemblyPart disassemblyPart) {
|
||||||
|
super(disassemblyPart);
|
||||||
|
setText(DisassemblyMessages.Disassembly_action_GotoPC_label);
|
||||||
|
setToolTipText(DisassemblyMessages.Disassembly_action_GotoPC_tooltip);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getDisassemblyPart().gotoProgramCounter();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CWordFinder;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||||
|
import org.eclipse.jface.dialogs.InputDialog;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
|
public final class ActionGotoSymbol extends AbstractDisassemblyAction {
|
||||||
|
public ActionGotoSymbol(IDisassemblyPart disassemblyPart) {
|
||||||
|
super(disassemblyPart);
|
||||||
|
setText(DisassemblyMessages.Disassembly_action_GotoSymbol_label);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ITextViewer viewer = getDisassemblyPart().getTextViewer();
|
||||||
|
IDocument document= viewer.getDocument();
|
||||||
|
IRegion wordRegion = CWordFinder.findWord(document, viewer.getSelectedRange().x);
|
||||||
|
String defaultValue = null;
|
||||||
|
if (wordRegion != null) {
|
||||||
|
try {
|
||||||
|
defaultValue = document.get(wordRegion.getOffset(), wordRegion.getLength());
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
// safely ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (defaultValue == null) {
|
||||||
|
defaultValue = DsfDebugUIPlugin.getDefault().getDialogSettings().get("gotoSymbol"); //$NON-NLS-1$
|
||||||
|
if (defaultValue == null) {
|
||||||
|
defaultValue = ""; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String dlgTitle = DisassemblyMessages.Disassembly_GotoSymbolDialog_title;
|
||||||
|
String dlgLabel = DisassemblyMessages.Disassembly_GotoSymbolDialog_label;
|
||||||
|
final Shell shell= getDisassemblyPart().getSite().getShell();
|
||||||
|
InputDialog dlg = new InputDialog(shell, dlgTitle, dlgLabel, defaultValue, null);
|
||||||
|
if (dlg.open() == IDialogConstants.OK_ID) {
|
||||||
|
String value = dlg.getValue();
|
||||||
|
DsfDebugUIPlugin.getDefault().getDialogSettings().put("gotoSymbol", value); //$NON-NLS-1$
|
||||||
|
getDisassemblyPart().gotoSymbol(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
|
||||||
|
import org.eclipse.jface.action.Action;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.ui.dialogs.PreferencesUtil;
|
||||||
|
|
||||||
|
public final class ActionOpenPreferences extends Action {
|
||||||
|
private final static String PREF_PAGE_ID = "org.eclipse.dd.dsf.debug.ui.disassembly.preferencePage"; //$NON-NLS-1$
|
||||||
|
private final Shell fShell;
|
||||||
|
public ActionOpenPreferences(Shell shell) {
|
||||||
|
fShell= shell;
|
||||||
|
setText(DisassemblyMessages.Disassembly_action_OpenPreferences_label);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
PreferencesUtil.createPreferenceDialogOn(fShell, PREF_PAGE_ID, new String[] { PREF_PAGE_ID }, null).open();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
|
||||||
|
import org.eclipse.cdt.debug.internal.ui.CBreakpointContext;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
|
import org.eclipse.debug.ui.DebugUITools;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerInfo;
|
||||||
|
import org.eclipse.jface.viewers.ISelection;
|
||||||
|
import org.eclipse.jface.viewers.ISelectionChangedListener;
|
||||||
|
import org.eclipse.jface.viewers.ISelectionProvider;
|
||||||
|
import org.eclipse.jface.viewers.StructuredSelection;
|
||||||
|
import org.eclipse.ui.dialogs.PropertyDialogAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruler action to display breakpoint properties.
|
||||||
|
*/
|
||||||
|
public class BreakpointPropertiesRulerAction extends AbstractDisassemblyBreakpointRulerAction {
|
||||||
|
|
||||||
|
private Object fContext;
|
||||||
|
|
||||||
|
protected BreakpointPropertiesRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) {
|
||||||
|
super(disassemblyPart, rulerInfo);
|
||||||
|
setText(DisassemblyMessages.Disassembly_action_BreakpointProperties_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyAction#run()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if ( fContext != null ) {
|
||||||
|
PropertyDialogAction action = new PropertyDialogAction( getDisassemblyPart().getSite(), new ISelectionProvider() {
|
||||||
|
|
||||||
|
public void addSelectionChangedListener( ISelectionChangedListener listener ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISelection getSelection() {
|
||||||
|
return new StructuredSelection( fContext );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeSelectionChangedListener( ISelectionChangedListener listener ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelection( ISelection selection ) {
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
action.run();
|
||||||
|
action.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see IUpdate#update()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void update() {
|
||||||
|
IBreakpoint breakpoint= getBreakpoint();
|
||||||
|
if (breakpoint instanceof ICBreakpoint) {
|
||||||
|
fContext = new CBreakpointContext((ICBreakpoint)breakpoint, getDebugContext());
|
||||||
|
} else {
|
||||||
|
fContext = breakpoint;
|
||||||
|
}
|
||||||
|
setEnabled( fContext != null );
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISelection getDebugContext() {
|
||||||
|
return DebugUITools.getDebugContextManager().getContextService(getDisassemblyPart().getSite().getWorkbenchWindow()).getActiveContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart;
|
||||||
|
import org.eclipse.jface.action.IAction;
|
||||||
|
import org.eclipse.jface.text.source.IVerticalRulerInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruler action delegate for the breakpoint properties action.
|
||||||
|
*/
|
||||||
|
public class BreakpointPropertiesRulerActionDelegate extends AbstractDisassemblyRulerActionDelegate {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions.AbstractDisassemblyRulerActionDelegate#createAction(org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyPart, org.eclipse.jface.text.source.IVerticalRulerInfo)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected IAction createAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) {
|
||||||
|
return new BreakpointPropertiesRulerAction(disassemblyPart, rulerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.actions;
|
||||||
|
|
||||||
|
import org.eclipse.jface.action.Action;
|
||||||
|
import org.eclipse.jface.text.ITextOperationTarget;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.ui.texteditor.IUpdate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TextOperationAction
|
||||||
|
*/
|
||||||
|
public class TextOperationAction extends Action implements IUpdate {
|
||||||
|
|
||||||
|
private int fOperationCode= -1;
|
||||||
|
private ITextOperationTarget fOperationTarget;
|
||||||
|
|
||||||
|
public TextOperationAction(ITextViewer viewer, int operationCode) {
|
||||||
|
fOperationCode= operationCode;
|
||||||
|
fOperationTarget= viewer.getTextOperationTarget();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the enabled state of the action.
|
||||||
|
* Fires a property change if the enabled state changes.
|
||||||
|
*
|
||||||
|
* @see Action#firePropertyChange(String, Object, Object)
|
||||||
|
*/
|
||||||
|
public void update() {
|
||||||
|
|
||||||
|
boolean wasEnabled= isEnabled();
|
||||||
|
boolean isEnabled= (fOperationTarget != null && fOperationTarget.canDoOperation(fOperationCode));
|
||||||
|
setEnabled(isEnabled);
|
||||||
|
|
||||||
|
if (wasEnabled != isEnabled) {
|
||||||
|
firePropertyChange(ENABLED, wasEnabled ? Boolean.TRUE : Boolean.FALSE, isEnabled ? Boolean.TRUE : Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see Action#run()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (fOperationCode != -1 && fOperationTarget != null) {
|
||||||
|
fOperationTarget.doOperation(fOperationCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
|
||||||
|
public class Addr2Line {
|
||||||
|
public BigInteger addr;
|
||||||
|
public Addr2Line next;
|
||||||
|
public int first;
|
||||||
|
public int last;
|
||||||
|
|
||||||
|
public static int hash(BigInteger addr, int size) {
|
||||||
|
return (int)((addr.shiftRight(2).longValue()) % size);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.Position;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AddressRangePosition
|
||||||
|
*/
|
||||||
|
public class AddressRangePosition extends Position {
|
||||||
|
|
||||||
|
public BigInteger fAddressOffset;
|
||||||
|
public BigInteger fAddressLength;
|
||||||
|
public boolean fValid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
*/
|
||||||
|
public AddressRangePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength) {
|
||||||
|
super(offset, length);
|
||||||
|
fAddressOffset = addressOffset;
|
||||||
|
fAddressLength = addressLength;
|
||||||
|
fValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @param valid
|
||||||
|
*/
|
||||||
|
public AddressRangePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, boolean valid) {
|
||||||
|
super(offset, length);
|
||||||
|
fAddressOffset = addressOffset;
|
||||||
|
fAddressLength = addressLength;
|
||||||
|
fValid = valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param address
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean containsAddress(BigInteger address) {
|
||||||
|
return address.compareTo(fAddressOffset) >= 0
|
||||||
|
&& address.compareTo(fAddressOffset.add(fAddressLength)) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
// identity comparison
|
||||||
|
return this == other;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,229 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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:
|
||||||
|
* Anton Leherbauer (Wind River Systems) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint;
|
||||||
|
import org.eclipse.cdt.debug.core.model.ICLineBreakpoint;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IMarker;
|
||||||
|
import org.eclipse.core.resources.IMarkerDelta;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
|
import org.eclipse.debug.core.IBreakpointListener;
|
||||||
|
import org.eclipse.debug.core.IBreakpointManager;
|
||||||
|
import org.eclipse.debug.core.model.IBreakpoint;
|
||||||
|
import org.eclipse.debug.core.model.ILineBreakpoint;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.DocumentEvent;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IDocumentListener;
|
||||||
|
import org.eclipse.jface.text.Position;
|
||||||
|
import org.eclipse.jface.text.source.Annotation;
|
||||||
|
import org.eclipse.jface.text.source.AnnotationModel;
|
||||||
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.ui.texteditor.MarkerAnnotation;
|
||||||
|
import org.eclipse.ui.texteditor.SimpleMarkerAnnotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation model for breakpoints in the disassembly.
|
||||||
|
* Works only with {@link DisassemblyDocument}.
|
||||||
|
*/
|
||||||
|
public class BreakpointsAnnotationModel extends AnnotationModel implements IBreakpointListener, IDocumentListener {
|
||||||
|
|
||||||
|
private Runnable fCatchup;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void connect(IDocument document) {
|
||||||
|
super.connect(document);
|
||||||
|
if (document instanceof DisassemblyDocument) {
|
||||||
|
final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager();
|
||||||
|
addBreakpoints(bpMgr.getBreakpoints());
|
||||||
|
bpMgr.addBreakpointListener(this);
|
||||||
|
document.addDocumentListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disconnect(IDocument document) {
|
||||||
|
if (document instanceof DisassemblyDocument) {
|
||||||
|
final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager();
|
||||||
|
bpMgr.removeBreakpointListener(this);
|
||||||
|
document.removeDocumentListener(this);
|
||||||
|
fCatchup= null;
|
||||||
|
}
|
||||||
|
super.disconnect(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void catchupWithBreakpoints() {
|
||||||
|
removeAllAnnotations(false);
|
||||||
|
final IBreakpointManager bpMgr= DebugPlugin.getDefault().getBreakpointManager();
|
||||||
|
addBreakpoints(bpMgr.getBreakpoints());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBreakpoints(IBreakpoint[] breakpoints) {
|
||||||
|
for (IBreakpoint breakpoint : breakpoints) {
|
||||||
|
addBreakpointAnnotation(breakpoint, false);
|
||||||
|
}
|
||||||
|
fireModelChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.debug.core.IBreakpointListener#breakpointAdded(org.eclipse.debug.core.model.IBreakpoint)
|
||||||
|
*/
|
||||||
|
public void breakpointAdded(IBreakpoint breakpoint) {
|
||||||
|
addBreakpointAnnotation(breakpoint, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.debug.core.IBreakpointListener#breakpointChanged(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
|
||||||
|
*/
|
||||||
|
public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
|
||||||
|
Annotation a= findAnnotation(breakpoint.getMarker());
|
||||||
|
if (a != null) {
|
||||||
|
if (a instanceof SimpleMarkerAnnotation) {
|
||||||
|
((SimpleMarkerAnnotation)a).update();
|
||||||
|
}
|
||||||
|
synchronized (getLockObject()) {
|
||||||
|
getAnnotationModelEvent().annotationChanged(a);
|
||||||
|
}
|
||||||
|
fireModelChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.debug.core.IBreakpointListener#breakpointRemoved(org.eclipse.debug.core.model.IBreakpoint, org.eclipse.core.resources.IMarkerDelta)
|
||||||
|
*/
|
||||||
|
public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
|
||||||
|
Annotation a= findAnnotation(breakpoint.getMarker());
|
||||||
|
if (a != null) {
|
||||||
|
removeAnnotation(a, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Annotation findAnnotation(IMarker marker) {
|
||||||
|
for (Iterator<SimpleMarkerAnnotation> it= getAnnotationIterator(false); it.hasNext();) {
|
||||||
|
SimpleMarkerAnnotation a= it.next();
|
||||||
|
if (a.getMarker().equals(marker)) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBreakpointAnnotation(IBreakpoint breakpoint, boolean fireEvent) {
|
||||||
|
final IMarker marker= breakpoint.getMarker();
|
||||||
|
if (marker == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Position position= createPositionFromBreakpoint(breakpoint);
|
||||||
|
if (position != null) {
|
||||||
|
addAnnotation(new MarkerAnnotation(marker), position, fireEvent);
|
||||||
|
}
|
||||||
|
} catch (CoreException exc) {
|
||||||
|
// ignore problems accessing attributes
|
||||||
|
} catch (BadLocationException exc) {
|
||||||
|
// ignore wrong positions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Position createPositionFromBreakpoint(IBreakpoint breakpoint) throws CoreException {
|
||||||
|
if (breakpoint instanceof ICAddressBreakpoint) {
|
||||||
|
ICAddressBreakpoint addressBreakpoint= (ICAddressBreakpoint) breakpoint;
|
||||||
|
return createPositionFromAddress(decodeAddress(addressBreakpoint.getAddress()));
|
||||||
|
} else if (breakpoint instanceof ILineBreakpoint) {
|
||||||
|
ILineBreakpoint lineBreakpoint= (ILineBreakpoint) breakpoint;
|
||||||
|
Position position= null;
|
||||||
|
final int lineNumber= lineBreakpoint.getLineNumber() - 1;
|
||||||
|
final IMarker marker= breakpoint.getMarker();
|
||||||
|
if (marker.getResource().getType() == IResource.FILE) {
|
||||||
|
position= createPositionFromSourceLine((IFile) marker.getResource(), lineNumber);
|
||||||
|
} else if (breakpoint instanceof ICLineBreakpoint) {
|
||||||
|
ICLineBreakpoint cBreakpoint= (ICLineBreakpoint) breakpoint;
|
||||||
|
position= createPositionFromSourceLine(cBreakpoint.getFileName(), lineNumber);
|
||||||
|
if (position == null) {
|
||||||
|
position= createPositionFromAddress(decodeAddress(cBreakpoint.getAddress()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String fileName= marker.getAttribute(ICLineBreakpoint.SOURCE_HANDLE, null);
|
||||||
|
if (fileName != null) {
|
||||||
|
position= createPositionFromSourceLine(fileName, lineNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Position createPositionFromSourceLine(String fileName, int lineNumber) {
|
||||||
|
return getDisassemblyDocument().getSourcePosition(fileName, lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Position createPositionFromSourceLine(IFile file, int lineNumber) {
|
||||||
|
return getDisassemblyDocument().getSourcePosition(file, lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Position createPositionFromAddress(BigInteger address) {
|
||||||
|
AddressRangePosition p= getDisassemblyDocument().getDisassemblyPosition(address);
|
||||||
|
if (p != null && p.fValid) {
|
||||||
|
return new Position(p.offset, p.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DisassemblyDocument getDisassemblyDocument() {
|
||||||
|
return (DisassemblyDocument) fDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode given string representation of a non-negative integer. A
|
||||||
|
* hexadecimal encoded integer is expected to start with <code>0x</code>.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* decimal or hexadecimal representation of an non-negative integer
|
||||||
|
* @return address value as <code>BigInteger</code>
|
||||||
|
*/
|
||||||
|
private static BigInteger decodeAddress(String string) {
|
||||||
|
if (string.startsWith("0x")) { //$NON-NLS-1$
|
||||||
|
return new BigInteger(string.substring(2), 16);
|
||||||
|
}
|
||||||
|
return new BigInteger(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
|
||||||
|
*/
|
||||||
|
public void documentAboutToBeChanged(DocumentEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
|
||||||
|
*/
|
||||||
|
public void documentChanged(DocumentEvent event) {
|
||||||
|
if (fCatchup == null && event.fText != null && event.fText.length() > 0) {
|
||||||
|
fCatchup= new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (fCatchup == this) {
|
||||||
|
catchupWithBreakpoints();
|
||||||
|
fCatchup= null;
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
Display.getCurrent().timerExec(50, fCatchup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,49 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyPosition
|
||||||
|
*/
|
||||||
|
public class DisassemblyPosition extends AddressRangePosition {
|
||||||
|
|
||||||
|
public char[] fFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @param addressOffset
|
||||||
|
* @param addressLength
|
||||||
|
* @param opcodes
|
||||||
|
*/
|
||||||
|
public DisassemblyPosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, String opcodes) {
|
||||||
|
super(offset, length, addressOffset, addressLength);
|
||||||
|
fFunction = opcodes.toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return source file
|
||||||
|
*/
|
||||||
|
public String getFile() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return source line number
|
||||||
|
*/
|
||||||
|
public int getLine() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyWithSourcePosition
|
||||||
|
*/
|
||||||
|
public class DisassemblyWithSourcePosition extends DisassemblyPosition {
|
||||||
|
|
||||||
|
private String fFile;
|
||||||
|
private int fLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @param addressOffset
|
||||||
|
* @param addressLength
|
||||||
|
* @param opcodes
|
||||||
|
*/
|
||||||
|
public DisassemblyWithSourcePosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, String opcodes, String file, int lineNr) {
|
||||||
|
super(offset, length, addressOffset, addressLength, opcodes);
|
||||||
|
fFile = file;
|
||||||
|
fLine = lineNr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see com.windriver.ide.disassembly.model.DisassemblyPosition#getFile()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getFile() {
|
||||||
|
return fFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see com.windriver.ide.disassembly.model.DisassemblyPosition#getLine()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getLine() {
|
||||||
|
return fLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ErrorPosition
|
||||||
|
*/
|
||||||
|
public class ErrorPosition extends AddressRangePosition {
|
||||||
|
|
||||||
|
public int fHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @param addressOffset
|
||||||
|
* @param addressLength
|
||||||
|
*/
|
||||||
|
public ErrorPosition(int offset, int length, BigInteger addressOffset, BigInteger addressLength, int hashCode) {
|
||||||
|
super(offset, length, addressOffset, addressLength);
|
||||||
|
fHashCode = hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return fHashCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LabelPosition
|
||||||
|
*/
|
||||||
|
public class LabelPosition extends AddressRangePosition {
|
||||||
|
|
||||||
|
public String fLabel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @param addressOffset
|
||||||
|
*/
|
||||||
|
public LabelPosition(int offset, int length, BigInteger addressOffset, String label) {
|
||||||
|
super(offset, length, addressOffset, BigInteger.ZERO);
|
||||||
|
fLabel = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant;
|
||||||
|
import org.eclipse.core.filesystem.EFS;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IFileState;
|
||||||
|
import org.eclipse.core.resources.IStorage;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.text.REDDocument;
|
||||||
|
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||||
|
import org.eclipse.ui.IStorageEditorInput;
|
||||||
|
import org.eclipse.ui.IURIEditorInput;
|
||||||
|
import org.eclipse.ui.editors.text.StorageDocumentProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SourceDocumentProvider
|
||||||
|
*/
|
||||||
|
public class SourceDocumentProvider extends StorageDocumentProvider {
|
||||||
|
|
||||||
|
public SourceDocumentProvider() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose all connected documents.
|
||||||
|
*/
|
||||||
|
public void dispose() {
|
||||||
|
Iterator<?> it = getConnectedElements();
|
||||||
|
while(it.hasNext()) {
|
||||||
|
Object element = it.next();
|
||||||
|
ElementInfo info = getElementInfo(element);
|
||||||
|
// force refcount to 1
|
||||||
|
info.fCount = 1;
|
||||||
|
disconnect(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createDocument(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected IDocument createEmptyDocument() {
|
||||||
|
IDocument doc = new REDDocument();
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.texteditor.AbstractDocumentProvider#createAnnotationModel(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected IAnnotationModel createAnnotationModel(Object element) throws CoreException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.editors.text.StorageDocumentProvider#setupDocument(java.lang.Object, org.eclipse.jface.text.IDocument)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void setupDocument(Object element, IDocument document) {
|
||||||
|
super.setupDocument(element, document);
|
||||||
|
if (element instanceof IStorageEditorInput) {
|
||||||
|
new CDocumentSetupParticipant().setup(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.texteditor.AbstractDocumentProvider#disposeElementInfo(java.lang.Object, org.eclipse.ui.texteditor.AbstractDocumentProvider.ElementInfo)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void disposeElementInfo(Object element, ElementInfo info) {
|
||||||
|
super.disposeElementInfo(element, info);
|
||||||
|
IDocument doc = info.fDocument;
|
||||||
|
if (doc instanceof REDDocument) {
|
||||||
|
((REDDocument)doc).dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.texteditor.AbstractDocumentProvider#getModificationStamp(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getModificationStamp(Object element) {
|
||||||
|
try {
|
||||||
|
if (element instanceof IStorageEditorInput) {
|
||||||
|
IStorage file= ((IStorageEditorInput)element).getStorage();
|
||||||
|
if (file instanceof IFile) {
|
||||||
|
return ((IFile)file).getLocalTimeStamp();
|
||||||
|
} else if (file instanceof IFileState) {
|
||||||
|
return ((IFileState)file).getModificationTime();
|
||||||
|
} else if (file instanceof LocalFileStorage) {
|
||||||
|
return ((LocalFileStorage)file).getFile().lastModified();
|
||||||
|
}
|
||||||
|
} else if (element instanceof IURIEditorInput) {
|
||||||
|
return EFS.getStore(((IURIEditorInput)element).getURI()).fetchInfo().getLastModified();
|
||||||
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IStorage;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.util.StorageEditorInput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SourceEditorInput
|
||||||
|
*/
|
||||||
|
public class SourceEditorInput extends StorageEditorInput {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param storage
|
||||||
|
*/
|
||||||
|
public SourceEditorInput(IStorage storage) {
|
||||||
|
super(storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.ui.IEditorInput#exists()
|
||||||
|
*/
|
||||||
|
public boolean exists() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,187 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
|
import org.eclipse.cdt.core.model.LanguageManager;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IStorage;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.content.IContentType;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation.ISourcePresentationCreator;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation.SourcePresentationCreatorFactory;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.jface.text.Region;
|
||||||
|
import org.eclipse.jface.text.TextPresentation;
|
||||||
|
import org.eclipse.ui.IEditorInput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds information about a source file.
|
||||||
|
*/
|
||||||
|
public class SourceFileInfo {
|
||||||
|
public final String fFileKey;
|
||||||
|
public final IStorage fFile;
|
||||||
|
public IStorage fEdition;
|
||||||
|
public BigInteger[] fLine2Addr;
|
||||||
|
public Addr2Line[] fAddr2Line;
|
||||||
|
public volatile IDocument fSource;
|
||||||
|
public volatile boolean fValid;
|
||||||
|
public Object fLinesNode;
|
||||||
|
public Throwable fError;
|
||||||
|
public volatile SourceReadingJob fReadingJob;
|
||||||
|
public volatile Job fEditionJob;
|
||||||
|
public ISourcePresentationCreator fPresentationCreator;
|
||||||
|
public BigInteger fStartAddress = BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE);
|
||||||
|
public BigInteger fEndAddress= BigInteger.ZERO;
|
||||||
|
|
||||||
|
public SourceFileInfo(String fileKey, IStorage file) {
|
||||||
|
fFileKey = fileKey;
|
||||||
|
fFile = fEdition = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize source document.
|
||||||
|
* @throws CoreException
|
||||||
|
*/
|
||||||
|
public void initSource() throws CoreException {
|
||||||
|
SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider();
|
||||||
|
IEditorInput input = new SourceEditorInput(fEdition);
|
||||||
|
synchronized (provider) {
|
||||||
|
provider.connect(input);
|
||||||
|
}
|
||||||
|
IStatus status = provider.getStatus(input);
|
||||||
|
if (status != null && !status.isOK()) {
|
||||||
|
throw new CoreException(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize presentation creator.
|
||||||
|
* @param viewer
|
||||||
|
*/
|
||||||
|
public void initPresentationCreator(ITextViewer viewer) {
|
||||||
|
SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider();
|
||||||
|
IEditorInput input = new SourceEditorInput(fEdition);
|
||||||
|
IDocument doc = provider.getDocument(input);
|
||||||
|
if (doc != null) {
|
||||||
|
IContentType contentType= null;
|
||||||
|
if (fEdition instanceof IFile) {
|
||||||
|
IFile file= (IFile)fEdition;
|
||||||
|
contentType= CCorePlugin.getContentType(file.getProject(), file.getName());
|
||||||
|
} else {
|
||||||
|
contentType= CCorePlugin.getContentType(fEdition.getName());
|
||||||
|
}
|
||||||
|
ILanguage language= null;
|
||||||
|
if (contentType != null) {
|
||||||
|
language= LanguageManager.getInstance().getLanguage(contentType);
|
||||||
|
}
|
||||||
|
if (language != null) {
|
||||||
|
fPresentationCreator= SourcePresentationCreatorFactory.create(language, fEdition, viewer);
|
||||||
|
}
|
||||||
|
int lines = doc.getNumberOfLines();
|
||||||
|
fLine2Addr = new BigInteger[lines];
|
||||||
|
fAddr2Line = new Addr2Line[lines / 10 + 1];
|
||||||
|
// assign fSource last, triggering source update
|
||||||
|
fSource = doc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose this object.
|
||||||
|
*/
|
||||||
|
public void dispose() {
|
||||||
|
if (fReadingJob != null) {
|
||||||
|
if (!fReadingJob.cancel()) {
|
||||||
|
fReadingJob.dispose();
|
||||||
|
}
|
||||||
|
fReadingJob = null;
|
||||||
|
}
|
||||||
|
if (fPresentationCreator != null) {
|
||||||
|
fPresentationCreator.dispose();
|
||||||
|
fPresentationCreator = null;
|
||||||
|
}
|
||||||
|
SourceDocumentProvider provider = DsfDebugUIPlugin.getSourceDocumentProvider();
|
||||||
|
synchronized (provider) {
|
||||||
|
provider.disconnect(new SourceEditorInput(fEdition));
|
||||||
|
}
|
||||||
|
fSource = null;
|
||||||
|
fValid = false;
|
||||||
|
// fLinesNode = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLine(int lineNr) {
|
||||||
|
return getLines(lineNr, lineNr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLines(int first, int last) {
|
||||||
|
try {
|
||||||
|
int startOffset = fSource.getLineOffset(first);
|
||||||
|
int endOffset;
|
||||||
|
if (last < fSource.getNumberOfLines()-1) {
|
||||||
|
IRegion lastRegion = fSource.getLineInformation(last+1);
|
||||||
|
endOffset = lastRegion.getOffset();
|
||||||
|
} else {
|
||||||
|
// last line
|
||||||
|
IRegion lastRegion = fSource.getLineInformation(last);
|
||||||
|
endOffset = lastRegion.getOffset() + lastRegion.getLength();
|
||||||
|
}
|
||||||
|
return fSource.get(startOffset, endOffset - startOffset);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRegion getRegion(int line, int length) {
|
||||||
|
try {
|
||||||
|
IRegion lineRegion = fSource.getLineInformation(line);
|
||||||
|
return new Region(lineRegion.getOffset(), length);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create text presentation for the given region.
|
||||||
|
* Must be called in display thread.
|
||||||
|
* @param region
|
||||||
|
* @return text presentation
|
||||||
|
*/
|
||||||
|
public TextPresentation getPresentation(IRegion region) {
|
||||||
|
if (fSource != null && fPresentationCreator != null) {
|
||||||
|
return fPresentationCreator.getPresentation(region, fSource);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return offset of given line
|
||||||
|
*/
|
||||||
|
public int getLineOffset(int line) {
|
||||||
|
if (fSource != null) {
|
||||||
|
try {
|
||||||
|
return fSource.getLineOffset(line);
|
||||||
|
} catch (BadLocationException e) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SourcePosition
|
||||||
|
*/
|
||||||
|
public class SourcePosition extends AddressRangePosition {
|
||||||
|
|
||||||
|
public SourceFileInfo fFileInfo;
|
||||||
|
public int fLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @param addressOffset
|
||||||
|
* @param fileInfo
|
||||||
|
* @param line
|
||||||
|
*/
|
||||||
|
public SourcePosition(int offset, int length, BigInteger addressOffset, SourceFileInfo fileInfo, int line) {
|
||||||
|
this(offset, length, addressOffset, fileInfo, line, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @param addressOffset
|
||||||
|
* @param fileInfo
|
||||||
|
* @param line
|
||||||
|
* @param valid
|
||||||
|
*/
|
||||||
|
public SourcePosition(int offset, int length, BigInteger addressOffset, SourceFileInfo fileInfo, int line, boolean valid) {
|
||||||
|
super(offset, length, addressOffset, BigInteger.ZERO, valid);
|
||||||
|
fFileInfo = fileInfo;
|
||||||
|
fLine = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.model;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Low-level job to read source files in the background.
|
||||||
|
*/
|
||||||
|
public class SourceReadingJob extends Job {
|
||||||
|
|
||||||
|
private final static String NAME = DisassemblyMessages.SourceReadingJob_name;
|
||||||
|
|
||||||
|
private SourceFileInfo fFileInfo;
|
||||||
|
private Runnable fDone;
|
||||||
|
|
||||||
|
public SourceReadingJob(SourceFileInfo fi, Runnable done) {
|
||||||
|
super(NAME);
|
||||||
|
fFileInfo = fi;
|
||||||
|
fFileInfo.fReadingJob = this;
|
||||||
|
fDone = done;
|
||||||
|
if (fi.fFile instanceof ISchedulingRule) {
|
||||||
|
setRule((ISchedulingRule)fi.fFile);
|
||||||
|
}
|
||||||
|
setSystem(true);
|
||||||
|
// usually short lived job
|
||||||
|
setPriority(SHORT);
|
||||||
|
if (fi.fFile.getFullPath() != null) {
|
||||||
|
String fileName = fi.fFile.getFullPath().lastSegment();
|
||||||
|
setName(NAME + " (" + fileName + ')'); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void dispose() {
|
||||||
|
fDone = null;
|
||||||
|
Thread thread = getThread();
|
||||||
|
if (thread != null && thread.isAlive()) {
|
||||||
|
thread.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IStatus run(IProgressMonitor monitor) {
|
||||||
|
if (fFileInfo.fEditionJob != null) {
|
||||||
|
try {
|
||||||
|
fFileInfo.fEditionJob.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
fFileInfo.initSource();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
fFileInfo.fError = e;
|
||||||
|
} finally {
|
||||||
|
fFileInfo.fReadingJob = null;
|
||||||
|
synchronized (this) {
|
||||||
|
if (fDone != null && !getThread().isInterrupted()) {
|
||||||
|
fDone.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// errors are handled elsewhere
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.preference.PreferenceConverter;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.ui.editors.text.EditorsUI;
|
||||||
|
import org.eclipse.ui.editors.text.TextEditorPreferenceConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyPreferenceConstants
|
||||||
|
*/
|
||||||
|
public class DisassemblyPreferenceConstants {
|
||||||
|
|
||||||
|
public static final String START_ADDRESS = "startAddress"; //$NON-NLS-1$
|
||||||
|
public static final String END_ADDRESS = "endAddress"; //$NON-NLS-1$
|
||||||
|
public static final String PC_HISTORY_SIZE = "pcHistorySize"; //$NON-NLS-1$
|
||||||
|
public static final String SHOW_SOURCE = "showSource"; //$NON-NLS-1$
|
||||||
|
public static final String SHOW_LABELS = "showLabels"; //$NON-NLS-1$
|
||||||
|
public static final String SHOW_SYMBOLS = "showSymbols"; //$NON-NLS-1$
|
||||||
|
public static final String SIMPLIFIED = "simplified"; //$NON-NLS-1$
|
||||||
|
public static final String INSTRUCTION_RADIX = "instructionRadix"; //$NON-NLS-1$
|
||||||
|
public static final String ADDRESS_RADIX = "addressRadix"; //$NON-NLS-1$
|
||||||
|
public static final String SHOW_ADDRESS_RADIX = "showAddressRadix"; //$NON-NLS-1$
|
||||||
|
public static final String SHOW_ADDRESS_RULER = "showAddressRuler"; //$NON-NLS-1$
|
||||||
|
public static final String ADDRESS_COLOR = "addressColor"; //$NON-NLS-1$
|
||||||
|
public static final String SHOW_FUNCTION_OFFSETS = "showOpcodeRuler"; //$NON-NLS-1$
|
||||||
|
public static final String OPCODE_COLOR = "opcodeColor"; //$NON-NLS-1$
|
||||||
|
public static final String USE_SOURCE_ONLY_MODE = "useSourceOnlyMode"; //$NON-NLS-1$
|
||||||
|
public static final String AVOID_READ_BEFORE_PC = "avoidReadBeforePC"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private DisassemblyPreferenceConstants() {
|
||||||
|
// not intended to be subclassed or instatiated
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize preference default values.
|
||||||
|
* @param store
|
||||||
|
*/
|
||||||
|
public static void initializeDefaults(IPreferenceStore store) {
|
||||||
|
TextEditorPreferenceConstants.initializeDefaultValues(store);
|
||||||
|
store.setDefault(START_ADDRESS, 0x0L);
|
||||||
|
store.setDefault(END_ADDRESS, "0x" + BigInteger.ONE.shiftLeft(64).toString(16)); //$NON-NLS-1$
|
||||||
|
store.setDefault(PC_HISTORY_SIZE, 4);
|
||||||
|
store.setDefault(SHOW_SOURCE, true);
|
||||||
|
store.setDefault(SHOW_FUNCTION_OFFSETS, false);
|
||||||
|
store.setDefault(SHOW_LABELS, true);
|
||||||
|
store.setDefault(SHOW_SYMBOLS, true);
|
||||||
|
store.setDefault(SIMPLIFIED, true);
|
||||||
|
store.setDefault(INSTRUCTION_RADIX, 16);
|
||||||
|
store.setDefault(ADDRESS_RADIX, 16);
|
||||||
|
store.setDefault(SHOW_ADDRESS_RADIX, false);
|
||||||
|
store.setDefault(SHOW_ADDRESS_RULER, true);
|
||||||
|
store.setDefault(AVOID_READ_BEFORE_PC, false);
|
||||||
|
store.setDefault(USE_SOURCE_ONLY_MODE, false);
|
||||||
|
PreferenceConverter.setDefault(store, ADDRESS_COLOR, new RGB(0, 96, 0));
|
||||||
|
PreferenceConverter.setDefault(store, OPCODE_COLOR, new RGB(96, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Initializer extends AbstractPreferenceInitializer {
|
||||||
|
@Override
|
||||||
|
public void initializeDefaultPreferences() {
|
||||||
|
IPreferenceStore store = DsfDebugUIPlugin.getDefault().getPreferenceStore();
|
||||||
|
initializeDefaults(store);
|
||||||
|
EditorsUI.useAnnotationsPreferencePage(store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,313 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.preferences;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.DsfDebugUIPlugin;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.IDisassemblyHelpContextIds;
|
||||||
|
import org.eclipse.jface.dialogs.Dialog;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.preference.PreferencePage;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.ModifyEvent;
|
||||||
|
import org.eclipse.swt.events.ModifyListener;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Combo;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Text;
|
||||||
|
import org.eclipse.ui.IWorkbench;
|
||||||
|
import org.eclipse.ui.IWorkbenchPreferencePage;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyPreferencePage
|
||||||
|
*/
|
||||||
|
public class DisassemblyPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
|
||||||
|
|
||||||
|
private List<Button> fCheckBoxes = new ArrayList<Button>();
|
||||||
|
private List<Combo> fComboBoxes = new ArrayList<Combo>();
|
||||||
|
private ArrayList<Text> fNumberFields = new ArrayList<Text>();
|
||||||
|
private ModifyListener fNumberFieldListener = new ModifyListener() {
|
||||||
|
public void modifyText(ModifyEvent e) {
|
||||||
|
numberFieldChanged((Text)e.widget);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private final static String[] fcRadixItems = {
|
||||||
|
DisassemblyMessages.DisassemblyPreferencePage_radix_octal,
|
||||||
|
DisassemblyMessages.DisassemblyPreferencePage_radix_decimal,
|
||||||
|
DisassemblyMessages.DisassemblyPreferencePage_radix_hexadecimal,
|
||||||
|
};
|
||||||
|
private final static int[] fcRadixValues = {
|
||||||
|
8, 10, 16
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the Disassembly preference page.
|
||||||
|
*/
|
||||||
|
public DisassemblyPreferencePage() {
|
||||||
|
super();
|
||||||
|
setPreferenceStore(DsfDebugUIPlugin.getDefault().getPreferenceStore());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void createControl(Composite parent) {
|
||||||
|
super.createControl(parent);
|
||||||
|
PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IDisassemblyHelpContextIds.DISASSEMBLY_PREFERENCE_PAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Control createContents(Composite parent) {
|
||||||
|
Composite composite = new Composite(parent, SWT.NULL);
|
||||||
|
GridLayout layout = new GridLayout();
|
||||||
|
layout.marginHeight = 0;
|
||||||
|
layout.marginWidth = 0;
|
||||||
|
layout.numColumns = 2;
|
||||||
|
composite.setLayout(layout);
|
||||||
|
composite.setFont(parent.getFont());
|
||||||
|
|
||||||
|
String label;
|
||||||
|
|
||||||
|
// label = DisassemblyMessages.DisassemblyPreferencePage_startAddress; //$NON-NLS-1$
|
||||||
|
// addTextField(composite, label, DisassemblyPreferenceConstants.START_ADDRESS, 20, 0, true);
|
||||||
|
// label = DisassemblyMessages.DisassemblyPreferencePage_endAddress; //$NON-NLS-1$
|
||||||
|
// addTextField(composite, label, DisassemblyPreferenceConstants.END_ADDRESS, 20, 0, true);
|
||||||
|
|
||||||
|
label = DisassemblyMessages.DisassemblyPreferencePage_addressRadix;
|
||||||
|
addComboBox(composite, label, DisassemblyPreferenceConstants.ADDRESS_RADIX, fcRadixItems);
|
||||||
|
// label = DisassemblyMessages.DisassemblyPreferencePage_instructionRadix;
|
||||||
|
// addComboBox(composite, label, DisassemblyPreferenceConstants.INSTRUCTION_RADIX, fcRadixItems);
|
||||||
|
|
||||||
|
label = DisassemblyMessages.DisassemblyPreferencePage_showSource;
|
||||||
|
addCheckBox(composite, label, DisassemblyPreferenceConstants.SHOW_SOURCE, 0);
|
||||||
|
label = DisassemblyMessages.DisassemblyPreferencePage_showSymbols;
|
||||||
|
addCheckBox(composite, label, DisassemblyPreferenceConstants.SHOW_SYMBOLS, 0);
|
||||||
|
// label = DisassemblyMessages.DisassemblyPreferencePage_simplifiedMnemonics;
|
||||||
|
// addCheckBox(composite, label, DisassemblyPreferenceConstants.SIMPLIFIED, 0);
|
||||||
|
label = DisassemblyMessages.DisassemblyPreferencePage_showAddressRadix;
|
||||||
|
addCheckBox(composite, label, DisassemblyPreferenceConstants.SHOW_ADDRESS_RADIX, 0);
|
||||||
|
label = DisassemblyMessages.DisassemblyPreferencePage_showFunctionOffsets;
|
||||||
|
addCheckBox(composite, label, DisassemblyPreferenceConstants.SHOW_FUNCTION_OFFSETS, 0);
|
||||||
|
label = DisassemblyMessages.DisassemblyPreferencePage_showAddress;
|
||||||
|
addCheckBox(composite, label, DisassemblyPreferenceConstants.SHOW_ADDRESS_RULER, 0);
|
||||||
|
// label = DisassemblyMessages.DisassemblyPreferencePage_avoidReadBeforePC;
|
||||||
|
// addCheckBox(composite, label, DisassemblyPreferenceConstants.AVOID_READ_BEFORE_PC, 0);
|
||||||
|
|
||||||
|
// horizontal line
|
||||||
|
// Label separator = new Label(composite, SWT.SEPARATOR|SWT.HORIZONTAL);
|
||||||
|
// GridData data;
|
||||||
|
// data = new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
// data.horizontalSpan = layout.numColumns;
|
||||||
|
// separator.setLayoutData(data);
|
||||||
|
//
|
||||||
|
// label = DisassemblyMessages.DisassemblyPreferencePage_useSourceOnlyMode;
|
||||||
|
// addCheckBox(composite, label, DisassemblyPreferenceConstants.USE_SOURCE_ONLY_MODE, 0);
|
||||||
|
//
|
||||||
|
// // note
|
||||||
|
// String noteTitle = DisassemblyMessages.DisassemblyPreferencePage_useSourceOnlyMode_noteTtitle;
|
||||||
|
// String noteMessage = DisassemblyMessages.DisassemblyPreferencePage_useSourceOnlyMode_noteMessage;
|
||||||
|
// Composite note = createNoteComposite(composite.getFont(), composite, noteTitle, noteMessage);
|
||||||
|
// data = (GridData)note.getLayoutData();
|
||||||
|
// if (data == null) {
|
||||||
|
// data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
|
||||||
|
// note.setLayoutData(data);
|
||||||
|
// }
|
||||||
|
// data.horizontalSpan = layout.numColumns;
|
||||||
|
// Control msgControl = note.getChildren()[1];
|
||||||
|
// data = new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
// data.widthHint = convertWidthInCharsToPixels(65);
|
||||||
|
// data.heightHint = convertHeightInCharsToPixels(3);
|
||||||
|
// msgControl.setLayoutData(data);
|
||||||
|
|
||||||
|
Dialog.applyDialogFont(parent);
|
||||||
|
|
||||||
|
initialize();
|
||||||
|
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
|
||||||
|
*/
|
||||||
|
public void init(IWorkbench workbench) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button addCheckBox(Composite parent, String label, String key, int indentation) {
|
||||||
|
Button checkBox = new Button(parent, SWT.CHECK);
|
||||||
|
checkBox.setText(label);
|
||||||
|
|
||||||
|
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
|
||||||
|
gd.horizontalIndent = indentation;
|
||||||
|
gd.horizontalSpan = 2;
|
||||||
|
checkBox.setLayoutData(gd);
|
||||||
|
checkBox.setData(key);
|
||||||
|
fCheckBoxes.add(checkBox);
|
||||||
|
|
||||||
|
return checkBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Combo addComboBox(Composite parent, String label, String key, String[] items) {
|
||||||
|
Label labelControl= new Label(parent, SWT.NONE);
|
||||||
|
labelControl.setText(label);
|
||||||
|
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
|
||||||
|
labelControl.setLayoutData(gd);
|
||||||
|
|
||||||
|
Combo combo = new Combo(parent, SWT.READ_ONLY);
|
||||||
|
gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
|
||||||
|
combo.setLayoutData(gd);
|
||||||
|
combo.setItems(items);
|
||||||
|
combo.setData(key);
|
||||||
|
fComboBoxes.add(combo);
|
||||||
|
|
||||||
|
return combo;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Text addTextField(Composite composite, String label, String key, int textLimit, int indentation, boolean isNumber) {
|
||||||
|
return getTextControl(addLabelledTextField(composite, label, key, textLimit, indentation, isNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static Label getLabelControl(Control[] labelledTextField){
|
||||||
|
// return (Label)labelledTextField[0];
|
||||||
|
// }
|
||||||
|
|
||||||
|
private static Text getTextControl(Control[] labelledTextField){
|
||||||
|
return (Text)labelledTextField[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of size 2:
|
||||||
|
* - first element is of type <code>Label</code>
|
||||||
|
* - second element is of type <code>Text</code>
|
||||||
|
* Use <code>getLabelControl</code> and <code>getTextControl</code> to get the 2 controls.
|
||||||
|
*/
|
||||||
|
private Control[] addLabelledTextField(Composite composite, String label, String key, int textLimit, int indentation, boolean isNumber) {
|
||||||
|
Label labelControl= new Label(composite, SWT.NONE);
|
||||||
|
labelControl.setText(label);
|
||||||
|
GridData gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
|
||||||
|
gd.horizontalIndent= indentation;
|
||||||
|
labelControl.setLayoutData(gd);
|
||||||
|
|
||||||
|
Text textControl= new Text(composite, SWT.BORDER | SWT.SINGLE);
|
||||||
|
gd= new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
|
||||||
|
gd.widthHint= convertWidthInCharsToPixels(textLimit + 1);
|
||||||
|
textControl.setLayoutData(gd);
|
||||||
|
textControl.setTextLimit(textLimit);
|
||||||
|
textControl.setData(key);
|
||||||
|
if (isNumber) {
|
||||||
|
fNumberFields.add(textControl);
|
||||||
|
textControl.addModifyListener(fNumberFieldListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Control[]{labelControl, textControl};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.preference.IPreferencePage#performOk()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean performOk() {
|
||||||
|
IPreferenceStore store = getPreferenceStore();
|
||||||
|
for (Iterator<Button> iter = fCheckBoxes.iterator(); iter.hasNext();) {
|
||||||
|
Button btn = iter.next();
|
||||||
|
store.setValue((String)btn.getData(), btn.getSelection());
|
||||||
|
}
|
||||||
|
for (Iterator<Text> iter = fNumberFields.iterator(); iter.hasNext();) {
|
||||||
|
Text field = iter.next();
|
||||||
|
store.setValue((String)field.getData(), Long.decode(field.getText()).longValue());
|
||||||
|
}
|
||||||
|
for (Iterator<Combo> iter = fComboBoxes.iterator(); iter.hasNext();) {
|
||||||
|
Combo combo = iter.next();
|
||||||
|
store.setValue((String)combo.getData(), fcRadixValues[combo.getSelectionIndex()]);
|
||||||
|
}
|
||||||
|
return super.performOk();
|
||||||
|
}
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.preference.PreferencePage#performDefaults()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void performDefaults() {
|
||||||
|
IPreferenceStore store = getPreferenceStore();
|
||||||
|
for (Iterator<Button> iter = fCheckBoxes.iterator(); iter.hasNext();) {
|
||||||
|
Button btn = iter.next();
|
||||||
|
btn.setSelection(store.getDefaultBoolean((String)btn.getData()));
|
||||||
|
}
|
||||||
|
for (Iterator<Text> iter = fNumberFields.iterator(); iter.hasNext();) {
|
||||||
|
Text field = iter.next();
|
||||||
|
long value = store.getDefaultLong((String)field.getData());
|
||||||
|
field.setText("0x"+Long.toHexString(value)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
for (Iterator<Combo> iter = fComboBoxes.iterator(); iter.hasNext();) {
|
||||||
|
Combo combo = iter.next();
|
||||||
|
int value = store.getDefaultInt((String)combo.getData());
|
||||||
|
for (int i = 0; i < fcRadixValues.length; i++) {
|
||||||
|
if (fcRadixValues[i] == value) {
|
||||||
|
combo.select(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.performDefaults();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Initialize widget values from preference store.
|
||||||
|
*/
|
||||||
|
private void initialize() {
|
||||||
|
IPreferenceStore store = getPreferenceStore();
|
||||||
|
for (Iterator<Button> iter = fCheckBoxes.iterator(); iter.hasNext();) {
|
||||||
|
Button btn = iter.next();
|
||||||
|
btn.setSelection(store.getBoolean((String)btn.getData()));
|
||||||
|
}
|
||||||
|
for (Iterator<Text> iter = fNumberFields.iterator(); iter.hasNext();) {
|
||||||
|
Text field = iter.next();
|
||||||
|
long value = store.getLong((String)field.getData());
|
||||||
|
field.setText("0x"+Long.toHexString(value)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
for (Iterator<Combo> iter = fComboBoxes.iterator(); iter.hasNext();) {
|
||||||
|
Combo combo = iter.next();
|
||||||
|
int value = store.getInt((String)combo.getData());
|
||||||
|
for (int i = 0; i < fcRadixValues.length; i++) {
|
||||||
|
if (fcRadixValues[i] == value) {
|
||||||
|
combo.select(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param text
|
||||||
|
*/
|
||||||
|
protected void numberFieldChanged(Text text) {
|
||||||
|
try {
|
||||||
|
long value = Long.decode(text.getText()).longValue();
|
||||||
|
if (value < 0) {
|
||||||
|
setErrorMessage(DisassemblyMessages.DisassemblyPreferencePage_error_negative_number);
|
||||||
|
} else {
|
||||||
|
setErrorMessage(null);
|
||||||
|
}
|
||||||
|
} catch(NumberFormatException nfe) {
|
||||||
|
setErrorMessage(DisassemblyMessages.DisassemblyPreferencePage_error_not_a_number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,349 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
|
import org.eclipse.cdt.core.model.IAsmLanguage;
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
import org.eclipse.cdt.core.model.ICModel;
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.CDocumentProvider;
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.ITranslationUnitEditorInput;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CCommentScanner;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.CTextTools;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.ICColorConstants;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.IColorManager;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.SimpleCSourceViewerConfiguration;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.TokenStore;
|
||||||
|
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
import org.eclipse.cdt.ui.text.ITokenStore;
|
||||||
|
import org.eclipse.cdt.ui.text.ITokenStoreFactory;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IFileState;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IStorage;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.jface.text.Region;
|
||||||
|
import org.eclipse.jface.text.TextPresentation;
|
||||||
|
import org.eclipse.jface.text.presentation.PresentationReconciler;
|
||||||
|
import org.eclipse.jface.text.rules.ITokenScanner;
|
||||||
|
import org.eclipse.jface.text.rules.RuleBasedScanner;
|
||||||
|
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||||
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.ui.IEditorInput;
|
||||||
|
import org.eclipse.ui.texteditor.IDocumentProvider;
|
||||||
|
import org.eclipse.ui.texteditor.ITextEditor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A presentation creator based on CDT syntax highlighting.
|
||||||
|
*/
|
||||||
|
public class CSourcePresentationCreator extends PresentationReconciler implements ISourcePresentationCreator, IPropertyChangeListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private final static class CustomCSourceViewerConfiguration extends SimpleCSourceViewerConfiguration {
|
||||||
|
/**
|
||||||
|
* Comment for <code>fLanguage</code>
|
||||||
|
*/
|
||||||
|
private final ILanguage fLanguage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param colorManager
|
||||||
|
* @param preferenceStore
|
||||||
|
* @param language
|
||||||
|
*/
|
||||||
|
private CustomCSourceViewerConfiguration(
|
||||||
|
IColorManager colorManager, IPreferenceStore preferenceStore,
|
||||||
|
ILanguage language) {
|
||||||
|
super(colorManager, preferenceStore, null, ICPartitions.C_PARTITIONING, false);
|
||||||
|
fLanguage = language;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration#getLanguage()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ILanguage getLanguage() {
|
||||||
|
return fLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param contentType
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ITokenScanner getScannerForContentType(String contentType) {
|
||||||
|
if (IDocument.DEFAULT_CONTENT_TYPE.equals(contentType)) {
|
||||||
|
return getLanguage() != null ? getCodeScanner(getLanguage()) : null;
|
||||||
|
} else if (ICPartitions.C_CHARACTER.equals(contentType)) {
|
||||||
|
return getStringScanner();
|
||||||
|
} else if (ICPartitions.C_STRING.equals(contentType)) {
|
||||||
|
return getStringScanner();
|
||||||
|
} else if (ICPartitions.C_SINGLE_LINE_COMMENT.equals(contentType)) {
|
||||||
|
return getSinglelineCommentScanner();
|
||||||
|
} else if (ICPartitions.C_SINGLE_LINE_DOC_COMMENT.equals(contentType)) {
|
||||||
|
return getSinglelineDocCommentScanner(getProject());
|
||||||
|
} else if (ICPartitions.C_MULTI_LINE_COMMENT.equals(contentType)) {
|
||||||
|
return getMultilineCommentScanner();
|
||||||
|
} else if (ICPartitions.C_MULTI_LINE_DOC_COMMENT.equals(contentType)) {
|
||||||
|
return getMultilineDocCommentScanner(getProject());
|
||||||
|
} else if (ICPartitions.C_PREPROCESSOR.equals(contentType)) {
|
||||||
|
return getPreprocessorScanner(getLanguage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITokenScanner getMultilineCommentScanner() {
|
||||||
|
return new CCommentScanner(getTokenStoreFactory(), ICColorConstants.C_SINGLE_LINE_COMMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITokenScanner getSinglelineCommentScanner() {
|
||||||
|
return new CCommentScanner(getTokenStoreFactory(), ICColorConstants.C_MULTI_LINE_COMMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ICProject associated with this CSourceViewerConfiguration, or null if
|
||||||
|
* no ICProject could be determined
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private ICProject internalGetCProject() {
|
||||||
|
ITextEditor editor= getEditor();
|
||||||
|
if (editor == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ICElement element= null;
|
||||||
|
IEditorInput input= editor.getEditorInput();
|
||||||
|
IDocumentProvider provider= editor.getDocumentProvider();
|
||||||
|
if (provider instanceof CDocumentProvider) {
|
||||||
|
CDocumentProvider cudp= (CDocumentProvider) provider;
|
||||||
|
element= cudp.getWorkingCopy(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return element.getCProject();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the IProject associated with this CSourceViewerConfiguration, or null if
|
||||||
|
* no IProject could be determined
|
||||||
|
*/
|
||||||
|
private IProject getProject() {
|
||||||
|
ICProject cproject= internalGetCProject();
|
||||||
|
return cproject!=null ? cproject.getProject() :null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITokenStoreFactory getTokenStoreFactory() {
|
||||||
|
return new ITokenStoreFactory() {
|
||||||
|
public ITokenStore createTokenStore(String[] propertyColorNames) {
|
||||||
|
return new TokenStore(getColorManager(), fPreferenceStore, propertyColorNames);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration#getCodeScanner(org.eclipse.cdt.core.model.ILanguage)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected RuleBasedScanner getCodeScanner(ILanguage language) {
|
||||||
|
if (language instanceof IAsmLanguage) {
|
||||||
|
return CUIPlugin.getDefault().getAsmTextTools().getCodeScanner();
|
||||||
|
}
|
||||||
|
return super.getCodeScanner(language);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration#getPreprocessorScanner(org.eclipse.cdt.core.model.ILanguage)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected RuleBasedScanner getPreprocessorScanner(ILanguage language) {
|
||||||
|
if (language instanceof IAsmLanguage) {
|
||||||
|
return CUIPlugin.getDefault().getAsmTextTools().getPreprocessorScanner();
|
||||||
|
}
|
||||||
|
return super.getPreprocessorScanner(language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ITextViewer fViewer;
|
||||||
|
private ISourceTagProvider fSourceTagProvider;
|
||||||
|
private SourceTagDamagerRepairer fDamagerRepairer;
|
||||||
|
private ISourceTagListener fSourceTagListener;
|
||||||
|
private TextPresentation fPresentation;
|
||||||
|
private CustomCSourceViewerConfiguration fSourceViewerConfiguration;
|
||||||
|
private IPreferenceStore fPreferenceStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param language
|
||||||
|
* @param storage
|
||||||
|
* @param textViewer
|
||||||
|
*/
|
||||||
|
public CSourcePresentationCreator(ILanguage language, IStorage storage, ITextViewer textViewer) {
|
||||||
|
if (language != null) {
|
||||||
|
fViewer= textViewer;
|
||||||
|
fPreferenceStore= CUIPlugin.getDefault().getCombinedPreferenceStore();
|
||||||
|
CTextTools textTools = CUIPlugin.getDefault().getTextTools();
|
||||||
|
fSourceViewerConfiguration= new CustomCSourceViewerConfiguration(textTools.getColorManager(), fPreferenceStore, language);
|
||||||
|
setDocumentPartitioning(fSourceViewerConfiguration.getConfiguredDocumentPartitioning(null));
|
||||||
|
initializeDamagerRepairer(storage, textTools.getColorManager(), fPreferenceStore);
|
||||||
|
fPreferenceStore.addPropertyChangeListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeDamagerRepairer(IStorage storage, IColorManager colorManager, IPreferenceStore store) {
|
||||||
|
String[] contentTypes= fSourceViewerConfiguration.getConfiguredContentTypes(null);
|
||||||
|
for (int i = 0; i < contentTypes.length; ++i) {
|
||||||
|
String contentType = contentTypes[i];
|
||||||
|
ITokenScanner scanner;
|
||||||
|
scanner = fSourceViewerConfiguration.getScannerForContentType(contentType);
|
||||||
|
if (scanner != null) {
|
||||||
|
if (fDamagerRepairer == null) {
|
||||||
|
fSourceTagProvider = createSourceTagProvider(storage);
|
||||||
|
fDamagerRepairer= new SourceTagDamagerRepairer(scanner, fSourceTagProvider, colorManager, store);
|
||||||
|
if (fSourceTagProvider != null) {
|
||||||
|
if (fSourceTagListener == null) {
|
||||||
|
fSourceTagListener= new ISourceTagListener() {
|
||||||
|
public void sourceTagsChanged(ISourceTagProvider provider) {
|
||||||
|
handleSourceTagsChanged();
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
fSourceTagProvider.addSourceTagListener(fSourceTagListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fDamagerRepairer.setScanner(contentType, scanner);
|
||||||
|
setDamager(fDamagerRepairer, contentType);
|
||||||
|
setRepairer(fDamagerRepairer, contentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.model.ISourcePresentationCreator#dispose()
|
||||||
|
*/
|
||||||
|
public void dispose() {
|
||||||
|
fViewer= null;
|
||||||
|
fPresentation= null;
|
||||||
|
if (fPreferenceStore != null) {
|
||||||
|
fPreferenceStore.removePropertyChangeListener(this);
|
||||||
|
fPreferenceStore= null;
|
||||||
|
}
|
||||||
|
if (fSourceViewerConfiguration != null) {
|
||||||
|
fSourceViewerConfiguration.dispose();
|
||||||
|
fSourceViewerConfiguration= null;
|
||||||
|
}
|
||||||
|
if (fSourceTagProvider != null) {
|
||||||
|
if (fSourceTagListener != null) {
|
||||||
|
fSourceTagProvider.removeSourceTagListener(fSourceTagListener);
|
||||||
|
fSourceTagListener= null;
|
||||||
|
}
|
||||||
|
fSourceTagProvider= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.disassembly.model.ISourcePresentationCreator#getPresentation(org.eclipse.jface.text.IRegion, org.eclipse.jface.text.IDocument)
|
||||||
|
*/
|
||||||
|
public TextPresentation getPresentation(IRegion region, IDocument document) {
|
||||||
|
assert fViewer != null;
|
||||||
|
if (fViewer == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (fPresentation == null) {
|
||||||
|
setDocumentToDamagers(document);
|
||||||
|
setDocumentToRepairers(document);
|
||||||
|
int docLength= document.getLength();
|
||||||
|
if (docLength <= 128*1024) {
|
||||||
|
IRegion all= new Region(0, docLength);
|
||||||
|
fPresentation= createPresentation(all, document);
|
||||||
|
} else {
|
||||||
|
return createPresentation(region, document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fPresentation.setResultWindow(region);
|
||||||
|
return fPresentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void handleSourceTagsChanged() {
|
||||||
|
invalidateTextPresentation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invalidateTextPresentation() {
|
||||||
|
if (fPresentation != null) {
|
||||||
|
fPresentation= null;
|
||||||
|
if (fViewer != null) {
|
||||||
|
Display display= fViewer.getTextWidget().getDisplay();
|
||||||
|
if (display.getThread() != Thread.currentThread()) {
|
||||||
|
display.asyncExec(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (fViewer != null) {
|
||||||
|
fViewer.invalidateTextPresentation();
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
} else {
|
||||||
|
fViewer.invalidateTextPresentation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISourceTagProvider createSourceTagProvider(IStorage storage) {
|
||||||
|
ITranslationUnit tUnit= null;
|
||||||
|
if (storage instanceof IFile) {
|
||||||
|
tUnit= (ITranslationUnit) CoreModel.getDefault().create((IFile)storage);
|
||||||
|
} else if (storage instanceof IFileState) {
|
||||||
|
ICModel cModel= CoreModel.getDefault().getCModel();
|
||||||
|
ICProject[] cProjects;
|
||||||
|
try {
|
||||||
|
cProjects = cModel.getCProjects();
|
||||||
|
if (cProjects.length > 0) {
|
||||||
|
tUnit= CoreModel.getDefault().createTranslationUnitFrom(cProjects[0], storage.getFullPath());
|
||||||
|
}
|
||||||
|
} catch (CModelException e) {
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IEditorInput input= EditorUtility.getEditorInputForLocation(storage.getFullPath(), null);
|
||||||
|
if (input instanceof ITranslationUnitEditorInput) {
|
||||||
|
tUnit= ((ITranslationUnitEditorInput)input).getTranslationUnit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tUnit != null) {
|
||||||
|
return new CSourceTagProvider(tUnit);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
|
||||||
|
*/
|
||||||
|
public void propertyChange(PropertyChangeEvent event) {
|
||||||
|
if (fSourceViewerConfiguration.affectsBehavior(event)) {
|
||||||
|
fSourceViewerConfiguration.handlePropertyChangeEvent(event);
|
||||||
|
invalidateTextPresentation();
|
||||||
|
} else if (fDamagerRepairer.affectsBahvior(event)) {
|
||||||
|
fDamagerRepairer.handlePropertyChangeEvent(event);
|
||||||
|
invalidateTextPresentation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
import org.eclipse.cdt.core.model.ISourceReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A source tag based on C Model elements.
|
||||||
|
*/
|
||||||
|
public class CSourceTag implements ISourceTag {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The zero-length source range.
|
||||||
|
*/
|
||||||
|
public class NullRange implements ISourceRange {
|
||||||
|
|
||||||
|
public boolean contains(int offset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBeginOffset() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndOffset() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(ISourceRange other) {
|
||||||
|
if (this == other) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The source range.
|
||||||
|
*/
|
||||||
|
public class CSourceRange implements ISourceRange {
|
||||||
|
|
||||||
|
private org.eclipse.cdt.core.model.ISourceRange fRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sourceRange
|
||||||
|
*/
|
||||||
|
public CSourceRange(org.eclipse.cdt.core.model.ISourceRange sourceRange) {
|
||||||
|
fRange= sourceRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(int offset) {
|
||||||
|
return fRange.getStartPos() <= offset && offset - fRange.getStartPos() < fRange.getLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBeginOffset() {
|
||||||
|
return fRange.getStartPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndOffset() {
|
||||||
|
return fRange.getStartPos() + fRange.getLength() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(ISourceRange other) {
|
||||||
|
int delta= this.getBeginOffset() - other.getBeginOffset();
|
||||||
|
if (delta == 0) {
|
||||||
|
delta= this.getEndOffset() - other.getEndOffset();
|
||||||
|
}
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifier range.
|
||||||
|
*/
|
||||||
|
public class CIdentifierRange implements ISourceRange {
|
||||||
|
|
||||||
|
private org.eclipse.cdt.core.model.ISourceRange fRange;
|
||||||
|
|
||||||
|
public CIdentifierRange(org.eclipse.cdt.core.model.ISourceRange sourceRange) {
|
||||||
|
fRange= sourceRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(int offset) {
|
||||||
|
return fRange.getIdStartPos() <= offset && offset - fRange.getIdStartPos() < fRange.getIdLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBeginOffset() {
|
||||||
|
return fRange.getIdStartPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEndOffset() {
|
||||||
|
return fRange.getIdStartPos() + fRange.getIdLength() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(ISourceRange other) {
|
||||||
|
int delta= this.getBeginOffset() - other.getBeginOffset();
|
||||||
|
if (delta == 0) {
|
||||||
|
delta= this.getEndOffset() - other.getEndOffset();
|
||||||
|
}
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISourceReference fReference;
|
||||||
|
private int fType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new source tag for the given element and type.
|
||||||
|
*
|
||||||
|
* @param element
|
||||||
|
* @param elementType
|
||||||
|
*/
|
||||||
|
public CSourceTag(ISourceReference element, int elementType) {
|
||||||
|
fReference= element;
|
||||||
|
fType= elementType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISourceRange getFullRange() {
|
||||||
|
try {
|
||||||
|
return new CSourceRange(fReference.getSourceRange());
|
||||||
|
} catch (CModelException e) {
|
||||||
|
}
|
||||||
|
return new NullRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return ((ICElement)fReference).getElementName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQualifiedName() {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISourceRange getRangeOfIdentifier() {
|
||||||
|
try {
|
||||||
|
return new CIdentifierRange(fReference.getSourceRange());
|
||||||
|
} catch (CModelException e) {
|
||||||
|
}
|
||||||
|
return new NullRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSnapshotTime() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStyleCode() {
|
||||||
|
switch (fType) {
|
||||||
|
case ICElement.C_METHOD :
|
||||||
|
case ICElement.C_METHOD_DECLARATION:
|
||||||
|
case ICElement.C_TEMPLATE_METHOD:
|
||||||
|
case ICElement.C_TEMPLATE_METHOD_DECLARATION:
|
||||||
|
return ISourceTag.STYLE_Method;
|
||||||
|
case ICElement.C_FUNCTION:
|
||||||
|
case ICElement.C_FUNCTION_DECLARATION:
|
||||||
|
case ICElement.C_TEMPLATE_FUNCTION:
|
||||||
|
case ICElement.C_TEMPLATE_FUNCTION_DECLARATION:
|
||||||
|
return ISourceTag.STYLE_Function;
|
||||||
|
case ICElement.C_FIELD :
|
||||||
|
return ISourceTag.STYLE_MemberVariable;
|
||||||
|
case ICElement.C_VARIABLE:
|
||||||
|
case ICElement.C_VARIABLE_DECLARATION:
|
||||||
|
return ISourceTag.STYLE_Variable;
|
||||||
|
case ICElement.C_CLASS:
|
||||||
|
case ICElement.C_TEMPLATE_CLASS:
|
||||||
|
case ICElement.C_TEMPLATE_CLASS_DECLARATION:
|
||||||
|
return ISourceTag.STYLE_Class;
|
||||||
|
case ICElement.C_STRUCT:
|
||||||
|
case ICElement.C_TEMPLATE_STRUCT:
|
||||||
|
case ICElement.C_TEMPLATE_STRUCT_DECLARATION:
|
||||||
|
return ISourceTag.STYLE_Struct;
|
||||||
|
case ICElement.C_UNION:
|
||||||
|
case ICElement.C_TEMPLATE_UNION:
|
||||||
|
case ICElement.C_TEMPLATE_UNION_DECLARATION:
|
||||||
|
return ISourceTag.STYLE_Union;
|
||||||
|
case ICElement.C_ENUMERATION:
|
||||||
|
return ISourceTag.STYLE_Enumeration;
|
||||||
|
case ICElement.C_ENUMERATOR:
|
||||||
|
return ISourceTag.STYLE_Enumerator;
|
||||||
|
case ICElement.C_NAMESPACE:
|
||||||
|
return ISourceTag.STYLE_None;
|
||||||
|
case ICElement.C_TYPEDEF:
|
||||||
|
return ISourceTag.STYLE_Typedef;
|
||||||
|
case ICElement.C_MACRO:
|
||||||
|
return ISourceTag.STYLE_Macro;
|
||||||
|
default:
|
||||||
|
return ISourceTag.STYLE_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ISourceTag getSourceTagAdapter() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
import org.eclipse.cdt.core.model.IParent;
|
||||||
|
import org.eclipse.cdt.core.model.ISourceReference;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
import org.eclipse.core.runtime.ListenerList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A source tag provider based on the C Model.
|
||||||
|
*/
|
||||||
|
public class CSourceTagProvider implements ISourceTagProvider {
|
||||||
|
|
||||||
|
private ListenerList fListenerList= new ListenerList(ListenerList.IDENTITY);
|
||||||
|
private ITranslationUnit fUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new source tag provider for the given translation unit.
|
||||||
|
*
|
||||||
|
* @param unit
|
||||||
|
*/
|
||||||
|
public CSourceTagProvider(ITranslationUnit unit) {
|
||||||
|
fUnit= unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSourceTagListener(ISourceTagListener listener) {
|
||||||
|
fListenerList.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getActiveCodePositions() {
|
||||||
|
// unsupported
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSnapshotTime() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getSourceTags(Collection<ISourceTag> target) {
|
||||||
|
try {
|
||||||
|
convertToSourceTags(fUnit.getChildren(), target);
|
||||||
|
} catch (CModelException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param element
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private ISourceTag convertToSourceTag(ICElement element) {
|
||||||
|
if (element instanceof ISourceReference) {
|
||||||
|
return new CSourceTag((ISourceReference)element, element.getElementType());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param children
|
||||||
|
* @param target
|
||||||
|
* @throws CModelException
|
||||||
|
*/
|
||||||
|
private void convertToSourceTags(ICElement[] children, Collection<ISourceTag> target) throws CModelException {
|
||||||
|
for (int i = 0; i < children.length; i++) {
|
||||||
|
ICElement element= children[i];
|
||||||
|
ISourceTag tag= convertToSourceTag(element);
|
||||||
|
if (tag != null) {
|
||||||
|
target.add(tag);
|
||||||
|
}
|
||||||
|
if (element instanceof IParent) {
|
||||||
|
convertToSourceTags(((IParent)element).getChildren(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see com.windriver.ide.editor.IWrsSourceTagProvider#removeSourceTagListener(com.windriver.ide.editor.IWrsSourceTagListener)
|
||||||
|
*/
|
||||||
|
public void removeSourceTagListener(ISourceTagListener listener) {
|
||||||
|
fListenerList.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
import org.eclipse.dd.dsf.debug.internal.ui.disassembly.DisassemblyMessages;
|
||||||
|
import org.eclipse.debug.ui.DebugUITools;
|
||||||
|
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||||
|
import org.eclipse.jface.text.source.Annotation;
|
||||||
|
import org.eclipse.jface.text.source.IAnnotationPresentation;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.widgets.Canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DisassemblyIPAnnotation
|
||||||
|
*/
|
||||||
|
public class DisassemblyIPAnnotation extends Annotation implements IAnnotationPresentation {
|
||||||
|
|
||||||
|
public static final String ID_TOP = "org.eclipse.dd.debug.currentIP"; //$NON-NLS-1$
|
||||||
|
public static final String ID_SECONDARY = "org.eclipse.dd.debug.secondaryIP"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private Image fImage;
|
||||||
|
private int fContext = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation denoting the current instruction pointer.
|
||||||
|
*/
|
||||||
|
public DisassemblyIPAnnotation(boolean isTopFrame, int context) {
|
||||||
|
super(
|
||||||
|
isTopFrame ? ID_TOP : ID_SECONDARY,
|
||||||
|
false,
|
||||||
|
isTopFrame ? DisassemblyMessages.DisassemblyIPAnnotation_primary
|
||||||
|
: DisassemblyMessages.DisassemblyIPAnnotation_secondary
|
||||||
|
);
|
||||||
|
setContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTopFrame() {
|
||||||
|
return ID_TOP.equals(getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContext(int context) {
|
||||||
|
if (context == fContext) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fContext = context;
|
||||||
|
// TLETODO [disassembly] context dependent IP icon
|
||||||
|
if (isTopFrame()) {
|
||||||
|
fImage = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER_TOP);
|
||||||
|
} else {
|
||||||
|
fImage = DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_INSTRUCTION_POINTER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IAnnotationPresentation#getLayer()
|
||||||
|
*/
|
||||||
|
public int getLayer() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.source.IAnnotationPresentation#paint(org.eclipse.swt.graphics.GC, org.eclipse.swt.widgets.Canvas, org.eclipse.swt.graphics.Rectangle)
|
||||||
|
*/
|
||||||
|
public void paint(GC gc, Canvas canvas, Rectangle bounds) {
|
||||||
|
Rectangle imageBounds = fImage.getBounds();
|
||||||
|
gc.drawImage(fImage, bounds.x + (bounds.width - imageBounds.width) / 2 , bounds.y + (bounds.height - imageBounds.height) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.TextPresentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A source presentation creator is used to create a {@link TextPresentation} of a document range.
|
||||||
|
*/
|
||||||
|
public interface ISourcePresentationCreator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose of this presentation creator.
|
||||||
|
*/
|
||||||
|
public abstract void dispose();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a text presentation for the given region and document.
|
||||||
|
* @param region
|
||||||
|
* @param document
|
||||||
|
* @return a text presentation
|
||||||
|
*/
|
||||||
|
public abstract TextPresentation getPresentation(IRegion region, IDocument document);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a range within a source file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface ISourceRange extends Comparable<ISourceRange> {
|
||||||
|
/**
|
||||||
|
* Returns 0-based absolute number for the inclusive start of the range.
|
||||||
|
*/
|
||||||
|
int getBeginOffset();
|
||||||
|
/**
|
||||||
|
* Returns 0-based absolute number for the inclusive end of the range.
|
||||||
|
*/
|
||||||
|
int getEndOffset();
|
||||||
|
/**
|
||||||
|
* Checks whether the range contains the given offset.
|
||||||
|
*/
|
||||||
|
boolean contains(int offset);
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the style of part of some text source.
|
||||||
|
*/
|
||||||
|
public interface ISourceTag {
|
||||||
|
// style codes
|
||||||
|
final static int STYLE_None = 0;
|
||||||
|
final static int STYLE_Class = 1;
|
||||||
|
final static int STYLE_Struct = 2;
|
||||||
|
final static int STYLE_Union = 3;
|
||||||
|
final static int STYLE_Interface = 4;
|
||||||
|
final static int STYLE_Package = 5;
|
||||||
|
final static int STYLE_Function = 6;
|
||||||
|
final static int STYLE_ProtectedFunction = 7;
|
||||||
|
final static int STYLE_Method = 8;
|
||||||
|
final static int STYLE_Exception = 9;
|
||||||
|
final static int STYLE_Variable = 10;
|
||||||
|
final static int STYLE_MemberVariable = 11;
|
||||||
|
final static int STYLE_Enumerator = 12;
|
||||||
|
final static int STYLE_Macro = 13;
|
||||||
|
final static int STYLE_Include = 14;
|
||||||
|
final static int STYLE_Undefined = 15;
|
||||||
|
final static int STYLE_Enumeration = 16;
|
||||||
|
final static int STYLE_Typedef = 17;
|
||||||
|
final static int STYLE_Type3 = 18;
|
||||||
|
final static int STYLE_Type4 = 19;
|
||||||
|
final static int STYLE_Type5 = 20;
|
||||||
|
final static int STYLE_File = 21;
|
||||||
|
final static int STYLE_Project = 22;
|
||||||
|
final static int STYLE_IncludeContainer = 23;
|
||||||
|
final static int STYLE_LocalVariable = 24;
|
||||||
|
final static int STYLE_Label = 25;
|
||||||
|
final static int STYLE_Record = 26;
|
||||||
|
final static int STYLE_TaggedType = 27;
|
||||||
|
final static int STYLE_Subtype = 28;
|
||||||
|
final static int STYLE_Warning = 29;
|
||||||
|
final static int STYLE_Count = 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the unqualified name of the source tag. Files return their base name.
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the fully qualified name of the source tag. Files return their path.
|
||||||
|
*/
|
||||||
|
String getQualifiedName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the range of the symbol within the file.
|
||||||
|
*/
|
||||||
|
ISourceRange getFullRange();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the range of the identifier of the symbol within the file.
|
||||||
|
*/
|
||||||
|
ISourceRange getRangeOfIdentifier();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the style code. Style codes are language dependent. You
|
||||||
|
* cannot derive any information from the style-code of a symbol. It
|
||||||
|
* may only be used to influence the visualization of a symbol. You
|
||||||
|
* may select color, font or icon depending on the style code.
|
||||||
|
* @return the style code of the symbol
|
||||||
|
*/
|
||||||
|
int getStyleCode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the timestamp of the file at the time the sourcetag was generated.
|
||||||
|
*/
|
||||||
|
long getSnapshotTime();
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ISourceTagListener
|
||||||
|
*/
|
||||||
|
public interface ISourceTagListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies this listener that the source tags have changed.
|
||||||
|
* @param provider the provider generating this event.
|
||||||
|
*/
|
||||||
|
void sourceTagsChanged(ISourceTagProvider provider);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A source tag provider provides access to source tags.
|
||||||
|
*/
|
||||||
|
public interface ISourceTagProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a source tag listener to receive source tag changed notifications.
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
public void addSourceTagListener(ISourceTagListener listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a source tag listener to stop receiving source tag changed notifications.
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
public void removeSourceTagListener(ISourceTagListener listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all symbols of the current file.
|
||||||
|
*/
|
||||||
|
public void getSourceTags(Collection<ISourceTag> target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the time stamp of the current symbol content.
|
||||||
|
* @return the modification time of the source file or 0L if no symbols available.
|
||||||
|
*/
|
||||||
|
public long getSnapshotTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the active code positions of the current file. Null if the
|
||||||
|
* information cannot be obtained.
|
||||||
|
*/
|
||||||
|
public int[] getActiveCodePositions();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
|
import org.eclipse.core.resources.IStorage;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory for source presentation creators.
|
||||||
|
*/
|
||||||
|
public final class SourcePresentationCreatorFactory {
|
||||||
|
|
||||||
|
public static ISourcePresentationCreator create(ILanguage language, IStorage storage, ITextViewer textViewer) {
|
||||||
|
return new CSourcePresentationCreator(language, storage, textViewer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,374 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.presentation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.SemanticHighlightings;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.IColorManager;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.IColorManagerExtension;
|
||||||
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.preference.PreferenceConverter;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.ITypedRegion;
|
||||||
|
import org.eclipse.jface.text.TextAttribute;
|
||||||
|
import org.eclipse.jface.text.TextPresentation;
|
||||||
|
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
|
||||||
|
import org.eclipse.jface.text.rules.IToken;
|
||||||
|
import org.eclipse.jface.text.rules.ITokenScanner;
|
||||||
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.StyleRange;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SourceTagDamagerRepairer extends DefaultDamagerRepairer implements ISourceTagListener {
|
||||||
|
|
||||||
|
private ISourceTagProvider fSourceTagProvider;
|
||||||
|
private Map<String, ITokenScanner> fScannerMap= new HashMap<String, ITokenScanner>();
|
||||||
|
private List<ISourceTag> fSourceTags = new ArrayList<ISourceTag>();
|
||||||
|
private IColorManager fColorManager;
|
||||||
|
private IPreferenceStore fPreferenceStore;
|
||||||
|
private Map<String, TextAttribute> fAttributeMap= new HashMap<String, TextAttribute>();
|
||||||
|
|
||||||
|
private final static String[] KEYS= {
|
||||||
|
SemanticHighlightings.CLASS,
|
||||||
|
SemanticHighlightings.METHOD_DECLARATION,
|
||||||
|
SemanticHighlightings.FUNCTION_DECLARATION,
|
||||||
|
SemanticHighlightings.FIELD,
|
||||||
|
SemanticHighlightings.GLOBAL_VARIABLE,
|
||||||
|
SemanticHighlightings.TYPEDEF,
|
||||||
|
SemanticHighlightings.MACRO_DEFINITION,
|
||||||
|
SemanticHighlightings.ENUMERATOR,
|
||||||
|
SemanticHighlightings.ENUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param scanner
|
||||||
|
* @param sourceTagProvider
|
||||||
|
*/
|
||||||
|
public SourceTagDamagerRepairer(ITokenScanner scanner, ISourceTagProvider sourceTagProvider, IColorManager colorManager, IPreferenceStore store) {
|
||||||
|
super(scanner);
|
||||||
|
fSourceTagProvider= sourceTagProvider;
|
||||||
|
fColorManager= colorManager;
|
||||||
|
fPreferenceStore= store;
|
||||||
|
fDefaultTextAttribute = new TextAttribute(null, null, SWT.NORMAL);
|
||||||
|
if (fSourceTagProvider != null) {
|
||||||
|
fSourceTagProvider.addSourceTagListener(this);
|
||||||
|
sourceTagsChanged(fSourceTagProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initTextAttributes() {
|
||||||
|
boolean shEnabled= fPreferenceStore.getBoolean(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ENABLED);
|
||||||
|
for (int i= 0; i < KEYS.length; i++) {
|
||||||
|
String enabledKey= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + KEYS[i] + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ENABLED_SUFFIX;
|
||||||
|
String colorKey= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + KEYS[i] + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_COLOR_SUFFIX;
|
||||||
|
boolean enabled= shEnabled && fPreferenceStore.getBoolean(enabledKey);
|
||||||
|
if (enabled) {
|
||||||
|
String boldKey= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + KEYS[i] + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_BOLD_SUFFIX;
|
||||||
|
String italicKey= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + KEYS[i] + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ITALIC_SUFFIX;
|
||||||
|
String strikethroughKey= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + KEYS[i] + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_STRIKETHROUGH_SUFFIX;
|
||||||
|
String underlineKey= PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX + KEYS[i] + PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_UNDERLINE_SUFFIX;
|
||||||
|
addTextAttribute(KEYS[i], colorKey, boldKey, italicKey, strikethroughKey, underlineKey);
|
||||||
|
} else {
|
||||||
|
removeTextAttribute(KEYS[i], colorKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeTextAttribute(String key, String colorKey) {
|
||||||
|
if (fColorManager != null && colorKey != null) {
|
||||||
|
Color color= fColorManager.getColor(colorKey);
|
||||||
|
if (fColorManager instanceof IColorManagerExtension && color != null) {
|
||||||
|
IColorManagerExtension ext= (IColorManagerExtension) fColorManager;
|
||||||
|
ext.unbindColor(colorKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fAttributeMap.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addTextAttribute(String key, String colorKey, String boldKey, String italicKey, String strikethroughKey, String underlineKey) {
|
||||||
|
if (fColorManager != null && colorKey != null && fColorManager instanceof IColorManagerExtension) {
|
||||||
|
RGB rgb= PreferenceConverter.getColor(fPreferenceStore, colorKey);
|
||||||
|
Color color= fColorManager.getColor(colorKey);
|
||||||
|
if (color == null || !rgb.equals(color.getRGB())) {
|
||||||
|
IColorManagerExtension ext= (IColorManagerExtension) fColorManager;
|
||||||
|
ext.unbindColor(colorKey);
|
||||||
|
ext.bindColor(colorKey, rgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAttribute textAttribute= createTextAttribute(colorKey, boldKey, italicKey, strikethroughKey, underlineKey);
|
||||||
|
fAttributeMap.put(key, textAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TextAttribute createTextAttribute(String colorKey, String boldKey, String italicKey, String strikethroughKey, String underlineKey) {
|
||||||
|
Color color= null;
|
||||||
|
if (colorKey != null)
|
||||||
|
color= fColorManager.getColor(colorKey);
|
||||||
|
|
||||||
|
int style= fPreferenceStore.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL;
|
||||||
|
if (fPreferenceStore.getBoolean(italicKey))
|
||||||
|
style |= SWT.ITALIC;
|
||||||
|
|
||||||
|
if (fPreferenceStore.getBoolean(strikethroughKey))
|
||||||
|
style |= TextAttribute.STRIKETHROUGH;
|
||||||
|
|
||||||
|
if (fPreferenceStore.getBoolean(underlineKey))
|
||||||
|
style |= TextAttribute.UNDERLINE;
|
||||||
|
|
||||||
|
return new TextAttribute(color, null, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set scanner for contentType.
|
||||||
|
* @param contentType
|
||||||
|
* @param scanner
|
||||||
|
*/
|
||||||
|
public void setScanner(String contentType, ITokenScanner scanner) {
|
||||||
|
fScannerMap.put(contentType, scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.presentation.IPresentationRepairer#createPresentation(org.eclipse.jface.text.TextPresentation, org.eclipse.jface.text.ITypedRegion)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void createPresentation(TextPresentation presentation, ITypedRegion region) {
|
||||||
|
if (fAttributeMap.isEmpty()) {
|
||||||
|
initTextAttributes();
|
||||||
|
}
|
||||||
|
String contentType= region.getType();
|
||||||
|
fScanner = fScannerMap.get(contentType);
|
||||||
|
if (!contentType.equals(IDocument.DEFAULT_CONTENT_TYPE) && !contentType.equals(ICPartitions.C_PREPROCESSOR)) {
|
||||||
|
super.createPresentation(presentation, region);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fScanner == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastStart = region.getOffset();
|
||||||
|
int regionEnd = lastStart + region.getLength();
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
int sourceTagCount = fSourceTags.size();
|
||||||
|
int sourceTagIdx = 0;
|
||||||
|
|
||||||
|
ISourceTag sourceTag = null;
|
||||||
|
ISourceRange range = null;
|
||||||
|
int sourceTagStart = 0;
|
||||||
|
int sourceTagEnd = 0;
|
||||||
|
|
||||||
|
if (sourceTagCount > 0 && fDocument.getLength() > 0) {
|
||||||
|
int left = 0;
|
||||||
|
int mid = (int) (sourceTagCount * ((float)lastStart / fDocument.getLength()));
|
||||||
|
int right = sourceTagCount - 1;
|
||||||
|
while (true) {
|
||||||
|
sourceTag = fSourceTags.get(mid);
|
||||||
|
range = sourceTag.getRangeOfIdentifier();
|
||||||
|
sourceTagStart = range.getBeginOffset();
|
||||||
|
sourceTagEnd = range.getEndOffset() + 1;
|
||||||
|
if (mid == left) {
|
||||||
|
break;
|
||||||
|
} else if (mid < right && sourceTagEnd < lastStart) {
|
||||||
|
left = mid;
|
||||||
|
mid = (mid + right) / 2;
|
||||||
|
} else if (sourceTagStart >= regionEnd) {
|
||||||
|
right = mid;
|
||||||
|
mid = (left + mid) / 2;
|
||||||
|
} else if (sourceTagStart > lastStart) {
|
||||||
|
--mid;
|
||||||
|
right = mid;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// set to next index
|
||||||
|
sourceTagIdx = mid + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextAttribute lastAttribute = fDefaultTextAttribute;
|
||||||
|
|
||||||
|
fScanner.setRange(fDocument, lastStart, region.getLength());
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
IToken token = fScanner.nextToken();
|
||||||
|
|
||||||
|
// if the attribute is the same as the previous, extend range and continue
|
||||||
|
TextAttribute attribute = getTokenTextAttribute(token);
|
||||||
|
int tokenLength = fScanner.getTokenLength();
|
||||||
|
if (tokenLength > 0
|
||||||
|
&& (lastAttribute == attribute || lastAttribute != null && lastAttribute.equals(attribute))) {
|
||||||
|
length += tokenLength;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// attribute has changed, now add the style range
|
||||||
|
while (sourceTag != null && length > 0) {
|
||||||
|
if (sourceTagStart >= regionEnd) {
|
||||||
|
// we are past the region boundary -> no more source tags
|
||||||
|
sourceTag = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sourceTagStart >= lastStart) {
|
||||||
|
if (sourceTagStart < lastStart + length) {
|
||||||
|
String sourceTagStyle = getSourceTagStyle(sourceTag.getStyleCode());
|
||||||
|
if (sourceTagStyle != null) {
|
||||||
|
if (sourceTagStart > lastStart) {
|
||||||
|
addRange(presentation, lastStart, Math.min(sourceTagStart - lastStart, length), lastAttribute);
|
||||||
|
}
|
||||||
|
int rangeEnd = Math.min(sourceTagEnd, regionEnd);
|
||||||
|
addRange(
|
||||||
|
presentation,
|
||||||
|
sourceTagStart,
|
||||||
|
rangeEnd - sourceTagStart,
|
||||||
|
getSourceTagTextAttribute(sourceTagStyle));
|
||||||
|
length = lastStart + length - rangeEnd;
|
||||||
|
lastStart = rangeEnd;
|
||||||
|
} else {
|
||||||
|
fSourceTags.remove(--sourceTagIdx);
|
||||||
|
--sourceTagCount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceTag = sourceTagIdx < sourceTagCount ? (ISourceTag)fSourceTags.get(sourceTagIdx++) : null;
|
||||||
|
if (sourceTag != null) {
|
||||||
|
range = sourceTag.getRangeOfIdentifier();
|
||||||
|
sourceTagStart = range.getBeginOffset();
|
||||||
|
sourceTagEnd = range.getEndOffset() + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (token.isEOF()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 0) {
|
||||||
|
addRange(presentation, lastStart, length, lastAttribute);
|
||||||
|
lastAttribute = attribute;
|
||||||
|
lastStart = fScanner.getTokenOffset();
|
||||||
|
length = tokenLength;
|
||||||
|
} else {
|
||||||
|
lastAttribute = attribute;
|
||||||
|
length = fScanner.getTokenOffset() - lastStart + tokenLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
addRange(presentation, lastStart, length, lastAttribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sourceTagStyle
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private TextAttribute getSourceTagTextAttribute(String sourceTagStyle) {
|
||||||
|
return fAttributeMap.get(sourceTagStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the style id for a source tag style code.
|
||||||
|
* @param styleCode
|
||||||
|
* @return the associated style id or <code>null</code>
|
||||||
|
*/
|
||||||
|
private String getSourceTagStyle(int styleCode) {
|
||||||
|
switch (styleCode) {
|
||||||
|
case ISourceTag.STYLE_None :
|
||||||
|
return null;
|
||||||
|
case ISourceTag.STYLE_Class :
|
||||||
|
return SemanticHighlightings.CLASS;
|
||||||
|
case ISourceTag.STYLE_Struct :
|
||||||
|
return SemanticHighlightings.CLASS;
|
||||||
|
case ISourceTag.STYLE_Union :
|
||||||
|
return SemanticHighlightings.CLASS;
|
||||||
|
case ISourceTag.STYLE_Function :
|
||||||
|
return SemanticHighlightings.FUNCTION_DECLARATION;
|
||||||
|
case ISourceTag.STYLE_Method :
|
||||||
|
return SemanticHighlightings.METHOD_DECLARATION;
|
||||||
|
case ISourceTag.STYLE_Variable :
|
||||||
|
return SemanticHighlightings.GLOBAL_VARIABLE;
|
||||||
|
case ISourceTag.STYLE_MemberVariable :
|
||||||
|
return SemanticHighlightings.FIELD;
|
||||||
|
case ISourceTag.STYLE_Enumerator :
|
||||||
|
return SemanticHighlightings.ENUMERATOR;
|
||||||
|
case ISourceTag.STYLE_Macro :
|
||||||
|
return SemanticHighlightings.MACRO_DEFINITION;
|
||||||
|
case ISourceTag.STYLE_Include :
|
||||||
|
// include is colored by the scanner
|
||||||
|
return null;
|
||||||
|
case ISourceTag.STYLE_Enumeration :
|
||||||
|
return SemanticHighlightings.ENUM;
|
||||||
|
case ISourceTag.STYLE_Undefined :
|
||||||
|
return null;
|
||||||
|
case ISourceTag.STYLE_Typedef :
|
||||||
|
return SemanticHighlightings.TYPEDEF;
|
||||||
|
default :
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sourceTagsChanged(ISourceTagProvider sourceTagProvider) {
|
||||||
|
fSourceTags.clear();
|
||||||
|
if (sourceTagProvider != null) {
|
||||||
|
sourceTagProvider.getSourceTags(fSourceTags);
|
||||||
|
Collections.sort(fSourceTags, new Comparator() {
|
||||||
|
public int compare(Object o1, Object o2) {
|
||||||
|
ISourceRange sr1 = ((ISourceTag)o1).getRangeOfIdentifier();
|
||||||
|
ISourceRange sr2 = ((ISourceTag)o2).getRangeOfIdentifier();
|
||||||
|
return (sr1.getBeginOffset() - sr2.getBeginOffset());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.rules.DefaultDamagerRepairer#addRange(org.eclipse.jface.text.TextPresentation, int, int, org.eclipse.jface.text.TextAttribute)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void addRange(TextPresentation presentation, int offset, int length, TextAttribute attr) {
|
||||||
|
if (length > 0 && attr != null) {
|
||||||
|
presentation.addStyleRange(
|
||||||
|
new StyleRange(offset, length, attr.getForeground(), attr.getBackground(), attr.getStyle()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether the given preference change affects us.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* @return <code>true</code> if the given event affects the behavior.
|
||||||
|
*/
|
||||||
|
public boolean affectsBahvior(PropertyChangeEvent event) {
|
||||||
|
return event.getProperty().startsWith(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt to changes in the preferences.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
public void handlePropertyChangeEvent(PropertyChangeEvent event) {
|
||||||
|
initTextAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.text;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IFileRider
|
||||||
|
*/
|
||||||
|
public interface IFileRider {
|
||||||
|
|
||||||
|
/** Set rider to position
|
||||||
|
* @param pos is normalized to be in range [0, f.length()]
|
||||||
|
*/
|
||||||
|
public abstract void seek(int pos) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a char.
|
||||||
|
* @param c
|
||||||
|
*/
|
||||||
|
public abstract void writeChar(char c) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a character array.
|
||||||
|
* @param buf
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract void writeChars(char[] buf) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write n characters of an array of characters.
|
||||||
|
* @param buf
|
||||||
|
* @param n
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract void writeChars(char[] buf, int n) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write n characters of an array of characters starting at an offset.
|
||||||
|
* @param buf
|
||||||
|
* @param off
|
||||||
|
* @param n
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract void writeChars(char[] buf, int off, int n) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write n characters of a String starting at an offset.
|
||||||
|
* @param buf
|
||||||
|
* @param off
|
||||||
|
* @param n
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract void writeChars(String buf, int off, int n) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read next character.
|
||||||
|
* @return next char in buffer.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract char readChar() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read as much characters as possible into a char array.
|
||||||
|
* @param buf
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract void readChars(char[] buf) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read n characters into character array.
|
||||||
|
* @param buf
|
||||||
|
* @param n
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract void readChars(char[] buf, int n) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read n characters into char array.
|
||||||
|
* @param buf
|
||||||
|
* @param off
|
||||||
|
* @param n
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract void readChars(char[] buf, int off, int n) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read n characters into StringBuffer.
|
||||||
|
* @param buf
|
||||||
|
* @param from
|
||||||
|
* @param n
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public abstract void readChars(StringBuffer buf, int n) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return length of file
|
||||||
|
*/
|
||||||
|
public abstract int length();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return length limit of file
|
||||||
|
*/
|
||||||
|
public abstract int limit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether this rider is readonly or not
|
||||||
|
*/
|
||||||
|
public abstract boolean isReadonly();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.text;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.AbstractDocument;
|
||||||
|
import org.eclipse.jface.text.DefaultLineTracker;
|
||||||
|
import org.eclipse.jface.text.ITextStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standard Document implementation with REDTextStore (splice texts)
|
||||||
|
* as text storage.
|
||||||
|
*/
|
||||||
|
public class REDDocument extends AbstractDocument {
|
||||||
|
|
||||||
|
public REDDocument() {
|
||||||
|
setTextStore(new REDTextStore());
|
||||||
|
setLineTracker(new DefaultLineTracker());
|
||||||
|
completeInitialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() {
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free text store (delete scratchfiles).
|
||||||
|
*/
|
||||||
|
public void dispose() {
|
||||||
|
ITextStore store = getStore();
|
||||||
|
if (store instanceof REDTextStore) {
|
||||||
|
((REDTextStore)store).dispose();
|
||||||
|
setTextStore(new StringTextStore());
|
||||||
|
getTracker().set(""); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,480 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.text;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File with buffered character access.
|
||||||
|
*/
|
||||||
|
public final class REDFile {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File cache object.
|
||||||
|
* TLETODO Use CharBuffer?
|
||||||
|
* @invariant fSize <= fcBufSize
|
||||||
|
* @invariant fSize >= 0
|
||||||
|
* @invariant fOffset <= fFile.length()
|
||||||
|
*/
|
||||||
|
private final static class Buffer {
|
||||||
|
|
||||||
|
final static int fcBufSize = 2048;
|
||||||
|
|
||||||
|
boolean fDirty;
|
||||||
|
int fOffset = -1;
|
||||||
|
int fPos;
|
||||||
|
int fSize;
|
||||||
|
char fData[] = new char[fcBufSize];
|
||||||
|
|
||||||
|
Buffer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the file offset is contained in this buffer.
|
||||||
|
* @param pos
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean containsOffset(int pos) {
|
||||||
|
return fOffset < pos || fOffset + fSize <= pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return number of available characters.
|
||||||
|
*/
|
||||||
|
public int avail() {
|
||||||
|
return fSize - fPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return number of free space.
|
||||||
|
*/
|
||||||
|
public int free() {
|
||||||
|
return fcBufSize - fPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final static private boolean DEBUG = false;
|
||||||
|
|
||||||
|
/** The maximum number of buffers for this file. */
|
||||||
|
final static public int fcNrBufs = 4;
|
||||||
|
|
||||||
|
private RandomAccessFile fFile;
|
||||||
|
private int fPosition;
|
||||||
|
private int fLength;
|
||||||
|
private Buffer fBuffer[] = new Buffer[fcNrBufs];
|
||||||
|
private byte[] fByteBuffer = new byte[2 * Buffer.fcBufSize];
|
||||||
|
private int fSwapper;
|
||||||
|
private String fName;
|
||||||
|
private boolean fReadonly;
|
||||||
|
private boolean fDeleteOnDispose;
|
||||||
|
|
||||||
|
private REDFile(File file, boolean readonly) {
|
||||||
|
assert !readonly || file != null;
|
||||||
|
fReadonly = readonly;
|
||||||
|
fDeleteOnDispose = file == null;
|
||||||
|
if (file != null) {
|
||||||
|
try {
|
||||||
|
setFile(file);
|
||||||
|
fLength = (int)(fFile.length() / 2);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new Error(ioe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public REDFile() {
|
||||||
|
this((File)null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public REDFile(String name, boolean readonly) {
|
||||||
|
this(new File(name), readonly);
|
||||||
|
}
|
||||||
|
|
||||||
|
public REDFile(String name) {
|
||||||
|
this(name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFile(File file) throws IOException {
|
||||||
|
assert file != null;
|
||||||
|
if (fReadonly) {
|
||||||
|
fFile = new RandomAccessFile(file, "r"); //$NON-NLS-1$
|
||||||
|
fName = file.toString();
|
||||||
|
} else if (file != null) {
|
||||||
|
fFile = new RandomAccessFile(file, "rw"); //$NON-NLS-1$
|
||||||
|
fName = file.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free resources.
|
||||||
|
*/
|
||||||
|
public void dispose() {
|
||||||
|
if (fFile != null) {
|
||||||
|
try {
|
||||||
|
close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
fFile = null;
|
||||||
|
if (fDeleteOnDispose) {
|
||||||
|
new File(fName).delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
flush();
|
||||||
|
if (fFile != null) {
|
||||||
|
fFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush buffers.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void flush() throws IOException {
|
||||||
|
for (int i = 0; i < fcNrBufs; i++) {
|
||||||
|
if (fBuffer[i] != null) {
|
||||||
|
if (fBuffer[i].fDirty) {
|
||||||
|
flush(fBuffer[i]);
|
||||||
|
}
|
||||||
|
fBuffer[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush a dirty buffer.
|
||||||
|
* @param buffer
|
||||||
|
*/
|
||||||
|
private void flush(Buffer buffer) throws IOException {
|
||||||
|
assert buffer.fDirty;
|
||||||
|
write(buffer.fOffset, buffer.fData, 0, buffer.fSize);
|
||||||
|
buffer.fDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this file is readonly.
|
||||||
|
*/
|
||||||
|
public boolean isReadonly() {
|
||||||
|
return fReadonly;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the length in char units.
|
||||||
|
*/
|
||||||
|
public int length() {
|
||||||
|
if (fLength < 0) {
|
||||||
|
if (fFile == null) {
|
||||||
|
fLength = 0;
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
fLength = (int)(fFile.length() / 2);
|
||||||
|
} catch (IOException e) {
|
||||||
|
fLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** erase file content
|
||||||
|
* @return true, if successful; false otherwise
|
||||||
|
* @post return == true implies length() == 0
|
||||||
|
*/
|
||||||
|
public boolean purge() throws IOException {
|
||||||
|
if (isReadonly()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fFile.setLength(0);
|
||||||
|
for (int i = 0; i < fcNrBufs; i++) {
|
||||||
|
if (fBuffer[i] != null) {
|
||||||
|
fBuffer[i].fOffset = -1;
|
||||||
|
fBuffer[i].fDirty = false;
|
||||||
|
if (i > 0) {
|
||||||
|
fBuffer[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fLength = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() {
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private File createTmpFile() {
|
||||||
|
try {
|
||||||
|
File file = File.createTempFile("scratch", ".tmp"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
file.deleteOnExit();
|
||||||
|
return file;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy file - Convenience method.
|
||||||
|
* @pre src != null
|
||||||
|
* @pre dest != null
|
||||||
|
*/
|
||||||
|
public static void copyFile(REDFile src, REDFile dest) throws IOException {
|
||||||
|
dest.purge();
|
||||||
|
byte buf[] = new byte[4096];
|
||||||
|
int n = src.fFile.read(buf);
|
||||||
|
while (n >= 0) {
|
||||||
|
if (n > 0) {
|
||||||
|
dest.fFile.write(buf, 0, n);
|
||||||
|
}
|
||||||
|
n = src.fFile.read(buf);
|
||||||
|
}
|
||||||
|
dest.fLength = src.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param offset
|
||||||
|
*/
|
||||||
|
public void seek(int offset) throws IOException {
|
||||||
|
if (offset < 0) {
|
||||||
|
throw new IOException("Negative seek position"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
fPosition = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write char array as 16-bit Unicode at absolute position.
|
||||||
|
* @param position File position
|
||||||
|
* @param data
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void write(int position, char[] data, int offset, int length) throws IOException {
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println("REDFile.write " + length + " at " + position); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
if (fFile == null) {
|
||||||
|
setFile(createTmpFile());
|
||||||
|
}
|
||||||
|
fFile.seek(position * 2);
|
||||||
|
int blen = 0;
|
||||||
|
for (int clen = 0; clen < length; ++clen) {
|
||||||
|
char c = data[offset + clen];
|
||||||
|
fByteBuffer[blen++] = (byte) ((c >>> 8) & 0xff);
|
||||||
|
fByteBuffer[blen++] = (byte) ((c >>> 0) & 0xff);
|
||||||
|
if (blen == fByteBuffer.length) {
|
||||||
|
fFile.write(fByteBuffer, 0, blen);
|
||||||
|
blen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blen > 0) {
|
||||||
|
fFile.write(fByteBuffer, 0, blen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write char array as UTF-16 bytes (2 bytes each).
|
||||||
|
* @param data
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void writeBuffered(char[] data, int offset, int length) throws IOException {
|
||||||
|
if (isReadonly()) {
|
||||||
|
throw new IOException("Cannot write to readonly file"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
Buffer buffer = null;
|
||||||
|
int clen = 0;
|
||||||
|
while (clen < length) {
|
||||||
|
buffer = getBufferForOffset(fPosition, true);
|
||||||
|
int count = Math.min(length - clen, buffer.free());
|
||||||
|
if (count == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
System.arraycopy(data, offset, buffer.fData, buffer.fPos, count);
|
||||||
|
buffer.fPos += count;
|
||||||
|
if (buffer.fPos > buffer.fSize) {
|
||||||
|
buffer.fSize = buffer.fPos;
|
||||||
|
}
|
||||||
|
buffer.fDirty = true;
|
||||||
|
offset += count;
|
||||||
|
clen += count;
|
||||||
|
fPosition += count;
|
||||||
|
}
|
||||||
|
if (fPosition > fLength) {
|
||||||
|
fLength = fPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write String as UTF-16 bytes (2 bytes each).
|
||||||
|
* @param data
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void writeBuffered(String data, int offset, int length) throws IOException {
|
||||||
|
if (isReadonly()) {
|
||||||
|
throw new IOException("Cannot write to readonly file"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
Buffer buffer = null;
|
||||||
|
int clen = 0;
|
||||||
|
while (clen < length) {
|
||||||
|
buffer = getBufferForOffset(fPosition, true);
|
||||||
|
int count = Math.min(length - clen, buffer.free());
|
||||||
|
if (count == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data.getChars(offset, offset + count, buffer.fData, buffer.fPos);
|
||||||
|
buffer.fPos += count;
|
||||||
|
if (buffer.fPos > buffer.fSize) {
|
||||||
|
buffer.fSize = buffer.fPos;
|
||||||
|
}
|
||||||
|
buffer.fDirty = true;
|
||||||
|
offset += count;
|
||||||
|
clen += count;
|
||||||
|
fPosition += count;
|
||||||
|
}
|
||||||
|
if (fPosition > fLength) {
|
||||||
|
fLength = fPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the content of a buffer.
|
||||||
|
* @param buffer
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void update(Buffer buffer) throws IOException {
|
||||||
|
assert !buffer.fDirty;
|
||||||
|
buffer.fSize = read(buffer.fOffset, buffer.fData, 0, buffer.fData.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an array of characters at absolute position.
|
||||||
|
* @param position File position
|
||||||
|
* @param data
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @return number of characters read.
|
||||||
|
*/
|
||||||
|
private int read(int position, char[] data, int offset, int length) throws IOException {
|
||||||
|
fFile.seek(position * 2);
|
||||||
|
int blen = 0;
|
||||||
|
int bsize = length * 2;
|
||||||
|
while (blen < bsize) {
|
||||||
|
int count = fFile.read(fByteBuffer, 0, Math.min(fByteBuffer.length, bsize - blen));
|
||||||
|
if (count < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count; i += 2) {
|
||||||
|
int hiByte = fByteBuffer[i] & 0xff;
|
||||||
|
int loByte = fByteBuffer[i + 1] & 0xff;
|
||||||
|
data[offset++] = (char) ((hiByte << 8) | (loByte << 0));
|
||||||
|
}
|
||||||
|
blen += count;
|
||||||
|
}
|
||||||
|
if (DEBUG)
|
||||||
|
System.out.println("REDFile.read " + length + " at " + position + " = " + blen / 2); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
// convert to character length
|
||||||
|
return blen / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an array of characters.
|
||||||
|
* @param data
|
||||||
|
* @param offset
|
||||||
|
* @param length
|
||||||
|
* @return number of characters read.
|
||||||
|
*/
|
||||||
|
public int readBuffered(char[] data, int offset, int length) throws IOException {
|
||||||
|
Buffer buffer;
|
||||||
|
int clen = 0;
|
||||||
|
while (clen < length) {
|
||||||
|
buffer = getBufferForOffset(fPosition, false);
|
||||||
|
int count = Math.min(length - clen, buffer.avail());
|
||||||
|
if (count <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
System.arraycopy(buffer.fData, buffer.fPos, data, offset, count);
|
||||||
|
buffer.fPos += count;
|
||||||
|
offset += count;
|
||||||
|
clen += count;
|
||||||
|
fPosition += count;
|
||||||
|
}
|
||||||
|
return clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read characters into StringBuffer.
|
||||||
|
* @param strBuf
|
||||||
|
* @param length
|
||||||
|
* @return number of characters read.
|
||||||
|
*/
|
||||||
|
public int readBuffered(StringBuffer strBuf, int length) throws IOException {
|
||||||
|
Buffer buffer;
|
||||||
|
int clen = 0;
|
||||||
|
while (clen < length) {
|
||||||
|
buffer = getBufferForOffset(fPosition, false);
|
||||||
|
int count = Math.min(length - clen, buffer.avail());
|
||||||
|
if (count <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strBuf.append(buffer.fData, buffer.fPos, count);
|
||||||
|
buffer.fPos += count;
|
||||||
|
clen += count;
|
||||||
|
fPosition += count;
|
||||||
|
}
|
||||||
|
return clen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a REDFileBuffer for an offset.
|
||||||
|
* @param pos
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Buffer getBufferForOffset(int offset, boolean write) throws IOException {
|
||||||
|
Buffer buffer = null;
|
||||||
|
int bufferOffset = (offset / Buffer.fcBufSize) * Buffer.fcBufSize;
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < fcNrBufs && fBuffer[i] != null; ++i) {
|
||||||
|
if (bufferOffset == fBuffer[i].fOffset) {
|
||||||
|
buffer = fBuffer[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (buffer == null) {
|
||||||
|
if (i < REDFile.fcNrBufs) {
|
||||||
|
buffer = new Buffer();
|
||||||
|
fBuffer[i] = buffer;
|
||||||
|
} else {
|
||||||
|
fSwapper = (fSwapper + 1) % REDFile.fcNrBufs;
|
||||||
|
buffer = fBuffer[fSwapper];
|
||||||
|
if (buffer.fDirty) {
|
||||||
|
flush(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.fOffset = bufferOffset;
|
||||||
|
buffer.fSize = 0;
|
||||||
|
}
|
||||||
|
buffer.fPos = offset - buffer.fOffset;
|
||||||
|
if (write && buffer.fSize < buffer.fPos || !write && buffer.avail() <= 0) {
|
||||||
|
if (buffer.fDirty) {
|
||||||
|
flush(buffer);
|
||||||
|
}
|
||||||
|
update(buffer);
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.text;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor to <code>REDFile</code>s.
|
||||||
|
*/
|
||||||
|
public final class REDFileRider implements IFileRider {
|
||||||
|
|
||||||
|
private REDFile fFile;
|
||||||
|
private int fLimit = Integer.MAX_VALUE;
|
||||||
|
private int fResult;
|
||||||
|
private boolean fEof;
|
||||||
|
private char[] fOneCharBuf = new char[1];
|
||||||
|
|
||||||
|
/** @pre f != null */
|
||||||
|
public REDFileRider(REDFile f) throws IOException {
|
||||||
|
set(f, 0);
|
||||||
|
}
|
||||||
|
public REDFileRider(REDFile f, int limit) throws IOException {
|
||||||
|
fLimit = limit;
|
||||||
|
set(f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see com.windriver.ide.editor.model.IFileRider#seek(int)
|
||||||
|
*/
|
||||||
|
public void seek(int pos) throws IOException {
|
||||||
|
fFile.seek(pos);
|
||||||
|
fEof = false;
|
||||||
|
fResult = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set rider to file and position
|
||||||
|
*
|
||||||
|
* @param f the file the rider should operate on
|
||||||
|
* @param pos is normalized to be in range [0, f.length()]
|
||||||
|
* @pre f != null
|
||||||
|
* @pre pos >= 0 && pos <= f.length()
|
||||||
|
* @post fBuffer != null
|
||||||
|
*/
|
||||||
|
private void set(REDFile f, int pos) throws IOException {
|
||||||
|
|
||||||
|
assert f != null;
|
||||||
|
assert pos >= 0 && pos <= f.length();
|
||||||
|
|
||||||
|
fFile = f;
|
||||||
|
fFile.seek(pos);
|
||||||
|
fEof = false;
|
||||||
|
fResult = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get end of file status
|
||||||
|
* @return true, if rider has tried to read beyond the end of file
|
||||||
|
*/
|
||||||
|
public boolean eof() {
|
||||||
|
return fEof;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get result of last operation
|
||||||
|
* will be 0 after successful write operation
|
||||||
|
* will contain nr. of characters requested but unavailable read after read operation
|
||||||
|
*/
|
||||||
|
public int getResult() {
|
||||||
|
return fResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the REDFile the rider operates on.
|
||||||
|
* @post return != null
|
||||||
|
*/
|
||||||
|
public REDFile getFile() {
|
||||||
|
return fFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChar(char c) throws IOException {
|
||||||
|
fOneCharBuf[0] = c;
|
||||||
|
writeChars(fOneCharBuf, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChars(char[] buf) throws IOException {
|
||||||
|
writeChars(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChars(char[] buf, int n) throws IOException {
|
||||||
|
writeChars(buf, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChars(char[] buf, int off, int n) throws IOException {
|
||||||
|
fFile.writeBuffered(buf, off, n);
|
||||||
|
fResult = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChars(String buf, int off, int n) throws IOException {
|
||||||
|
fFile.writeBuffered(buf, off, n);
|
||||||
|
fResult = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char readChar() throws IOException {
|
||||||
|
readChars(fOneCharBuf, 0, 1);
|
||||||
|
return fEof ? '\0' : fOneCharBuf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readChars(char[] buf) throws IOException {
|
||||||
|
readChars(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readChars(char[] buf, int n) throws IOException {
|
||||||
|
readChars(buf, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readChars(char[] buf, int off, int n) throws IOException {
|
||||||
|
int count = fFile.readBuffered(buf, off, n);
|
||||||
|
fResult = n-count;
|
||||||
|
fEof = fResult > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readChars(StringBuffer buf, int n) throws IOException {
|
||||||
|
int count = fFile.readBuffered(buf, n);
|
||||||
|
fResult = n-count;
|
||||||
|
fEof = fResult > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int length() {
|
||||||
|
return fFile.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int limit() {
|
||||||
|
return fLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReadonly() {
|
||||||
|
return fFile.isReadonly();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.text;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A piece of text on a scratch file.
|
||||||
|
*/
|
||||||
|
public class REDRun implements CharSequence {
|
||||||
|
|
||||||
|
IFileRider fRider;
|
||||||
|
int fOffset;
|
||||||
|
int fLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre rider != null
|
||||||
|
* @pre style != null
|
||||||
|
* @pre length > 0
|
||||||
|
*/
|
||||||
|
public REDRun(IFileRider rider, int offset, int length) {
|
||||||
|
fRider = rider;
|
||||||
|
fOffset = offset;
|
||||||
|
fLength = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre rider != null
|
||||||
|
* @pre style != null
|
||||||
|
* @pre str.length() > 0
|
||||||
|
*/
|
||||||
|
public REDRun(IFileRider rider, String str) throws IOException {
|
||||||
|
fRider = rider;
|
||||||
|
fLength = str.length();
|
||||||
|
fOffset = fRider.length();
|
||||||
|
fRider.seek(fOffset);
|
||||||
|
fRider.writeChars(str, 0, fLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param rider
|
||||||
|
* @param buf
|
||||||
|
* @param off
|
||||||
|
* @param n
|
||||||
|
*/
|
||||||
|
public REDRun(IFileRider rider, char[] buf, int off, int n) throws IOException {
|
||||||
|
fRider = rider;
|
||||||
|
fLength = n;
|
||||||
|
fOffset = fRider.length();
|
||||||
|
fRider.seek(fOffset);
|
||||||
|
fRider.writeChars(buf, off, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @post return.length() == length()
|
||||||
|
*/
|
||||||
|
public String asString() throws IOException {
|
||||||
|
String retVal;
|
||||||
|
char[] buf = new char[fLength];
|
||||||
|
fRider.seek(fOffset);
|
||||||
|
fRider.readChars(buf);
|
||||||
|
retVal = new String(buf);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy parts of run into char-array
|
||||||
|
* @param arr array to copy into
|
||||||
|
* @param from offset of arr to copy bytes to
|
||||||
|
* @param arrSize max offset of arr to write into
|
||||||
|
* @param myOff offset of run to start reading at
|
||||||
|
* @return the number of bytes copied
|
||||||
|
*/
|
||||||
|
public int copyInto(char[] arr, int from, int arrSize, int myOff) throws IOException {
|
||||||
|
fRider.seek(fOffset + myOff);
|
||||||
|
int readAmount = Math.min(arrSize - from, fLength - myOff);
|
||||||
|
fRider.readChars(arr, from, readAmount);
|
||||||
|
return readAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append parts of run to a StringBuffer
|
||||||
|
* @param buffer StringBuffer to append to
|
||||||
|
* @param length number of characters to append
|
||||||
|
* @param myOff offset of run to start reading at
|
||||||
|
* @return the number of bytes appended
|
||||||
|
*/
|
||||||
|
public int appendTo(StringBuffer buffer, int length, int myOff) throws IOException {
|
||||||
|
fRider.seek(fOffset + myOff);
|
||||||
|
int readAmount = Math.min(length, fLength - myOff);
|
||||||
|
fRider.readChars(buffer, readAmount);
|
||||||
|
return readAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A run is mergable with another if the other a direct successor in the scratch file.
|
||||||
|
* @pre r != null
|
||||||
|
*/
|
||||||
|
public boolean isMergeableWith(REDRun r) {
|
||||||
|
return r.fRider == fRider && r.fOffset == fOffset + fLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
try {
|
||||||
|
return asString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see java.lang.CharSequence#charAt(int)
|
||||||
|
*/
|
||||||
|
public char charAt(int pos) {
|
||||||
|
try {
|
||||||
|
fRider.seek(fOffset + pos);
|
||||||
|
return fRider.readChar();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see java.lang.CharSequence#subSequence(int, int)
|
||||||
|
*/
|
||||||
|
public CharSequence subSequence(int start, int end) {
|
||||||
|
return new REDRun(fRider, fOffset + start, end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see java.lang.CharSequence#length()
|
||||||
|
*/
|
||||||
|
public int length() {
|
||||||
|
return fLength;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,874 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.text;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
import org.eclipse.jface.text.ITextStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Piece list text store implementation with scratch files.
|
||||||
|
*/
|
||||||
|
public final class REDTextStore implements ITextStore {
|
||||||
|
|
||||||
|
private static final int SCRATCH_FILE_THRESHOLD = 1024 * 1024;
|
||||||
|
private static final int MAX_SCRATCH_FILES = 4;
|
||||||
|
private static final int RECYCLE_THRESHOLD = 20;
|
||||||
|
private static final int IN_MEMORY_LIMIT = 1024 * 32;
|
||||||
|
private final static int CHUNK_SIZE = 1024 * 4;
|
||||||
|
private REDFileRider[] fScratchFiles = new REDFileRider[MAX_SCRATCH_FILES];
|
||||||
|
private LinkedRun fHead;
|
||||||
|
private LinkedRun fSpare;
|
||||||
|
private LinkedRun fCache;
|
||||||
|
private int fCachePos;
|
||||||
|
private int fLength;
|
||||||
|
private int fDeadLength;
|
||||||
|
private final RunSpec fRunSpec = new RunSpec();
|
||||||
|
private Job fSwapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This job swaps readonly IFileRider to disk.
|
||||||
|
*/
|
||||||
|
private final class TextStoreSwapper extends Job {
|
||||||
|
private IFileRider fRider;
|
||||||
|
private String fText;
|
||||||
|
|
||||||
|
private TextStoreSwapper(IFileRider rider, String text) {
|
||||||
|
super(""); //$NON-NLS-1$
|
||||||
|
fRider = rider;
|
||||||
|
fText = text;
|
||||||
|
setName("Swapping editor buffer to disk"); //$NON-NLS-1$
|
||||||
|
setPriority(Job.LONG);
|
||||||
|
// setSystem(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IStatus run(IProgressMonitor monitor) {
|
||||||
|
REDFileRider fileRider = null;
|
||||||
|
if (!monitor.isCanceled()) {
|
||||||
|
try {
|
||||||
|
// System.out.println("TextStoreSwapper.run() creating swap file");
|
||||||
|
fileRider = new REDFileRider(new REDFile());
|
||||||
|
int size = fText.length();
|
||||||
|
monitor.beginTask(getName(), size+1);
|
||||||
|
int written = 0;
|
||||||
|
while (written < size && !monitor.isCanceled()) {
|
||||||
|
int n = Math.min(size-written, CHUNK_SIZE);
|
||||||
|
fileRider.writeChars(fText, written, n);
|
||||||
|
monitor.worked(n);
|
||||||
|
written += n;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!monitor.isCanceled()) {
|
||||||
|
// System.out.println("TextStoreSwapper.run() swapping");
|
||||||
|
fileRider = swap(fRider, fileRider);
|
||||||
|
monitor.done();
|
||||||
|
}
|
||||||
|
// something went wrong, dispose the file
|
||||||
|
if (fileRider != null) {
|
||||||
|
// System.out.println("TextStoreSwapper.run() disposing");
|
||||||
|
fileRider.getFile().dispose();
|
||||||
|
}
|
||||||
|
// remove references
|
||||||
|
fText = null;
|
||||||
|
fRider = null;
|
||||||
|
// System.out.println("TextStoreSwapper.run() done");
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static class LinkedRun extends REDRun {
|
||||||
|
LinkedRun fNext;
|
||||||
|
LinkedRun fPrev;
|
||||||
|
|
||||||
|
LinkedRun(IFileRider rider, String str) throws IOException {
|
||||||
|
super(rider, str);
|
||||||
|
}
|
||||||
|
LinkedRun(IFileRider rider, char[] buf, int off, int n) throws IOException {
|
||||||
|
super(rider, buf, off, n);
|
||||||
|
}
|
||||||
|
LinkedRun(IFileRider rider, int offset, int length) {
|
||||||
|
super(rider, offset, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an empty text store.
|
||||||
|
*/
|
||||||
|
public REDTextStore() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a text store with intial content.
|
||||||
|
*/
|
||||||
|
public REDTextStore(String text) {
|
||||||
|
set(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() {
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free resources.
|
||||||
|
* Can be reactivated by calling <code>set(String)</code>.
|
||||||
|
*/
|
||||||
|
public void dispose() {
|
||||||
|
synchronized (fRunSpec) {
|
||||||
|
if (fSwapper != null) {
|
||||||
|
fSwapper.cancel();
|
||||||
|
fSwapper = null;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < fScratchFiles.length; ++i) {
|
||||||
|
if (fScratchFiles[i] != null) {
|
||||||
|
fScratchFiles[i].getFile().dispose();
|
||||||
|
fScratchFiles[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fHead = null;
|
||||||
|
fCache = null;
|
||||||
|
fSpare = null;
|
||||||
|
fRunSpec.fRun = null;
|
||||||
|
fCachePos = 0;
|
||||||
|
fLength = 0;
|
||||||
|
fDeadLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- ITextStore interface ------------------------------------
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#get(int)
|
||||||
|
*/
|
||||||
|
public char get(int offset) {
|
||||||
|
synchronized (fRunSpec) {
|
||||||
|
RunSpec spec = findNextRun(offset, null);
|
||||||
|
if (spec.fRun != null) {
|
||||||
|
return spec.fRun.charAt(spec.fOff);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#get(int, int)
|
||||||
|
*/
|
||||||
|
public String get(int offset, int length) {
|
||||||
|
synchronized (fRunSpec) {
|
||||||
|
// special case: long in-memory text in full length (about to be swapped)
|
||||||
|
if (length == fLength && fSwapper != null && fHead != null && fHead.fNext == null) {
|
||||||
|
((StringRider)fHead.fRider).fBuffer.position(0);
|
||||||
|
return ((StringRider)fHead.fRider).fBuffer.toString();
|
||||||
|
}
|
||||||
|
return toString(offset, offset + length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#getLength()
|
||||||
|
*/
|
||||||
|
public int getLength() {
|
||||||
|
synchronized (fRunSpec) {
|
||||||
|
return fLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
|
||||||
|
*/
|
||||||
|
public void set(String text) {
|
||||||
|
synchronized (fRunSpec) {
|
||||||
|
dispose();
|
||||||
|
if (text != null) {
|
||||||
|
fHead = new LinkedRun(new StringRider(text), 0, text.length());
|
||||||
|
fLength = text.length();
|
||||||
|
if (fLength > IN_MEMORY_LIMIT) {
|
||||||
|
fSwapper = new TextStoreSwapper(fHead.fRider, text);
|
||||||
|
fSwapper.schedule(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#replace(int, int, java.lang.String)
|
||||||
|
*/
|
||||||
|
public void replace(int offset, int length, String text) {
|
||||||
|
synchronized (fRunSpec) {
|
||||||
|
if (text == null || text.length() == 0) {
|
||||||
|
// delete only
|
||||||
|
replace(offset, length, null, 0, 0);
|
||||||
|
} else {
|
||||||
|
replace(offset, length, text, 0, text.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
synchronized (fRunSpec) {
|
||||||
|
return toString(0, getLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- implementation ----------------------------------------------------
|
||||||
|
|
||||||
|
/** Get part of the text as string.
|
||||||
|
* The parameters from and to are normalized to be in range: [0, fLength]
|
||||||
|
* Not MT-safe!
|
||||||
|
* @param from The beginning of the stretch of text to be returned; for from == n, the nth character is included.
|
||||||
|
* @param to The end of the stretch of text to be returned; for to == n, the nth character is not included.
|
||||||
|
* @return The stretch [from, to[ as String.
|
||||||
|
*/
|
||||||
|
private String toString(int from, int to) {
|
||||||
|
assert from >= 0 && from <= to && to <= fLength;
|
||||||
|
|
||||||
|
int len = to - from;
|
||||||
|
StringBuffer strBuf = new StringBuffer(len);
|
||||||
|
if (len > 0) {
|
||||||
|
RunSpec spec = findPrevRun(from, fRunSpec);
|
||||||
|
try {
|
||||||
|
int done = spec.fRun.appendTo(strBuf, len, spec.fOff);
|
||||||
|
while (done < len) {
|
||||||
|
spec.fRun = spec.fRun.fNext;
|
||||||
|
assert spec.fRun != null;
|
||||||
|
done += spec.fRun.appendTo(strBuf, len - done, 0);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
internalError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert strBuf.length() == len;
|
||||||
|
return strBuf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace [from;deleteLen[ with buf[off;insertLen[
|
||||||
|
* Not MT-safe!
|
||||||
|
* @param from
|
||||||
|
* @param deleteLen
|
||||||
|
* @param buf
|
||||||
|
* @param off
|
||||||
|
* @param insertLen
|
||||||
|
*/
|
||||||
|
private void replace(int from, int deleteLen, Object buf, int off, int insertLen) {
|
||||||
|
assert from >= 0 && from <= fLength;
|
||||||
|
assert deleteLen >= 0;
|
||||||
|
assert from + deleteLen <= fLength;
|
||||||
|
|
||||||
|
RunPair split = null;
|
||||||
|
if (deleteLen > 0) {
|
||||||
|
split = delete(from, from + deleteLen);
|
||||||
|
}
|
||||||
|
if (buf == null || insertLen == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// assert off >= 0 && off < buf.length;
|
||||||
|
// assert insertLen >= 0 && off+insertLen <= buf.length;
|
||||||
|
if (split == null) {
|
||||||
|
split = splitRun(from);
|
||||||
|
}
|
||||||
|
RunPair insert = makeRuns(split.fBefore, buf, off, insertLen);
|
||||||
|
// assert runLength(insert.fBefore, insert.fAfter) == insertLen;
|
||||||
|
insertRuns(split, insert.fBefore, insert.fAfter);
|
||||||
|
fLength += insertLen;
|
||||||
|
// assert runLength(fHead, null) == fLength;
|
||||||
|
fCache = insert.fAfter;
|
||||||
|
fCachePos = from+insertLen-insert.fAfter.fLength;
|
||||||
|
// assert checkConsistency();
|
||||||
|
if (split.fBefore != null) {
|
||||||
|
mergeRuns(split.fBefore, split.fAfter);
|
||||||
|
} else {
|
||||||
|
mergeRuns(fHead, split.fAfter);
|
||||||
|
}
|
||||||
|
if (fDeadLength > fLength / 10) {
|
||||||
|
reconcile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recreate text store by reinserting all runs.
|
||||||
|
* Not MT-safe!
|
||||||
|
*/
|
||||||
|
public void reconcile() {
|
||||||
|
LinkedRun run = fHead;
|
||||||
|
REDFileRider[] scratchFiles = fScratchFiles;
|
||||||
|
fScratchFiles = new REDFileRider[MAX_SCRATCH_FILES];
|
||||||
|
fHead = null;
|
||||||
|
fCache = null;
|
||||||
|
fCachePos = -1;
|
||||||
|
fSpare = null;
|
||||||
|
fLength = 0;
|
||||||
|
fDeadLength = 0;
|
||||||
|
char[] buf = new char[CHUNK_SIZE];
|
||||||
|
int offset = 0;
|
||||||
|
int runOffset = 0;
|
||||||
|
while (run != null) {
|
||||||
|
int n;
|
||||||
|
try {
|
||||||
|
do {
|
||||||
|
n = run.copyInto(buf, 0, buf.length, runOffset);
|
||||||
|
replace(offset, 0, buf, 0, n);
|
||||||
|
offset += n;
|
||||||
|
runOffset += n;
|
||||||
|
} while (runOffset < run.fLength);
|
||||||
|
} catch (IOException e) {
|
||||||
|
internalError(e);
|
||||||
|
}
|
||||||
|
run = run.fNext;
|
||||||
|
runOffset = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < scratchFiles.length; ++i) {
|
||||||
|
if (scratchFiles[i] != null) {
|
||||||
|
scratchFiles[i].getFile().dispose();
|
||||||
|
scratchFiles[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *******************************************************************************************************************************************************
|
||||||
|
// P R I V A T E - L I N E
|
||||||
|
// *******************************************************************************************************************************************************
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new LinkedRun
|
||||||
|
* @param before LinkedRun before new run
|
||||||
|
* @param n length of content
|
||||||
|
* @return new LinkedRun
|
||||||
|
*/
|
||||||
|
private LinkedRun createRun(LinkedRun before, int n) {
|
||||||
|
IFileRider scratchFile;
|
||||||
|
if (before != null && before.fRider.length() == before.fOffset + before.fLength && before.fRider.limit() >= before.fRider.length() + n) {
|
||||||
|
scratchFile = before.fRider;
|
||||||
|
} else {
|
||||||
|
scratchFile = getScratchFile();
|
||||||
|
}
|
||||||
|
return new LinkedRun(scratchFile, scratchFile.length(), n);
|
||||||
|
}
|
||||||
|
|
||||||
|
private REDFileRider getScratchFile() {
|
||||||
|
REDFileRider rider = null;
|
||||||
|
for (int i = 0; i < fScratchFiles.length; ++i) {
|
||||||
|
rider = fScratchFiles[i];
|
||||||
|
if (rider == null) {
|
||||||
|
try {
|
||||||
|
rider = new REDFileRider(new REDFile());
|
||||||
|
} catch (IOException e) {
|
||||||
|
internalError(e);
|
||||||
|
}
|
||||||
|
fScratchFiles[i] = rider;
|
||||||
|
break;
|
||||||
|
} else if (rider.length() < SCRATCH_FILE_THRESHOLD) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save run for later recycling.
|
||||||
|
* @param run
|
||||||
|
*/
|
||||||
|
private void spareRun(LinkedRun run, LinkedRun last) {
|
||||||
|
// remove readonly runs first
|
||||||
|
if (last != null) {
|
||||||
|
last.fNext = null;
|
||||||
|
}
|
||||||
|
LinkedRun cur = run;
|
||||||
|
LinkedRun prev = null;
|
||||||
|
while (cur != null) {
|
||||||
|
if (cur.fRider.isReadonly()) {
|
||||||
|
if (prev != null) {
|
||||||
|
prev.fNext = cur.fNext;
|
||||||
|
} else {
|
||||||
|
run = cur.fNext;
|
||||||
|
}
|
||||||
|
if (cur.fNext != null) {
|
||||||
|
cur.fNext.fPrev = prev;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prev = cur;
|
||||||
|
}
|
||||||
|
cur = cur.fNext;
|
||||||
|
}
|
||||||
|
if (run == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last = prev;
|
||||||
|
if (last != null) {
|
||||||
|
last.fNext = fSpare;
|
||||||
|
}
|
||||||
|
if (fSpare != null) {
|
||||||
|
fSpare.fPrev = last;
|
||||||
|
}
|
||||||
|
fSpare = run;
|
||||||
|
fSpare.fPrev = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recycle a run.
|
||||||
|
* @returns run
|
||||||
|
*/
|
||||||
|
private LinkedRun recycleRun() {
|
||||||
|
LinkedRun recycled = fSpare;
|
||||||
|
fSpare = null;
|
||||||
|
return recycled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
private void internalError(Exception e) {
|
||||||
|
throw new Error("Internal error", e); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REDRunSpec represents a specification of a run, including the run itself, its origin and offset.
|
||||||
|
* It is used for findRun - operations.
|
||||||
|
*/
|
||||||
|
private final static class RunSpec {
|
||||||
|
public LinkedRun fRun = null;
|
||||||
|
public int fOrg = -1;
|
||||||
|
public int fOff = -1;
|
||||||
|
public boolean isValid() {
|
||||||
|
return fRun != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* auxiliary class: pair of red runs
|
||||||
|
*/
|
||||||
|
private final static class RunPair {
|
||||||
|
public LinkedRun fBefore;
|
||||||
|
public LinkedRun fAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auxiliary method to delete part of the text.
|
||||||
|
* from and to have gap semantics.
|
||||||
|
* @param from start of the stretch to be deleted.
|
||||||
|
* @param to end of the stretch to be deleted.
|
||||||
|
* @return split pos for insertion
|
||||||
|
*/
|
||||||
|
private RunPair delete(int from, int to) {
|
||||||
|
RunPair start = splitRun(from);
|
||||||
|
RunPair end = splitRun(to);
|
||||||
|
if (start.fBefore != null) {
|
||||||
|
start.fBefore.fNext = end.fAfter;
|
||||||
|
} else {
|
||||||
|
fHead = end.fAfter;
|
||||||
|
}
|
||||||
|
if (end.fAfter != null) {
|
||||||
|
end.fAfter.fPrev = start.fBefore;
|
||||||
|
}
|
||||||
|
if (end.fAfter != null) {
|
||||||
|
fCache = end.fAfter;
|
||||||
|
fCachePos = from;
|
||||||
|
} else {
|
||||||
|
fCache = fHead;
|
||||||
|
fCachePos = 0;
|
||||||
|
}
|
||||||
|
fLength -= (to - from);
|
||||||
|
if (fLength == 0) {
|
||||||
|
dispose();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
spareRun(start.fAfter, end.fBefore);
|
||||||
|
start.fAfter = end.fAfter;
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the run which contains given position.
|
||||||
|
* caveat: if the given position lies between run a and b, a is returned
|
||||||
|
* @param pos The position to find the run for
|
||||||
|
* @return A run specification representing the found run. May be invalid (if given position was larger than text)
|
||||||
|
* @pre pos >= 0
|
||||||
|
* @pre pos <= length()
|
||||||
|
* @post return != null
|
||||||
|
* @post return.fOff > 0 || pos == 0
|
||||||
|
* @post return.fOff <= return.fRun.fLength
|
||||||
|
* @post return.fOrg >= 0
|
||||||
|
*/
|
||||||
|
private RunSpec findPrevRun(int pos, RunSpec spec) {
|
||||||
|
assert pos >= 0 && pos <= fLength;
|
||||||
|
LinkedRun cur;
|
||||||
|
int curPos;
|
||||||
|
|
||||||
|
if (fCache != null && fCachePos - pos < pos) {
|
||||||
|
assert fCache != null;
|
||||||
|
cur = fCache;
|
||||||
|
curPos = fCachePos;
|
||||||
|
} else {
|
||||||
|
cur = fHead;
|
||||||
|
curPos = 0;
|
||||||
|
}
|
||||||
|
while (cur != null && pos - curPos > cur.fLength) {
|
||||||
|
curPos += cur.fLength;
|
||||||
|
cur = cur.fNext;
|
||||||
|
}
|
||||||
|
if (pos != 0) {
|
||||||
|
while (pos - curPos <= 0) {
|
||||||
|
cur = cur.fPrev;
|
||||||
|
curPos -= cur.fLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fCache = cur;
|
||||||
|
fCachePos = curPos;
|
||||||
|
|
||||||
|
if (spec == null) {
|
||||||
|
spec = fRunSpec;
|
||||||
|
}
|
||||||
|
spec.fRun = cur;
|
||||||
|
spec.fOrg = curPos;
|
||||||
|
spec.fOff = pos - curPos;
|
||||||
|
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the run which contains given position.
|
||||||
|
* caveat: if the given position lies between run a and b, b is returned
|
||||||
|
* @param pos The position to find the run for
|
||||||
|
* @return A run specification representing the found run. May be invalid (if given position was larger than text)
|
||||||
|
* @pre pos >= 0
|
||||||
|
* @pre pos <= length()
|
||||||
|
* @post return != null
|
||||||
|
* @post return.fOff >= 0
|
||||||
|
* @post return.fOff < return.fRun.fLength
|
||||||
|
*/
|
||||||
|
private RunSpec findNextRun(int pos, RunSpec spec) {
|
||||||
|
if (pos < fLength) {
|
||||||
|
spec = findPrevRun(pos + 1, spec);
|
||||||
|
spec.fOff--;
|
||||||
|
} else {
|
||||||
|
spec = findPrevRun(pos, spec);
|
||||||
|
}
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Split run at pos and return pair of runs. */
|
||||||
|
private RunPair splitRun(int pos) {
|
||||||
|
RunPair p = new RunPair();
|
||||||
|
if (pos == 0) {
|
||||||
|
p.fBefore = null;
|
||||||
|
p.fAfter = fHead;
|
||||||
|
} else {
|
||||||
|
RunSpec spec = findPrevRun(pos, null);
|
||||||
|
assert spec.isValid();
|
||||||
|
p.fBefore = spec.fRun;
|
||||||
|
int len = spec.fRun.length();
|
||||||
|
if (spec.fOff != len) { // need to split
|
||||||
|
p.fAfter = new LinkedRun(p.fBefore.fRider, p.fBefore.fOffset + spec.fOff, p.fBefore.fLength - spec.fOff);
|
||||||
|
p.fBefore.fLength = spec.fOff;
|
||||||
|
p.fAfter.fNext = p.fBefore.fNext;
|
||||||
|
if (p.fAfter.fNext != null) {
|
||||||
|
p.fAfter.fNext.fPrev = p.fAfter;
|
||||||
|
}
|
||||||
|
p.fBefore.fNext = p.fAfter;
|
||||||
|
p.fAfter.fPrev = p.fBefore;
|
||||||
|
} else { // we already have a split
|
||||||
|
p.fAfter = p.fBefore.fNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge all runs between start and end where possible.
|
||||||
|
* @pre start != null
|
||||||
|
*/
|
||||||
|
private void mergeRuns(LinkedRun start, LinkedRun end) {
|
||||||
|
LinkedRun cur = start;
|
||||||
|
LinkedRun next = cur.fNext;
|
||||||
|
|
||||||
|
while (cur != end && next != null) {
|
||||||
|
if (cur.isMergeableWith(next)) {
|
||||||
|
if (next == fCache) {
|
||||||
|
fCache = cur;
|
||||||
|
fCachePos -= cur.fLength;
|
||||||
|
}
|
||||||
|
cur.fLength += next.fLength;
|
||||||
|
cur.fNext = next.fNext;
|
||||||
|
if (cur.fNext != null) {
|
||||||
|
cur.fNext.fPrev = cur;
|
||||||
|
}
|
||||||
|
if (next == end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
next = cur.fNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RunPair makeRuns(LinkedRun before, Object buf, int off, int n) {
|
||||||
|
RunPair result = new RunPair();
|
||||||
|
LinkedRun run;
|
||||||
|
LinkedRun recycled = recycleRun();
|
||||||
|
if (recycled != null) {
|
||||||
|
result.fBefore = recycled;
|
||||||
|
run = recycled;
|
||||||
|
do {
|
||||||
|
int count = Math.min(run.fLength, n);
|
||||||
|
try {
|
||||||
|
assert !run.fRider.isReadonly();
|
||||||
|
// safeguard
|
||||||
|
if (run.fRider.isReadonly()) {
|
||||||
|
run = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
run.fRider.seek(run.fOffset);
|
||||||
|
if (buf instanceof char[]) {
|
||||||
|
run.fRider.writeChars((char[])buf, off, count);
|
||||||
|
} else {
|
||||||
|
run.fRider.writeChars((String)buf, off, count);
|
||||||
|
}
|
||||||
|
if (run.fLength - count >= RECYCLE_THRESHOLD) {
|
||||||
|
LinkedRun next = run.fNext;
|
||||||
|
LinkedRun newRun = new LinkedRun(run.fRider, run.fOffset+count, run.fLength-count);
|
||||||
|
joinRuns(run, newRun);
|
||||||
|
joinRuns(newRun, next);
|
||||||
|
} else {
|
||||||
|
fDeadLength += run.fLength - count;
|
||||||
|
}
|
||||||
|
run.fLength = count;
|
||||||
|
off += count;
|
||||||
|
n -= count;
|
||||||
|
before = run;
|
||||||
|
run = run.fNext;
|
||||||
|
} catch (IOException e) {
|
||||||
|
run = null;
|
||||||
|
// internalError(e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (run != null && n > 0);
|
||||||
|
if (run != null) {
|
||||||
|
// shortcut for spareRun(run, null)
|
||||||
|
fSpare = run;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n > 0) {
|
||||||
|
run = createRun(before, n);
|
||||||
|
if (buf instanceof char[]) {
|
||||||
|
try {
|
||||||
|
run.fRider.seek(run.fOffset);
|
||||||
|
run.fRider.writeChars((char[])buf, off, n);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// internalError(e);
|
||||||
|
run = new LinkedRun(new StringRider(CharBuffer.wrap((char[])buf, off, off+n)), 0, n);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
run.fRider.seek(run.fOffset);
|
||||||
|
run.fRider.writeChars((String)buf, off, n);
|
||||||
|
} catch (IOException e) {
|
||||||
|
// internalError(e);
|
||||||
|
run = new LinkedRun(new StringRider(CharBuffer.wrap((String)buf, off, off+n)), 0, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result.fBefore == null) {
|
||||||
|
result.fBefore = run;
|
||||||
|
} else {
|
||||||
|
joinRuns(before, run);
|
||||||
|
}
|
||||||
|
result.fAfter = run;
|
||||||
|
} else {
|
||||||
|
result.fAfter = before;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void joinRuns(LinkedRun start, LinkedRun next) {
|
||||||
|
assert start != next;
|
||||||
|
start.fNext = next;
|
||||||
|
if (next != null) {
|
||||||
|
next.fPrev = start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void insertRuns(RunPair pos, LinkedRun start, LinkedRun end) {
|
||||||
|
assert pos.fBefore == null || pos.fBefore != pos.fAfter;
|
||||||
|
start.fPrev = pos.fBefore;
|
||||||
|
if (pos.fBefore != null) {
|
||||||
|
pos.fBefore.fNext = start;
|
||||||
|
} else {
|
||||||
|
fHead = start;
|
||||||
|
}
|
||||||
|
end.fNext = pos.fAfter;
|
||||||
|
if (pos.fAfter != null) {
|
||||||
|
pos.fAfter.fPrev = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swap given old (readonly) rider with the new (writable) one.
|
||||||
|
* @param oldRider
|
||||||
|
* @param newRider
|
||||||
|
* @return <code>null</code> if the new rider was consumed
|
||||||
|
*/
|
||||||
|
private REDFileRider swap(IFileRider oldRider, REDFileRider newRider) {
|
||||||
|
synchronized(fRunSpec) {
|
||||||
|
// search linked run list starting from head and replace
|
||||||
|
// all instances of oldRider with newRider
|
||||||
|
// in the general case, spare list should be searched, too
|
||||||
|
LinkedRun cur = fHead;
|
||||||
|
while (cur != null) {
|
||||||
|
if (cur.fRider == oldRider) {
|
||||||
|
cur.fRider = newRider;
|
||||||
|
}
|
||||||
|
cur = cur.fNext;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < fScratchFiles.length; i++) {
|
||||||
|
if (fScratchFiles[i] == null) {
|
||||||
|
fScratchFiles[i] = newRider;
|
||||||
|
newRider = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newRider != null) {
|
||||||
|
// unlikely, but possible: need to increase array
|
||||||
|
REDFileRider[] scratchFiles = new REDFileRider[fScratchFiles.length+1];
|
||||||
|
System.arraycopy(fScratchFiles, 0, scratchFiles, 0, fScratchFiles.length);
|
||||||
|
scratchFiles[fScratchFiles.length] = newRider;
|
||||||
|
fScratchFiles = scratchFiles;
|
||||||
|
newRider = null;
|
||||||
|
}
|
||||||
|
// clean out fRunSpec reference (just in case)
|
||||||
|
fRunSpec.fRun = null;
|
||||||
|
// clean out swapper reference
|
||||||
|
fSwapper = null;
|
||||||
|
}
|
||||||
|
return newRider;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- For debugging purposes
|
||||||
|
|
||||||
|
public void printStatistics(PrintStream out) {
|
||||||
|
int nRuns = 0;
|
||||||
|
int nSpare = 0;
|
||||||
|
int spareLength = 0;
|
||||||
|
LinkedRun run = fHead;
|
||||||
|
while(run != null) {
|
||||||
|
++nRuns;
|
||||||
|
run = run.fNext;
|
||||||
|
}
|
||||||
|
run = fSpare;
|
||||||
|
while(run != null) {
|
||||||
|
++nSpare;
|
||||||
|
spareLength += run.fLength;
|
||||||
|
run = run.fNext;
|
||||||
|
}
|
||||||
|
double runMean = nRuns > 0 ? (double)fLength / nRuns : Double.NaN;
|
||||||
|
double spareMean = nSpare > 0 ? spareLength / nSpare : Double.NaN;
|
||||||
|
out.println("Length: "+fLength); //$NON-NLS-1$
|
||||||
|
out.println("Number of runs: "+nRuns); //$NON-NLS-1$
|
||||||
|
out.println("Mean length of runs: " + runMean); //$NON-NLS-1$
|
||||||
|
out.println("Length of spare runs: "+spareLength); //$NON-NLS-1$
|
||||||
|
out.println("Number of spare runs: "+nSpare); //$NON-NLS-1$
|
||||||
|
out.println("Mean length of spare runs: " + spareMean); //$NON-NLS-1$
|
||||||
|
out.println("Length of dead runs: " + fDeadLength); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get structure.
|
||||||
|
* Returns the structure (Runs) as a single string. The Runs are separated
|
||||||
|
* by "->\n". At the end the string "null" is added to indicate, that no
|
||||||
|
* more runs exist. This implies that the string "null" is returned for an
|
||||||
|
* empty text.
|
||||||
|
*/
|
||||||
|
String getStructure() {
|
||||||
|
LinkedRun cur = fHead;
|
||||||
|
String structure = ""; //$NON-NLS-1$
|
||||||
|
while (cur != null) {
|
||||||
|
try {
|
||||||
|
structure += cur.asString() + "->\n"; //$NON-NLS-1$
|
||||||
|
} catch (IOException e) {
|
||||||
|
internalError(e);
|
||||||
|
}
|
||||||
|
cur = cur.fNext;
|
||||||
|
}
|
||||||
|
structure += "null"; //$NON-NLS-1$
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For debugging purposes only.
|
||||||
|
*/
|
||||||
|
boolean checkConsistency() {
|
||||||
|
LinkedRun run = fHead;
|
||||||
|
int length = 0;
|
||||||
|
while (run != null) {
|
||||||
|
LinkedRun prev = run.fPrev;
|
||||||
|
LinkedRun next = run.fNext;
|
||||||
|
assert prev != run;
|
||||||
|
assert next != run;
|
||||||
|
assert prev == null || prev.fNext == run;
|
||||||
|
assert next == null || next.fPrev == run;
|
||||||
|
while (prev != null) {
|
||||||
|
prev = prev.fPrev;
|
||||||
|
assert run != prev;
|
||||||
|
}
|
||||||
|
LinkedRun spare = fSpare;
|
||||||
|
while (spare != null) {
|
||||||
|
assert run != spare;
|
||||||
|
spare = spare.fPrev;
|
||||||
|
}
|
||||||
|
length += run.fLength;
|
||||||
|
run = next;
|
||||||
|
}
|
||||||
|
assert length == fLength;
|
||||||
|
if (fCache != null) {
|
||||||
|
int pos = fCachePos;
|
||||||
|
run = fCache;
|
||||||
|
while (run.fPrev != null) {
|
||||||
|
run = run.fPrev;
|
||||||
|
pos -= run.fLength;
|
||||||
|
}
|
||||||
|
assert pos == 0;
|
||||||
|
pos = fCachePos;
|
||||||
|
run = fCache;
|
||||||
|
while (run != null) {
|
||||||
|
pos += run.fLength;
|
||||||
|
run = run.fNext;
|
||||||
|
}
|
||||||
|
assert pos == fLength;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int runLength(LinkedRun first, LinkedRun last) {
|
||||||
|
LinkedRun run = first;
|
||||||
|
int length = 0;
|
||||||
|
while (run != null) {
|
||||||
|
length += run.fLength;
|
||||||
|
if (run == last) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
run = run.fNext;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.text;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.CharBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StringRider
|
||||||
|
*/
|
||||||
|
public class StringRider implements IFileRider {
|
||||||
|
|
||||||
|
CharBuffer fBuffer;
|
||||||
|
|
||||||
|
public StringRider(CharSequence text) {
|
||||||
|
super();
|
||||||
|
// create a readonly buffer
|
||||||
|
fBuffer = CharBuffer.wrap(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringRider(CharBuffer buffer) {
|
||||||
|
super();
|
||||||
|
fBuffer = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void seek(int pos) throws IOException {
|
||||||
|
fBuffer.position(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChar(char c) throws IOException {
|
||||||
|
fBuffer.put(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChars(char[] buf) throws IOException {
|
||||||
|
fBuffer.put(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChars(char[] buf, int n) throws IOException {
|
||||||
|
fBuffer.put(buf, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChars(char[] buf, int off, int n) throws IOException {
|
||||||
|
fBuffer.put(buf, off, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChars(String buf, int off, int n) throws IOException {
|
||||||
|
fBuffer.put(buf, off, off+n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public char readChar() throws IOException {
|
||||||
|
return fBuffer.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readChars(char[] buf) throws IOException {
|
||||||
|
fBuffer.get(buf, 0, buf.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readChars(char[] buf, int n) throws IOException {
|
||||||
|
fBuffer.get(buf, 0, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readChars(char[] buf, int off, int n) throws IOException {
|
||||||
|
fBuffer.get(buf, off, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readChars(StringBuffer buf, int n) throws IOException {
|
||||||
|
int pos = fBuffer.position();
|
||||||
|
if (fBuffer.hasArray()) {
|
||||||
|
buf.append(fBuffer.array(), fBuffer.arrayOffset() + pos, n);
|
||||||
|
} else {
|
||||||
|
fBuffer.limit(pos+n);
|
||||||
|
String str = fBuffer.toString();
|
||||||
|
assert str.length() == n;
|
||||||
|
buf.append(str);
|
||||||
|
fBuffer.limit(fBuffer.capacity());
|
||||||
|
}
|
||||||
|
fBuffer.position(pos + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int length() {
|
||||||
|
return fBuffer.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int limit() {
|
||||||
|
return fBuffer.limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReadonly() {
|
||||||
|
return fBuffer.isReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.text;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.ITextStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Readonly ITextStore implementation.
|
||||||
|
*/
|
||||||
|
public class StringTextStore implements ITextStore {
|
||||||
|
|
||||||
|
private String fText = ""; //$NON-NLS-1$
|
||||||
|
|
||||||
|
public StringTextStore() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringTextStore(String text) {
|
||||||
|
super();
|
||||||
|
fText = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#get(int)
|
||||||
|
*/
|
||||||
|
public char get(int offset) {
|
||||||
|
return fText.charAt(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#get(int, int)
|
||||||
|
*/
|
||||||
|
public String get(int offset, int length) {
|
||||||
|
if (length == fText.length()) {
|
||||||
|
return fText;
|
||||||
|
}
|
||||||
|
return new String(fText.substring(offset, offset+length));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#getLength()
|
||||||
|
*/
|
||||||
|
public int getLength() {
|
||||||
|
return fText.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#replace(int, int, java.lang.String)
|
||||||
|
*/
|
||||||
|
public void replace(int offset, int length, String text) {
|
||||||
|
// unmodifiable
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
|
||||||
|
*/
|
||||||
|
public void set(String text) {
|
||||||
|
fText = text != null ? text : ""; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.util;
|
||||||
|
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HSL (Hue, Saturation, Luminance) color model.
|
||||||
|
*/
|
||||||
|
public class HSL {
|
||||||
|
|
||||||
|
public double hue;
|
||||||
|
public double saturation;
|
||||||
|
public double luminance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create HSL from RGB.
|
||||||
|
*/
|
||||||
|
public HSL(RGB rgb) {
|
||||||
|
super();
|
||||||
|
double red = rgb.red / 255.0;
|
||||||
|
double green = rgb.green / 255.0;
|
||||||
|
double blue = rgb.blue / 255.0;
|
||||||
|
double cmax= Math.max(Math.max(red, green), blue);
|
||||||
|
double cmin= Math.min(Math.min(red, green), blue);
|
||||||
|
luminance = (cmax+cmin)/2;
|
||||||
|
if (cmax == cmin) {
|
||||||
|
hue = 0;
|
||||||
|
saturation = 0;
|
||||||
|
} else {
|
||||||
|
double delta = cmax-cmin;
|
||||||
|
if (luminance < 0.5) {
|
||||||
|
saturation = delta / (cmax + cmin);
|
||||||
|
} else {
|
||||||
|
saturation = delta / (2 - cmax - cmin);
|
||||||
|
}
|
||||||
|
if (red == cmax) {
|
||||||
|
hue = (green - blue) / delta;
|
||||||
|
} else if (green == cmax) {
|
||||||
|
hue = 2 + (blue - red) / delta;
|
||||||
|
} else {
|
||||||
|
hue = 4 + (red - green) / delta;
|
||||||
|
}
|
||||||
|
hue /= 6;
|
||||||
|
if (hue < 0) {
|
||||||
|
hue += 1;
|
||||||
|
} else if (hue > 1) {
|
||||||
|
hue -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RGB toRGB() {
|
||||||
|
int red,green,blue;
|
||||||
|
if (saturation == 0) {
|
||||||
|
red = (int)Math.round(255*luminance);
|
||||||
|
green = red;
|
||||||
|
blue = red;
|
||||||
|
} else {
|
||||||
|
double m1, m2;
|
||||||
|
if (luminance <= 0.5) {
|
||||||
|
m2 = luminance * (1 + saturation);
|
||||||
|
} else {
|
||||||
|
m2 = luminance + saturation - luminance * saturation;
|
||||||
|
}
|
||||||
|
m1 = 2 * luminance - m2;
|
||||||
|
red = hueToColorValue(hue + 1./3., m1, m2);
|
||||||
|
green = hueToColorValue(hue, m1, m2);
|
||||||
|
blue = hueToColorValue(hue - 1./3., m1, m2);
|
||||||
|
}
|
||||||
|
return new RGB(red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int hueToColorValue(double hue, double m1, double m2) {
|
||||||
|
double v;
|
||||||
|
if (hue < 0) {
|
||||||
|
hue += 1;
|
||||||
|
} else if (hue > 1) {
|
||||||
|
hue -= 1;
|
||||||
|
}
|
||||||
|
if (6*hue < 1) {
|
||||||
|
v = m1 + (m2-m1) * hue * 6;
|
||||||
|
} else if (2*hue < 1) {
|
||||||
|
v = m2;
|
||||||
|
} else if (3*hue < 2) {
|
||||||
|
v = m1 + (m2-m1) * (2./3. - hue) * 6;
|
||||||
|
} else {
|
||||||
|
v = m1;
|
||||||
|
}
|
||||||
|
return (int)Math.round(255 * v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string containing a concise, human-readable
|
||||||
|
* description of the receiver.
|
||||||
|
*
|
||||||
|
* @return a string representation of the <code>HSL</code>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString () {
|
||||||
|
return "HSL {" + hue + ", " + saturation + ", " + luminance + "}"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2008 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
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.dsf.debug.internal.ui.disassembly.util;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IStorage;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
|
import org.eclipse.ui.IPersistableElement;
|
||||||
|
import org.eclipse.ui.IStorageEditorInput;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract implementation of <code>IStorageEditorInput</code>.
|
||||||
|
*/
|
||||||
|
abstract public class StorageEditorInput implements IStorageEditorInput {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Storage associated with this editor input
|
||||||
|
*/
|
||||||
|
private IStorage fStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an editor input on the given storage
|
||||||
|
*/
|
||||||
|
public StorageEditorInput(IStorage storage) {
|
||||||
|
fStorage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see IStorageEditorInput#getStorage()
|
||||||
|
*/
|
||||||
|
public IStorage getStorage() {
|
||||||
|
return fStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set new storage. For subclasses only.
|
||||||
|
* @param storage
|
||||||
|
*/
|
||||||
|
protected void setStorage(IStorage storage) {
|
||||||
|
assert storage != null;
|
||||||
|
fStorage = storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see IEditorInput#getImageDescriptor()
|
||||||
|
*/
|
||||||
|
public ImageDescriptor getImageDescriptor() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see IEditorInput#getName()
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return getStorage().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see IEditorInput#getPersistable()
|
||||||
|
*/
|
||||||
|
public IPersistableElement getPersistable() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see IEditorInput#getToolTipText()
|
||||||
|
*/
|
||||||
|
public String getToolTipText() {
|
||||||
|
return getStorage().getFullPath().toOSString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object object) {
|
||||||
|
if (object == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return object instanceof IStorageEditorInput
|
||||||
|
&& getStorage().equals(((IStorageEditorInput)object).getStorage());
|
||||||
|
} catch (CoreException e) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return getStorage().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
|
||||||
|
*/
|
||||||
|
public Object getAdapter(Class adapter) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2000, 2006 QNX Software Systems and others.
|
* Copyright (c) 2000, 2008 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -60,7 +60,7 @@ public class MIInstruction implements IInstruction {
|
||||||
* - Function name
|
* - Function name
|
||||||
* - Offset
|
* - Offset
|
||||||
* - Instruction
|
* - Instruction
|
||||||
*
|
*
|
||||||
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
|
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
|
||||||
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
|
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
|
||||||
* ...,
|
* ...,
|
||||||
|
@ -81,7 +81,7 @@ public class MIInstruction implements IInstruction {
|
||||||
|
|
||||||
if (var.equals("address")) { //$NON-NLS-1$
|
if (var.equals("address")) { //$NON-NLS-1$
|
||||||
try {
|
try {
|
||||||
address = new BigInteger(str.trim(), 16);
|
address = decodeAddress(str.trim());
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -127,4 +127,19 @@ public class MIInstruction implements IInstruction {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode given string representation of a non-negative integer. A
|
||||||
|
* hexadecimal encoded integer is expected to start with <code>0x</code>.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* decimal or hexadecimal representation of an non-negative integer
|
||||||
|
* @return address value as <code>BigInteger</code>
|
||||||
|
*/
|
||||||
|
private static BigInteger decodeAddress(String string) {
|
||||||
|
if (string.startsWith("0x")) { //$NON-NLS-1$
|
||||||
|
return new BigInteger(string.substring(2), 16);
|
||||||
|
}
|
||||||
|
return new BigInteger(string);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue