[Lldb-commits] [lldb] r262271 - When 'help' cannot find a command, produce additional help text that also points the user to the apropos and type lookup commands

Enrico Granata via lldb-commits lldb-commits at lists.llvm.org
Mon Feb 29 15:22:53 PST 2016


Author: enrico
Date: Mon Feb 29 17:22:53 2016
New Revision: 262271

URL: http://llvm.org/viewvc/llvm-project?rev=262271&view=rev
Log:
When 'help' cannot find a command, produce additional help text that also points the user to the apropos and type lookup commands

This is useful in cases such as, e.g.

(lldb) help NSString
(the user meant type lookup)

or

(lldb) help kill
(the user is looking for process kill)

Fixes rdar://24868537


Modified:
    lldb/trunk/packages/Python/lldbsuite/test/help/TestHelp.py
    lldb/trunk/source/Commands/CommandObjectCommands.cpp
    lldb/trunk/source/Commands/CommandObjectHelp.cpp
    lldb/trunk/source/Commands/CommandObjectHelp.h
    lldb/trunk/source/Commands/CommandObjectSyntax.cpp

Modified: lldb/trunk/packages/Python/lldbsuite/test/help/TestHelp.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/help/TestHelp.py?rev=262271&r1=262270&r2=262271&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/help/TestHelp.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/help/TestHelp.py Mon Feb 29 17:22:53 2016
@@ -165,3 +165,18 @@ class HelpCommandTestCase(TestBase):
             substrs = ['The following subcommands are supported:'],
             patterns = ['expression +--',
                         'variable +--'])
+
+    @no_debug_info_test
+    def test_help_provides_alternatives(self):
+        """Test that help on commands that don't exist provides information on additional help avenues"""
+        self.expect("help thisisnotadebuggercommand",
+            substrs = ["'thisisnotadebuggercommand' is not a known command.",
+            "Try 'help' to see a current list of commands.",
+            "Try 'apropos thisisnotadebuggercommand' for a list of related commands.",
+            "Try 'type lookup thisisnotadebuggercommand' for information on types, methods, functions, modules, etc."], error=True)
+
+        self.expect("help process thisisnotadebuggercommand",
+            substrs = ["'process thisisnotadebuggercommand' is not a known command.",
+            "Try 'help' to see a current list of commands.",
+            "Try 'apropos thisisnotadebuggercommand' for a list of related commands.",
+            "Try 'type lookup thisisnotadebuggercommand' for information on types, methods, functions, modules, etc."])

Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=262271&r1=262270&r2=262271&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Mon Feb 29 17:22:53 2016
@@ -14,6 +14,7 @@
 
 // Project includes
 #include "CommandObjectCommands.h"
+#include "CommandObjectHelp.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/IOHandler.h"
 #include "lldb/Core/StringList.h"
@@ -920,8 +921,16 @@ protected:
             }
             else
             {
-                result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
-                                              command_name);
+                StreamString error_msg_stream;
+                const bool generate_apropos = true;
+                const bool generate_type_lookup = false;
+                CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
+                                                                        command_name,
+                                                                        nullptr,
+                                                                        nullptr,
+                                                                        generate_apropos,
+                                                                        generate_type_lookup);
+                result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
                 result.SetStatus (eReturnStatusFailed);
             }
         }

Modified: lldb/trunk/source/Commands/CommandObjectHelp.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectHelp.cpp?rev=262271&r1=262270&r2=262271&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectHelp.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectHelp.cpp Mon Feb 29 17:22:53 2016
@@ -24,6 +24,37 @@ using namespace lldb_private;
 // CommandObjectHelp
 //-------------------------------------------------------------------------
 
