summaryrefslogtreecommitdiffstats
path: root/source/Commands/CommandObjectType.cpp
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2013-08-23 17:46:38 +0000
committeremaste <emaste@FreeBSD.org>2013-08-23 17:46:38 +0000
commitdcd15f81789e389c1cb27d264fcdddfd0a6002bd (patch)
treef561dabc721ad515599172c16da3a4400b7f4aec /source/Commands/CommandObjectType.cpp
downloadFreeBSD-src-dcd15f81789e389c1cb27d264fcdddfd0a6002bd.zip
FreeBSD-src-dcd15f81789e389c1cb27d264fcdddfd0a6002bd.tar.gz
Import lldb as of SVN r188801
(A number of files not required for the FreeBSD build have been removed.) Sponsored by: DARPA, AFRL
Diffstat (limited to 'source/Commands/CommandObjectType.cpp')
-rw-r--r--source/Commands/CommandObjectType.cpp4112
1 files changed, 4112 insertions, 0 deletions
diff --git a/source/Commands/CommandObjectType.cpp b/source/Commands/CommandObjectType.cpp
new file mode 100644
index 0000000..b300f21
--- /dev/null
+++ b/source/Commands/CommandObjectType.cpp
@@ -0,0 +1,4112 @@
+//===-- 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 "lldb/lldb-python.h"
+
+#include "CommandObjectType.h"
+
+// C Includes
+
+#include <ctype.h>
+
+// C++ Includes
+
+#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/DataFormatters/DataVisualization.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 CommandObjectParsed
+{
+
+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 ()
+ {
+ }
+
+ static bool
+ AddSummary(ConstString type_name,
+ lldb::TypeSummaryImplSP entry,
+ SummaryFormatType type,
+ std::string category,
+ Error* error = NULL);
+protected:
+ bool
+ DoExecute (Args& command, CommandReturnObject &result);
+
+};
+
+class CommandObjectTypeSynthAdd : public CommandObjectParsed
+{
+
+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;
+ const int short_option = 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);
+
+protected:
+ bool
+ DoExecute (Args& command, CommandReturnObject &result);
+
+public:
+
+ enum SynthFormatType
+ {
+ eRegularSynth,
+ eRegexSynth
+ };
+
+ CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
+
+ ~CommandObjectTypeSynthAdd ()
+ {
+ }
+
+ static bool
+ AddSynth(ConstString type_name,
+ lldb::SyntheticChildrenSP entry,
+ SynthFormatType type,
+ std::string category_name,
+ Error* error);
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectTypeFormatAdd
+//-------------------------------------------------------------------------
+
+class CommandObjectTypeFormatAdd : public CommandObjectParsed
+{
+
+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 int short_option = 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) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+public:
+ CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+public:
+ CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
+ CommandObjectParsed (interpreter,
+ "type format clear",
+ "Delete all existing format styles.",
+ NULL)
+ {
+ }
+
+ ~CommandObjectTypeFormatClear ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+public:
+ CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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,internal_dict):\n"
+ " \"\"\"valobj: an SBValue which you want to provide a summary for\n"
+ " internal_dict: an LLDB support object not to be used\"\"\"";
+
+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 synchronization information missing or invalid.\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 ("no script interpreter.\n");
+ out_stream->Flush();
+ return;
+ }
+ std::string funct_name_str;
+ if (!interpreter->GenerateTypeScriptFunction (options->m_user_source,
+ funct_name_str))
+ {
+ out_stream->Printf ("unable to generate a function.\n");
+ out_stream->Flush();
+ return;
+ }
+ if (funct_name_str.empty())
+ {
+ out_stream->Printf ("unable to obtain a valid function name from the script interpreter.\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;
+ const int short_option = 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
+ {
+ const char *funct_name = m_options.m_python_function.c_str();
+ if (!funct_name || !funct_name[0])
+ {
+ result.AppendError ("function name empty.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)");
+
+ script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
+ funct_name,
+ code.c_str()));
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+
+ if (interpreter && interpreter->CheckObjectExists(funct_name) == false)
+ result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
+ "please define it before attempting to use this summary.\n",
+ funct_name);
+ }
+ 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 ("script interpreter missing - unable to generate function wrapper.\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 ("unable to generate function wrapper.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ if (funct_name_str.empty())
+ {
+ result.AppendError ("script interpreter failed to generate a valid function name.\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) :
+ CommandObjectParsed (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::DoExecute (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(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 == eRegularSummary)
+ {
+ std::string type_name_str(type_name.GetCString());
+ if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
+ {
+ type_name_str.resize(type_name_str.length()-2);
+ if (type_name_str.back() != ' ')
+ type_name_str.append(" \\[[0-9]+\\]");
+ else
+ type_name_str.append("\\[[0-9]+\\]");
+ type_name.SetCString(type_name_str.c_str());
+ type = eRegexSummary;
+ }
+ }
+
+ 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 CommandObjectParsed
+{
+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;
+ const int short_option = 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) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+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;
+ const int short_option = 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) :
+ CommandObjectParsed (interpreter,
+ "type summary clear",
+ "Delete all existing summary styles.",
+ NULL),
+ m_options(interpreter)
+ {
+ }
+
+ ~CommandObjectTypeSummaryClear ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+
+ 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;
+ const int short_option = 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) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 && strcmp(cate_name,param->cate_regex->GetText()) != 0 && 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 || strcmp(type,regex->GetText()) == 0 || 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 CommandObjectParsed
+{
+public:
+ CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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;
+ }
+
+ if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
+ {
+ // we want to make sure to enable "system" last and "default" first
+ DataVisualization::Categories::Enable(ConstString("default"), TypeCategoryMap::First);
+ uint32_t num_categories = DataVisualization::Categories::GetCount();
+ for (uint32_t i = 0; i < num_categories; i++)
+ {
+ lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i);
+ if (category_sp)
+ {
+ if ( ::strcmp(category_sp->GetName(), "system") == 0 ||
+ ::strcmp(category_sp->GetName(), "default") == 0 )
+ continue;
+ else
+ DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
+ }
+ }
+ DataVisualization::Categories::Enable(ConstString("system"), TypeCategoryMap::Last);
+ }
+ else
+ {
+ 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 CommandObjectParsed
+{
+public:
+ CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+public:
+ CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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;
+ }
+
+ if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
+ {
+ uint32_t num_categories = DataVisualization::Categories::GetCount();
+ for (uint32_t i = 0; i < num_categories; i++)
+ {
+ lldb::TypeCategoryImplSP category_sp = DataVisualization::Categories::GetCategoryAtIndex(i);
+ // no need to check if the category is enabled - disabling a disabled category has no effect
+ if (category_sp)
+ DataVisualization::Categories::Disable(category_sp);
+ }
+ }
+ else
+ {
+ // 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 CommandObjectParsed
+{
+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 || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name))
+ result->GetOutputStream().Printf("Category %s is%s enabled\n",
+ cate_name,
+ (cate->IsEnabled() ? "" : " not"));
+ return true;
+ }
+public:
+ CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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, &param);
+
+ 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 CommandObjectParsed
+{
+
+ 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;
+ const int short_option = 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) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 && strcmp(cate_name,param->cate_regex->GetText()) != 0 && 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 CommandObjectParsed
+{
+
+ 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;
+ const int short_option = 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) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 && strcmp(cate_name,param->cate_regex->GetText()) != 0 && 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 CommandObjectParsed
+{
+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;
+ const int short_option = 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) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+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;
+ const int short_option = 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) :
+ CommandObjectParsed (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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+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;
+ const int short_option = 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) :
+ CommandObjectParsed (interpreter,
+ "type filter clear",
+ "Delete all existing filters.",
+ NULL),
+ m_options(interpreter)
+ {
+ }
+
+ ~CommandObjectTypeFilterClear ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 CommandObjectParsed
+{
+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;
+ const int short_option = 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) :
+ CommandObjectParsed (interpreter,
+ "type synthetic clear",
+ "Delete all existing synthetic providers.",
+ NULL),
+ m_options(interpreter)
+ {
+ }
+
+ ~CommandObjectTypeSynthClear ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 synchronization data missing.\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 ("no script interpreter.\n");
+ out_stream->Flush();
+ return;
+ }
+ std::string class_name_str;
+ if (!interpreter->GenerateTypeSynthClass (options->m_user_source,
+ class_name_str))
+ {
+ out_stream->Printf ("unable to generate a class.\n");
+ out_stream->Flush();
+ return;
+ }
+ if (class_name_str.empty())
+ {
+ out_stream->Printf ("unable to obtain a proper name for the class.\n");
+ out_stream->Flush();
+ return;
+ }
+
+ // everything should be fine now, let's add the synth provider class
+
+ SyntheticChildrenSP synth_provider;
+ synth_provider.reset(new ScriptedSyntheticChildren(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 ("invalid type name.\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;
+
+ ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(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);
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+
+ if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false)
+ result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
+
+ // 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) :
+ CommandObjectParsed (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(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 (type == eRegularSynth)
+ {
+ std::string type_name_str(type_name.GetCString());
+ if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
+ {
+ type_name_str.resize(type_name_str.length()-2);
+ if (type_name_str.back() != ' ')
+ type_name_str.append(" \\[[0-9]+\\]");
+ else
+ type_name_str.append("\\[[0-9]+\\]");
+ type_name.SetCString(type_name_str.c_str());
+ type = eRegularSynth;
+ }
+ }
+
+ 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::DoExecute (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 CommandObjectParsed
+{
+
+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;
+ const int short_option = 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(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 (type == eRegularFilter)
+ {
+ std::string type_name_str(type_name.GetCString());
+ if (type_name_str.compare(type_name_str.length() - 2, 2, "[]") == 0)
+ {
+ type_name_str.resize(type_name_str.length()-2);
+ if (type_name_str.back() != ' ')
+ type_name_str.append(" \\[[0-9]+\\]");
+ else
+ type_name_str.append("\\[[0-9]+\\]");
+ type_name.SetCString(type_name_str.c_str());
+ type = eRegexFilter;
+ }
+ }
+
+ 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) :
+ CommandObjectParsed (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 g 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 ()
+ {
+ }
+
+protected:
+ bool
+ DoExecute (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 ()
+{
+}
+
+
OpenPOWER on IntegriCloud