diff options
author | Enrico Granata <granata.enrico@gmail.com> | 2011-08-05 01:32:50 +0000 |
---|---|---|
committer | Enrico Granata <granata.enrico@gmail.com> | 2011-08-05 01:32:50 +0000 |
commit | f1af1ed6d2d56b4e9e7b2c4744ffdf104b9c37cb (patch) | |
tree | b497548d35a9d1349976bb8d98a8169e9ecba128 | |
parent | 2536b51aaee9be8581c2a467fc796d200d78ae94 (diff) | |
download | bcm5719-llvm-f1af1ed6d2d56b4e9e7b2c4744ffdf104b9c37cb.tar.gz bcm5719-llvm-f1af1ed6d2d56b4e9e7b2c4744ffdf104b9c37cb.zip |
Option --regex (-x) now also works for synthetic children:
- Added a test case in python-synth
Minor code improvements in categories, making them ready for adding new element types
llvm-svn: 136957
5 files changed, 442 insertions, 297 deletions
diff --git a/lldb/include/lldb/Core/FormatManager.h b/lldb/include/lldb/Core/FormatManager.h index 4bb8e8785b2..ad1c993882f 100644 --- a/lldb/include/lldb/Core/FormatManager.h +++ b/lldb/include/lldb/Core/FormatManager.h @@ -632,6 +632,17 @@ private: public: + enum FormatCategoryItem + { + eSummary = 0x0001, + eRegexSummary = 0x1001, + eFilter = 0x0002, + eRegexFilter = 0x1002, + }; + + typedef uint16_t FormatCategoryItems; + static const uint16_t ALL_ITEM_TYPES = 0xFFFF; + typedef SummaryNavigator::SharedPointer SummaryNavigatorSP; typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP; typedef FilterNavigator::SharedPointer FilterNavigatorSP; @@ -715,24 +726,59 @@ public: void ClearSummaries() { - m_summary_nav->Clear(); - m_regex_summary_nav->Clear(); + Clear(eSummary | eRegexSummary); } // just a shortcut for (Summary()->Delete(name) || RegexSummary()->Delete(name)) bool DeleteSummaries(const char* name) { - bool del_sum = m_summary_nav->Delete(name); - bool del_rex = m_regex_summary_nav->Delete(name); - - return (del_sum || del_rex); + return Delete(name, (eSummary | eRegexSummary)); + } + + + void + Clear(FormatCategoryItems items = ALL_ITEM_TYPES) + { + if ( (items & eSummary) ) + m_summary_nav->Clear(); + if ( (items & eRegexSummary) ) + m_regex_summary_nav->Clear(); + if ( (items & eFilter) ) + m_filter_nav->Clear(); + if ( (items & eRegexFilter) ) + m_regex_filter_nav->Clear(); + } + + bool + Delete(const char* name, + FormatCategoryItems items = ALL_ITEM_TYPES) + { + bool success = false; + if ( (items & eSummary) ) + success = m_summary_nav->Delete(name) || success; + if ( (items & eRegexSummary) ) + success = m_regex_summary_nav->Delete(name) || success; + if ( (items & eFilter) ) + success = m_filter_nav->Delete(name) || success; + if ( (items & eRegexFilter) ) + success = m_regex_filter_nav->Delete(name) || success; + return success; } uint32_t - GetCount() + GetCount(FormatCategoryItems items = ALL_ITEM_TYPES) { - return Summary()->GetCount() + RegexSummary()->GetCount(); + uint32_t count = 0; + if ( (items & eSummary) ) + count += m_summary_nav->GetCount(); + if ( (items & eRegexSummary) ) + count += m_regex_summary_nav->GetCount(); + if ( (items & eFilter) ) + count += m_filter_nav->GetCount(); + if ( (items & eRegexFilter) ) + count += m_regex_filter_nav->GetCount(); + return count; } std::string diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index 959432a1203..9687986b4e3 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -1168,8 +1168,7 @@ private: const FormatCategory::SharedPointer& cate) { const char* name = (const char*)param; - cate->Summary()->Delete(name); - cate->RegexSummary()->Delete(name); + cate->Delete(name, FormatCategory::eSummary | FormatCategory::eRegexSummary); return true; } @@ -1892,6 +1891,7 @@ public: //------------------------------------------------------------------------- bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry); +bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticFilter::SharedPointer& entry); class CommandObjectTypeSynthList; @@ -2044,6 +2044,12 @@ private: cate->Filter()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp); + if (cate->RegexFilter()->GetCount() > 0) + { + result->GetOutputStream().Printf("Regex-based filters (slower):\n"); + cate->RegexFilter()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp); + } + return true; } @@ -2059,6 +2065,7 @@ private: } friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry); + friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticFilter::SharedPointer& entry); }; bool @@ -2070,6 +2077,15 @@ CommandObjectTypeSynthList_LoopCallback (void* pt2self, return param->self->LoopCallback(type, entry, param->regex, param->result); } +bool +CommandObjectTypeSynthRXList_LoopCallback (void* pt2self, + lldb::RegularExpressionSP regex, + const SyntheticFilter::SharedPointer& entry) +{ + CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; + return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); +} + OptionDefinition CommandObjectTypeSynthList::CommandOptions::g_option_table[] = @@ -2157,8 +2173,7 @@ private: const FormatCategory::SharedPointer& cate) { const char* name = (const char*)param; - cate->Filter()->Delete(name); - return true; + return cate->Delete(name, FormatCategory::eFilter | FormatCategory::eRegexFilter); } public: @@ -2217,6 +2232,7 @@ public: Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category); bool delete_category = category->Filter()->Delete(typeCS.GetCString()); + delete_category = category->RegexFilter()->Delete(typeCS.GetCString()) || delete_category; if (delete_category) { @@ -2315,7 +2331,7 @@ private: const char* cate_name, const FormatCategory::SharedPointer& cate) { - cate->Filter()->Clear(); + cate->Clear(FormatCategory::eFilter | FormatCategory::eRegexFilter); return true; } @@ -2352,6 +2368,7 @@ public: else Debugger::Formatting::Categories::Get(ConstString(NULL), category); category->Filter()->Clear(); + category->RegexFilter()->Clear(); } result.SetStatus(eReturnStatusSuccessFinishResult); @@ -2506,7 +2523,11 @@ public: const char *type_name = options->m_target_types.GetStringAtIndex(i); ConstString typeCS(type_name); if (typeCS) - category->Filter()->Add(typeCS.GetCString(), synth_provider); + CommandObjectTypeSynthAdd::AddSynth(typeCS, + synth_provider, + options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth, + options->m_category, + NULL); else { out_stream->Printf ("Internal error #6: no script attached.\n"); @@ -2517,319 +2538,242 @@ public: } }; -class CommandObjectTypeSynthAdd : public CommandObject +void +CommandObjectTypeSynthAdd::CollectPythonScript (SynthAddOptions *options, + CommandReturnObject &result) { - -private: - - class CommandOptions : public Options + InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger())); + if (reader_sp && options) { - typedef std::vector<std::string> option_vector; - public: - - CommandOptions (CommandInterpreter &interpreter) : - Options (interpreter) - { - } - virtual - ~CommandOptions (){} + InputReaderEZ::InitializationParameters ipr; - virtual Error - SetOptionValue (uint32_t option_idx, const char *option_arg) + Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" "))); + if (err.Success()) { - Error error; - char short_option = (char) m_getopt_table[option_idx].val; - bool success; - - switch (short_option) - { - case 'C': - m_cascade = Args::StringToBoolean(option_arg, true, &success); - if (!success) - error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); - break; - case 'c': - m_expr_paths.push_back(option_arg); - has_child_list = true; - break; - case 'P': - handwrite_python = true; - break; - case 'l': - m_class_name = std::string(option_arg); - is_class_based = true; - break; - case 'p': - m_skip_pointers = true; - break; - case 'r': - m_skip_references = true; - break; - case 'w': - m_category = ConstString(option_arg).GetCString(); - break; - default: - error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); - break; - } - - return error; + m_interpreter.GetDebugger().PushInputReader (reader_sp); + result.SetStatus (eReturnStatusSuccessFinishNoResult); } - - void - OptionParsingStarting () + else { - m_cascade = true; - m_class_name = ""; - m_skip_pointers = false; - m_skip_references = false; - m_category = NULL; - m_expr_paths.clear(); - is_class_based = false; - handwrite_python = false; - has_child_list = false; + result.AppendError (err.AsCString()); + result.SetStatus (eReturnStatusFailed); } - - const OptionDefinition* - GetDefinitions () + } + else + { + result.AppendError("out of memory"); + result.SetStatus (eReturnStatusFailed); + } +} + +bool +CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result) +{ + SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers, + m_options.m_skip_references, + m_options.m_cascade, + m_options.m_regex, + m_options.m_category); + + const size_t argc = command.GetArgumentCount(); + + for (size_t i = 0; i < argc; i++) { + const char* typeA = command.GetArgumentAtIndex(i); + if (typeA && *typeA) + options->m_target_types << typeA; + else { - return g_option_table; + result.AppendError("empty typenames not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; } - - // Options table: Required for subclasses of Options. - - static OptionDefinition g_option_table[]; - - // Instance variables to hold the values for command options. - - bool m_cascade; - bool m_skip_references; - bool m_skip_pointers; - std::string m_class_name; - bool m_input_python; - option_vector m_expr_paths; - const char* m_category; - - bool is_class_based; - - bool handwrite_python; - - bool has_child_list; - - typedef option_vector::iterator ExpressionPathsIterator; - }; + } - CommandOptions m_options; + CollectPythonScript(options,result); + return result.Succeeded(); +} - virtual Options * - GetOptions () +bool +CommandObjectTypeSynthAdd::Execute_ChildrenList (Args& command, CommandReturnObject &result) +{ + const size_t argc = command.GetArgumentCount(); + + if (argc < 1) { - return &m_options; + result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; } - void - CollectPythonScript (SynthAddOptions *options, - CommandReturnObject &result) + if (m_options.m_expr_paths.size() == 0) { - InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger())); - if (reader_sp && options) - { - - InputReaderEZ::InitializationParameters ipr; - - Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" "))); - if (err.Success()) - { - m_interpreter.GetDebugger().PushInputReader (reader_sp); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - } - else - { - result.AppendError (err.AsCString()); - result.SetStatus (eReturnStatusFailed); - } - } + result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + SyntheticChildrenSP entry; + + SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade, + m_options.m_skip_pointers, + m_options.m_skip_references); + + entry.reset(impl); + + // go through the expression paths + CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end(); + + for (begin = m_options.m_expr_paths.begin(); begin != end; begin++) + impl->AddExpressionPath(*begin); + + + // now I have a valid provider, let's add it to every type + + lldb::FormatCategorySP category; + Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category); + + for (size_t i = 0; i < argc; i++) { + const char* typeA = command.GetArgumentAtIndex(i); + ConstString typeCS(typeA); + if (typeCS) + AddSynth(typeCS, + entry, + m_options.m_regex ? eRegexSynth : eRegularSynth, + m_options.m_category, + NULL); else { - result.AppendError("out of memory"); - result.SetStatus (eReturnStatusFailed); + result.AppendError("empty typenames not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; } } - bool - Execute_HandwritePython (Args& command, CommandReturnObject &result) + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); +} + +bool +CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result) +{ + const size_t argc = command.GetArgumentCount(); + + if (argc < 1) { - SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers, - m_options.m_skip_references, - m_options.m_cascade, - m_options.m_category); - - const size_t argc = command.GetArgumentCount(); - - for (size_t i = 0; i < argc; i++) { - const char* typeA = command.GetArgumentAtIndex(i); - if (typeA && *typeA) - options->m_target_types << typeA; - else - { - result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - - CollectPythonScript(options,result); - return result.Succeeded(); + result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; } - bool - Execute_ChildrenList (Args& command, CommandReturnObject &result) + if (m_options.m_class_name.empty() && !m_options.m_input_python) { - const size_t argc = command.GetArgumentCount(); - - if (argc < 1) - { - result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - - if (m_options.m_expr_paths.size() == 0) + result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + SyntheticChildrenSP entry; + + SyntheticScriptProvider* impl = new SyntheticScriptProvider(m_options.m_cascade, + m_options.m_skip_pointers, + m_options.m_skip_references, + m_options.m_class_name); + + entry.reset(impl); + + // now I have a valid provider, let's add it to every type + + lldb::FormatCategorySP category; + Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category); + + for (size_t i = 0; i < argc; i++) { + const char* typeA = command.GetArgumentAtIndex(i); + ConstString typeCS(typeA); + if (typeCS) + AddSynth(typeCS, + entry, + m_options.m_regex ? eRegexSynth : eRegularSynth, + m_options.m_category, + NULL); + else { - result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str()); + result.AppendError("empty typenames not allowed"); result.SetStatus(eReturnStatusFailed); return false; } - - SyntheticChildrenSP entry; - - SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade, - m_options.m_skip_pointers, - m_options.m_skip_references); - - entry.reset(impl); - - // go through the expression paths - CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end(); - - for (begin = m_options.m_expr_paths.begin(); begin != end; begin++) - impl->AddExpressionPath(*begin); - - - // now I have a valid provider, let's add it to every type - - lldb::FormatCategorySP category; - Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category); - - for (size_t i = 0; i < argc; i++) { - const char* typeA = command.GetArgumentAtIndex(i); - ConstString typeCS(typeA); - if (typeCS) - category->Filter()->Add(typeCS.GetCString(), entry); - else - { - result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); } - bool - Execute_PythonClass (Args& command, CommandReturnObject &result) + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); +} + +CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) : +CommandObject (interpreter, + "type synth add", + "Add a new synthetic provider for a type.", + NULL), m_options (interpreter) +{ + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatPlus; + + type_arg.push_back (type_style_arg); + + m_arguments.push_back (type_arg); + +} + +bool +CommandObjectTypeSynthAdd::AddSynth(const ConstString& type_name, + SyntheticChildrenSP entry, + SynthFormatType type, + const char* category_name, + Error* error) +{ + lldb::FormatCategorySP category; + Debugger::Formatting::Categories::Get(ConstString(category_name), category); + + if (type == eRegexSynth) { - const size_t argc = command.GetArgumentCount(); - - if (argc < 1) - { - result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - - if (m_options.m_class_name.empty() && !m_options.m_input_python) + RegularExpressionSP typeRX(new RegularExpression()); + if (!typeRX->Compile(type_name.GetCString())) { - result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); + if (error) + error->SetErrorString("regex format error (maybe this is not really a regex?)"); return false; } - SyntheticChildrenSP entry; - - SyntheticScriptProvider* impl = new SyntheticScriptProvider(m_options.m_cascade, - m_options.m_skip_pointers, - m_options.m_skip_references, - m_options.m_class_name); - - entry.reset(impl); - - // now I have a valid provider, let's add it to every type - - lldb::FormatCategorySP category; - Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category); - - for (size_t i = 0; i < argc; i++) { - const char* typeA = command.GetArgumentAtIndex(i); - ConstString typeCS(typeA); - if (typeCS) - category->Filter()->Add(typeCS.GetCString(), entry); - else - { - result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } - -public: - - CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) : - CommandObject (interpreter, - "type synth add", - "Add a new synthetic provider for a type.", - NULL), m_options (interpreter) - { - CommandArgumentEntry type_arg; - CommandArgumentData type_style_arg; - - type_style_arg.arg_type = eArgTypeName; - type_style_arg.arg_repetition = eArgRepeatPlus; - - type_arg.push_back (type_style_arg); - - m_arguments.push_back (type_arg); + category->RegexFilter()->Delete(type_name.GetCString()); + category->RegexFilter()->Add(typeRX, entry); + return true; } - - ~CommandObjectTypeSynthAdd () + else { + category->Filter()->Add(type_name.GetCString(), entry); + return true; } +} - bool - Execute (Args& command, CommandReturnObject &result) +bool +CommandObjectTypeSynthAdd::Execute (Args& command, CommandReturnObject &result) +{ + if (m_options.handwrite_python) + return Execute_HandwritePython(command, result); + else if (m_options.is_class_based) + return Execute_PythonClass(command, result); + else if (m_options.has_child_list) + return Execute_ChildrenList(command, result); + else { - if (m_options.handwrite_python) - return Execute_HandwritePython(command, result); - else if (m_options.is_class_based) - return Execute_PythonClass(command, result); - else if (m_options.has_child_list) - return Execute_ChildrenList(command, result); - else - { - result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line"); - result.SetStatus(eReturnStatusFailed); - return false; - } + result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line"); + result.SetStatus(eReturnStatusFailed); + return false; } -}; +} OptionDefinition CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] = @@ -2841,6 +2785,7 @@ CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] = { LLDB_OPT_SET_1, false, "child", 'c', required_argument, NULL, 0, eArgTypeName, "Include this expression path in the synthetic view."}, { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypeName, "Use this Python class to produce synthetic children."}, { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."}, + { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; diff --git a/lldb/source/Commands/CommandObjectType.h b/lldb/source/Commands/CommandObjectType.h index 1e5279de470..aa230bb31f2 100644 --- a/lldb/source/Commands/CommandObjectType.h +++ b/lldb/source/Commands/CommandObjectType.h @@ -78,6 +78,7 @@ public: bool m_skip_pointers; bool m_skip_references; bool m_cascade; + bool m_regex; StringList m_user_source; StringList m_target_types; @@ -86,10 +87,12 @@ public: SynthAddOptions(bool sptr, bool sref, bool casc, + bool regx, const char* catg) : m_skip_pointers(sptr), m_skip_references(sref), m_cascade(casc), + m_regex(regx), m_user_source(), m_target_types(), m_category(catg) @@ -203,7 +206,157 @@ public: const char* category, Error* error = NULL); }; - + +class CommandObjectTypeSynthAdd : public CommandObject +{ + +private: + + class CommandOptions : public Options + { + typedef std::vector<std::string> option_vector; + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter) + { + } + + virtual + ~CommandOptions (){} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + bool success; + + switch (short_option) + { + case 'C': + m_cascade = Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); + break; + case 'c': + m_expr_paths.push_back(option_arg); + has_child_list = true; + break; + case 'P': + handwrite_python = true; + break; + case 'l': + m_class_name = std::string(option_arg); + is_class_based = true; + break; + case 'p': + m_skip_pointers = true; + break; + case 'r': + m_skip_references = true; + break; + case 'w': + m_category = ConstString(option_arg).GetCString(); + break; + case 'x': + m_regex = true; + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_cascade = true; + m_class_name = ""; + m_skip_pointers = false; + m_skip_references = false; + m_category = NULL; + m_expr_paths.clear(); + is_class_based = false; + handwrite_python = false; + has_child_list = false; + m_regex = false; + } + + const OptionDefinition* + GetDefinitions () + { + return g_option_table; + } + + // Options table: Required for subclasses of Options. + + static OptionDefinition g_option_table[]; + + // Instance variables to hold the values for command options. + + bool m_cascade; + bool m_skip_references; + bool m_skip_pointers; + std::string m_class_name; + bool m_input_python; + option_vector m_expr_paths; + const char* m_category; + + bool is_class_based; + + bool handwrite_python; + + bool has_child_list; + + bool m_regex; + + typedef option_vector::iterator ExpressionPathsIterator; + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } + + void + CollectPythonScript (SynthAddOptions *options, + CommandReturnObject &result); + bool + Execute_HandwritePython (Args& command, CommandReturnObject &result); + bool + Execute_ChildrenList (Args& command, CommandReturnObject &result); + bool + Execute_PythonClass (Args& command, CommandReturnObject &result); + bool + Execute (Args& command, CommandReturnObject &result); + +public: + + enum SynthFormatType + { + eRegularSynth, + eRegexSynth, + }; + + CommandObjectTypeSynthAdd (CommandInterpreter &interpreter); + + ~CommandObjectTypeSynthAdd () + { + } + + static bool + AddSynth(const ConstString& type_name, + lldb::SyntheticChildrenSP entry, + SynthFormatType type, + const char* category_name, + Error* error); +}; } // namespace lldb_private diff --git a/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py b/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py index 1161f75e0ce..548e22b6afd 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py @@ -300,13 +300,14 @@ class DataFormatterTestCase(TestBase): '[3] = \"!!!\"']) # now std::map<K,V> + # also take a chance to test regex synth here self.runCmd("n") self.runCmd("frame variable ii -T") self.runCmd("script from StdMapSynthProvider import *") - self.runCmd("type summary add std::intint_map intint_map -f \"map has ${svar%#} items\" -e") - self.runCmd("type synth add std::intint_map intint_map -l StdMapSynthProvider") + self.runCmd("type summary add -x \"std::map<\" -f \"map has ${svar%#} items\" -e") + self.runCmd("type synth add -x \"std::map<\" -l StdMapSynthProvider") self.expect('frame variable ii', @@ -356,8 +357,8 @@ class DataFormatterTestCase(TestBase): self.runCmd("n") self.runCmd("frame variable si -T") - self.runCmd("type summary add std::strint_map strint_map -f \"map has ${svar%#} items\" -e") - self.runCmd("type synth add std::strint_map strint_map -l StdMapSynthProvider") + #self.runCmd("type summary add std::strint_map strint_map -f \"map has ${svar%#} items\" -e") + #self.runCmd("type synth add std::strint_map strint_map -l StdMapSynthProvider") self.expect('frame variable si', substrs = ['map has 0 items', @@ -400,8 +401,8 @@ class DataFormatterTestCase(TestBase): self.runCmd("n") self.runCmd("frame variable is -T") - self.runCmd("type summary add std::intstr_map intstr_map -f \"map has ${svar%#} items\" -e") - self.runCmd("type synth add std::intstr_map intstr_map -l StdMapSynthProvider") + #self.runCmd("type summary add std::intstr_map intstr_map -f \"map has ${svar%#} items\" -e") + #self.runCmd("type synth add std::intstr_map intstr_map -l StdMapSynthProvider") self.expect('frame variable is', substrs = ['map has 0 items', @@ -433,8 +434,8 @@ class DataFormatterTestCase(TestBase): self.runCmd("n") self.runCmd("frame variable ss -T") - self.runCmd("type summary add std::strstr_map strstr_map -f \"map has ${svar%#} items\" -e") - self.runCmd("type synth add std::strstr_map strstr_map -l StdMapSynthProvider") + #self.runCmd("type summary add std::strstr_map strstr_map -f \"map has ${svar%#} items\" -e") + #self.runCmd("type synth add std::strstr_map strstr_map -l StdMapSynthProvider") self.expect('frame variable ss', substrs = ['map has 0 items', diff --git a/lldb/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp index 9a189861d6f..67f04e721d2 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp +++ b/lldb/test/functionalities/data-formatter/data-formatter-python-synth/main.cpp @@ -8,10 +8,10 @@ typedef std::vector<std::string> string_vect; typedef std::list<int> int_list; typedef std::list<std::string> string_list; -typedef std::map<int, int> intint_map; -typedef std::map<std::string, int> strint_map; -typedef std::map<int, std::string> intstr_map; -typedef std::map<std::string, std::string> strstr_map; +#define intint_map std::map<int, int> +#define strint_map std::map<std::string, int> +#define intstr_map std::map<int, std::string> +#define strstr_map std::map<std::string, std::string> struct foo { |