[Lldb-commits] [lldb] r135326 - in /lldb/trunk: include/lldb/Core/ source/Commands/ source/Core/ source/Symbol/ test/functionalities/data-formatter/data-formatter-script/
Enrico Granata
granata.enrico at gmail.com
Fri Jul 15 16:30:15 PDT 2011
Author: enrico
Date: Fri Jul 15 18:30:15 2011
New Revision: 135326
URL: http://llvm.org/viewvc/llvm-project?rev=135326&view=rev
Log:
System-wide summaries:
- Summaries for char*, const char* and char[] are loaded at startup as
system-wide summaries. This means you cannot delete them unless you use
the -a option to type summary delete/clear
- You can add your own system-wide summaries by using the -w option to type
summary add
Several code improvements for the Python summaries feature
Modified:
lldb/trunk/include/lldb/Core/Debugger.h
lldb/trunk/include/lldb/Core/FormatManager.h
lldb/trunk/include/lldb/Core/InputReader.h
lldb/trunk/include/lldb/Core/InputReaderEZ.h
lldb/trunk/source/Commands/CommandObjectType.cpp
lldb/trunk/source/Commands/CommandObjectType.h
lldb/trunk/source/Core/Debugger.cpp
lldb/trunk/source/Core/InputReaderEZ.cpp
lldb/trunk/source/Core/ValueObject.cpp
lldb/trunk/source/Symbol/ClangASTContext.cpp
lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp
lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp
Modified: lldb/trunk/include/lldb/Core/Debugger.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Debugger.h (original)
+++ lldb/trunk/include/lldb/Core/Debugger.h Fri Jul 15 18:30:15 2011
@@ -525,6 +525,32 @@
GetCount();
};
+ class SystemSummaryFormats
+ {
+ public:
+
+ static bool
+ Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry);
+
+ static void
+ Add(const ConstString &type, const SummaryFormat::SharedPointer &entry);
+
+ static bool
+ Delete(const ConstString &type);
+
+ static void
+ Clear();
+
+ static void
+ LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton);
+
+ static uint32_t
+ GetCurrentRevision();
+
+ static uint32_t
+ GetCount();
+ };
+
class RegexSummaryFormats
{
public:
@@ -551,6 +577,32 @@
GetCount();
};
+ class SystemRegexSummaryFormats
+ {
+ public:
+
+ static bool
+ Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry);
+
+ static void
+ Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry);
+
+ static bool
+ Delete(const ConstString &type);
+
+ static void
+ Clear();
+
+ static void
+ LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton);
+
+ static uint32_t
+ GetCurrentRevision();
+
+ static uint32_t
+ GetCount();
+ };
+
class NamedSummaryFormats
{
public:
Modified: lldb/trunk/include/lldb/Core/FormatManager.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FormatManager.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FormatManager.h (original)
+++ lldb/trunk/include/lldb/Core/FormatManager.h Fri Jul 15 18:30:15 2011
@@ -150,19 +150,22 @@
bool m_dont_show_children;
bool m_dont_show_value;
bool m_show_members_oneliner;
+ bool m_is_system;
SummaryFormat(bool casc = false,
bool skipptr = false,
bool skipref = false,
bool nochildren = true,
bool novalue = true,
- bool oneliner = false) :
+ bool oneliner = false,
+ bool system = false) :
m_cascades(casc),
m_skip_pointers(skipptr),
m_skip_references(skipref),
m_dont_show_children(nochildren),
m_dont_show_value(novalue),
- m_show_members_oneliner(oneliner)
+ m_show_members_oneliner(oneliner),
+ m_is_system(system)
{
}
@@ -200,6 +203,12 @@
return m_show_members_oneliner;
}
+ bool
+ IsSystem() const
+ {
+ return m_is_system;
+ }
+
virtual
~SummaryFormat()
{
@@ -228,8 +237,9 @@
bool nochildren = true,
bool novalue = true,
bool oneliner = false,
+ bool system = false,
std::string f = "") :
- SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner),
+ SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner,system),
m_format(f)
{
}
@@ -252,13 +262,14 @@
GetDescription()
{
StreamString sstr;
- sstr.Printf ("`%s`%s%s%s%s%s%s\n", m_format.c_str(),
+ sstr.Printf ("`%s`%s%s%s%s%s%s%s", m_format.c_str(),
m_cascades ? "" : " (not cascading)",
m_dont_show_children ? "" : " (show children)",
m_dont_show_value ? " (hide value)" : "",
m_show_members_oneliner ? " (one-line printout)" : "",
m_skip_pointers ? " (skip pointers)" : "",
- m_skip_references ? " (skip references)" : "");
+ m_skip_references ? " (skip references)" : "",
+ m_is_system ? " (system)" : "");
return sstr.GetString();
}
@@ -276,9 +287,10 @@
bool nochildren = true,
bool novalue = true,
bool oneliner = false,
+ bool system = false,
std::string fname = "",
std::string pscri = "") :
- SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner),
+ SummaryFormat(casc,skipptr,skipref,nochildren,novalue,oneliner,system),
m_function_name(fname),
m_python_script(pscri)
{
@@ -312,10 +324,14 @@
GetDescription()
{
StreamString sstr;
- sstr.Printf ("%s%s%s\n%s\n", m_cascades ? "" : " (not cascading)",
- m_skip_pointers ? " (skip pointers)" : "",
- m_skip_references ? " (skip references)" : "",
- m_python_script.c_str());
+ sstr.Printf ("%s%s%s%s%s%s%s\n%s", m_cascades ? "" : " (not cascading)",
+ m_dont_show_children ? "" : " (show children)",
+ m_dont_show_value ? " (hide value)" : "",
+ m_show_members_oneliner ? " (one-line printout)" : "",
+ m_skip_pointers ? " (skip pointers)" : "",
+ m_skip_references ? " (skip references)" : "",
+ m_is_system ? " (system)" : "",
+ m_python_script.c_str());
return sstr.GetString();
}
@@ -727,12 +743,12 @@
ValueNavigator m_value_nav;
SummaryNavigator m_summary_nav;
+ SummaryNavigator m_system_summary_nav;
RegexSummaryNavigator m_regex_summary_nav;
-
+ RegexSummaryNavigator m_system_regex_summary_nav;
+
NamedSummariesMap m_named_summaries_map;
-
- ScriptNavigator m_script_nav;
-
+
uint32_t m_last_revision;
public:
@@ -740,19 +756,48 @@
FormatManager() :
m_value_nav(this),
m_summary_nav(this),
+ m_system_summary_nav(this),
m_regex_summary_nav(this),
+ m_system_regex_summary_nav(this),
m_named_summaries_map(this),
- m_script_nav(this),
m_last_revision(0)
{
+ // add some default stuff
+ // most formats, summaries, ... actually belong to the users' lldbinit file rather than here
+ SummaryFormat::SharedPointer string_format(new StringSummaryFormat(false,
+ true,
+ false,
+ true,
+ false,
+ false,
+ true,
+ "${var%s}"));
+
+
+ SummaryFormat::SharedPointer string_array_format(new StringSummaryFormat(false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ true,
+ "${var%s}"));
+
+ lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
+
+
+ SystemSummary().Add(ConstString("char *").GetCString(), string_format);
+ SystemSummary().Add(ConstString("const char *").GetCString(), string_format);
+ SystemRegexSummary().Add(any_size_char_arr, string_array_format);
}
ValueNavigator& Value() { return m_value_nav; }
SummaryNavigator& Summary() { return m_summary_nav; }
+ SummaryNavigator& SystemSummary() { return m_system_summary_nav; }
RegexSummaryNavigator& RegexSummary() { return m_regex_summary_nav; }
+ RegexSummaryNavigator& SystemRegexSummary() { return m_system_regex_summary_nav; }
NamedSummariesMap& NamedSummary() { return m_named_summaries_map; }
- ScriptNavigator& Script() { return m_script_nav; }
static bool
GetFormatFromCString (const char *format_cstr,
Modified: lldb/trunk/include/lldb/Core/InputReader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReader.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReader.h (original)
+++ lldb/trunk/include/lldb/Core/InputReader.h Fri Jul 15 18:30:15 2011
@@ -52,6 +52,65 @@
bool
GetBatchMode();
};
+
+ struct InitializationParameters
+ {
+ private:
+ void* m_baton;
+ lldb::InputReaderGranularity m_token_size;
+ char* m_end_token;
+ char* m_prompt;
+ bool m_echo;
+ public:
+ InitializationParameters() :
+ m_baton(NULL),
+ m_token_size(lldb::eInputReaderGranularityLine),
+ m_echo(true)
+ {
+ SetEndToken("DONE");
+ SetPrompt("> ");
+ }
+
+ InitializationParameters&
+ SetEcho(bool e)
+ {
+ m_echo = e;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetBaton(void* b)
+ {
+ m_baton = b;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetGranularity(lldb::InputReaderGranularity g)
+ {
+ m_token_size = g;
+ return *this;
+ }
+
+ InitializationParameters&
+ SetEndToken(const char* e)
+ {
+ m_end_token = new char[strlen(e)+1];
+ ::strcpy(m_end_token,e);
+ return *this;
+ }
+
+ InitializationParameters&
+ SetPrompt(const char* p)
+ {
+ m_prompt = new char[strlen(p)+1];
+ ::strcpy(m_prompt,p);
+ return *this;
+ }
+
+ friend class InputReaderEZ;
+
+ };
InputReader (Debugger &debugger);
@@ -75,6 +134,12 @@
return Error("unimplemented");
}
+ virtual Error
+ Initialize(InitializationParameters& params)
+ {
+ return Error("unimplemented");
+ }
+
// to use these handlers instead of the Callback function, you must subclass
// InputReaderEZ, and redefine the handlers for the events you care about
virtual void
Modified: lldb/trunk/include/lldb/Core/InputReaderEZ.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/InputReaderEZ.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/InputReaderEZ.h (original)
+++ lldb/trunk/include/lldb/Core/InputReaderEZ.h Fri Jul 15 18:30:15 2011
@@ -10,6 +10,8 @@
#ifndef liblldb_InputReaderEZ_h_
#define liblldb_InputReaderEZ_h_
+#include <string.h>
+
#include "lldb/lldb-public.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/Core/Debugger.h"
@@ -30,7 +32,7 @@
const char *bytes,
size_t bytes_len);
public:
-
+
InputReaderEZ (Debugger &debugger) :
InputReader(debugger)
{}
@@ -38,11 +40,15 @@
virtual
~InputReaderEZ ();
- virtual Error Initialize(void* baton,
- lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
- const char* end_token = "DONE",
- const char *prompt = "> ",
- bool echo = true);
+ virtual Error
+ Initialize(void* baton,
+ lldb::InputReaderGranularity token_size = lldb::eInputReaderGranularityLine,
+ const char* end_token = "DONE",
+ const char *prompt = "> ",
+ bool echo = true);
+
+ virtual Error
+ Initialize(InitializationParameters& params);
virtual void
ActivateHandler(HandlerData&) {}
Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Fri Jul 15 18:30:15 2011
@@ -176,7 +176,7 @@
return false;
}
- if(m_options.m_format == eFormatInvalid)
+ if (m_options.m_format == eFormatInvalid)
{
result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -265,7 +265,7 @@
const char* typeA = command.GetArgumentAtIndex(0);
ConstString typeCS(typeA);
- if(!typeCS)
+ if (!typeCS)
{
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
@@ -418,34 +418,8 @@
// CommandObjectTypeSummaryAdd
//-------------------------------------------------------------------------
-class ScriptAddOptions
-{
-
-public:
-
- bool m_skip_pointers;
- bool m_skip_references;
- bool m_cascade;
- bool m_callback_is_synchronous;
- StringList m_target_types;
- StringList m_user_source;
-
- ScriptAddOptions(bool p,
- bool r,
- bool c) :
- m_skip_pointers(p),
- m_skip_references(r),
- m_cascade(c),
- m_target_types(),
- m_user_source()
- {
- }
-
- typedef lldb::SharedPtr<ScriptAddOptions>::Type SharedPointer;
-
-};
-
-static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.";
+static const char *g_reader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
+ "def function (valobj,dict):";
class TypeScriptAddInputReader : public InputReaderEZ
{
@@ -560,473 +534,542 @@
script_format.reset(new ScriptSummaryFormat(options->m_cascade,
options->m_skip_pointers,
options->m_skip_references,
- true,
- true,
- false,
+ options->m_no_children,
+ options->m_no_value,
+ options->m_one_liner,
+ options->m_is_system,
std::string(funct_name),
options->m_user_source.CopyList(" ")));
+ Error error;
+
for (int i = 0; i < options->m_target_types.GetSize(); i++)
{
const char *type_name = options->m_target_types.GetStringAtIndex(i);
- Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
+ CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
+ script_format,
+ (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
+ options->m_is_system,
+ &error);
+ if (error.Fail())
+ {
+ out_stream->Printf (error.AsCString());
+ out_stream->Flush();
+ return;
+ }
+ }
+
+ if (options->m_name)
+ {
+ if ( (bool)(*(options->m_name)) )
+ {
+ CommandObjectTypeSummaryAdd::AddSummary(*(options->m_name),
+ script_format,
+ CommandObjectTypeSummaryAdd::eNamedSummary,
+ options->m_is_system,
+ &error);
+ if (error.Fail())
+ {
+ out_stream->Printf (error.AsCString());
+ out_stream->Flush();
+ return;
+ }
+ }
+ else
+ {
+ out_stream->Printf (error.AsCString());
+ out_stream->Flush();
+ return;
+ }
}
}
};
-class CommandObjectTypeSummaryAdd : public CommandObject
+Error
+CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
{
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+ bool success;
+
+ switch (short_option)
+ {
+ case 'C':
+ m_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;
+ case 'n':
+ m_name = new ConstString(option_arg);
+ break;
+ case 's':
+ 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_is_system = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
-private:
-
- class CommandOptions : public Options
+ return error;
+}
+
+void
+CommandObjectTypeSummaryAdd::CommandOptions::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;
+ m_name = NULL;
+ m_python_script = "";
+ m_python_function = "";
+ m_is_add_script = false;
+ m_is_system = false;
+}
+
+void
+CommandObjectTypeSummaryAdd::CollectPythonScript (ScriptAddOptions *options,
+ CommandReturnObject &result)
+{
+ InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger()));
+ if (reader_sp && 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;
- case 'n':
- m_name = new ConstString(option_arg);
- break;
- case 's':
- 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;
- default:
- error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
- break;
- }
-
- return error;
- }
+ InputReaderEZ::InitializationParameters ipr;
- void
- OptionParsingStarting ()
+ Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" ")));
+ if (err.Success())
{
- 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;
- m_name = NULL;
- m_python_script = "";
- m_python_function = "";
- m_is_add_script = false;
+ m_interpreter.GetDebugger().PushInputReader (reader_sp);
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
-
- const OptionDefinition*
- GetDefinitions ()
+ else
{
- return g_option_table;
+ result.AppendError (err.AsCString());
+ result.SetStatus (eReturnStatusFailed);
}
-
- // 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;
- ConstString* m_name;
- std::string m_python_script;
- std::string m_python_function;
- bool m_is_add_script;
- };
+ }
+ else
+ {
+ result.AppendError("out of memory");
+ result.SetStatus (eReturnStatusFailed);
+ }
- CommandOptions m_options;
+}
+
+bool
+CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
+{
+ const size_t argc = command.GetArgumentCount();
- virtual Options *
- GetOptions ()
+ if (argc < 1 && !m_options.m_name)
{
- return &m_options;
+ result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-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 ()
- {
- }
-
- void
- CollectPythonScript
- (
- ScriptAddOptions *options,
- CommandReturnObject &result
- )
+ SummaryFormatSP script_format;
+
+ if (!m_options.m_python_function.empty()) // we have a Python function ready to use
{
- InputReaderSP reader_sp (new TypeScriptAddInputReader(m_interpreter.GetDebugger()));
- if (reader_sp && options)
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (!interpreter)
{
-
- Error err (reader_sp->Initialize (options));
- if (err.Success())
- {
- m_interpreter.GetDebugger().PushInputReader (reader_sp);
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.AppendError (err.AsCString());
- result.SetStatus (eReturnStatusFailed);
- }
+ result.AppendError ("Internal error #1N: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else
+ const char *funct_name = m_options.m_python_function.c_str();
+ if (!funct_name || !funct_name[0])
{
- result.AppendError("out of memory");
+ result.AppendError ("Internal error #2N: no script attached.\n");
result.SetStatus (eReturnStatusFailed);
+ return false;
}
+ script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ m_options.m_is_system,
+ std::string(funct_name),
+ " " + m_options.m_python_function + "(valobj,dict)"));
}
-
- bool
- Execute (Args& command, CommandReturnObject &result)
- {
- if (m_options.m_is_add_script)
- return Execute_ScriptSummary(command, result);
- else
- return Execute_StringSummary(command, result);
- }
-
- bool
- Execute_ScriptSummary (Args& command, CommandReturnObject &result)
+ else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
{
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1)
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+ if (!interpreter)
{
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
- result.SetStatus(eReturnStatusFailed);
+ result.AppendError ("Internal error #1Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
return false;
}
-
- if (!m_options.m_python_function.empty()) // we have a Python function ready to use
+ StringList funct_sl;
+ funct_sl << m_options.m_python_script.c_str();
+ StringList funct_name_sl;
+ if (!interpreter->GenerateTypeScriptFunction (funct_sl,
+ funct_name_sl))
{
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (!interpreter)
- {
- result.AppendError ("Internal error #1N: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- const char *funct_name = m_options.m_python_function.c_str();
- if (!funct_name || !funct_name[0])
- {
- result.AppendError ("Internal error #2N: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- // now I have a valid function name, let's add this as script for every type in the list
-
- SummaryFormatSP script_format;
- script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
- m_options.m_skip_pointers,
- m_options.m_skip_references,
- true,
- true,
- false,
- std::string(funct_name),
- " " + m_options.m_python_function + "(valobj,dict)"));
-
- for (int i = 0; i < command.GetArgumentCount(); i++)
- {
- const char *type_name = command.GetArgumentAtIndex(i);
- Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
- }
+ result.AppendError ("Internal error #2Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else if (m_options.m_python_script.empty()) // use an InputReader to grab Python code from the user
- {
- ScriptAddOptions *options = new ScriptAddOptions(m_options.m_skip_pointers,
- m_options.m_skip_references,
- m_options.m_cascade);
-
- for(int 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 (funct_name_sl.GetSize() == 0)
+ {
+ result.AppendError ("Internal error #3Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else // we have a quick 1-line script, just use it
+ const char *funct_name = funct_name_sl.GetStringAtIndex(0);
+ if (!funct_name || !funct_name[0])
{
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (!interpreter)
- {
- result.AppendError ("Internal error #1Q: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- StringList funct_sl;
- funct_sl << m_options.m_python_script.c_str();
- StringList funct_name_sl;
- if (!interpreter->GenerateTypeScriptFunction (funct_sl,
- funct_name_sl))
- {
- result.AppendError ("Internal error #2Q: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- if (funct_name_sl.GetSize() == 0)
- {
- result.AppendError ("Internal error #3Q: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- const char *funct_name = funct_name_sl.GetStringAtIndex(0);
- if (!funct_name || !funct_name[0])
+ result.AppendError ("Internal error #4Q: no script attached.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ m_options.m_is_system,
+ std::string(funct_name),
+ " " + m_options.m_python_script));
+ }
+ else // use an InputReader to grab Python code from the user
+ {
+ ScriptAddOptions *options = new ScriptAddOptions(m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_cascade,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ m_options.m_regex,
+ m_options.m_is_system,
+ m_options.m_name);
+
+ for(int i = 0; i < argc; i++) {
+ const char* typeA = command.GetArgumentAtIndex(i);
+ if (typeA && *typeA)
+ options->m_target_types << typeA;
+ else
{
- result.AppendError ("Internal error #4Q: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
+ result.AppendError("empty typenames not allowed");
+ result.SetStatus(eReturnStatusFailed);
return false;
}
- // now I have a valid function name, let's add this as script for every type in the list
-
- ScriptFormatSP script_format;
- script_format.reset(new ScriptSummaryFormat(m_options.m_cascade,
- m_options.m_skip_pointers,
- m_options.m_skip_references,
- true,
- true,
- false,
- std::string(funct_name),
- " " + m_options.m_python_script));
-
- for (int i = 0; i < command.GetArgumentCount(); i++)
- {
- const char *type_name = command.GetArgumentAtIndex(i);
- Debugger::SummaryFormats::Add(ConstString(type_name), script_format);
- }
}
+ CollectPythonScript(options,result);
return result.Succeeded();
}
-
- bool
- Execute_StringSummary (Args& command, CommandReturnObject &result)
+
+ // 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 (int i = 0; i < command.GetArgumentCount(); i++)
{
- const size_t argc = command.GetArgumentCount();
-
- if (argc < 1 && !m_options.m_name)
+ const char *type_name = command.GetArgumentAtIndex(i);
+ CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
+ script_format,
+ (m_options.m_regex ? eRegexSummary : eRegularSummary),
+ m_options.m_is_system,
+ &error);
+ if (error.Fail())
{
- result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
+ result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
-
- if(!m_options.m_one_liner && m_options.m_format_string.empty())
+ }
+
+ if (m_options.m_name)
+ {
+ if ( (bool)(*(m_options.m_name)) )
{
- result.AppendError("empty summary strings not allowed");
+ AddSummary(*(m_options.m_name), script_format, eNamedSummary, m_options.m_is_system, &error);
+ if (error.Fail())
+ {
+ result.AppendError(error.AsCString());
+ result.AppendError("added to types, but not given a name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
+ else
+ {
+ result.AppendError("added to types, but not given a name");
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 StringSummaryFormat(m_options.m_cascade,
- m_options.m_skip_pointers,
- m_options.m_skip_references,
- m_options.m_no_children,
- m_options.m_no_value,
- m_options.m_one_liner,
- format_cstr));
-
- if (error.Fail())
+ }
+
+ return result.Succeeded();
+}
+
+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_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 StringSummaryFormat(m_options.m_cascade,
+ m_options.m_skip_pointers,
+ m_options.m_skip_references,
+ m_options.m_no_children,
+ m_options.m_no_value,
+ m_options.m_one_liner,
+ m_options.m_is_system,
+ 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(int i = 0; i < argc; i++) {
+ const char* typeA = command.GetArgumentAtIndex(i);
+ if (!typeA || typeA[0] == '\0')
{
- result.AppendError(error.AsCString());
+ result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
return false;
}
+ ConstString typeCS(typeA);
- // now I have a valid format, let's add it to every type
+ AddSummary(typeCS,
+ entry,
+ (m_options.m_regex ? eRegexSummary : eRegularSummary),
+ m_options.m_is_system,
+ &error);
- 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);
- }
+ if (error.Fail())
+ {
+ result.AppendError(error.AsCString());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
-
- if (m_options.m_name)
+ }
+
+ if (m_options.m_name)
+ {
+ if ( (bool)(*(m_options.m_name)) )
{
- if( (bool)(*(m_options.m_name)) )
- {
- Debugger::NamedSummaryFormats::Add(*(m_options.m_name), entry);
- }
- else
+ AddSummary(*(m_options.m_name), entry, eNamedSummary, m_options.m_is_system, &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();
+ else
+ {
+ result.AppendError("added to types, but not given a name");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
-};
+ result.SetStatus(eReturnStatusSuccessFinishNoResult);
+ return result.Succeeded();
+}
+
+CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
+CommandObject (interpreter,
+ "type summary add",
+ "Add a new summary style for a type.",
+ NULL), m_options (interpreter)
+{
+ CommandArgumentEntry type_arg;
+ CommandArgumentData type_style_arg;
+
+ type_style_arg.arg_type = eArgTypeName;
+ type_style_arg.arg_repetition = eArgRepeatPlus;
+
+ type_arg.push_back (type_style_arg);
+
+ m_arguments.push_back (type_arg);
+
+ SetHelpLong(
+ "Some examples of using this command.\n"
+ "We use as reference the following snippet of code:\n"
+ "struct JustADemo\n"
+ "{\n"
+ "int* ptr;\n"
+ "float value;\n"
+ "JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}\n"
+ "};\n"
+ "JustADemo object(42,3.14);\n"
+ "struct AnotherDemo : public JustADemo\n"
+ "{\n"
+ "uint8_t byte;\n"
+ "AnotherDemo(uint8_t b = 'E', int p = 1, float v = 0.1) : JustADemo(p,v), byte(b) {}\n"
+ "};\n"
+ "AnotherDemo *another_object = new AnotherDemo('E',42,3.14);\n"
+ "\n"
+ "type summary add -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"
+ );
+}
+
+bool
+CommandObjectTypeSummaryAdd::Execute (Args& command, CommandReturnObject &result)
+{
+ if (m_options.m_is_add_script)
+ return Execute_ScriptSummary(command, result);
+ else
+ return Execute_StringSummary(command, result);
+}
+
+bool
+CommandObjectTypeSummaryAdd::AddSummary(const ConstString& type_name,
+ SummaryFormatSP entry,
+ SummaryFormatType type,
+ bool is_system,
+ Error* error)
+{
+ 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;
+ }
+
+ if (!is_system)
+ {
+ Debugger::RegexSummaryFormats::Delete(type_name);
+ Debugger::RegexSummaryFormats::Add(typeRX, entry);
+ }
+ else
+ {
+ Debugger::SystemRegexSummaryFormats::Delete(type_name);
+ Debugger::SystemRegexSummaryFormats::Add(typeRX, entry);
+ }
+ return true;
+ }
+ else if (type == eNamedSummary)
+ {
+ // system named summaries do not exist (yet?)
+ Debugger::NamedSummaryFormats::Add(type_name,entry);
+ return true;
+ }
+ else
+ {
+ if (!is_system)
+ Debugger::SummaryFormats::Add(type_name,entry);
+ else
+ Debugger::SystemSummaryFormats::Add(type_name,entry);
+ return true;
+ }
+}
OptionDefinition
CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
{
+ { LLDB_OPT_SET_ALL, false, "system", 'w', no_argument, NULL, 0, eArgTypeBoolean, "This is a system summary (makes it harder to delete it by accident)."},
{ 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."},
@@ -1034,11 +1077,11 @@
{ 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."},
- { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, 0, eArgTypeName, "A name for this summary string."},
{ LLDB_OPT_SET_3, false, "python-script", 's', required_argument, NULL, 0, eArgTypeName, "Give a one-liner Python script as part of the command."},
{ LLDB_OPT_SET_3, false, "python-function", 'F', required_argument, NULL, 0, eArgTypeName, "Give the name of a Python function to use for this type."},
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeName, "Input Python code to use for this type manually."},
+ { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', no_argument, NULL, 0, eArgTypeBoolean, "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 }
};
@@ -1049,12 +1092,73 @@
class CommandObjectTypeSummaryDelete : public CommandObject
{
+private:
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter)
+ {
+ }
+
+ virtual
+ ~CommandOptions (){}
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'a':
+ m_delete_system = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_delete_system = 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_system;
+ };
+
+ CommandOptions m_options;
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
public:
CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type summary delete",
"Delete an existing summary style for a type.",
- NULL)
+ NULL), m_options(interpreter)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@@ -1087,7 +1191,7 @@
const char* typeA = command.GetArgumentAtIndex(0);
ConstString typeCS(typeA);
- if(!typeCS)
+ if (!typeCS)
{
result.AppendError("empty typenames not allowed");
result.SetStatus(eReturnStatusFailed);
@@ -1097,8 +1201,10 @@
bool delete_summary = Debugger::SummaryFormats::Delete(typeCS);
bool delete_regex = Debugger::RegexSummaryFormats::Delete(typeCS);
bool delete_named = Debugger::NamedSummaryFormats::Delete(typeCS);
+ bool delete_sys = m_options.m_delete_system ? Debugger::SystemSummaryFormats::Delete(typeCS) : false;
+ bool delete_sys_regex = m_options.m_delete_system ? Debugger::SystemRegexSummaryFormats::Delete(typeCS) : false;
- if (delete_summary || delete_regex || delete_named)
+ if (delete_summary || delete_regex || delete_named || delete_sys || delete_sys_regex)
{
result.SetStatus(eReturnStatusSuccessFinishNoResult);
return result.Succeeded();
@@ -1111,7 +1217,13 @@
}
}
-
+};
+
+OptionDefinition
+CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean, "Also delete system summaries (not recommended)."},
+ { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
//-------------------------------------------------------------------------
@@ -1120,12 +1232,74 @@
class CommandObjectTypeSummaryClear : public CommandObject
{
+private:
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter)
+ {
+ }
+
+ virtual
+ ~CommandOptions (){}
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'a':
+ m_delete_system = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_delete_system = 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_system;
+ };
+
+ CommandOptions m_options;
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
public:
CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
CommandObject (interpreter,
"type summary clear",
"Delete all existing summary styles.",
- NULL)
+ NULL), m_options(interpreter)
{
}
@@ -1139,12 +1313,26 @@
Debugger::SummaryFormats::Clear();
Debugger::RegexSummaryFormats::Clear();
Debugger::NamedSummaryFormats::Clear();
+
+ if (m_options.m_delete_system)
+ {
+ Debugger::SystemSummaryFormats::Clear();
+ Debugger::SystemRegexSummaryFormats::Clear();
+ }
+
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
+OptionDefinition
+CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeBoolean, "Also clear system summaries (not recommended)."},
+ { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
//-------------------------------------------------------------------------
// CommandObjectTypeSummaryList
//-------------------------------------------------------------------------
@@ -1210,9 +1398,10 @@
else
param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
Debugger::SummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
+ Debugger::SystemSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
delete param;
- if(Debugger::RegexSummaryFormats::GetCount() > 0)
+ if (Debugger::RegexSummaryFormats::GetCount() > 0 || Debugger::SystemRegexSummaryFormats::GetCount() > 0 )
{
result.GetOutputStream().Printf("Regex-based summaries (slower):\n");
if (argc == 1) {
@@ -1223,10 +1412,11 @@
else
rxparam = new CommandObjectTypeRXSummaryList_LoopCallbackParam(this,&result);
Debugger::RegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
+ Debugger::SystemRegexSummaryFormats::LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, rxparam);
delete rxparam;
}
- if(Debugger::NamedSummaryFormats::GetCount() > 0)
+ if (Debugger::NamedSummaryFormats::GetCount() > 0)
{
result.GetOutputStream().Printf("Named summaries:\n");
if (argc == 1) {
@@ -1259,7 +1449,6 @@
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
@@ -1282,7 +1471,6 @@
return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
}
-
class CommandObjectTypeFormat : public CommandObjectMultiword
{
public:
Modified: lldb/trunk/source/Commands/CommandObjectType.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.h?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.h (original)
+++ lldb/trunk/source/Commands/CommandObjectType.h Fri Jul 15 18:30:15 2011
@@ -19,13 +19,57 @@
#include "lldb/lldb-types.h"
#include "lldb/Interpreter/CommandObjectMultiword.h"
+#include "lldb/Interpreter/Options.h"
namespace lldb_private {
-//-------------------------------------------------------------------------
-// CommandObjectMultiwordBreakpoint
-//-------------------------------------------------------------------------
-
+class ScriptAddOptions
+{
+
+public:
+
+ bool m_skip_pointers;
+ bool m_skip_references;
+ bool m_cascade;
+ StringList m_target_types;
+ StringList m_user_source;
+
+ bool m_no_children;
+ bool m_no_value;
+ bool m_one_liner;
+ bool m_regex;
+
+ bool m_is_system;
+
+ ConstString* m_name;
+
+ ScriptAddOptions(bool sptr,
+ bool sref,
+ bool casc,
+ bool noch,
+ bool novl,
+ bool onel,
+ bool regx,
+ bool syst,
+ ConstString* name) :
+ m_skip_pointers(sptr),
+ m_skip_references(sref),
+ m_cascade(casc),
+ m_target_types(),
+ m_user_source(),
+ m_no_children(noch),
+ m_no_value(novl),
+ m_one_liner(onel),
+ m_regex(regx),
+ m_is_system(syst),
+ m_name(name)
+ {
+ }
+
+ typedef lldb::SharedPtr<ScriptAddOptions>::Type SharedPointer;
+
+};
+
class CommandObjectType : public CommandObjectMultiword
{
public:
@@ -35,6 +79,99 @@
~CommandObjectType ();
};
+class CommandObjectTypeSummaryAdd : public CommandObject
+{
+
+private:
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter)
+ {
+ }
+
+ virtual
+ ~CommandOptions (){}
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg);
+
+ void
+ OptionParsingStarting ();
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ 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;
+ ConstString* m_name;
+ std::string m_python_script;
+ std::string m_python_function;
+ bool m_is_add_script;
+ bool m_is_system;
+ };
+
+ CommandOptions m_options;
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+ void
+ CollectPythonScript(ScriptAddOptions *options,
+ CommandReturnObject &result);
+
+ bool
+ Execute_ScriptSummary (Args& command, CommandReturnObject &result);
+
+ bool
+ Execute_StringSummary (Args& command, CommandReturnObject &result);
+
+public:
+
+ enum SummaryFormatType
+ {
+ eRegularSummary,
+ eRegexSummary,
+ eNamedSummary,
+ };
+
+ CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
+
+ ~CommandObjectTypeSummaryAdd ()
+ {
+ }
+
+ bool
+ Execute (Args& command, CommandReturnObject &result);
+
+ static bool
+ AddSummary(const ConstString& type_name,
+ lldb::SummaryFormatSP entry,
+ SummaryFormatType type,
+ bool is_system,
+ Error* error = NULL);
+};
} // namespace lldb_private
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Fri Jul 15 18:30:15 2011
@@ -1798,6 +1798,48 @@
}
bool
+Debugger::SystemSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
+{
+ return GetFormatManager().SystemSummary().Get(vobj,entry);
+}
+
+void
+Debugger::SystemSummaryFormats::Add(const ConstString &type, const SummaryFormat::SharedPointer &entry)
+{
+ GetFormatManager().SystemSummary().Add(type.AsCString(),entry);
+}
+
+bool
+Debugger::SystemSummaryFormats::Delete(const ConstString &type)
+{
+ return GetFormatManager().SystemSummary().Delete(type.AsCString());
+}
+
+void
+Debugger::SystemSummaryFormats::Clear()
+{
+ GetFormatManager().SystemSummary().Clear();
+}
+
+void
+Debugger::SystemSummaryFormats::LoopThrough(SummaryFormat::SummaryCallback callback, void* callback_baton)
+{
+ GetFormatManager().SystemSummary().LoopThrough(callback, callback_baton);
+}
+
+uint32_t
+Debugger::SystemSummaryFormats::GetCurrentRevision()
+{
+ return GetFormatManager().GetCurrentRevision();
+}
+
+uint32_t
+Debugger::SystemSummaryFormats::GetCount()
+{
+ return GetFormatManager().SystemSummary().GetCount();
+}
+
+bool
Debugger::RegexSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
{
return GetFormatManager().RegexSummary().Get(vobj,entry);
@@ -1840,6 +1882,48 @@
}
bool
+Debugger::SystemRegexSummaryFormats::Get(ValueObject& vobj, SummaryFormat::SharedPointer &entry)
+{
+ return GetFormatManager().SystemRegexSummary().Get(vobj,entry);
+}
+
+void
+Debugger::SystemRegexSummaryFormats::Add(const lldb::RegularExpressionSP &type, const SummaryFormat::SharedPointer &entry)
+{
+ GetFormatManager().SystemRegexSummary().Add(type,entry);
+}
+
+bool
+Debugger::SystemRegexSummaryFormats::Delete(const ConstString &type)
+{
+ return GetFormatManager().SystemRegexSummary().Delete(type.AsCString());
+}
+
+void
+Debugger::SystemRegexSummaryFormats::Clear()
+{
+ GetFormatManager().SystemRegexSummary().Clear();
+}
+
+void
+Debugger::SystemRegexSummaryFormats::LoopThrough(SummaryFormat::RegexSummaryCallback callback, void* callback_baton)
+{
+ GetFormatManager().SystemRegexSummary().LoopThrough(callback, callback_baton);
+}
+
+uint32_t
+Debugger::SystemRegexSummaryFormats::GetCurrentRevision()
+{
+ return GetFormatManager().GetCurrentRevision();
+}
+
+uint32_t
+Debugger::SystemRegexSummaryFormats::GetCount()
+{
+ return GetFormatManager().SystemRegexSummary().GetCount();
+}
+
+bool
Debugger::NamedSummaryFormats::Get(const ConstString &type, SummaryFormat::SharedPointer &entry)
{
return GetFormatManager().NamedSummary().Get(type.AsCString(),entry);
Modified: lldb/trunk/source/Core/InputReaderEZ.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/InputReaderEZ.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Core/InputReaderEZ.cpp (original)
+++ lldb/trunk/source/Core/InputReaderEZ.cpp Fri Jul 15 18:30:15 2011
@@ -75,6 +75,16 @@
echo);
}
+Error
+InputReaderEZ::Initialize(InitializationParameters& params)
+{
+ return Initialize(params.m_baton,
+ params.m_token_size,
+ params.m_end_token,
+ params.m_prompt,
+ params.m_echo);
+}
+
InputReaderEZ::~InputReaderEZ ()
{
}
\ No newline at end of file
Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Fri Jul 15 18:30:15 2011
@@ -209,8 +209,14 @@
if (m_last_value_format.get())
m_last_value_format.reset((ValueFormat*)NULL);
Debugger::ValueFormats::Get(*this, m_last_value_format);
+ // to find a summary we look for a direct summary, then if there is none
+ // we look for a regex summary. if there is none we look for a system
+ // summary (direct), and if also that fails, we look for a system
+ // regex summary
if (!Debugger::SummaryFormats::Get(*this, m_last_summary_format))
- Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format);
+ if (!Debugger::RegexSummaryFormats::Get(*this, m_last_summary_format))
+ if (!Debugger::SystemSummaryFormats::Get(*this, m_last_summary_format))
+ Debugger::SystemRegexSummaryFormats::Get(*this, m_last_summary_format);
m_last_format_mgr_revision = Debugger::ValueFormats::GetCurrentRevision();
ClearUserVisibleData();
@@ -518,7 +524,7 @@
{
clang_type_t clang_type = GetClangType();
- // See if this is a pointer to a C string?
+ // Do some default printout for function pointers
if (clang_type)
{
StreamString sstr;
@@ -530,116 +536,7 @@
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (exe_scope)
{
- if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
- ClangASTContext::IsCharType (elem_or_pointee_clang_type))
- {
- Target *target = exe_scope->CalculateTarget();
- if (target != NULL)
- {
- lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
- AddressType cstr_address_type = eAddressTypeInvalid;
-
- size_t cstr_len = 0;
- bool capped_data = false;
- if (type_flags.Test (ClangASTContext::eTypeIsArray))
- {
- // We have an array
- cstr_len = ClangASTContext::GetArraySize (clang_type);
- if (cstr_len > 512) // TODO: make cap a setting
- {
- cstr_len = ClangASTContext::GetArraySize (clang_type);
- if (cstr_len > 512) // TODO: make cap a setting
- {
- capped_data = true;
- cstr_len = 512;
- }
- }
- cstr_address = GetAddressOf (cstr_address_type, true);
- }
- else
- {
- // We have a pointer
- cstr_address = GetPointerValue (cstr_address_type, true);
- }
- if (cstr_address != LLDB_INVALID_ADDRESS)
- {
- Address cstr_so_addr (NULL, cstr_address);
- DataExtractor data;
- size_t bytes_read = 0;
- std::vector<char> data_buffer;
- Error error;
- bool prefer_file_cache = false;
- if (cstr_len > 0)
- {
- data_buffer.resize(cstr_len);
- data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
- bytes_read = target->ReadMemory (cstr_so_addr,
- prefer_file_cache,
- &data_buffer.front(),
- cstr_len,
- error);
- if (bytes_read > 0)
- {
- sstr << '"';
- data.Dump (&sstr,
- 0, // Start offset in "data"
- eFormatCharArray, // Print as characters
- 1, // Size of item (1 byte for a char!)
- bytes_read, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
- if (capped_data)
- sstr << "...";
- sstr << '"';
- }
- }
- else
- {
- const size_t k_max_buf_size = 256;
- data_buffer.resize (k_max_buf_size + 1);
- // NULL terminate in case we don't get the entire C string
- data_buffer.back() = '\0';
-
- sstr << '"';
-
- data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
- while ((bytes_read = target->ReadMemory (cstr_so_addr,
- prefer_file_cache,
- &data_buffer.front(),
- k_max_buf_size,
- error)) > 0)
- {
- size_t len = strlen(&data_buffer.front());
- if (len == 0)
- break;
- if (len > bytes_read)
- len = bytes_read;
-
- data.Dump (&sstr,
- 0, // Start offset in "data"
- eFormatCharArray, // Print as characters
- 1, // Size of item (1 byte for a char!)
- len, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
-
- if (len < k_max_buf_size)
- break;
- cstr_so_addr.Slide (k_max_buf_size);
- }
- sstr << '"';
- }
- }
- }
-
- if (sstr.GetSize() > 0)
- m_summary_str.assign (sstr.GetData(), sstr.GetSize());
- }
- else if (ClangASTContext::IsFunctionPointerType (clang_type))
+ if (ClangASTContext::IsFunctionPointerType (clang_type))
{
AddressType func_ptr_address_type = eAddressTypeInvalid;
lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
@@ -988,7 +885,7 @@
RefCounter ref(&m_dump_printable_counter);
- if(custom_format != lldb::eFormatInvalid)
+ if (custom_format != lldb::eFormatInvalid)
SetFormat(custom_format);
const char * return_value;
@@ -1146,10 +1043,10 @@
return false;
}
const char *targetvalue = GetPrintableRepresentation(val_obj_display, custom_format);
- if(targetvalue)
+ if (targetvalue)
s.PutCString(targetvalue);
bool var_success = (targetvalue != NULL);
- if(custom_format != eFormatInvalid)
+ if (custom_format != eFormatInvalid)
SetFormat(eFormatDefault);
return var_success;
}
@@ -1624,7 +1521,7 @@
{
const bool is_deref_of_parent = IsDereferenceOfParent ();
- if(is_deref_of_parent && epformat == eDereferencePointers) {
+ if (is_deref_of_parent && epformat == eDereferencePointers) {
// this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
// fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
// the eHonorPointers mode is meant to produce strings in this latter format
@@ -1639,7 +1536,7 @@
// if we are a deref_of_parent just because we are synthetic array
// members made up to allow ptr[%d] syntax to work in variable
// printing, then add our name ([%d]) to the expression path
- if(m_is_array_item_for_pointer && epformat == eHonorPointers)
+ if (m_is_array_item_for_pointer && epformat == eHonorPointers)
s.PutCString(m_name.AsCString());
if (!IsBaseClass())
@@ -1654,7 +1551,7 @@
{
const uint32_t non_base_class_parent_type_info = ClangASTContext::GetTypeInfo (non_base_class_parent_clang_type, NULL, NULL);
- if(parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
+ if (parent && parent->IsDereferenceOfParent() && epformat == eHonorPointers)
{
s.PutCString("->");
}
@@ -2584,7 +2481,7 @@
if (val_cstr && (!entry || entry->DoesPrintValue() || !sum_cstr))
s.Printf(" %s", valobj->GetValueAsCString());
- if(sum_cstr)
+ if (sum_cstr)
{
// for some reason, using %@ (ObjC description) in a summary string, makes
// us believe we need to reset ourselves, thus invalidating the content of
Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Fri Jul 15 18:30:15 2011
@@ -117,7 +117,7 @@
clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
// We currently can't complete objective C types through the newly added ASTContext
// because it only supports TagDecl objects right now...
- if(class_interface_decl)
+ if (class_interface_decl)
{
bool is_forward_decl = class_interface_decl->isForwardDecl();
if (is_forward_decl && class_interface_decl->hasExternalLexicalStorage())
Modified: lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp (original)
+++ lldb/trunk/source/Symbol/TypeHierarchyNavigator.cpp Fri Jul 15 18:30:15 2011
@@ -61,7 +61,7 @@
*/
Error error;
ValueObject* target = m_value_object.Dereference(error).get();
- if(error.Fail() || !target)
+ if (error.Fail() || !target)
return true;
if (LoopThrough(typePtr->getPointeeType(), callback, eStrippedPointer, callback_baton) == false)
return false;
@@ -73,10 +73,10 @@
if (ClangASTContext::GetCompleteType(ast, m_value_object.GetClangType()) && !objc_class_type->isObjCId())
{
clang::ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
- if(class_interface_decl)
+ if (class_interface_decl)
{
clang::ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if(superclass_interface_decl)
+ if (superclass_interface_decl)
{
clang::QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
return LoopThrough(ivar_qual_type, callback, eObjCBaseClass, callback_baton);
@@ -95,7 +95,7 @@
if (record->hasDefinition())
{
clang::CXXRecordDecl::base_class_iterator pos,end;
- if( record->getNumBases() > 0)
+ if ( record->getNumBases() > 0)
{
end = record->bases_end();
for (pos = record->bases_begin(); pos != end; pos++)
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-script/TestDataFormatterScript.py Fri Jul 15 18:30:15 2011
@@ -56,7 +56,7 @@
# Set the script here to ease the formatting
script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');'
- self.runCmd("type summary add add i_am_cool -s \"%s\"" % script)
+ self.runCmd("type summary add i_am_cool -s \"%s\"" % script)
self.expect("frame variable one",
substrs = ['Hello from Python',
@@ -85,6 +85,9 @@
self.expect("frame variable two",
substrs = ['int says 1'])
+
+ self.expect("frame variable twoptr",
+ substrs = ['int says 1'])
# Change the summary
self.runCmd("type summary add -f \"int says ${var.integer}, and float says ${var.floating}\" i_am_cool")
@@ -103,6 +106,72 @@
self.expect("frame variable twoptr", matching=False,
substrs = ['and float says 2.71'])
+ script = 'return \'Python summary\'';
+
+ self.runCmd("type summary add --name test_summary -s \"%s\"" % script)
+
+ # attach the Python named summary to someone
+ self.runCmd("frame variable one --summary test_summary")
+
+ self.expect("frame variable one",
+ substrs = ['Python summary'])
+
+ # should not bind to the type
+ self.expect("frame variable two", matching=False,
+ substrs = ['Python summary'])
+
+ self.runCmd("type summary add i_am_cool -f \"Text summary\"")
+
+ self.expect("frame variable one",
+ substrs = ['Python summary'])
+
+ # use the type summary
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ self.runCmd("n"); # skip ahead to make values change
+
+ # both should use the type summary now
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ # disable type summary for pointers, and make a Python regex summary
+ self.runCmd("type summary add i_am_cool -p -f \"Text summary\"")
+ self.runCmd("type summary add -x cool -s \"%s\"" % script)
+
+ # variables should stick to the type summary
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ # array and pointer should match the Python one
+ self.expect("frame variable twoptr",
+ substrs = ['Python summary'])
+
+ self.expect("frame variable array",
+ substrs = ['Python summary'])
+
+ # return pointers to the type summary
+ self.runCmd("type summary add i_am_cool -f \"Text summary\"")
+
+ self.expect("frame variable one",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable two",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable twoptr",
+ substrs = ['Text summary'])
+
+ self.expect("frame variable array",
+ substrs = ['Python summary'])
+
+
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp?rev=135326&r1=135325&r2=135326&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-script/main.cpp Fri Jul 15 18:30:15 2011
@@ -41,9 +41,13 @@
i_am_cool* twoptr = &two;
+ i_am_cool array[5];
+
i_am_cooler three(10,4,1985,1/1/2011,'B','E'); // Set break point at this line.
two.integer = 1;
+ int dummy = 1;
+
return 0;
}
\ No newline at end of file
More information about the lldb-commits
mailing list