| //===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "CommandObjectType.h" |
| |
| // C Includes |
| |
| #include <ctype.h> |
| |
| // C++ Includes |
| |
| #include "lldb/Core/DataVisualization.h" |
| #include "lldb/Core/ConstString.h" |
| #include "lldb/Core/Debugger.h" |
| #include "lldb/Core/InputReaderEZ.h" |
| #include "lldb/Core/RegularExpression.h" |
| #include "lldb/Core/State.h" |
| #include "lldb/Core/StringList.h" |
| #include "lldb/Interpreter/CommandInterpreter.h" |
| #include "lldb/Interpreter/CommandObject.h" |
| #include "lldb/Interpreter/CommandReturnObject.h" |
| #include "lldb/Interpreter/Options.h" |
| #include "lldb/Interpreter/OptionGroupFormat.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| |
| class ScriptAddOptions |
| { |
| |
| public: |
| |
| TypeSummaryImpl::Flags m_flags; |
| |
| StringList m_target_types; |
| StringList m_user_source; |
| |
| bool m_regex; |
| |
| ConstString m_name; |
| |
| std::string m_category; |
| |
| ScriptAddOptions(const TypeSummaryImpl::Flags& flags, |
| bool regx, |
| const ConstString& name, |
| std::string catg) : |
| m_flags(flags), |
| m_regex(regx), |
| m_name(name), |
| m_category(catg) |
| { |
| } |
| |
| typedef STD_SHARED_PTR(ScriptAddOptions) SharedPointer; |
| |
| }; |
| |
| class SynthAddOptions |
| { |
| |
| public: |
| |
| bool m_skip_pointers; |
| bool m_skip_references; |
| bool m_cascade; |
| bool m_regex; |
| StringList m_user_source; |
| StringList m_target_types; |
| |
| std::string m_category; |
| |
| SynthAddOptions(bool sptr, |
| bool sref, |
| bool casc, |
| bool regx, |
| std::string catg) : |
| m_skip_pointers(sptr), |
| m_skip_references(sref), |
| m_cascade(casc), |
| m_regex(regx), |
| m_user_source(), |
| m_target_types(), |
| m_category(catg) |
| { |
| } |
| |
| typedef STD_SHARED_PTR(SynthAddOptions) SharedPointer; |
| |
| }; |
| |
| |
| |
| class CommandObjectTypeSummaryAdd : public CommandObject |
| { |
| |
| private: |
| |
| class CommandOptions : public Options |
| { |
| public: |
| |
| CommandOptions (CommandInterpreter &interpreter) : |
| Options (interpreter) |
| { |
| } |
| |
| virtual |
| ~CommandOptions (){} |
| |
| virtual Error |
| SetOptionValue (uint32_t option_idx, const char *option_arg); |
| |
| void |
| OptionParsingStarting (); |
| |
| 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. |
| |
| TypeSummaryImpl::Flags m_flags; |
| bool m_regex; |
| std::string m_format_string; |
| ConstString m_name; |
| std::string m_python_script; |
| std::string m_python_function; |
| bool m_is_add_script; |
| std::string m_category; |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| void |
| CollectPythonScript(ScriptAddOptions *options, |
| CommandReturnObject &result); |
| |
| bool |
| Execute_ScriptSummary (Args& command, CommandReturnObject &result); |
| |
| bool |
| Execute_StringSummary (Args& command, CommandReturnObject &result); |
| |
| public: |
| |
| enum SummaryFormatType |
| { |
| eRegularSummary, |
| eRegexSummary, |
| eNamedSummary |
| }; |
| |
| CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter); |
| |
| ~CommandObjectTypeSummaryAdd () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result); |
| |
| static bool |
| AddSummary(const ConstString& type_name, |
| lldb::TypeSummaryImplSP entry, |
| SummaryFormatType type, |
| std::string category, |
| Error* error = NULL); |
| }; |
| |
| class CommandObjectTypeSynthAdd : public CommandObject |
| { |
| |
| private: |
| |
| class CommandOptions : public Options |
| { |
| 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", option_arg); |
| 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 = std::string(option_arg); |
| break; |
| case 'x': |
| m_regex = true; |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_cascade = true; |
| m_class_name = ""; |
| m_skip_pointers = false; |
| m_skip_references = false; |
| m_category = "default"; |
| is_class_based = false; |
| handwrite_python = 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; |
| std::string m_category; |
| |
| bool is_class_based; |
| |
| bool handwrite_python; |
| |
| bool m_regex; |
| |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| void |
| CollectPythonScript (SynthAddOptions *options, |
| CommandReturnObject &result); |
| bool |
| Execute_HandwritePython (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, |
| std::string category_name, |
| Error* error); |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeFormatAdd |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeFormatAdd : public CommandObject |
| { |
| |
| private: |
| |
| class CommandOptions : public OptionGroup |
| { |
| public: |
| |
| CommandOptions () : |
| OptionGroup() |
| { |
| } |
| |
| virtual |
| ~CommandOptions () |
| { |
| } |
| |
| virtual uint32_t |
| GetNumDefinitions (); |
| |
| virtual const OptionDefinition* |
| GetDefinitions () |
| { |
| return g_option_table; |
| } |
| |
| virtual void |
| OptionParsingStarting (CommandInterpreter &interpreter) |
| { |
| m_cascade = true; |
| m_skip_pointers = false; |
| m_skip_references = false; |
| } |
| virtual Error |
| SetOptionValue (CommandInterpreter &interpreter, |
| uint32_t option_idx, |
| const char *option_value) |
| { |
| Error error; |
| const char short_option = (char) g_option_table[option_idx].short_option; |
| bool success; |
| |
| switch (short_option) |
| { |
| case 'C': |
| m_cascade = Args::StringToBoolean(option_value, true, &success); |
| if (!success) |
| error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value); |
| break; |
| case 'p': |
| m_skip_pointers = true; |
| break; |
| case 'r': |
| m_skip_references = true; |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| // 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; |
| }; |
| |
| OptionGroupOptions m_option_group; |
| OptionGroupFormat m_format_options; |
| CommandOptions m_command_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_option_group; |
| } |
| |
| public: |
| CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type format add", |
| "Add a new formatting style for a type.", |
| NULL), |
| m_option_group (interpreter), |
| m_format_options (eFormatInvalid), |
| m_command_options () |
| { |
| 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); |
| |
| SetHelpLong( |
| "Some examples of using this command.\n" |
| "We use as reference the following snippet of code:\n" |
| "\n" |
| "typedef int Aint;\n" |
| "typedef float Afloat;\n" |
| "typedef Aint Bint;\n" |
| "typedef Afloat Bfloat;\n" |
| "\n" |
| "Aint ix = 5;\n" |
| "Bint iy = 5;\n" |
| "\n" |
| "Afloat fx = 3.14;\n" |
| "BFloat fy = 3.14;\n" |
| "\n" |
| "Typing:\n" |
| "type format add -f hex AInt\n" |
| "frame variable iy\n" |
| "will produce an hex display of iy, because no formatter is available for Bint and the one for Aint is used instead\n" |
| "To prevent this type\n" |
| "type format add -f hex -C no AInt\n" |
| "\n" |
| "A similar reasoning applies to\n" |
| "type format add -f hex -C no float -p\n" |
| "which now prints all floats and float&s as hexadecimal, but does not format float*s\n" |
| "and does not change the default display for Afloat and Bfloat objects.\n" |
| ); |
| |
| // Add the "--format" to all options groups |
| m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_ALL); |
| m_option_group.Append (&m_command_options); |
| m_option_group.Finalize(); |
| |
| } |
| |
| ~CommandObjectTypeFormatAdd () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| 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; |
| } |
| |
| const Format format = m_format_options.GetFormat(); |
| if (format == eFormatInvalid) |
| { |
| result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| TypeFormatImplSP entry; |
| |
| entry.reset(new TypeFormatImpl(format, |
| TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade). |
| SetSkipPointers(m_command_options.m_skip_pointers). |
| SetSkipReferences(m_command_options.m_skip_references))); |
| |
| // now I have a valid format, let's add it to every type |
| |
| for (size_t i = 0; i < argc; i++) |
| { |
| const char* typeA = command.GetArgumentAtIndex(i); |
| ConstString typeCS(typeA); |
| if (typeCS) |
| DataVisualization::ValueFormats::Add(typeCS, entry); |
| else |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| }; |
| |
| OptionDefinition |
| CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, |
| { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, |
| { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, |
| }; |
| |
| |
| uint32_t |
| CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions () |
| { |
| return sizeof(g_option_table) / sizeof (OptionDefinition); |
| } |
| |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeFormatDelete |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeFormatDelete : public CommandObject |
| { |
| public: |
| CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type format delete", |
| "Delete an existing formatting style for a type.", |
| NULL) |
| { |
| CommandArgumentEntry type_arg; |
| CommandArgumentData type_style_arg; |
| |
| type_style_arg.arg_type = eArgTypeName; |
| type_style_arg.arg_repetition = eArgRepeatPlain; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| |
| } |
| |
| ~CommandObjectTypeFormatDelete () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc != 1) |
| { |
| result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| const char* typeA = command.GetArgumentAtIndex(0); |
| ConstString typeCS(typeA); |
| |
| if (!typeCS) |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| |
| if (DataVisualization::ValueFormats::Delete(typeCS)) |
| { |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| else |
| { |
| result.AppendErrorWithFormat ("no custom format for %s.\n", typeA); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| } |
| |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeFormatClear |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeFormatClear : public CommandObject |
| { |
| public: |
| CommandObjectTypeFormatClear (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type format clear", |
| "Delete all existing format styles.", |
| NULL) |
| { |
| } |
| |
| ~CommandObjectTypeFormatClear () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| DataVisualization::ValueFormats::Clear(); |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeFormatList |
| //------------------------------------------------------------------------- |
| |
| bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry); |
| |
| class CommandObjectTypeFormatList; |
| |
| struct CommandObjectTypeFormatList_LoopCallbackParam { |
| CommandObjectTypeFormatList* self; |
| CommandReturnObject* result; |
| RegularExpression* regex; |
| CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R, |
| RegularExpression* X = NULL) : self(S), result(R), regex(X) {} |
| }; |
| |
| class CommandObjectTypeFormatList : public CommandObject |
| { |
| public: |
| CommandObjectTypeFormatList (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type format list", |
| "Show a list of current formatting styles.", |
| NULL) |
| { |
| CommandArgumentEntry type_arg; |
| CommandArgumentData type_style_arg; |
| |
| type_style_arg.arg_type = eArgTypeName; |
| type_style_arg.arg_repetition = eArgRepeatOptional; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| } |
| |
| ~CommandObjectTypeFormatList () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| CommandObjectTypeFormatList_LoopCallbackParam *param; |
| |
| if (argc == 1) |
| { |
| RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); |
| regex->Compile(command.GetArgumentAtIndex(0)); |
| param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex); |
| } |
| else |
| param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result); |
| DataVisualization::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param); |
| delete param; |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| private: |
| |
| bool |
| LoopCallback (ConstString type, |
| const lldb::TypeFormatImplSP& entry, |
| RegularExpression* regex, |
| CommandReturnObject *result) |
| { |
| if (regex == NULL || regex->Execute(type.AsCString())) |
| { |
| result->GetOutputStream().Printf ("%s: %s\n", type.AsCString(), |
| entry->GetDescription().c_str()); |
| } |
| return true; |
| } |
| |
| friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry); |
| |
| }; |
| |
| bool |
| CommandObjectTypeFormatList_LoopCallback ( |
| void* pt2self, |
| ConstString type, |
| const lldb::TypeFormatImplSP& entry) |
| { |
| CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self; |
| return param->self->LoopCallback(type, entry, param->regex, param->result); |
| } |
| |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeSummaryAdd |
| //------------------------------------------------------------------------- |
| |
| static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" |
| "def function (valobj,dict):"; |
| |
| class TypeScriptAddInputReader : public InputReaderEZ |
| { |
| private: |
| DISALLOW_COPY_AND_ASSIGN (TypeScriptAddInputReader); |
| public: |
| TypeScriptAddInputReader(Debugger& debugger) : |
| InputReaderEZ(debugger) |
| {} |
| |
| virtual |
| ~TypeScriptAddInputReader() |
| { |
| } |
| |
| virtual void ActivateHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); |
| bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); |
| if (!batch_mode) |
| { |
| out_stream->Printf ("%s\n", g_summary_addreader_instructions); |
| if (data.reader.GetPrompt()) |
| out_stream->Printf ("%s", data.reader.GetPrompt()); |
| out_stream->Flush(); |
| } |
| } |
| |
| virtual void ReactivateHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); |
| bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); |
| if (data.reader.GetPrompt() && !batch_mode) |
| { |
| out_stream->Printf ("%s", data.reader.GetPrompt()); |
| out_stream->Flush(); |
| } |
| } |
| virtual void GotTokenHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); |
| bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); |
| if (data.bytes && data.bytes_len && data.baton) |
| { |
| ((ScriptAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len); |
| } |
| if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) |
| { |
| out_stream->Printf ("%s", data.reader.GetPrompt()); |
| out_stream->Flush(); |
| } |
| } |
| virtual void InterruptHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); |
| bool batch_mode = data.reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); |
| data.reader.SetIsDone (true); |
| if (!batch_mode) |
| { |
| out_stream->Printf ("Warning: No command attached to breakpoint.\n"); |
| out_stream->Flush(); |
| } |
| } |
| virtual void EOFHandler(HandlerData& data) |
| { |
| data.reader.SetIsDone (true); |
| } |
| virtual void DoneHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.reader.GetDebugger().GetAsyncOutputStream(); |
| ScriptAddOptions *options_ptr = ((ScriptAddOptions*)data.baton); |
| if (!options_ptr) |
| { |
| out_stream->Printf ("Internal error #1: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| |
| ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope |
| |
| ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); |
| if (!interpreter) |
| { |
| out_stream->Printf ("Internal error #2: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| std::string funct_name_str; |
| if (!interpreter->GenerateTypeScriptFunction (options->m_user_source, |
| funct_name_str)) |
| { |
| out_stream->Printf ("Internal error #3: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| if (funct_name_str.empty()) |
| { |
| out_stream->Printf ("Internal error #4: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| // now I have a valid function name, let's add this as script for every type in the list |
| |
| TypeSummaryImplSP script_format; |
| script_format.reset(new ScriptSummaryFormat(options->m_flags, |
| funct_name_str.c_str(), |
| options->m_user_source.CopyList(" ").c_str())); |
| |
| Error error; |
| |
| for (size_t i = 0; i < options->m_target_types.GetSize(); i++) |
| { |
| const char *type_name = options->m_target_types.GetStringAtIndex(i); |
| CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name), |
| script_format, |
| (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary), |
| options->m_category, |
| &error); |
| if (error.Fail()) |
| { |
| out_stream->Printf ("%s", error.AsCString()); |
| out_stream->Flush(); |
| return; |
| } |
| } |
| |
| if (options->m_name) |
| { |
| CommandObjectTypeSummaryAdd::AddSummary (options->m_name, |
| script_format, |
| CommandObjectTypeSummaryAdd::eNamedSummary, |
| options->m_category, |
| &error); |
| if (error.Fail()) |
| { |
| CommandObjectTypeSummaryAdd::AddSummary (options->m_name, |
| script_format, |
| CommandObjectTypeSummaryAdd::eNamedSummary, |
| options->m_category, |
| &error); |
| if (error.Fail()) |
| { |
| out_stream->Printf ("%s", error.AsCString()); |
| out_stream->Flush(); |
| return; |
| } |
| } |
| else |
| { |
| out_stream->Printf ("%s", error.AsCString()); |
| out_stream->Flush(); |
| return; |
| } |
| } |
| else |
| { |
| if (error.AsCString()) |
| { |
| out_stream->PutCString (error.AsCString()); |
| out_stream->Flush(); |
| } |
| return; |
| } |
| } |
| }; |
| |
| #endif // #ifndef LLDB_DISABLE_PYTHON |
| |
| Error |
| CommandObjectTypeSummaryAdd::CommandOptions::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_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success)); |
| if (!success) |
| error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg); |
| break; |
| case 'e': |
| m_flags.SetDontShowChildren(false); |
| break; |
| case 'v': |
| m_flags.SetDontShowValue(true); |
| break; |
| case 'c': |
| m_flags.SetShowMembersOneLiner(true); |
| break; |
| case 's': |
| m_format_string = std::string(option_arg); |
| break; |
| case 'p': |
| m_flags.SetSkipPointers(true); |
| break; |
| case 'r': |
| m_flags.SetSkipReferences(true); |
| break; |
| case 'x': |
| m_regex = true; |
| break; |
| case 'n': |
| m_name.SetCString(option_arg); |
| break; |
| case 'o': |
| m_python_script = std::string(option_arg); |
| m_is_add_script = true; |
| break; |
| case 'F': |
| m_python_function = std::string(option_arg); |
| m_is_add_script = true; |
| break; |
| case 'P': |
| m_is_add_script = true; |
| break; |
| case 'w': |
| m_category = std::string(option_arg); |
| break; |
| case 'O': |
| m_flags.SetHideItemNames(true); |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting () |
| { |
| m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false); |
| m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false); |
| |
| m_regex = false; |
| m_name.Clear(); |
| m_python_script = ""; |
| m_python_function = ""; |
| m_format_string = ""; |
| m_is_add_script = false; |
| m_category = "default"; |
| } |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| void |
| CommandObjectTypeSummaryAdd::CollectPythonScript (ScriptAddOptions *options, |
| CommandReturnObject &result) |
| { |
| InputReaderSP reader_sp (new TypeScriptAddInputReader(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); |
| } |
| } |
| else |
| { |
| result.AppendError("out of memory"); |
| result.SetStatus (eReturnStatusFailed); |
| } |
| } |
| |
| bool |
| CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc < 1 && !m_options.m_name) |
| { |
| result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| TypeSummaryImplSP script_format; |
| |
| if (!m_options.m_python_function.empty()) // we have a Python function ready to use |
| { |
| ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); |
| if (!interpreter) |
| { |
| result.AppendError ("Internal error #1N: no script attached.\n"); |
| result.SetStatus (eReturnStatusFailed); |
| return false; |
| } |
| const char *funct_name = m_options.m_python_function.c_str(); |
| if (!funct_name || !funct_name[0]) |
| { |
| result.AppendError ("Internal error #2N: no script attached.\n"); |
| result.SetStatus (eReturnStatusFailed); |
| return false; |
| } |
| |
| std::string code = (" " + m_options.m_python_function + "(valobj,dict)"); |
| |
| script_format.reset(new ScriptSummaryFormat(m_options.m_flags, |
| funct_name, |
| code.c_str())); |
| } |
| else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it |
| { |
| ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); |
| if (!interpreter) |
| { |
| result.AppendError ("Internal error #1Q: no script attached.\n"); |
| result.SetStatus (eReturnStatusFailed); |
| return false; |
| } |
| StringList funct_sl; |
| funct_sl << m_options.m_python_script.c_str(); |
| std::string funct_name_str; |
| if (!interpreter->GenerateTypeScriptFunction (funct_sl, |
| funct_name_str)) |
| { |
| result.AppendError ("Internal error #2Q: no script attached.\n"); |
| result.SetStatus (eReturnStatusFailed); |
| return false; |
| } |
| if (funct_name_str.empty()) |
| { |
| result.AppendError ("Internal error #3Q: no script attached.\n"); |
| result.SetStatus (eReturnStatusFailed); |
| return false; |
| } |
| |
| std::string code = " " + m_options.m_python_script; |
| |
| script_format.reset(new ScriptSummaryFormat(m_options.m_flags, |
| funct_name_str.c_str(), |
| code.c_str())); |
| } |
| else // use an InputReader to grab Python code from the user |
| { |
| ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags, |
| m_options.m_regex, |
| m_options.m_name, |
| m_options.m_category); |
| |
| 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(); |
| } |
| |
| // if I am here, script_format must point to something good, so I can add that |
| // as a script summary to all interested parties |
| |
| Error error; |
| |
| for (size_t i = 0; i < command.GetArgumentCount(); i++) |
| { |
| const char *type_name = command.GetArgumentAtIndex(i); |
| CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name), |
| script_format, |
| (m_options.m_regex ? eRegexSummary : eRegularSummary), |
| m_options.m_category, |
| &error); |
| if (error.Fail()) |
| { |
| result.AppendError(error.AsCString()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| |
| if (m_options.m_name) |
| { |
| AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error); |
| if (error.Fail()) |
| { |
| result.AppendError(error.AsCString()); |
| result.AppendError("added to types, but not given a name"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| |
| return result.Succeeded(); |
| } |
| |
| #endif |
| |
| |
| bool |
| CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc < 1 && !m_options.m_name) |
| { |
| result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty()) |
| { |
| result.AppendError("empty summary strings not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str()); |
| |
| // ${var%S} is an endless recursion, prevent it |
| if (strcmp(format_cstr, "${var%S}") == 0) |
| { |
| result.AppendError("recursive summary not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| Error error; |
| |
| lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags, |
| format_cstr)); |
| |
| if (error.Fail()) |
| { |
| result.AppendError(error.AsCString()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| // now I have a valid format, let's add it to every type |
| |
| for (size_t i = 0; i < argc; i++) |
| { |
| const char* typeA = command.GetArgumentAtIndex(i); |
| if (!typeA || typeA[0] == '\0') |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| ConstString typeCS(typeA); |
| |
| AddSummary(typeCS, |
| entry, |
| (m_options.m_regex ? eRegexSummary : eRegularSummary), |
| m_options.m_category, |
| &error); |
| |
| if (error.Fail()) |
| { |
| result.AppendError(error.AsCString()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| |
| if (m_options.m_name) |
| { |
| AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error); |
| if (error.Fail()) |
| { |
| result.AppendError(error.AsCString()); |
| result.AppendError("added to types, but not given a name"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| |
| CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type summary add", |
| "Add a new summary style 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); |
| |
| SetHelpLong( |
| "Some examples of using this command.\n" |
| "We use as reference the following snippet of code:\n" |
| "struct JustADemo\n" |
| "{\n" |
| "int* ptr;\n" |
| "float value;\n" |
| "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n" |
| "};\n" |
| "JustADemo object(42,3.14);\n" |
| "struct AnotherDemo : public JustADemo\n" |
| "{\n" |
| "uint8_t byte;\n" |
| "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n" |
| "};\n" |
| "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n" |
| "\n" |
| "type summary add --summary-string \"the answer is ${*var.ptr}\" JustADemo\n" |
| "when typing frame variable object you will get \"the answer is 42\"\n" |
| "type summary add --summary-string \"the answer is ${*var.ptr}, and the question is ${var.value}\" JustADemo\n" |
| "when typing frame variable object you will get \"the answer is 42 and the question is 3.14\"\n" |
| "\n" |
| "Alternatively, you could also say\n" |
| "type summary add --summary-string \"${var%V} -> ${*var}\" \"int *\"\n" |
| "and replace the above summary string with\n" |
| "type summary add --summary-string \"the answer is ${var.ptr}, and the question is ${var.value}\" JustADemo\n" |
| "to obtain a similar result\n" |
| "\n" |
| "To add a summary valid for both JustADemo and AnotherDemo you can use the scoping operator, as in:\n" |
| "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes\n" |
| "\n" |
| "This will be used for both variables of type JustADemo and AnotherDemo. To prevent this, change the -C to read -C no\n" |
| "If you do not want pointers to be shown using that summary, you can use the -p option, as in:\n" |
| "type summary add --summary-string \"${var.ptr}, ${var.value},{${var.byte}}\" JustADemo -C yes -p\n" |
| "A similar option -r exists for references.\n" |
| "\n" |
| "If you simply want a one-line summary of the content of your variable, without typing an explicit string to that effect\n" |
| "you can use the -c option, without giving any summary string:\n" |
| "type summary add -c JustADemo\n" |
| "frame variable object\n" |
| "the output being similar to (ptr=0xsomeaddress, value=3.14)\n" |
| "\n" |
| "If you want to display some summary text, but also expand the structure of your object, you can add the -e option, as in:\n" |
| "type summary add -e --summary-string \"*ptr = ${*var.ptr}\" JustADemo\n" |
| "Here the value of the int* is displayed, followed by the standard LLDB sequence of children objects, one per line.\n" |
| "to get an output like:\n" |
| "\n" |
| "*ptr = 42 {\n" |
| " ptr = 0xsomeaddress\n" |
| " value = 3.14\n" |
| "}\n" |
| "\n" |
| "You can also add Python summaries, in which case you will use lldb public API to gather information from your variables" |
| "and elaborate them to a meaningful summary inside a script written in Python. The variable object will be passed to your" |
| "script as an SBValue object. The following example might help you when starting to use the Python summaries feature:\n" |
| "type summary add JustADemo -o \"value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();\"\n" |
| "If you prefer to type your scripts on multiple lines, you will use the -P option and then type your script, ending it with " |
| "the word DONE on a line by itself to mark you're finished editing your code:\n" |
| "(lldb)type summary add JustADemo -P\n" |
| " value = valobj.GetChildMemberWithName('value');\n" |
| " return 'My value is ' + value.GetValue();\n" |
| "DONE\n" |
| "(lldb) <-- type further LLDB commands here\n" |
| ); |
| } |
| |
| bool |
| CommandObjectTypeSummaryAdd::Execute (Args& command, CommandReturnObject &result) |
| { |
| if (m_options.m_is_add_script) |
| { |
| #ifndef LLDB_DISABLE_PYTHON |
| return Execute_ScriptSummary(command, result); |
| #else |
| result.AppendError ("python is disabled"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| #endif |
| } |
| |
| return Execute_StringSummary(command, result); |
| } |
| |
| bool |
| CommandObjectTypeSummaryAdd::AddSummary(const ConstString& type_name, |
| TypeSummaryImplSP entry, |
| SummaryFormatType type, |
| std::string category_name, |
| Error* error) |
| { |
| lldb::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); |
| |
| if (type == eRegexSummary) |
| { |
| RegularExpressionSP typeRX(new RegularExpression()); |
| if (!typeRX->Compile(type_name.GetCString())) |
| { |
| if (error) |
| error->SetErrorString("regex format error (maybe this is not really a regex?)"); |
| return false; |
| } |
| |
| category->GetRegexSummaryNavigator()->Delete(type_name); |
| category->GetRegexSummaryNavigator()->Add(typeRX, entry); |
| |
| return true; |
| } |
| else if (type == eNamedSummary) |
| { |
| // system named summaries do not exist (yet?) |
| DataVisualization::NamedSummaryFormats::Add(type_name,entry); |
| return true; |
| } |
| else |
| { |
| category->GetSummaryNavigator()->Add(type_name, entry); |
| return true; |
| } |
| } |
| |
| OptionDefinition |
| CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, |
| { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, |
| { LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."}, |
| { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, |
| { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, |
| { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, |
| { LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."}, |
| { LLDB_OPT_SET_1 , false, "omit-names", 'O', no_argument, NULL, 0, eArgTypeNone, "If true, omit value names in the summary display."}, |
| { LLDB_OPT_SET_2 , true, "summary-string", 's', required_argument, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."}, |
| { LLDB_OPT_SET_3, false, "python-script", 'o', required_argument, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."}, |
| { LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."}, |
| { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."}, |
| { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', no_argument, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."}, |
| { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeSummaryDelete |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeSummaryDelete : public CommandObject |
| { |
| private: |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'a': |
| m_delete_all = true; |
| break; |
| case 'w': |
| m_category = std::string(option_arg); |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_delete_all = false; |
| m_category = "default"; |
| } |
| |
| 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_delete_all; |
| std::string m_category; |
| |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| static bool |
| PerCategoryCallback(void* param, |
| const lldb::TypeCategoryImplSP& category_sp) |
| { |
| ConstString *name = (ConstString*)param; |
| category_sp->Delete(*name, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); |
| return true; |
| } |
| |
| public: |
| CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type summary delete", |
| "Delete an existing summary style 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 = eArgRepeatPlain; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| |
| } |
| |
| ~CommandObjectTypeSummaryDelete () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc != 1) |
| { |
| result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| const char* typeA = command.GetArgumentAtIndex(0); |
| ConstString typeCS(typeA); |
| |
| if (!typeCS) |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| if (m_options.m_delete_all) |
| { |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS); |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| |
| lldb::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); |
| |
| bool delete_category = category->Delete(typeCS, |
| eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); |
| bool delete_named = DataVisualization::NamedSummaryFormats::Delete(typeCS); |
| |
| if (delete_category || delete_named) |
| { |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| else |
| { |
| result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| } |
| }; |
| |
| OptionDefinition |
| CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Delete from every category."}, |
| { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Delete from given category."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| class CommandObjectTypeSummaryClear : public CommandObject |
| { |
| private: |
| |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'a': |
| m_delete_all = true; |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_delete_all = 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_delete_all; |
| bool m_delete_named; |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| static bool |
| PerCategoryCallback(void* param, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| cate->GetSummaryNavigator()->Clear(); |
| cate->GetRegexSummaryNavigator()->Clear(); |
| return true; |
| |
| } |
| |
| public: |
| CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type summary clear", |
| "Delete all existing summary styles.", |
| NULL), m_options(interpreter) |
| { |
| } |
| |
| ~CommandObjectTypeSummaryClear () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| |
| if (m_options.m_delete_all) |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); |
| |
| else |
| { |
| lldb::TypeCategoryImplSP category; |
| if (command.GetArgumentCount() > 0) |
| { |
| const char* cat_name = command.GetArgumentAtIndex(0); |
| ConstString cat_nameCS(cat_name); |
| DataVisualization::Categories::GetCategory(cat_nameCS, category); |
| } |
| else |
| DataVisualization::Categories::GetCategory(ConstString(NULL), category); |
| category->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary); |
| } |
| |
| DataVisualization::NamedSummaryFormats::Clear(); |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| }; |
| |
| OptionDefinition |
| CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Clear every category."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeSummaryList |
| //------------------------------------------------------------------------- |
| |
| bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const StringSummaryFormat::SharedPointer& entry); |
| bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry); |
| |
| class CommandObjectTypeSummaryList; |
| |
| struct CommandObjectTypeSummaryList_LoopCallbackParam { |
| CommandObjectTypeSummaryList* self; |
| CommandReturnObject* result; |
| RegularExpression* regex; |
| RegularExpression* cate_regex; |
| CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R, |
| RegularExpression* X = NULL, |
| RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} |
| }; |
| |
| class CommandObjectTypeSummaryList : public CommandObject |
| { |
| |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'w': |
| m_category_regex = std::string(option_arg); |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_category_regex = ""; |
| } |
| |
| 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. |
| |
| std::string m_category_regex; |
| |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| public: |
| CommandObjectTypeSummaryList (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type summary list", |
| "Show a list of current summary styles.", |
| NULL), m_options(interpreter) |
| { |
| CommandArgumentEntry type_arg; |
| CommandArgumentData type_style_arg; |
| |
| type_style_arg.arg_type = eArgTypeName; |
| type_style_arg.arg_repetition = eArgRepeatOptional; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| } |
| |
| ~CommandObjectTypeSummaryList () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| CommandObjectTypeSummaryList_LoopCallbackParam *param; |
| RegularExpression* cate_regex = |
| m_options.m_category_regex.empty() ? NULL : |
| new RegularExpression(m_options.m_category_regex.c_str()); |
| |
| if (argc == 1) |
| { |
| RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); |
| regex->Compile(command.GetArgumentAtIndex(0)); |
| param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex,cate_regex); |
| } |
| else |
| param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex); |
| |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); |
| |
| if (DataVisualization::NamedSummaryFormats::GetCount() > 0) |
| { |
| result.GetOutputStream().Printf("Named summaries:\n"); |
| if (argc == 1) |
| { |
| RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); |
| regex->Compile(command.GetArgumentAtIndex(0)); |
| param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex); |
| } |
| else |
| param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result); |
| DataVisualization::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param); |
| delete param; |
| } |
| |
| if (cate_regex) |
| delete cate_regex; |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| private: |
| |
| static bool |
| PerCategoryCallback(void* param_vp, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| |
| CommandObjectTypeSummaryList_LoopCallbackParam* param = |
| (CommandObjectTypeSummaryList_LoopCallbackParam*)param_vp; |
| CommandReturnObject* result = param->result; |
| |
| const char* cate_name = cate->GetName(); |
| |
| // if the category is disabled or empty and there is no regex, just skip it |
| if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary) == 0) && param->cate_regex == NULL) |
| return true; |
| |
| // if we have a regex and this category does not match it, just skip it |
| if(param->cate_regex != NULL && param->cate_regex->Execute(cate_name) == false) |
| return true; |
| |
| result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", |
| cate_name, |
| (cate->IsEnabled() ? "enabled" : "disabled")); |
| |
| cate->GetSummaryNavigator()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp); |
| |
| if (cate->GetRegexSummaryNavigator()->GetCount() > 0) |
| { |
| result->GetOutputStream().Printf("Regex-based summaries (slower):\n"); |
| cate->GetRegexSummaryNavigator()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp); |
| } |
| return true; |
| } |
| |
| |
| bool |
| LoopCallback (const char* type, |
| const lldb::TypeSummaryImplSP& entry, |
| RegularExpression* regex, |
| CommandReturnObject *result) |
| { |
| if (regex == NULL || regex->Execute(type)) |
| result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); |
| return true; |
| } |
| |
| friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry); |
| friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry); |
| }; |
| |
| bool |
| CommandObjectTypeSummaryList_LoopCallback ( |
| void* pt2self, |
| ConstString type, |
| const lldb::TypeSummaryImplSP& entry) |
| { |
| CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; |
| return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); |
| } |
| |
| bool |
| CommandObjectTypeRXSummaryList_LoopCallback ( |
| void* pt2self, |
| lldb::RegularExpressionSP regex, |
| const lldb::TypeSummaryImplSP& entry) |
| { |
| CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self; |
| return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); |
| } |
| |
| OptionDefinition |
| CommandObjectTypeSummaryList::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeCategoryEnable |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeCategoryEnable : public CommandObject |
| { |
| public: |
| CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type category enable", |
| "Enable a category as a source of formatters.", |
| NULL) |
| { |
| 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); |
| |
| } |
| |
| ~CommandObjectTypeCategoryEnable () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc < 1) |
| { |
| result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| for (int i = argc - 1; i >= 0; i--) |
| { |
| const char* typeA = command.GetArgumentAtIndex(i); |
| ConstString typeCS(typeA); |
| |
| if (!typeCS) |
| { |
| result.AppendError("empty category name not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| DataVisualization::Categories::Enable(typeCS); |
| lldb::TypeCategoryImplSP cate; |
| if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get()) |
| { |
| if (cate->GetCount() == 0) |
| { |
| result.AppendWarning("empty category enabled (typo?)"); |
| } |
| } |
| } |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeCategoryDelete |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeCategoryDelete : public CommandObject |
| { |
| public: |
| CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type category delete", |
| "Delete a category and all associated formatters.", |
| NULL) |
| { |
| 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); |
| |
| } |
| |
| ~CommandObjectTypeCategoryDelete () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc < 1) |
| { |
| result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| bool success = true; |
| |
| // the order is not relevant here |
| for (int i = argc - 1; i >= 0; i--) |
| { |
| const char* typeA = command.GetArgumentAtIndex(i); |
| ConstString typeCS(typeA); |
| |
| if (!typeCS) |
| { |
| result.AppendError("empty category name not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| if (!DataVisualization::Categories::Delete(typeCS)) |
| success = false; // keep deleting even if we hit an error |
| } |
| if (success) |
| { |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| else |
| { |
| result.AppendError("cannot delete one or more categories\n"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeCategoryDisable |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeCategoryDisable : public CommandObject |
| { |
| public: |
| CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type category disable", |
| "Disable a category as a source of formatters.", |
| NULL) |
| { |
| 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); |
| |
| } |
| |
| ~CommandObjectTypeCategoryDisable () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc < 1) |
| { |
| result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| // the order is not relevant here |
| for (int i = argc - 1; i >= 0; i--) |
| { |
| const char* typeA = command.GetArgumentAtIndex(i); |
| ConstString typeCS(typeA); |
| |
| if (!typeCS) |
| { |
| result.AppendError("empty category name not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| DataVisualization::Categories::Disable(typeCS); |
| } |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeCategoryList |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeCategoryList : public CommandObject |
| { |
| private: |
| |
| struct CommandObjectTypeCategoryList_CallbackParam |
| { |
| CommandReturnObject* result; |
| RegularExpression* regex; |
| |
| CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res, |
| RegularExpression* rex = NULL) : |
| result(res), |
| regex(rex) |
| { |
| } |
| |
| }; |
| |
| static bool |
| PerCategoryCallback(void* param_vp, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| CommandObjectTypeCategoryList_CallbackParam* param = |
| (CommandObjectTypeCategoryList_CallbackParam*)param_vp; |
| CommandReturnObject* result = param->result; |
| RegularExpression* regex = param->regex; |
| |
| const char* cate_name = cate->GetName(); |
| |
| if (regex == NULL || regex->Execute(cate_name)) |
| result->GetOutputStream().Printf("Category %s is%s enabled\n", |
| cate_name, |
| (cate->IsEnabled() ? "" : " not")); |
| return true; |
| } |
| public: |
| CommandObjectTypeCategoryList (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type category list", |
| "Provide a list of all existing categories.", |
| NULL) |
| { |
| CommandArgumentEntry type_arg; |
| CommandArgumentData type_style_arg; |
| |
| type_style_arg.arg_type = eArgTypeName; |
| type_style_arg.arg_repetition = eArgRepeatOptional; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| } |
| |
| ~CommandObjectTypeCategoryList () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| RegularExpression* regex = NULL; |
| |
| if (argc == 0) |
| ; |
| else if (argc == 1) |
| regex = new RegularExpression(command.GetArgumentAtIndex(0)); |
| else |
| { |
| result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| CommandObjectTypeCategoryList_CallbackParam param(&result, |
| regex); |
| |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback, ¶m); |
| |
| if (regex) |
| delete regex; |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeFilterList |
| //------------------------------------------------------------------------- |
| |
| bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); |
| bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); |
| |
| class CommandObjectTypeFilterList; |
| |
| struct CommandObjectTypeFilterList_LoopCallbackParam { |
| CommandObjectTypeFilterList* self; |
| CommandReturnObject* result; |
| RegularExpression* regex; |
| RegularExpression* cate_regex; |
| CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R, |
| RegularExpression* X = NULL, |
| RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} |
| }; |
| |
| class CommandObjectTypeFilterList : public CommandObject |
| { |
| |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'w': |
| m_category_regex = std::string(option_arg); |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_category_regex = ""; |
| } |
| |
| 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. |
| |
| std::string m_category_regex; |
| |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| public: |
| CommandObjectTypeFilterList (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type filter list", |
| "Show a list of current filters.", |
| NULL), m_options(interpreter) |
| { |
| CommandArgumentEntry type_arg; |
| CommandArgumentData type_style_arg; |
| |
| type_style_arg.arg_type = eArgTypeName; |
| type_style_arg.arg_repetition = eArgRepeatOptional; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| } |
| |
| ~CommandObjectTypeFilterList () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| CommandObjectTypeFilterList_LoopCallbackParam *param; |
| RegularExpression* cate_regex = |
| m_options.m_category_regex.empty() ? NULL : |
| new RegularExpression(m_options.m_category_regex.c_str()); |
| |
| if (argc == 1) |
| { |
| RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); |
| regex->Compile(command.GetArgumentAtIndex(0)); |
| param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex); |
| } |
| else |
| param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex); |
| |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); |
| |
| if (cate_regex) |
| delete cate_regex; |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| private: |
| |
| static bool |
| PerCategoryCallback(void* param_vp, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| |
| const char* cate_name = cate->GetName(); |
| |
| CommandObjectTypeFilterList_LoopCallbackParam* param = |
| (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp; |
| CommandReturnObject* result = param->result; |
| |
| // if the category is disabled or empty and there is no regex, just skip it |
| if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL) |
| return true; |
| |
| // if we have a regex and this category does not match it, just skip it |
| if(param->cate_regex != NULL && param->cate_regex->Execute(cate_name) == false) |
| return true; |
| |
| result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", |
| cate_name, |
| (cate->IsEnabled() ? "enabled" : "disabled")); |
| |
| cate->GetFilterNavigator()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp); |
| |
| if (cate->GetRegexFilterNavigator()->GetCount() > 0) |
| { |
| result->GetOutputStream().Printf("Regex-based filters (slower):\n"); |
| cate->GetRegexFilterNavigator()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp); |
| } |
| |
| return true; |
| } |
| |
| bool |
| LoopCallback (const char* type, |
| const SyntheticChildren::SharedPointer& entry, |
| RegularExpression* regex, |
| CommandReturnObject *result) |
| { |
| if (regex == NULL || regex->Execute(type)) |
| result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); |
| return true; |
| } |
| |
| friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); |
| friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); |
| }; |
| |
| bool |
| CommandObjectTypeFilterList_LoopCallback (void* pt2self, |
| ConstString type, |
| const SyntheticChildren::SharedPointer& entry) |
| { |
| CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; |
| return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); |
| } |
| |
| bool |
| CommandObjectTypeFilterRXList_LoopCallback (void* pt2self, |
| lldb::RegularExpressionSP regex, |
| const SyntheticChildren::SharedPointer& entry) |
| { |
| CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; |
| return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); |
| } |
| |
| |
| OptionDefinition |
| CommandObjectTypeFilterList::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeSynthList |
| //------------------------------------------------------------------------- |
| |
| bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); |
| bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); |
| |
| class CommandObjectTypeSynthList; |
| |
| struct CommandObjectTypeSynthList_LoopCallbackParam { |
| CommandObjectTypeSynthList* self; |
| CommandReturnObject* result; |
| RegularExpression* regex; |
| RegularExpression* cate_regex; |
| CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R, |
| RegularExpression* X = NULL, |
| RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} |
| }; |
| |
| class CommandObjectTypeSynthList : public CommandObject |
| { |
| |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'w': |
| m_category_regex = std::string(option_arg); |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_category_regex = ""; |
| } |
| |
| 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. |
| |
| std::string m_category_regex; |
| |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| public: |
| CommandObjectTypeSynthList (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type synthetic list", |
| "Show a list of current synthetic providers.", |
| NULL), m_options(interpreter) |
| { |
| CommandArgumentEntry type_arg; |
| CommandArgumentData type_style_arg; |
| |
| type_style_arg.arg_type = eArgTypeName; |
| type_style_arg.arg_repetition = eArgRepeatOptional; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| } |
| |
| ~CommandObjectTypeSynthList () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| CommandObjectTypeSynthList_LoopCallbackParam *param; |
| RegularExpression* cate_regex = |
| m_options.m_category_regex.empty() ? NULL : |
| new RegularExpression(m_options.m_category_regex.c_str()); |
| |
| if (argc == 1) |
| { |
| RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); |
| regex->Compile(command.GetArgumentAtIndex(0)); |
| param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex); |
| } |
| else |
| param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex); |
| |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback,param); |
| |
| if (cate_regex) |
| delete cate_regex; |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| private: |
| |
| static bool |
| PerCategoryCallback(void* param_vp, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| |
| CommandObjectTypeSynthList_LoopCallbackParam* param = |
| (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp; |
| CommandReturnObject* result = param->result; |
| |
| const char* cate_name = cate->GetName(); |
| |
| // if the category is disabled or empty and there is no regex, just skip it |
| if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL) |
| return true; |
| |
| // if we have a regex and this category does not match it, just skip it |
| if(param->cate_regex != NULL && param->cate_regex->Execute(cate_name) == false) |
| return true; |
| |
| result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", |
| cate_name, |
| (cate->IsEnabled() ? "enabled" : "disabled")); |
| |
| cate->GetSyntheticNavigator()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp); |
| |
| if (cate->GetRegexSyntheticNavigator()->GetCount() > 0) |
| { |
| result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n"); |
| cate->GetRegexSyntheticNavigator()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp); |
| } |
| |
| return true; |
| } |
| |
| bool |
| LoopCallback (const char* type, |
| const SyntheticChildren::SharedPointer& entry, |
| RegularExpression* regex, |
| CommandReturnObject *result) |
| { |
| if (regex == NULL || regex->Execute(type)) |
| result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); |
| return true; |
| } |
| |
| friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry); |
| friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); |
| }; |
| |
| bool |
| CommandObjectTypeSynthList_LoopCallback (void* pt2self, |
| ConstString type, |
| const SyntheticChildren::SharedPointer& entry) |
| { |
| CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; |
| return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result); |
| } |
| |
| bool |
| CommandObjectTypeSynthRXList_LoopCallback (void* pt2self, |
| lldb::RegularExpressionSP regex, |
| const SyntheticChildren::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[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| #endif // #ifndef LLDB_DISABLE_PYTHON |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeFilterDelete |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeFilterDelete : public CommandObject |
| { |
| private: |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'a': |
| m_delete_all = true; |
| break; |
| case 'w': |
| m_category = std::string(option_arg); |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_delete_all = false; |
| m_category = "default"; |
| } |
| |
| 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_delete_all; |
| std::string m_category; |
| |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| static bool |
| PerCategoryCallback(void* param, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| ConstString *name = (ConstString*)param; |
| return cate->Delete(*name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); |
| } |
| |
| public: |
| CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type filter delete", |
| "Delete an existing filter 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 = eArgRepeatPlain; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| |
| } |
| |
| ~CommandObjectTypeFilterDelete () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc != 1) |
| { |
| result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| const char* typeA = command.GetArgumentAtIndex(0); |
| ConstString typeCS(typeA); |
| |
| if (!typeCS) |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| if (m_options.m_delete_all) |
| { |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| |
| lldb::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); |
| |
| bool delete_category = category->GetFilterNavigator()->Delete(typeCS); |
| delete_category = category->GetRegexFilterNavigator()->Delete(typeCS) || delete_category; |
| |
| if (delete_category) |
| { |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| else |
| { |
| result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| } |
| }; |
| |
| OptionDefinition |
| CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Delete from every category."}, |
| { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Delete from given category."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeSynthDelete |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeSynthDelete : public CommandObject |
| { |
| private: |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'a': |
| m_delete_all = true; |
| break; |
| case 'w': |
| m_category = std::string(option_arg); |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_delete_all = false; |
| m_category = "default"; |
| } |
| |
| 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_delete_all; |
| std::string m_category; |
| |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| static bool |
| PerCategoryCallback(void* param, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| ConstString* name = (ConstString*)param; |
| return cate->Delete(*name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); |
| } |
| |
| public: |
| CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type synthetic delete", |
| "Delete an existing 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 = eArgRepeatPlain; |
| |
| type_arg.push_back (type_style_arg); |
| |
| m_arguments.push_back (type_arg); |
| |
| } |
| |
| ~CommandObjectTypeSynthDelete () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| |
| if (argc != 1) |
| { |
| result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| const char* typeA = command.GetArgumentAtIndex(0); |
| ConstString typeCS(typeA); |
| |
| if (!typeCS) |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| if (m_options.m_delete_all) |
| { |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS); |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| |
| lldb::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); |
| |
| bool delete_category = category->GetSyntheticNavigator()->Delete(typeCS); |
| delete_category = category->GetRegexSyntheticNavigator()->Delete(typeCS) || delete_category; |
| |
| if (delete_category) |
| { |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| else |
| { |
| result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| } |
| }; |
| |
| OptionDefinition |
| CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Delete from every category."}, |
| { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Delete from given category."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| #endif // #ifndef LLDB_DISABLE_PYTHON |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeFilterClear |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeFilterClear : public CommandObject |
| { |
| private: |
| |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'a': |
| m_delete_all = true; |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_delete_all = 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_delete_all; |
| bool m_delete_named; |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| static bool |
| PerCategoryCallback(void* param, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter); |
| return true; |
| |
| } |
| |
| public: |
| CommandObjectTypeFilterClear (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type filter clear", |
| "Delete all existing filters.", |
| NULL), m_options(interpreter) |
| { |
| } |
| |
| ~CommandObjectTypeFilterClear () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| |
| if (m_options.m_delete_all) |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); |
| |
| else |
| { |
| lldb::TypeCategoryImplSP category; |
| if (command.GetArgumentCount() > 0) |
| { |
| const char* cat_name = command.GetArgumentAtIndex(0); |
| ConstString cat_nameCS(cat_name); |
| DataVisualization::Categories::GetCategory(cat_nameCS, category); |
| } |
| else |
| DataVisualization::Categories::GetCategory(ConstString(NULL), category); |
| category->GetFilterNavigator()->Clear(); |
| category->GetRegexFilterNavigator()->Clear(); |
| } |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| }; |
| |
| OptionDefinition |
| CommandObjectTypeFilterClear::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Clear every category."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| //------------------------------------------------------------------------- |
| // CommandObjectTypeSynthClear |
| //------------------------------------------------------------------------- |
| |
| class CommandObjectTypeSynthClear : public CommandObject |
| { |
| private: |
| |
| class CommandOptions : public Options |
| { |
| 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; |
| |
| switch (short_option) |
| { |
| case 'a': |
| m_delete_all = true; |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_delete_all = 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_delete_all; |
| bool m_delete_named; |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| static bool |
| PerCategoryCallback(void* param, |
| const lldb::TypeCategoryImplSP& cate) |
| { |
| cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth); |
| return true; |
| |
| } |
| |
| public: |
| CommandObjectTypeSynthClear (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type synthetic clear", |
| "Delete all existing synthetic providers.", |
| NULL), m_options(interpreter) |
| { |
| } |
| |
| ~CommandObjectTypeSynthClear () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| |
| if (m_options.m_delete_all) |
| DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL); |
| |
| else |
| { |
| lldb::TypeCategoryImplSP category; |
| if (command.GetArgumentCount() > 0) |
| { |
| const char* cat_name = command.GetArgumentAtIndex(0); |
| ConstString cat_nameCS(cat_name); |
| DataVisualization::Categories::GetCategory(cat_nameCS, category); |
| } |
| else |
| DataVisualization::Categories::GetCategory(ConstString(NULL), category); |
| category->GetSyntheticNavigator()->Clear(); |
| category->GetRegexSyntheticNavigator()->Clear(); |
| } |
| |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return result.Succeeded(); |
| } |
| |
| }; |
| |
| OptionDefinition |
| CommandObjectTypeSynthClear::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Clear every category."}, |
| { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } |
| }; |
| |
| |
| //------------------------------------------------------------------------- |
| // TypeSynthAddInputReader |
| //------------------------------------------------------------------------- |
| |
| static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" |
| "You must define a Python class with these methods:\n" |
| " def __init__(self, valobj, dict):\n" |
| " def num_children(self):\n" |
| " def get_child_at_index(self, index):\n" |
| " def get_child_index(self, name):\n" |
| "Optionally, you can also define a method:\n" |
| " def update(self):\n" |
| "if your synthetic provider is holding on to any per-object state variables (currently, this is not implemented because of the way LLDB handles instances of SBValue and you should not rely on object persistence and per-object state)\n" |
| "class synthProvider:"; |
| |
| class TypeSynthAddInputReader : public InputReaderEZ |
| { |
| public: |
| TypeSynthAddInputReader(Debugger& debugger) : |
| InputReaderEZ(debugger) |
| {} |
| |
| virtual |
| ~TypeSynthAddInputReader() |
| { |
| } |
| |
| virtual void ActivateHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.GetOutStream(); |
| bool batch_mode = data.GetBatchMode(); |
| if (!batch_mode) |
| { |
| out_stream->Printf ("%s\n", g_synth_addreader_instructions); |
| if (data.reader.GetPrompt()) |
| out_stream->Printf ("%s", data.reader.GetPrompt()); |
| out_stream->Flush(); |
| } |
| } |
| |
| virtual void ReactivateHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.GetOutStream(); |
| bool batch_mode = data.GetBatchMode(); |
| if (data.reader.GetPrompt() && !batch_mode) |
| { |
| out_stream->Printf ("%s", data.reader.GetPrompt()); |
| out_stream->Flush(); |
| } |
| } |
| virtual void GotTokenHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.GetOutStream(); |
| bool batch_mode = data.GetBatchMode(); |
| if (data.bytes && data.bytes_len && data.baton) |
| { |
| ((SynthAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len); |
| } |
| if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) |
| { |
| out_stream->Printf ("%s", data.reader.GetPrompt()); |
| out_stream->Flush(); |
| } |
| } |
| virtual void InterruptHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.GetOutStream(); |
| bool batch_mode = data.GetBatchMode(); |
| data.reader.SetIsDone (true); |
| if (!batch_mode) |
| { |
| out_stream->Printf ("Warning: No command attached to breakpoint.\n"); |
| out_stream->Flush(); |
| } |
| } |
| virtual void EOFHandler(HandlerData& data) |
| { |
| data.reader.SetIsDone (true); |
| } |
| virtual void DoneHandler(HandlerData& data) |
| { |
| StreamSP out_stream = data.GetOutStream(); |
| SynthAddOptions *options_ptr = ((SynthAddOptions*)data.baton); |
| if (!options_ptr) |
| { |
| out_stream->Printf ("Internal error #1: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| |
| SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope |
| |
| ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); |
| if (!interpreter) |
| { |
| out_stream->Printf ("Internal error #2: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| std::string class_name_str; |
| if (!interpreter->GenerateTypeSynthClass (options->m_user_source, |
| class_name_str)) |
| { |
| out_stream->Printf ("Internal error #3: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| if (class_name_str.empty()) |
| { |
| out_stream->Printf ("Internal error #4: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| |
| // everything should be fine now, let's add the synth provider class |
| |
| SyntheticChildrenSP synth_provider; |
| synth_provider.reset(new TypeSyntheticImpl(SyntheticChildren::Flags().SetCascades(options->m_cascade). |
| SetSkipPointers(options->m_skip_pointers). |
| SetSkipReferences(options->m_skip_references), |
| class_name_str.c_str())); |
| |
| |
| lldb::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category); |
| |
| Error error; |
| |
| for (size_t i = 0; i < options->m_target_types.GetSize(); i++) |
| { |
| const char *type_name = options->m_target_types.GetStringAtIndex(i); |
| ConstString typeCS(type_name); |
| if (typeCS) |
| { |
| if (!CommandObjectTypeSynthAdd::AddSynth(typeCS, |
| synth_provider, |
| options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth, |
| options->m_category, |
| &error)) |
| { |
| out_stream->Printf("%s\n", error.AsCString()); |
| out_stream->Flush(); |
| return; |
| } |
| } |
| else |
| { |
| out_stream->Printf ("Internal error #6: no script attached.\n"); |
| out_stream->Flush(); |
| return; |
| } |
| } |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN (TypeSynthAddInputReader); |
| }; |
| |
| void |
| CommandObjectTypeSynthAdd::CollectPythonScript (SynthAddOptions *options, |
| CommandReturnObject &result) |
| { |
| 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); |
| } |
| } |
| 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 |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| |
| CollectPythonScript(options,result); |
| return result.Succeeded(); |
| } |
| |
| bool |
| CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result) |
| { |
| 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) |
| { |
| 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; |
| |
| TypeSyntheticImpl* impl = new TypeSyntheticImpl(SyntheticChildren::Flags(). |
| SetCascades(m_options.m_cascade). |
| SetSkipPointers(m_options.m_skip_pointers). |
| SetSkipReferences(m_options.m_skip_references), |
| m_options.m_class_name.c_str()); |
| |
| entry.reset(impl); |
| |
| // now I have a valid provider, let's add it to every type |
| |
| lldb::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); |
| |
| Error error; |
| |
| for (size_t i = 0; i < argc; i++) |
| { |
| const char* typeA = command.GetArgumentAtIndex(i); |
| ConstString typeCS(typeA); |
| if (typeCS) |
| { |
| if (!AddSynth(typeCS, |
| entry, |
| m_options.m_regex ? eRegexSynth : eRegularSynth, |
| m_options.m_category, |
| &error)) |
| { |
| result.AppendError(error.AsCString()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| else |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| |
| CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type synthetic 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, |
| std::string category_name, |
| Error* error) |
| { |
| lldb::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); |
| |
| if (category->AnyMatches(type_name, |
| eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter, |
| false)) |
| { |
| if (error) |
| error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString()); |
| return false; |
| } |
| |
| if (type == eRegexSynth) |
| { |
| RegularExpressionSP typeRX(new RegularExpression()); |
| if (!typeRX->Compile(type_name.GetCString())) |
| { |
| if (error) |
| error->SetErrorString("regex format error (maybe this is not really a regex?)"); |
| return false; |
| } |
| |
| category->GetRegexSyntheticNavigator()->Delete(type_name); |
| category->GetRegexSyntheticNavigator()->Add(typeRX, entry); |
| |
| return true; |
| } |
| else |
| { |
| category->GetSyntheticNavigator()->Add(type_name, entry); |
| return true; |
| } |
| } |
| |
| 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 |
| { |
| 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[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, |
| { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, |
| { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, |
| { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, |
| { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypePythonClass, "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 } |
| }; |
| |
| #endif // #ifndef LLDB_DISABLE_PYTHON |
| |
| class CommandObjectTypeFilterAdd : 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", option_arg); |
| break; |
| case 'c': |
| m_expr_paths.push_back(option_arg); |
| has_child_list = true; |
| break; |
| case 'p': |
| m_skip_pointers = true; |
| break; |
| case 'r': |
| m_skip_references = true; |
| break; |
| case 'w': |
| m_category = std::string(option_arg); |
| break; |
| case 'x': |
| m_regex = true; |
| break; |
| default: |
| error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); |
| break; |
| } |
| |
| return error; |
| } |
| |
| void |
| OptionParsingStarting () |
| { |
| m_cascade = true; |
| m_skip_pointers = false; |
| m_skip_references = false; |
| m_category = "default"; |
| m_expr_paths.clear(); |
| 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; |
| bool m_input_python; |
| option_vector m_expr_paths; |
| std::string m_category; |
| |
| bool has_child_list; |
| |
| bool m_regex; |
| |
| typedef option_vector::iterator ExpressionPathsIterator; |
| }; |
| |
| CommandOptions m_options; |
| |
| virtual Options * |
| GetOptions () |
| { |
| return &m_options; |
| } |
| |
| enum FilterFormatType |
| { |
| eRegularFilter, |
| eRegexFilter |
| }; |
| |
| bool |
| AddFilter(const ConstString& type_name, |
| SyntheticChildrenSP entry, |
| FilterFormatType type, |
| std::string category_name, |
| Error* error) |
| { |
| lldb::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category); |
| |
| if (category->AnyMatches(type_name, |
| eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth, |
| false)) |
| { |
| if (error) |
| error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString()); |
| return false; |
| } |
| |
| if (type == eRegexFilter) |
| { |
| RegularExpressionSP typeRX(new RegularExpression()); |
| if (!typeRX->Compile(type_name.GetCString())) |
| { |
| if (error) |
| error->SetErrorString("regex format error (maybe this is not really a regex?)"); |
| return false; |
| } |
| |
| category->GetRegexFilterNavigator()->Delete(type_name); |
| category->GetRegexFilterNavigator()->Add(typeRX, entry); |
| |
| return true; |
| } |
| else |
| { |
| category->GetFilterNavigator()->Add(type_name, entry); |
| return true; |
| } |
| } |
| |
| |
| public: |
| |
| CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) : |
| CommandObject (interpreter, |
| "type filter add", |
| "Add a new filter 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); |
| |
| SetHelpLong( |
| "Some examples of using this command.\n" |
| "We use as reference the following snippet of code:\n" |
| "\n" |
| "class Foo {;\n" |
| " int a;\n" |
| " int b;\n" |
| " int c;\n" |
| " int d;\n" |
| " int e;\n" |
| " int f;\n" |
| " int g;\n" |
| " int h;\n" |
| " int i;\n" |
| "} \n" |
| "Typing:\n" |
| "type filter add --child a -- child g Foo\n" |
| "frame variable a_foo\n" |
| "will produce an output where only a and b are displayed\n" |
| "Other children of a_foo (b,c,d,e,f,h and i) are available by asking for them, as in:\n" |
| "frame variable a_foo.b a_foo.c ... a_foo.i\n" |
| "\n" |
| "Use option --raw to frame variable prevails on the filter\n" |
| "frame variable a_foo --raw\n" |
| "shows all the children of a_foo (a thru i) as if no filter was defined\n" |
| ); |
| } |
| |
| ~CommandObjectTypeFilterAdd () |
| { |
| } |
| |
| bool |
| Execute (Args& command, CommandReturnObject &result) |
| { |
| 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 one or more children.\n", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| |
| SyntheticChildrenSP entry; |
| |
| TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade). |
| SetSkipPointers(m_options.m_skip_pointers). |
| SetSkipReferences(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::TypeCategoryImplSP category; |
| DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category); |
| |
| Error error; |
| |
| for (size_t i = 0; i < argc; i++) |
| { |
| const char* typeA = command.GetArgumentAtIndex(i); |
| ConstString typeCS(typeA); |
| if (typeCS) |
| { |
| if (!AddFilter(typeCS, |
| entry, |
| m_options.m_regex ? eRegexFilter : eRegularFilter, |
| m_options.m_category, |
| &error)) |
| { |
| result.AppendError(error.AsCString()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| else |
| { |
| result.AppendError("empty typenames not allowed"); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| } |
| |
| result.SetStatus(eReturnStatusSuccessFinishNoResult); |
| return result.Succeeded(); |
| } |
| |
| }; |
| |
| OptionDefinition |
| CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] = |
| { |
| { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."}, |
| { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, |
| { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, |
| { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, |
| { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."}, |
| { 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 } |
| }; |
| |
| class CommandObjectTypeFormat : public CommandObjectMultiword |
| { |
| public: |
| CommandObjectTypeFormat (CommandInterpreter &interpreter) : |
| CommandObjectMultiword (interpreter, |
| "type format", |
| "A set of commands for editing variable value display options", |
| "type format [<sub-command-options>] ") |
| { |
| LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter))); |
| LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter))); |
| LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter))); |
| LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter))); |
| } |
| |
| |
| ~CommandObjectTypeFormat () |
| { |
| } |
| }; |
| |
| #ifndef LLDB_DISABLE_PYTHON |
| |
| class CommandObjectTypeSynth : public CommandObjectMultiword |
| { |
| public: |
| CommandObjectTypeSynth (CommandInterpreter &interpreter) : |
| CommandObjectMultiword (interpreter, |
| "type synthetic", |
| "A set of commands for operating on synthetic type representations", |
| "type synthetic [<sub-command-options>] ") |
| { |
| LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter))); |
| LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter))); |
| LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter))); |
| LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSynthList (interpreter))); |
| } |
| |
| |
| ~CommandObjectTypeSynth () |
| { |
| } |
| }; |
| |
| #endif // #ifndef LLDB_DISABLE_PYTHON |
| |
| class CommandObjectTypeFilter : public CommandObjectMultiword |
| { |
| public: |
| CommandObjectTypeFilter (CommandInterpreter &interpreter) : |
| CommandObjectMultiword (interpreter, |
| "type filter", |
| "A set of commands for operating on type filters", |
| "type synthetic [<sub-command-options>] ") |
| { |
| LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter))); |
| LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter))); |
| LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter))); |
| LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter))); |
| } |
| |
| |
| ~CommandObjectTypeFilter () |
| { |
| } |
| }; |
| |
| class CommandObjectTypeCategory : public CommandObjectMultiword |
| { |
| public: |
| CommandObjectTypeCategory (CommandInterpreter &interpreter) : |
| CommandObjectMultiword (interpreter, |
| "type category", |
| "A set of commands for operating on categories", |
| "type category [<sub-command-options>] ") |
| { |
| LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter))); |
| LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter))); |
| LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter))); |
| LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeCategoryList (interpreter))); |
| } |
| |
| |
| ~CommandObjectTypeCategory () |
| { |
| } |
| }; |
| |
| class CommandObjectTypeSummary : public CommandObjectMultiword |
| { |
| public: |
| CommandObjectTypeSummary (CommandInterpreter &interpreter) : |
| CommandObjectMultiword (interpreter, |
| "type summary", |
| "A set of commands for editing variable summary display options", |
| "type summary [<sub-command-options>] ") |
| { |
| LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter))); |
| LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter))); |
| LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter))); |
| LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter))); |
| } |
| |
| |
| ~CommandObjectTypeSummary () |
| { |
| } |
| }; |
| |
| //------------------------------------------------------------------------- |
| // CommandObjectType |
| //------------------------------------------------------------------------- |
| |
| CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) : |
| CommandObjectMultiword (interpreter, |
| "type", |
| "A set of commands for operating on the type system", |
| "type [<sub-command-options>]") |
| { |
| LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter))); |
| LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter))); |
| LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); |
| LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter))); |
| #ifndef LLDB_DISABLE_PYTHON |
| LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter))); |
| #endif |
| } |
| |
| |
| CommandObjectType::~CommandObjectType () |
| { |
| } |
| |
| |