[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