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 <sstream>
14 #include <map>
15 
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/DataFormatters/FormatManager.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/Target.h"
30 
31 #include "lldb/Interpreter/CommandInterpreter.h"
32 #include "lldb/Interpreter/CommandReturnObject.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 ? 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_deprecated_command_override_callback (nullptr),
58     m_command_override_callback (nullptr),
59     m_command_override_baton (nullptr)
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() != nullptr)
91             syntax_str.Printf (" <cmd-options>");
92         if (m_arguments.size() > 0)
93         {
94             syntax_str.Printf (" ");
95             if (WantsRawCommandString() && GetOptions() && GetOptions()->NumCommandOptions())
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::GetCommandName ()
107 {
108     return m_cmd_name.c_str();
109 }
110 
111 void
112 CommandObject::SetCommandName (const char *name)
113 {
114     m_cmd_name = name;
115 }
116 
117 void
118 CommandObject::SetHelp (const char *cstr)
119 {
120     m_cmd_help_short = cstr;
121 }
122 
123 void
124 CommandObject::SetHelp (std::string str)
125 {
126     m_cmd_help_short = str;
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 nullptr;
153 }
154 
155 bool
156 CommandObject::ParseOptions
157 (
158     Args& args,
159     CommandReturnObject &result
160 )
161 {
162     // See if the subclass has options?
163     Options *options = GetOptions();
164     if (options != nullptr)
165     {
166         Error error;
167         options->NotifyOptionParsingStarting();
168 
169         // ParseOptions calls getopt_long_only, which always skips the zero'th item in the array and starts at position 1,
170         // so we need to push a dummy value into position zero.
171         args.Unshift("dummy_string");
172         error = args.ParseOptions (*options);
173 
174         // The "dummy_string" will have already been removed by ParseOptions,
175         // so no need to remove it.
176 
177         if (error.Success())
178             error = options->NotifyOptionParsingFinished();
179 
180         if (error.Success())
181         {
182             if (options->VerifyOptions (result))
183                 return true;
184         }
185         else
186         {
187             const char *error_cstr = error.AsCString();
188             if (error_cstr)
189             {
190                 // We got an error string, lets use that
191                 result.AppendError(error_cstr);
192             }
193             else
194             {
195                 // No error string, output the usage information into result
196                 options->GenerateOptionUsage (result.GetErrorStream(), this);
197             }
198         }
199         result.SetStatus (eReturnStatusFailed);
200         return false;
201     }
202     return true;
203 }
204 
205 
206 
207 bool
208 CommandObject::CheckRequirements (CommandReturnObject &result)
209 {
210 #ifdef LLDB_CONFIGURATION_DEBUG
211     // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx
212     // has shared pointers to the target, process, thread and frame and we don't
213     // want any CommandObject instances to keep any of these objects around
214     // longer than for a single command. Every command should call
215     // CommandObject::Cleanup() after it has completed
216     assert (m_exe_ctx.GetTargetPtr() == NULL);
217     assert (m_exe_ctx.GetProcessPtr() == NULL);
218     assert (m_exe_ctx.GetThreadPtr() == NULL);
219     assert (m_exe_ctx.GetFramePtr() == NULL);
220 #endif
221 
222     // Lock down the interpreter's execution context prior to running the
223     // command so we guarantee the selected target, process, thread and frame
224     // can't go away during the execution
225     m_exe_ctx = m_interpreter.GetExecutionContext();
226 
227     const uint32_t flags = GetFlags().Get();
228     if (flags & (eCommandRequiresTarget   |
229                  eCommandRequiresProcess  |
230                  eCommandRequiresThread   |
231                  eCommandRequiresFrame    |
232                  eCommandTryTargetAPILock ))
233     {
234 
235         if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope())
236         {
237             result.AppendError (GetInvalidTargetDescription());
238             return false;
239         }
240 
241         if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope())
242         {
243             if (!m_exe_ctx.HasTargetScope())
244                 result.AppendError (GetInvalidTargetDescription());
245             else
246                 result.AppendError (GetInvalidProcessDescription());
247             return false;
248         }
249 
250         if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope())
251         {
252             if (!m_exe_ctx.HasTargetScope())
253                 result.AppendError (GetInvalidTargetDescription());
254             else if (!m_exe_ctx.HasProcessScope())
255                 result.AppendError (GetInvalidProcessDescription());
256             else
257                 result.AppendError (GetInvalidThreadDescription());
258             return false;
259         }
260 
261         if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope())
262         {
263             if (!m_exe_ctx.HasTargetScope())
264                 result.AppendError (GetInvalidTargetDescription());
265             else if (!m_exe_ctx.HasProcessScope())
266                 result.AppendError (GetInvalidProcessDescription());
267             else if (!m_exe_ctx.HasThreadScope())
268                 result.AppendError (GetInvalidThreadDescription());
269             else
270                 result.AppendError (GetInvalidFrameDescription());
271             return false;
272         }
273 
274         if ((flags & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
275         {
276             result.AppendError (GetInvalidRegContextDescription());
277             return false;
278         }
279 
280         if (flags & eCommandTryTargetAPILock)
281         {
282             Target *target = m_exe_ctx.GetTargetPtr();
283             if (target)
284                 m_api_locker.Lock (target->GetAPIMutex());
285         }
286     }
287 
288     if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused))
289     {
290         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
291         if (process == nullptr)
292         {
293             // A process that is not running is considered paused.
294             if (GetFlags().Test(eCommandProcessMustBeLaunched))
295             {
296                 result.AppendError ("Process must exist.");
297                 result.SetStatus (eReturnStatusFailed);
298                 return false;
299             }
300         }
301         else
302         {
303             StateType state = process->GetState();
304             switch (state)
305             {
306             case eStateInvalid:
307             case eStateSuspended:
308             case eStateCrashed:
309             case eStateStopped:
310                 break;
311 
312             case eStateConnected:
313             case eStateAttaching:
314             case eStateLaunching:
315             case eStateDetached:
316             case eStateExited:
317             case eStateUnloaded:
318                 if (GetFlags().Test(eCommandProcessMustBeLaunched))
319                 {
320                     result.AppendError ("Process must be launched.");
321                     result.SetStatus (eReturnStatusFailed);
322                     return false;
323                 }
324                 break;
325 
326             case eStateRunning:
327             case eStateStepping:
328                 if (GetFlags().Test(eCommandProcessMustBePaused))
329                 {
330                     result.AppendError ("Process is running.  Use 'process interrupt' to pause execution.");
331                     result.SetStatus (eReturnStatusFailed);
332                     return false;
333                 }
334             }
335         }
336     }
337     return true;
338 }
339 
340 void
341 CommandObject::Cleanup ()
342 {
343     m_exe_ctx.Clear();
344     m_api_locker.Unlock();
345 }
346 
347 
348 class CommandDictCommandPartialMatch
349 {
350     public:
351         CommandDictCommandPartialMatch (const char *match_str)
352         {
353             m_match_str = match_str;
354         }
355         bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const
356         {
357             // A NULL or empty string matches everything.
358             if (m_match_str == nullptr || *m_match_str == '\0')
359                 return true;
360 
361             return map_element.first.find (m_match_str, 0) == 0;
362         }
363 
364     private:
365         const char *m_match_str;
366 };
367 
368 int
369 CommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str,
370                                               StringList &matches)
371 {
372     int number_added = 0;
373     CommandDictCommandPartialMatch matcher(cmd_str);
374 
375     CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher);
376 
377     while (matching_cmds != in_map.end())
378     {
379         ++number_added;
380         matches.AppendString((*matching_cmds).first.c_str());
381         matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);;
382     }
383     return number_added;
384 }
385 
386 int
387 CommandObject::HandleCompletion
388 (
389     Args &input,
390     int &cursor_index,
391     int &cursor_char_position,
392     int match_start_point,
393     int max_return_elements,
394     bool &word_complete,
395     StringList &matches
396 )
397 {
398     // Default implmentation of WantsCompletion() is !WantsRawCommandString().
399     // Subclasses who want raw command string but desire, for example,
400     // argument completion should override WantsCompletion() to return true,
401     // instead.
402     if (WantsRawCommandString() && !WantsCompletion())
403     {
404         // FIXME: Abstract telling the completion to insert the completion character.
405         matches.Clear();
406         return -1;
407     }
408     else
409     {
410         // Can we do anything generic with the options?
411         Options *cur_options = GetOptions();
412         CommandReturnObject result;
413         OptionElementVector opt_element_vector;
414 
415         if (cur_options != nullptr)
416         {
417             // Re-insert the dummy command name string which will have been
418             // stripped off:
419             input.Unshift ("dummy-string");
420             cursor_index++;
421 
422 
423             // I stick an element on the end of the input, because if the last element is
424             // option that requires an argument, getopt_long_only will freak out.
425 
426             input.AppendArgument ("<FAKE-VALUE>");
427 
428             input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index);
429 
430             input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1);
431 
432             bool handled_by_options;
433             handled_by_options = cur_options->HandleOptionCompletion (input,
434                                                                       opt_element_vector,
435                                                                       cursor_index,
436                                                                       cursor_char_position,
437                                                                       match_start_point,
438                                                                       max_return_elements,
439                                                                       word_complete,
440                                                                       matches);
441             if (handled_by_options)
442                 return matches.GetSize();
443         }
444 
445         // If we got here, the last word is not an option or an option argument.
446         return HandleArgumentCompletion (input,
447                                          cursor_index,
448                                          cursor_char_position,
449                                          opt_element_vector,
450                                          match_start_point,
451                                          max_return_elements,
452                                          word_complete,
453                                          matches);
454     }
455 }
456 
457 bool
458 CommandObject::HelpTextContainsWord (const char *search_word)
459 {
460     std::string options_usage_help;
461 
462     bool found_word = false;
463 
464     const char *short_help = GetHelp();
465     const char *long_help = GetHelpLong();
466     const char *syntax_help = GetSyntax();
467 
468     if (short_help && strcasestr (short_help, search_word))
469         found_word = true;
470     else if (long_help && strcasestr (long_help, search_word))
471         found_word = true;
472     else if (syntax_help && strcasestr (syntax_help, search_word))
473         found_word = true;
474 
475     if (!found_word
476         && GetOptions() != nullptr)
477     {
478         StreamString usage_help;
479         GetOptions()->GenerateOptionUsage (usage_help, this);
480         if (usage_help.GetSize() > 0)
481         {
482             const char *usage_text = usage_help.GetData();
483             if (strcasestr (usage_text, search_word))
484               found_word = true;
485         }
486     }
487 
488     return found_word;
489 }
490 
491 int
492 CommandObject::GetNumArgumentEntries  ()
493 {
494     return m_arguments.size();
495 }
496 
497 CommandObject::CommandArgumentEntry *
498 CommandObject::GetArgumentEntryAtIndex (int idx)
499 {
500     if (static_cast<size_t>(idx) < m_arguments.size())
501         return &(m_arguments[idx]);
502 
503     return nullptr;
504 }
505 
506 const CommandObject::ArgumentTableEntry *
507 CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
508 {
509     const ArgumentTableEntry *table = CommandObject::GetArgumentTable();
510 
511     for (int i = 0; i < eArgTypeLastArg; ++i)
512         if (table[i].arg_type == arg_type)
513             return &(table[i]);
514 
515     return nullptr;
516 }
517 
518 void
519 CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
520 {
521     const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
522     const ArgumentTableEntry *entry = &(table[arg_type]);
523 
524     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
525 
526     if (entry->arg_type != arg_type)
527         entry = CommandObject::FindArgumentDataByType (arg_type);
528 
529     if (!entry)
530         return;
531 
532     StreamString name_str;
533     name_str.Printf ("<%s>", entry->arg_name);
534 
535     if (entry->help_function)
536     {
537         const char* help_text = entry->help_function();
538         if (!entry->help_function.self_formatting)
539         {
540             interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,
541                                                  name_str.GetSize());
542         }
543         else
544         {
545             interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text,
546                                        name_str.GetSize());
547         }
548     }
549     else
550         interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
551 }
552 
553 const char *
554 CommandObject::GetArgumentName (CommandArgumentType arg_type)
555 {
556     const ArgumentTableEntry *entry = &(CommandObject::GetArgumentTable()[arg_type]);
557 
558     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
559 
560     if (entry->arg_type != arg_type)
561         entry = CommandObject::FindArgumentDataByType (arg_type);
562 
563     if (entry)
564         return entry->arg_name;
565 
566     StreamString str;
567     str << "Arg name for type (" << arg_type << ") not in arg table!";
568     return str.GetData();
569 }
570 
571 bool
572 CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type)
573 {
574     if ((arg_repeat_type == eArgRepeatPairPlain)
575         ||  (arg_repeat_type == eArgRepeatPairOptional)
576         ||  (arg_repeat_type == eArgRepeatPairPlus)
577         ||  (arg_repeat_type == eArgRepeatPairStar)
578         ||  (arg_repeat_type == eArgRepeatPairRange)
579         ||  (arg_repeat_type == eArgRepeatPairRangeOptional))
580         return true;
581 
582     return false;
583 }
584 
585 static CommandObject::CommandArgumentEntry
586 OptSetFiltered(uint32_t opt_set_mask, CommandObject::CommandArgumentEntry &cmd_arg_entry)
587 {
588     CommandObject::CommandArgumentEntry ret_val;
589     for (unsigned i = 0; i < cmd_arg_entry.size(); ++i)
590         if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association)
591             ret_val.push_back(cmd_arg_entry[i]);
592     return ret_val;
593 }
594 
595 // Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take
596 // all the argument data into account.  On rare cases where some argument sticks
597 // with certain option sets, this function returns the option set filtered args.
598 void
599 CommandObject::GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask)
600 {
601     int num_args = m_arguments.size();
602     for (int i = 0; i < num_args; ++i)
603     {
604         if (i > 0)
605             str.Printf (" ");
606         CommandArgumentEntry arg_entry =
607             opt_set_mask == LLDB_OPT_SET_ALL ? m_arguments[i]
608                                              : OptSetFiltered(opt_set_mask, m_arguments[i]);
609         int num_alternatives = arg_entry.size();
610 
611         if ((num_alternatives == 2)
612             && IsPairType (arg_entry[0].arg_repetition))
613         {
614             const char *first_name = GetArgumentName (arg_entry[0].arg_type);
615             const char *second_name = GetArgumentName (arg_entry[1].arg_type);
616             switch (arg_entry[0].arg_repetition)
617             {
618                 case eArgRepeatPairPlain:
619                     str.Printf ("<%s> <%s>", first_name, second_name);
620                     break;
621                 case eArgRepeatPairOptional:
622                     str.Printf ("[<%s> <%s>]", first_name, second_name);
623                     break;
624                 case eArgRepeatPairPlus:
625                     str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name);
626                     break;
627                 case eArgRepeatPairStar:
628                     str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name);
629                     break;
630                 case eArgRepeatPairRange:
631                     str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name);
632                     break;
633                 case eArgRepeatPairRangeOptional:
634                     str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name);
635                     break;
636                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
637                 // missing case statement(s).
638                 case eArgRepeatPlain:
639                 case eArgRepeatOptional:
640                 case eArgRepeatPlus:
641                 case eArgRepeatStar:
642                 case eArgRepeatRange:
643                     // These should not be reached, as they should fail the IsPairType test above.
644                     break;
645             }
646         }
647         else
648         {
649             StreamString names;
650             for (int j = 0; j < num_alternatives; ++j)
651             {
652                 if (j > 0)
653                     names.Printf (" | ");
654                 names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type));
655             }
656             switch (arg_entry[0].arg_repetition)
657             {
658                 case eArgRepeatPlain:
659                     str.Printf ("<%s>", names.GetData());
660                     break;
661                 case eArgRepeatPlus:
662                     str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData());
663                     break;
664                 case eArgRepeatStar:
665                     str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData());
666                     break;
667                 case eArgRepeatOptional:
668                     str.Printf ("[<%s>]", names.GetData());
669                     break;
670                 case eArgRepeatRange:
671                     str.Printf ("<%s_1> .. <%s_n>", names.GetData(), names.GetData());
672                     break;
673                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
674                 // missing case statement(s).
675                 case eArgRepeatPairPlain:
676                 case eArgRepeatPairOptional:
677                 case eArgRepeatPairPlus:
678                 case eArgRepeatPairStar:
679                 case eArgRepeatPairRange:
680                 case eArgRepeatPairRangeOptional:
681                     // These should not be hit, as they should pass the IsPairType test above, and control should
682                     // have gone into the other branch of the if statement.
683                     break;
684             }
685         }
686     }
687 }
688 
689 CommandArgumentType
690 CommandObject::LookupArgumentName (const char *arg_name)
691 {
692     CommandArgumentType return_type = eArgTypeLastArg;
693 
694     std::string arg_name_str (arg_name);
695     size_t len = arg_name_str.length();
696     if (arg_name[0] == '<'
697         && arg_name[len-1] == '>')
698         arg_name_str = arg_name_str.substr (1, len-2);
699 
700     const ArgumentTableEntry *table = GetArgumentTable();
701     for (int i = 0; i < eArgTypeLastArg; ++i)
702         if (arg_name_str.compare (table[i].arg_name) == 0)
703             return_type = g_arguments_data[i].arg_type;
704 
705     return return_type;
706 }
707 
708 static const char *
709 RegisterNameHelpTextCallback ()
710 {
711     return "Register names can be specified using the architecture specific names.  "
712     "They can also be specified using generic names.  Not all generic entities have "
713     "registers backing them on all architectures.  When they don't the generic name "
714     "will return an error.\n"
715     "The generic names defined in lldb are:\n"
716     "\n"
717     "pc       - program counter register\n"
718     "ra       - return address register\n"
719     "fp       - frame pointer register\n"
720     "sp       - stack pointer register\n"
721     "flags    - the flags register\n"
722     "arg{1-6} - integer argument passing registers.\n";
723 }
724 
725 static const char *
726 BreakpointIDHelpTextCallback ()
727 {
728     return "Breakpoint ID's consist major and minor numbers;  the major number "
729     "corresponds to the single entity that was created with a 'breakpoint set' "
730     "command; the minor numbers correspond to all the locations that were actually "
731     "found/set based on the major breakpoint.  A full breakpoint ID might look like "
732     "3.14, meaning the 14th location set for the 3rd breakpoint.  You can specify "
733     "all the locations of a breakpoint by just indicating the major breakpoint "
734     "number. A valid breakpoint id consists either of just the major id number, "
735     "or the major number, a dot, and the location number (e.g. 3 or 3.2 could "
736     "both be valid breakpoint ids).";
737 }
738 
739 static const char *
740 BreakpointIDRangeHelpTextCallback ()
741 {
742     return "A 'breakpoint id list' is a manner of specifying multiple breakpoints. "
743     "This can be done  through several mechanisms.  The easiest way is to just "
744     "enter a space-separated list of breakpoint ids.  To specify all the "
745     "breakpoint locations under a major breakpoint, you can use the major "
746     "breakpoint number followed by '.*', eg. '5.*' means all the locations under "
747     "breakpoint 5.  You can also indicate a range of breakpoints by using "
748     "<start-bp-id> - <end-bp-id>.  The start-bp-id and end-bp-id for a range can "
749     "be any valid breakpoint ids.  It is not legal, however, to specify a range "
750     "using specific locations that cross major breakpoint numbers.  I.e. 3.2 - 3.7"
751     " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
752 }
753 
754 static const char *
755 BreakpointNameHelpTextCallback ()
756 {
757     return "A name that can be added to a breakpoint when it is created, or later "
758     "on with the \"breakpoint name add\" command.  "
759     "Breakpoint names can be used to specify breakpoints in all the places breakpoint ID's "
760     "and breakpoint ID ranges can be used.  As such they provide a convenient way to group breakpoints, "
761     "and to operate on breakpoints you create without having to track the breakpoint number.  "
762     "Note, the attributes you set when using a breakpoint name in a breakpoint command don't "
763     "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that name.  Future breakpoints "
764     "tagged with that name will not pick up the attributes previously given using that name.  "
765     "In order to distinguish breakpoint names from breakpoint ID's and ranges, "
766     "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\".  "
767     "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations.";
768 }
769 
770 static const char *
771 GDBFormatHelpTextCallback ()
772 {
773     return "A GDB format consists of a repeat count, a format letter and a size letter. "
774     "The repeat count is optional and defaults to 1. The format letter is optional "
775     "and defaults to the previous format that was used. The size letter is optional "
776     "and defaults to the previous size that was used.\n"
777     "\n"
778     "Format letters include:\n"
779     "o - octal\n"
780     "x - hexadecimal\n"
781     "d - decimal\n"
782     "u - unsigned decimal\n"
783     "t - binary\n"
784     "f - float\n"
785     "a - address\n"
786     "i - instruction\n"
787     "c - char\n"
788     "s - string\n"
789     "T - OSType\n"
790     "A - float as hex\n"
791     "\n"
792     "Size letters include:\n"
793     "b - 1 byte  (byte)\n"
794     "h - 2 bytes (halfword)\n"
795     "w - 4 bytes (word)\n"
796     "g - 8 bytes (giant)\n"
797     "\n"
798     "Example formats:\n"
799     "32xb - show 32 1 byte hexadecimal integer values\n"
800     "16xh - show 16 2 byte hexadecimal integer values\n"
801     "64   - show 64 2 byte hexadecimal integer values (format and size from the last format)\n"
802     "dw   - show 1 4 byte decimal integer value\n"
803     ;
804 }
805 
806 static const char *
807 FormatHelpTextCallback ()
808 {
809 
810     static char* help_text_ptr = nullptr;
811 
812     if (help_text_ptr)
813         return help_text_ptr;
814 
815     StreamString sstr;
816     sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n";
817     for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
818     {
819         if (f != eFormatDefault)
820             sstr.PutChar('\n');
821 
822         char format_char = FormatManager::GetFormatAsFormatChar(f);
823         if (format_char)
824             sstr.Printf("'%c' or ", format_char);
825 
826         sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
827     }
828 
829     sstr.Flush();
830 
831     std::string data = sstr.GetString();
832 
833     help_text_ptr = new char[data.length()+1];
834 
835     data.copy(help_text_ptr, data.length());
836 
837     return help_text_ptr;
838 }
839 
840 static const char *
841 LanguageTypeHelpTextCallback ()
842 {
843     static char* help_text_ptr = nullptr;
844 
845     if (help_text_ptr)
846         return help_text_ptr;
847 
848     StreamString sstr;
849     sstr << "One of the following languages:\n";
850 
851     LanguageRuntime::PrintAllLanguages(sstr, "  ", "\n");
852 
853     sstr.Flush();
854 
855     std::string data = sstr.GetString();
856 
857     help_text_ptr = new char[data.length()+1];
858 
859     data.copy(help_text_ptr, data.length());
860 
861     return help_text_ptr;
862 }
863 
864 static const char *
865 SummaryStringHelpTextCallback()
866 {
867     return
868         "A summary string is a way to extract information from variables in order to present them using a summary.\n"
869         "Summary strings contain static text, variables, scopes and control sequences:\n"
870         "  - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n"
871         "  - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n"
872         "  - 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"
873         "  - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n"
874         "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n"
875         "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"
876         "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"
877         " (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"
878         " ${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."
879         " 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"
880         "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."
881         "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"
882         " path refers to:\n"
883         "  - 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"
884         " and displayed as an individual variable\n"
885         "  - 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"
886         " 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"
887         "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"
888         "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"
889         " special symbols only allowed as part of a variable:\n"
890         "    %V: show the value of the object by default\n"
891         "    %S: show the summary of the object by default\n"
892         "    %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n"
893         "    %L: show the location of the object (memory address or a register name)\n"
894         "    %#: show the number of children of the object\n"
895         "    %T: show the type of the object\n"
896         "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"
897         " 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"
898         " count the number of actual elements stored in an std::list:\n"
899         "type summary add -s \"${svar%#}\" -x \"std::list<\"";
900 }
901 
902 static const char *
903 ExprPathHelpTextCallback()
904 {
905     return
906     "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"
907     "For instance, given a class:\n"
908     "  class foo {\n"
909     "      int a;\n"
910     "      int b; .\n"
911     "      foo* next;\n"
912     "  };\n"
913     "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n"
914     "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"
915     "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n"
916     "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n"
917     "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n"
918     "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"
919     " 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"
920     " 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"
921     " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory).";
922 }
923 
924 void
925 CommandObject::FormatLongHelpText (Stream &output_strm, const char *long_help)
926 {
927     CommandInterpreter& interpreter = GetCommandInterpreter();
928     std::stringstream lineStream (long_help);
929     std::string line;
930     while (std::getline (lineStream, line)) {
931         if (line.empty()) {
932             output_strm << "\n";
933             continue;
934         }
935         size_t result = line.find_first_not_of (" \t");
936         if (result == std::string::npos) {
937             result = 0;
938         }
939         std::string whitespace_prefix = line.substr (0, result);
940         std::string remainder = line.substr (result);
941         interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), remainder.c_str());
942     }
943 }
944 
945 void
946 CommandObject::GenerateHelpText (CommandReturnObject &result)
947 {
948     GenerateHelpText(result.GetOutputStream());
949 
950     result.SetStatus (eReturnStatusSuccessFinishNoResult);
951 }
952 
953 void
954 CommandObject::GenerateHelpText (Stream &output_strm)
955 {
956     CommandInterpreter& interpreter = GetCommandInterpreter();
957     if (GetOptions() != nullptr)
958     {
959         if (WantsRawCommandString())
960         {
961             std::string help_text (GetHelp());
962             help_text.append ("  This command takes 'raw' input (no need to quote stuff).");
963             interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
964         }
965         else
966             interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
967         output_strm.Printf ("\nSyntax: %s\n", GetSyntax());
968         GetOptions()->GenerateOptionUsage (output_strm, this);
969         const char *long_help = GetHelpLong();
970         if ((long_help != nullptr)
971             && (strlen (long_help) > 0))
972             FormatLongHelpText (output_strm, long_help);
973         if (WantsRawCommandString() && !WantsCompletion())
974         {
975             // Emit the message about using ' -- ' between the end of the command options and the raw input
976             // conditionally, i.e., only if the command object does not want completion.
977             interpreter.OutputFormattedHelpText (output_strm, "", "",
978                                                  "\nIMPORTANT NOTE:  Because this command takes 'raw' input, if you use any command options"
979                                                  " you must use ' -- ' between the end of the command options and the beginning of the raw input.", 1);
980         }
981         else if (GetNumArgumentEntries() > 0
982                  && GetOptions()
983                  && GetOptions()->NumCommandOptions() > 0)
984         {
985             // Also emit a warning about using "--" in case you are using a command that takes options and arguments.
986             interpreter.OutputFormattedHelpText (output_strm, "", "",
987                                                  "\nThis command takes options and free-form arguments.  If your arguments resemble"
988                                                  " option specifiers (i.e., they start with a - or --), you must use ' -- ' between"
989                                                  " the end of the command options and the beginning of the arguments.", 1);
990         }
991     }
992     else if (IsMultiwordObject())
993     {
994         if (WantsRawCommandString())
995         {
996             std::string help_text (GetHelp());
997             help_text.append ("  This command takes 'raw' input (no need to quote stuff).");
998             interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
999         }
1000         else
1001             interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
1002         GenerateHelpText (output_strm);
1003     }
1004     else
1005     {
1006         const char *long_help = GetHelpLong();
1007         if ((long_help != nullptr)
1008             && (strlen (long_help) > 0))
1009             FormatLongHelpText (output_strm, long_help);
1010         else if (WantsRawCommandString())
1011         {
1012             std::string help_text (GetHelp());
1013             help_text.append ("  This command takes 'raw' input (no need to quote stuff).");
1014             interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
1015         }
1016         else
1017             interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
1018         output_strm.Printf ("\nSyntax: %s\n", GetSyntax());
1019     }
1020 }
1021 
1022 void
1023 CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType ID, CommandArgumentType IDRange)
1024 {
1025     CommandArgumentData id_arg;
1026     CommandArgumentData id_range_arg;
1027 
1028     // Create the first variant for the first (and only) argument for this command.
1029     id_arg.arg_type = ID;
1030     id_arg.arg_repetition = eArgRepeatOptional;
1031 
1032     // Create the second variant for the first (and only) argument for this command.
1033     id_range_arg.arg_type = IDRange;
1034     id_range_arg.arg_repetition = eArgRepeatOptional;
1035 
1036     // The first (and only) argument for this command could be either an id or an id_range.
1037     // Push both variants into the entry for the first argument for this command.
1038     arg.push_back(id_arg);
1039     arg.push_back(id_range_arg);
1040 }
1041 
1042 const char *
1043 CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
1044 {
1045     assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentTypeAsCString");
1046     return g_arguments_data[arg_type].arg_name;
1047 }
1048 
1049 const char *
1050 CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
1051 {
1052     assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentDescriptionAsCString");
1053     return g_arguments_data[arg_type].help_text;
1054 }
1055 
1056 Target *
1057 CommandObject::GetDummyTarget()
1058 {
1059     return m_interpreter.GetDebugger().GetDummyTarget();
1060 }
1061 
1062 Target *
1063 CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy)
1064 {
1065     return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
1066 }
1067 
1068 bool
1069 CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result)
1070 {
1071     bool handled = false;
1072     Args cmd_args (args_string);
1073     if (HasOverrideCallback())
1074     {
1075         Args full_args (GetCommandName ());
1076         full_args.AppendArguments(cmd_args);
1077         handled = InvokeOverrideCallback (full_args.GetConstArgumentVector(), result);
1078     }
1079     if (!handled)
1080     {
1081         for (size_t i = 0; i < cmd_args.GetArgumentCount();  ++i)
1082         {
1083             const char *tmp_str = cmd_args.GetArgumentAtIndex (i);
1084             if (tmp_str[0] == '`')  // back-quote
1085                 cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
1086         }
1087 
1088         if (CheckRequirements(result))
1089         {
1090             if (ParseOptions (cmd_args, result))
1091             {
1092                 // Call the command-specific version of 'Execute', passing it the already processed arguments.
1093                 handled = DoExecute (cmd_args, result);
1094             }
1095         }
1096 
1097         Cleanup();
1098     }
1099     return handled;
1100 }
1101 
1102 bool
1103 CommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result)
1104 {
1105     bool handled = false;
1106     if (HasOverrideCallback())
1107     {
1108         std::string full_command (GetCommandName ());
1109         full_command += ' ';
1110         full_command += args_string;
1111         const char *argv[2] = { nullptr, nullptr };
1112         argv[0] = full_command.c_str();
1113         handled = InvokeOverrideCallback (argv, result);
1114     }
1115     if (!handled)
1116     {
1117         if (CheckRequirements(result))
1118             handled = DoExecute (args_string, result);
1119 
1120         Cleanup();
1121     }
1122     return handled;
1123 }
1124 
1125 static
1126 const char *arch_helper()
1127 {
1128     static StreamString g_archs_help;
1129     if (g_archs_help.Empty())
1130     {
1131         StringList archs;
1132         ArchSpec::AutoComplete(nullptr, archs);
1133         g_archs_help.Printf("These are the supported architecture names:\n");
1134         archs.Join("\n", g_archs_help);
1135     }
1136     return g_archs_help.GetData();
1137 }
1138 
1139 CommandObject::ArgumentTableEntry
1140 CommandObject::g_arguments_data[] =
1141 {
1142     { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid address in the target program's execution space." },
1143     { eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "An expression that resolves to an address." },
1144     { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of an abbreviation (alias) for a debugger command." },
1145     { eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, { nullptr, false }, "Command options to be used as part of an alias (abbreviation) definition.  (See 'help commands alias' for more information.)" },
1146     { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." },
1147     { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { nullptr, false }, "A Boolean value: 'true' or 'false'" },
1148     { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, nullptr },
1149     { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, nullptr },
1150     { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eNoCompletion, { BreakpointNameHelpTextCallback, false }, nullptr },
1151     { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { nullptr, false }, "Number of bytes to use." },
1152     { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { nullptr, false }, "Then name of a class from the debug information in the program." },
1153     { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A debugger command (may be multiple words), without any options or arguments." },
1154     { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
1155     { eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { nullptr, false }, "A directory name." },
1156     { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eNoCompletion, { nullptr, false }, "A disassembly flavor recognized by your disassembly plugin.  Currently the only valid options are \"att\" and \"intel\" for Intel targets" },
1157     { eArgTypeDescriptionVerbosity, "description-verbosity", CommandCompletions::eNoCompletion, { nullptr, false }, "How verbose the output of 'po' should be." },
1158     { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1159     { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1160     { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, nullptr },
1161     { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { nullptr, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
1162     { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "The name of a file (can include path)." },
1163     { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, nullptr },
1164     { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into a thread's list of frames." },
1165     { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1166     { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function." },
1167     { eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function or symbol." },
1168     { eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, nullptr },
1169     { eArgTypeHelpText, "help-text", CommandCompletions::eNoCompletion, { nullptr, false }, "Text to be used as help for some other entity in LLDB" },
1170     { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." },
1171     { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
1172     { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." },
1173     { eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { nullptr, 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." },
1174     { eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { nullptr, 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)." },
1175     { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { nullptr, false }, "A C++ method name." },
1176     { eArgTypeName, "name", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1177     { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1178     { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of lines to use." },
1179     { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of items per line to display." },
1180     { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1181     { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1182     { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { nullptr, false }, "A command that is entered as a single line of text." },
1183     { eArgTypePath, "path", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "Path." },
1184     { eArgTypePermissionsNumber, "perms-numeric", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as an octal number (e.g. 755)." },
1185     { eArgTypePermissionsString, "perms=string", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as a string value (e.g. rw-r-xr--)." },
1186     { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { nullptr, false }, "The process ID number." },
1187     { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1188     { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the process." },
1189     { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python class." },
1190     { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python function." },
1191     { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { nullptr, false }, "Source code written in Python." },
1192     { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the thread queue." },
1193     { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, nullptr },
1194     { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A regular expression." },
1195     { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." },
1196     { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1197     { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
1198     { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { nullptr, false }, "The scripting language to be used for script-based commands.  Currently only Python is valid." },
1199     { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { nullptr, false }, "The word for which you wish to search for information about." },
1200     { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { nullptr, false }, "An Objective-C selector name." },
1201     { eArgTypeSettingIndex, "setting-index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." },
1202     { eArgTypeSettingKey, "setting-key", CommandCompletions::eNoCompletion, { nullptr, false }, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." },
1203     { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
1204     { eArgTypeSettingVariableName, "setting-variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a settable internal debugger variable.  Type 'settings list' to see a complete list of such variables." },
1205     { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a shared library." },
1206     { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, { nullptr, false }, "The name of a source file.." },
1207     { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify a sort order when dumping lists." },
1208     { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1209     { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, { SummaryStringHelpTextCallback, true }, nullptr },
1210     { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, { nullptr, false }, "Any symbol name (function name, variable, argument, etc.)" },
1211     { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Thread ID number." },
1212     { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into the process' list of threads." },
1213     { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The thread's name." },
1214     { eArgTypeTypeName, "type-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A type name." },
1215     { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
1216     { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
1217     { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a variable in your program." },
1218     { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { nullptr, false }, "A value could be anything, depending on where and how it is used." },
1219     { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1220     { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { nullptr, false }, "No help available for this." },
1221     { eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, { nullptr, false }, "The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms." },
1222     { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." },
1223     { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." },
1224     { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." }
1225 };
1226 
1227 const CommandObject::ArgumentTableEntry*
1228 CommandObject::GetArgumentTable ()
1229 {
1230     // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration
1231     assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg);
1232     return CommandObject::g_arguments_data;
1233 }
1234 
1235 
1236