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