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