Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java16
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDTLaunchConfigurationConstants.java6
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/CVariableFormat.java44
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CSettingsManager.java267
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java20
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CExpression.java1
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CRegister.java2
-rw-r--r--debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java187
8 files changed, 522 insertions, 21 deletions
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java
index 19840592824..0338a2376d8 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java
@@ -209,20 +209,32 @@ public class CDebugUtils {
* Serializes a XML document into a string - encoded in UTF8 format, with platform line separators.
*
* @param doc document to serialize
+ * @param indent if the xml text should be indented.
+ *
* @return the document as a string
*/
- public static String serializeDocument( Document doc ) throws IOException, TransformerException {
+ public static String serializeDocument( Document doc, boolean indent ) throws IOException, TransformerException {
ByteArrayOutputStream s = new ByteArrayOutputStream();
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty( OutputKeys.METHOD, "xml" ); //$NON-NLS-1$
- transformer.setOutputProperty( OutputKeys.INDENT, "yes" ); //$NON-NLS-1$
+ transformer.setOutputProperty( OutputKeys.INDENT, indent ? "yes" : "no" ); //$NON-NLS-1$
DOMSource source = new DOMSource( doc );
StreamResult outputTarget = new StreamResult( s );
transformer.transform( source, outputTarget );
return s.toString( "UTF8" ); //$NON-NLS-1$
}
+ /**
+ * Serializes a XML document into a string - encoded in UTF8 format, with platform line separators.
+ *
+ * @param doc document to serialize
+ * @return the document as a string
+ */
+ public static String serializeDocument( Document doc ) throws IOException, TransformerException {
+ return serializeDocument(doc, true);
+ }
+
public static Number getFloatingPointValue( ICValue value ) {
if ( value instanceof CFloatingPointValue ) {
try {
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDTLaunchConfigurationConstants.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDTLaunchConfigurationConstants.java
index d75f9160a80..c7b5de6b93b 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDTLaunchConfigurationConstants.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/ICDTLaunchConfigurationConstants.java
@@ -174,6 +174,12 @@ public interface ICDTLaunchConfigurationConstants {
* memento.
*/
public static final String ATTR_DEBUGGER_GLOBAL_VARIABLES = CDT_LAUNCH_ID + ".GLOBAL_VARIABLES"; //$NON-NLS-1$
+
+ /**
+ * Launch configuration attribute key. The value is a format list'
+ * memento.
+ */
+ public static final String ATTR_DEBUGGER_FORMAT = CDT_LAUNCH_ID + ".FORMAT"; //$NON-NLS-1$
/**
* Launch configuration attribute key. The value is a memory blocks' memento.
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/CVariableFormat.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/CVariableFormat.java
index 553ea295687..12f8dc7d592 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/CVariableFormat.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/CVariableFormat.java
@@ -16,35 +16,41 @@ package org.eclipse.cdt.debug.core.model;
public class CVariableFormat {
private final String fName;
+ private final int fNum;
- private CVariableFormat( String name ) {
+ private CVariableFormat( String name, int num ) {
this.fName = name;
+ this.fNum= num;
}
public String toString() {
return this.fName;
}
+
+ public int getFormatNumber() {
+ return this.fNum;
+ }
public static CVariableFormat getFormat( int code ) {
- switch( code ) {
- case 0:
- return NATURAL;
- case 1:
- return DECIMAL;
- case 2:
- return BINARY;
- case 3:
- return OCTAL;
- case 4:
- return HEXADECIMAL;
- default:
- return NATURAL;
+ if ( code == NATURAL.getFormatNumber() ) {
+ return NATURAL;
+ } else if ( code == DECIMAL.getFormatNumber() ) {
+ return DECIMAL;
+ } else if ( code == BINARY.getFormatNumber() ) {
+ return BINARY;
+ } else if ( code == OCTAL.getFormatNumber() ) {
+ return OCTAL;
+ } else if ( code == HEXADECIMAL.getFormatNumber() ) {
+ return HEXADECIMAL;
+ } else {
+ // unexpected value, mapping to NATURAL
+ return NATURAL;
}
}
- public static final CVariableFormat NATURAL = new CVariableFormat( "natural" ); //$NON-NLS-1$
- public static final CVariableFormat DECIMAL = new CVariableFormat( "decimal" ); //$NON-NLS-1$
- public static final CVariableFormat BINARY = new CVariableFormat( "binary" ); //$NON-NLS-1$
- public static final CVariableFormat OCTAL = new CVariableFormat( "octal" ); //$NON-NLS-1$
- public static final CVariableFormat HEXADECIMAL = new CVariableFormat( "hexadecimal" ); //$NON-NLS-1$
+ public static final CVariableFormat NATURAL = new CVariableFormat( "natural", 0 ); //$NON-NLS-1$
+ public static final CVariableFormat DECIMAL = new CVariableFormat( "decimal", 1 ); //$NON-NLS-1$
+ public static final CVariableFormat BINARY = new CVariableFormat( "binary", 2 ); //$NON-NLS-1$
+ public static final CVariableFormat OCTAL = new CVariableFormat( "octal", 3 ); //$NON-NLS-1$
+ public static final CVariableFormat HEXADECIMAL = new CVariableFormat( "hexadecimal", 4 ); //$NON-NLS-1$
}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CSettingsManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CSettingsManager.java
new file mode 100644
index 00000000000..96ee541ef12
--- /dev/null
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CSettingsManager.java
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Freescale Semiconductor 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:
+ * Freescale Semiconductor - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.debug.internal.core;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+
+import org.eclipse.cdt.debug.core.CDebugUtils;
+import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
+import org.eclipse.cdt.debug.internal.core.model.CDebugTarget;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunchConfiguration;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Settings manager
+ *
+ * The settings manager stores a set of settings,
+ * (key/value) pairs in the launch configuration so they exist across debug sessions.
+ *
+ * All active settings are stored together in a single configuration entry
+ * (ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_FORMAT).
+ *
+ * Every setting is identified by a string identifier. That string identifier can be used to
+ * store an additional setting, to remove an exiting one or to retrieve a previously stored setting.
+ *
+ * The setting value consists of a String.
+ *
+ * Settings fade out automatically so clients do not necessarily need to delete old settings. This makes it
+ * possible to build the string identifiers with names out of the user application, like function names or
+ * variable names, without the danger of a constantly growing launch configuration.
+ * However it also causes that the settings manager must only be used for configurations and customizations for which
+ * always reasonable defaults exist.
+ *
+ * As cleanup policy the settings manager only keeps a certain number of settings and drops the
+ * least recently used one when more settings are added. The least recently used order is maintained
+ * across debug sessions.
+ *
+ */
+
+public class CSettingsManager {
+
+ /**
+ * the name of the XML node for the list
+ */
+ private static final String CONTENT_LIST = "contentList"; //$NON-NLS-1$
+
+ /**
+ * the name of the XML node for every format entry
+ */
+ private static final String CONTENT = "content"; //$NON-NLS-1$
+
+ /**
+ * the attribute name used to identify the object to store the content for.
+ */
+ private static final String ATTR_CONTENT_ID = "id"; //$NON-NLS-1$
+
+ /**
+ * the attribute name of the actual content
+ */
+ private static final String ATTR_CONTENT_VALUE = "val"; //$NON-NLS-1$
+
+ /**
+ * Number defining how many settings are stored.
+ * Whenever an additional setting is added when there are already MAX_USED_COUNT settings, the
+ * least recently used setting is dropped.
+ *
+ * The actual value is chosen to be high enough for normal use cases, but still low enough to avoid that the launch configuration
+ * gets arbitrarily large
+ */
+ private static int MAX_ELEMENT_COUNT = 100;
+
+ /**
+ * the map used to actually store the format information
+ * as key String are used, values are of type String too.
+ *
+ * The map automatically is limited to MAX_ELEMENT_COUNT
+ * elements, dropping the least recently used one
+ * when more elements are added.
+ */
+ private Map fContentMap = new LinkedHashMap(MAX_ELEMENT_COUNT, 0.75f, true) {
+ private static final long serialVersionUID = 1;
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return size() > MAX_ELEMENT_COUNT;
+ }
+ };
+
+ /**
+ * the debug target we store the values for
+ */
+ private CDebugTarget fDebugTarget;
+
+ /**
+ * Store the value for the given id.
+ * @param id used to identify the information. Different objects/topics should use different identifiers.
+ * @param value content to be stored
+ */
+ public synchronized void putValue( String id, String value ) {
+ fContentMap.put(id, value);
+ }
+ /**
+ * remove the stored format for the given id.
+ * @param id used to identify the formatting information. Different objects/topics should use different identifiers.
+ */
+ public synchronized void removeValue( String id ) {
+ fContentMap.remove( id );
+ }
+
+ /** Retrieve the value for the given id.
+ * @param id used to identify the formatting information. Different objects/topics should use different identifiers.
+ * @return returns the entry information for the given id, or null if no such information is available.
+ */
+ public synchronized String getValue( String id ) {
+ String entry= (String) fContentMap.get( id );
+ return entry;
+ }
+
+ /** constructor.
+ * @param debugTarget
+ */
+ public CSettingsManager( CDebugTarget debugTarget ) {
+ fDebugTarget = debugTarget;
+ initialize();
+ }
+
+ /** get the string format of the current content.
+ * Only stores entries which have been used in the last MAX_USED_COUNT debug sessions.
+ * @return
+ */
+ private String getMemento() {
+ Document document = null;
+ try {
+ document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ Element node = document.createElement( CONTENT_LIST );
+ document.appendChild( node );
+ Set entrySet = fContentMap.entrySet();
+ Iterator it = entrySet.iterator();
+ while ( it.hasNext() ) {
+ Map.Entry entry= (Map.Entry) it.next();
+ String id= (String)entry.getKey();
+ String value= (String)entry.getValue();
+ Element child = document.createElement( CONTENT );
+ child.setAttribute( ATTR_CONTENT_ID, id );
+ child.setAttribute( ATTR_CONTENT_VALUE, value );
+ node.appendChild( child );
+ }
+ return CDebugUtils.serializeDocument( document, false );
+ }
+ catch( ParserConfigurationException e ) {
+ DebugPlugin.log( e );
+ }
+ catch( IOException e ) {
+ DebugPlugin.log( e );
+ }
+ catch( TransformerException e ) {
+ DebugPlugin.log( e );
+ }
+ return null;
+ }
+
+ /** set the current state to the one given by the memento.
+ * @param memento a string representation of the state to be loaded.
+ * @throws CoreException
+ */
+ private void initializeFromMemento( String memento ) throws CoreException {
+ try {
+ fContentMap.clear();
+ DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ StringReader reader = new StringReader( memento );
+ InputSource source = new InputSource( reader );
+ Element root = parser.parse( source ).getDocumentElement();
+ if ( root.getNodeName().equalsIgnoreCase( CONTENT_LIST ) ) {
+ NodeList list = root.getChildNodes();
+ int i = list.getLength() - 1; // backwards to keep least recent access order.
+ for( ; i >= 0; i-- ) {
+ Node node = list.item( i );
+ short type = node.getNodeType();
+ if ( type == Node.ELEMENT_NODE ) {
+ Element elem = (Element)node;
+ if ( elem.getNodeName().equalsIgnoreCase( CONTENT ) ) {
+ String id = elem.getAttribute( ATTR_CONTENT_ID );
+ String value= elem.getAttribute( ATTR_CONTENT_VALUE );
+ if ( id == null || id.length() == 0 ) {
+ DebugPlugin.logMessage( "unexpected entry in CSettingsManager.initializeFromMemento", null ); //$NON-NLS-1$
+ continue;
+ }
+ putValue( id, value );
+ }
+ }
+ }
+ return;
+ }
+ DebugPlugin.logMessage( "unexpected content", null ); //$NON-NLS-1$
+ }
+ catch( ParserConfigurationException e ) {
+ DebugPlugin.log( e );
+ }
+ catch( SAXException e ) {
+ DebugPlugin.log( e );
+ }
+ catch( IOException e ) {
+ DebugPlugin.log( e );
+ }
+ }
+
+ /**
+ * read the stored format from the launch configuration
+ */
+ private void initialize() {
+ ILaunchConfiguration config = getDebugTarget().getLaunch().getLaunchConfiguration();
+ try {
+ String memento = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_FORMAT, "" ); //$NON-NLS-1$
+ if ( memento != null && memento.trim().length() != 0 )
+ initializeFromMemento( memento );
+ }
+ catch( CoreException e ) {
+ DebugPlugin.log( e );
+ }
+ }
+
+ /**
+ * store the current content in the launch configuration.
+ */
+ public synchronized void save() {
+ ILaunchConfiguration config = getDebugTarget().getLaunch().getLaunchConfiguration();
+ try {
+ ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
+ wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_FORMAT, getMemento() );
+ wc.doSave();
+ }
+ catch( CoreException e ) {
+ DebugPlugin.log( e );
+ }
+ }
+
+ /**
+ * accessor to the debug target
+ */
+ IDebugTarget getDebugTarget() {
+ return fDebugTarget;
+ }
+}
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java
index 81ad1d14d6a..5ba6634c0a1 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CDebugTarget.java
@@ -85,6 +85,7 @@ import org.eclipse.cdt.debug.core.model.IRegisterDescriptor;
import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator;
import org.eclipse.cdt.debug.core.sourcelookup.ISourceLookupChangeListener;
import org.eclipse.cdt.debug.internal.core.CBreakpointManager;
+import org.eclipse.cdt.debug.internal.core.CSettingsManager;
import org.eclipse.cdt.debug.internal.core.CGlobalVariableManager;
import org.eclipse.cdt.debug.internal.core.CMemoryBlockRetrievalExtension;
import org.eclipse.cdt.debug.internal.core.CRegisterManager;
@@ -198,6 +199,11 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
private CGlobalVariableManager fGlobalVariableManager;
/**
+ * container for Default format information
+ */
+ private CSettingsManager fFormatManager;
+
+ /**
* The executable binary file associated with this target.
*/
private IBinaryObject fBinaryFile;
@@ -256,6 +262,7 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
setRegisterManager( new CRegisterManager( this ) );
setBreakpointManager( new CBreakpointManager( this ) );
setGlobalVariableManager( new CGlobalVariableManager( this ) );
+ setFormatManager( new CSettingsManager( this ) );
setMemoryBlockRetrieval( new CMemoryBlockRetrievalExtension( this ) );
initialize();
DebugPlugin.getDefault().getLaunchManager().addLaunchListener( this );
@@ -997,6 +1004,7 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
getCDISession().getEventManager().removeEventListener( this );
DebugPlugin.getDefault().getExpressionManager().removeExpressionListener( this );
DebugPlugin.getDefault().getLaunchManager().removeLaunchListener( this );
+ saveFormats();
saveGlobalVariables();
disposeGlobalVariableManager();
disposeModuleManager();
@@ -1436,6 +1444,10 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
fGlobalVariableManager.save();
}
+ protected void saveFormats() {
+ fFormatManager.save();
+ }
+
protected void disposeGlobalVariableManager() {
fGlobalVariableManager.dispose();
}
@@ -1635,6 +1647,14 @@ public class CDebugTarget extends CDebugElement implements ICDebugTarget, ICDIEv
fGlobalVariableManager = globalVariableManager;
}
+ protected CSettingsManager getFormatManager() {
+ return fFormatManager;
+ }
+
+ private void setFormatManager( CSettingsManager formatManager ) {
+ fFormatManager = formatManager;
+ }
+
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.model.ICDebugTarget#isPostMortem()
*/
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CExpression.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CExpression.java
index 4df54a7cdea..a13fc022f4f 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CExpression.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CExpression.java
@@ -55,6 +55,7 @@ public class CExpression extends CLocalVariable implements IExpression {
fText = cdiExpression.getExpressionText();
fCDIExpression = cdiExpression;
fStackFrame = frame;
+ setInitialFormat();
}
/* (non-Javadoc)
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CRegister.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CRegister.java
index 856493c6c74..a9a12036865 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CRegister.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CRegister.java
@@ -326,6 +326,7 @@ public class CRegister extends CVariable implements ICRegister {
protected CRegister( CRegisterGroup parent, IRegisterDescriptor descriptor ) {
super( parent, ((CRegisterDescriptor)descriptor).getCDIDescriptor() );
setFormat( CVariableFormat.getFormat( CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_DEFAULT_REGISTER_FORMAT ) ) );
+ setInitialFormat();
}
/**
@@ -334,6 +335,7 @@ public class CRegister extends CVariable implements ICRegister {
protected CRegister( CRegisterGroup parent, IRegisterDescriptor descriptor, String message ) {
super( parent, ((CRegisterDescriptor)descriptor).getCDIDescriptor(), message );
setFormat( CVariableFormat.getFormat( CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_DEFAULT_REGISTER_FORMAT ) ) );
+ setInitialFormat();
}
/* (non-Javadoc)
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java
index 4c1ab6f4fd0..6f72d51ee1b 100644
--- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java
+++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java
@@ -11,6 +11,7 @@
package org.eclipse.cdt.debug.internal.core.model;
import java.text.MessageFormat;
+
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.ICDebugConstants;
@@ -30,9 +31,11 @@ import org.eclipse.cdt.debug.core.model.CVariableFormat;
import org.eclipse.cdt.debug.core.model.ICDebugElementStatus;
import org.eclipse.cdt.debug.core.model.ICType;
import org.eclipse.cdt.debug.core.model.ICValue;
+import org.eclipse.cdt.debug.internal.core.CSettingsManager;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IValue;
/**
@@ -101,6 +104,7 @@ public abstract class CVariable extends AbstractCVariable implements ICDIEventLi
}
fIsEnabled = ( parent instanceof AbstractCValue ) ? ((AbstractCValue)parent).getParentVariable().isEnabled() : !isBookkeepingEnabled();
getCDISession().getEventManager().addEventListener( this );
+ setInitialFormat();
}
/**
@@ -115,6 +119,7 @@ public abstract class CVariable extends AbstractCVariable implements ICDIEventLi
fIsEnabled = !isBookkeepingEnabled();
setStatus( ICDebugElementStatus.ERROR, MessageFormat.format( CoreModelMessages.getString( "CVariable.1" ), new String[]{ errorMessage } ) ); //$NON-NLS-1$
getCDISession().getEventManager().addEventListener( this );
+ setInitialFormat();
}
/*
@@ -262,6 +267,7 @@ public abstract class CVariable extends AbstractCVariable implements ICDIEventLi
*/
public void changeFormat( CVariableFormat format ) throws DebugException {
setFormat( format );
+ storeFormat( format );
resetValue();
}
@@ -297,6 +303,7 @@ public abstract class CVariable extends AbstractCVariable implements ICDIEventLi
// If casting of variable to a type or array causes an error, the status
// of the variable is set to "error" and it can't be reset by subsequent castings.
resetValue();
+ storeCastToArray( startIndex, length );
}
}
@@ -393,6 +400,7 @@ public abstract class CVariable extends AbstractCVariable implements ICDIEventLi
// If casting of variable to a type or array causes an error, the status
// of the variable is set to "error" and it can't be reset by subsequent castings.
resetValue();
+ storeCast(type);
}
}
@@ -412,6 +420,8 @@ public abstract class CVariable extends AbstractCVariable implements ICDIEventLi
// If casting of variable to a type or array causes an error, the status
// of the variable is set to "error" and it can't be reset by subsequent castings.
resetValue();
+ forgetCast();
+ forgetCastToArray();
}
/*
@@ -621,4 +631,181 @@ public abstract class CVariable extends AbstractCVariable implements ICDIEventLi
protected void setName( String name ) {
fName = name;
}
+
+ protected CSettingsManager getFormatManager() {
+ return ((CDebugTarget) getDebugTarget()).getFormatManager();
+ }
+
+ /**
+ * used to concatenate multiple names to a single identifier
+ */
+ private final static String NAME_PART_SEPARATOR = "-"; //$NON-NLS-1$
+
+ /**
+ * suffix used to identify format informations
+ */
+ private final static String FORMAT_SUFFIX = NAME_PART_SEPARATOR + "(format)"; //$NON-NLS-1$
+
+ /**
+ * suffix used to identify cast settings
+ */
+ private final static String CAST_SUFFIX = NAME_PART_SEPARATOR + "(cast)"; //$NON-NLS-1$
+
+ /**
+ * suffix used to identify cast to array settings
+ */
+ private final static String CAST_TO_ARRAY_SUFFIX = NAME_PART_SEPARATOR + "(cast_to_array)";
+
+ /** retrieve the identification for this variable.
+ * @return a string identifying this variable, to be used to store settings
+ * @throws DebugException
+ */
+ String getVariableID() throws DebugException {
+ return getName(); // TODO: better identification if multiple variables have the same name
+ }
+
+ /** helper to generate a string id used to persist the settings.
+ * @param next_obj next object to encode into the id
+ * @param buf contains the id of the part encoded so far.
+ * @throws DebugException
+ */
+ static private void buildPesistID( CDebugElement next_obj, StringBuffer buf ) throws DebugException {
+ if ( next_obj instanceof CVariable ) {
+ CVariable cVariableParent = (CVariable) next_obj;
+ buf.append( NAME_PART_SEPARATOR );
+ buf.append( cVariableParent.getVariableID() );
+ buildPesistID( cVariableParent.getParent(), buf );
+ } else if ( next_obj instanceof CStackFrame ) {
+ buf.append(NAME_PART_SEPARATOR);
+ // TODO: better identification if multiple functions have the same name (say for static functions)
+ buf.append( ((CStackFrame)next_obj ).getFunction() );
+ } else if ( next_obj instanceof CDebugTarget ) {
+ // global, we use a root NAME_PART_SEPARATOR as indicator of that
+ buf.append( NAME_PART_SEPARATOR );
+ } else if ( next_obj instanceof AbstractCValue ) {
+ // index or indirection.
+ AbstractCValue av = (AbstractCValue) next_obj;
+ buildPesistID( av.getParentVariable(), buf );
+ }
+ }
+
+ /** returns an string used to identify this variable
+ * @return
+ * @throws DebugException
+ */
+ private final String getPersistID() throws DebugException {
+ StringBuffer id = new StringBuffer();
+ id.append( getVariableID() );
+ buildPesistID( getParent(), id );
+ return id.toString();
+ }
+
+ /** stores the given format
+ * @param format the format to be used for this variable
+ */
+ protected void storeFormat( CVariableFormat format ) {
+ try {
+ String formatString = Integer.toString( format.getFormatNumber() );
+
+ getFormatManager().putValue( getPersistID() + FORMAT_SUFFIX, formatString );
+ } catch ( DebugException e ) {
+ // if we do not get the name, we use the default format, no reason for the creation to fail too.
+ DebugPlugin.log( e );
+ }
+ }
+
+ /** stores the cast information.
+ * @param type the type to be displayed instead
+ */
+ protected void storeCast( String type ) {
+ try {
+ String id = getPersistID() + CAST_SUFFIX;
+ getFormatManager().putValue( id, type );
+ } catch ( DebugException e ) {
+ DebugPlugin.log( e );
+ }
+ }
+
+ /** drops the cast information.
+ */
+ protected void forgetCast() {
+ try {
+ String id = getPersistID() + CAST_SUFFIX;
+ getFormatManager().removeValue( id );
+ } catch ( DebugException e ) {
+ DebugPlugin.log( e );
+ }
+ }
+
+ /** stores the cast array information.
+ * @param startIndex the first item to be displayed in the cast array operation
+ * @param length the number of elements to display
+ */
+ protected void storeCastToArray(int startIndex, int length) {
+ try {
+ // we persist the information in a (startIndex):(Length) format.
+ String content = Integer.toString( startIndex ) + ":" + Integer.toString( length ); //$NON-NLS-1$
+ getFormatManager().putValue( getPersistID() + CAST_TO_ARRAY_SUFFIX, content );
+ } catch ( DebugException e ) {
+ DebugPlugin.log( e );
+ }
+ }
+
+ /** drops previously stored cast array information.
+ */
+ protected void forgetCastToArray() {
+ try {
+ String id = getPersistID() + CAST_TO_ARRAY_SUFFIX;
+ getFormatManager().removeValue( id );
+ } catch ( DebugException e ) {
+ DebugPlugin.log( e );
+ }
+ }
+
+ /**
+ * restore the format stored previously for this variable.
+ * Only sets explictly retrieved formats in order to maintain defaults.
+ */
+ protected void setInitialFormat() {
+ try {
+ String persistID= getPersistID();
+ String stringFormat = getFormatManager().getValue( persistID + FORMAT_SUFFIX );
+ if ( stringFormat != null ) {
+ try {
+ CVariableFormat format = CVariableFormat.getFormat( Integer.parseInt( stringFormat ) );
+ setFormat( format );
+ } catch ( NumberFormatException e ) {
+ DebugPlugin.log( e );
+ }
+ }
+
+ if ( canCast() ) {
+ String castString = getFormatManager().getValue( persistID + CAST_SUFFIX );
+ if ( castString != null ) {
+ cast( castString );
+ }
+ }
+ if ( canCastToArray() ) {
+ String castToArrayString = getFormatManager().getValue( persistID + CAST_TO_ARRAY_SUFFIX );
+ if (castToArrayString != null) {
+ int index = castToArrayString.indexOf( ':' );
+ if ( index > 0 ) {
+ try {
+ int beg = Integer.parseInt( castToArrayString.substring( 0, index ) );
+ int num = Integer.parseInt( castToArrayString.substring( index + 1 ) );
+ castToArray( beg, num );
+ } catch ( NumberFormatException e ) {
+ DebugPlugin.log( e );
+ }
+ } else {
+ DebugPlugin.logMessage( "did not find expected : for cast to array", null ); //$NON-NLS-1$
+ }
+ }
+ }
+ } catch ( DebugException e ) {
+ DebugPlugin.log( e );
+ // we drop (and log) the exception here.
+ // even if the initial setup fails, we still want the complete creation to be successful
+ }
+ }
}

Back to the top