1
0
Fork 0
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:
Francois Chouinard 2008-04-29 21:26:59 +00:00
parent 5474268d37
commit cc153db8ba
73 changed files with 13585 additions and 11 deletions

View file

@ -0,0 +1 @@
org.eclipse.dd.dsf.debug.ui/debug = false

View file

@ -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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

View file

@ -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...

View file

@ -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>

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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());
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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$
}

View file

@ -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);
}

View file

@ -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();
}
}
}

View file

@ -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();
}
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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) {
}
}

View file

@ -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);
}
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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();
}
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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();
}

View file

@ -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$
}
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}
}

View file

@ -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$
}
}

View file

@ -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$
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}