Added type/value handlers for C strings. This allow's the debugger's

variable view to actually render their contents rather than simply giving
the string's address.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39367 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent 2010-11-09 01:06:32 +00:00
parent b9767a83ed
commit 716f06ce58
14 changed files with 455 additions and 2 deletions

View File

@ -27,6 +27,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui util ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui value ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) util ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) value ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) value type_handlers ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) value value_handlers ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) value value_nodes ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) value values ] ;
@ -210,17 +211,22 @@ Application Debugger :
ValueNode.cpp
ValueNodeContainer.cpp
# value/type_handlers
CStringTypeHandler.cpp
# value/value_handlers
AddressValueHandler.cpp
BoolValueHandler.cpp
EnumerationValueHandler.cpp
FloatValueHandler.cpp
IntegerValueHandler.cpp
StringValueHandler.cpp
# value/value_nodes
AddressValueNode.cpp
ArrayValueNode.cpp
CompoundValueNode.cpp
CStringValueNode.cpp
EnumerationValueNode.cpp
PointerToMemberValueNode.cpp
PrimitiveValueNode.cpp
@ -232,6 +238,7 @@ Application Debugger :
EnumerationValue.cpp
FloatValue.cpp
IntegerValue.cpp
StringValue.cpp
:
<nogrist>Debugger_demangler.o

View File

@ -6,6 +6,8 @@
#include "TableCellStringRenderer.h"
#include <stdio.h>
#include <String.h>
#include "TableCellValueRendererUtils.h"
@ -16,9 +18,50 @@ void
TableCellStringRenderer::RenderValue(Value* value, BRect rect,
BView* targetView)
{
BString string;
if (!value->ToString(string))
BString string = "\"";
BString tempString;
if (!value->ToString(tempString))
return;
for (int32 i = 0; i < tempString.Length(); i++) {
if (tempString[i] < 31) {
switch (tempString[i]) {
case '\0':
string << "\\0";
break;
case '\a':
string << "\\a";
break;
case '\b':
string << "\\b";
break;
case '\t':
string << "\\t";
break;
case '\r':
string << "\\r";
break;
case '\n':
string << "\\n";
break;
case '\f':
string << "\\f";
break;
default:
{
char buffer[5];
snprintf(buffer, sizeof(buffer), "\\x%x",
tempString.String()[i]);
string << buffer;
break;
}
}
} else if (tempString[i] == '\"')
string << "\\\"";
else
string << tempString[i];
}
string += "\"";
TableCellValueRendererUtils::DrawString(targetView, rect, string,
B_ALIGN_LEFT, true);

View File

@ -14,6 +14,7 @@
#include "AddressValueNode.h"
#include "ArrayValueNode.h"
#include "CompoundValueNode.h"
#include "CStringTypeHandler.h"
#include "EnumerationValueNode.h"
#include "PointerToMemberValueNode.h"
#include "PrimitiveValueNode.h"
@ -140,6 +141,11 @@ TypeHandlerRoster::RegisterDefaultHandlers()
REGISTER_HANDLER(PointerToMember);
REGISTER_HANDLER(Primitive);
handler = new(std::nothrow) CStringTypeHandler();
handlerReference.SetTo(handler, true);
if (handler == NULL || !RegisterHandler(handler))
return B_NO_MEMORY;
return B_OK;
}

View File

@ -15,6 +15,7 @@
#include "BoolValueHandler.h"
#include "EnumerationValueHandler.h"
#include "FloatValueHandler.h"
#include "StringValueHandler.h"
#include "Value.h"
@ -106,6 +107,7 @@ ValueHandlerRoster::RegisterDefaultHandlers()
REGISTER_HANDLER(Enumeration)
REGISTER_HANDLER(Float)
REGISTER_HANDLER(Integer)
REGISTER_HANDLER(String)
return B_OK;
}

View File

@ -185,3 +185,14 @@ ValueLoader::LoadValue(ValueLocation* location, type_code valueType,
_value = value;
return B_OK;
}
status_t
ValueLoader::LoadStringValue(BVariant& location, type_code valueType,
BString& _value)
{
static const size_t kMaxStringSize = 255;
return fTeamMemory->ReadMemoryString(location.ToUInt64(), kMaxStringSize,
_value);
}

