1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Initial commit of memory space support in the memory view (made possible by 3.2 platform additions).

This commit is contained in:
John Cortell 2006-10-03 19:07:38 +00:00
parent 254779d07d
commit 1b67f9c817
12 changed files with 999 additions and 1 deletions

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - Initial API
*******************************************************************************/
package org.eclipse.cdt.debug.core.cdi.model;
import java.math.BigInteger;
import org.eclipse.cdt.debug.core.cdi.CDIException;
/**
* Extension of ICDIMemoryBlockManagement
*
* @since May 26, 2006
*/
public interface ICDIMemoryBlockManagement2 extends ICDIMemoryBlockManagement {
/**
* Returns a memory block specified by given parameters. Differs
* from {@link ICDIMemoryBlockManagement#createMemoryBlock(String, int, int)}
* in that this support memory spaces.
* @param address
* @param memorySpaceID - value is meaningful only to the backend
* @param units - number of units
* @param wordSize - The size of each memory word in bytes
* @return a memory block with the specified identifier
* @throws CDIException on failure. Reasons include:
*/
ICDIMemoryBlock createMemoryBlock(BigInteger address, String memorySpaceID, int units, int wordSize)
throws CDIException;
}

View file

@ -0,0 +1,40 @@
/*******************************************************************************
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - Initial API
*******************************************************************************/
package org.eclipse.cdt.debug.core.cdi.model;
import java.math.BigInteger;
/**
* The memory space manager provides varous memory-space related operations.
* The backend implementation of ICDITarget should implement this interface
* as well if the target supports memory spaces.
*/
public interface ICDIMemorySpaceManagement extends ICDIObject {
/**
* Optionally provides the string encoding of a memory space qualified address.
* CDT provides a default encoding of <memory-space-id>:<address(hex)>.
* If this is adequate, the client can return null from this function.
*
* @param address - a numeric address
* @param memorySpaceID - a string which represents the memory space
* @return the encoded string representation of the address or null
*/
String addressToString(BigInteger address, String memorySpaceID);
/**
* Provides the memory spaces available.
*
* @return an array of memory space identifiers
*/
String [] getMemorySpaces();
}

View file

