Author: anevilyak Date: 2010-11-09 02:06:32 +0100 (Tue, 09 Nov 2010) New Revision: 39367 Changeset: http://dev.haiku-os.org/changeset/39367 Added: haiku/trunk/src/apps/debugger/value/type_handlers/ haiku/trunk/src/apps/debugger/value/type_handlers/CStringTypeHandler.cpp haiku/trunk/src/apps/debugger/value/type_handlers/CStringTypeHandler.h haiku/trunk/src/apps/debugger/value/value_handlers/StringValueHandler.cpp haiku/trunk/src/apps/debugger/value/value_handlers/StringValueHandler.h haiku/trunk/src/apps/debugger/value/value_nodes/CStringValueNode.cpp haiku/trunk/src/apps/debugger/value/value_nodes/CStringValueNode.h haiku/trunk/src/apps/debugger/value/values/StringValue.cpp haiku/trunk/src/apps/debugger/value/values/StringValue.h Modified: haiku/trunk/src/apps/debugger/Jamfile haiku/trunk/src/apps/debugger/user_interface/gui/value/TableCellStringRenderer.cpp haiku/trunk/src/apps/debugger/value/TypeHandlerRoster.cpp haiku/trunk/src/apps/debugger/value/ValueHandlerRoster.cpp haiku/trunk/src/apps/debugger/value/ValueLoader.cpp haiku/trunk/src/apps/debugger/value/ValueLoader.h Log: 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. Modified: haiku/trunk/src/apps/debugger/Jamfile =================================================================== --- haiku/trunk/src/apps/debugger/Jamfile 2010-11-08 23:52:19 UTC (rev 39366) +++ haiku/trunk/src/apps/debugger/Jamfile 2010-11-09 01:06:32 UTC (rev 39367) @@ -27,6 +27,7 @@ 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 @@ 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 @@ EnumerationValue.cpp FloatValue.cpp IntegerValue.cpp + StringValue.cpp : <nogrist>Debugger_demangler.o Modified: haiku/trunk/src/apps/debugger/user_interface/gui/value/TableCellStringRenderer.cpp =================================================================== --- haiku/trunk/src/apps/debugger/user_interface/gui/value/TableCellStringRenderer.cpp 2010-11-08 23:52:19 UTC (rev 39366) +++ haiku/trunk/src/apps/debugger/user_interface/gui/value/TableCellStringRenderer.cpp 2010-11-09 01:06:32 UTC (rev 39367) @@ -6,6 +6,8 @@ #include "TableCellStringRenderer.h" +#include <stdio.h> + #include <String.h> #include "TableCellValueRendererUtils.h" @@ -16,10 +18,51 @@ 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); } Modified: haiku/trunk/src/apps/debugger/value/TypeHandlerRoster.cpp =================================================================== --- haiku/trunk/src/apps/debugger/value/TypeHandlerRoster.cpp 2010-11-08 23:52:19 UTC (rev 39366) +++ haiku/trunk/src/apps/debugger/value/TypeHandlerRoster.cpp 2010-11-09 01:06:32 UTC (rev 39367) @@ -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 @@ 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; } Modified: haiku/trunk/src/apps/debugger/value/ValueHandlerRoster.cpp =================================================================== --- haiku/trunk/src/apps/debugger/value/ValueHandlerRoster.cpp 2010-11-08 23:52:19 UTC (rev 39366) +++ haiku/trunk/src/apps/debugger/value/ValueHandlerRoster.cpp 2010-11-09 01:06:32 UTC (rev 39367) @@ -15,6 +15,7 @@ #include "BoolValueHandler.h" #include "EnumerationValueHandler.h" #include "FloatValueHandler.h" +#include "StringValueHandler.h" #include "Value.h" @@ -106,6 +107,7 @@ REGISTER_HANDLER(Enumeration) REGISTER_HANDLER(Float) REGISTER_HANDLER(Integer) + REGISTER_HANDLER(String) return B_OK; } Modified: haiku/trunk/src/apps/debugger/value/ValueLoader.cpp =================================================================== --- haiku/trunk/src/apps/debugger/value/ValueLoader.cpp 2010-11-08 23:52:19 UTC (rev 39366) +++ haiku/trunk/src/apps/debugger/value/ValueLoader.cpp 2010-11-09 01:06:32 UTC (rev 39367) @@ -185,3 +185,14 @@ _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); +} Modified: haiku/trunk/src/apps/debugger/value/ValueLoader.h =================================================================== --- haiku/trunk/src/apps/debugger/value/ValueLoader.h 2010-11-08 23:52:19 UTC (rev 39366) +++ haiku/trunk/src/apps/debugger/value/ValueLoader.h 2010-11-09 01:06:32 UTC (rev 39367) @@ -31,6 +31,10 @@ type_code valueType, bool shortValueIsFine, BVariant& _value); + status_t LoadStringValue(BVariant& location, + type_code valueType, + BString& _value); + private: Architecture* fArchitecture; TeamMemory* fTeamMemory; Added: haiku/trunk/src/apps/debugger/value/type_handlers/CStringTypeHandler.cpp =================================================================== --- haiku/trunk/src/apps/debugger/value/type_handlers/CStringTypeHandler.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/value/type_handlers/CStringTypeHandler.cpp 2010-11-09 01:06:32 UTC (rev 39367) @@ -0,0 +1,70 @@ +/* + * Copyright 2010, Rene Gollent, rene@xxxxxxxxxxx + * 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; +} Added: haiku/trunk/src/apps/debugger/value/type_handlers/CStringTypeHandler.h =================================================================== --- haiku/trunk/src/apps/debugger/value/type_handlers/CStringTypeHandler.h (rev 0) +++ haiku/trunk/src/apps/debugger/value/type_handlers/CStringTypeHandler.h 2010-11-09 01:06:32 UTC (rev 39367) @@ -0,0 +1,21 @@ +/* + * Copyright 2010, Rene Gollent, rene@xxxxxxxxxxx + * 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 Added: haiku/trunk/src/apps/debugger/value/value_handlers/StringValueHandler.cpp =================================================================== --- haiku/trunk/src/apps/debugger/value/value_handlers/StringValueHandler.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/value/value_handlers/StringValueHandler.cpp 2010-11-09 01:06:32 UTC (rev 39367) @@ -0,0 +1,65 @@ +/* + * Copyright 2010, Rene Gollent, rene@xxxxxxxxxxx + * 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; +} Added: haiku/trunk/src/apps/debugger/value/value_handlers/StringValueHandler.h =================================================================== --- haiku/trunk/src/apps/debugger/value/value_handlers/StringValueHandler.h (rev 0) +++ haiku/trunk/src/apps/debugger/value/value_handlers/StringValueHandler.h 2010-11-09 01:06:32 UTC (rev 39367) @@ -0,0 +1,27 @@ +/* + * Copyright 2010, Rene Gollent, rene@xxxxxxxxxxxx + * 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 Added: haiku/trunk/src/apps/debugger/value/value_nodes/CStringValueNode.cpp =================================================================== --- haiku/trunk/src/apps/debugger/value/value_nodes/CStringValueNode.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/value/value_nodes/CStringValueNode.cpp 2010-11-09 01:06:32 UTC (rev 39367) @@ -0,0 +1,90 @@ +/* + * Copyright 2010, Rene Gollent, rene@xxxxxxxxxxx + * 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; +} Added: haiku/trunk/src/apps/debugger/value/value_nodes/CStringValueNode.h =================================================================== --- haiku/trunk/src/apps/debugger/value/value_nodes/CStringValueNode.h (rev 0) +++ haiku/trunk/src/apps/debugger/value/value_nodes/CStringValueNode.h 2010-11-09 01:06:32 UTC (rev 39367) @@ -0,0 +1,32 @@ +/* + * Copyright 2010, Rene Gollent, rene@xxxxxxxxxxxx + * 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 Added: haiku/trunk/src/apps/debugger/value/values/StringValue.cpp =================================================================== --- haiku/trunk/src/apps/debugger/value/values/StringValue.cpp (rev 0) +++ haiku/trunk/src/apps/debugger/value/values/StringValue.cpp 2010-11-09 01:06:32 UTC (rev 39367) @@ -0,0 +1,45 @@ +/* + * Copyright 2010, Rene Gollent, rene@xxxxxxxxxxxx + * 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; +} Added: haiku/trunk/src/apps/debugger/value/values/StringValue.h =================================================================== --- haiku/trunk/src/apps/debugger/value/values/StringValue.h (rev 0) +++ haiku/trunk/src/apps/debugger/value/values/StringValue.h 2010-11-09 01:06:32 UTC (rev 39367) @@ -0,0 +1,30 @@ +/* + * Copyright 2010, Rene Gollent, rene@xxxxxxxxxxxx + * 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