View File

@ -31,6 +31,10 @@ public:
type_code valueType, bool shortValueIsFine,
BVariant& _value);
status_t LoadStringValue(BVariant& location,
type_code valueType,
BString& _value);
private:
Architecture* fArchitecture;
TeamMemory* fTeamMemory;

View File

@ -0,0 +1,70 @@
/*
* Copyright 2010, Rene Gollent, rene@gollent.com
* Distributed under the terms of the MIT License.
*/
#include "CStringTypeHandler.h"
#include <new>
#include <stdio.h>
#include "CStringValueNode.h"
#include "Type.h"
CStringTypeHandler::~CStringTypeHandler()
{
}
float
CStringTypeHandler::SupportsType(Type* type)
{
AddressType* addressType = dynamic_cast<AddressType*>(type);
if (addressType != NULL && addressType->AddressKind()
== DERIVED_TYPE_POINTER) {
PrimitiveType* baseType = dynamic_cast<PrimitiveType*>(
addressType->BaseType());
if (baseType == NULL) {
ModifiedType* modifiedType = dynamic_cast<ModifiedType*>(
addressType->BaseType());
if (modifiedType == NULL)
return 0.0f;
baseType = dynamic_cast<PrimitiveType*>(
modifiedType->ResolveRawType(false));
if (baseType == NULL)
return 0.0f;
}
if (baseType->TypeConstant() == B_UINT8_TYPE
|| baseType->TypeConstant() == B_INT8_TYPE)
return 0.8f;
}
return 0.0f;
}
status_t
CStringTypeHandler::CreateValueNode(ValueNodeChild* nodeChild, Type* type,
ValueNode*& _node)
{
if (SupportsType(type) == 0.0f)
return B_BAD_VALUE;
AddressType* supportedType = dynamic_cast<AddressType*>(type);
ValueNode* node = new(std::nothrow) CStringValueNode(nodeChild,
supportedType);
if (node == NULL)
return B_NO_MEMORY;
_node = node;
return B_OK;
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2010, Rene Gollent, rene@gollent.com
* Distributed under the terms of the MIT License.
*/
#ifndef CSTRING_TYPE_HANDLER_H
#define CSTRING_TYPE_HANDLER_H
#include "TypeHandler.h"
class CStringTypeHandler : public TypeHandler {
public:
virtual ~CStringTypeHandler();
virtual float SupportsType(Type* type);
virtual status_t CreateValueNode(ValueNodeChild* nodeChild,
Type* type, ValueNode*& _node);
};
#endif // CSTRING_TYPE_HANDLER_H

View File

@ -0,0 +1,65 @@
/*
* Copyright 2010, Rene Gollent, rene@gollent.com
* Distributed under the terms of the MIT License.
*/
#include "StringValueHandler.h"
#include <new>
#include <stdio.h>
#include "StringValue.h"
#include "TableCellStringRenderer.h"
StringValueHandler::StringValueHandler()
{
}
StringValueHandler::~StringValueHandler()
{
}
status_t
StringValueHandler::Init()
{
return B_OK;
}
float
StringValueHandler::SupportsValue(Value* value)
{
return dynamic_cast<StringValue*>(value) != NULL ? 0.8f : 0;
}
status_t
StringValueHandler::GetValueFormatter(Value* value,
ValueFormatter*& _formatter)
{
// TODO:...
return B_UNSUPPORTED;
}
status_t
StringValueHandler::GetTableCellValueRenderer(Value* value,
TableCellValueRenderer*& _renderer)
{
if (dynamic_cast<StringValue*>(value) == NULL)
return B_BAD_VALUE;
// create the renderer
TableCellValueRenderer* renderer = new(std::nothrow)
TableCellStringRenderer;
if (renderer == NULL)
return B_NO_MEMORY;
_renderer = renderer;
return B_OK;
}

View File

@ -0,0 +1,27 @@
/*
* Copyright 2010, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef STRING_VALUE_HANDLER_H
#define STRING_VALUE_HANDLER_H
#include "ValueHandler.h"
class StringValueHandler : public ValueHandler {
public:
StringValueHandler();
~StringValueHandler();
status_t Init();
virtual float SupportsValue(Value* value);
virtual status_t GetValueFormatter(Value* value,
ValueFormatter*& _formatter);
virtual status_t GetTableCellValueRenderer(Value* value,
TableCellValueRenderer*& _renderer);
};
#endif // STRING_VALUE_HANDLER_H

View File

@ -0,0 +1,90 @@
/*
* Copyright 2010, Rene Gollent, rene@gollent.com
* Distributed under the terms of the MIT License.
*/
#include "CStringValueNode.h"
#include <new>
#include "Architecture.h"
#include "StringValue.h"
#include "Tracing.h"
#include "Type.h"
#include "ValueLoader.h"
#include "ValueLocation.h"
#include "ValueNodeContainer.h"
// #pragma mark - CStringValueNode
CStringValueNode::CStringValueNode(ValueNodeChild* nodeChild,
AddressType* type)
:
ChildlessValueNode(nodeChild),
fType(type)
{
fType->AcquireReference();
}
CStringValueNode::~CStringValueNode()
{
fType->ReleaseReference();
}
Type*
CStringValueNode::GetType() const
{
return fType;
}
status_t
CStringValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
ValueLocation*& _location, Value*& _value)
{
// get the location
ValueLocation* location = NodeChild()->Location();
if (location == NULL)
return B_BAD_VALUE;
TRACE_LOCALS(" TYPE_ADDRESS (C string)\n");
// get the value type
type_code valueType;
if (valueLoader->GetArchitecture()->AddressSize() == 4) {
valueType = B_UINT32_TYPE;
TRACE_LOCALS(" -> 32 bit\n");
} else {
valueType = B_UINT64_TYPE;
TRACE_LOCALS(" -> 64 bit\n");
}
// load the value data
BVariant addressData;
BString valueData;
status_t error = valueLoader->LoadValue(location, valueType, false,
addressData);
if (error != B_OK)
return error;
error = valueLoader->LoadStringValue(addressData, valueType,
valueData);
if (error != B_OK)
return error;
// create the type object
Value* value = new(std::nothrow) StringValue(valueData);
if (value == NULL)
return B_NO_MEMORY;
location->AcquireReference();
_location = location;
_value = value;
return B_OK;
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2010, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef CSTRING_VALUE_NODE_H
#define CSTRING_VALUE_NODE_H
#include "ValueNode.h"
class AddressType;
class CStringValueNode : public ChildlessValueNode {
public:
CStringValueNode(ValueNodeChild* nodeChild,
AddressType* type);
virtual ~CStringValueNode();
virtual Type* GetType() const;
virtual status_t ResolvedLocationAndValue(
ValueLoader* valueLoader,
ValueLocation*& _location,
Value*& _value);
private:
AddressType* fType;
};
#endif // CSTRING_VALUE_NODE_H

View File

@ -0,0 +1,45 @@
/*
* Copyright 2010, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "StringValue.h"
#include <stdio.h>
StringValue::StringValue(const char* value)
:
fValue(value)
{
}
StringValue::~StringValue()
{
}
bool
StringValue::ToString(BString& _string) const
{
_string = fValue;
return true;
}
bool
StringValue::ToVariant(BVariant& _value) const
{
_value = fValue.String();
return true;
}
bool
StringValue::operator==(const Value& other) const
{
const StringValue* otherString = dynamic_cast<const StringValue*>(&other);
return otherString != NULL ? fValue == otherString->fValue : false;
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2010, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef STRING_VALUE_H
#define STRING_VALUE_H
#include "Value.h"
class StringValue : public Value {
public:
StringValue(const char* value);
virtual ~StringValue();
BString GetValue() const
{ return fValue; }
virtual bool ToString(BString& _string) const;
virtual bool ToVariant(BVariant& _value) const;
virtual bool operator==(const Value& other) const;
private:
BString fValue;
};
#endif // STRING_VALUE_H