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