blob: 1ce242889a6f7adde4d014b1123e0d2f78c27341 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObject.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 "lldb/Interpreter/CommandObject.h"
11
12#include <string>
13#include <map>
14
15#include <getopt.h>
16#include <stdlib.h>
17#include <ctype.h>
18
19#include "lldb/Core/Address.h"
Jim Ingham84cdc152010-06-15 19:49:27 +000020#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021
22// These are for the Sourcename completers.
23// FIXME: Make a separate file for the completers.
Greg Clayton5f54ac32011-02-08 05:05:52 +000024#include "lldb/Host/FileSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Core/FileSpecList.h"
26#include "lldb/Target/Process.h"
27#include "lldb/Target/Target.h"
28
29#include "lldb/Interpreter/CommandInterpreter.h"
30#include "lldb/Interpreter/CommandReturnObject.h"
31#include "lldb/Interpreter/ScriptInterpreter.h"
32#include "lldb/Interpreter/ScriptInterpreterPython.h"
33
34using namespace lldb;
35using namespace lldb_private;
36
37//-------------------------------------------------------------------------
38// CommandObject
39//-------------------------------------------------------------------------
40
Greg Clayton238c0a12010-09-18 01:14:36 +000041CommandObject::CommandObject
42(
43 CommandInterpreter &interpreter,
44 const char *name,
45 const char *help,
46 const char *syntax,
47 uint32_t flags
48) :
49 m_interpreter (interpreter),
Chris Lattner24943d22010-06-08 16:52:24 +000050 m_cmd_name (name),
51 m_cmd_help_short (),
52 m_cmd_help_long (),
53 m_cmd_syntax (),
Jim Inghamd40f8a62010-07-06 22:46:59 +000054 m_is_alias (false),
Caroline Ticefb355112010-10-01 17:46:38 +000055 m_flags (flags),
56 m_arguments()
Chris Lattner24943d22010-06-08 16:52:24 +000057{
58 if (help && help[0])
59 m_cmd_help_short = help;
60 if (syntax && syntax[0])
61 m_cmd_syntax = syntax;
62}
63
64CommandObject::~CommandObject ()
65{
66}
67
68const char *
69CommandObject::GetHelp ()
70{
71 return m_cmd_help_short.c_str();
72}
73
74const char *
75CommandObject::GetHelpLong ()
76{
77 return m_cmd_help_long.c_str();
78}
79
80const char *
81CommandObject::GetSyntax ()
82{
Caroline Ticefb355112010-10-01 17:46:38 +000083 if (m_cmd_syntax.length() == 0)
84 {
85 StreamString syntax_str;
86 syntax_str.Printf ("%s", GetCommandName());
87 if (GetOptions() != NULL)
Caroline Tice43b014a2010-10-04 22:28:36 +000088 syntax_str.Printf (" <cmd-options>");
Caroline Ticefb355112010-10-01 17:46:38 +000089 if (m_arguments.size() > 0)
90 {
91 syntax_str.Printf (" ");
92 GetFormattedCommandArguments (syntax_str);
93 }
94 m_cmd_syntax = syntax_str.GetData ();
95 }
96
Chris Lattner24943d22010-06-08 16:52:24 +000097 return m_cmd_syntax.c_str();
98}
99
100const char *
101CommandObject::Translate ()
102{
103 //return m_cmd_func_name.c_str();
104 return "This function is currently not implemented.";
105}
106
107const char *
108CommandObject::GetCommandName ()
109{
110 return m_cmd_name.c_str();
111}
112
113void
114CommandObject::SetCommandName (const char *name)
115{
116 m_cmd_name = name;
117}
118
119void
120CommandObject::SetHelp (const char *cstr)
121{
122 m_cmd_help_short = cstr;
123}
124
125void
126CommandObject::SetHelpLong (const char *cstr)
127{
128 m_cmd_help_long = cstr;
129}
130
131void
132CommandObject::SetSyntax (const char *cstr)
133{
134 m_cmd_syntax = cstr;
135}
136
137Options *
138CommandObject::GetOptions ()
139{
140 // By default commands don't have options unless this virtual function
141 // is overridden by base classes.
142 return NULL;
143}
144
145Flags&
146CommandObject::GetFlags()
147{
148 return m_flags;
149}
150
151const Flags&
152CommandObject::GetFlags() const
153{
154 return m_flags;
155}
156
157bool
158CommandObject::ExecuteCommandString
159(
160 const char *command_line,
Chris Lattner24943d22010-06-08 16:52:24 +0000161 CommandReturnObject &result
162)
163{
164 Args command_args(command_line);
Greg Clayton238c0a12010-09-18 01:14:36 +0000165 return ExecuteWithOptions (command_args, result);
Chris Lattner24943d22010-06-08 16:52:24 +0000166}
167
168bool
169CommandObject::ParseOptions
170(
171 Args& args,
Chris Lattner24943d22010-06-08 16:52:24 +0000172 CommandReturnObject &result
173)
174{
175 // See if the subclass has options?
176 Options *options = GetOptions();
177 if (options != NULL)
178 {
179 Error error;
Greg Clayton143fcc32011-04-13 00:18:08 +0000180 options->NotifyOptionParsingStarting();
Chris Lattner24943d22010-06-08 16:52:24 +0000181
182 // ParseOptions calls getopt_long, which always skips the zero'th item in the array and starts at position 1,
183 // so we need to push a dummy value into position zero.
184 args.Unshift("dummy_string");
185 error = args.ParseOptions (*options);
186
187 // The "dummy_string" will have already been removed by ParseOptions,
188 // so no need to remove it.
189
Greg Clayton143fcc32011-04-13 00:18:08 +0000190 if (error.Success())
191 error = options->NotifyOptionParsingFinished();
192
193 if (error.Success())
194 {
195 if (options->VerifyOptions (result))
196 return true;
197 }
198 else
Chris Lattner24943d22010-06-08 16:52:24 +0000199 {
200 const char *error_cstr = error.AsCString();
201 if (error_cstr)
202 {
203 // We got an error string, lets use that
204 result.GetErrorStream().PutCString(error_cstr);
205 }
206 else
207 {
208 // No error string, output the usage information into result
Greg Claytonf15996e2011-04-07 22:46:35 +0000209 options->GenerateOptionUsage (result.GetErrorStream(), this);
Chris Lattner24943d22010-06-08 16:52:24 +0000210 }
Chris Lattner24943d22010-06-08 16:52:24 +0000211 }
Greg Clayton143fcc32011-04-13 00:18:08 +0000212 result.SetStatus (eReturnStatusFailed);
213 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000214 }
215 return true;
216}
217bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000218CommandObject::ExecuteWithOptions (Args& args, CommandReturnObject &result)
Chris Lattner24943d22010-06-08 16:52:24 +0000219{
220 for (size_t i = 0; i < args.GetArgumentCount(); ++i)
221 {
222 const char *tmp_str = args.GetArgumentAtIndex (i);
223 if (tmp_str[0] == '`') // back-quote
Greg Clayton238c0a12010-09-18 01:14:36 +0000224 args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
Chris Lattner24943d22010-06-08 16:52:24 +0000225 }
226
Greg Claytone71e2582011-02-04 01:58:07 +0000227 if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
Chris Lattner24943d22010-06-08 16:52:24 +0000228 {
Greg Claytonb72d0f02011-04-12 05:54:46 +0000229 Process *process = m_interpreter.GetExecutionContext().process;
Greg Claytone71e2582011-02-04 01:58:07 +0000230 if (process == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000231 {
232 result.AppendError ("Process must exist.");
233 result.SetStatus (eReturnStatusFailed);
234 return false;
235 }
Greg Claytone71e2582011-02-04 01:58:07 +0000236 else
Chris Lattner24943d22010-06-08 16:52:24 +0000237 {
Greg Claytone71e2582011-02-04 01:58:07 +0000238 StateType state = process->GetState();
239
240 switch (state)
Chris Lattner24943d22010-06-08 16:52:24 +0000241 {
Greg Clayton4fdf7602011-03-20 04:57:14 +0000242 case eStateInvalid:
Greg Claytone71e2582011-02-04 01:58:07 +0000243 case eStateSuspended:
244 case eStateCrashed:
245 case eStateStopped:
246 break;
247
248 case eStateConnected:
249 case eStateAttaching:
250 case eStateLaunching:
251 case eStateDetached:
252 case eStateExited:
253 case eStateUnloaded:
254 if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
255 {
256 result.AppendError ("Process must be launched.");
257 result.SetStatus (eReturnStatusFailed);
258 return false;
259 }
260 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000261
Greg Claytone71e2582011-02-04 01:58:07 +0000262 case eStateRunning:
263 case eStateStepping:
264 if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
265 {
266 result.AppendError ("Process is running. Use 'process interrupt' to pause execution.");
267 result.SetStatus (eReturnStatusFailed);
268 return false;
269 }
Chris Lattner24943d22010-06-08 16:52:24 +0000270 }
271 }
272 }
273
Greg Clayton238c0a12010-09-18 01:14:36 +0000274 if (!ParseOptions (args, result))
Chris Lattner24943d22010-06-08 16:52:24 +0000275 return false;
276
277 // Call the command-specific version of 'Execute', passing it the already processed arguments.
Greg Clayton238c0a12010-09-18 01:14:36 +0000278 return Execute (args, result);
Chris Lattner24943d22010-06-08 16:52:24 +0000279}
280
281class CommandDictCommandPartialMatch
282{
283 public:
284 CommandDictCommandPartialMatch (const char *match_str)
285 {
286 m_match_str = match_str;
287 }
288 bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const
289 {
290 // A NULL or empty string matches everything.
291 if (m_match_str == NULL || *m_match_str == '\0')
292 return 1;
293
294 size_t found = map_element.first.find (m_match_str, 0);
295 if (found == std::string::npos)
296 return 0;
297 else
298 return found == 0;
299 }
300
301 private:
302 const char *m_match_str;
303};
304
305int
306CommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str,
307 StringList &matches)
308{
309 int number_added = 0;
310 CommandDictCommandPartialMatch matcher(cmd_str);
311
312 CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher);
313
314 while (matching_cmds != in_map.end())
315 {
316 ++number_added;
317 matches.AppendString((*matching_cmds).first.c_str());
318 matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);;
319 }
320 return number_added;
321}
322
323int
324CommandObject::HandleCompletion
325(
326 Args &input,
327 int &cursor_index,
328 int &cursor_char_position,
329 int match_start_point,
330 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000331 bool &word_complete,
Chris Lattner24943d22010-06-08 16:52:24 +0000332 StringList &matches
333)
334{
335 if (WantsRawCommandString())
336 {
337 // FIXME: Abstract telling the completion to insert the completion character.
338 matches.Clear();
339 return -1;
340 }
341 else
342 {
343 // Can we do anything generic with the options?
344 Options *cur_options = GetOptions();
345 CommandReturnObject result;
346 OptionElementVector opt_element_vector;
347
348 if (cur_options != NULL)
349 {
350 // Re-insert the dummy command name string which will have been
351 // stripped off:
352 input.Unshift ("dummy-string");
353 cursor_index++;
354
355
356 // I stick an element on the end of the input, because if the last element is
357 // option that requires an argument, getopt_long will freak out.
358
359 input.AppendArgument ("<FAKE-VALUE>");
360
Jim Inghamadb84292010-06-24 20:31:04 +0000361 input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index);
Chris Lattner24943d22010-06-08 16:52:24 +0000362
363 input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1);
364
365 bool handled_by_options;
Greg Claytonf15996e2011-04-07 22:46:35 +0000366 handled_by_options = cur_options->HandleOptionCompletion (input,
Greg Clayton63094e02010-06-23 01:19:29 +0000367 opt_element_vector,
368 cursor_index,
369 cursor_char_position,
370 match_start_point,
371 max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000372 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000373 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000374 if (handled_by_options)
375 return matches.GetSize();
376 }
377
378 // If we got here, the last word is not an option or an option argument.
Greg Clayton238c0a12010-09-18 01:14:36 +0000379 return HandleArgumentCompletion (input,
Greg Clayton63094e02010-06-23 01:19:29 +0000380 cursor_index,
381 cursor_char_position,
382 opt_element_vector,
383 match_start_point,
384 max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000385 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000386 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000387 }
388}
389
Chris Lattner24943d22010-06-08 16:52:24 +0000390bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000391CommandObject::HelpTextContainsWord (const char *search_word)
Chris Lattner24943d22010-06-08 16:52:24 +0000392{
393 const char *short_help;
394 const char *long_help;
395 const char *syntax_help;
396 std::string options_usage_help;
397
398
399 bool found_word = false;
400
401 short_help = GetHelp();
402 long_help = GetHelpLong();
403 syntax_help = GetSyntax();
404
Caroline Tice34391782010-10-12 22:16:53 +0000405 if (strcasestr (short_help, search_word))
Chris Lattner24943d22010-06-08 16:52:24 +0000406 found_word = true;
Caroline Tice34391782010-10-12 22:16:53 +0000407 else if (strcasestr (long_help, search_word))
Chris Lattner24943d22010-06-08 16:52:24 +0000408 found_word = true;
Caroline Tice34391782010-10-12 22:16:53 +0000409 else if (strcasestr (syntax_help, search_word))
Chris Lattner24943d22010-06-08 16:52:24 +0000410 found_word = true;
411
412 if (!found_word
413 && GetOptions() != NULL)
414 {
415 StreamString usage_help;
Greg Claytonf15996e2011-04-07 22:46:35 +0000416 GetOptions()->GenerateOptionUsage (usage_help, this);
Chris Lattner24943d22010-06-08 16:52:24 +0000417 if (usage_help.GetSize() > 0)
418 {
419 const char *usage_text = usage_help.GetData();
Caroline Tice34391782010-10-12 22:16:53 +0000420 if (strcasestr (usage_text, search_word))
Chris Lattner24943d22010-06-08 16:52:24 +0000421 found_word = true;
422 }
423 }
424
425 return found_word;
426}
Caroline Ticefb355112010-10-01 17:46:38 +0000427
428int
429CommandObject::GetNumArgumentEntries ()
430{
431 return m_arguments.size();
432}
433
434CommandObject::CommandArgumentEntry *
435CommandObject::GetArgumentEntryAtIndex (int idx)
436{
437 if (idx < m_arguments.size())
438 return &(m_arguments[idx]);
439
440 return NULL;
441}
442
443CommandObject::ArgumentTableEntry *
444CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
445{
446 const ArgumentTableEntry *table = CommandObject::GetArgumentTable();
447
448 for (int i = 0; i < eArgTypeLastArg; ++i)
449 if (table[i].arg_type == arg_type)
450 return (ArgumentTableEntry *) &(table[i]);
451
452 return NULL;
453}
454
455void
456CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
457{
458 const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
459 ArgumentTableEntry *entry = (ArgumentTableEntry *) &(table[arg_type]);
460
461 // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
462
463 if (entry->arg_type != arg_type)
464 entry = CommandObject::FindArgumentDataByType (arg_type);
465
466 if (!entry)
467 return;
468
469 StreamString name_str;
470 name_str.Printf ("<%s>", entry->arg_name);
471
Enrico Granata1bba6e52011-07-07 00:38:40 +0000472 if (entry->help_function)
473 {
474 const char* help_text = entry->help_function();
475 if (!entry->help_function.self_formatting)
476 {
477 interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,
478 name_str.GetSize());
479 }
480 else
481 {
482 interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text,
483 name_str.GetSize());
484 }
485 }
Caroline Ticefb355112010-10-01 17:46:38 +0000486 else
487 interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
488}
489
490const char *
491CommandObject::GetArgumentName (CommandArgumentType arg_type)
492{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000493 ArgumentTableEntry *entry = (ArgumentTableEntry *) &(CommandObject::GetArgumentTable()[arg_type]);
494
495 // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
496
497 if (entry->arg_type != arg_type)
498 entry = CommandObject::FindArgumentDataByType (arg_type);
499
Johnny Chen25ca9842010-10-08 22:01:52 +0000500 if (entry)
501 return entry->arg_name;
502
503 StreamString str;
504 str << "Arg name for type (" << arg_type << ") not in arg table!";
505 return str.GetData();
Caroline Ticefb355112010-10-01 17:46:38 +0000506}
507
Caroline Tice43b014a2010-10-04 22:28:36 +0000508bool
Greg Claytonb3448432011-03-24 21:19:54 +0000509CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type)
Caroline Tice43b014a2010-10-04 22:28:36 +0000510{
511 if ((arg_repeat_type == eArgRepeatPairPlain)
512 || (arg_repeat_type == eArgRepeatPairOptional)
513 || (arg_repeat_type == eArgRepeatPairPlus)
514 || (arg_repeat_type == eArgRepeatPairStar)
515 || (arg_repeat_type == eArgRepeatPairRange)
516 || (arg_repeat_type == eArgRepeatPairRangeOptional))
517 return true;
518
519 return false;
520}
521
Caroline Ticefb355112010-10-01 17:46:38 +0000522void
523CommandObject::GetFormattedCommandArguments (Stream &str)
524{
525 int num_args = m_arguments.size();
526 for (int i = 0; i < num_args; ++i)
527 {
528 if (i > 0)
529 str.Printf (" ");
530 CommandArgumentEntry arg_entry = m_arguments[i];
531 int num_alternatives = arg_entry.size();
Caroline Tice43b014a2010-10-04 22:28:36 +0000532
533 if ((num_alternatives == 2)
534 && IsPairType (arg_entry[0].arg_repetition))
Caroline Ticefb355112010-10-01 17:46:38 +0000535 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000536 const char *first_name = GetArgumentName (arg_entry[0].arg_type);
537 const char *second_name = GetArgumentName (arg_entry[1].arg_type);
538 switch (arg_entry[0].arg_repetition)
539 {
540 case eArgRepeatPairPlain:
541 str.Printf ("<%s> <%s>", first_name, second_name);
542 break;
543 case eArgRepeatPairOptional:
544 str.Printf ("[<%s> <%s>]", first_name, second_name);
545 break;
546 case eArgRepeatPairPlus:
547 str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name);
548 break;
549 case eArgRepeatPairStar:
550 str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name);
551 break;
552 case eArgRepeatPairRange:
553 str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name);
554 break;
555 case eArgRepeatPairRangeOptional:
556 str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name);
557 break;
Caroline Ticeb5772842011-03-23 22:31:13 +0000558 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
559 // missing case statement(s).
560 case eArgRepeatPlain:
561 case eArgRepeatOptional:
562 case eArgRepeatPlus:
563 case eArgRepeatStar:
564 case eArgRepeatRange:
565 // These should not be reached, as they should fail the IsPairType test above.
566 break;
Caroline Tice43b014a2010-10-04 22:28:36 +0000567 }
Caroline Ticefb355112010-10-01 17:46:38 +0000568 }
Caroline Tice43b014a2010-10-04 22:28:36 +0000569 else
Caroline Ticefb355112010-10-01 17:46:38 +0000570 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000571 StreamString names;
572 for (int j = 0; j < num_alternatives; ++j)
573 {
574 if (j > 0)
575 names.Printf (" | ");
576 names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type));
577 }
578 switch (arg_entry[0].arg_repetition)
579 {
580 case eArgRepeatPlain:
581 str.Printf ("<%s>", names.GetData());
582 break;
583 case eArgRepeatPlus:
584 str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData());
585 break;
586 case eArgRepeatStar:
587 str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData());
588 break;
589 case eArgRepeatOptional:
590 str.Printf ("[<%s>]", names.GetData());
591 break;
592 case eArgRepeatRange:
593 str.Printf ("<%s_1> .. <%s_n>", names.GetData());
Caroline Ticeb5772842011-03-23 22:31:13 +0000594 break;
595 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
596 // missing case statement(s).
597 case eArgRepeatPairPlain:
598 case eArgRepeatPairOptional:
599 case eArgRepeatPairPlus:
600 case eArgRepeatPairStar:
601 case eArgRepeatPairRange:
602 case eArgRepeatPairRangeOptional:
603 // These should not be hit, as they should pass the IsPairType test above, and control should
604 // have gone into the other branch of the if statement.
605 break;
Caroline Tice43b014a2010-10-04 22:28:36 +0000606 }
Caroline Ticefb355112010-10-01 17:46:38 +0000607 }
608 }
609}
610
Stephen Wilson47f07852011-03-23 02:12:10 +0000611CommandArgumentType
Caroline Ticefb355112010-10-01 17:46:38 +0000612CommandObject::LookupArgumentName (const char *arg_name)
613{
614 CommandArgumentType return_type = eArgTypeLastArg;
615
616 std::string arg_name_str (arg_name);
617 size_t len = arg_name_str.length();
618 if (arg_name[0] == '<'
619 && arg_name[len-1] == '>')
620 arg_name_str = arg_name_str.substr (1, len-2);
621
622 for (int i = 0; i < eArgTypeLastArg; ++i)
623 if (arg_name_str.compare (g_arguments_data[i].arg_name) == 0)
624 return_type = g_arguments_data[i].arg_type;
625
626 return return_type;
627}
628
629static const char *
630BreakpointIDHelpTextCallback ()
631{
632 return "Breakpoint ID's consist major and minor numbers; the major number corresponds to the single entity that was created with a 'breakpoint set' command; the minor numbers correspond to all the locations that were actually found/set based on the major breakpoint. A full breakpoint ID might look like 3.14, meaning the 14th location set for the 3rd breakpoint. You can specify all the locations of a breakpoint by just indicating the major breakpoint number. A valid breakpoint id consists either of just the major id number, or the major number, a dot, and the location number (e.g. 3 or 3.2 could both be valid breakpoint ids).";
633}
634
635static const char *
636BreakpointIDRangeHelpTextCallback ()
637{
Caroline Tice43b014a2010-10-04 22:28:36 +0000638 return "A 'breakpoint id list' is a manner of specifying multiple breakpoints. This can be done through several mechanisms. The easiest way is to just enter a space-separated list of breakpoint ids. To specify all the breakpoint locations under a major breakpoint, you can use the major breakpoint number followed by '.*', eg. '5.*' means all the locations under breakpoint 5. You can also indicate a range of breakpoints by using <start-bp-id> - <end-bp-id>. The start-bp-id and end-bp-id for a range can be any valid breakpoint ids. It is not legal, however, to specify a range using specific locations that cross major breakpoint numbers. I.e. 3.2 - 3.7 is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
Caroline Ticefb355112010-10-01 17:46:38 +0000639}
640
Enrico Granata886bc3e2011-07-02 00:25:22 +0000641static const char *
642FormatHelpTextCallback ()
643{
Enrico Granata1bba6e52011-07-07 00:38:40 +0000644
645 static char* help_text_ptr = NULL;
646
647 if (help_text_ptr)
648 return help_text_ptr;
649
Enrico Granata886bc3e2011-07-02 00:25:22 +0000650 StreamString sstr;
651 sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n";
652 for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
653 {
Enrico Granata1bba6e52011-07-07 00:38:40 +0000654 if (f != eFormatDefault)
655 sstr.PutChar('\n');
656
Enrico Granata886bc3e2011-07-02 00:25:22 +0000657 char format_char = FormatManager::GetFormatAsFormatChar(f);
658 if (format_char)
659 sstr.Printf("'%c' or ", format_char);
660
Enrico Granata1bba6e52011-07-07 00:38:40 +0000661 sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
Enrico Granata886bc3e2011-07-02 00:25:22 +0000662 }
663
664 sstr.Flush();
665
666 std::string data = sstr.GetString();
667
Enrico Granata1bba6e52011-07-07 00:38:40 +0000668 help_text_ptr = new char[data.length()+1];
Enrico Granata886bc3e2011-07-02 00:25:22 +0000669
Enrico Granata1bba6e52011-07-07 00:38:40 +0000670 data.copy(help_text_ptr, data.length());
Enrico Granata886bc3e2011-07-02 00:25:22 +0000671
Enrico Granata1bba6e52011-07-07 00:38:40 +0000672 return help_text_ptr;
Enrico Granata886bc3e2011-07-02 00:25:22 +0000673}
674
675static const char *
Enrico Granata1bba6e52011-07-07 00:38:40 +0000676SummaryStringHelpTextCallback()
Enrico Granata886bc3e2011-07-02 00:25:22 +0000677{
Enrico Granata1bba6e52011-07-07 00:38:40 +0000678 return
679 "A summary string is a way to extract information from variables in order to present them using a summary.\n"
680 "Summary strings contain static text, variables, scopes and control sequences:\n"
681 " - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n"
682 " - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n"
683 " - 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"
684 " - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n"
685 "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n"
686 "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"
687 "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"
688 " (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"
689 " ${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"
690 " 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"
691 "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."
692 "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"
693 " path refers to:\n"
694 " - 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"
695 " and displayed as an individual variable\n"
696 " - 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"
697 " 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"
698 "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.";
Enrico Granata886bc3e2011-07-02 00:25:22 +0000699}
700
Greg Claytonaa378b12011-02-20 02:15:07 +0000701const char *
702CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
703{
704 if (arg_type >=0 && arg_type < eArgTypeLastArg)
705 return g_arguments_data[arg_type].arg_name;
706 return NULL;
707
708}
709
710const char *
711CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
712{
713 if (arg_type >=0 && arg_type < eArgTypeLastArg)
714 return g_arguments_data[arg_type].help_text;
715 return NULL;
716}
717
Caroline Ticefb355112010-10-01 17:46:38 +0000718CommandObject::ArgumentTableEntry
719CommandObject::g_arguments_data[] =
720{
Caroline Tice43b014a2010-10-04 22:28:36 +0000721 { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, NULL, "A valid address in the target program's execution space." },
722 { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, NULL, "The name of an abbreviation (alias) for a debugger command." },
Greg Clayton8f6be2a2010-10-09 01:40:57 +0000723 { eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, NULL, "Command options to be used as part of an alias (abbreviation) definition. (See 'help commands alias' for more information.)" },
Greg Clayton5e342f52011-04-13 22:47:15 +0000724 { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, NULL, "The architecture name, e.g. i386 or x86_64." },
Caroline Tice4d6675c2010-10-01 19:59:14 +0000725 { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, NULL, "A Boolean value: 'true' or 'false'" },
Caroline Tice43b014a2010-10-04 22:28:36 +0000726 { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, BreakpointIDHelpTextCallback, NULL },
727 { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, BreakpointIDRangeHelpTextCallback, NULL },
728 { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, NULL, "Number of bytes to use." },
Jim Ingham4a9d7902011-03-11 01:50:30 +0000729 { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, NULL, "Then name of a class from the debug information in the program." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000730 { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, NULL, "A debugger command (may be multiple words), without any options or arguments." },
Caroline Tice4d6675c2010-10-01 19:59:14 +0000731 { eArgTypeCount, "count", CommandCompletions::eNoCompletion, NULL, "An unsigned integer." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000732 { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
733 { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Caroline Tice4d6675c2010-10-01 19:59:14 +0000734 { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, NULL, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
Jim Ingham949d5ac2011-02-18 00:54:25 +0000735 { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, NULL, "The name of a file (can include path)." },
Enrico Granata1bba6e52011-07-07 00:38:40 +0000736 { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, CommandObject::ArgumentHelpCallback(FormatHelpTextCallback, true), NULL },
Caroline Tice43b014a2010-10-04 22:28:36 +0000737 { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, NULL, "Index into a thread's list of frames." },
738 { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
739 { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, NULL, "The name of a function." },
740 { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, NULL, "An index into a list." },
741 { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, NULL, "Line number in a source file." },
Caroline Tice7826c882010-10-26 03:11:13 +0000742 { eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, NULL, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." },
743 { eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, NULL, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000744 { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, NULL, "A C++ method name." },
Caroline Ticefb355112010-10-01 17:46:38 +0000745 { eArgTypeName, "name", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000746 { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
747 { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, NULL, "The number of lines to use." },
748 { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, NULL, "The number of items per line to display." },
Caroline Ticefb355112010-10-01 17:46:38 +0000749 { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000750 { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Jim Ingham4a9d7902011-03-11 01:50:30 +0000751 { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, NULL, "A command that is entered as a single line of text." },
Caroline Ticefb355112010-10-01 17:46:38 +0000752 { eArgTypePath, "path", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000753 { eArgTypePid, "pid", CommandCompletions::eNoCompletion, NULL, "The process ID number." },
Caroline Ticefb355112010-10-01 17:46:38 +0000754 { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000755 { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, NULL, "The name of the process." },
756 { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, NULL, "The name of the thread queue." },
757 { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, NULL, "A register name." },
758 { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, NULL, "A regular expression." },
759 { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, NULL, "Arguments to be passed to the target program when it starts executing." },
Caroline Ticefb355112010-10-01 17:46:38 +0000760 { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000761 { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, NULL, "The scripting language to be used for script-based commands. Currently only Python is valid." },
762 { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, NULL, "The word for which you wish to search for information about." },
763 { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, NULL, "An Objective-C selector name." },
764 { eArgTypeSettingIndex, "setting-index", CommandCompletions::eNoCompletion, NULL, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." },
765 { eArgTypeSettingKey, "setting-key", CommandCompletions::eNoCompletion, NULL, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." },
766 { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, NULL, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
Caroline Tice3a62e6d2010-10-18 22:56:57 +0000767 { eArgTypeSettingVariableName, "setting-variable-name", CommandCompletions::eNoCompletion, NULL, "The name of a settable internal debugger variable. Type 'settings list' to see a complete list of such variables." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000768 { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, NULL, "The name of a shared library." },
Jim Ingham4a9d7902011-03-11 01:50:30 +0000769 { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, NULL, "The name of a source file.." },
Greg Clayton8f6be2a2010-10-09 01:40:57 +0000770 { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, NULL, "Specify a sort order when dumping lists." },
Caroline Ticefb355112010-10-01 17:46:38 +0000771 { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Enrico Granata1bba6e52011-07-07 00:38:40 +0000772 { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, CommandObject::ArgumentHelpCallback(SummaryStringHelpTextCallback, true), NULL },
Jim Ingham4a9d7902011-03-11 01:50:30 +0000773 { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, NULL, "Any symbol name (function name, variable, argument, etc.)" },
Caroline Tice43b014a2010-10-04 22:28:36 +0000774 { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, NULL, "Thread ID number." },
775 { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, NULL, "Index into the process' list of threads." },
776 { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, NULL, "The thread's name." },
Caroline Tice3a62e6d2010-10-18 22:56:57 +0000777 { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, NULL, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000778 { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, NULL, "The name of a variable in your program." },
779 { eArgTypeValue, "value", CommandCompletions::eNoCompletion, NULL, "A value could be anything, depending on where and how it is used." },
Caroline Ticefb355112010-10-01 17:46:38 +0000780 { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
Caroline Tice43b014a2010-10-04 22:28:36 +0000781 { eArgTypeNone, "none", CommandCompletions::eNoCompletion, NULL, "No help available for this." },
Greg Clayton5e342f52011-04-13 22:47:15 +0000782 { eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, NULL, "The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms." }
Caroline Ticefb355112010-10-01 17:46:38 +0000783};
784
785const CommandObject::ArgumentTableEntry*
786CommandObject::GetArgumentTable ()
787{
Greg Claytonaa378b12011-02-20 02:15:07 +0000788 // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration
789 assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg);
Caroline Ticefb355112010-10-01 17:46:38 +0000790 return CommandObject::g_arguments_data;
791}
792
793