blob: 635d9a588386246c16fbbaffa44bf0bcf80dc1d9 [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 {
Jim Ingham8cc3f692011-07-09 00:55:34 +0000232 // A process that is not running is considered paused.
233 if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
234 {
235 result.AppendError ("Process must exist.");
236 result.SetStatus (eReturnStatusFailed);
237 return false;
238 }
Chris Lattner24943d22010-06-08 16:52:24 +0000239 }
Greg Claytone71e2582011-02-04 01:58:07 +0000240 else
Chris Lattner24943d22010-06-08 16:52:24 +0000241 {
Greg Claytone71e2582011-02-04 01:58:07 +0000242 StateType state = process->GetState();
243
244 switch (state)
Chris Lattner24943d22010-06-08 16:52:24 +0000245 {
Greg Clayton4fdf7602011-03-20 04:57:14 +0000246 case eStateInvalid:
Greg Claytone71e2582011-02-04 01:58:07 +0000247 case eStateSuspended:
248 case eStateCrashed:
249 case eStateStopped:
250 break;
251
252 case eStateConnected:
253 case eStateAttaching:
254 case eStateLaunching:
255 case eStateDetached:
256 case eStateExited:
257 case eStateUnloaded:
258 if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
259 {
260 result.AppendError ("Process must be launched.");
261 result.SetStatus (eReturnStatusFailed);
262 return false;
263 }
264 break;
Chris Lattner24943d22010-06-08 16:52:24 +0000265
Greg Claytone71e2582011-02-04 01:58:07 +0000266 case eStateRunning:
267 case eStateStepping:
268 if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
269 {
270 result.AppendError ("Process is running. Use 'process interrupt' to pause execution.");
271 result.SetStatus (eReturnStatusFailed);
272 return false;
273 }
Chris Lattner24943d22010-06-08 16:52:24 +0000274 }
275 }
276 }
277
Greg Clayton238c0a12010-09-18 01:14:36 +0000278 if (!ParseOptions (args, result))
Chris Lattner24943d22010-06-08 16:52:24 +0000279 return false;
280
281 // Call the command-specific version of 'Execute', passing it the already processed arguments.
Greg Clayton238c0a12010-09-18 01:14:36 +0000282 return Execute (args, result);
Chris Lattner24943d22010-06-08 16:52:24 +0000283}
284
285class CommandDictCommandPartialMatch
286{
287 public:
288 CommandDictCommandPartialMatch (const char *match_str)
289 {
290 m_match_str = match_str;
291 }
292 bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const
293 {
294 // A NULL or empty string matches everything.
295 if (m_match_str == NULL || *m_match_str == '\0')
296 return 1;
297
298 size_t found = map_element.first.find (m_match_str, 0);
299 if (found == std::string::npos)
300 return 0;
301 else
302 return found == 0;
303 }
304
305 private:
306 const char *m_match_str;
307};
308
309int
310CommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str,
311 StringList &matches)
312{
313 int number_added = 0;
314 CommandDictCommandPartialMatch matcher(cmd_str);
315
316 CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher);
317
318 while (matching_cmds != in_map.end())
319 {
320 ++number_added;
321 matches.AppendString((*matching_cmds).first.c_str());
322 matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);;
323 }
324 return number_added;
325}
326
327int
328CommandObject::HandleCompletion
329(
330 Args &input,
331 int &cursor_index,
332 int &cursor_char_position,
333 int match_start_point,
334 int max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000335 bool &word_complete,
Chris Lattner24943d22010-06-08 16:52:24 +0000336 StringList &matches
337)
338{
339 if (WantsRawCommandString())
340 {
341 // FIXME: Abstract telling the completion to insert the completion character.
342 matches.Clear();
343 return -1;
344 }
345 else
346 {
347 // Can we do anything generic with the options?
348 Options *cur_options = GetOptions();
349 CommandReturnObject result;
350 OptionElementVector opt_element_vector;
351
352 if (cur_options != NULL)
353 {
354 // Re-insert the dummy command name string which will have been
355 // stripped off:
356 input.Unshift ("dummy-string");
357 cursor_index++;
358
359
360 // I stick an element on the end of the input, because if the last element is
361 // option that requires an argument, getopt_long will freak out.
362
363 input.AppendArgument ("<FAKE-VALUE>");
364
Jim Inghamadb84292010-06-24 20:31:04 +0000365 input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index);
Chris Lattner24943d22010-06-08 16:52:24 +0000366
367 input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1);
368
369 bool handled_by_options;
Greg Claytonf15996e2011-04-07 22:46:35 +0000370 handled_by_options = cur_options->HandleOptionCompletion (input,
Greg Clayton63094e02010-06-23 01:19:29 +0000371 opt_element_vector,
372 cursor_index,
373 cursor_char_position,
374 match_start_point,
375 max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000376 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000377 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000378 if (handled_by_options)
379 return matches.GetSize();
380 }
381
382 // If we got here, the last word is not an option or an option argument.
Greg Clayton238c0a12010-09-18 01:14:36 +0000383 return HandleArgumentCompletion (input,
Greg Clayton63094e02010-06-23 01:19:29 +0000384 cursor_index,
385 cursor_char_position,
386 opt_element_vector,
387 match_start_point,
388 max_return_elements,
Jim Ingham802f8b02010-06-30 05:02:46 +0000389 word_complete,
Greg Clayton63094e02010-06-23 01:19:29 +0000390 matches);
Chris Lattner24943d22010-06-08 16:52:24 +0000391 }
392}
393
Chris Lattner24943d22010-06-08 16:52:24 +0000394bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000395CommandObject::HelpTextContainsWord (const char *search_word)
Chris Lattner24943d22010-06-08 16:52:24 +0000396{
397 const char *short_help;
398 const char *long_help;
399 const char *syntax_help;
400 std::string options_usage_help;
401
402
403 bool found_word = false;
404
405 short_help = GetHelp();
406 long_help = GetHelpLong();
407 syntax_help = GetSyntax();
408
Caroline Tice34391782010-10-12 22:16:53 +0000409 if (strcasestr (short_help, search_word))
Chris Lattner24943d22010-06-08 16:52:24 +0000410 found_word = true;
Caroline Tice34391782010-10-12 22:16:53 +0000411 else if (strcasestr (long_help, search_word))
Chris Lattner24943d22010-06-08 16:52:24 +0000412 found_word = true;
Caroline Tice34391782010-10-12 22:16:53 +0000413 else if (strcasestr (syntax_help, search_word))
Chris Lattner24943d22010-06-08 16:52:24 +0000414 found_word = true;
415
416 if (!found_word
417 && GetOptions() != NULL)
418 {
419 StreamString usage_help;
Greg Claytonf15996e2011-04-07 22:46:35 +0000420 GetOptions()->GenerateOptionUsage (usage_help, this);
Chris Lattner24943d22010-06-08 16:52:24 +0000421 if (usage_help.GetSize() > 0)
422 {
423 const char *usage_text = usage_help.GetData();
Caroline Tice34391782010-10-12 22:16:53 +0000424 if (strcasestr (usage_text, search_word))
Chris Lattner24943d22010-06-08 16:52:24 +0000425 found_word = true;
426 }
427 }
428
429 return found_word;
430}
Caroline Ticefb355112010-10-01 17:46:38 +0000431
432int
433CommandObject::GetNumArgumentEntries ()
434{
435 return m_arguments.size();
436}
437
438CommandObject::CommandArgumentEntry *
439CommandObject::GetArgumentEntryAtIndex (int idx)
440{
441 if (idx < m_arguments.size())
442 return &(m_arguments[idx]);
443
444 return NULL;
445}
446
447CommandObject::ArgumentTableEntry *
448CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
449{
450 const ArgumentTableEntry *table = CommandObject::GetArgumentTable();
451
452 for (int i = 0; i < eArgTypeLastArg; ++i)
453 if (table[i].arg_type == arg_type)
454 return (ArgumentTableEntry *) &(table[i]);
455
456 return NULL;
457}
458
459void
460CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
461{
462 const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
463 ArgumentTableEntry *entry = (ArgumentTableEntry *) &(table[arg_type]);
464
465 // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
466
467 if (entry->arg_type != arg_type)
468 entry = CommandObject::FindArgumentDataByType (arg_type);
469
470 if (!entry)
471 return;
472
473 StreamString name_str;
474 name_str.Printf ("<%s>", entry->arg_name);
475
Enrico Granataff782382011-07-08 02:51:01 +0000476 if (entry->help_function)
Enrico Granata1bba6e52011-07-07 00:38:40 +0000477 {
Enrico Granataff782382011-07-08 02:51:01 +0000478 const char* help_text = entry->help_function();
Enrico Granata1bba6e52011-07-07 00:38:40 +0000479 if (!entry->help_function.self_formatting)
480 {
481 interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,
482 name_str.GetSize());
483 }
484 else
485 {
486 interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text,
487 name_str.GetSize());
488 }
489 }
Caroline Ticefb355112010-10-01 17:46:38 +0000490 else
491 interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
492}
493
494const char *
495CommandObject::GetArgumentName (CommandArgumentType arg_type)
496{
Caroline Tice4d6675c2010-10-01 19:59:14 +0000497 ArgumentTableEntry *entry = (ArgumentTableEntry *) &(CommandObject::GetArgumentTable()[arg_type]);
498
499 // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
500
501 if (entry->arg_type != arg_type)
502 entry = CommandObject::FindArgumentDataByType (arg_type);
503
Johnny Chen25ca9842010-10-08 22:01:52 +0000504 if (entry)
505 return entry->arg_name;
506
507 StreamString str;
508 str << "Arg name for type (" << arg_type << ") not in arg table!";
509 return str.GetData();
Caroline Ticefb355112010-10-01 17:46:38 +0000510}
511
Caroline Tice43b014a2010-10-04 22:28:36 +0000512bool
Greg Claytonb3448432011-03-24 21:19:54 +0000513CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type)
Caroline Tice43b014a2010-10-04 22:28:36 +0000514{
515 if ((arg_repeat_type == eArgRepeatPairPlain)
516 || (arg_repeat_type == eArgRepeatPairOptional)
517 || (arg_repeat_type == eArgRepeatPairPlus)
518 || (arg_repeat_type == eArgRepeatPairStar)
519 || (arg_repeat_type == eArgRepeatPairRange)
520 || (arg_repeat_type == eArgRepeatPairRangeOptional))
521 return true;
522
523 return false;
524}
525
Caroline Ticefb355112010-10-01 17:46:38 +0000526void
527CommandObject::GetFormattedCommandArguments (Stream &str)
528{
529 int num_args = m_arguments.size();
530 for (int i = 0; i < num_args; ++i)
531 {
532 if (i > 0)
533 str.Printf (" ");
534 CommandArgumentEntry arg_entry = m_arguments[i];
535 int num_alternatives = arg_entry.size();
Caroline Tice43b014a2010-10-04 22:28:36 +0000536
537 if ((num_alternatives == 2)
538 && IsPairType (arg_entry[0].arg_repetition))
Caroline Ticefb355112010-10-01 17:46:38 +0000539 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000540 const char *first_name = GetArgumentName (arg_entry[0].arg_type);
541 const char *second_name = GetArgumentName (arg_entry[1].arg_type);
542 switch (arg_entry[0].arg_repetition)
543 {
544 case eArgRepeatPairPlain:
545 str.Printf ("<%s> <%s>", first_name, second_name);
546 break;
547 case eArgRepeatPairOptional:
548 str.Printf ("[<%s> <%s>]", first_name, second_name);
549 break;
550 case eArgRepeatPairPlus:
551 str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name);
552 break;
553 case eArgRepeatPairStar:
554 str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name);
555 break;
556 case eArgRepeatPairRange:
557 str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name);
558 break;
559 case eArgRepeatPairRangeOptional:
560 str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name);
561 break;
Caroline Ticeb5772842011-03-23 22:31:13 +0000562 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
563 // missing case statement(s).
564 case eArgRepeatPlain:
565 case eArgRepeatOptional:
566 case eArgRepeatPlus:
567 case eArgRepeatStar:
568 case eArgRepeatRange:
569 // These should not be reached, as they should fail the IsPairType test above.
570 break;
Caroline Tice43b014a2010-10-04 22:28:36 +0000571 }
Caroline Ticefb355112010-10-01 17:46:38 +0000572 }
Caroline Tice43b014a2010-10-04 22:28:36 +0000573 else
Caroline Ticefb355112010-10-01 17:46:38 +0000574 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000575 StreamString names;
576 for (int j = 0; j < num_alternatives; ++j)
577 {
578 if (j > 0)
579 names.Printf (" | ");
580 names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type));
581 }
582 switch (arg_entry[0].arg_repetition)
583 {
584 case eArgRepeatPlain:
585 str.Printf ("<%s>", names.GetData());
586 break;
587 case eArgRepeatPlus:
588 str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData());
589 break;
590 case eArgRepeatStar:
591 str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData());
592 break;
593 case eArgRepeatOptional:
594 str.Printf ("[<%s>]", names.GetData());
595 break;
596 case eArgRepeatRange:
597 str.Printf ("<%s_1> .. <%s_n>", names.GetData());
Caroline Ticeb5772842011-03-23 22:31:13 +0000598 break;
599 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
600 // missing case statement(s).
601 case eArgRepeatPairPlain:
602 case eArgRepeatPairOptional:
603 case eArgRepeatPairPlus:
604 case eArgRepeatPairStar:
605 case eArgRepeatPairRange:
606 case eArgRepeatPairRangeOptional:
607 // These should not be hit, as they should pass the IsPairType test above, and control should
608 // have gone into the other branch of the if statement.
609 break;
Caroline Tice43b014a2010-10-04 22:28:36 +0000610 }
Caroline Ticefb355112010-10-01 17:46:38 +0000611 }
612 }
613}
614
Stephen Wilson47f07852011-03-23 02:12:10 +0000615CommandArgumentType
Caroline Ticefb355112010-10-01 17:46:38 +0000616CommandObject::LookupArgumentName (const char *arg_name)
617{
618 CommandArgumentType return_type = eArgTypeLastArg;
619
620 std::string arg_name_str (arg_name);
621 size_t len = arg_name_str.length();
622 if (arg_name[0] == '<'
623 && arg_name[len-1] == '>')
624 arg_name_str = arg_name_str.substr (1, len-2);
625
Johnny Chen309c89d2011-07-14 22:20:12 +0000626 const ArgumentTableEntry *table = GetArgumentTable();
Caroline Ticefb355112010-10-01 17:46:38 +0000627 for (int i = 0; i < eArgTypeLastArg; ++i)
Johnny Chen309c89d2011-07-14 22:20:12 +0000628 if (arg_name_str.compare (table[i].arg_name) == 0)
Caroline Ticefb355112010-10-01 17:46:38 +0000629 return_type = g_arguments_data[i].arg_type;
630
631 return return_type;
632}
633
634static const char *
635BreakpointIDHelpTextCallback ()
636{
637 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).";
638}
639
640static const char *
641BreakpointIDRangeHelpTextCallback ()
642{
Caroline Tice43b014a2010-10-04 22:28:36 +0000643 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 +0000644}
645
Enrico Granata886bc3e2011-07-02 00:25:22 +0000646static const char *
647FormatHelpTextCallback ()
648{
Enrico Granata1bba6e52011-07-07 00:38:40 +0000649
650 static char* help_text_ptr = NULL;
651
652 if (help_text_ptr)
653 return help_text_ptr;
654
Enrico Granata886bc3e2011-07-02 00:25:22 +0000655 StreamString sstr;
656 sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n";
657 for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
658 {
Enrico Granata1bba6e52011-07-07 00:38:40 +0000659 if (f != eFormatDefault)
660 sstr.PutChar('\n');
661
Enrico Granata886bc3e2011-07-02 00:25:22 +0000662 char format_char = FormatManager::GetFormatAsFormatChar(f);
663 if (format_char)
664 sstr.Printf("'%c' or ", format_char);
665
Enrico Granata1bba6e52011-07-07 00:38:40 +0000666 sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
Enrico Granata886bc3e2011-07-02 00:25:22 +0000667 }
668
669 sstr.Flush();
670
671 std::string data = sstr.GetString();
672
Enrico Granata1bba6e52011-07-07 00:38:40 +0000673 help_text_ptr = new char[data.length()+1];
Enrico Granata886bc3e2011-07-02 00:25:22 +0000674
Enrico Granata1bba6e52011-07-07 00:38:40 +0000675 data.copy(help_text_ptr, data.length());
Enrico Granata886bc3e2011-07-02 00:25:22 +0000676
Enrico Granata1bba6e52011-07-07 00:38:40 +0000677 return help_text_ptr;
Enrico Granata886bc3e2011-07-02 00:25:22 +0000678}
679
680static const char *
Enrico Granata1bba6e52011-07-07 00:38:40 +0000681SummaryStringHelpTextCallback()
Enrico Granata886bc3e2011-07-02 00:25:22 +0000682{
Enrico Granata1bba6e52011-07-07 00:38:40 +0000683 return
684 "A summary string is a way to extract information from variables in order to present them using a summary.\n"
685 "Summary strings contain static text, variables, scopes and control sequences:\n"
686 " - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n"
687 " - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n"
688 " - 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"
689 " - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n"
690 "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n"
691 "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"
692 "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"
693 " (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"
694 " ${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"
695 " 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"
696 "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."
697 "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"
698 " path refers to:\n"
699 " - 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"
700 " and displayed as an individual variable\n"
701 " - 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"
702 " 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"
703 "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 +0000704}
705
Greg Claytonaa378b12011-02-20 02:15:07 +0000706const char *
707CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
708{
709 if (arg_type >=0 && arg_type < eArgTypeLastArg)
710 return g_arguments_data[arg_type].arg_name;
711 return NULL;
712
713}
714
715const char *
716CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
717{
718 if (arg_type >=0 && arg_type < eArgTypeLastArg)
719 return g_arguments_data[arg_type].help_text;
720 return NULL;
721}
722
Caroline Ticefb355112010-10-01 17:46:38 +0000723CommandObject::ArgumentTableEntry
724CommandObject::g_arguments_data[] =
725{
Enrico Granata9ae9fd32011-07-07 15:49:54 +0000726 { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { NULL, false }, "A valid address in the target program's execution space." },
727 { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of an abbreviation (alias) for a debugger command." },
728 { eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, { NULL, false }, "Command options to be used as part of an alias (abbreviation) definition. (See 'help commands alias' for more information.)" },
729 { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { NULL, false }, "The architecture name, e.g. i386 or x86_64." },
730 { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { NULL, false }, "A Boolean value: 'true' or 'false'" },
731 { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, NULL },
732 { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, NULL },
733 { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { NULL, false }, "Number of bytes to use." },
734 { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { NULL, false }, "Then name of a class from the debug information in the program." },
735 { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { NULL, false }, "A debugger command (may be multiple words), without any options or arguments." },
736 { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
737 { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
738 { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
739 { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { NULL, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
740 { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { NULL, false }, "The name of a file (can include path)." },
741 { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, NULL },
742 { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { NULL, false }, "Index into a thread's list of frames." },
743 { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
744 { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a function." },
745 { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { NULL, false }, "An index into a list." },
746 { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { NULL, false }, "Line number in a source file." },
747 { eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { NULL, false }, "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." },
748 { eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." },
749 { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { NULL, false }, "A C++ method name." },
750 { eArgTypeName, "name", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
751 { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
752 { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { NULL, false }, "The number of lines to use." },
753 { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { NULL, false }, "The number of items per line to display." },
754 { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
755 { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
756 { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { NULL, false }, "A command that is entered as a single line of text." },
757 { eArgTypePath, "path", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
758 { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { NULL, false }, "The process ID number." },
759 { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
760 { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the process." },
761 { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the thread queue." },
762 { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { NULL, false }, "A register name." },
763 { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { NULL, false }, "A regular expression." },
764 { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { NULL, false }, "Arguments to be passed to the target program when it starts executing." },
765 { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
766 { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { NULL, false }, "The scripting language to be used for script-based commands. Currently only Python is valid." },
767 { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { NULL, false }, "The word for which you wish to search for information about." },
768 { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { NULL, false }, "An Objective-C selector name." },
769 { eArgTypeSettingIndex, "setting-index", CommandCompletions::eNoCompletion, { NULL, false }, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." },
770 { eArgTypeSettingKey, "setting-key", CommandCompletions::eNoCompletion, { NULL, false }, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." },
771 { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
772 { eArgTypeSettingVariableName, "setting-variable-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a settable internal debugger variable. Type 'settings list' to see a complete list of such variables." },
773 { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a shared library." },
774 { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, { NULL, false }, "The name of a source file.." },
775 { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, { NULL, false }, "Specify a sort order when dumping lists." },
776 { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
777 { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, { SummaryStringHelpTextCallback, true }, NULL },
778 { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, { NULL, false }, "Any symbol name (function name, variable, argument, etc.)" },
779 { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { NULL, false }, "Thread ID number." },
780 { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { NULL, false }, "Index into the process' list of threads." },
781 { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { NULL, false }, "The thread's name." },
Johnny Chen309c89d2011-07-14 22:20:12 +0000782 { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
Enrico Granata9ae9fd32011-07-07 15:49:54 +0000783 { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { NULL, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
784 { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a variable in your program." },
785 { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { NULL, false }, "A value could be anything, depending on where and how it is used." },
786 { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
787 { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { NULL, false }, "No help available for this." },
788 { eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, { NULL, false }, "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 +0000789};
790
791const CommandObject::ArgumentTableEntry*
792CommandObject::GetArgumentTable ()
793{
Greg Claytonaa378b12011-02-20 02:15:07 +0000794 // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration
795 assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg);
Caroline Ticefb355112010-10-01 17:46:38 +0000796 return CommandObject::g_arguments_data;
797}
798
799