Mikhail,
Letting the back-end take care of formatting would be the most flexible
solution, no doubt.
I have made the following (minor) changes to the CDT to experiment with
big integer values. This works quite well so far.
I introduced a new marker interface:
package org.eclipse.cdt.debug.core.cdi.model.type;
/**
* Represents a value type. This interface may be implemented by
* aggregate (struct) types that can be converted to a simple value.
* For example, a big integer struct that implements this interface
* might produce instances of ICDIIntegralValue which can be formatted
* and displayed directly in the debugger's variables view.
*/
public interface ICDIValueType { }
The ICType interface and CType implementation have been extended with the
isValueType() method:
/**
* Returns whether this is a value type. Integral types, floating point
numbers
* and pointers are value types. But certain aggregates may be regarded
as
* value types also.
*
* @return whether this is a value type
*/
boolean isValueType();
In the mi.core.cdi.model.type package I have a subclass of StructType that
implements ICDIValueType, let's call it BigIntType. I have also tagged
ICDIFloatingPointType, ICDIIntegralType and ICDIPointerType with
ICDIValueType. For BigIntType I added a corresponding value called
BigIntValue (subclass of StructValue) which implements ICDIIntegralValue.
A simple change to CDebugModelPresentation.getValueText(IValue) in the
first else clause below:
protected String getValueText( IValue value ) {
....
String valueString = value.getValueString();
if ( valueString != null ) {
valueString = valueString.trim();
if ( type != null && type.isCharacter()) {
if ( valueString.length() == 0 )
valueString = "."; //$NON-NLS-1$
label.append( valueString );
}
else if ( type != null && type.isValueType())
{ // Check for value types here (might even be a struct)
if (type.isFloatingPointType() ) {
Number floatingPointValue =
CDebugUtils.getFloatingPointValue( (ICValue)value );
if ( CDebugUtils.isNaN( floatingPointValue ) )
valueString = "NAN"; //$NON-NLS-1$
if ( CDebugUtils.isPositiveInfinity(
floatingPointValue ) )
valueString = CDebugUIMessages.getString(
"CDTDebugModelPresentation.23" ); //$NON-NLS-1$
if ( CDebugUtils.isNegativeInfinity(
floatingPointValue ) )
valueString = CDebugUIMessages.getString(
"CDTDebugModelPresentation.24" ); //$NON-NLS-1$
label.append( valueString );
}
else if ( valueString.length() > 0 ) {
label.append( valueString );
// Conversion of aggregate value to string here
}
}
else if ( type == null || (!type.isArray() &&
!type.isStructure()) ) { // Eliminates values for non-value-type
aggregates
if ( valueString.length() > 0 ) {
label.append( valueString );
}
}
}
...
and a minor extension to CValue.processUnderlyingValue(ICDIValue) takes
care of the rest:
private String processUnderlyingValue( ICDIValue cdiValue ) throws
CDIException {
if ( cdiValue != null ) {
if ( cdiValue instanceof ICDIIntegralValue )
{ // Separate integral and floating point values
from others
if ( cdiValue instanceof ICDICharValue )
return getCharValueString( (ICDICharValue)cdiValue );
else if ( cdiValue instanceof ICDIShortValue )
return getShortValueString( (ICDIShortValue)cdiValue );
else if ( cdiValue instanceof ICDIIntValue )
return getIntValueString( (ICDIIntValue)cdiValue );
else if ( cdiValue instanceof ICDILongValue )
return getLongValueString( (ICDILongValue)cdiValue );
else if ( cdiValue instanceof ICDILongLongValue )
return getLongLongValueString(
(ICDILongLongValue)cdiValue );
else if ( cdiValue instanceof ICDIWCharValue )
return getWCharValueString( (ICDIWCharValue)cdiValue );
else
return getIntegralValueString(
(ICDIIntegralValue)cdiValue ); // New method here for other integral
values
} else if (cdiValue instanceof ICDIFloatingPointValue) {
if ( cdiValue instanceof ICDIFloatValue )
return getFloatValueString( (ICDIFloatValue)cdiValue );
else if ( cdiValue instanceof ICDIDoubleValue )
return getDoubleValueString(
(ICDIDoubleValue)cdiValue );
else
return cdiValue.getValueString();
// Could have a special method here for other floating point values
} else if ( cdiValue instanceof ICDIPointerValue )
return getPointerValueString( (ICDIPointerValue)cdiValue );
else if ( cdiValue instanceof ICDIReferenceValue )
return
processUnderlyingValue(((ICDIReferenceValue)cdiValue).referenceValue());
else
return cdiValue.getValueString();
}
return null;
}
...
private String getIntegralValueString( ICDIIntegralValue value ) throws
CDIException {
try {
CVariableFormat format = getParentVariable().getFormat();
if ( CVariableFormat.NATURAL.equals( format ) ||
CVariableFormat.DECIMAL.equals( format ) ) {
return value.bigIntegerValue().toString();
}
else if ( CVariableFormat.HEXADECIMAL.equals( format ) ) {
StringBuffer sb = new StringBuffer( "0x" ); //$NON-NLS-1$
sb.append( value.bigIntegerValue().toString( 16 ) );
return sb.toString();
}
}
catch( NumberFormatException e ) {
}
return null;
}
...
So subclasses of StructType that implement ICDIValueType, and whose
corresponding values implement ICDIIntegralValue or ICDIFloatingPointValue
will have a label in the variables view that includes a simple numeric
value which may be formatted as well. Note that the hieararchical nature
of the struct value is not eliminated, users can still expand the tree and
examine each field's value in the variables view.
In our case ICDIIntegralValue and ICDIFloatingPointValue are sufficient,
although the latter could include a bigDecimalValue() for consistency. The
backend debugger, which in our case provides a superset of gdb
functionality, replaces the struct's string value which gdb produces into
a simple numeric value.
Hope this makes sense.
Matthias
_______________________________________________
cdt-debug-dev mailing list
cdt-debug-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/cdt-debug-dev