Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [cdt-debug-dev] Displaying values of custom data types

Matthias,

Looks good to me. The only thing I don't like is "value type", it is confusing because we have ICDIValue which has different meaning. But I can't come up with a better name right now. My other thought is, this is a common problem and we should provide a common solution to contribute new types. But this is in the future (not so distant, I hope). One more question. This patch is large enough to raise a legal issue. Do you have a permission from your management to submit it?

Thanks,
Mikhail
----- Original Message ----- From: "Matthias Spycher" <matthias@xxxxxxxxxx>
To: <cdt-debug-dev@xxxxxxxxxxx>
Sent: Wednesday, February 01, 2006 1:19 PM
Subject: Re: [cdt-debug-dev] Displaying values of custom data types


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



Back to the top