@ -19,6 +19,8 @@ import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.cdi.CDIException; import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDIExpression; import org.eclipse.cdt.debug.core.cdi.model.ICDIExpression;
import org.eclipse.cdt.debug.core.cdi.model.ICDIMemorySpaceManagement;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.core.model.ICType; import org.eclipse.cdt.debug.core.model.ICType;
import org.eclipse.cdt.debug.core.model.ICValue; import org.eclipse.cdt.debug.core.model.ICValue;
import org.eclipse.cdt.debug.internal.core.model.CDebugTarget; import org.eclipse.cdt.debug.internal.core.model.CDebugTarget;
@ -200,6 +202,39 @@ public class CMemoryBlockRetrievalExtension extends PlatformObject implements IM
return new CMemoryBlockExtension( getDebugTarget(), expression, address ); return new CMemoryBlockExtension( getDebugTarget(), expression, address );
} }
/**
* Variant of getExtendedMemoryBlock that takes a memory space ID. Note that unlike that one,
* this method is not part of IMemoryBlockRetrievalExtension; it is not exercised by the
* platform. We invoke it internally in CDT from our hook into the platform's "add memory
* monitor" action.
*
* @param address - a numric address value, hex or decimal. An expression
* (even something simple like 10000 +1) is not allowed.
* @param memorySpaceID - identifies the memory space; cannot be null.
* @param selected - the object selected in the Debug view
* @return
* @throws DebugException
*/
public IMemoryBlockExtension getMemoryBlockWithMemorySpaceID( String address, String memorySpaceID, Object selected ) throws DebugException {
String msg = null;
try {
if (selected instanceof IDebugElement) {
IDebugElement debugElement = (IDebugElement)selected;
IDebugTarget target = debugElement.getDebugTarget();
if ( target instanceof CDebugTarget ) {
if ( address != null ) {
BigInteger addr = ( address.startsWith( "0x" ) ) ? new BigInteger( address.substring( 2 ), 16 ) : new BigInteger( address ); //$NON-NLS-1$
return new CMemoryBlockExtension( (CDebugTarget)target, addr, memorySpaceID );
}
}
}
}
catch( NumberFormatException e ) {
msg = MessageFormat.format( InternalDebugCoreMessages.getString( "CMemoryBlockRetrievalExtension.4" ), new String[] { address } ); //$NON-NLS-1$
}
throw new DebugException( new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED, msg, null ) );
}
private CStackFrame getStackFrame( IDebugElement selected ) throws DebugException { private CStackFrame getStackFrame( IDebugElement selected ) throws DebugException {
if ( selected instanceof CStackFrame ) { if ( selected instanceof CStackFrame ) {
return (CStackFrame)selected; return (CStackFrame)selected;
@ -234,4 +269,26 @@ public class CMemoryBlockRetrievalExtension extends PlatformObject implements IM
public void dispose() { public void dispose() {
} }
/**
* Checks the CDI backend to see is memory spaces are supported
*
* @return true if the backend supports memory spaces
*/
public boolean supportsMemorySpaces() {
return fDebugTarget.getCDITarget() instanceof ICDIMemorySpaceManagement;
}
/**
* Get the list of available memory spaces from the CDI backend
*
* @return an array of memory space identifiers
*/
public String [] getMemorySpaces() {
ICDITarget cdiTarget = fDebugTarget.getCDITarget();
if (cdiTarget instanceof ICDIMemorySpaceManagement)
return ((ICDIMemorySpaceManagement)cdiTarget).getMemorySpaces();
return new String[0];
}
} }

View file

@ -13,6 +13,7 @@ CMemoryBlockRetrievalExtension.0=Expression ''{0}'' evaluated to invalid address
CMemoryBlockRetrievalExtension.1=Invalid expression type: ''{0}'' CMemoryBlockRetrievalExtension.1=Invalid expression type: ''{0}''
CMemoryBlockRetrievalExtension.2=Invalid expression: ''{0}'' CMemoryBlockRetrievalExtension.2=Invalid expression: ''{0}''
CMemoryBlockRetrievalExtension.3=Memory initialization: invalid memento. CMemoryBlockRetrievalExtension.3=Memory initialization: invalid memento.
CMemoryBlockRetrievalExtension.4=Invalid address: ''{0}''
DebugConfiguration.0=This debugger no longer supports this operation DebugConfiguration.0=This debugger no longer supports this operation
CDebugAdapter.0=This debugger does not support debugging external files CDebugAdapter.0=This debugger does not support debugging external files
CDebugAdapter.1=Debugger Process CDebugAdapter.1=Debugger Process

View file

@ -21,7 +21,10 @@ import org.eclipse.cdt.debug.core.cdi.event.ICDIMemoryChangedEvent;
import org.eclipse.cdt.debug.core.cdi.event.ICDIRestartedEvent; import org.eclipse.cdt.debug.core.cdi.event.ICDIRestartedEvent;
import org.eclipse.cdt.debug.core.cdi.event.ICDIResumedEvent; import org.eclipse.cdt.debug.core.cdi.event.ICDIResumedEvent;
import org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock; import org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlock;
import org.eclipse.cdt.debug.core.cdi.model.ICDIMemoryBlockManagement2;
import org.eclipse.cdt.debug.core.cdi.model.ICDIMemorySpaceManagement;
import org.eclipse.cdt.debug.core.cdi.model.ICDIObject; import org.eclipse.cdt.debug.core.cdi.model.ICDIObject;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.core.model.IExecFileInfo; import org.eclipse.cdt.debug.core.model.IExecFileInfo;
import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugException;
@ -45,6 +48,12 @@ public class CMemoryBlockExtension extends CDebugElement implements IMemoryBlock
*/ */
private BigInteger fBaseAddress; private BigInteger fBaseAddress;
/**
* The memory space identifier; will be null for backends that
* don't require memory space support
*/
private String fMemorySpaceID;
/** /**
* The underlying CDI memory block. * The underlying CDI memory block.
*/ */
@ -77,6 +86,24 @@ public class CMemoryBlockExtension extends CDebugElement implements IMemoryBlock
fWordSize = wordSize; fWordSize = wordSize;
} }
/**
* Constructor for CMemoryBlockExtension that supports memory spaces
*
*/
public CMemoryBlockExtension( CDebugTarget target, BigInteger baseAddress, String memorySpaceID ) {
super( target );
fBaseAddress = baseAddress;
fMemorySpaceID = memorySpaceID;
fWordSize = 1;
if (target.getCDITarget() instanceof ICDIMemorySpaceManagement)
fExpression = ((ICDIMemorySpaceManagement)target.getCDITarget()).addressToString(baseAddress, memorySpaceID);
if (fExpression == null)
// If the backend supports memory spaces, it should implement ICDIMemorySpaceManagement
// If not, we use a default encoding
fExpression = memorySpaceID + ':' + baseAddress.toString(16);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.debug.core.model.IMemoryBlockExtension#getExpression() * @see org.eclipse.debug.core.model.IMemoryBlockExtension#getExpression()
*/ */
@ -264,7 +291,14 @@ public class CMemoryBlockExtension extends CDebugElement implements IMemoryBlock
} }
private ICDIMemoryBlock createCDIBlock( BigInteger address, long length, int wordSize ) throws CDIException { private ICDIMemoryBlock createCDIBlock( BigInteger address, long length, int wordSize ) throws CDIException {
ICDIMemoryBlock block = ((CDebugTarget)getDebugTarget()).getCDITarget().createMemoryBlock( address.toString(), (int)length, wordSize ); ICDIMemoryBlock block = null;
CDebugTarget target = (CDebugTarget)getDebugTarget();
ICDITarget cdiTarget = target.getCDITarget();
if ((fMemorySpaceID != null) && (cdiTarget instanceof ICDIMemoryBlockManagement2)) {
block = ((ICDIMemoryBlockManagement2)cdiTarget).createMemoryBlock(address, fMemorySpaceID, (int)length, wordSize);
} else {
block = cdiTarget.createMemoryBlock( address.toString(), (int)length, wordSize );
}
block.setFrozen( false ); block.setFrozen( false );
getCDISession().getEventManager().addEventListener( this ); getCDISession().getEventManager().addEventListener( this );
return block; return block;
@ -456,4 +490,18 @@ public class CMemoryBlockExtension extends CDebugElement implements IMemoryBlock
} }
return new MemoryByte( value, flags ); return new MemoryByte( value, flags );
} }
/**
* Provides the memory space associated with this block if and only if the
* block was created with an address value + memory space qualifier. If the
* block was created from an expression, this method should return null--
* even if the target CDI backend supports memory spaces.
*
* @return a memory space ID or null
* expression
*/
public String getMemorySpaceID() {
return fMemorySpaceID;
}
} }

