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