1 //===-- 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"
20 #include "lldb/Core/ArchSpec.h"
21 #include "lldb/Interpreter/Options.h"
22 
23 // These are for the Sourcename completers.
24 // FIXME: Make a separate file for the completers.
25 #include "lldb/Host/FileSpec.h"
26 #include "lldb/Core/FileSpecList.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/Target.h"
29 
30 #include "lldb/Interpreter/CommandInterpreter.h"
31 #include "lldb/Interpreter/CommandReturnObject.h"
32 #include "lldb/Interpreter/ScriptInterpreter.h"
33 #include "lldb/Interpreter/ScriptInterpreterPython.h"
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 //-------------------------------------------------------------------------
39 // CommandObject
40 //-------------------------------------------------------------------------
41 
42 CommandObject::CommandObject
43 (
44     CommandInterpreter &interpreter,
45     const char *name,
46     const char *help,
47     const char *syntax,
48     uint32_t flags
49 ) :
50     m_interpreter (interpreter),
51     m_cmd_name (name),
52     m_cmd_help_short (),
53     m_cmd_help_long (),
54     m_cmd_syntax (),
55     m_is_alias (false),
56     m_flags (flags),
57     m_arguments(),
58     m_command_override_callback (NULL),
59     m_command_override_baton (NULL)
60 {
61     if (help && help[0])
62         m_cmd_help_short = help;
63     if (syntax && syntax[0])
64         m_cmd_syntax = syntax;
65 }
66 
67 CommandObject::~CommandObject ()
68 {
69 }
70 
71 const char *
72 CommandObject::GetHelp ()
73 {
74     return m_cmd_help_short.c_str();
75 }
76 
77 const char *
78 CommandObject::GetHelpLong ()
79 {
80     return m_cmd_help_long.c_str();
81 }
82 
83 const char *
84 CommandObject::GetSyntax ()
85 {
86     if (m_cmd_syntax.length() == 0)
87     {
88         StreamString syntax_str;
89         syntax_str.Printf ("%s", GetCommandName());
90         if (GetOptions() != NULL)
91             syntax_str.Printf (" <cmd-options>");
92         if (m_arguments.size() > 0)
93         {
94             syntax_str.Printf (" ");
95             if (WantsRawCommandString())
96                 syntax_str.Printf("-- ");
97             GetFormattedCommandArguments (syntax_str);
98         }
99         m_cmd_syntax = syntax_str.GetData ();
100     }
101 
102     return m_cmd_syntax.c_str();
103 }
104 
105 const char *
106 CommandObject::Translate ()
107 {
108     //return m_cmd_func_name.c_str();
109     return "This function is currently not implemented.";
110 }
111 
112 const char *
113 CommandObject::GetCommandName ()
114 {
115     return m_cmd_name.c_str();
116 }
117 
118 void
119 CommandObject::SetCommandName (const char *name)
120 {
121     m_cmd_name = name;
122 }
123 
124 void
125 CommandObject::SetHelp (const char *cstr)
126 {
127     m_cmd_help_short = cstr;
128 }
129 
130 void
131 CommandObject::SetHelpLong (const char *cstr)
132 {
133     m_cmd_help_long = cstr;
134 }
135 
136 void
137 CommandObject::SetHelpLong (std::string str)
138 {
139     m_cmd_help_long = str;
140 }
141 
142 void
143 CommandObject::SetSyntax (const char *cstr)
144 {
145     m_cmd_syntax = cstr;
146 }
147 
148 Options *
149 CommandObject::GetOptions ()
150 {
151     // By default commands don't have options unless this virtual function
152     // is overridden by base classes.
153     return NULL;
154 }
155 
156 bool
157 CommandObject::ParseOptions
158 (
159     Args& args,
160     CommandReturnObject &result
161 )
162 {
163     // See if the subclass has options?
164     Options *options = GetOptions();
165     if (options != NULL)
166     {
167         Error error;
168         options->NotifyOptionParsingStarting();
169 
170         // ParseOptions calls getopt_long, which always skips the zero'th item in the array and starts at position 1,
171         // so we need to push a dummy value into position zero.
172         args.Unshift("dummy_string");
173         error = args.ParseOptions (*options);
174 
175         // The "dummy_string" will have already been removed by ParseOptions,
176         // so no need to remove it.
177 
178         if (error.Success())
179             error = options->NotifyOptionParsingFinished();
180 
181         if (error.Success())
182         {
183             if (options->VerifyOptions (result))
184                 return true;
185         }
186         else
187         {
188             const char *error_cstr = error.AsCString();
189             if (error_cstr)
190             {
191                 // We got an error string, lets use that
192                 result.AppendError(error_cstr);
193             }
194             else
195             {
196                 // No error string, output the usage information into result
197                 options->GenerateOptionUsage (result.GetErrorStream(), this);
198             }
199         }
200         result.SetStatus (eReturnStatusFailed);
201         return false;
202     }
203     return true;
204 }
205 
206 
207 
208 bool
209 CommandObject::CheckFlags (CommandReturnObject &result)
210 {
211     if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
212     {
213         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
214         if (process == NULL)
215         {
216             // A process that is not running is considered paused.
217             if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
218             {
219                 result.AppendError ("Process must exist.");
220                 result.SetStatus (eReturnStatusFailed);
221                 return false;
222             }
223         }
224         else
225         {
226             StateType state = process->GetState();
227 
228             switch (state)
229             {
230             case eStateInvalid:
231             case eStateSuspended:
232             case eStateCrashed:
233             case eStateStopped:
234                 break;
235 
236             case eStateConnected:
237             case eStateAttaching:
238             case eStateLaunching:
239             case eStateDetached:
240             case eStateExited:
241             case eStateUnloaded:
242                 if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
243                 {
244                     result.AppendError ("Process must be launched.");
245                     result.SetStatus (eReturnStatusFailed);
246                     return false;
247                 }
248                 break;
249 
250             case eStateRunning:
251             case eStateStepping:
252                 if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
253                 {
254                     result.AppendError ("Process is running.  Use 'process interrupt' to pause execution.");
255                     result.SetStatus (eReturnStatusFailed);
256                     return false;
257                 }
258             }
259         }
260     }
261     return true;
262 }
263 
264 class CommandDictCommandPartialMatch
265 {
266     public:
267         CommandDictCommandPartialMatch (const char *match_str)
268         {
269             m_match_str = match_str;
270         }
271         bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const
272         {
273             // A NULL or empty string matches everything.
274             if (m_match_str == NULL || *m_match_str == '\0')
275                 return 1;
276 
277             size_t found = map_element.first.find (m_match_str, 0);
278             if (found == std::string::npos)
279                 return 0;
280             else
281                 return found == 0;
282         }
283 
284     private:
285         const char *m_match_str;
286 };
287 
288 int
289 CommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str,
290                                               StringList &matches)
291 {
292     int number_added = 0;
293     CommandDictCommandPartialMatch matcher(cmd_str);
294 
295     CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher);
296 
297     while (matching_cmds != in_map.end())
298     {
299         ++number_added;
300         matches.AppendString((*matching_cmds).first.c_str());
301         matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);;
302     }
303     return number_added;
304 }
305 
306 int
307 CommandObject::HandleCompletion
308 (
309     Args &input,
310     int &cursor_index,
311     int &cursor_char_position,
312     int match_start_point,
313     int max_return_elements,
314     bool &word_complete,
315     StringList &matches
316 )
317 {
318     // Default implmentation of WantsCompletion() is !WantsRawCommandString().
319     // Subclasses who want raw command string but desire, for example,
320     // argument completion should override WantsCompletion() to return true,
321     // instead.
322     if (WantsRawCommandString() && !WantsCompletion())
323     {
324         // FIXME: Abstract telling the completion to insert the completion character.
325         matches.Clear();
326         return -1;
327     }
328     else
329     {
330         // Can we do anything generic with the options?
331         Options *cur_options = GetOptions();
332         CommandReturnObject result;
333         OptionElementVector opt_element_vector;
334 
335         if (cur_options != NULL)
336         {
337             // Re-insert the dummy command name string which will have been
338             // stripped off:
339             input.Unshift ("dummy-string");
340             cursor_index++;
341 
342 
343             // I stick an element on the end of the input, because if the last element is
344             // option that requires an argument, getopt_long will freak out.
345 
346             input.AppendArgument ("<FAKE-VALUE>");
347 
348             input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index);
349 
350             input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1);
351 
352             bool handled_by_options;
353             handled_by_options = cur_options->HandleOptionCompletion (input,
354                                                                       opt_element_vector,
355                                                                       cursor_index,
356                                                                       cursor_char_position,
357                                                                       match_start_point,
358                                                                       max_return_elements,
359                                                                       word_complete,
360                                                                       matches);
361             if (handled_by_options)
362                 return matches.GetSize();
363         }
364 
365         // If we got here, the last word is not an option or an option argument.
366         return HandleArgumentCompletion (input,
367                                          cursor_index,
368                                          cursor_char_position,
369                                          opt_element_vector,
370                                          match_start_point,
371                                          max_return_elements,
372                                          word_complete,
373                                          matches);
374     }
375 }
376 
377 bool
378 CommandObject::HelpTextContainsWord (const char *search_word)
379 {
380     std::string options_usage_help;
381 
382     bool found_word = false;
383 
384     const char *short_help = GetHelp();
385     const char *long_help = GetHelpLong();
386     const char *syntax_help = GetSyntax();
387 
388     if (short_help && strcasestr (short_help, search_word))
389         found_word = true;
390     else if (long_help && strcasestr (long_help, search_word))
391         found_word = true;
392     else if (syntax_help && strcasestr (syntax_help, search_word))
393         found_word = true;
394 
395     if (!found_word
396         && GetOptions() != NULL)
397     {
398         StreamString usage_help;
399         GetOptions()->GenerateOptionUsage (usage_help, this);
400         if (usage_help.GetSize() > 0)
401         {
402             const char *usage_text = usage_help.GetData();
403             if (strcasestr (usage_text, search_word))
404               found_word = true;
405         }
406     }
407 
408     return found_word;
409 }
410 
411 int
412 CommandObject::GetNumArgumentEntries  ()
413 {
414     return m_arguments.size();
415 }
416 
417 CommandObject::CommandArgumentEntry *
418 CommandObject::GetArgumentEntryAtIndex (int idx)
419 {
420     if (idx < m_arguments.size())
421         return &(m_arguments[idx]);
422 
423     return NULL;
424 }
425 
426 CommandObject::ArgumentTableEntry *
427 CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
428 {
429     const ArgumentTableEntry *table = CommandObject::GetArgumentTable();
430 
431     for (int i = 0; i < eArgTypeLastArg; ++i)
432         if (table[i].arg_type == arg_type)
433             return (ArgumentTableEntry *) &(table[i]);
434 
435     return NULL;
436 }
437 
438 void
439 CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
440 {
441     const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
442     ArgumentTableEntry *entry = (ArgumentTableEntry *) &(table[arg_type]);
443 
444     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
445 
446     if (entry->arg_type != arg_type)
447         entry = CommandObject::FindArgumentDataByType (arg_type);
448 
449     if (!entry)
450         return;
451 
452     StreamString name_str;
453     name_str.Printf ("<%s>", entry->arg_name);
454 
455     if (entry->help_function)
456     {
457         const char* help_text = entry->help_function();
458         if (!entry->help_function.self_formatting)
459         {
460             interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,
461                                                  name_str.GetSize());
462         }
463         else
464         {
465             interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text,
466                                        name_str.GetSize());
467         }
468     }
469     else
470         interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
471 }
472 
473 const char *
474 CommandObject::GetArgumentName (CommandArgumentType arg_type)
475 {
476     ArgumentTableEntry *entry = (ArgumentTableEntry *) &(CommandObject::GetArgumentTable()[arg_type]);
477 
478     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
479 
480     if (entry->arg_type != arg_type)
481         entry = CommandObject::FindArgumentDataByType (arg_type);
482 
483     if (entry)
484         return entry->arg_name;
485 
486     StreamString str;
487     str << "Arg name for type (" << arg_type << ") not in arg table!";
488     return str.GetData();
489 }
490 
491 bool
492 CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type)
493 {
494     if ((arg_repeat_type == eArgRepeatPairPlain)
495         ||  (arg_repeat_type == eArgRepeatPairOptional)
496         ||  (arg_repeat_type == eArgRepeatPairPlus)
497         ||  (arg_repeat_type == eArgRepeatPairStar)
498         ||  (arg_repeat_type == eArgRepeatPairRange)
499         ||  (arg_repeat_type == eArgRepeatPairRangeOptional))
500         return true;
501 
502     return false;
503 }
504 
505 static CommandObject::CommandArgumentEntry
506 OptSetFiltered(uint32_t opt_set_mask, CommandObject::CommandArgumentEntry &cmd_arg_entry)
507 {
508     CommandObject::CommandArgumentEntry ret_val;
509     for (unsigned i = 0; i < cmd_arg_entry.size(); ++i)
510         if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association)
511             ret_val.push_back(cmd_arg_entry[i]);
512     return ret_val;
513 }
514 
515 // Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take
516 // all the argument data into account.  On rare cases where some argument sticks
517 // with certain option sets, this function returns the option set filtered args.
518 void
519 CommandObject::GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask)
520 {
521     int num_args = m_arguments.size();
522     for (int i = 0; i < num_args; ++i)
523     {
524         if (i > 0)
525             str.Printf (" ");
526         CommandArgumentEntry arg_entry =
527             opt_set_mask == LLDB_OPT_SET_ALL ? m_arguments[i]
528                                              : OptSetFiltered(opt_set_mask, m_arguments[i]);
529         int num_alternatives = arg_entry.size();
530 
531         if ((num_alternatives == 2)
532             && IsPairType (arg_entry[0].arg_repetition))
533         {
534             const char *first_name = GetArgumentName (arg_entry[0].arg_type);
535             const char *second_name = GetArgumentName (arg_entry[1].arg_type);
536             switch (arg_entry[0].arg_repetition)
537             {
538                 case eArgRepeatPairPlain:
539                     str.Printf ("<%s> <%s>", first_name, second_name);
540                     break;
541                 case eArgRepeatPairOptional:
542                     str.Printf ("[<%s> <%s>]", first_name, second_name);
543                     break;
544                 case eArgRepeatPairPlus:
545                     str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name);
546                     break;
547                 case eArgRepeatPairStar:
548                     str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name);
549                     break;
550                 case eArgRepeatPairRange:
551                     str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name);
552                     break;
553                 case eArgRepeatPairRangeOptional:
554                     str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name);
555                     break;
556                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
557                 // missing case statement(s).
558                 case eArgRepeatPlain:
559                 case eArgRepeatOptional:
560                 case eArgRepeatPlus:
561                 case eArgRepeatStar:
562                 case eArgRepeatRange:
563                     // These should not be reached, as they should fail the IsPairType test above.
564                     break;
565             }
566         }
567         else
568         {
569             StreamString names;
570             for (int j = 0; j < num_alternatives; ++j)
571             {
572                 if (j > 0)
573                     names.Printf (" | ");
574                 names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type));
575             }
576             switch (arg_entry[0].arg_repetition)
577             {
578                 case eArgRepeatPlain:
579                     str.Printf ("<%s>", names.GetData());
580                     break;
581                 case eArgRepeatPlus:
582                     str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData());
583                     break;
584                 case eArgRepeatStar:
585                     str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData());
586                     break;
587                 case eArgRepeatOptional:
588                     str.Printf ("[<%s>]", names.GetData());
589                     break;
590                 case eArgRepeatRange:
591                     str.Printf ("<%s_1> .. <%s_n>", names.GetData(), names.GetData());
592                     break;
593                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
594                 // missing case statement(s).
595                 case eArgRepeatPairPlain:
596                 case eArgRepeatPairOptional:
597                 case eArgRepeatPairPlus:
598                 case eArgRepeatPairStar:
599                 case eArgRepeatPairRange:
600                 case eArgRepeatPairRangeOptional:
601                     // These should not be hit, as they should pass the IsPairType test above, and control should
602                     // have gone into the other branch of the if statement.
603                     break;
604             }
605         }
606     }
607 }
608 
609 CommandArgumentType
610 CommandObject::LookupArgumentName (const char *arg_name)
611 {
612     CommandArgumentType return_type = eArgTypeLastArg;
613 
614     std::string arg_name_str (arg_name);
615     size_t len = arg_name_str.length();
616     if (arg_name[0] == '<'
617         && arg_name[len-1] == '>')
618         arg_name_str = arg_name_str.substr (1, len-2);
619 
620     const ArgumentTableEntry *table = GetArgumentTable();
621     for (int i = 0; i < eArgTypeLastArg; ++i)
622         if (arg_name_str.compare (table[i].arg_name) == 0)
623             return_type = g_arguments_data[i].arg_type;
624 
625     return return_type;
626 }
627 
628 static const char *
629 RegisterNameHelpTextCallback ()
630 {
631     return "Register names can be specified using the architecture specific names.  "
632     "They can also be specified using generic names.  Not all generic entities have "
633     "registers backing them on all architectures.  When they don't the generic name "
634     "will return an error.\n"
635     "The generic names defined in lldb are:\n"
636     "\n"
637     "pc       - program counter register\n"
638     "ra       - return address register\n"
639     "fp       - frame pointer register\n"
640     "sp       - stack pointer register\n"
641     "flags    - the flags register\n"
642     "arg{1-6} - integer argument passing registers.\n";
643 }
644 
645 static const char *
646 BreakpointIDHelpTextCallback ()
647 {
648     return "Breakpoint ID's consist major and minor numbers;  the major number "
649     "corresponds to the single entity that was created with a 'breakpoint set' "
650     "command; the minor numbers correspond to all the locations that were actually "
651     "found/set based on the major breakpoint.  A full breakpoint ID might look like "
652     "3.14, meaning the 14th location set for the 3rd breakpoint.  You can specify "
653     "all the locations of a breakpoint by just indicating the major breakpoint "
654     "number. A valid breakpoint id consists either of just the major id number, "
655     "or the major number, a dot, and the location number (e.g. 3 or 3.2 could "
656     "both be valid breakpoint ids).";
657 }
658 
659 static const char *
660 BreakpointIDRangeHelpTextCallback ()
661 {
662     return "A 'breakpoint id list' is a manner of specifying multiple breakpoints. "
663     "This can be done  through several mechanisms.  The easiest way is to just "
664     "enter a space-separated list of breakpoint ids.  To specify all the "
665     "breakpoint locations under a major breakpoint, you can use the major "
666     "breakpoint number followed by '.*', eg. '5.*' means all the locations under "
667     "breakpoint 5.  You can also indicate a range of breakpoints by using "
668     "<start-bp-id> - <end-bp-id>.  The start-bp-id and end-bp-id for a range can "
669     "be any valid breakpoint ids.  It is not legal, however, to specify a range "
670     "using specific locations that cross major breakpoint numbers.  I.e. 3.2 - 3.7"
671     " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
672 }
673 
674 static const char *
675 GDBFormatHelpTextCallback ()
676 {
677     return "A GDB format consists of a repeat count, a format letter and a size letter. "
678     "The repeat count is optional and defaults to 1. The format letter is optional "
679     "and defaults to the previous format that was used. The size letter is optional "
680     "and defaults to the previous size that was used.\n"
681     "\n"
682     "Format letters include:\n"
683     "o - octal\n"
684     "x - hexadecimal\n"
685     "d - decimal\n"
686     "u - unsigned decimal\n"
687     "t - binary\n"
688     "f - float\n"
689     "a - address\n"
690     "i - instruction\n"
691     "c - char\n"
692     "s - string\n"
693     "T - OSType\n"
694     "A - float as hex\n"
695     "\n"
696     "Size letters include:\n"
697     "b - 1 byte  (byte)\n"
698     "h - 2 bytes (halfword)\n"
699     "w - 4 bytes (word)\n"
700     "g - 8 bytes (giant)\n"
701     "\n"
702     "Example formats:\n"
703     "32xb - show 32 1 byte hexadecimal integer values\n"
704     "16xh - show 16 2 byte hexadecimal integer values\n"
705     "64   - show 64 2 byte hexadecimal integer values (format and size from the last format)\n"
706     "dw   - show 1 4 byte decimal integer value\n"
707     ;
708 }
709 
710 static const char *
711 FormatHelpTextCallback ()
712 {
713 
714     static char* help_text_ptr = NULL;
715 
716     if (help_text_ptr)
717         return help_text_ptr;
718 
719     StreamString sstr;
720     sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n";
721     for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
722     {
723         if (f != eFormatDefault)
724             sstr.PutChar('\n');
725 
726         char format_char = FormatManager::GetFormatAsFormatChar(f);
727         if (format_char)
728             sstr.Printf("'%c' or ", format_char);
729 
730         sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
731     }
732 
733     sstr.Flush();
734 
735     std::string data = sstr.GetString();
736 
737     help_text_ptr = new char[data.length()+1];
738 
739     data.copy(help_text_ptr, data.length());
740 
741     return help_text_ptr;
742 }
743 
744 static const char *
745 SummaryStringHelpTextCallback()
746 {
747     return
748         "A summary string is a way to extract information from variables in order to present them using a summary.\n"
749         "Summary strings contain static text, variables, scopes and control sequences:\n"
750         "  - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n"
751         "  - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n"
752         "  - 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"
753         "  - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n"
754         "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n"
755         "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"
756         "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"
757         " (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"
758         " ${var.x.y}). You can also use ${*var followed by an expression path and in that case the object referred by the path will be dereferenced before being displayed."
759         " If the object is not a pointer, doing so will cause an error. For additional details on expression paths, you can type 'help expr-path'. \n"
760         "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."
761         "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"
762         " path refers to:\n"
763         "  - 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"
764         " and displayed as an individual variable\n"
765         "  - 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"
766         " 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"
767         "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.\n"
768         "Additionally, a variable can contain an (optional) format code, as in ${var.x.y%code}, where code can be any of the valid formats described in 'help format', or one of the"
769         " special symbols only allowed as part of a variable:\n"
770         "    %V: show the value of the object by default\n"
771         "    %S: show the summary of the object by default\n"
772         "    %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n"
773         "    %L: show the location of the object (memory address or a register name)\n"
774         "    %#: show the number of children of the object\n"
775         "    %T: show the type of the object\n"
776         "Another variable that you can use in summary strings is ${svar . This sequence works exactly like ${var, including the fact that ${*svar is an allowed sequence, but uses"
777         " the object's synthetic children provider instead of the actual objects. For instance, if you are using STL synthetic children providers, the following summary string would"
778         " count the number of actual elements stored in an std::list:\n"
779         "type summary add -s \"${svar%#}\" -x \"std::list<\"";
780 }
781 
782 static const char *
783 ExprPathHelpTextCallback()
784 {
785     return
786     "An expression path is the sequence of symbols that is used in C/C++ to access a member variable of an aggregate object (class).\n"
787     "For instance, given a class:\n"
788     "  class foo {\n"
789     "      int a;\n"
790     "      int b; .\n"
791     "      foo* next;\n"
792     "  };\n"
793     "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n"
794     "Given that aFoo could just be any object of type foo, the string '.next->b' is the expression path, because it can be attached to any foo instance to achieve the effect.\n"
795     "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n"
796     "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n"
797     "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n"
798     "for objects of native types (int, float, char, ...) saying '[n-m]' as an expression path (where n and m are any positive integers, e.g. [3-5]) causes LLDB to extract"
799     " bits n thru m from the value of the variable. If n == m, [n] is also allowed as a shortcut syntax. For arrays and pointers, expression paths can only contain one index"
800     " and the meaning of the operation is the same as the one defined by C/C++ (item extraction). Some commands extend bitfield-like syntax for arrays and pointers with the"
801     " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory).";
802 }
803 
804 void
805 CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType ID, CommandArgumentType IDRange)
806 {
807     CommandArgumentData id_arg;
808     CommandArgumentData id_range_arg;
809 
810     // Create the first variant for the first (and only) argument for this command.
811     id_arg.arg_type = ID;
812     id_arg.arg_repetition = eArgRepeatOptional;
813 
814     // Create the second variant for the first (and only) argument for this command.
815     id_range_arg.arg_type = IDRange;
816     id_range_arg.arg_repetition = eArgRepeatOptional;
817 
818     // The first (and only) argument for this command could be either an id or an id_range.
819     // Push both variants into the entry for the first argument for this command.
820     arg.push_back(id_arg);
821     arg.push_back(id_range_arg);
822 }
823 
824 const char *
825 CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
826 {
827     if (arg_type >=0 && arg_type < eArgTypeLastArg)
828         return g_arguments_data[arg_type].arg_name;
829     return NULL;
830 
831 }
832 
833 const char *
834 CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
835 {
836     if (arg_type >=0 && arg_type < eArgTypeLastArg)
837         return g_arguments_data[arg_type].help_text;
838     return NULL;
839 }
840 
841 bool
842 CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result)
843 {
844     CommandOverrideCallback command_callback = GetOverrideCallback();
845     bool handled = false;
846     Args cmd_args (args_string);
847     if (command_callback)
848     {
849         Args full_args (GetCommandName ());
850         full_args.AppendArguments(cmd_args);
851         handled = command_callback (GetOverrideCallbackBaton(), full_args.GetConstArgumentVector());
852     }
853     if (!handled)
854     {
855         for (size_t i = 0; i < cmd_args.GetArgumentCount();  ++i)
856         {
857             const char *tmp_str = cmd_args.GetArgumentAtIndex (i);
858             if (tmp_str[0] == '`')  // back-quote
859                 cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
860         }
861 
862         if (!CheckFlags(result))
863             return false;
864 
865         if (!ParseOptions (cmd_args, result))
866             return false;
867 
868         // Call the command-specific version of 'Execute', passing it the already processed arguments.
869         handled = DoExecute (cmd_args, result);
870     }
871     return handled;
872 }
873 
874 bool
875 CommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result)
876 {
877     CommandOverrideCallback command_callback = GetOverrideCallback();
878     bool handled = false;
879     if (command_callback)
880     {
881         std::string full_command (GetCommandName ());
882         full_command += ' ';
883         full_command += args_string;
884         const char *argv[2] = { NULL, NULL };
885         argv[0] = full_command.c_str();
886         handled = command_callback (GetOverrideCallbackBaton(), argv);
887     }
888     if (!handled)
889     {
890         if (!CheckFlags(result))
891             return false;
892         else
893             handled = DoExecute (args_string, result);
894     }
895     return handled;
896 }
897 
898 static
899 const char *arch_helper()
900 {
901     static StreamString g_archs_help;
902     if (g_archs_help.Empty())
903     {
904         StringList archs;
905         ArchSpec::AutoComplete(NULL, archs);
906         g_archs_help.Printf("These are the supported architecture names:\n");
907         archs.Join("\n", g_archs_help);
908     }
909     return g_archs_help.GetData();
910 }
911 
912 CommandObject::ArgumentTableEntry
913 CommandObject::g_arguments_data[] =
914 {
915     { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { NULL, false }, "A valid address in the target program's execution space." },
916     { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of an abbreviation (alias) for a debugger command." },
917     { 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.)" },
918     { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." },
919     { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { NULL, false }, "A Boolean value: 'true' or 'false'" },
920     { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, NULL },
921     { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, NULL },
922     { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { NULL, false }, "Number of bytes to use." },
923     { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { NULL, false }, "Then name of a class from the debug information in the program." },
924     { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { NULL, false }, "A debugger command (may be multiple words), without any options or arguments." },
925     { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
926     { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
927     { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
928     { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, NULL },
929     { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { NULL, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
930     { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { NULL, false }, "The name of a file (can include path)." },
931     { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, NULL },
932     { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { NULL, false }, "Index into a thread's list of frames." },
933     { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
934     { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a function." },
935     { eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a function or symbol." },
936     { eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, NULL },
937     { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { NULL, false }, "An index into a list." },
938     { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { NULL, false }, "A source language name." },
939     { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { NULL, false }, "Line number in a source file." },
940     { 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." },
941     { 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)." },
942     { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { NULL, false }, "A C++ method name." },
943     { eArgTypeName, "name", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
944     { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
945     { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { NULL, false }, "The number of lines to use." },
946     { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { NULL, false }, "The number of items per line to display." },
947     { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
948     { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
949     { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { NULL, false }, "A command that is entered as a single line of text." },
950     { eArgTypePath, "path", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
951     { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { NULL, false }, "The process ID number." },
952     { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
953     { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the process." },
954     { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python class." },
955     { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python function." },
956     { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { NULL, false }, "Source code written in Python." },
957     { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the thread queue." },
958     { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, NULL },
959     { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { NULL, false }, "A regular expression." },
960     { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { NULL, false }, "Arguments to be passed to the target program when it starts executing." },
961     { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
962     { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { NULL, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
963     { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { NULL, false }, "The scripting language to be used for script-based commands.  Currently only Python is valid." },
964     { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { NULL, false }, "The word for which you wish to search for information about." },
965     { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { NULL, false }, "An Objective-C selector name." },
966     { 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)." },
967     { 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)." },
968     { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
969     { 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." },
970     { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a shared library." },
971     { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, { NULL, false }, "The name of a source file.." },
972     { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, { NULL, false }, "Specify a sort order when dumping lists." },
973     { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
974     { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, { SummaryStringHelpTextCallback, true }, NULL },
975     { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, { NULL, false }, "Any symbol name (function name, variable, argument, etc.)" },
976     { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { NULL, false }, "Thread ID number." },
977     { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { NULL, false }, "Index into the process' list of threads." },
978     { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { NULL, false }, "The thread's name." },
979     { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
980     { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { NULL, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
981     { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a variable in your program." },
982     { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { NULL, false }, "A value could be anything, depending on where and how it is used." },
983     { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
984     { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { NULL, false }, "No help available for this." },
985     { 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." },
986     { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { NULL, false }, "Watchpoint IDs are positive integers." },
987     { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { NULL, false }, "For example, '1-3' or '1 to 3'." },
988     { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { NULL, false }, "Specify the type for a watchpoint." }
989 };
990 
991 const CommandObject::ArgumentTableEntry*
992 CommandObject::GetArgumentTable ()
993 {
994     // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration
995     assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg);
996     return CommandObject::g_arguments_data;
997 }
998 
999 
1000