130fdc8d8SChris Lattner //===-- CommandObjectHelp.cpp -----------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "CommandObjectHelp.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner #include "lldb/Interpreter/CommandObjectMultiword.h"
1730fdc8d8SChris Lattner #include "lldb/Interpreter/CommandInterpreter.h"
18*40af72e1SJim Ingham #include "lldb/Interpreter/Options.h"
1930fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
2030fdc8d8SChris Lattner 
2130fdc8d8SChris Lattner using namespace lldb;
2230fdc8d8SChris Lattner using namespace lldb_private;
2330fdc8d8SChris Lattner 
2430fdc8d8SChris Lattner //-------------------------------------------------------------------------
2530fdc8d8SChris Lattner // CommandObjectHelp
2630fdc8d8SChris Lattner //-------------------------------------------------------------------------
2730fdc8d8SChris Lattner 
2830fdc8d8SChris Lattner CommandObjectHelp::CommandObjectHelp () :
2930fdc8d8SChris Lattner     CommandObject ("help",
3030fdc8d8SChris Lattner                      "Shows a list of all debugger commands, or give details about specific commands.",
3130fdc8d8SChris Lattner                      "help [<cmd-name>]")
3230fdc8d8SChris Lattner {
3330fdc8d8SChris Lattner }
3430fdc8d8SChris Lattner 
3530fdc8d8SChris Lattner CommandObjectHelp::~CommandObjectHelp()
3630fdc8d8SChris Lattner {
3730fdc8d8SChris Lattner }
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner 
4030fdc8d8SChris Lattner bool
4130fdc8d8SChris Lattner CommandObjectHelp::OldExecute
4230fdc8d8SChris Lattner (
4330fdc8d8SChris Lattner     Args& command,
4430fdc8d8SChris Lattner     CommandContext *context,
4530fdc8d8SChris Lattner     CommandInterpreter *interpreter,
4630fdc8d8SChris Lattner     CommandReturnObject &result
4730fdc8d8SChris Lattner )
4830fdc8d8SChris Lattner {
4930fdc8d8SChris Lattner     CommandObject::CommandMap::iterator pos;
5030fdc8d8SChris Lattner     CommandObject *cmd_obj;
5130fdc8d8SChris Lattner 
5230fdc8d8SChris Lattner     const int argc = command.GetArgumentCount();
5330fdc8d8SChris Lattner     if (argc > 0)
5430fdc8d8SChris Lattner     {
5530fdc8d8SChris Lattner         cmd_obj = interpreter->GetCommandObject (command.GetArgumentAtIndex(0), false, false);
5630fdc8d8SChris Lattner         if (cmd_obj == NULL)
5730fdc8d8SChris Lattner         {
5830fdc8d8SChris Lattner             cmd_obj = interpreter->GetCommandObject (command.GetArgumentAtIndex(0), true, false);
5930fdc8d8SChris Lattner             if (cmd_obj != NULL)
6030fdc8d8SChris Lattner             {
6130fdc8d8SChris Lattner                 StreamString alias_help_str;
6230fdc8d8SChris Lattner                 interpreter->GetAliasHelp (command.GetArgumentAtIndex(0), cmd_obj->GetCommandName(), alias_help_str);
6330fdc8d8SChris Lattner                 result.AppendMessageWithFormat ("'%s' is an alias for %s.\n", command.GetArgumentAtIndex (0),
6430fdc8d8SChris Lattner                                                alias_help_str.GetData());
6530fdc8d8SChris Lattner             }
6630fdc8d8SChris Lattner         }
6730fdc8d8SChris Lattner 
6830fdc8d8SChris Lattner         if (cmd_obj)
6930fdc8d8SChris Lattner         {
7030fdc8d8SChris Lattner             Stream &output_strm = result.GetOutputStream();
7130fdc8d8SChris Lattner             if (cmd_obj->GetOptions() != NULL)
7230fdc8d8SChris Lattner             {
7330fdc8d8SChris Lattner                 const char * long_help = cmd_obj->GetHelpLong();
7430fdc8d8SChris Lattner                 if ((long_help!= NULL)
7530fdc8d8SChris Lattner                     && strlen (long_help) > 0)
7630fdc8d8SChris Lattner                     output_strm.Printf ("\n%s", cmd_obj->GetHelpLong());
7730fdc8d8SChris Lattner                 else
7830fdc8d8SChris Lattner                     output_strm.Printf ("\n%s\n", cmd_obj->GetHelp());
7930fdc8d8SChris Lattner                 output_strm.Printf ("\nSyntax: %s\n", cmd_obj->GetSyntax());
8030fdc8d8SChris Lattner                 cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, cmd_obj);
8130fdc8d8SChris Lattner             }
8230fdc8d8SChris Lattner             else if (cmd_obj->IsMultiwordObject())
8330fdc8d8SChris Lattner             {
8430fdc8d8SChris Lattner                 bool done = false;
8530fdc8d8SChris Lattner                 if (argc > 1)
8630fdc8d8SChris Lattner                 {
8730fdc8d8SChris Lattner                     CommandObject::CommandMap::iterator pos;
8830fdc8d8SChris Lattner                     std::string sub_command = command.GetArgumentAtIndex(1);
8930fdc8d8SChris Lattner                     pos = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.find(sub_command);
9030fdc8d8SChris Lattner                     if (pos != ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.end())
9130fdc8d8SChris Lattner                     {
9230fdc8d8SChris Lattner                         CommandObject *sub_cmd_obj = pos->second.get();
9330fdc8d8SChris Lattner                         if (sub_cmd_obj->GetOptions() != NULL)
9430fdc8d8SChris Lattner                         {
9530fdc8d8SChris Lattner                             output_strm.Printf ("\n%s\n", sub_cmd_obj->GetHelp());
9630fdc8d8SChris Lattner                             output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax());
9730fdc8d8SChris Lattner                             sub_cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, sub_cmd_obj);
9830fdc8d8SChris Lattner                             done = true;
9930fdc8d8SChris Lattner                         }
10030fdc8d8SChris Lattner                         else
10130fdc8d8SChris Lattner                         {
10230fdc8d8SChris Lattner                             output_strm.Printf ("\n%s\n", sub_cmd_obj->GetHelp());
10330fdc8d8SChris Lattner                             output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax());
10430fdc8d8SChris Lattner                             done = true;
10530fdc8d8SChris Lattner                         }
10630fdc8d8SChris Lattner                     }
10730fdc8d8SChris Lattner                 }
10830fdc8d8SChris Lattner                 if (!done)
10930fdc8d8SChris Lattner                 {
11030fdc8d8SChris Lattner                     output_strm.Printf ("%s\n", cmd_obj->GetHelp());
11130fdc8d8SChris Lattner                     ((CommandObjectMultiword *) cmd_obj)->GenerateHelpText (result, interpreter);
11230fdc8d8SChris Lattner                 }
11330fdc8d8SChris Lattner             }
11430fdc8d8SChris Lattner             else
11530fdc8d8SChris Lattner             {
11630fdc8d8SChris Lattner                 const char *long_help = cmd_obj->GetHelpLong();
11730fdc8d8SChris Lattner                 if ((long_help != NULL)
11830fdc8d8SChris Lattner                     && (strlen (long_help) > 0))
11930fdc8d8SChris Lattner                     output_strm.Printf ("\n%s", cmd_obj->GetHelpLong());
12030fdc8d8SChris Lattner                 else
12130fdc8d8SChris Lattner                     output_strm.Printf ("\n%s\n", cmd_obj->GetHelp());
12230fdc8d8SChris Lattner                 output_strm.Printf ("\nSyntax: %s\n", cmd_obj->GetSyntax());
12330fdc8d8SChris Lattner             }
12430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusSuccessFinishNoResult);
12530fdc8d8SChris Lattner         }
12630fdc8d8SChris Lattner         else
12730fdc8d8SChris Lattner         {
12830fdc8d8SChris Lattner             result.AppendErrorWithFormat
12930fdc8d8SChris Lattner             ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
13030fdc8d8SChris Lattner              command.GetArgumentAtIndex(0));
13130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
13230fdc8d8SChris Lattner         }
13330fdc8d8SChris Lattner     }
13430fdc8d8SChris Lattner     else
13530fdc8d8SChris Lattner     {
13630fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
13730fdc8d8SChris Lattner         interpreter->GetHelp(result);
13830fdc8d8SChris Lattner     }
13930fdc8d8SChris Lattner     return result.Succeeded();
14030fdc8d8SChris Lattner }
14130fdc8d8SChris Lattner 
14230fdc8d8SChris Lattner bool
14330fdc8d8SChris Lattner CommandObjectHelp::Execute (Args &command, CommandContext *context, CommandInterpreter *interpreter,
14430fdc8d8SChris Lattner                             CommandReturnObject &result)
14530fdc8d8SChris Lattner {
14630fdc8d8SChris Lattner     CommandObject::CommandMap::iterator pos;
14730fdc8d8SChris Lattner     CommandObject *cmd_obj;
14830fdc8d8SChris Lattner     const int argc = command.GetArgumentCount ();
14930fdc8d8SChris Lattner 
15030fdc8d8SChris Lattner     // 'help' doesn't take any options or arguments, other than command names.  If argc is 0, we show the user
15130fdc8d8SChris Lattner     // all commands and aliases.  Otherwise every argument must be the name of a command or a sub-command.
15230fdc8d8SChris Lattner 
15330fdc8d8SChris Lattner     if (argc == 0)
15430fdc8d8SChris Lattner     {
15530fdc8d8SChris Lattner         result.SetStatus (eReturnStatusSuccessFinishNoResult);
15630fdc8d8SChris Lattner         interpreter->GetHelp (result);  // General help, for ALL commands.
15730fdc8d8SChris Lattner     }
15830fdc8d8SChris Lattner     else
15930fdc8d8SChris Lattner     {
16030fdc8d8SChris Lattner         // Get command object for the first command argument. Only search built-in command dictionary.
16130fdc8d8SChris Lattner         cmd_obj = interpreter->GetCommandObject (command.GetArgumentAtIndex (0), false, false);
16230fdc8d8SChris Lattner         if (cmd_obj == NULL)
16330fdc8d8SChris Lattner           {
16430fdc8d8SChris Lattner             // That failed, so now search in the aliases dictionary, too.
16530fdc8d8SChris Lattner             cmd_obj = interpreter->GetCommandObject (command.GetArgumentAtIndex (0), true, false);
16630fdc8d8SChris Lattner           }
16730fdc8d8SChris Lattner 
16830fdc8d8SChris Lattner         if (cmd_obj != NULL)
16930fdc8d8SChris Lattner         {
17030fdc8d8SChris Lattner             bool all_okay = true;
17130fdc8d8SChris Lattner             CommandObject *sub_cmd_obj = cmd_obj;
17230fdc8d8SChris Lattner             // Loop down through sub_command dictionaries until we find the command object that corresponds
17330fdc8d8SChris Lattner             // to the help command entered.
17430fdc8d8SChris Lattner             for (int i = 1; i < argc && all_okay; ++i)
17530fdc8d8SChris Lattner             {
17630fdc8d8SChris Lattner                 std::string sub_command = command.GetArgumentAtIndex(i);
17730fdc8d8SChris Lattner                 if (! sub_cmd_obj->IsMultiwordObject ())
17830fdc8d8SChris Lattner                 {
17930fdc8d8SChris Lattner                     all_okay = false;
18030fdc8d8SChris Lattner                 }
18130fdc8d8SChris Lattner                 else
18230fdc8d8SChris Lattner                 {
18330fdc8d8SChris Lattner                     pos = ((CommandObjectMultiword *) sub_cmd_obj)->m_subcommand_dict.find (sub_command);
18430fdc8d8SChris Lattner                     if (pos != ((CommandObjectMultiword *) sub_cmd_obj)->m_subcommand_dict.end())
18530fdc8d8SChris Lattner                       sub_cmd_obj = pos->second.get();
18630fdc8d8SChris Lattner                     else
18730fdc8d8SChris Lattner                       all_okay = false;
18830fdc8d8SChris Lattner                 }
18930fdc8d8SChris Lattner             }
19030fdc8d8SChris Lattner 
19130fdc8d8SChris Lattner             if (!all_okay || (sub_cmd_obj == NULL))
19230fdc8d8SChris Lattner             {
19330fdc8d8SChris Lattner                 std::string cmd_string;
19430fdc8d8SChris Lattner                 command.GetCommandString (cmd_string);
19530fdc8d8SChris Lattner                 result.AppendErrorWithFormat
19630fdc8d8SChris Lattner                                       ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
19730fdc8d8SChris Lattner                                        cmd_string.c_str());
19830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
19930fdc8d8SChris Lattner             }
20030fdc8d8SChris Lattner             else
20130fdc8d8SChris Lattner             {
20230fdc8d8SChris Lattner                 Stream &output_strm = result.GetOutputStream();
20330fdc8d8SChris Lattner                 if (sub_cmd_obj->GetOptions() != NULL)
20430fdc8d8SChris Lattner                 {
20530fdc8d8SChris Lattner                     output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp());
20630fdc8d8SChris Lattner                     output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax());
20730fdc8d8SChris Lattner                     sub_cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, sub_cmd_obj);
20830fdc8d8SChris Lattner                     const char *long_help = sub_cmd_obj->GetHelpLong();
20930fdc8d8SChris Lattner                     if ((long_help != NULL)
21030fdc8d8SChris Lattner                         && (strlen (long_help) > 0))
21130fdc8d8SChris Lattner                       output_strm.Printf ("\n%s", long_help);
21230fdc8d8SChris Lattner                 }
21330fdc8d8SChris Lattner                 else if (sub_cmd_obj->IsMultiwordObject())
21430fdc8d8SChris Lattner                 {
21530fdc8d8SChris Lattner                     output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp());
21630fdc8d8SChris Lattner                     ((CommandObjectMultiword *) sub_cmd_obj)->GenerateHelpText (result, interpreter);
21730fdc8d8SChris Lattner                 }
21830fdc8d8SChris Lattner                 else
21930fdc8d8SChris Lattner                 {
22030fdc8d8SChris Lattner                   const char *long_help = sub_cmd_obj->GetHelpLong();
22130fdc8d8SChris Lattner                   if ((long_help != NULL)
22230fdc8d8SChris Lattner                       && (strlen (long_help) > 0))
22330fdc8d8SChris Lattner                     output_strm.Printf ("%s", long_help);
22430fdc8d8SChris Lattner                   else
22530fdc8d8SChris Lattner                     output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp());
22630fdc8d8SChris Lattner                   output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax());
22730fdc8d8SChris Lattner                 }
22830fdc8d8SChris Lattner             }
22930fdc8d8SChris Lattner         }
23030fdc8d8SChris Lattner         else
23130fdc8d8SChris Lattner         {
23230fdc8d8SChris Lattner             result.AppendErrorWithFormat
23330fdc8d8SChris Lattner                                       ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n",
23430fdc8d8SChris Lattner                                        command.GetArgumentAtIndex(0));
23530fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
23630fdc8d8SChris Lattner         }
23730fdc8d8SChris Lattner     }
23830fdc8d8SChris Lattner 
23930fdc8d8SChris Lattner     return result.Succeeded();
24030fdc8d8SChris Lattner }
24130fdc8d8SChris Lattner 
24230fdc8d8SChris Lattner int
24330fdc8d8SChris Lattner CommandObjectHelp::HandleCompletion
24430fdc8d8SChris Lattner (
24530fdc8d8SChris Lattner     Args &input,
24630fdc8d8SChris Lattner     int &cursor_index,
24730fdc8d8SChris Lattner     int &cursor_char_position,
24830fdc8d8SChris Lattner     int match_start_point,
24930fdc8d8SChris Lattner     int max_return_elements,
25030fdc8d8SChris Lattner     CommandInterpreter *interpreter,
25130fdc8d8SChris Lattner     StringList &matches
25230fdc8d8SChris Lattner )
25330fdc8d8SChris Lattner {
25430fdc8d8SChris Lattner     // Return the completions of the commands in the help system:
25530fdc8d8SChris Lattner     if (cursor_index == 0)
25630fdc8d8SChris Lattner     {
25730fdc8d8SChris Lattner         return interpreter->HandleCompletionMatches(input, cursor_index, cursor_char_position, match_start_point, max_return_elements, matches);
25830fdc8d8SChris Lattner     }
25930fdc8d8SChris Lattner     else
26030fdc8d8SChris Lattner     {
26130fdc8d8SChris Lattner         CommandObject *cmd_obj = interpreter->GetCommandObject (input.GetArgumentAtIndex(0), true, false);
26230fdc8d8SChris Lattner         input.Shift();
26330fdc8d8SChris Lattner         cursor_index--;
26430fdc8d8SChris Lattner         return cmd_obj->HandleCompletion (input, cursor_index, cursor_char_position, match_start_point, max_return_elements, interpreter, matches);
26530fdc8d8SChris Lattner     }
26630fdc8d8SChris Lattner }
267