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     const char *short_help;
381     const char *long_help;
382     const char *syntax_help;
383     std::string options_usage_help;
384 
385 
386     bool found_word = false;
387 
388     short_help = GetHelp();
389     long_help = GetHelpLong();
390     syntax_help = GetSyntax();
391 
392     if (strcasestr (short_help, search_word))
393         found_word = true;
394     else if (strcasestr (long_help, search_word))
395         found_word = true;
396     else if (strcasestr (syntax_help, search_word))
397         found_word = true;
398 
399     if (!found_word
400         && GetOptions() != NULL)
401     {
402         StreamString usage_help;
403         GetOptions()->GenerateOptionUsage (usage_help, this);
404         if (usage_help.GetSize() > 0)
405         {
406             const char *usage_text = usage_help.GetData();
407             if (strcasestr (usage_text, search_word))
408               found_word = true;
409         }
410     }
411 
412     return found_word;
413 }
414 
415 int
416 CommandObject::GetNumArgumentEntries  ()
417 {
418     return m_arguments.size();
419 }
420 
421 CommandObject::CommandArgumentEntry *
422 CommandObject::GetArgumentEntryAtIndex (int idx)
423 {
424     if (idx < m_arguments.size())
425         return &(m_arguments[idx]);
426 
427     return NULL;
428 }
429 
430 CommandObject::ArgumentTableEntry *
431 CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
432 {
433     const ArgumentTableEntry *table = CommandObject::GetArgumentTable();
434 
435     for (int i = 0; i < eArgTypeLastArg; ++i)
436         if (table[i].arg_type == arg_type)
437             return (ArgumentTableEntry *) &(table[i]);
438 
439     return NULL;
440 }
441 
442 void
443 CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
444 {
445     const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
446     ArgumentTableEntry *entry = (ArgumentTableEntry *) &(table[arg_type]);
447 
448     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
449 
450     if (entry->arg_type != arg_type)
451         entry = CommandObject::FindArgumentDataByType (arg_type);
452 
453     if (!entry)
454         return;
455 
456     StreamString name_str;
457     name_str.Printf ("<%s>", entry->arg_name);
458 
459     if (entry->help_function)
460     {
461         const char* help_text = entry->help_function();
462         if (!entry->help_function.self_formatting)
463         {
464             interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,
465                                                  name_str.GetSize());
466         }
467         else
468         {
469             interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text,
470                                        name_str.GetSize());
471         }
472     }
473     else
474         interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
475 }
476 
477 const char *
478 CommandObject::GetArgumentName (CommandArgumentType arg_type)
479 {
480     ArgumentTableEntry *entry = (ArgumentTableEntry *) &(CommandObject::GetArgumentTable()[arg_type]);
481 
482     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
483 
484     if (entry->arg_type != arg_type)
485         entry = CommandObject::FindArgumentDataByType (arg_type);
486 
487     if (entry)
488         return entry->arg_name;
489 
490     StreamString str;
491     str << "Arg name for type (" << arg_type << ") not in arg table!";
492     return str.GetData();
493 }
494 
495 bool
496 CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type)
497 {
498     if ((arg_repeat_type == eArgRepeatPairPlain)
499         ||  (arg_repeat_type == eArgRepeatPairOptional)
500         ||  (arg_repeat_type == eArgRepeatPairPlus)
501         ||  (arg_repeat_type == eArgRepeatPairStar)
502         ||  (arg_repeat_type == eArgRepeatPairRange)
503         ||  (arg_repeat_type == eArgRepeatPairRangeOptional))
504         return true;
505 
506     return false;
507 }
508 
509 static CommandObject::CommandArgumentEntry
510 OptSetFiltered(uint32_t opt_set_mask, CommandObject::CommandArgumentEntry &cmd_arg_entry)
511 {
512     CommandObject::CommandArgumentEntry ret_val;
513     for (unsigned i = 0; i < cmd_arg_entry.size(); ++i)
514         if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association)
515             ret_val.push_back(cmd_arg_entry[i]);
516     return ret_val;
517 }
518 
519 // Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take
520 // all the argument data into account.  On rare cases where some argument sticks
521 // with certain option sets, this function returns the option set filtered args.
522 void
523 CommandObject::GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask)
524 {
525     int num_args = m_arguments.size();
526     for (int i = 0; i < num_args; ++i)
527     {
528         if (i > 0)
529             str.Printf (" ");
530         CommandArgumentEntry arg_entry =
531             opt_set_mask == LLDB_OPT_SET_ALL ? m_arguments[i]
532                                              : OptSetFiltered(opt_set_mask, m_arguments[i]);
533         int num_alternatives = arg_entry.size();
534 
535         if ((num_alternatives == 2)
536             && IsPairType (arg_entry[0].arg_repetition))
537         {
538             const char *first_name = GetArgumentName (arg_entry[0].arg_type);
539             const char *second_name = GetArgumentName (arg_entry[1].arg_type);
540             switch (arg_entry[0].arg_repetition)
541             {
542                 case eArgRepeatPairPlain:
543                     str.Printf ("<%s> <%s>", first_name, second_name);
544                     break;
545                 case eArgRepeatPairOptional:
546                     str.Printf ("[<%s> <%s>]", first_name, second_name);
547                     break;
548                 case eArgRepeatPairPlus:
549                     str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name);
550                     break;
551                 case eArgRepeatPairStar:
552                     str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name);
553                     break;
554                 case eArgRepeatPairRange:
555                     str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name);
556                     break;
557                 case eArgRepeatPairRangeOptional:
558                     str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name);
559                     break;
560                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
561                 // missing case statement(s).
562                 case eArgRepeatPlain:
563                 case eArgRepeatOptional:
564                 case eArgRepeatPlus:
565                 case eArgRepeatStar:
566                 case eArgRepeatRange:
567                     // These should not be reached, as they should fail the IsPairType test above.
568                     break;
569             }
570         }
571         else
572         {
573             StreamString names;
574             for (int j = 0; j < num_alternatives; ++j)
575             {
576                 if (j > 0)
577                     names.Printf (" | ");
578                 names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type));
579             }
580             switch (arg_entry[0].arg_repetition)
581             {
582                 case eArgRepeatPlain:
583                     str.Printf ("<%s>", names.GetData());
584                     break;
585                 case eArgRepeatPlus:
586                     str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData());
587                     break;
588                 case eArgRepeatStar:
589                     str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData());
590                     break;
591                 case eArgRepeatOptional:
592                     str.Printf ("[<%s>]", names.GetData());
593                     break;
594                 case eArgRepeatRange:
595                     str.Printf ("<%s_1> .. <%s_n>", names.GetData(), names.GetData());
596                     break;
597                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
598                 // missing case statement(s).
599                 case eArgRepeatPairPlain:
600                 case eArgRepeatPairOptional:
601                 case eArgRepeatPairPlus:
602                 case eArgRepeatPairStar:
603                 case eArgRepeatPairRange:
604                 case eArgRepeatPairRangeOptional:
605                     // These should not be hit, as they should pass the IsPairType test above, and control should
606                     // have gone into the other branch of the if statement.
607                     break;
608             }
609         }
610     }
611 }
612 
613 CommandArgumentType
614 CommandObject::LookupArgumentName (const char *arg_name)
615 {
616     CommandArgumentType return_type = eArgTypeLastArg;
617 
618     std::string arg_name_str (arg_name);
619     size_t len = arg_name_str.length();
620     if (arg_name[0] == '<'
621         && arg_name[len-1] == '>')
622         arg_name_str = arg_name_str.substr (1, len-2);
623 
624     const ArgumentTableEntry *table = GetArgumentTable();
625     for (int i = 0; i < eArgTypeLastArg; ++i)
626         if (arg_name_str.compare (table[i].arg_name) == 0)
627             return_type = g_arguments_data[i].arg_type;
628 
629     return return_type;
630 }
631 
632 static const char *
633 BreakpointIDHelpTextCallback ()
634 {
635     return "Breakpoint ID's consist major and minor numbers;  the major number "
636     "corresponds to the single entity that was created with a 'breakpoint set' "
637     "command; the minor numbers correspond to all the locations that were actually "
638     "found/set based on the major breakpoint.  A full breakpoint ID might look like "
639     "3.14, meaning the 14th location set for the 3rd breakpoint.  You can specify "
640     "all the locations of a breakpoint by just indicating the major breakpoint "
641     "number. A valid breakpoint id consists either of just the major id number, "
642     "or the major number, a dot, and the location number (e.g. 3 or 3.2 could "
643     "both be valid breakpoint ids).";
644 }
645 
646 static const char *
647 BreakpointIDRangeHelpTextCallback ()
648 {
649     return "A 'breakpoint id list' is a manner of specifying multiple breakpoints. "
650     "This can be done  through several mechanisms.  The easiest way is to just "
651     "enter a space-separated list of breakpoint ids.  To specify all the "
652     "breakpoint locations under a major breakpoint, you can use the major "
653     "breakpoint number followed by '.*', eg. '5.*' means all the locations under "
654     "breakpoint 5.  You can also indicate a range of breakpoints by using "
655     "<start-bp-id> - <end-bp-id>.  The start-bp-id and end-bp-id for a range can "
656     "be any valid breakpoint ids.  It is not legal, however, to specify a range "
657     "using specific locations that cross major breakpoint numbers.  I.e. 3.2 - 3.7"
658     " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
659 }
660 
661 static const char *
662 GDBFormatHelpTextCallback ()
663 {
664     return "A GDB format consists of a repeat count, a format letter and a size letter. "
665     "The repeat count is optional and defaults to 1. The format letter is optional "
666     "and defaults to the previous format that was used. The size letter is optional "
667     "and defaults to the previous size that was used.\n"
668     "\n"
669     "Format letters include:\n"
670     "o - octal\n"
671     "x - hexadecimal\n"
672     "d - decimal\n"
673     "u - unsigned decimal\n"
674     "t - binary\n"
675     "f - float\n"
676     "a - address\n"
677     "i - instruction\n"
678     "c - char\n"
679     "s - string\n"
680     "T - OSType\n"
681     "A - float as hex\n"
682     "\n"
683     "Size letters include:\n"
684     "b - 1 byte  (byte)\n"
685     "h - 2 bytes (halfword)\n"
686     "w - 4 bytes (word)\n"
687     "g - 8 bytes (giant)\n"
688     "\n"
689     "Example formats:\n"
690     "32xb - show 32 1 byte hexadecimal integer values\n"
691     "16xh - show 16 2 byte hexadecimal integer values\n"
692     "64   - show 64 2 byte hexadecimal integer values (format and size from the last format)\n"
693     "dw   - show 1 4 byte decimal integer value\n"
694     ;
695 }
696 
697 static const char *
698 FormatHelpTextCallback ()
699 {
700 
701     static char* help_text_ptr = NULL;
702 
703     if (help_text_ptr)
704         return help_text_ptr;
705 
706     StreamString sstr;
707     sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n";
708     for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
709     {
710         if (f != eFormatDefault)
711             sstr.PutChar('\n');
712 
713         char format_char = FormatManager::GetFormatAsFormatChar(f);
714         if (format_char)
715             sstr.Printf("'%c' or ", format_char);
716 
717         sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
718     }
719 
720     sstr.Flush();
721 
722     std::string data = sstr.GetString();
723 
724     help_text_ptr = new char[data.length()+1];
725 
726     data.copy(help_text_ptr, data.length());
727 
728     return help_text_ptr;
729 }
730 
731 static const char *
732 SummaryStringHelpTextCallback()
733 {
734     return
735         "A summary string is a way to extract information from variables in order to present them using a summary.\n"
736         "Summary strings contain static text, variables, scopes and control sequences:\n"
737         "  - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n"
738         "  - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n"
739         "  - 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"
740         "  - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n"
741         "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n"
742         "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"
743         "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"
744         " (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"
745         " ${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."
746         " 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"
747         "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."
748         "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"
749         " path refers to:\n"
750         "  - 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"
751         " and displayed as an individual variable\n"
752         "  - 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"
753         " 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"
754         "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"
755         "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"
756         " special symbols only allowed as part of a variable:\n"
757         "    %V: show the value of the object by default\n"
758         "    %S: show the summary of the object by default\n"
759         "    %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n"
760         "    %L: show the location of the object (memory address or a register name)\n"
761         "    %#: show the number of children of the object\n"
762         "    %T: show the type of the object\n"
763         "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"
764         " 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"
765         " count the number of actual elements stored in an std::list:\n"
766         "type summary add -s \"${svar%#}\" -x \"std::list<\"";
767 }
768 
769 static const char *
770 ExprPathHelpTextCallback()
771 {
772     return
773     "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"
774     "For instance, given a class:\n"
775     "  class foo {\n"
776     "      int a;\n"
777     "      int b; .\n"
778     "      foo* next;\n"
779     "  };\n"
780     "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n"
781     "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"
782     "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n"
783     "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n"
784     "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n"
785     "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"
786     " 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"
787     " 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"
788     " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory).";
789 }
790 
791 void
792 CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType ID, CommandArgumentType IDRange)
793 {
794     CommandArgumentData id_arg;
795     CommandArgumentData id_range_arg;
796 
797     // Create the first variant for the first (and only) argument for this command.
798     id_arg.arg_type = ID;
799     id_arg.arg_repetition = eArgRepeatOptional;
800 
801     // Create the second variant for the first (and only) argument for this command.
802     id_range_arg.arg_type = IDRange;
803     id_range_arg.arg_repetition = eArgRepeatOptional;
804 
805     // The first (and only) argument for this command could be either an id or an id_range.
806     // Push both variants into the entry for the first argument for this command.
807     arg.push_back(id_arg);
808     arg.push_back(id_range_arg);
809 }
810 
811 const char *
812 CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
813 {
814     if (arg_type >=0 && arg_type < eArgTypeLastArg)
815         return g_arguments_data[arg_type].arg_name;
816     return NULL;
817 
818 }
819 
820 const char *
821 CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
822 {
823     if (arg_type >=0 && arg_type < eArgTypeLastArg)
824         return g_arguments_data[arg_type].help_text;
825     return NULL;
826 }
827 
828 bool
829 CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result)
830 {
831     CommandOverrideCallback command_callback = GetOverrideCallback();
832     bool handled = false;
833     Args cmd_args (args_string);
834     if (command_callback)
835     {
836         Args full_args (GetCommandName ());
837         full_args.AppendArguments(cmd_args);
838         handled = command_callback (GetOverrideCallbackBaton(), full_args.GetConstArgumentVector());
839     }
840     if (!handled)
841     {
842         for (size_t i = 0; i < cmd_args.GetArgumentCount();  ++i)
843         {
844             const char *tmp_str = cmd_args.GetArgumentAtIndex (i);
845             if (tmp_str[0] == '`')  // back-quote
846                 cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
847         }
848 
849         if (!CheckFlags(result))
850             return false;
851 
852         if (!ParseOptions (cmd_args, result))
853             return false;
854 
855         // Call the command-specific version of 'Execute', passing it the already processed arguments.
856         handled = DoExecute (cmd_args, result);
857     }
858     return handled;
859 }
860 
861 bool
862 CommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result)
863 {
864     CommandOverrideCallback command_callback = GetOverrideCallback();
865     bool handled = false;
866     if (command_callback)
867     {
868         std::string full_command (GetCommandName ());
869         full_command += ' ';
870         full_command += args_string;
871         const char *argv[2] = { NULL, NULL };
872         argv[0] = full_command.c_str();
873         handled = command_callback (GetOverrideCallbackBaton(), argv);
874     }
875     if (!handled)
876     {
877         if (!CheckFlags(result))
878             return false;
879         else
880             handled = DoExecute (args_string, result);
881     }
882     return handled;
883 }
884 
885 static
886 const char *arch_helper()
887 {
888     static StreamString g_archs_help;
889     if (g_archs_help.Empty())
890     {
891         StringList archs;
892         ArchSpec::AutoComplete(NULL, archs);
893         g_archs_help.Printf("These are the supported architecture names:\n");
894         archs.Join("\n", g_archs_help);
895     }
896     return g_archs_help.GetData();
897 }
898 
899 CommandObject::ArgumentTableEntry
900 CommandObject::g_arguments_data[] =
901 {
902     { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { NULL, false }, "A valid address in the target program's execution space." },
903     { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of an abbreviation (alias) for a debugger command." },
904     { 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.)" },
905     { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." },
906     { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { NULL, false }, "A Boolean value: 'true' or 'false'" },
907     { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, NULL },
908     { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, NULL },
909     { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { NULL, false }, "Number of bytes to use." },
910     { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { NULL, false }, "Then name of a class from the debug information in the program." },
911     { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { NULL, false }, "A debugger command (may be multiple words), without any options or arguments." },
912     { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
913     { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
914     { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
915     { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, NULL },
916     { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { NULL, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
917     { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { NULL, false }, "The name of a file (can include path)." },
918     { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, NULL },
919     { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { NULL, false }, "Index into a thread's list of frames." },
920     { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
921     { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a function." },
922     { eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, NULL },
923     { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { NULL, false }, "An index into a list." },
924     { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { NULL, false }, "A source language name." },
925     { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { NULL, false }, "Line number in a source file." },
926     { 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." },
927     { 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)." },
928     { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { NULL, false }, "A C++ method name." },
929     { eArgTypeName, "name", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
930     { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
931     { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { NULL, false }, "The number of lines to use." },
932     { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { NULL, false }, "The number of items per line to display." },
933     { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
934     { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
935     { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { NULL, false }, "A command that is entered as a single line of text." },
936     { eArgTypePath, "path", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
937     { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { NULL, false }, "The process ID number." },
938     { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
939     { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the process." },
940     { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python class." },
941     { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a Python function." },
942     { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { NULL, false }, "Source code written in Python." },
943     { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of the thread queue." },
944     { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { NULL, false }, "A register name." },
945     { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { NULL, false }, "A regular expression." },
946     { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { NULL, false }, "Arguments to be passed to the target program when it starts executing." },
947     { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
948     { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { NULL, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
949     { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { NULL, false }, "The scripting language to be used for script-based commands.  Currently only Python is valid." },
950     { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { NULL, false }, "The word for which you wish to search for information about." },
951     { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { NULL, false }, "An Objective-C selector name." },
952     { 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)." },
953     { 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)." },
954     { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
955     { 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." },
956     { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a shared library." },
957     { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, { NULL, false }, "The name of a source file.." },
958     { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, { NULL, false }, "Specify a sort order when dumping lists." },
959     { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
960     { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, { SummaryStringHelpTextCallback, true }, NULL },
961     { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, { NULL, false }, "Any symbol name (function name, variable, argument, etc.)" },
962     { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { NULL, false }, "Thread ID number." },
963     { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { NULL, false }, "Index into the process' list of threads." },
964     { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { NULL, false }, "The thread's name." },
965     { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
966     { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { NULL, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
967     { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a variable in your program." },
968     { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { NULL, false }, "A value could be anything, depending on where and how it is used." },
969     { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
970     { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { NULL, false }, "No help available for this." },
971     { 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." },
972     { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { NULL, false }, "Watchpoint IDs are positive integers." },
973     { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { NULL, false }, "For example, '1-3' or '1 to 3'." },
974     { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { NULL, false }, "Specify the type for a watchpoint." }
975 };
976 
977 const CommandObject::ArgumentTableEntry*
978 CommandObject::GetArgumentTable ()
979 {
980     // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration
981     assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg);
982     return CommandObject::g_arguments_data;
983 }
984 
985 
986