+void
+CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage (Stream *s,
+                                                         const char* command,
+                                                         const char* prefix,
+                                                         const char* subcommand,
+                                                         bool include_apropos,
+                                                         bool include_type_lookup)
+{
+    if (s && command && *command)
+    {
+        s->Printf("'%s' is not a known command.\n", command);
+        if (prefix && *prefix)
+        {
+            s->Printf("Try '%shelp' to see a current list of commands.\n", prefix);
+        }
+        else
+        {
+            s->PutCString("Try 'help' to see a current list of commands.\n");
+        }
+        
+        if (include_apropos)
+        {
+            s->Printf("Try 'apropos %s' for a list of related commands.\n", subcommand ? subcommand : command);
+        }
+        if (include_type_lookup)
+        {
+            s->Printf("Try 'type lookup %s' for information on types, methods, functions, modules, etc.", subcommand ? subcommand : command);
+        }
+    }
+}
+
 CommandObjectHelp::CommandObjectHelp (CommandInterpreter &interpreter) :
     CommandObjectParsed (interpreter,
                          "help",
@@ -92,9 +123,10 @@ CommandObjectHelp::DoExecute (Args& comm
             CommandObject *sub_cmd_obj = cmd_obj;
             // Loop down through sub_command dictionaries until we find the command object that corresponds
             // to the help command entered.
+            std::string sub_command;
             for (size_t i = 1; i < argc && all_okay; ++i)
             {
-                std::string sub_command = command.GetArgumentAtIndex(i);
+                sub_command = command.GetArgumentAtIndex(i);
                 matches.Clear();
                 if (! sub_cmd_obj->IsMultiwordObject ())
                 {
@@ -133,21 +165,22 @@ CommandObjectHelp::DoExecute (Args& comm
                 }
                 else if (!sub_cmd_obj)
                 {
-                    result.AppendErrorWithFormat("'%s' is not a known command.\n"
-                                                 "Try '%shelp' to see a current list of commands.\n",
-                                                 cmd_string.c_str(),
-                                                 m_interpreter.GetCommandPrefix());
+                    StreamString error_msg_stream;
+                    GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
+                                                         cmd_string.c_str(),
+                                                         m_interpreter.GetCommandPrefix(),
+                                                         sub_command.c_str());
+                    result.AppendErrorWithFormat("%s",error_msg_stream.GetData());
                     result.SetStatus (eReturnStatusFailed);
                     return false;
                 }
                 else
                 {
-                    result.GetOutputStream().Printf("'%s' is not a known command.\n"
-                                                   "Try '%shelp' to see a current list of commands.\n"
-                                                    "The closest match is '%s'. Help on it follows.\n\n",
-                                                   cmd_string.c_str(),
-                                                   m_interpreter.GetCommandPrefix(),
-                                                   sub_cmd_obj->GetCommandName());
+                    GenerateAdditionalHelpAvenuesMessage(&result.GetOutputStream(),
+                                                         cmd_string.c_str(),
+                                                         m_interpreter.GetCommandPrefix(),
+                                                         sub_command.c_str());
+                    result.GetOutputStream().Printf("\nThe closest match is '%s'. Help on it follows.\n\n", sub_cmd_obj->GetCommandName());
                 }
             }
             
@@ -182,10 +215,9 @@ CommandObjectHelp::DoExecute (Args& comm
             }
             else
             {
-                result.AppendErrorWithFormat 
-                    ("'%s' is not a known command.\nTry '%shelp' to see a current list of commands.\n",
-                     command.GetArgumentAtIndex(0),
-                     m_interpreter.GetCommandPrefix());
+                StreamString error_msg_stream;
+                GenerateAdditionalHelpAvenuesMessage(&error_msg_stream, command.GetArgumentAtIndex(0), m_interpreter.GetCommandPrefix());
+                result.AppendErrorWithFormat("%s",error_msg_stream.GetData());
                 result.SetStatus (eReturnStatusFailed);
             }
         }

Modified: lldb/trunk/source/Commands/CommandObjectHelp.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectHelp.h?rev=262271&r1=262270&r2=262271&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectHelp.h (original)
+++ lldb/trunk/source/Commands/CommandObjectHelp.h Mon Feb 29 17:22:53 2016
@@ -40,6 +40,14 @@ public:
 		     bool &word_complete,
 		     StringList &matches) override;
     
+    static void
+    GenerateAdditionalHelpAvenuesMessage (Stream *s,
+                                          const char* command,
+                                          const char* prefix = nullptr,
+                                          const char* subcommand = nullptr,
+                                          bool include_apropos = true,
+                                          bool include_type_lookup = true);
+    
     class CommandOptions : public Options
     {
     public:

Modified: lldb/trunk/source/Commands/CommandObjectSyntax.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectSyntax.cpp?rev=262271&r1=262270&r2=262271&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectSyntax.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectSyntax.cpp Mon Feb 29 17:22:53 2016
@@ -12,6 +12,7 @@
 // Other libraries and framework includes
 // Project includes
 #include "CommandObjectSyntax.h"
+#include "CommandObjectHelp.h"
 #include "lldb/Interpreter/Args.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
@@ -97,8 +98,17 @@ CommandObjectSyntax::DoExecute (Args& co
         {
             std::string cmd_string;
             command.GetCommandString (cmd_string);
-            result.AppendErrorWithFormat ("'%s' is not a known command.\n", cmd_string.c_str());
-            result.AppendError ("Try 'help' to see a current list of commands.");
+
+            StreamString error_msg_stream;
+            const bool generate_apropos = true;
+            const bool generate_type_lookup = false;
+            CommandObjectHelp::GenerateAdditionalHelpAvenuesMessage(&error_msg_stream,
+                                                                    cmd_string.c_str(),
+                                                                    nullptr,
+                                                                    nullptr,
+                                                                    generate_apropos,
+                                                                    generate_type_lookup);
+            result.AppendErrorWithFormat ("%s", error_msg_stream.GetData());
             result.SetStatus (eReturnStatusFailed);
         }
     }




More information about the lldb-commits mailing list