]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Interpreter/CommandObject.cpp
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / source / Interpreter / CommandObject.cpp
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 = std::unique_lock<std::recursive_mutex>(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     if (m_api_locker.owns_lock())
340         m_api_locker.unlock();
341 }
342
343 int
344 CommandObject::HandleCompletion
345 (
346     Args &input,
347     int &cursor_index,
348     int &cursor_char_position,
349     int match_start_point,
350     int max_return_elements,
351     bool &word_complete,
352     StringList &matches
353 )
354 {
355     // Default implementation of WantsCompletion() is !WantsRawCommandString().
356     // Subclasses who want raw command string but desire, for example,
357     // argument completion should override WantsCompletion() to return true,
358     // instead.
359     if (WantsRawCommandString() && !WantsCompletion())
360     {
361         // FIXME: Abstract telling the completion to insert the completion character.
362         matches.Clear();
363         return -1;
364     }
365     else
366     {
367         // Can we do anything generic with the options?
368         Options *cur_options = GetOptions();
369         CommandReturnObject result;
370         OptionElementVector opt_element_vector;
371
372         if (cur_options != nullptr)
373         {
374             // Re-insert the dummy command name string which will have been
375             // stripped off:
376             input.Unshift ("dummy-string");
377             cursor_index++;
378
379
380             // I stick an element on the end of the input, because if the last element is
381             // option that requires an argument, getopt_long_only will freak out.
382
383             input.AppendArgument ("<FAKE-VALUE>");
384
385             input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index);
386
387             input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1);
388
389             bool handled_by_options;
390             handled_by_options = cur_options->HandleOptionCompletion (input,
391                                                                       opt_element_vector,
392                                                                       cursor_index,
393                                                                       cursor_char_position,
394                                                                       match_start_point,
395                                                                       max_return_elements,
396                                                                       word_complete,
397                                                                       matches);
398             if (handled_by_options)
399                 return matches.GetSize();
400         }
401
402         // If we got here, the last word is not an option or an option argument.
403         return HandleArgumentCompletion (input,
404                                          cursor_index,
405                                          cursor_char_position,
406                                          opt_element_vector,
407                                          match_start_point,
408                                          max_return_elements,
409                                          word_complete,
410                                          matches);
411     }
412 }
413
414 bool
415 CommandObject::HelpTextContainsWord (const char *search_word,
416                                      bool search_short_help,
417                                      bool search_long_help,
418                                      bool search_syntax,
419                                      bool search_options)
420 {
421     std::string options_usage_help;
422
423     bool found_word = false;
424
425     const char *short_help = GetHelp();
426     const char *long_help = GetHelpLong();
427     const char *syntax_help = GetSyntax();
428     
429     if (search_short_help && short_help && strcasestr (short_help, search_word))
430         found_word = true;
431     else if (search_long_help && long_help && strcasestr (long_help, search_word))
432         found_word = true;
433     else if (search_syntax && syntax_help && strcasestr (syntax_help, search_word))
434         found_word = true;
435
436     if (!found_word
437         && search_options
438         && GetOptions() != nullptr)
439     {
440         StreamString usage_help;
441         GetOptions()->GenerateOptionUsage (usage_help, this);
442         if (usage_help.GetSize() > 0)
443         {
444             const char *usage_text = usage_help.GetData();
445             if (strcasestr (usage_text, search_word))
446               found_word = true;
447         }
448     }
449
450     return found_word;
451 }
452
453 int
454 CommandObject::GetNumArgumentEntries  ()
455 {
456     return m_arguments.size();
457 }
458
459 CommandObject::CommandArgumentEntry *
460 CommandObject::GetArgumentEntryAtIndex (int idx)
461 {
462     if (static_cast<size_t>(idx) < m_arguments.size())
463         return &(m_arguments[idx]);
464
465     return nullptr;
466 }
467
468 const CommandObject::ArgumentTableEntry *
469 CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
470 {
471     const ArgumentTableEntry *table = CommandObject::GetArgumentTable();
472
473     for (int i = 0; i < eArgTypeLastArg; ++i)
474         if (table[i].arg_type == arg_type)
475             return &(table[i]);
476
477     return nullptr;
478 }
479
480 void
481 CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
482 {
483     const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
484     const ArgumentTableEntry *entry = &(table[arg_type]);
485     
486     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
487
488     if (entry->arg_type != arg_type)
489         entry = CommandObject::FindArgumentDataByType (arg_type);
490
491     if (!entry)
492         return;
493
494     StreamString name_str;
495     name_str.Printf ("<%s>", entry->arg_name);
496
497     if (entry->help_function)
498     {
499         const char* help_text = entry->help_function();
500         if (!entry->help_function.self_formatting)
501         {
502             interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,
503                                                  name_str.GetSize());
504         }
505         else
506         {
507             interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text,
508                                        name_str.GetSize());
509         }
510     }
511     else
512         interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
513 }
514
515 const char *
516 CommandObject::GetArgumentName (CommandArgumentType arg_type)
517 {
518     const ArgumentTableEntry *entry = &(CommandObject::GetArgumentTable()[arg_type]);
519
520     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
521
522     if (entry->arg_type != arg_type)
523         entry = CommandObject::FindArgumentDataByType (arg_type);
524
525     if (entry)
526         return entry->arg_name;
527
528     StreamString str;
529     str << "Arg name for type (" << arg_type << ") not in arg table!";
530     return str.GetData();
531 }
532
533 bool
534 CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type)
535 {
536     if ((arg_repeat_type == eArgRepeatPairPlain)
537         ||  (arg_repeat_type == eArgRepeatPairOptional)
538         ||  (arg_repeat_type == eArgRepeatPairPlus)
539         ||  (arg_repeat_type == eArgRepeatPairStar)
540         ||  (arg_repeat_type == eArgRepeatPairRange)
541         ||  (arg_repeat_type == eArgRepeatPairRangeOptional))
542         return true;
543
544     return false;
545 }
546
547 static CommandObject::CommandArgumentEntry
548 OptSetFiltered(uint32_t opt_set_mask, CommandObject::CommandArgumentEntry &cmd_arg_entry)
549 {
550     CommandObject::CommandArgumentEntry ret_val;
551     for (unsigned i = 0; i < cmd_arg_entry.size(); ++i)
552         if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association)
553             ret_val.push_back(cmd_arg_entry[i]);
554     return ret_val;
555 }
556
557 // Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take
558 // all the argument data into account.  On rare cases where some argument sticks
559 // with certain option sets, this function returns the option set filtered args.
560 void
561 CommandObject::GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask)
562 {
563     int num_args = m_arguments.size();
564     for (int i = 0; i < num_args; ++i)
565     {
566         if (i > 0)
567             str.Printf (" ");
568         CommandArgumentEntry arg_entry =
569             opt_set_mask == LLDB_OPT_SET_ALL ? m_arguments[i]
570                                              : OptSetFiltered(opt_set_mask, m_arguments[i]);
571         int num_alternatives = arg_entry.size();
572
573         if ((num_alternatives == 2)
574             && IsPairType (arg_entry[0].arg_repetition))
575         {
576             const char *first_name = GetArgumentName (arg_entry[0].arg_type);
577             const char *second_name = GetArgumentName (arg_entry[1].arg_type);
578             switch (arg_entry[0].arg_repetition)
579             {
580                 case eArgRepeatPairPlain:
581                     str.Printf ("<%s> <%s>", first_name, second_name);
582                     break;
583                 case eArgRepeatPairOptional:
584                     str.Printf ("[<%s> <%s>]", first_name, second_name);
585                     break;
586                 case eArgRepeatPairPlus:
587                     str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name);
588                     break;
589                 case eArgRepeatPairStar:
590                     str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name);
591                     break;
592                 case eArgRepeatPairRange:
593                     str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name);
594                     break;
595                 case eArgRepeatPairRangeOptional:
596                     str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name);
597                     break;
598                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
599                 // missing case statement(s).
600                 case eArgRepeatPlain:
601                 case eArgRepeatOptional:
602                 case eArgRepeatPlus:
603                 case eArgRepeatStar:
604                 case eArgRepeatRange:
605                     // These should not be reached, as they should fail the IsPairType test above.
606                     break;
607             }
608         }
609         else
610         {
611             StreamString names;
612             for (int j = 0; j < num_alternatives; ++j)
613             {
614                 if (j > 0)
615                     names.Printf (" | ");
616                 names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type));
617             }
618             switch (arg_entry[0].arg_repetition)
619             {
620                 case eArgRepeatPlain:
621                     str.Printf ("<%s>", names.GetData());
622                     break;
623                 case eArgRepeatPlus:
624                     str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData());
625                     break;
626                 case eArgRepeatStar:
627                     str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData());
628                     break;
629                 case eArgRepeatOptional:
630                     str.Printf ("[<%s>]", names.GetData());
631                     break;
632                 case eArgRepeatRange:
633                     str.Printf ("<%s_1> .. <%s_n>", names.GetData(), names.GetData());
634                     break;
635                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
636                 // missing case statement(s).
637                 case eArgRepeatPairPlain:
638                 case eArgRepeatPairOptional:
639                 case eArgRepeatPairPlus:
640                 case eArgRepeatPairStar:
641                 case eArgRepeatPairRange:
642                 case eArgRepeatPairRangeOptional:
643                     // These should not be hit, as they should pass the IsPairType test above, and control should
644                     // have gone into the other branch of the if statement.
645                     break;
646             }
647         }
648     }
649 }
650
651 CommandArgumentType
652 CommandObject::LookupArgumentName (const char *arg_name)
653 {
654     CommandArgumentType return_type = eArgTypeLastArg;
655
656     std::string arg_name_str (arg_name);
657     size_t len = arg_name_str.length();
658     if (arg_name[0] == '<'
659         && arg_name[len-1] == '>')
660         arg_name_str = arg_name_str.substr (1, len-2);
661
662     const ArgumentTableEntry *table = GetArgumentTable();
663     for (int i = 0; i < eArgTypeLastArg; ++i)
664         if (arg_name_str.compare (table[i].arg_name) == 0)
665             return_type = g_arguments_data[i].arg_type;
666
667     return return_type;
668 }
669
670 static const char *
671 RegisterNameHelpTextCallback ()
672 {
673     return "Register names can be specified using the architecture specific names.  "
674     "They can also be specified using generic names.  Not all generic entities have "
675     "registers backing them on all architectures.  When they don't the generic name "
676     "will return an error.\n"
677     "The generic names defined in lldb are:\n"
678     "\n"
679     "pc       - program counter register\n"
680     "ra       - return address register\n"
681     "fp       - frame pointer register\n"
682     "sp       - stack pointer register\n"
683     "flags    - the flags register\n"
684     "arg{1-6} - integer argument passing registers.\n";
685 }
686
687 static const char *
688 BreakpointIDHelpTextCallback ()
689 {
690     return "Breakpoints are identified using major and minor numbers; the major "
691            "number corresponds to the single entity that was created with a 'breakpoint "
692            "set' command; the minor numbers correspond to all the locations that were "
693            "actually found/set based on the major breakpoint.  A full breakpoint ID might "
694            "look like 3.14, meaning the 14th location set for the 3rd breakpoint.  You "
695            "can specify all the locations of a breakpoint by just indicating the major "
696            "breakpoint number. A valid breakpoint ID consists either of just the major "
697            "number, or the major number followed by a dot and the location number (e.g. "
698            "3 or 3.2 could both be valid breakpoint IDs.)";
699 }
700
701 static const char *
702 BreakpointIDRangeHelpTextCallback ()
703 {
704     return "A 'breakpoint ID list' is a manner of specifying multiple breakpoints. "
705            "This can be done through several mechanisms.  The easiest way is to just "
706            "enter a space-separated list of breakpoint IDs.  To specify all the "
707            "breakpoint locations under a major breakpoint, you can use the major "
708            "breakpoint number followed by '.*', eg. '5.*' means all the locations under "
709            "breakpoint 5.  You can also indicate a range of breakpoints by using "
710            "<start-bp-id> - <end-bp-id>.  The start-bp-id and end-bp-id for a range can "
711            "be any valid breakpoint IDs.  It is not legal, however, to specify a range "
712            "using specific locations that cross major breakpoint numbers.  I.e. 3.2 - 3.7"
713            " is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
714 }
715
716 static const char *
717 BreakpointNameHelpTextCallback ()
718 {
719     return "A name that can be added to a breakpoint when it is created, or later "
720            "on with the \"breakpoint name add\" command.  "
721            "Breakpoint names can be used to specify breakpoints in all the places breakpoint IDs "
722            "and breakpoint ID ranges can be used.  As such they provide a convenient way to group breakpoints, "
723            "and to operate on breakpoints you create without having to track the breakpoint number.  "
724            "Note, the attributes you set when using a breakpoint name in a breakpoint command don't "
725            "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that "
726            "name.  Future breakpoints "
727            "tagged with that name will not pick up the attributes previously given using that name.  "
728            "In order to distinguish breakpoint names from breakpoint IDs and ranges, "
729            "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\".  "
730            "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations.";
731 }
732
733 static const char *
734 GDBFormatHelpTextCallback ()
735 {
736     return "A GDB format consists of a repeat count, a format letter and a size letter. "
737     "The repeat count is optional and defaults to 1. The format letter is optional "
738     "and defaults to the previous format that was used. The size letter is optional "
739     "and defaults to the previous size that was used.\n"
740     "\n"
741     "Format letters include:\n"
742     "o - octal\n"
743     "x - hexadecimal\n"
744     "d - decimal\n"
745     "u - unsigned decimal\n"
746     "t - binary\n"
747     "f - float\n"
748     "a - address\n"
749     "i - instruction\n"
750     "c - char\n"
751     "s - string\n"
752     "T - OSType\n"
753     "A - float as hex\n"
754     "\n"
755     "Size letters include:\n"
756     "b - 1 byte  (byte)\n"
757     "h - 2 bytes (halfword)\n"
758     "w - 4 bytes (word)\n"
759     "g - 8 bytes (giant)\n"
760     "\n"
761     "Example formats:\n"
762     "32xb - show 32 1 byte hexadecimal integer values\n"
763     "16xh - show 16 2 byte hexadecimal integer values\n"
764     "64   - show 64 2 byte hexadecimal integer values (format and size from the last format)\n"
765     "dw   - show 1 4 byte decimal integer value\n"
766     ;
767
768
769 static const char *
770 FormatHelpTextCallback ()
771 {
772     
773     static char* help_text_ptr = nullptr;
774     
775     if (help_text_ptr)
776         return help_text_ptr;
777     
778     StreamString sstr;
779     sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n";
780     for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
781     {
782         if (f != eFormatDefault)
783             sstr.PutChar('\n');
784         
785         char format_char = FormatManager::GetFormatAsFormatChar(f);
786         if (format_char)
787             sstr.Printf("'%c' or ", format_char);
788         
789         sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
790     }
791     
792     sstr.Flush();
793     
794     std::string data = sstr.GetString();
795     
796     help_text_ptr = new char[data.length()+1];
797     
798     data.copy(help_text_ptr, data.length());
799     
800     return help_text_ptr;
801 }
802
803 static const char *
804 LanguageTypeHelpTextCallback ()
805 {
806     static char* help_text_ptr = nullptr;
807     
808     if (help_text_ptr)
809         return help_text_ptr;
810     
811     StreamString sstr;
812     sstr << "One of the following languages:\n";
813
814     Language::PrintAllLanguages(sstr, "  ", "\n");
815
816     sstr.Flush();
817     
818     std::string data = sstr.GetString();
819     
820     help_text_ptr = new char[data.length()+1];
821     
822     data.copy(help_text_ptr, data.length());
823     
824     return help_text_ptr;
825 }
826
827 static const char *
828 SummaryStringHelpTextCallback()
829 {
830     return
831         "A summary string is a way to extract information from variables in order to present them using a summary.\n"
832         "Summary strings contain static text, variables, scopes and control sequences:\n"
833         "  - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n"
834         "  - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n"
835         "  - 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"
836         "  - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n"
837         "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n"
838         "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"
839         "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"
840         " (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"
841         " ${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."
842         " 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"
843         "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."
844         "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"
845         " path refers to:\n"
846         "  - 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"
847         " and displayed as an individual variable\n"
848         "  - 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"
849         " 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"
850         "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"
851         "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"
852         " special symbols only allowed as part of a variable:\n"
853         "    %V: show the value of the object by default\n"
854         "    %S: show the summary of the object by default\n"
855         "    %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n"
856         "    %L: show the location of the object (memory address or a register name)\n"
857         "    %#: show the number of children of the object\n"
858         "    %T: show the type of the object\n"
859         "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"
860         " 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"
861         " count the number of actual elements stored in an std::list:\n"
862         "type summary add -s \"${svar%#}\" -x \"std::list<\"";
863 }
864
865 static const char *
866 ExprPathHelpTextCallback()
867 {
868     return
869     "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"
870     "For instance, given a class:\n"
871     "  class foo {\n"
872     "      int a;\n"
873     "      int b; .\n"
874     "      foo* next;\n"
875     "  };\n"
876     "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n"
877     "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"
878     "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n"
879     "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n"
880     "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n"
881     "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"
882     " 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"
883     " 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"
884     " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory).";
885 }
886
887 void
888 CommandObject::FormatLongHelpText (Stream &output_strm, const char *long_help)
889 {
890     CommandInterpreter& interpreter = GetCommandInterpreter();
891     std::stringstream lineStream (long_help);
892     std::string line;
893     while (std::getline (lineStream, line)) {
894         if (line.empty()) {
895             output_strm << "\n";
896             continue;
897         }
898         size_t result = line.find_first_not_of (" \t");
899         if (result == std::string::npos) {
900             result = 0;
901         }
902         std::string whitespace_prefix = line.substr (0, result);
903         std::string remainder = line.substr (result);
904         interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), remainder.c_str());
905     }
906 }
907
908 void
909 CommandObject::GenerateHelpText (CommandReturnObject &result)
910 {
911     GenerateHelpText(result.GetOutputStream());
912     
913     result.SetStatus (eReturnStatusSuccessFinishNoResult);
914 }
915
916 void
917 CommandObject::GenerateHelpText (Stream &output_strm)
918 {
919     CommandInterpreter& interpreter = GetCommandInterpreter();
920     if (WantsRawCommandString())
921     {
922         std::string help_text(GetHelp());
923         help_text.append("  Expects 'raw' input (see 'help raw-input'.)");
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     Options *options = GetOptions();
930     if (options != nullptr)
931     {
932         options->GenerateOptionUsage(output_strm, this);
933     }
934     const char *long_help = GetHelpLong();
935     if ((long_help != nullptr) && (strlen(long_help) > 0))
936     {
937         FormatLongHelpText(output_strm, long_help);
938     }
939     if (!IsDashDashCommand() && options && options->NumCommandOptions() > 0)
940     {
941         if (WantsRawCommandString() && !WantsCompletion())
942         {
943             // Emit the message about using ' -- ' between the end of the command options and the raw input
944             // conditionally, i.e., only if the command object does not want completion.
945             interpreter.OutputFormattedHelpText(
946                 output_strm, "", "",
947                 "\nImportant Note: Because this command takes 'raw' input, if you use any command options"
948                 " you must use ' -- ' between the end of the command options and the beginning of the raw input.",
949                 1);
950         }
951         else if (GetNumArgumentEntries() > 0)
952         {
953             // Also emit a warning about using "--" in case you are using a command that takes options and arguments.
954             interpreter.OutputFormattedHelpText(
955                 output_strm, "", "", "\nThis command takes options and free-form arguments.  If your arguments resemble"
956                                      " option specifiers (i.e., they start with a - or --), you must use ' -- ' between"
957                                      " the end of the command options and the beginning of the arguments.",
958                 1);
959         }
960     }
961 }
962
963 void
964 CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType ID, CommandArgumentType IDRange)
965 {
966     CommandArgumentData id_arg;
967     CommandArgumentData id_range_arg;
968
969     // Create the first variant for the first (and only) argument for this command.
970     id_arg.arg_type = ID;
971     id_arg.arg_repetition = eArgRepeatOptional;
972
973     // Create the second variant for the first (and only) argument for this command.
974     id_range_arg.arg_type = IDRange;
975     id_range_arg.arg_repetition = eArgRepeatOptional;
976
977     // The first (and only) argument for this command could be either an id or an id_range.
978     // Push both variants into the entry for the first argument for this command.
979     arg.push_back(id_arg);
980     arg.push_back(id_range_arg);
981 }
982
983 const char * 
984 CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
985 {
986     assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentTypeAsCString");
987     return g_arguments_data[arg_type].arg_name;
988 }
989
990 const char * 
991 CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
992 {
993     assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentDescriptionAsCString");
994     return g_arguments_data[arg_type].help_text;
995 }
996
997 Target *
998 CommandObject::GetDummyTarget()
999 {
1000     return m_interpreter.GetDebugger().GetDummyTarget();
1001 }
1002
1003 Target *
1004 CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy)
1005 {
1006     return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
1007 }
1008
1009 Thread *
1010 CommandObject::GetDefaultThread()
1011 {
1012     Thread *thread_to_use = m_exe_ctx.GetThreadPtr();
1013     if (thread_to_use)
1014         return thread_to_use;
1015     
1016     Process *process = m_exe_ctx.GetProcessPtr();
1017     if (!process)
1018     {
1019         Target *target = m_exe_ctx.GetTargetPtr();
1020         if (!target)
1021         {
1022             target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1023         }
1024         if (target)
1025             process = target->GetProcessSP().get();
1026     }
1027
1028     if (process)
1029         return process->GetThreadList().GetSelectedThread().get();
1030     else
1031         return nullptr;
1032 }
1033
1034 bool
1035 CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result)
1036 {
1037     bool handled = false;
1038     Args cmd_args (args_string);
1039     if (HasOverrideCallback())
1040     {
1041         Args full_args (GetCommandName ());
1042         full_args.AppendArguments(cmd_args);
1043         handled = InvokeOverrideCallback (full_args.GetConstArgumentVector(), result);
1044     }
1045     if (!handled)
1046     {
1047         for (size_t i = 0; i < cmd_args.GetArgumentCount();  ++i)
1048         {
1049             const char *tmp_str = cmd_args.GetArgumentAtIndex (i);
1050             if (tmp_str[0] == '`')  // back-quote
1051                 cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
1052         }
1053
1054         if (CheckRequirements(result))
1055         {
1056             if (ParseOptions (cmd_args, result))
1057             {
1058                 // Call the command-specific version of 'Execute', passing it the already processed arguments.
1059                 handled = DoExecute (cmd_args, result);
1060             }
1061         }
1062
1063         Cleanup();
1064     }
1065     return handled;
1066 }
1067
1068 bool
1069 CommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result)
1070 {
1071     bool handled = false;
1072     if (HasOverrideCallback())
1073     {
1074         std::string full_command (GetCommandName ());
1075         full_command += ' ';
1076         full_command += args_string;
1077         const char *argv[2] = { nullptr, nullptr };
1078         argv[0] = full_command.c_str();
1079         handled = InvokeOverrideCallback (argv, result);
1080     }
1081     if (!handled)
1082     {
1083         if (CheckRequirements(result))
1084             handled = DoExecute (args_string, result);
1085         
1086         Cleanup();
1087     }
1088     return handled;
1089 }
1090
1091 static
1092 const char *arch_helper()
1093 {
1094     static StreamString g_archs_help;
1095     if (g_archs_help.Empty())
1096     {
1097         StringList archs;
1098         ArchSpec::AutoComplete(nullptr, archs);
1099         g_archs_help.Printf("These are the supported architecture names:\n");
1100         archs.Join("\n", g_archs_help);
1101     }
1102     return g_archs_help.GetData();
1103 }
1104
1105 CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
1106     // clang-format off
1107     { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid address in the target program's execution space." },
1108     { eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "An expression that resolves to an address." },
1109     { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of an abbreviation (alias) for a debugger command." },
1110     { 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.)" },
1111     { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." },
1112     { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { nullptr, false }, "A Boolean value: 'true' or 'false'" },
1113     { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, nullptr },
1114     { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, nullptr },
1115     { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eNoCompletion, { BreakpointNameHelpTextCallback, false }, nullptr },
1116     { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { nullptr, false }, "Number of bytes to use." },
1117     { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { nullptr, false }, "Then name of a class from the debug information in the program." },
1118     { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A debugger command (may be multiple words), without any options or arguments." },
1119     { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
1120     { eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { nullptr, false }, "A directory name." },
1121     { 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" },
1122     { eArgTypeDescriptionVerbosity, "description-verbosity", CommandCompletions::eNoCompletion, { nullptr, false }, "How verbose the output of 'po' should be." },
1123     { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1124     { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1125     { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, nullptr },
1126     { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { nullptr, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
1127     { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "The name of a file (can include path)." },
1128     { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, nullptr },
1129     { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into a thread's list of frames." },
1130     { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1131     { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function." },
1132     { eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function or symbol." },
1133     { eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, nullptr },
1134     { eArgTypeHelpText, "help-text", CommandCompletions::eNoCompletion, { nullptr, false }, "Text to be used as help for some other entity in LLDB" },
1135     { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." },
1136     { eArgTypeLanguage, "source-language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
1137     { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." },
1138     { 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." },
1139     { 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)." },
1140     { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { nullptr, false }, "A C++ method name." },
1141     { eArgTypeName, "name", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1142     { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1143     { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of lines to use." },
1144     { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of items per line to display." },
1145     { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1146     { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1147     { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { nullptr, false }, "A command that is entered as a single line of text." },
1148     { eArgTypePath, "path", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "Path." },
1149     { eArgTypePermissionsNumber, "perms-numeric", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as an octal number (e.g. 755)." },
1150     { eArgTypePermissionsString, "perms=string", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as a string value (e.g. rw-r-xr--)." },
1151     { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { nullptr, false }, "The process ID number." },
1152     { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1153     { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the process." },
1154     { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python class." },
1155     { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python function." },
1156     { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { nullptr, false }, "Source code written in Python." },
1157     { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the thread queue." },
1158     { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, nullptr },
1159     { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A regular expression." },
1160     { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." },
1161     { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1162     { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
1163     { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { nullptr, false }, "The scripting language to be used for script-based commands.  Currently only Python is valid." },
1164     { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { nullptr, false }, "Any word of interest for search purposes." },
1165     { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { nullptr, false }, "An Objective-C selector name." },
1166     { 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)." },
1167     { 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)." },
1168     { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
1169     { 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." },
1170     { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a shared library." },
1171     { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, { nullptr, false }, "The name of a source file.." },
1172     { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify a sort order when dumping lists." },
1173     { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1174     { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, { SummaryStringHelpTextCallback, true }, nullptr },
1175     { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, { nullptr, false }, "Any symbol name (function name, variable, argument, etc.)" },
1176     { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Thread ID number." },
1177     { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into the process' list of threads." },
1178     { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The thread's name." },
1179     { eArgTypeTypeName, "type-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A type name." },
1180     { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
1181     { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
1182     { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a variable in your program." },
1183     { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { nullptr, false }, "A value could be anything, depending on where and how it is used." },
1184     { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
1185     { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { nullptr, false }, "No help available for this." },
1186     { 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." },
1187     { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." },
1188     { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." },
1189     { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." },
1190     { eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes.  To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }
1191     // clang-format on
1192 };
1193
1194 const CommandObject::ArgumentTableEntry*
1195 CommandObject::GetArgumentTable ()
1196 {
1197     // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration
1198     assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg);
1199     return CommandObject::g_arguments_data;
1200 }
1201
1202