View file

@ -0,0 +1,68 @@
/*******************************************************************************
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - initial API and implementation
*
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.elements.adapters;
import org.eclipse.cdt.debug.internal.core.CMemoryBlockRetrievalExtension;
import org.eclipse.cdt.debug.internal.core.model.CMemoryBlockExtension;
import org.eclipse.cdt.debug.internal.ui.views.memory.AddMemoryBlocks;
import org.eclipse.cdt.debug.internal.ui.views.memory.MemoryBlockLabelDecorator;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.ui.actions.IAddMemoryBlocksTarget;
import org.eclipse.jface.viewers.ILabelDecorator;
/**
* Provides the IAdaptable mapping for things related to the memory-space
* extension of the platform's Memory view
*/
public class CMemoryAdapterFactory implements IAdapterFactory {
private static IAddMemoryBlocksTarget fgAddMemoryBlocks = new AddMemoryBlocks();
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object,
* java.lang.Class)
*/
public Object getAdapter(Object adaptableObject, Class adapterType) {
if (adapterType.isInstance(adaptableObject)) {
return adaptableObject;
}
if (adapterType.equals(IAddMemoryBlocksTarget.class)) {
if (adaptableObject instanceof CMemoryBlockRetrievalExtension) {
if (((CMemoryBlockRetrievalExtension)adaptableObject).supportsMemorySpaces())
return fgAddMemoryBlocks;
}
}
if (adapterType.equals(ILabelDecorator.class)) {
if (adaptableObject instanceof CMemoryBlockExtension) {
// If a memory space isn't involved, the standard label is fine
CMemoryBlockExtension memBlock = (CMemoryBlockExtension)adaptableObject;
if (memBlock.getMemorySpaceID() != null)
return new MemoryBlockLabelDecorator(memBlock);
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
*/
public Class[] getAdapterList() {
return new Class[] { IAddMemoryBlocksTarget.class, ILabelDecorator.class };
}
}

View file

@ -0,0 +1,298 @@
/*******************************************************************************
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - initial API and implementation
*
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.memory;
import java.util.ArrayList;
import org.eclipse.cdt.debug.internal.core.CMemoryBlockRetrievalExtension;
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
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.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
/**
* Dialog CDT puts up when adding a memory monitor to the memory view for a
* debug target that supports memory spaces.
* <p>
* It differs from the platform one in that you can enter an expression or
* an memory space + address pair.
*
* @since 3.2
*/
public class AddMemoryBlockDialog extends TrayDialog implements ModifyListener, FocusListener, VerifyListener {
private Combo fAddressInput;
private Combo fMemorySpaceInput;
private Combo fExpressionInput;
private String fExpression;
private String fAddress;
private String fMemorySpace;
private boolean fExpressionEntered;
private CMemoryBlockRetrievalExtension fMemRetrieval;
private Button fEnterAddr;
private Button fEnterExpression;
private static boolean sfExpressionSetLast = false; // used to persist the default entry-type selection
private static ArrayList sAddressHistory = new ArrayList();
private static ArrayList sExpressionHistory = new ArrayList();
public AddMemoryBlockDialog(Shell parentShell,
IMemoryBlockRetrieval memRetrieval) {
super(parentShell);
setShellStyle(getShellStyle() | SWT.RESIZE);
if (memRetrieval instanceof CMemoryBlockRetrievalExtension) {
fMemRetrieval = (CMemoryBlockRetrievalExtension)memRetrieval;
}
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
*/
protected Control createDialogArea(Composite parent) {
PlatformUI.getWorkbench().getHelpSystem().setHelp(
parent,
IDebugUIConstants.PLUGIN_ID
+ ".MonitorMemoryBlockDialog_context"); //$NON-NLS-1$
// The button bar will work better if we make the parent composite
// a single column grid layout. For the widgets we add, we want a
// a two-column grid, so we just create a sub composite for that.
GridLayout gridLayout = new GridLayout();
parent.setLayout(gridLayout);
GridData gridData = new GridData(GridData.FILL_BOTH);
parent.setLayoutData(gridData);
Composite composite = new Composite(parent, SWT.None);
gridLayout = new GridLayout();
gridLayout.numColumns = 2;
composite.setLayout(gridLayout);
gridData = new GridData(GridData.FILL_BOTH);
composite.setLayoutData(gridData);
parent = composite; // for all our widgets, the two-column composite is the real parent
fEnterAddr = new Button(parent, SWT.RADIO);
// take this opportunity to get the width of just the radion buton
// (w/no text), as we'll need it below
int buttonWidth = fEnterAddr.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).x;
fEnterAddr.setText(Messages.AddMemBlockDlg_enterMemSpaceAndAddr);
gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 2;
fEnterAddr.setLayoutData(gridData);
fMemorySpaceInput = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
gridData = new GridData();
gridData.horizontalIndent = buttonWidth;
fMemorySpaceInput.setLayoutData(gridData);
fMemorySpaceInput.addFocusListener(this);
// Populate the memory space combobox with the available spaces
if (fMemRetrieval != null) {
String [] memorySpaces = fMemRetrieval.getMemorySpaces();
for (int i = 0; i < memorySpaces.length; i++)
fMemorySpaceInput.add(memorySpaces[i]);
if (memorySpaces.length > 0)
fMemorySpaceInput.select(0);
}
fAddressInput = new Combo(parent, SWT.BORDER);
gridData = new GridData(GridData.FILL_HORIZONTAL);
fAddressInput.setLayoutData(gridData);
fAddressInput.addModifyListener(this);
fAddressInput.addFocusListener(this);
fAddressInput.addVerifyListener(this);
fEnterExpression = new Button(parent, SWT.RADIO);
fEnterExpression.setText(Messages.AddMemBlockDlg_enterExpression);
gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 2;
fEnterExpression.setLayoutData(gridData);
fExpressionInput = new Combo(parent, SWT.BORDER);
gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 2;
gridData.horizontalIndent = buttonWidth;
fExpressionInput.setLayoutData(gridData);
fExpressionInput.addModifyListener(this);
fExpressionInput.addFocusListener(this);
// add the history into the combo boxes
String[] history = getHistory(sExpressionHistory);
for (int i = 0; i < history.length; i++)
fExpressionInput.add(history[i]);
history = getHistory(sAddressHistory);
for (int i = 0; i < history.length; i++)
fAddressInput.add(history[i]);
fExpressionInput.addFocusListener(this);
fEnterExpression.setSelection(sfExpressionSetLast);
fEnterAddr.setSelection(!sfExpressionSetLast);
if (sfExpressionSetLast) {
fExpressionInput.forceFocus();
} else {
fAddressInput.forceFocus();
}
return parent;
}
/* (non-Javadoc)
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
*/
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
// use the same title used by the platform dialog
newShell.setText(Messages.AddMemBlockDlg_MonitorMemory);
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.Dialog#okPressed()
*/
protected void okPressed() {
fExpressionEntered = fEnterExpression.getSelection();
fExpression = fExpressionInput.getText();
fAddress = fAddressInput.getText();
fMemorySpace = fMemorySpaceInput.getText();
// add to HISTORY list; add to the platform dialog's for the expression
if (fExpression.length() > 0)
addHistory(sExpressionHistory, fExpression);
if (fAddress.length() > 0)
addHistory(sAddressHistory, fAddress);
// this will persist the entry type from one dialog invocation to another
sfExpressionSetLast = fExpressionEntered;
super.okPressed();
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
*/
public void modifyText(ModifyEvent e) {
// if user enters text into one of the two input options, disable/gray the other
// to make the mutual exlusivity obvious
fAddressInput.setEnabled(fExpressionInput.getText().length() == 0);
fEnterAddr.setEnabled(fExpressionInput.getText().length() == 0);
fMemorySpaceInput.setEnabled(fExpressionInput.getText().length() == 0);
fExpressionInput.setEnabled(fAddressInput.getText().length() == 0);
fEnterExpression.setEnabled(fAddressInput.getText().length() == 0);
}
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.TrayDialog#createButtonBar(org.eclipse.swt.widgets.Composite)
*/
protected Control createButtonBar(Composite parent) {
return super.createButtonBar(parent);
}
public String getExpression() {
return fExpression;
}
public String getAddress() {
return fAddress;
}
public String getMemorySpace() {
return fMemorySpace;
}
public boolean wasExpressionEntered() {
return fExpressionEntered;
}
private static void addHistory(ArrayList list, String item) {
if (!list.contains(item))
list.add(0, item);
if (list.size() > 5)
list.remove(list.size()-1);
}
private static String[] getHistory(ArrayList list) {
return (String[])list.toArray(new String[list.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
*/
public void focusGained(FocusEvent e) {
// when the user gives focus to one of the combo boxes, shift the radio button state accordingly
if (e.widget == fAddressInput || e.widget == fMemorySpaceInput) {
fEnterAddr.setSelection(true);
fEnterExpression.setSelection(false);
}
else if (e.widget == fExpressionInput) {
fEnterAddr.setSelection(false);
fEnterExpression.setSelection(true);
}
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
*/
public void focusLost(FocusEvent e) {
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent)
*/
public void verifyText(VerifyEvent event) {
if (event.widget == fAddressInput) {
// assume we won't allow it
event.doit = false;
char c = event.character;
String textAlreadyInControl = ((Combo)event.widget).getText();
if ((c == 'x') && (textAlreadyInControl.length() == 1)
&& textAlreadyInControl.charAt(0) == '0') {
// allow 'x' if it's the second character and the first is zero.
// Note that this level of verification has a hole; user can use
// ISO control characters (e.g., the Delete key) to move the 'x'
// in the first slot. Oh well; this doesn't need to be bullet proof
event.doit = true;
} else if ((c == '\b') || // allow backspace
Character.isDigit(c) || ('a' <= c && c <= 'f')
|| ('A' <= c && c <= 'F')) {
event.doit = true;
} else if (Character.isISOControl(c)) {
event.doit = true;
}
}
}
}

View file

@ -0,0 +1,296 @@
/*******************************************************************************
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - initial API and implementation
*
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.memory;
import java.util.ArrayList;
import java.util.StringTokenizer;
import org.eclipse.cdt.debug.internal.core.CMemoryBlockRetrievalExtension;
import org.eclipse.cdt.debug.ui.CDebugUIPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
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.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IMemoryBlockExtension;
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.actions.IAddMemoryBlocksTarget;
import org.eclipse.debug.ui.memory.IMemoryRendering;
import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
import org.eclipse.debug.ui.memory.IMemoryRenderingSite;
import org.eclipse.debug.ui.memory.IMemoryRenderingType;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.progress.UIJob;
/**
* Adds memory blocks to the Memory view.
*
* <p>
* CDT adapter logic will link us to a CMemoryBlockRetrievalExtension
* if and only if the CDI backend support memory spaces. When this is the case,
* the platform will call us to add a memory monitor to the Memory view. We
* must put up a dialog, handle the user input, create the memory blocks
* with default renderings and add them to the view.
*
* <p>
* @since 3.2
*
*/
public class AddMemoryBlocks implements IAddMemoryBlocksTarget {
public void addMemoryBlocks(IWorkbenchPart part, ISelection selection) throws CoreException {
if (!(part instanceof IMemoryRenderingSite))
return;
IAdaptable debugViewElement = DebugUITools.getDebugContext();
CMemoryBlockRetrievalExtension cdtRetrieval = null;
{
IMemoryBlockRetrieval retrieval = (IMemoryBlockRetrieval)debugViewElement.getAdapter(IMemoryBlockRetrieval.class);
if (retrieval == null && debugViewElement instanceof IDebugElement)
retrieval = ((IDebugElement)debugViewElement).getDebugTarget();
if (retrieval == null || !(retrieval instanceof CMemoryBlockRetrievalExtension))
return;
cdtRetrieval = (CMemoryBlockRetrievalExtension) retrieval;
}
Shell shell = CDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell();
// create dialog to ask for expression/address to block
AddMemoryBlockDialog dialog = new AddMemoryBlockDialog(shell, cdtRetrieval);
dialog.open();
int returnCode = dialog.getReturnCode();
if (returnCode == Window.CANCEL)
return;
String input = (dialog.getAddress().length() > 0) ? dialog.getAddress()
: dialog.getExpression();
ArrayList list = new ArrayList();
if (input.length() == 0)
list.add(""); //$NON-NLS-1$
else {
StringTokenizer tokenizer = new StringTokenizer(input, ","); //$NON-NLS-1$
while (tokenizer.hasMoreTokens())
list.add(tokenizer.nextToken());
}
final String[] addrsOrExprs = (String[]) list.toArray(new String[list.size()]);
ParamHolder params;
if (dialog.wasExpressionEntered())
params = new ExpressionsHolder(addrsOrExprs);
else
params = new AddressAndSpaceHolder(addrsOrExprs, dialog.getMemorySpace());
final IAdaptable debugViewElement_f = debugViewElement;
final CMemoryBlockRetrievalExtension retrieval_f = cdtRetrieval;
final ParamHolder params_f = params;
final IMemoryRenderingSite memRendSite = (IMemoryRenderingSite) part;
Job job = new Job("Add Memory Block") { //$NON-NLS-1$
protected IStatus run(IProgressMonitor monitor) {
addMemoryBlocks(debugViewElement_f, retrieval_f, params_f,
memRendSite);
return Status.OK_STATUS;
}
};
job.setSystem(true);
job.schedule();
}
public boolean canAddMemoryBlocks(IWorkbenchPart part, ISelection selection)
throws CoreException {
return true;
}
public boolean supportsAddMemoryBlocks(IWorkbenchPart part) {
return (IDebugUIConstants.ID_MEMORY_VIEW.equals(part.getSite().getId()));
}
// In order to avoid duplicating the addMemoryBlocks method--one
// version for expressions, one for memory-space+address, we pass in a
// an opaque parameter and let the logic within addMemoryBlocks
// differentiate where needed via isinstanceof
private class ParamHolder {
}
class AddressAndSpaceHolder extends ParamHolder {
public AddressAndSpaceHolder(final String[] addresses,
final String memorySpace) {
this.addresses = addresses;
this.memorySpace = memorySpace;
}
public String[] addresses;
public String memorySpace;
}
private class ExpressionsHolder extends ParamHolder {
public ExpressionsHolder(final String[] expressions) {
this.expressions = expressions;
}
public String[] expressions;
}
private void addMemoryBlocks(IAdaptable debugViewElement,
CMemoryBlockRetrievalExtension memRetrieval,
final ParamHolder params, IMemoryRenderingSite memRendSite) {
final String[] addrsOrExprs = (params instanceof AddressAndSpaceHolder) ? ((AddressAndSpaceHolder) params).addresses
: ((ExpressionsHolder) params).expressions;
for (int i = 0; i < addrsOrExprs.length; i++) {
String addrOrExpr = addrsOrExprs[i].trim();
try {
// get extended memory block with the expression or address
// entered
IMemoryBlockExtension memBlock;
if (params instanceof AddressAndSpaceHolder)
memBlock = memRetrieval.getMemoryBlockWithMemorySpaceID(
addrOrExpr,
((AddressAndSpaceHolder) params).memorySpace,
debugViewElement);
else
memBlock = memRetrieval.getExtendedMemoryBlock(addrOrExpr,
debugViewElement);
// add block to memory block manager
if (memBlock != null) {
IMemoryBlock[] memArray = new IMemoryBlock[] { memBlock };
DebugPlugin.getDefault().getMemoryBlockManager().addMemoryBlocks(memArray);
addDefaultRenderings(memBlock, memRendSite);
} else {
// open error if it failed to retrieve a memory block
openError(Messages.AddMemBlocks_title,
Messages.AddMemBlocks_noMemoryBlock,
null);
}
} catch (DebugException e1) {
openError(Messages.AddMemBlocks_title,
Messages.AddMemBlocks_failed, e1);
} catch (NumberFormatException e2) {
String message = Messages.AddMemBlocks_failed + "\n" + Messages.AddMemBlocks_input_invalid; //$NON-NLS-1$
openError(Messages.AddMemBlocks_title, message,
null);
}
}
}
private void addDefaultRenderings(IMemoryBlock memoryBlock,
IMemoryRenderingSite memRendSite) {
// This method was mostly lifted from the platform's AddMemoryBlockAction
IMemoryRenderingType primaryType = DebugUITools.getMemoryRenderingManager().getPrimaryRenderingType(
memoryBlock);
IMemoryRenderingType renderingTypes[] = DebugUITools.getMemoryRenderingManager().getDefaultRenderingTypes(
memoryBlock);
// create primary rendering
try {
if (primaryType != null) {
createRenderingInContainer(memoryBlock, memRendSite,
primaryType, IDebugUIConstants.ID_RENDERING_VIEW_PANE_1);
} else if (renderingTypes.length > 0) {
primaryType = renderingTypes[0];
createRenderingInContainer(memoryBlock, memRendSite,
renderingTypes[0],
IDebugUIConstants.ID_RENDERING_VIEW_PANE_1);
}
} catch (CoreException e1) {
CDebugUIPlugin.log(e1);
}
for (int i = 0; i < renderingTypes.length; i++) {
try {
boolean create = true;
if (primaryType != null) {
if (primaryType.getId().equals(renderingTypes[i].getId()))
create = false;
}
if (create)
createRenderingInContainer(memoryBlock, memRendSite,
renderingTypes[i],
IDebugUIConstants.ID_RENDERING_VIEW_PANE_2);
} catch (CoreException e) {
CDebugUIPlugin.log(e);
}
}
}
private void createRenderingInContainer(IMemoryBlock memoryBlock,
IMemoryRenderingSite memRendSite, IMemoryRenderingType primaryType,
String paneId) throws CoreException {
// This method was mostly lifted from the platform's AddMemoryBlockAction
IMemoryRendering rendering = primaryType.createRendering();
IMemoryRenderingContainer container = memRendSite.getContainer(paneId);
rendering.init(container, memoryBlock);
container.addMemoryRendering(rendering);
}
/**
* Helper function to open an error dialog.
* @param title
* @param message
* @param e
*/
static public void openError (final String title, final String message, final Exception e)
{
UIJob uiJob = new UIJob("open error"){ //$NON-NLS-1$
public IStatus runInUIThread(IProgressMonitor monitor) {
// open error for the exception
String detail = ""; //$NON-NLS-1$
if (e != null)
detail = e.getMessage();
Shell shell = CDebugUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell();
MessageDialog.openError(
shell,
title,
message + "\n" + detail); //$NON-NLS-1$
return Status.OK_STATUS;
}};
uiJob.setSystem(true);
uiJob.schedule();
}
}

View file

@ -0,0 +1,100 @@
/*******************************************************************************
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - initial API and implementation
*
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.memory;
import org.eclipse.cdt.debug.internal.core.model.CMemoryBlockExtension;
import org.eclipse.jface.viewers.ILabelDecorator;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;
/**
* Modifies the label shown in a rendering tab of the memory view.
*
* <p> CDT adapter logic will link us to a CMemoryBlockExtension if and
* only if that block was created by specifying a memory space. In that
* case, a literal address and memory space identifier are the basis for
* the memory monitor, and the default label provided by the platform:
* <PRE> expression : address &lt;rendering-name&gt; </PRE>
* isn't well suited. Our job is to reduce this to
* <pre> expression &lt;rendering-name&gt; </PRE>
* The expression ends up being the back-end provided string encoding of
* a memory space + address pair.
* <p>
* @since 3.2
*/
public class MemoryBlockLabelDecorator implements ILabelDecorator {
/**
* The memory block we decorate the label for
*/
private CMemoryBlockExtension fMemoryBlock;
/**
* Constructor
* @param memoryBlock the memory block we decorate the label for
*/
public MemoryBlockLabelDecorator(CMemoryBlockExtension memoryBlock) {
super();
fMemoryBlock = memoryBlock;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ILabelDecorator#decorateImage(org.eclipse.swt.graphics.Image, java.lang.Object)
*/
public Image decorateImage(Image image, Object element) {
// we only decorate the text
return null;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.ILabelDecorator#decorateText(java.lang.String, java.lang.Object)
*/
public String decorateText(String text, Object element) {
// The rendering name is enclosed in <>. We replace everything before
// that with the memory block's expression.
int i = text.indexOf('<');
if (i >= 0)
return fMemoryBlock.getExpression() + " " + text.substring(i);
return text;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
*/
public void addListener(ILabelProviderListener listener) {
// how we decorate labels is not affected by any state
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
*/
public void dispose() {
// nothing to clean up
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
*/
public boolean isLabelProperty(Object element, String property) {
// how we decorate a label is not affected by any properties
return false;
}
/* (non-Javadoc)
* @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
*/
public void removeListener(ILabelProviderListener listener) {
// how we decorate labels is not affected by any state
}
}

View file

@ -0,0 +1,36 @@
/*******************************************************************************
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Freescale Semiconductor - initial API and implementation
*
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.memory;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = Messages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
public static String AddMemBlockDlg_enterMemSpaceAndAddr;
public static String AddMemBlockDlg_enterExpression;
public static String AddMemBlockDlg_or;
public static String AddMemBlockDlg_MonitorMemory;
public static String AddMemBlocks_title;
public static String AddMemBlocks_noMemoryBlock;
public static String AddMemBlocks_failed;
public static String AddMemBlocks_input_invalid;
}

View file

@ -0,0 +1,10 @@
AddMemBlockDlg_enterMemSpaceAndAddr=Enter memory space and address
AddMemBlockDlg_enterExpression=Enter expression
AddMemBlockDlg_or=or
AddMemBlockDlg_MonitorMemory = Monitor Memory
AddMemBlocks_title=Add Memory Monitor
AddMemBlocks_noMemoryBlock = Failed to get memory monitor.
AddMemBlocks_failed =Add Memory Monitor Failed.
AddMemBlocks_input_invalid = Input is invalid.

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.debug.internal.ui.ColorManager;
import org.eclipse.cdt.debug.internal.ui.EvaluationContextManager; import org.eclipse.cdt.debug.internal.ui.EvaluationContextManager;
import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants;
import org.eclipse.cdt.debug.internal.ui.elements.adapters.CDebugElementAdapterFactory; import org.eclipse.cdt.debug.internal.ui.elements.adapters.CDebugElementAdapterFactory;
import org.eclipse.cdt.debug.internal.ui.elements.adapters.CMemoryAdapterFactory;
import org.eclipse.cdt.debug.ui.sourcelookup.DefaultSourceLocator; import org.eclipse.cdt.debug.ui.sourcelookup.DefaultSourceLocator;
import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator; import org.eclipse.cdt.debug.ui.sourcelookup.OldDefaultSourceLocator;
import org.eclipse.cdt.internal.ui.editor.SharedTextColors; import org.eclipse.cdt.internal.ui.editor.SharedTextColors;
@ -36,6 +37,8 @@ import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.model.IMemoryBlockExtension;
import org.eclipse.debug.core.model.IMemoryBlockRetrievalExtension;
import org.eclipse.debug.core.model.IPersistableSourceLocator; import org.eclipse.debug.core.model.IPersistableSourceLocator;
import org.eclipse.debug.ui.ILaunchConfigurationTab; import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.ErrorDialog;
@ -274,6 +277,10 @@ public class CDebugUIPlugin extends AbstractUIPlugin {
manager.registerAdapters( elementAdapterFactory, IModuleRetrieval.class ); manager.registerAdapters( elementAdapterFactory, IModuleRetrieval.class );
manager.registerAdapters( elementAdapterFactory, ICModule.class ); manager.registerAdapters( elementAdapterFactory, ICModule.class );
manager.registerAdapters( elementAdapterFactory, ICElement.class ); manager.registerAdapters( elementAdapterFactory, ICElement.class );
CMemoryAdapterFactory memoryAdapterFactory = new CMemoryAdapterFactory();
manager.registerAdapters( memoryAdapterFactory, IMemoryBlockRetrievalExtension.class );
manager.registerAdapters( memoryAdapterFactory, IMemoryBlockExtension.class );
} }
/* /*