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
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Debug Services Framework Debug UI
|
||||
Bundle-Vendor: Eclipse.org
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-SymbolicName: org.eclipse.dd.dsf.debug.ui; singleton:=true
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
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.debug,
|
||||
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
|
||||
Export-Package:
|
||||
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
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
|
@ -8,6 +8,21 @@
|
|||
# Contributors:
|
||||
# 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
|
||||
|
||||
# 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">
|
||||
</detailFactories>
|
||||
</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>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
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.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
@ -17,8 +18,11 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin {
|
|||
private static DsfDebugUIPlugin 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
|
||||
*/
|
||||
|
@ -35,6 +39,7 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin {
|
|||
plugin = this;
|
||||
fgBundleContext = context;
|
||||
|
||||
fSourceDocumentProvider = new SourceDocumentProvider();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -43,6 +48,8 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin {
|
|||
*/
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
fSourceDocumentProvider.dispose();
|
||||
fSourceDocumentProvider = null;
|
||||
plugin = null;
|
||||
super.stop(context);
|
||||
}
|
||||
|
@ -75,4 +82,8 @@ public class DsfDebugUIPlugin extends AbstractUIPlugin {
|
|||
public static ImageDescriptor getImageDescriptor(String 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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -60,7 +60,7 @@ public class MIInstruction implements IInstruction {
|
|||
* - Function name
|
||||
* - Offset
|
||||
* - Instruction
|
||||
*
|
||||
*
|
||||
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
|
||||
* {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$
|
||||
try {
|
||||
address = new BigInteger(str.trim(), 16);
|
||||
address = decodeAddress(str.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
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