1 //===-- CommandObject.cpp ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Interpreter/CommandObject.h"
11 
12 #include <string>
13 #include <map>
14 
15 #include <getopt.h>
16 #include <stdlib.h>
17 #include <ctype.h>
18 
19 #include "lldb/Core/Address.h"
20 #include "lldb/Interpreter/Options.h"
21 
22 // These are for the Sourcename completers.
23 // FIXME: Make a separate file for the completers.
24 #include "lldb/Host/FileSpec.h"
25 #include "lldb/Core/FileSpecList.h"
26 #include "lldb/Target/Process.h"
27 #include "lldb/Target/Target.h"
28 
29 #include "lldb/Interpreter/CommandInterpreter.h"
30 #include "lldb/Interpreter/CommandReturnObject.h"
31 #include "lldb/Interpreter/ScriptInterpreter.h"
32 #include "lldb/Interpreter/ScriptInterpreterPython.h"
33 
34 using namespace lldb;
35 using namespace lldb_private;
36 
37 //-------------------------------------------------------------------------
38 // CommandObject
39 //-------------------------------------------------------------------------
40 
41 CommandObject::CommandObject
42 (
43     CommandInterpreter &interpreter,
44     const char *name,
45     const char *help,
46     const char *syntax,
47     uint32_t flags
48 ) :
49     m_interpreter (interpreter),
50     m_cmd_name (name),
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 {
58     if (help && help[0])
59         m_cmd_help_short = help;
60     if (syntax && syntax[0])
61         m_cmd_syntax = syntax;
62 }
63 
64 CommandObject::~CommandObject ()
65 {
66 }
67 
68 const char *
69 CommandObject::GetHelp ()
70 {
71     return m_cmd_help_short.c_str();
72 }
73 
74 const char *
75 CommandObject::GetHelpLong ()
76 {
77     return m_cmd_help_long.c_str();
78 }
79 
80 const char *
81 CommandObject::GetSyntax ()
82 {
83     if (m_cmd_syntax.length() == 0)
84     {
85         StreamString syntax_str;
86         syntax_str.Printf ("%s", GetCommandName());
87         if (GetOptions() != NULL)
88             syntax_str.Printf (" <cmd-options>");
89         if (m_arguments.size() > 0)
90         {
91             syntax_str.Printf (" ");
92             GetFormattedCommandArguments (syntax_str);
93         }
94         m_cmd_syntax = syntax_str.GetData ();
95     }
96 
97     return m_cmd_syntax.c_str();
98 }
99 
100 const char *
101 CommandObject::Translate ()
102 {
103     //return m_cmd_func_name.c_str();
104     return "This function is currently not implemented.";
105 }
106 
107 const char *
108 CommandObject::GetCommandName ()
109 {
110     return m_cmd_name.c_str();
111 }
112 
113 void
114 CommandObject::SetCommandName (const char *name)
115 {
116     m_cmd_name = name;
117 }
118 
119 void
120 CommandObject::SetHelp (const char *cstr)
121 {
122     m_cmd_help_short = cstr;
123 }
124 
125 void
126 CommandObject::SetHelpLong (const char *cstr)
127 {
128     m_cmd_help_long = cstr;
129 }
130 
131 void
132 CommandObject::SetSyntax (const char *cstr)
133 {
134     m_cmd_syntax = cstr;
135 }
136 
137 Options *
138 CommandObject::GetOptions ()
139 {
140     // By default commands don't have options unless this virtual function
141     // is overridden by base classes.
142     return NULL;
143 }
144 
145 Flags&
146 CommandObject::GetFlags()
147 {
148     return m_flags;
149 }
150 
151 const Flags&
152 CommandObject::GetFlags() const
153 {
154     return m_flags;
155 }
156 
157 bool
158 CommandObject::ExecuteCommandString
159 (
160     const char *command_line,
161     CommandReturnObject &result
162 )
163 {
164     Args command_args(command_line);
165     return ExecuteWithOptions (command_args, result);
166 }
167 
168 bool
169 CommandObject::ParseOptions
170 (
171     Args& args,
172     CommandReturnObject &result
173 )
174 {
175     // See if the subclass has options?
176     Options *options = GetOptions();
177     if (options != NULL)
178     {
179         Error error;
180         options->NotifyOptionParsingStarting();
181 
182         // ParseOptions calls getopt_long, which always skips the zero'th item in the array and starts at position 1,
183         // so we need to push a dummy value into position zero.
184         args.Unshift("dummy_string");
185         error = args.ParseOptions (*options);
186 
187         // The "dummy_string" will have already been removed by ParseOptions,
188         // so no need to remove it.
189 
190         if (error.Success())
191             error = options->NotifyOptionParsingFinished();
192 
193         if (error.Success())
194         {
195             if (options->VerifyOptions (result))
196                 return true;
197         }
198         else
199         {
200             const char *error_cstr = error.AsCString();
201             if (error_cstr)
202             {
203                 // We got an error string, lets use that
204                 result.GetErrorStream().PutCString(error_cstr);
205             }
206             else
207             {
208                 // No error string, output the usage information into result
209                 options->GenerateOptionUsage (result.GetErrorStream(), this);
210             }
211         }
212         result.SetStatus (eReturnStatusFailed);
213         return false;
214     }
215     return true;
216 }
217 bool
218 CommandObject::ExecuteWithOptions (Args& args, CommandReturnObject &result)
219 {
220     for (size_t i = 0; i < args.GetArgumentCount();  ++i)
221     {
222         const char *tmp_str = args.GetArgumentAtIndex (i);
223         if (tmp_str[0] == '`')  // back-quote
224             args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
225     }
226 
227     if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
228     {
229         Process *process = m_interpreter.GetExecutionContext().process;
230         if (process == NULL)
231         {
232             result.AppendError ("Process must exist.");
233             result.SetStatus (eReturnStatusFailed);
234             return false;
235         }
236         else
237         {
238             StateType state = process->GetState();
239 
240             switch (state)
241             {
242             case eStateInvalid:
243             case eStateSuspended:
244             case eStateCrashed:
245             case eStateStopped:
246                 break;
247 
248             case eStateConnected:
249             case eStateAttaching:
250             case eStateLaunching:
251             case eStateDetached:
252             case eStateExited:
253             case eStateUnloaded:
254                 if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
255                 {
256                     result.AppendError ("Process must be launched.");
257                     result.SetStatus (eReturnStatusFailed);
258                     return false;
259                 }
260                 break;
261 
262             case eStateRunning:
263             case eStateStepping:
264                 if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
265                 {
266                     result.AppendError ("Process is running.  Use 'process interrupt' to pause execution.");
267                     result.SetStatus (eReturnStatusFailed);
268                     return false;
269                 }
270             }
271         }
272     }
273 
274     if (!ParseOptions (args, result))
275         return false;
276 
277     // Call the command-specific version of 'Execute', passing it the already processed arguments.
278     return Execute (args, result);
279 }
280 
281 class CommandDictCommandPartialMatch
282 {
283     public:
284         CommandDictCommandPartialMatch (const char *match_str)
285         {
286             m_match_str = match_str;
287         }
288         bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const
289         {
290             // A NULL or empty string matches everything.
291             if (m_match_str == NULL || *m_match_str == '\0')
292                 return 1;
293 
294             size_t found = map_element.first.find (m_match_str, 0);
295             if (found == std::string::npos)
296                 return 0;
297             else
298                 return found == 0;
299         }
300 
301     private:
302         const char *m_match_str;
303 };
304 
305 int
306 CommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str,
307                                               StringList &matches)
308 {
309     int number_added = 0;
310     CommandDictCommandPartialMatch matcher(cmd_str);
311 
312     CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher);
313 
314     while (matching_cmds != in_map.end())
315     {
316         ++number_added;
317         matches.AppendString((*matching_cmds).first.c_str());
318         matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);;
319     }
320     return number_added;
321 }
322 
323 int
324 CommandObject::HandleCompletion
325 (
326     Args &input,
327     int &cursor_index,
328     int &cursor_char_position,
329     int match_start_point,
330     int max_return_elements,
331     bool &word_complete,
332     StringList &matches
333 )
334 {
335     if (WantsRawCommandString())
336     {
337         // FIXME: Abstract telling the completion to insert the completion character.
338         matches.Clear();
339         return -1;
340     }
341     else
342     {
343         // Can we do anything generic with the options?
344         Options *cur_options = GetOptions();
345         CommandReturnObject result;
346         OptionElementVector opt_element_vector;
347 
348         if (cur_options != NULL)
349         {
350             // Re-insert the dummy command name string which will have been
351             // stripped off:
352             input.Unshift ("dummy-string");
353             cursor_index++;
354 
355 
356             // I stick an element on the end of the input, because if the last element is
357             // option that requires an argument, getopt_long will freak out.
358 
359             input.AppendArgument ("<FAKE-VALUE>");
360 
361             input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index);
362 
363             input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1);
364 
365             bool handled_by_options;
366             handled_by_options = cur_options->HandleOptionCompletion (input,
367                                                                       opt_element_vector,
368                                                                       cursor_index,
369                                                                       cursor_char_position,
370                                                                       match_start_point,
371                                                                       max_return_elements,
372                                                                       word_complete,
373                                                                       matches);
374             if (handled_by_options)
375                 return matches.GetSize();
376         }
377 
378         // If we got here, the last word is not an option or an option argument.
379         return HandleArgumentCompletion (input,
380                                          cursor_index,
381                                          cursor_char_position,
382                                          opt_element_vector,
383                                          match_start_point,
384                                          max_return_elements,
385                                          word_complete,
386                                          matches);
387     }
388 }
389 
390 bool
391 CommandObject::HelpTextContainsWord (const char *search_word)
392 {
393     const char *short_help;
394     const char *long_help;
395     const char *syntax_help;
396     std::string options_usage_help;
397 
398 
399     bool found_word = false;
400 
401     short_help = GetHelp();
402     long_help = GetHelpLong();
403     syntax_help = GetSyntax();
404 
405     if (strcasestr (short_help, search_word))
406         found_word = true;
407     else if (strcasestr (long_help, search_word))
408         found_word = true;
409     else if (strcasestr (syntax_help, search_word))
410         found_word = true;
411 
412     if (!found_word
413         && GetOptions() != NULL)
414     {
415         StreamString usage_help;
416         GetOptions()->GenerateOptionUsage (usage_help, this);
417         if (usage_help.GetSize() > 0)
418         {
419             const char *usage_text = usage_help.GetData();
420             if (strcasestr (usage_text, search_word))
421               found_word = true;
422         }
423     }
424 
425     return found_word;
426 }
427 
428 int
429 CommandObject::GetNumArgumentEntries  ()
430 {
431     return m_arguments.size();
432 }
433 
434 CommandObject::CommandArgumentEntry *
435 CommandObject::GetArgumentEntryAtIndex (int idx)
436 {
437     if (idx < m_arguments.size())
438         return &(m_arguments[idx]);
439 
440     return NULL;
441 }
442 
443 CommandObject::ArgumentTableEntry *
444 CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
445 {
446     const ArgumentTableEntry *table = CommandObject::GetArgumentTable();
447 
448     for (int i = 0; i < eArgTypeLastArg; ++i)
449         if (table[i].arg_type == arg_type)
450             return (ArgumentTableEntry *) &(table[i]);
451 
452     return NULL;
453 }
454 
455 void
456 CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
457 {
458     const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
459     ArgumentTableEntry *entry = (ArgumentTableEntry *) &(table[arg_type]);
460 
461     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
462 
463     if (entry->arg_type != arg_type)
464         entry = CommandObject::FindArgumentDataByType (arg_type);
465 
466     if (!entry)
467         return;
468 
469     StreamString name_str;
470     name_str.Printf ("<%s>", entry->arg_name);
471 
472     if (entry->help_function != NULL)
473         interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", (*(entry->help_function)) (),
474                                              name_str.GetSize());
475     else
476         interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
477 }
478 
479 const char *
480 CommandObject::GetArgumentName (CommandArgumentType arg_type)
481 {
482     ArgumentTableEntry *entry = (ArgumentTableEntry *) &(CommandObject::GetArgumentTable()[arg_type]);
483 
484     // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...
485 
486     if (entry->arg_type != arg_type)
487         entry = CommandObject::FindArgumentDataByType (arg_type);
488 
489     if (entry)
490         return entry->arg_name;
491 
492     StreamString str;
493     str << "Arg name for type (" << arg_type << ") not in arg table!";
494     return str.GetData();
495 }
496 
497 bool
498 CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type)
499 {
500     if ((arg_repeat_type == eArgRepeatPairPlain)
501         ||  (arg_repeat_type == eArgRepeatPairOptional)
502         ||  (arg_repeat_type == eArgRepeatPairPlus)
503         ||  (arg_repeat_type == eArgRepeatPairStar)
504         ||  (arg_repeat_type == eArgRepeatPairRange)
505         ||  (arg_repeat_type == eArgRepeatPairRangeOptional))
506         return true;
507 
508     return false;
509 }
510 
511 void
512 CommandObject::GetFormattedCommandArguments (Stream &str)
513 {
514     int num_args = m_arguments.size();
515     for (int i = 0; i < num_args; ++i)
516     {
517         if (i > 0)
518             str.Printf (" ");
519         CommandArgumentEntry arg_entry = m_arguments[i];
520         int num_alternatives = arg_entry.size();
521 
522         if ((num_alternatives == 2)
523             && IsPairType (arg_entry[0].arg_repetition))
524         {
525             const char *first_name = GetArgumentName (arg_entry[0].arg_type);
526             const char *second_name = GetArgumentName (arg_entry[1].arg_type);
527             switch (arg_entry[0].arg_repetition)
528             {
529                 case eArgRepeatPairPlain:
530                     str.Printf ("<%s> <%s>", first_name, second_name);
531                     break;
532                 case eArgRepeatPairOptional:
533                     str.Printf ("[<%s> <%s>]", first_name, second_name);
534                     break;
535                 case eArgRepeatPairPlus:
536                     str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name);
537                     break;
538                 case eArgRepeatPairStar:
539                     str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name);
540                     break;
541                 case eArgRepeatPairRange:
542                     str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name);
543                     break;
544                 case eArgRepeatPairRangeOptional:
545                     str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name);
546                     break;
547                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
548                 // missing case statement(s).
549                 case eArgRepeatPlain:
550                 case eArgRepeatOptional:
551                 case eArgRepeatPlus:
552                 case eArgRepeatStar:
553                 case eArgRepeatRange:
554                     // These should not be reached, as they should fail the IsPairType test above.
555                     break;
556             }
557         }
558         else
559         {
560             StreamString names;
561             for (int j = 0; j < num_alternatives; ++j)
562             {
563                 if (j > 0)
564                     names.Printf (" | ");
565                 names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type));
566             }
567             switch (arg_entry[0].arg_repetition)
568             {
569                 case eArgRepeatPlain:
570                     str.Printf ("<%s>", names.GetData());
571                     break;
572                 case eArgRepeatPlus:
573                     str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData());
574                     break;
575                 case eArgRepeatStar:
576                     str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData());
577                     break;
578                 case eArgRepeatOptional:
579                     str.Printf ("[<%s>]", names.GetData());
580                     break;
581                 case eArgRepeatRange:
582                     str.Printf ("<%s_1> .. <%s_n>", names.GetData());
583                     break;
584                 // Explicitly test for all the rest of the cases, so if new types get added we will notice the
585                 // missing case statement(s).
586                 case eArgRepeatPairPlain:
587                 case eArgRepeatPairOptional:
588                 case eArgRepeatPairPlus:
589                 case eArgRepeatPairStar:
590                 case eArgRepeatPairRange:
591                 case eArgRepeatPairRangeOptional:
592                     // These should not be hit, as they should pass the IsPairType test above, and control should
593                     // have gone into the other branch of the if statement.
594                     break;
595             }
596         }
597     }
598 }
599 
600 CommandArgumentType
601 CommandObject::LookupArgumentName (const char *arg_name)
602 {
603     CommandArgumentType return_type = eArgTypeLastArg;
604 
605     std::string arg_name_str (arg_name);
606     size_t len = arg_name_str.length();
607     if (arg_name[0] == '<'
608         && arg_name[len-1] == '>')
609         arg_name_str = arg_name_str.substr (1, len-2);
610 
611     for (int i = 0; i < eArgTypeLastArg; ++i)
612         if (arg_name_str.compare (g_arguments_data[i].arg_name) == 0)
613             return_type = g_arguments_data[i].arg_type;
614 
615     return return_type;
616 }
617 
618 static const char *
619 BreakpointIDHelpTextCallback ()
620 {
621     return "Breakpoint ID's consist major and minor numbers;  the major number corresponds to the single entity that was created with a 'breakpoint set' command; the minor numbers correspond to all the locations that were actually found/set based on the major breakpoint.  A full breakpoint ID might look like 3.14, meaning the 14th location set for the 3rd breakpoint.  You can specify all the locations of a breakpoint by just indicating the major breakpoint number. A valid breakpoint id consists either of just the major id number, or the major number, a dot, and the location number (e.g. 3 or 3.2 could both be valid breakpoint ids).";
622 }
623 
624 static const char *
625 BreakpointIDRangeHelpTextCallback ()
626 {
627     return "A 'breakpoint id list' is a manner of specifying multiple breakpoints. This can be done  through several mechanisms.  The easiest way is to just enter a space-separated list of breakpoint ids.  To specify all the breakpoint locations under a major breakpoint, you can use the major breakpoint number followed by '.*', eg. '5.*' means all the locations under breakpoint 5.  You can also indicate a range of breakpoints by using <start-bp-id> - <end-bp-id>.  The start-bp-id and end-bp-id for a range can be any valid breakpoint ids.  It is not legal, however, to specify a range using specific locations that cross major breakpoint numbers.  I.e. 3.2 - 3.7 is legal; 2 - 5 is legal; but 3.2 - 4.4 is not legal.";
628 }
629 
630 const char *
631 CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
632 {
633     if (arg_type >=0 && arg_type < eArgTypeLastArg)
634         return g_arguments_data[arg_type].arg_name;
635     return NULL;
636 
637 }
638 
639 const char *
640 CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
641 {
642     if (arg_type >=0 && arg_type < eArgTypeLastArg)
643         return g_arguments_data[arg_type].help_text;
644     return NULL;
645 }
646 
647 CommandObject::ArgumentTableEntry
648 CommandObject::g_arguments_data[] =
649 {
650     { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, NULL, "A valid address in the target program's execution space." },
651     { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, NULL, "The name of an abbreviation (alias) for a debugger command." },
652     { eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, NULL, "Command options to be used as part of an alias (abbreviation) definition.  (See 'help commands alias' for more information.)" },
653     { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, NULL, "The architecture name, e.g. i386 or x86_64." },
654     { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, NULL, "A Boolean value: 'true' or 'false'" },
655     { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, BreakpointIDHelpTextCallback, NULL },
656     { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, BreakpointIDRangeHelpTextCallback, NULL },
657     { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, NULL, "Number of bytes to use." },
658     { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, NULL, "Then name of a class from the debug information in the program." },
659     { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, NULL, "A debugger command (may be multiple words), without any options or arguments." },
660     { eArgTypeCount, "count", CommandCompletions::eNoCompletion, NULL, "An unsigned integer." },
661     { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
662     { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
663     { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, NULL, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
664     { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, NULL, "The name of a file (can include path)." },
665     { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
666     { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, NULL, "Index into a thread's list of frames." },
667     { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
668     { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, NULL, "The name of a function." },
669     { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, NULL, "An index into a list." },
670     { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, NULL, "Line number in a source file." },
671     { eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, NULL, "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." },
672     { eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, NULL, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." },
673     { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, NULL, "A C++ method name." },
674     { eArgTypeName, "name", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
675     { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
676     { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, NULL, "The number of lines to use." },
677     { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, NULL, "The number of items per line to display." },
678     { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
679     { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
680     { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, NULL, "A command that is entered as a single line of text." },
681     { eArgTypePath, "path", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
682     { eArgTypePid, "pid", CommandCompletions::eNoCompletion, NULL, "The process ID number." },
683     { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
684     { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, NULL, "The name of the process." },
685     { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, NULL, "The name of the thread queue." },
686     { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, NULL, "A register name." },
687     { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, NULL, "A regular expression." },
688     { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, NULL, "Arguments to be passed to the target program when it starts executing." },
689     { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
690     { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, NULL, "The scripting language to be used for script-based commands.  Currently only Python is valid." },
691     { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, NULL, "The word for which you wish to search for information about." },
692     { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, NULL, "An Objective-C selector name." },
693     { eArgTypeSettingIndex, "setting-index", CommandCompletions::eNoCompletion, NULL, "An index into a settings variable that is an array (try 'settings list' to see all the possible settings variables and their types)." },
694     { eArgTypeSettingKey, "setting-key", CommandCompletions::eNoCompletion, NULL, "A key into a settings variables that is a dictionary (try 'settings list' to see all the possible settings variables and their types)." },
695     { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, NULL, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
696     { eArgTypeSettingVariableName, "setting-variable-name", CommandCompletions::eNoCompletion, NULL, "The name of a settable internal debugger variable.  Type 'settings list' to see a complete list of such variables." },
697     { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, NULL, "The name of a shared library." },
698     { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, NULL, "The name of a source file.." },
699     { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, NULL, "Specify a sort order when dumping lists." },
700     { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
701     { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, NULL, "Any symbol name (function name, variable, argument, etc.)" },
702     { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, NULL, "Thread ID number." },
703     { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, NULL, "Index into the process' list of threads." },
704     { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, NULL, "The thread's name." },
705     { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, NULL, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
706     { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, NULL, "The name of a variable in your program." },
707     { eArgTypeValue, "value", CommandCompletions::eNoCompletion, NULL, "A value could be anything, depending on where and how it is used." },
708     { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, NULL, "Help text goes here." },
709     { eArgTypeNone, "none", CommandCompletions::eNoCompletion, NULL, "No help available for this." },
710     { eArgTypePlatform, "platform-name", CommandCompletions::ePlatformPluginCompletion, NULL, "The name of an installed platform plug-in . Type 'platform list' to see a complete list of installed platforms." }
711 };
712 
713 const CommandObject::ArgumentTableEntry*
714 CommandObject::GetArgumentTable ()
715 {
716     // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration
717     assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg);
718     return CommandObject::g_arguments_data;
719 }
720 
721 
722