1 //===-- CommandObjectHelp.cpp -----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "CommandObjectHelp.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 // Project includes 16 #include "lldb/Interpreter/CommandObjectMultiword.h" 17 #include "lldb/Interpreter/CommandInterpreter.h" 18 #include "lldb/Core/Options.h" 19 #include "lldb/Interpreter/CommandReturnObject.h" 20 21 using namespace lldb; 22 using namespace lldb_private; 23 24 //------------------------------------------------------------------------- 25 // CommandObjectHelp 26 //------------------------------------------------------------------------- 27 28 CommandObjectHelp::CommandObjectHelp () : 29 CommandObject ("help", 30 "Shows a list of all debugger commands, or give details about specific commands.", 31 "help [<cmd-name>]") 32 { 33 } 34 35 CommandObjectHelp::~CommandObjectHelp() 36 { 37 } 38 39 40 bool 41 CommandObjectHelp::OldExecute 42 ( 43 Args& command, 44 CommandContext *context, 45 CommandInterpreter *interpreter, 46 CommandReturnObject &result 47 ) 48 { 49 CommandObject::CommandMap::iterator pos; 50 CommandObject *cmd_obj; 51 52 const int argc = command.GetArgumentCount(); 53 if (argc > 0) 54 { 55 cmd_obj = interpreter->GetCommandObject (command.GetArgumentAtIndex(0), false, false); 56 if (cmd_obj == NULL) 57 { 58 cmd_obj = interpreter->GetCommandObject (command.GetArgumentAtIndex(0), true, false); 59 if (cmd_obj != NULL) 60 { 61 StreamString alias_help_str; 62 interpreter->GetAliasHelp (command.GetArgumentAtIndex(0), cmd_obj->GetCommandName(), alias_help_str); 63 result.AppendMessageWithFormat ("'%s' is an alias for %s.\n", command.GetArgumentAtIndex (0), 64 alias_help_str.GetData()); 65 } 66 } 67 68 if (cmd_obj) 69 { 70 Stream &output_strm = result.GetOutputStream(); 71 if (cmd_obj->GetOptions() != NULL) 72 { 73 const char * long_help = cmd_obj->GetHelpLong(); 74 if ((long_help!= NULL) 75 && strlen (long_help) > 0) 76 output_strm.Printf ("\n%s", cmd_obj->GetHelpLong()); 77 else 78 output_strm.Printf ("\n%s\n", cmd_obj->GetHelp()); 79 output_strm.Printf ("\nSyntax: %s\n", cmd_obj->GetSyntax()); 80 cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, cmd_obj); 81 } 82 else if (cmd_obj->IsMultiwordObject()) 83 { 84 bool done = false; 85 if (argc > 1) 86 { 87 CommandObject::CommandMap::iterator pos; 88 std::string sub_command = command.GetArgumentAtIndex(1); 89 pos = ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.find(sub_command); 90 if (pos != ((CommandObjectMultiword *) cmd_obj)->m_subcommand_dict.end()) 91 { 92 CommandObject *sub_cmd_obj = pos->second.get(); 93 if (sub_cmd_obj->GetOptions() != NULL) 94 { 95 output_strm.Printf ("\n%s\n", sub_cmd_obj->GetHelp()); 96 output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax()); 97 sub_cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, sub_cmd_obj); 98 done = true; 99 } 100 else 101 { 102 output_strm.Printf ("\n%s\n", sub_cmd_obj->GetHelp()); 103 output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax()); 104 done = true; 105 } 106 } 107 } 108 if (!done) 109 { 110 output_strm.Printf ("%s\n", cmd_obj->GetHelp()); 111 ((CommandObjectMultiword *) cmd_obj)->GenerateHelpText (result, interpreter); 112 } 113 } 114 else 115 { 116 const char *long_help = cmd_obj->GetHelpLong(); 117 if ((long_help != NULL) 118 && (strlen (long_help) > 0)) 119 output_strm.Printf ("\n%s", cmd_obj->GetHelpLong()); 120 else 121 output_strm.Printf ("\n%s\n", cmd_obj->GetHelp()); 122 output_strm.Printf ("\nSyntax: %s\n", cmd_obj->GetSyntax()); 123 } 124 result.SetStatus (eReturnStatusSuccessFinishNoResult); 125 } 126 else 127 { 128 result.AppendErrorWithFormat 129 ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n", 130 command.GetArgumentAtIndex(0)); 131 result.SetStatus (eReturnStatusFailed); 132 } 133 } 134 else 135 { 136 result.SetStatus (eReturnStatusSuccessFinishNoResult); 137 interpreter->GetHelp(result); 138 } 139 return result.Succeeded(); 140 } 141 142 bool 143 CommandObjectHelp::Execute (Args &command, CommandContext *context, CommandInterpreter *interpreter, 144 CommandReturnObject &result) 145 { 146 CommandObject::CommandMap::iterator pos; 147 CommandObject *cmd_obj; 148 const int argc = command.GetArgumentCount (); 149 150 // 'help' doesn't take any options or arguments, other than command names. If argc is 0, we show the user 151 // all commands and aliases. Otherwise every argument must be the name of a command or a sub-command. 152 153 if (argc == 0) 154 { 155 result.SetStatus (eReturnStatusSuccessFinishNoResult); 156 interpreter->GetHelp (result); // General help, for ALL commands. 157 } 158 else 159 { 160 // Get command object for the first command argument. Only search built-in command dictionary. 161 cmd_obj = interpreter->GetCommandObject (command.GetArgumentAtIndex (0), false, false); 162 if (cmd_obj == NULL) 163 { 164 // That failed, so now search in the aliases dictionary, too. 165 cmd_obj = interpreter->GetCommandObject (command.GetArgumentAtIndex (0), true, false); 166 } 167 168 if (cmd_obj != NULL) 169 { 170 bool all_okay = true; 171 CommandObject *sub_cmd_obj = cmd_obj; 172 // Loop down through sub_command dictionaries until we find the command object that corresponds 173 // to the help command entered. 174 for (int i = 1; i < argc && all_okay; ++i) 175 { 176 std::string sub_command = command.GetArgumentAtIndex(i); 177 if (! sub_cmd_obj->IsMultiwordObject ()) 178 { 179 all_okay = false; 180 } 181 else 182 { 183 pos = ((CommandObjectMultiword *) sub_cmd_obj)->m_subcommand_dict.find (sub_command); 184 if (pos != ((CommandObjectMultiword *) sub_cmd_obj)->m_subcommand_dict.end()) 185 sub_cmd_obj = pos->second.get(); 186 else 187 all_okay = false; 188 } 189 } 190 191 if (!all_okay || (sub_cmd_obj == NULL)) 192 { 193 std::string cmd_string; 194 command.GetCommandString (cmd_string); 195 result.AppendErrorWithFormat 196 ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n", 197 cmd_string.c_str()); 198 result.SetStatus (eReturnStatusFailed); 199 } 200 else 201 { 202 Stream &output_strm = result.GetOutputStream(); 203 if (sub_cmd_obj->GetOptions() != NULL) 204 { 205 output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); 206 output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax()); 207 sub_cmd_obj->GetOptions()->GenerateOptionUsage (output_strm, sub_cmd_obj); 208 const char *long_help = sub_cmd_obj->GetHelpLong(); 209 if ((long_help != NULL) 210 && (strlen (long_help) > 0)) 211 output_strm.Printf ("\n%s", long_help); 212 } 213 else if (sub_cmd_obj->IsMultiwordObject()) 214 { 215 output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); 216 ((CommandObjectMultiword *) sub_cmd_obj)->GenerateHelpText (result, interpreter); 217 } 218 else 219 { 220 const char *long_help = sub_cmd_obj->GetHelpLong(); 221 if ((long_help != NULL) 222 && (strlen (long_help) > 0)) 223 output_strm.Printf ("%s", long_help); 224 else 225 output_strm.Printf ("%s\n", sub_cmd_obj->GetHelp()); 226 output_strm.Printf ("\nSyntax: %s\n", sub_cmd_obj->GetSyntax()); 227 } 228 } 229 } 230 else 231 { 232 result.AppendErrorWithFormat 233 ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n", 234 command.GetArgumentAtIndex(0)); 235 result.SetStatus (eReturnStatusFailed); 236 } 237 } 238 239 return result.Succeeded(); 240 } 241 242 int 243 CommandObjectHelp::HandleCompletion 244 ( 245 Args &input, 246 int &cursor_index, 247 int &cursor_char_position, 248 int match_start_point, 249 int max_return_elements, 250 CommandInterpreter *interpreter, 251 StringList &matches 252 ) 253 { 254 // Return the completions of the commands in the help system: 255 if (cursor_index == 0) 256 { 257 return interpreter->HandleCompletionMatches(input, cursor_index, cursor_char_position, match_start_point, max_return_elements, matches); 258 } 259 else 260 { 261 CommandObject *cmd_obj = interpreter->GetCommandObject (input.GetArgumentAtIndex(0), true, false); 262 input.Shift(); 263 cursor_index--; 264 return cmd_obj->HandleCompletion (input, cursor_index, cursor_char_position, match_start_point, max_return_elements, interpreter, matches); 265 } 266 } 267