[Lldb-commits] [lldb] r134574 - in /lldb/trunk: include/lldb/Interpreter/CommandInterpreter.h include/lldb/Interpreter/CommandObject.h include/lldb/lldb-enumerations.h source/Commands/CommandObjectType.cpp source/Interpreter/CommandInterpreter.cpp source/Interpreter/CommandObject.cpp
Enrico Granata
granata.enrico at gmail.com
Wed Jul 6 17:38:40 PDT 2011
Author: enrico
Date: Wed Jul 6 19:38:40 2011
New Revision: 134574
URL: http://llvm.org/viewvc/llvm-project?rev=134574&view=rev
Log:
new detailed descriptions for type summary add and type format add
some changes to the help system code for better display of long help text
-p and -r flags now also work for type format add
Modified:
lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
lldb/trunk/include/lldb/Interpreter/CommandObject.h
lldb/trunk/include/lldb/lldb-enumerations.h
lldb/trunk/source/Commands/CommandObjectType.cpp
lldb/trunk/source/Interpreter/CommandInterpreter.cpp
lldb/trunk/source/Interpreter/CommandObject.cpp
Modified: lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h?rev=134574&r1=134573&r2=134574&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandInterpreter.h Wed Jul 6 19:38:40 2011
@@ -242,6 +242,18 @@
const char *separator,
const char *help_text,
uint32_t max_word_len);
+
+ // this mimics OutputFormattedHelpText but it does perform a much simpler
+ // formatting, basically ensuring line alignment. This is only good if you have
+ // some complicated layout for your help text and want as little help as reasonable
+ // in properly displaying it. Most of the times, you simply want to type some text
+ // and have it printed in a reasonable way on screen. If so, use OutputFormattedHelpText
+ void
+ OutputHelpText (Stream &stream,
+ const char *command_word,
+ const char *separator,
+ const char *help_text,
+ uint32_t max_word_len);
Debugger &
GetDebugger ()
Modified: lldb/trunk/include/lldb/Interpreter/CommandObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/CommandObject.h?rev=134574&r1=134573&r2=134574&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/CommandObject.h (original)
+++ lldb/trunk/include/lldb/Interpreter/CommandObject.h Wed Jul 6 19:38:40 2011
@@ -29,12 +29,36 @@
typedef const char *(ArgumentHelpCallbackFunction) ();
+ struct ArgumentHelpCallback
+ {
+ ArgumentHelpCallbackFunction *help_callback;
+ bool self_formatting;
+ ArgumentHelpCallback(ArgumentHelpCallbackFunction *p,
+ bool f = false) :
+ help_callback(p),
+ self_formatting(f)
+ {
+ }
+
+ const char*
+ operator () () const
+ {
+ return (*help_callback)();
+ }
+
+ operator bool() const
+ {
+ return (help_callback != NULL);
+ }
+
+ };
+
struct ArgumentTableEntry // Entries in the main argument information table
{
lldb::CommandArgumentType arg_type;
const char *arg_name;
CommandCompletions::CommonCompletionTypes completion_type;
- ArgumentHelpCallbackFunction *help_function;
+ ArgumentHelpCallback help_function;
const char *help_text;
};
Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=134574&r1=134573&r2=134574&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Wed Jul 6 19:38:40 2011
@@ -351,7 +351,6 @@
eArgTypeExprFormat,
eArgTypeFilename,
eArgTypeFormat,
- eArgTypeFormatString,
eArgTypeFrameIndex,
eArgTypeFullName,
eArgTypeFunctionName,
@@ -387,6 +386,7 @@
eArgTypeSourceFile,
eArgTypeSortOrder,
eArgTypeStartAddress,
+ eArgTypeSummaryString,
eArgTypeSymbol,
eArgTypeThreadID,
eArgTypeThreadIndex,
Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=134574&r1=134573&r2=134574&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectType.cpp Wed Jul 6 19:38:40 2011
@@ -63,6 +63,12 @@
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;
@@ -76,6 +82,8 @@
{
m_cascade = true;
m_format = eFormatInvalid;
+ m_skip_pointers = false;
+ m_skip_references = false;
}
const OptionDefinition*
@@ -92,6 +100,8 @@
bool m_cascade;
lldb::Format m_format;
+ bool m_skip_references;
+ bool m_skip_pointers;
};
CommandOptions m_options;
@@ -118,6 +128,34 @@
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 ()
@@ -145,7 +183,10 @@
ValueFormatSP entry;
- entry.reset(new ValueFormat(m_options.m_format,m_options.m_cascade));
+ 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
@@ -172,6 +213,8 @@
{
{ 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 }
};
@@ -343,9 +386,11 @@
{
if (regex == NULL || regex->Execute(type))
{
- result->GetOutputStream().Printf ("%s: %s%s\n", type,
+ result->GetOutputStream().Printf ("%s: %s%s%s%s\n", type,
FormatManager::GetFormatAsCString (entry->m_format),
- entry->m_cascades ? "" : " (not cascading)");
+ entry->m_cascades ? "" : " (not cascading)",
+ entry->m_skip_pointers ? " (skip pointers)" : "",
+ entry->m_skip_references ? " (skip references)" : "");
}
return true;
}
@@ -489,6 +534,62 @@
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 ()
@@ -574,7 +675,7 @@
{ 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, eArgTypeFormatString, "Format string used to display text and object contents."},
+ { 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 }
};
Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=134574&r1=134573&r2=134574&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Wed Jul 6 19:38:40 2011
@@ -2014,6 +2014,49 @@
}
void
+CommandInterpreter::OutputHelpText (Stream &strm,
+ const char *word_text,
+ const char *separator,
+ const char *help_text,
+ uint32_t max_word_len)
+{
+ int indent_size = max_word_len + strlen (separator) + 2;
+
+ strm.IndentMore (indent_size);
+
+ StreamString text_strm;
+ text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text);
+
+ const uint32_t max_columns = m_debugger.GetTerminalWidth();
+ bool first_line = true;
+
+ size_t len = text_strm.GetSize();
+ const char *text = text_strm.GetData();
+
+ uint32_t chars_left = max_columns;
+
+ for (uint32_t i = 0; i < len; i++)
+ {
+ if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n')
+ {
+ first_line = false;
+ chars_left = max_columns - indent_size;
+ strm.EOL();
+ strm.Indent();
+ }
+ else
+ {
+ strm.PutChar(text[i]);
+ chars_left--;
+ }
+
+ }
+
+ strm.EOL();
+ strm.IndentLess(indent_size);
+}
+
+void
CommandInterpreter::AproposAllSubCommands (CommandObject *cmd_obj, const char *prefix, const char *search_word,
StringList &commands_found, StringList &commands_help)
{
Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=134574&r1=134573&r2=134574&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Wed Jul 6 19:38:40 2011
@@ -469,9 +469,20 @@
StreamString name_str;
name_str.Printf ("<%s>", entry->arg_name);
- if (entry->help_function != NULL)
- interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", (*(entry->help_function)) (),
- name_str.GetSize());
+ if (entry->help_function)
+ {
+ const char* help_text = entry->help_function();
+ if (!entry->help_function.self_formatting)
+ {
+ interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,
+ name_str.GetSize());
+ }
+ else
+ {
+ interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text,
+ name_str.GetSize());
+ }
+ }
else
interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
}
@@ -630,32 +641,61 @@
static const char *
FormatHelpTextCallback ()
{
+
+ static char* help_text_ptr = NULL;
+
+ if (help_text_ptr)
+ return help_text_ptr;
+
StreamString sstr;
sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n";
for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
{
+ if (f != eFormatDefault)
+ sstr.PutChar('\n');
+
char format_char = FormatManager::GetFormatAsFormatChar(f);
if (format_char)
sstr.Printf("'%c' or ", format_char);
- sstr.Printf ("\"%s\" ; ", FormatManager::GetFormatAsCString(f));
+ sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
}
sstr.Flush();
std::string data = sstr.GetString();
- char* help = new char[data.length()+1];
+ help_text_ptr = new char[data.length()+1];
- data.copy(help, data.length());
+ data.copy(help_text_ptr, data.length());
- return help;
+ return help_text_ptr;
}
static const char *
-FormatStringHelpTextCallback()
+SummaryStringHelpTextCallback()
{
- return "Ask me tomorrow";
+ return
+ "A summary string is a way to extract information from variables in order to present them using a summary.\n"
+ "Summary strings contain static text, variables, scopes and control sequences:\n"
+ " - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n"
+ " - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n"
+ " - Scopes are any sequence of text between { and }. Anything included in a scope will only appear in the output summary if there were no errors.\n"
+ " - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n"
+ "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n"
+ "A variable is expanded by giving it a value other than its textual representation, and the way this is done depends on what comes after the ${ marker.\n"
+ "The most common sequence if ${var followed by an expression path, which is the text one would type to access a member of an aggregate types, given a variable of that type"
+ " (e.g. if type T has a member named x, which has a member named y, and if t is of type T, the expression path would be .x.y and the way to fit that into a summary string would be"
+ " ${var.x.y}). In expression paths you can use either . or -> without any difference in meaning. You can also use ${*var followed by an expression path and in that case"
+ " the object referred by the path will be dereferenced before being displayed. If the object is not a pointer, doing so will cause an error.\n"
+ "By default, summary strings attempt to display the summary for any variable they reference, and if that fails the value. If neither can be shown, nothing is displayed."
+ "In a summary string, you can also use an array index [n], or a slice-like range [n-m]. This can have two different meanings depending on what kind of object the expression"
+ " path refers to:\n"
+ " - if it is a scalar type (any basic type like int, float, ...) the expression is a bitfield, i.e. the bits indicated by the indexing operator are extracted out of the number"
+ " and displayed as an individual variable\n"
+ " - if it is an array or pointer the array items indicated by the indexing operator are shown as the result of the variable. if the expression is an array, real array items are"
+ " printed; if it is a pointer, the pointer-as-array syntax is used to obtain the values (this means, the latter case can have no range checking)\n"
+ "If you are trying to display an array for which the size is known, you can also use [] instead of giving an exact range. This has the effect of showing items 0 thru size - 1.";
}
const char *
@@ -693,8 +733,7 @@
{ eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
{ eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, NULL, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
{ eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, NULL, "The name of a file (can include path)." },
- { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, FormatHelpTextCallback, NULL },
- { eArgTypeFormatString, "format-string", CommandCompletions::eNoCompletion, FormatStringHelpTextCallback, NULL },
+ { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, CommandObject::ArgumentHelpCallback(FormatHelpTextCallback, true), NULL },
{ eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, NULL, "Index into a thread's list of frames." },
{ eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
{ eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, NULL, "The name of a function." },
@@ -730,6 +769,7 @@
{ eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, NULL, "The name of a source file.." },
{ eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, NULL, "Specify a sort order when dumping lists." },
{ eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
+ { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, CommandObject::ArgumentHelpCallback(SummaryStringHelpTextCallback, true), NULL },
{ eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, NULL, "Any symbol name (function name, variable, argument, etc.)" },
{ eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, NULL, "Thread ID number." },
{ eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, NULL, "Index into the process' list of threads." },
More information about the lldb-commits
mailing list