diff options
Diffstat (limited to 'lldb/source/DataFormatters')
| -rw-r--r-- | lldb/source/DataFormatters/Cocoa.cpp | 30 | ||||
| -rw-r--r-- | lldb/source/DataFormatters/FormatManager.cpp | 6 | ||||
| -rw-r--r-- | lldb/source/DataFormatters/StringPrinter.cpp | 88 |
3 files changed, 83 insertions, 41 deletions
diff --git a/lldb/source/DataFormatters/Cocoa.cpp b/lldb/source/DataFormatters/Cocoa.cpp index 0942c8da2a3..64d4edb6af0 100644 --- a/lldb/source/DataFormatters/Cocoa.cpp +++ b/lldb/source/DataFormatters/Cocoa.cpp @@ -866,7 +866,7 @@ lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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::NSStringSummaryProvider (ValueObject& valobj, Stream& 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); } } diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index bc8e8e7c063..3fdb9b8d103 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -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: 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"); |

