LanguageCategory*
GetCategoryForLanguage (lldb::LanguageType lang_type);
+ static std::vector<lldb::LanguageType>
+ GetCandidateLanguages (lldb::LanguageType lang_type);
+
private:
static std::vector<lldb::LanguageType>
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)
- {
- 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)
+
+ enum class StringElementType
{
- 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
struct StringPrinterBufferPointer
{
public:
-
typedef std::function<void(const T*)> Deleter;
StringPrinterBufferPointer (std::nullptr_t ptr) :
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);
// 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 {
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
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();
}
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);
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);
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);
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)
{
if (error.Fail())
return false;
}
- ReadStringAndDumpToStreamOptions options(valobj);
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
options.SetLocation(location);
options.SetProcessSP(process_sp);
options.SetStream(&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)
{
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);
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)
{
has_explicit_length = true;
location++;
}
- ReadStringAndDumpToStreamOptions options(valobj);
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
options.SetLocation(location);
options.SetProcessSP(process_sp);
options.SetStream(&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
{
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);
}
}
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:
#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"
// 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);
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};
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};
{
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;
// 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
UTF8**,
UTF8*,
ConversionFlags),
- const ReadBufferAndDumpToStreamOptions& dump_options)
+ const StringPrinter::ReadBufferAndDumpToStreamOptions& dump_options)
{
Stream &stream(*dump_options.GetStream());
if (dump_options.GetPrefixToken() != 0)
}
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
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)
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());
SetQuote(options.GetQuote());
SetEscapeNonPrintables(options.GetEscapeNonPrintables());
SetBinaryZeroIsTerminator(options.GetBinaryZeroIsTerminator());
+ SetLanguage(options.GetLanguage());
}
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;
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)
template<typename SourceDataType>
static bool
-ReadUTFBufferAndDumpToStream (const ReadStringAndDumpToStreamOptions& options,
+ReadUTFBufferAndDumpToStream (const StringPrinter::ReadStringAndDumpToStreamOptions& options,
ConversionResult (*ConvertFunction) (const SourceDataType**,
const SourceDataType*,
UTF8**,
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);
template <>
bool
-StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF8> (const ReadStringAndDumpToStreamOptions& options)
+StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8> (const ReadStringAndDumpToStreamOptions& options)
{
return ReadUTFBufferAndDumpToStream<UTF8>(options,
nullptr);
template <>
bool
-StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF16> (const ReadStringAndDumpToStreamOptions& options)
+StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF16> (const ReadStringAndDumpToStreamOptions& options)
{
return ReadUTFBufferAndDumpToStream<UTF16>(options,
ConvertUTF16toUTF8);
template <>
bool
-StringPrinter::ReadStringAndDumpToStream<StringElementType::UTF32> (const ReadStringAndDumpToStreamOptions& options)
+StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32> (const ReadStringAndDumpToStreamOptions& options)
{
return ReadUTFBufferAndDumpToStream<UTF32>(options,
ConvertUTF32toUTF8);
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");
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?
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");
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");
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;
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;
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);
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;
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');
options.SetSourceSize(1);
options.SetBinaryZeroIsTerminator(false);
- return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF16>(options);
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
}
bool
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');
options.SetSourceSize(1);
options.SetBinaryZeroIsTerminator(false);
- return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF32>(options);
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
}
bool
if (error.Fail())
return false;
- ReadBufferAndDumpToStreamOptions options(valobj);
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
options.SetData(data);
options.SetStream(&stream);
options.SetPrefixToken('L');
options.SetSourceSize(1);
options.SetBinaryZeroIsTerminator(false);
- return StringPrinter::ReadBufferAndDumpToStream<StringElementType::UTF16>(options);
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
}
// 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');
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:
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;
}
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;
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;