Author: enrico Date: Wed Sep 9 17:30:24 2015 New Revision: 247200 URL: http://llvm.org/viewvc/llvm-project?rev=247200&view=rev Log: Introduce the notion of an escape helper. Different languages have different notion of what to print in a string and how to escape non-printable things. The escape helper is where this notion is provided to LLDB
This is NFC, other than a code re-org Modified: lldb/trunk/include/lldb/DataFormatters/FormatManager.h lldb/trunk/include/lldb/DataFormatters/StringPrinter.h lldb/trunk/include/lldb/Target/Language.h lldb/trunk/source/Core/ValueObject.cpp lldb/trunk/source/DataFormatters/Cocoa.cpp lldb/trunk/source/DataFormatters/FormatManager.cpp lldb/trunk/source/DataFormatters/StringPrinter.cpp lldb/trunk/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp lldb/trunk/source/Target/Language.cpp Modified: lldb/trunk/include/lldb/DataFormatters/FormatManager.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/FormatManager.h?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/include/lldb/DataFormatters/FormatManager.h (original) +++ lldb/trunk/include/lldb/DataFormatters/FormatManager.h Wed Sep 9 17:30:24 2015 @@ -262,6 +262,9 @@ public: LanguageCategory* GetCategoryForLanguage (lldb::LanguageType lang_type); + static std::vector<lldb::LanguageType> + GetCandidateLanguages (lldb::LanguageType lang_type); + private: static std::vector<lldb::LanguageType> Modified: lldb/trunk/include/lldb/DataFormatters/StringPrinter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/StringPrinter.h?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/include/lldb/DataFormatters/StringPrinter.h (original) +++ lldb/trunk/include/lldb/DataFormatters/StringPrinter.h Wed Sep 9 17:30:24 2015 @@ -19,300 +19,339 @@ namespace lldb_private { namespace formatters { - - enum class StringElementType { - ASCII, - UTF8, - UTF16, - UTF32 - }; - - class ReadStringAndDumpToStreamOptions - { - public: - - ReadStringAndDumpToStreamOptions () : - m_location(0), - m_process_sp(), - m_stream(NULL), - m_prefix_token(0), - m_quote('"'), - m_source_size(0), - m_needs_zero_termination(true), - m_escape_non_printables(true), - m_ignore_max_length(false), - m_zero_is_terminator(true) - { - } - - ReadStringAndDumpToStreamOptions (ValueObject& valobj); - - ReadStringAndDumpToStreamOptions& - SetLocation (uint64_t l) - { - m_location = l; - return *this; - } - - uint64_t - GetLocation () const - { - return m_location; - } - - ReadStringAndDumpToStreamOptions& - SetProcessSP (lldb::ProcessSP p) - { - m_process_sp = p; - return *this; - } - - lldb::ProcessSP - GetProcessSP () const - { - return m_process_sp; - } - - ReadStringAndDumpToStreamOptions& - SetStream (Stream* s) - { - m_stream = s; - return *this; - } - - Stream* - GetStream () const - { - return m_stream; - } - - ReadStringAndDumpToStreamOptions& - SetPrefixToken (char p) - { - m_prefix_token = p; - return *this; - } - - char - GetPrefixToken () const - { - return m_prefix_token; - } - - ReadStringAndDumpToStreamOptions& - SetQuote (char q) - { - m_quote = q; - return *this; - } - - char - GetQuote () const - { - return m_quote; - } - - ReadStringAndDumpToStreamOptions& - SetSourceSize (uint32_t s) - { - m_source_size = s; - return *this; - } - - uint32_t - GetSourceSize () const - { - return m_source_size; - } - - ReadStringAndDumpToStreamOptions& - SetNeedsZeroTermination (bool z) - { - m_needs_zero_termination = z; - return *this; - } - - bool - GetNeedsZeroTermination () const - { - return m_needs_zero_termination; - } - - ReadStringAndDumpToStreamOptions& - SetBinaryZeroIsTerminator (bool e) - { - m_zero_is_terminator = e; - return *this; - } - - bool - GetBinaryZeroIsTerminator () const - { - return m_zero_is_terminator; - } - - ReadStringAndDumpToStreamOptions& - SetEscapeNonPrintables (bool e) - { - m_escape_non_printables = e; - return *this; - } - - bool - GetEscapeNonPrintables () const - { - return m_escape_non_printables; - } - - ReadStringAndDumpToStreamOptions& - SetIgnoreMaxLength (bool e) - { - m_ignore_max_length = e; - return *this; - } - - bool - GetIgnoreMaxLength () const - { - return m_ignore_max_length; - } - - private: - uint64_t m_location; - lldb::ProcessSP m_process_sp; - Stream* m_stream; - char m_prefix_token; - char m_quote; - uint32_t m_source_size; - bool m_needs_zero_termination; - bool m_escape_non_printables; - bool m_ignore_max_length; - bool m_zero_is_terminator; - }; - - class ReadBufferAndDumpToStreamOptions + class StringPrinter { public: - - ReadBufferAndDumpToStreamOptions () : - m_data(), - m_stream(NULL), - m_prefix_token(0), - m_quote('"'), - m_source_size(0), - m_escape_non_printables(true), - m_zero_is_terminator(true) - { - } - - ReadBufferAndDumpToStreamOptions (ValueObject& valobj); - - ReadBufferAndDumpToStreamOptions (const ReadStringAndDumpToStreamOptions& options); - - ReadBufferAndDumpToStreamOptions& - SetData (DataExtractor d) + + enum class StringElementType { - m_data = d; - return *this; - } - - lldb_private::DataExtractor - GetData () const - { - return m_data; - } - - ReadBufferAndDumpToStreamOptions& - SetStream (Stream* s) - { - m_stream = s; - return *this; - } - - Stream* - GetStream () const - { - return m_stream; - } - - ReadBufferAndDumpToStreamOptions& - SetPrefixToken (char p) - { - m_prefix_token = p; - return *this; - } - - char - GetPrefixToken () const - { - return m_prefix_token; - } - - ReadBufferAndDumpToStreamOptions& - SetQuote (char q) - { - m_quote = q; - return *this; - } - - char - GetQuote () const - { - return m_quote; - } - - ReadBufferAndDumpToStreamOptions& - SetSourceSize (uint32_t s) - { - m_source_size = s; - return *this; - } - - uint32_t - GetSourceSize () const - { - return m_source_size; - } - - ReadBufferAndDumpToStreamOptions& - SetEscapeNonPrintables (bool e) - { - m_escape_non_printables = e; - return *this; - } + ASCII, + UTF8, + UTF16, + UTF32 + }; - bool - GetEscapeNonPrintables () const + enum class GetPrintableElementType { - return m_escape_non_printables; - } + ASCII, + UTF8 + }; - ReadBufferAndDumpToStreamOptions& - SetBinaryZeroIsTerminator (bool e) + class ReadStringAndDumpToStreamOptions { - m_zero_is_terminator = e; - return *this; - } + public: + + ReadStringAndDumpToStreamOptions () : + m_location(0), + m_process_sp(), + m_stream(NULL), + m_prefix_token(0), + m_quote('"'), + m_source_size(0), + m_needs_zero_termination(true), + m_escape_non_printables(true), + m_ignore_max_length(false), + m_zero_is_terminator(true), + m_language_type(lldb::eLanguageTypeUnknown) + { + } + + ReadStringAndDumpToStreamOptions (ValueObject& valobj); + + ReadStringAndDumpToStreamOptions& + SetLocation (uint64_t l) + { + m_location = l; + return *this; + } + + uint64_t + GetLocation () const + { + return m_location; + } + + ReadStringAndDumpToStreamOptions& + SetProcessSP (lldb::ProcessSP p) + { + m_process_sp = p; + return *this; + } + + lldb::ProcessSP + GetProcessSP () const + { + return m_process_sp; + } + + ReadStringAndDumpToStreamOptions& + SetStream (Stream* s) + { + m_stream = s; + return *this; + } + + Stream* + GetStream () const + { + return m_stream; + } + + ReadStringAndDumpToStreamOptions& + SetPrefixToken (char p) + { + m_prefix_token = p; + return *this; + } + + char + GetPrefixToken () const + { + return m_prefix_token; + } + + ReadStringAndDumpToStreamOptions& + SetQuote (char q) + { + m_quote = q; + return *this; + } + + char + GetQuote () const + { + return m_quote; + } + + ReadStringAndDumpToStreamOptions& + SetSourceSize (uint32_t s) + { + m_source_size = s; + return *this; + } + + uint32_t + GetSourceSize () const + { + return m_source_size; + } + + ReadStringAndDumpToStreamOptions& + SetNeedsZeroTermination (bool z) + { + m_needs_zero_termination = z; + return *this; + } + + bool + GetNeedsZeroTermination () const + { + return m_needs_zero_termination; + } + + ReadStringAndDumpToStreamOptions& + SetBinaryZeroIsTerminator (bool e) + { + m_zero_is_terminator = e; + return *this; + } + + bool + GetBinaryZeroIsTerminator () const + { + return m_zero_is_terminator; + } + + ReadStringAndDumpToStreamOptions& + SetEscapeNonPrintables (bool e) + { + m_escape_non_printables = e; + return *this; + } + + bool + GetEscapeNonPrintables () const + { + return m_escape_non_printables; + } + + ReadStringAndDumpToStreamOptions& + SetIgnoreMaxLength (bool e) + { + m_ignore_max_length = e; + return *this; + } + + bool + GetIgnoreMaxLength () const + { + return m_ignore_max_length; + } + + ReadStringAndDumpToStreamOptions& + SetLanguage (lldb::LanguageType l) + { + m_language_type = l; + return *this; + } + + lldb::LanguageType + GetLanguage () const + + { + return m_language_type; + } + + private: + uint64_t m_location; + lldb::ProcessSP m_process_sp; + Stream* m_stream; + char m_prefix_token; + char m_quote; + uint32_t m_source_size; + bool m_needs_zero_termination; + bool m_escape_non_printables; + bool m_ignore_max_length; + bool m_zero_is_terminator; + lldb::LanguageType m_language_type; + }; - bool - GetBinaryZeroIsTerminator () const + class ReadBufferAndDumpToStreamOptions { - return m_zero_is_terminator; - } - - private: - DataExtractor m_data; - Stream* m_stream; - char m_prefix_token; - char m_quote; - uint32_t m_source_size; - bool m_escape_non_printables; - bool m_zero_is_terminator; - }; - - class StringPrinter - { - public: + public: + + ReadBufferAndDumpToStreamOptions () : + m_data(), + m_stream(NULL), + m_prefix_token(0), + m_quote('"'), + m_source_size(0), + m_escape_non_printables(true), + m_zero_is_terminator(true), + m_language_type(lldb::eLanguageTypeUnknown) + { + } + + ReadBufferAndDumpToStreamOptions (ValueObject& valobj); + + ReadBufferAndDumpToStreamOptions (const ReadStringAndDumpToStreamOptions& options); + + ReadBufferAndDumpToStreamOptions& + SetData (DataExtractor d) + { + m_data = d; + return *this; + } + + lldb_private::DataExtractor + GetData () const + { + return m_data; + } + + ReadBufferAndDumpToStreamOptions& + SetStream (Stream* s) + { + m_stream = s; + return *this; + } + + Stream* + GetStream () const + { + return m_stream; + } + + ReadBufferAndDumpToStreamOptions& + SetPrefixToken (char p) + { + m_prefix_token = p; + return *this; + } + + char + GetPrefixToken () const + { + return m_prefix_token; + } + + ReadBufferAndDumpToStreamOptions& + SetQuote (char q) + { + m_quote = q; + return *this; + } + + char + GetQuote () const + { + return m_quote; + } + + ReadBufferAndDumpToStreamOptions& + SetSourceSize (uint32_t s) + { + m_source_size = s; + return *this; + } + + uint32_t + GetSourceSize () const + { + return m_source_size; + } + + ReadBufferAndDumpToStreamOptions& + SetEscapeNonPrintables (bool e) + { + m_escape_non_printables = e; + return *this; + } + + bool + GetEscapeNonPrintables () const + { + return m_escape_non_printables; + } + + ReadBufferAndDumpToStreamOptions& + SetBinaryZeroIsTerminator (bool e) + { + m_zero_is_terminator = e; + return *this; + } + + bool + GetBinaryZeroIsTerminator () const + { + return m_zero_is_terminator; + } + + ReadBufferAndDumpToStreamOptions& + SetLanguage (lldb::LanguageType l) + { + m_language_type = l; + return *this; + } + + lldb::LanguageType + GetLanguage () const + + { + return m_language_type; + } + + private: + DataExtractor m_data; + Stream* m_stream; + char m_prefix_token; + char m_quote; + uint32_t m_source_size; + bool m_escape_non_printables; + bool m_zero_is_terminator; + lldb::LanguageType m_language_type; + }; + // I can't use a std::unique_ptr for this because the Deleter is a template argument there // and I want the same type to represent both pointers I want to free and pointers I don't need // to free - which is what this class essentially is @@ -321,7 +360,6 @@ namespace lldb_private { struct StringPrinterBufferPointer { public: - typedef std::function<void(const T*)> Deleter; StringPrinterBufferPointer (std::nullptr_t ptr) : @@ -395,6 +433,12 @@ namespace lldb_private { Deleter m_deleter; }; + typedef std::function<StringPrinter::StringPrinterBufferPointer<uint8_t,char,size_t>(uint8_t*, uint8_t*, uint8_t*&)> EscapingHelper; + typedef std::function<EscapingHelper(GetPrintableElementType)> EscapingHelperGenerator; + + static EscapingHelper + GetDefaultEscapingHelper (GetPrintableElementType elem_type); + template <StringElementType element_type> static bool ReadStringAndDumpToStream (const ReadStringAndDumpToStreamOptions& options); Modified: lldb/trunk/include/lldb/Target/Language.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Language.h?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Language.h (original) +++ lldb/trunk/include/lldb/Target/Language.h Wed Sep 9 17:30:24 2015 @@ -18,8 +18,9 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-public.h" -#include "lldb/Core/PluginInterface.h" #include "lldb/lldb-private.h" +#include "lldb/Core/PluginInterface.h" +#include "lldb/DataFormatters/StringPrinter.h" namespace lldb_private { @@ -45,6 +46,9 @@ public: virtual std::vector<ConstString> GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic); + virtual lldb_private::formatters::StringPrinter::EscapingHelper + GetStringPrinterEscapingHelper (lldb_private::formatters::StringPrinter::GetPrintableElementType); + // These are accessors for general information about the Languages lldb knows about: static lldb::LanguageType Modified: lldb/trunk/source/Core/ValueObject.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/source/Core/ValueObject.cpp (original) +++ lldb/trunk/source/Core/ValueObject.cpp Wed Sep 9 17:30:24 2015 @@ -1595,13 +1595,13 @@ ValueObject::DumpPrintableRepresentation 0, (custom_format == eFormatVectorOfChar) || (custom_format == eFormatCharArray)); - lldb_private::formatters::ReadBufferAndDumpToStreamOptions options(*this); + lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions options(*this); options.SetData(DataExtractor(buffer_sp, lldb::eByteOrderInvalid, 8)); // none of this matters for a string - pass some defaults options.SetStream(&s); options.SetPrefixToken(0); options.SetQuote('"'); options.SetSourceSize(buffer_sp->GetByteSize()); - formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options); + formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::ASCII>(options); return !error.Fail(); } Modified: lldb/trunk/source/DataFormatters/Cocoa.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/Cocoa.cpp?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/source/DataFormatters/Cocoa.cpp (original) +++ lldb/trunk/source/DataFormatters/Cocoa.cpp Wed Sep 9 17:30:24 2015 @@ -866,7 +866,7 @@ lldb_private::formatters::NSStringSummar return false; if (has_explicit_length && is_unicode) { - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(location); options.SetProcessSP(process_sp); options.SetStream(&stream); @@ -876,11 +876,11 @@ lldb_private::formatters::NSStringSummar options.SetNeedsZeroTermination(false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(false); - return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16>(options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options); } else { - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(location+1); options.SetProcessSP(process_sp); options.SetStream(&stream); @@ -889,14 +889,14 @@ lldb_private::formatters::NSStringSummar options.SetNeedsZeroTermination(false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(false); - return StringPrinter::ReadStringAndDumpToStream<StringElementType::ASCII>(options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options); } } else if (is_inline && has_explicit_length && !is_unicode && !is_path_store && !is_mutable) { uint64_t location = 3 * ptr_size + valobj_addr; - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(location); options.SetProcessSP(process_sp); options.SetStream(&stream); @@ -904,7 +904,7 @@ lldb_private::formatters::NSStringSummar options.SetQuote('"'); options.SetSourceSize(explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - return StringPrinter::ReadStringAndDumpToStream<StringElementType::ASCII> (options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII> (options); } else if (is_unicode) { @@ -925,7 +925,7 @@ lldb_private::formatters::NSStringSummar if (error.Fail()) return false; } - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(location); options.SetProcessSP(process_sp); options.SetStream(&stream); @@ -935,7 +935,7 @@ lldb_private::formatters::NSStringSummar options.SetNeedsZeroTermination(has_explicit_length == false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(has_explicit_length == false); - return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16> (options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options); } else if (is_path_store) { @@ -943,7 +943,7 @@ lldb_private::formatters::NSStringSummar explicit_length = reader.GetField<uint32_t>(ConstString("lengthAndRef")) >> 20; lldb::addr_t location = valobj.GetValueAsUnsigned(0) + ptr_size + 4; - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(location); options.SetProcessSP(process_sp); options.SetStream(&stream); @@ -953,7 +953,7 @@ lldb_private::formatters::NSStringSummar options.SetNeedsZeroTermination(has_explicit_length == false); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(has_explicit_length == false); - return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16> (options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (options); } else if (is_inline) { @@ -970,7 +970,7 @@ lldb_private::formatters::NSStringSummar has_explicit_length = true; location++; } - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(location); options.SetProcessSP(process_sp); options.SetStream(&stream); @@ -980,9 +980,9 @@ lldb_private::formatters::NSStringSummar options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); options.SetBinaryZeroIsTerminator(!has_explicit_length); if (has_explicit_length) - return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF8>(options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options); else - return StringPrinter::ReadStringAndDumpToStream<StringElementType::ASCII>(options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options); } else { @@ -992,14 +992,14 @@ lldb_private::formatters::NSStringSummar return false; if (has_explicit_length && !has_null) explicit_length++; // account for the fact that there is no NULL and we need to have one added - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(location); options.SetProcessSP(process_sp); options.SetPrefixToken('@'); options.SetStream(&stream); options.SetSourceSize(explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - return StringPrinter::ReadStringAndDumpToStream<StringElementType::ASCII>(options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(options); } } Modified: lldb/trunk/source/DataFormatters/FormatManager.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/FormatManager.cpp?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/source/DataFormatters/FormatManager.cpp (original) +++ lldb/trunk/source/DataFormatters/FormatManager.cpp Wed Sep 9 17:30:24 2015 @@ -651,6 +651,12 @@ std::vector<lldb::LanguageType> FormatManager::GetCandidateLanguages (ValueObject& valobj) { lldb::LanguageType lang_type = valobj.GetObjectRuntimeLanguage(); + return GetCandidateLanguages(lang_type); +} + +std::vector<lldb::LanguageType> +FormatManager::GetCandidateLanguages (lldb::LanguageType lang_type) +{ switch (lang_type) { case lldb::eLanguageTypeC: Modified: lldb/trunk/source/DataFormatters/StringPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/DataFormatters/StringPrinter.cpp?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/source/DataFormatters/StringPrinter.cpp (original) +++ lldb/trunk/source/DataFormatters/StringPrinter.cpp Wed Sep 9 17:30:24 2015 @@ -13,6 +13,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Error.h" #include "lldb/Core/ValueObject.h" +#include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -27,7 +28,7 @@ using namespace lldb_private::formatters // we define this for all values of type but only implement it for those we care about // that's good because we get linker errors for any unsupported type -template <StringElementType type> +template <lldb_private::formatters::StringPrinter::StringElementType type> static StringPrinter::StringPrinterBufferPointer<> GetPrintableImpl(uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next); @@ -60,7 +61,7 @@ isprint(char32_t codepoint) template <> StringPrinter::StringPrinterBufferPointer<> -GetPrintableImpl<StringElementType::ASCII> (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) +GetPrintableImpl<StringPrinter::StringElementType::ASCII> (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) { StringPrinter::StringPrinterBufferPointer<> retval = {nullptr}; @@ -130,7 +131,7 @@ ConvertUTF8ToCodePoint (unsigned char c0 template <> StringPrinter::StringPrinterBufferPointer<> -GetPrintableImpl<StringElementType::UTF8> (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) +GetPrintableImpl<StringPrinter::StringElementType::UTF8> (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) { StringPrinter::StringPrinterBufferPointer<> retval {nullptr}; @@ -149,7 +150,7 @@ GetPrintableImpl<StringElementType::UTF8 { case 1: // this is just an ASCII byte - ask ASCII - return GetPrintableImpl<StringElementType::ASCII>(buffer, buffer_end, next); + return GetPrintableImpl<StringPrinter::StringElementType::ASCII>(buffer, buffer_end, next); case 2: codepoint = ConvertUTF8ToCodePoint((unsigned char)*buffer, (unsigned char)*(buffer+1)); break; @@ -227,22 +228,38 @@ GetPrintableImpl<StringElementType::UTF8 // a sequence of bytes to actually print out + a length // the following unscanned position of the buffer is in next static StringPrinter::StringPrinterBufferPointer<> -GetPrintable(StringElementType type, uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) +GetPrintable(StringPrinter::StringElementType type, uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) { if (!buffer) return {nullptr}; switch (type) { - case StringElementType::ASCII: - return GetPrintableImpl<StringElementType::ASCII>(buffer, buffer_end, next); - case StringElementType::UTF8: - return GetPrintableImpl<StringElementType::UTF8>(buffer, buffer_end, next); + case StringPrinter::StringElementType::ASCII: + return GetPrintableImpl<StringPrinter::StringElementType::ASCII>(buffer, buffer_end, next); + case StringPrinter::StringElementType::UTF8: + return GetPrintableImpl<StringPrinter::StringElementType::UTF8>(buffer, buffer_end, next); default: return {nullptr}; } } +StringPrinter::EscapingHelper +StringPrinter::GetDefaultEscapingHelper (GetPrintableElementType elem_type) +{ + switch (elem_type) + { + case GetPrintableElementType::UTF8: + return [] (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) -> StringPrinter::StringPrinterBufferPointer<> { + return GetPrintable(StringPrinter::StringElementType::UTF8, buffer, buffer_end, next); + }; + case GetPrintableElementType::ASCII: + return [] (uint8_t* buffer, uint8_t* buffer_end, uint8_t*& next) -> StringPrinter::StringPrinterBufferPointer<> { + return GetPrintable(StringPrinter::StringElementType::ASCII, buffer, buffer_end, next); + }; + } +} + // use this call if you already have an LLDB-side buffer for the data template<typename SourceDataType> static bool @@ -251,7 +268,7 @@ DumpUTFBufferToStream (ConversionResult UTF8**, UTF8*, ConversionFlags), - const ReadBufferAndDumpToStreamOptions& dump_options) + const StringPrinter::ReadBufferAndDumpToStreamOptions& dump_options) { Stream &stream(*dump_options.GetStream()); if (dump_options.GetPrefixToken() != 0) @@ -312,6 +329,14 @@ DumpUTFBufferToStream (ConversionResult } const bool escape_non_printables = dump_options.GetEscapeNonPrintables(); + lldb_private::formatters::StringPrinter::EscapingHelper escaping_callback; + if (escape_non_printables) + { + if (Language *language = Language::FindPlugin(dump_options.GetLanguage())) + escaping_callback = language->GetStringPrinterEscapingHelper(lldb_private::formatters::StringPrinter::GetPrintableElementType::UTF8); + else + escaping_callback = lldb_private::formatters::StringPrinter::GetDefaultEscapingHelper(lldb_private::formatters::StringPrinter::GetPrintableElementType::UTF8); + } // since we tend to accept partial data (and even partially malformed data) // we might end up with no NULL terminator before the end_ptr @@ -324,7 +349,7 @@ DumpUTFBufferToStream (ConversionResult if (escape_non_printables) { uint8_t* next_data = nullptr; - auto printable = GetPrintable(StringElementType::UTF8, utf8_data_ptr, utf8_data_end_ptr, next_data); + auto printable = escaping_callback(utf8_data_ptr, utf8_data_end_ptr, next_data); auto printable_bytes = printable.GetBytes(); auto printable_size = printable.GetSize(); if (!printable_bytes || !next_data) @@ -350,19 +375,19 @@ DumpUTFBufferToStream (ConversionResult return true; } -lldb_private::formatters::ReadStringAndDumpToStreamOptions::ReadStringAndDumpToStreamOptions (ValueObject& valobj) : +lldb_private::formatters::StringPrinter::ReadStringAndDumpToStreamOptions::ReadStringAndDumpToStreamOptions (ValueObject& valobj) : ReadStringAndDumpToStreamOptions() { SetEscapeNonPrintables(valobj.GetTargetSP()->GetDebugger().GetEscapeNonPrintables()); } -lldb_private::formatters::ReadBufferAndDumpToStreamOptions::ReadBufferAndDumpToStreamOptions (ValueObject& valobj) : +lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions::ReadBufferAndDumpToStreamOptions (ValueObject& valobj) : ReadBufferAndDumpToStreamOptions() { SetEscapeNonPrintables(valobj.GetTargetSP()->GetDebugger().GetEscapeNonPrintables()); } -lldb_private::formatters::ReadBufferAndDumpToStreamOptions::ReadBufferAndDumpToStreamOptions (const lldb_private::formatters::ReadStringAndDumpToStreamOptions& options) : +lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions::ReadBufferAndDumpToStreamOptions (const ReadStringAndDumpToStreamOptions& options) : ReadBufferAndDumpToStreamOptions() { SetStream(options.GetStream()); @@ -370,6 +395,7 @@ lldb_private::formatters::ReadBufferAndD SetQuote(options.GetQuote()); SetEscapeNonPrintables(options.GetEscapeNonPrintables()); SetBinaryZeroIsTerminator(options.GetBinaryZeroIsTerminator()); + SetLanguage(options.GetLanguage()); } @@ -381,7 +407,7 @@ namespace formatters template <> bool -StringPrinter::ReadStringAndDumpToStream<StringElementType::ASCII> (const ReadStringAndDumpToStreamOptions& options) +StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII> (const ReadStringAndDumpToStreamOptions& options) { assert(options.GetStream() && "need a Stream to print the string to"); Error my_error; @@ -417,15 +443,25 @@ StringPrinter::ReadStringAndDumpToStream uint8_t* data_end = buffer_sp->GetBytes()+buffer_sp->GetByteSize(); + const bool escape_non_printables = options.GetEscapeNonPrintables(); + lldb_private::formatters::StringPrinter::EscapingHelper escaping_callback; + if (escape_non_printables) + { + if (Language *language = Language::FindPlugin(options.GetLanguage())) + escaping_callback = language->GetStringPrinterEscapingHelper(lldb_private::formatters::StringPrinter::GetPrintableElementType::ASCII); + else + escaping_callback = lldb_private::formatters::StringPrinter::GetDefaultEscapingHelper(lldb_private::formatters::StringPrinter::GetPrintableElementType::ASCII); + } + // since we tend to accept partial data (and even partially malformed data) // we might end up with no NULL terminator before the end_ptr // hence we need to take a slower route and ensure we stay within boundaries for (uint8_t* data = buffer_sp->GetBytes(); *data && (data < data_end);) { - if (options.GetEscapeNonPrintables()) + if (escape_non_printables) { uint8_t* next_data = nullptr; - auto printable = GetPrintable(StringElementType::ASCII, data, data_end, next_data); + auto printable = escaping_callback(data, data_end, next_data); auto printable_bytes = printable.GetBytes(); auto printable_size = printable.GetSize(); if (!printable_bytes || !next_data) @@ -454,7 +490,7 @@ StringPrinter::ReadStringAndDumpToStream template<typename SourceDataType> static bool -ReadUTFBufferAndDumpToStream (const ReadStringAndDumpToStreamOptions& options, +ReadUTFBufferAndDumpToStream (const StringPrinter::ReadStringAndDumpToStreamOptions& options, ConversionResult (*ConvertFunction) (const SourceDataType**, const SourceDataType*, UTF8**, @@ -516,7 +552,7 @@ ReadUTFBufferAndDumpToStream (const Read DataExtractor data(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); - ReadBufferAndDumpToStreamOptions dump_options(options); + StringPrinter::ReadBufferAndDumpToStreamOptions dump_options(options); dump_options.SetData(data); dump_options.SetSourceSize(sourceSize); @@ -525,7 +561,7 @@ ReadUTFBufferAndDumpToStream (const Read template <> bool -StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF8> (const ReadStringAndDumpToStreamOptions& options) +StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8> (const ReadStringAndDumpToStreamOptions& options) { return ReadUTFBufferAndDumpToStream<UTF8>(options, nullptr); @@ -533,7 +569,7 @@ StringPrinter::ReadStringAndDumpToStream template <> bool -StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16> (const ReadStringAndDumpToStreamOptions& options) +StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (const ReadStringAndDumpToStreamOptions& options) { return ReadUTFBufferAndDumpToStream<UTF16>(options, ConvertUTF16toUTF8); @@ -541,7 +577,7 @@ StringPrinter::ReadStringAndDumpToStream template <> bool -StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF32> (const ReadStringAndDumpToStreamOptions& options) +StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32> (const ReadStringAndDumpToStreamOptions& options) { return ReadUTFBufferAndDumpToStream<UTF32>(options, ConvertUTF32toUTF8); @@ -549,7 +585,7 @@ StringPrinter::ReadStringAndDumpToStream template <> bool -StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF8> (const ReadBufferAndDumpToStreamOptions& options) +StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF8> (const ReadBufferAndDumpToStreamOptions& options) { assert(options.GetStream() && "need a Stream to print the string to"); @@ -558,7 +594,7 @@ StringPrinter::ReadBufferAndDumpToStream template <> bool -StringPrinter::ReadBufferAndDumpToStream<StringElementType::ASCII> (const ReadBufferAndDumpToStreamOptions& options) +StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::ASCII> (const ReadBufferAndDumpToStreamOptions& options) { // treat ASCII the same as UTF8 // FIXME: can we optimize ASCII some more? @@ -567,7 +603,7 @@ StringPrinter::ReadBufferAndDumpToStream template <> bool -StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF16> (const ReadBufferAndDumpToStreamOptions& options) +StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16> (const ReadBufferAndDumpToStreamOptions& options) { assert(options.GetStream() && "need a Stream to print the string to"); @@ -576,7 +612,7 @@ StringPrinter::ReadBufferAndDumpToStream template <> bool -StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF32> (const ReadBufferAndDumpToStreamOptions& options) +StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32> (const ReadBufferAndDumpToStreamOptions& options) { assert(options.GetStream() && "need a Stream to print the string to"); Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp (original) +++ lldb/trunk/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp Wed Sep 9 17:30:24 2015 @@ -49,13 +49,13 @@ lldb_private::formatters::Char16StringSu if (!valobj_addr) return false; - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('u'); - if (!StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16>(options)) + if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options)) { stream.Printf("Summary Unavailable"); return true; @@ -76,13 +76,13 @@ lldb_private::formatters::Char32StringSu if (!valobj_addr) return false; - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('U'); - if (!StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF32>(options)) + if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options)) { stream.Printf("Summary Unavailable"); return true; @@ -116,7 +116,7 @@ lldb_private::formatters::WCharStringSum const uint32_t wchar_size = wchar_clang_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here - ReadStringAndDumpToStreamOptions options(valobj); + StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(data_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); @@ -125,11 +125,11 @@ lldb_private::formatters::WCharStringSum switch (wchar_size) { case 8: - return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF8>(options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(options); case 16: - return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16>(options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16>(options); case 32: - return StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF32>(options); + return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options); default: stream.Printf("size for wchar_t is not valid"); return true; @@ -152,7 +152,7 @@ lldb_private::formatters::Char16SummaryP if (!value.empty()) stream.Printf("%s ", value.c_str()); - ReadBufferAndDumpToStreamOptions options(valobj); + StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); options.SetData(data); options.SetStream(&stream); options.SetPrefixToken('u'); @@ -160,7 +160,7 @@ lldb_private::formatters::Char16SummaryP options.SetSourceSize(1); options.SetBinaryZeroIsTerminator(false); - return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF16>(options); + return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options); } bool @@ -178,7 +178,7 @@ lldb_private::formatters::Char32SummaryP if (!value.empty()) stream.Printf("%s ", value.c_str()); - ReadBufferAndDumpToStreamOptions options(valobj); + StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); options.SetData(data); options.SetStream(&stream); options.SetPrefixToken('U'); @@ -186,7 +186,7 @@ lldb_private::formatters::Char32SummaryP options.SetSourceSize(1); options.SetBinaryZeroIsTerminator(false); - return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF32>(options); + return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32>(options); } bool @@ -199,7 +199,7 @@ lldb_private::formatters::WCharSummaryPr if (error.Fail()) return false; - ReadBufferAndDumpToStreamOptions options(valobj); + StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); options.SetData(data); options.SetStream(&stream); options.SetPrefixToken('L'); @@ -207,5 +207,5 @@ lldb_private::formatters::WCharSummaryPr options.SetSourceSize(1); options.SetBinaryZeroIsTerminator(false); - return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF16>(options); + return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options); } Modified: lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp (original) +++ lldb/trunk/source/Plugins/Language/CPlusPlus/LibCxx.cpp Wed Sep 9 17:30:24 2015 @@ -570,7 +570,7 @@ lldb_private::formatters::LibcxxWStringS // std::wstring::size() is measured in 'characters', not bytes auto wchar_t_size = valobj.GetTargetSP()->GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeWChar).GetByteSize(nullptr); - ReadBufferAndDumpToStreamOptions options(valobj); + StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); options.SetData(extractor); options.SetStream(&stream); options.SetPrefixToken('L'); @@ -581,15 +581,15 @@ lldb_private::formatters::LibcxxWStringS switch (wchar_t_size) { case 1: - StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::UTF8>(options); + StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF8>(options); break; case 2: - lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::UTF16>(options); + lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF16>(options); break; case 4: - lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::UTF32>(options); + lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::UTF32>(options); break; default: @@ -623,14 +623,14 @@ lldb_private::formatters::LibcxxStringSu size = std::min<decltype(size)>(size, valobj.GetTargetSP()->GetMaximumSizeOfStringSummary()); location_sp->GetPointeeData(extractor, 0, size); - ReadBufferAndDumpToStreamOptions options(valobj); + StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); options.SetData(extractor); options.SetStream(&stream); options.SetPrefixToken(0); options.SetQuote('"'); options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); - StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options); + StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::ASCII>(options); return true; } Modified: lldb/trunk/source/Target/Language.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Language.cpp?rev=247200&r1=247199&r2=247200&view=diff ============================================================================== --- lldb/trunk/source/Target/Language.cpp (original) +++ lldb/trunk/source/Target/Language.cpp Wed Sep 9 17:30:24 2015 @@ -19,6 +19,7 @@ using namespace lldb; using namespace lldb_private; +using namespace lldb_private::formatters; typedef std::unique_ptr<Language> LanguageUP; typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap; @@ -100,6 +101,12 @@ Language::GetPossibleFormattersMatches ( return {}; } +lldb_private::formatters::StringPrinter::EscapingHelper +Language::GetStringPrinterEscapingHelper (lldb_private::formatters::StringPrinter::GetPrintableElementType elem_type) +{ + return StringPrinter::GetDefaultEscapingHelper(elem_type); +} + struct language_name_pair { const char *name; LanguageType type; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits