diff options
Diffstat (limited to 'lldb/source/DataFormatters/StringPrinter.cpp')
| -rw-r--r-- | lldb/source/DataFormatters/StringPrinter.cpp | 88 |
1 files changed, 62 insertions, 26 deletions
diff --git a/lldb/source/DataFormatters/StringPrinter.cpp b/lldb/source/DataFormatters/StringPrinter.cpp index a5ed7e45cdf..3225168a2a3 100644 --- a/lldb/source/DataFormatters/StringPrinter.cpp +++ b/lldb/source/DataFormatters/StringPrinter.cpp @@ -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, unsigned char c1, unsigned char c2, un 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> (uint8_t* buffer, uint8_t* buffer_end, { 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> (uint8_t* buffer, uint8_t* buffer_end, // 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 (*ConvertFunction) (const SourceDataType 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 (*ConvertFunction) (const SourceDataType } 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 (*ConvertFunction) (const SourceDataType 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 (*ConvertFunction) (const SourceDataType 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::ReadBufferAndDumpToStreamOptions::ReadBufferAndDumpToS 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<StringElementType::ASCII> (const ReadSt 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<StringElementType::ASCII> (const ReadSt 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 ReadStringAndDumpToStreamOptions& options, 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 ReadStringAndDumpToStreamOptions& options, 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<StringElementType::UTF8> (const ReadStr 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<StringElementType::UTF16> (const ReadSt 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<StringElementType::UTF32> (const ReadSt 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<StringElementType::UTF8> (const ReadBuf 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<StringElementType::ASCII> (const ReadBu 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<StringElementType::UTF16> (const ReadBu 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"); |

