blob: 2e0aa5c07496dc590024e57c69f53356ad6b05c9 [file] [log] [blame]
//===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "CommandObjectType.h"
// C Includes
// C++ Includes
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/State.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
using namespace lldb;
using namespace lldb_private;
//-------------------------------------------------------------------------
// CommandObjectTypeFormatAdd
//-------------------------------------------------------------------------
class CommandObjectTypeFormatAdd : public CommandObject
{
private:
class CommandOptions : public Options
{
public:
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
virtual
~CommandOptions (){}
virtual Error
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
char short_option = (char) m_getopt_table[option_idx].val;
bool success;
switch (short_option)
{
case 'C':
m_cascade = Args::StringToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
break;
case 'f':
error = Args::StringToFormat(option_arg, m_format, NULL);
break;
case 'p':
m_skip_pointers = true;
break;
case 'r':
m_skip_references = true;
break;
default:
error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
break;
}
return error;
}
void
OptionParsingStarting ()
{
m_cascade = true;
m_format = eFormatInvalid;
m_skip_pointers = false;
m_skip_references = 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;
lldb::Format m_format;
bool m_skip_references;
bool m_skip_pointers;
};
CommandOptions m_options;
virtual Options *
GetOptions ()
{
return &m_options;
}
public:
CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type format add",
"Add a new formatting 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"
"\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"
);
}
~CommandObjectTypeFormatAdd ()
{
}
bool
Execute (Args& command, CommandReturnObject &result)
{
const size_t argc = command.GetArgumentCount();
if (argc < 1)
{
result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
if(m_options.m_format == eFormatInvalid)
{
result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
ValueFormatSP entry;
entry.reset(new ValueFormat(m_options.m_format,
m_options.m_cascade,
m_options.m_skip_pointers,
m_options.m_skip_references));
// now I have a valid format, let's add it to every type
for(int i = 0; i < argc; i++) {
const char* typeA = command.GetArgumentAtIndex(i);
ConstString typeCS(typeA);
if (typeCS)
Debugger::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 to derived typedefs."},
{ LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeFormat, "The format to use to display this type."},
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for references-to-type objects."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
//-------------------------------------------------------------------------
// CommandObjectTypeFormatDelete
//-------------------------------------------------------------------------
class CommandObjectTypeFormatDelete : public CommandObject
{
public:
CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type format delete",
"Delete an existing formatting style for a type.",
NULL)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
type_style_arg.arg_type = eArgTypeName;
type_style_arg.arg_repetition = eArgRepeatPlain;
type_arg.push_back (type_style_arg);
m_arguments.push_back (type_arg);
}
~CommandObjectTypeFormatDelete ()
{
}
bool
Execute (Args& command, CommandReturnObject &result)
{
const size_t argc = command.GetArgumentCount();
if (argc != 1)
{
result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
const char* typeA = command.GetArgumentAtIndex(0);
ConstString typeCS(typeA);
if(!typeCS)
{
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
if (Debugger::ValueFormats::Delete(typeCS))
{
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
else
{
result.AppendErrorWithFormat ("no custom format for %s.\n", typeA);
result.SetStatus(eReturnStatusFailed);
return false;
}
}
};
//-------------------------------------------------------------------------
// CommandObjectTypeFormatClear
//-------------------------------------------------------------------------
class CommandObjectTypeFormatClear : public CommandObject
{
public:
CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type format clear",
"Delete all existing format styles.",
NULL)
{
}
~CommandObjectTypeFormatClear ()
{
}
bool
Execute (Args& command, CommandReturnObject &result)
{
Debugger::ValueFormats::Clear();
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
//-------------------------------------------------------------------------
// CommandObjectTypeFormatList
//-------------------------------------------------------------------------
bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, const char* type, const ValueFormat::SharedPointer& entry);
class CommandObjectTypeFormatList;
struct CommandObjectTypeFormatList_LoopCallbackParam {
CommandObjectTypeFormatList* self;
CommandReturnObject* result;
RegularExpression* regex;
CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R,
RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
};
class CommandObjectTypeFormatList : public CommandObject
{
public:
CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type format list",
"Show a list of current formatting styles.",
NULL)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
type_style_arg.arg_type = eArgTypeName;
type_style_arg.arg_repetition = eArgRepeatOptional;
type_arg.push_back (type_style_arg);
m_arguments.push_back (type_arg);
}
~CommandObjectTypeFormatList ()
{
}
bool
Execute (Args& command, CommandReturnObject &result)
{
const size_t argc = command.GetArgumentCount();
CommandObjectTypeFormatList_LoopCallbackParam *param;
if (argc == 1) {
RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
regex->Compile(command.GetArgumentAtIndex(0));
param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex);
}
else
param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result);
Debugger::ValueFormats::LoopThrough(CommandObjectTypeFormatList_LoopCallback, param);
delete param;
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
private:
bool
LoopCallback (const char* type,
const ValueFormat::SharedPointer& entry,
RegularExpression* regex,
CommandReturnObject *result)
{
if (regex == NULL || regex->Execute(type))
{
result->GetOutputStream().Printf ("%s: %s%s%s%s\n", type,
FormatManager::GetFormatAsCString (entry->m_format),
entry->m_cascades ? "" : " (not cascading)",
entry->m_skip_pointers ? " (skip pointers)" : "",
entry->m_skip_references ? " (skip references)" : "");
}
return true;
}
friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, const char* type, const ValueFormat::SharedPointer& entry);
};
bool
CommandObjectTypeFormatList_LoopCallback (
void* pt2self,
const char* type,
const ValueFormat::SharedPointer& entry)
{
CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
return param->self->LoopCallback(type, entry, param->regex, param->result);
}
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryAdd
//-------------------------------------------------------------------------
class CommandObjectTypeSummaryAdd : public CommandObject
{
private:
class CommandOptions : public Options
{
public:
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
virtual
~CommandOptions (){}
virtual Error
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
char short_option = (char) m_getopt_table[option_idx].val;
bool success;
switch (short_option)
{
case 'C':
m_cascade = Args::StringToBoolean(option_arg, true, &success);
if (!success)
error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg);
break;
case 'e':
m_no_children = false;
break;
case 'v':
m_no_value = true;
break;
case 'c':
m_one_liner = true;
break;
case 'f':
m_format_string = std::string(option_arg);
break;
case 'p':
m_skip_pointers = true;
break;
case 'r':
m_skip_references = true;
break;
case 'x':
m_regex = true;
break;
default:
error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
break;
}
return error;
}
void
OptionParsingStarting ()
{
m_cascade = true;
m_no_children = true;
m_no_value = false;
m_one_liner = false;
m_skip_references = false;
m_skip_pointers = 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_no_children;
bool m_no_value;
bool m_one_liner;
bool m_skip_references;
bool m_skip_pointers;
bool m_regex;
std::string m_format_string;
};
CommandOptions m_options;
virtual Options *
GetOptions ()
{
return &m_options;
}
public:
CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type summary add",
"Add a new summary style for a type.",
NULL), m_options (interpreter)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
type_style_arg.arg_type = eArgTypeName;
type_style_arg.arg_repetition = eArgRepeatPlus;
type_arg.push_back (type_style_arg);
m_arguments.push_back (type_arg);
SetHelpLong(
"Some examples of using this command.\n"
"We use as reference the following snippet of code:\n"
"struct JustADemo\n"
"{\n"
"int* ptr;\n"
"float value;\n"
"JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n"
"};\n"
"JustADemo object(42,3.14);\n"
"struct AnotherDemo : public JustADemo\n"
"{\n"
"uint8_t byte;\n"
"AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n"
"};\n"
"AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n"
"\n"
"type summary add -f \"the answer is ${*var.ptr}\" JustADemo\n"
"when typing frame variable object you will get \"the answer is 42\"\n"
"type summary add -f \"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 -f \"${var%V} -> ${*var}\" \"int *\"\n"
"and replace the above summary string with\n"
"type summary add -f \"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 -f \"${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 -f \"${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 -f \"*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"
"A command you may definitely want to try if you're doing C++ debugging is:\n"
"type summary add -f \"${var._M_dataplus._M_p}\" std::string\n"
);
}
~CommandObjectTypeSummaryAdd ()
{
}
bool
Execute (Args& command, CommandReturnObject &result)
{
const size_t argc = command.GetArgumentCount();
if (argc < 1)
{
result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
if(!m_options.m_one_liner && 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_one_liner ? "" : m_options.m_format_string.c_str());
Error error;
SummaryFormat::SharedPointer entry(new SummaryFormat(format_cstr,m_options.m_cascade,
m_options.m_no_children,m_options.m_no_value,
m_options.m_one_liner,
m_options.m_skip_pointers,
m_options.m_skip_references));
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(int 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);
if(!m_options.m_regex)
{
Debugger::SummaryFormats::Add(typeCS, entry);
}
else
{
RegularExpressionSP typeRX(new RegularExpression());
if(!typeRX->Compile(typeA))
{
result.AppendError("regex format error (maybe this is not really a regex?)");
result.SetStatus(eReturnStatusFailed);
return false;
}
Debugger::RegexSummaryFormats::Delete(typeCS);
Debugger::RegexSummaryFormats::Add(typeRX, entry);
}
}
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
};
OptionDefinition
CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."},
{ LLDB_OPT_SET_ALL, false, "no-value", 'v', no_argument, NULL, 0, eArgTypeBoolean, "Don't show the value, just show the summary, for this type."},
{ LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for pointers-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeBoolean, "Don't use this format for references-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeBoolean, "Type names are actually regular expressions."},
{ LLDB_OPT_SET_1 , true, "inline-children", 'c', no_argument, NULL, 0, eArgTypeBoolean, "If true, inline all child values into summary string."},
{ LLDB_OPT_SET_2 , true, "format-string", 'f', required_argument, NULL, 0, eArgTypeSummaryString, "Format string used to display text and object contents."},
{ LLDB_OPT_SET_2, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean, "Expand aggregate data types to show children on separate lines."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryDelete
//-------------------------------------------------------------------------
class CommandObjectTypeSummaryDelete : public CommandObject
{
public:
CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type summary delete",
"Delete an existing summary 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);
}
~CommandObjectTypeSummaryDelete ()
{
}
bool
Execute (Args& command, CommandReturnObject &result)
{
const size_t argc = command.GetArgumentCount();
if (argc != 1)
{
result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
const char* typeA = command.GetArgumentAtIndex(0);
ConstString typeCS(typeA);
if(!typeCS)
{
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
bool delete_summary = Debugger::SummaryFormats::Delete(typeCS);
bool delete_regex = Debugger::RegexSummaryFormats::Delete(typeCS);
if (delete_summary || delete_regex)
{
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
}
else
{
result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA);
result.SetStatus(eReturnStatusFailed);
return false;
}
}
};
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryClear
//-------------------------------------------------------------------------
class CommandObjectTypeSummaryClear : public CommandObject
{
public:
CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type summary clear",
"Delete all existing summary styles.",
NULL)
{
}
~CommandObjectTypeSummaryClear ()
{
}
bool
Execute (Args& command, CommandReturnObject &result)
{
Debugger::SummaryFormats::Clear();
Debugger::RegexSummaryFormats::Clear();
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryList
//-------------------------------------------------------------------------
bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry);
bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry);
class CommandObjectTypeSummaryList;
struct CommandObjectTypeSummaryList_LoopCallbackParam {
CommandObjectTypeSummaryList* self;
CommandReturnObject* result;
RegularExpression* regex;
CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
};
struct CommandObjectTypeRXSummaryList_LoopCallbackParam {
CommandObjectTypeSummaryList* self;
CommandReturnObject* result;
RegularExpression* regex;
CommandObjectTypeRXSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
RegularExpression* X = NULL) : self(S), result(R), regex(X) {}
};
class CommandObjectTypeSummaryList : public CommandObject
{
public:
CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type summary list",
"Show a list of current summary 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);
}
~CommandObjectTypeSummaryList ()
{
}
bool
Execute (Args& command, CommandReturnObject &result)
{
const size_t argc = command.GetArgumentCount();
CommandObjectTypeSummaryList_LoopCallbackParam *param;
CommandObjectTypeRXSummaryList_LoopCallbackParam *rxparam;
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);
Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
delete param;
if(Debugger::RegexSummaryFormats::GetCount() == 0)
{
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
result.GetOutputStream().Printf("Regex-based summaries (slower):\n");
if (argc == 1) {
RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
regex->Compile(command.GetArgumentAtIndex(0));
rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result,regex);
}
else
rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result);
Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
delete rxparam;
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
private:
bool
LoopCallback (const char* type,
const SummaryFormat::SharedPointer& entry,
RegularExpression* regex,
CommandReturnObject *result)
{
if (regex == NULL || regex->Execute(type))
{
result->GetOutputStream().Printf ("%s: `%s`%s%s%s%s%s%s\n", type,
entry->m_format.c_str(),
entry->m_cascades ? "" : " (not cascading)",
entry->m_dont_show_children ? "" : " (show children)",
entry->m_dont_show_value ? " (hide value)" : "",
entry->m_show_members_oneliner ? " (one-line printout)" : "",
entry->m_skip_pointers ? " (skip pointers)" : "",
entry->m_skip_references ? " (skip references)" : "");
}
return true;
}
friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, const char* type, const SummaryFormat::SharedPointer& entry);
friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SummaryFormat::SharedPointer& entry);
};
bool
CommandObjectTypeSummaryList_LoopCallback (
void* pt2self,
const char* type,
const SummaryFormat::SharedPointer& entry)
{
CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
return param->self->LoopCallback(type, entry, param->regex, param->result);
}
bool
CommandObjectTypeRXSummaryList_LoopCallback (
void* pt2self,
lldb::RegularExpressionSP regex,
const SummaryFormat::SharedPointer& entry)
{
CommandObjectTypeRXSummaryList_LoopCallbackParam* param = (CommandObjectTypeRXSummaryList_LoopCallbackParam*)pt2self;
return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
}
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 ()
{
}
};
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 ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
}
CommandObjectType::~CommandObjectType ()
{
}