//===-- CommandObject.cpp ---------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/lldb-python.h"

#include "lldb/Interpreter/CommandObject.h"

#include <string>
#include <map>

#include <stdlib.h>
#include <ctype.h>

#include "lldb/Core/Address.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Interpreter/Options.h"

// These are for the Sourcename completers.
// FIXME: Make a separate file for the completers.
#include "lldb/Host/FileSpec.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"

using namespace lldb;
using namespace lldb_private;

//-------------------------------------------------------------------------
// CommandObject
//-------------------------------------------------------------------------

CommandObject::CommandObject 
(
    CommandInterpreter &interpreter, 
    const char *name, 
    const char *help, 
    const char *syntax, 
    uint32_t flags
) :
    m_interpreter (interpreter),
    m_cmd_name (name ? name : ""),
    m_cmd_help_short (),
    m_cmd_help_long (),
    m_cmd_syntax (),
    m_is_alias (false),
    m_flags (flags),
    m_arguments(),
    m_deprecated_command_override_callback (nullptr),
    m_command_override_callback (nullptr),
    m_command_override_baton (nullptr)
{
    if (help && help[0])
        m_cmd_help_short = help;
    if (syntax && syntax[0])
        m_cmd_syntax = syntax;
}

CommandObject::~CommandObject ()
{
}

const char *
CommandObject::GetHelp ()
{
    return m_cmd_help_short.c_str();
}

const char *
CommandObject::GetHelpLong ()
{
    return m_cmd_help_long.c_str();
}

const char *
CommandObject::GetSyntax ()
{
    if (m_cmd_syntax.length() == 0)
    {
        StreamString syntax_str;
        syntax_str.Printf ("%s", GetCommandName());
        if (GetOptions() != nullptr)
            syntax_str.Printf (" <cmd-options>");
        if (m_arguments.size() > 0)
        {
            syntax_str.Printf (" ");
            if (WantsRawCommandString() && GetOptions() && GetOptions()->NumCommandOptions())
                syntax_str.Printf("-- ");
            GetFormattedCommandArguments (syntax_str);
        }
        m_cmd_syntax = syntax_str.GetData ();
    }

    return m_cmd_syntax.c_str();
}

const char *
CommandObject::GetCommandName ()
{
    return m_cmd_name.c_str();
}

void
CommandObject::SetCommandName (const char *name)
{
    m_cmd_name = name;
}

void
CommandObject::SetHelp (const char *cstr)
{
    m_cmd_help_short = cstr;
}

void
CommandObject::SetHelp (std::string str)
{
    m_cmd_help_short = str;
}

void
CommandObject::SetHelpLong (const char *cstr)
{
    m_cmd_help_long = cstr;
}

void
CommandObject::SetHelpLong (std::string str)
{
    m_cmd_help_long = str;
}

void
CommandObject::SetSyntax (const char *cstr)
{
    m_cmd_syntax = cstr;
}

Options *
CommandObject::GetOptions ()
{
    // By default commands don't have options unless this virtual function
    // is overridden by base classes.
    return nullptr;
}

bool
CommandObject::ParseOptions
(
    Args& args,
    CommandReturnObject &result
)
{
    // See if the subclass has options?
    Options *options = GetOptions();
    if (options != nullptr)
    {
        Error error;
        options->NotifyOptionParsingStarting();

        // ParseOptions calls getopt_long_only, which always skips the zero'th item in the array and starts at position 1,
        // so we need to push a dummy value into position zero.
        args.Unshift("dummy_string");
        error = args.ParseOptions (*options);

        // The "dummy_string" will have already been removed by ParseOptions,
        // so no need to remove it.

        if (error.Success())
            error = options->NotifyOptionParsingFinished();

        if (error.Success())
        {
            if (options->VerifyOptions (result))
                return true;
        }
        else
        {
            const char *error_cstr = error.AsCString();
            if (error_cstr)
            {
                // We got an error string, lets use that
                result.AppendError(error_cstr);
            }
            else
            {
                // No error string, output the usage information into result
                options->GenerateOptionUsage (result.GetErrorStream(), this);
            }
        }
        result.SetStatus (eReturnStatusFailed);
        return false;
    }
    return true;
}



bool
CommandObject::CheckRequirements (CommandReturnObject &result)
{
#ifdef LLDB_CONFIGURATION_DEBUG
    // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx
    // has shared pointers to the target, process, thread and frame and we don't
    // want any CommandObject instances to keep any of these objects around
    // longer than for a single command. Every command should call
    // CommandObject::Cleanup() after it has completed
    assert (m_exe_ctx.GetTargetPtr() == NULL);
    assert (m_exe_ctx.GetProcessPtr() == NULL);
    assert (m_exe_ctx.GetThreadPtr() == NULL);
    assert (m_exe_ctx.GetFramePtr() == NULL);
#endif

    // Lock down the interpreter's execution context prior to running the
    // command so we guarantee the selected target, process, thread and frame
    // can't go away during the execution
    m_exe_ctx = m_interpreter.GetExecutionContext();

    const uint32_t flags = GetFlags().Get();
    if (flags & (eFlagRequiresTarget   |
                 eFlagRequiresProcess  |
                 eFlagRequiresThread   |
                 eFlagRequiresFrame    |
                 eFlagTryTargetAPILock ))
    {

        if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope())
        {
            result.AppendError (GetInvalidTargetDescription());
            return false;
        }

        if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
        {
            if (!m_exe_ctx.HasTargetScope())
                result.AppendError (GetInvalidTargetDescription());
            else
                result.AppendError (GetInvalidProcessDescription());
            return false;
        }
        
        if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
        {
            if (!m_exe_ctx.HasTargetScope())
                result.AppendError (GetInvalidTargetDescription());
            else if (!m_exe_ctx.HasProcessScope())
                result.AppendError (GetInvalidProcessDescription());
            else 
                result.AppendError (GetInvalidThreadDescription());
            return false;
        }
        
        if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
        {
            if (!m_exe_ctx.HasTargetScope())
                result.AppendError (GetInvalidTargetDescription());
            else if (!m_exe_ctx.HasProcessScope())
                result.AppendError (GetInvalidProcessDescription());
            else if (!m_exe_ctx.HasThreadScope())
                result.AppendError (GetInvalidThreadDescription());
            else
                result.AppendError (GetInvalidFrameDescription());
            return false;
        }
        
        if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
        {
            result.AppendError (GetInvalidRegContextDescription());
            return false;
        }

        if (flags & eFlagTryTargetAPILock)
        {
            Target *target = m_exe_ctx.GetTargetPtr();
            if (target)
                m_api_locker.Lock (target->GetAPIMutex());
        }
    }

    if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
    {
        Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
        if (process == nullptr)
        {
            // A process that is not running is considered paused.
            if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
            {
                result.AppendError ("Process must exist.");
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
        }
        else
        {
            StateType state = process->GetState();
            switch (state)
            {
            case eStateInvalid:
            case eStateSuspended:
            case eStateCrashed:
            case eStateStopped:
                break;
            
            case eStateConnected:
            case eStateAttaching:
            case eStateLaunching:
            case eStateDetached:
            case eStateExited:
            case eStateUnloaded:
                if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
                {
                    result.AppendError ("Process must be launched.");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                break;

            case eStateRunning:
            case eStateStepping:
                if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
                {
                    result.AppendError ("Process is running.  Use 'process interrupt' to pause execution.");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
        }
    }
    return true;
}

void
CommandObject::Cleanup ()
{
    m_exe_ctx.Clear();
    m_api_locker.Unlock();
}


class CommandDictCommandPartialMatch
{
    public:
        CommandDictCommandPartialMatch (const char *match_str)
        {
            m_match_str = match_str;
        }
        bool operator() (const std::pair<std::string, lldb::CommandObjectSP> map_element) const
        {
            // A NULL or empty string matches everything.
            if (m_match_str == nullptr || *m_match_str == '\0')
                return true;

            return map_element.first.find (m_match_str, 0) == 0;
        }

    private:
        const char *m_match_str;
};

int
CommandObject::AddNamesMatchingPartialString (CommandObject::CommandMap &in_map, const char *cmd_str,
                                              StringList &matches)
{
    int number_added = 0;
    CommandDictCommandPartialMatch matcher(cmd_str);

    CommandObject::CommandMap::iterator matching_cmds = std::find_if (in_map.begin(), in_map.end(), matcher);

    while (matching_cmds != in_map.end())
    {
        ++number_added;
        matches.AppendString((*matching_cmds).first.c_str());
        matching_cmds = std::find_if (++matching_cmds, in_map.end(), matcher);;
    }
    return number_added;
}

int
CommandObject::HandleCompletion
(
    Args &input,
    int &cursor_index,
    int &cursor_char_position,
    int match_start_point,
    int max_return_elements,
    bool &word_complete,
    StringList &matches
)
{
    // Default implmentation of WantsCompletion() is !WantsRawCommandString().
    // Subclasses who want raw command string but desire, for example,
    // argument completion should override WantsCompletion() to return true,
    // instead.
    if (WantsRawCommandString() && !WantsCompletion())
    {
        // FIXME: Abstract telling the completion to insert the completion character.
        matches.Clear();
        return -1;
    }
    else
    {
        // Can we do anything generic with the options?
        Options *cur_options = GetOptions();
        CommandReturnObject result;
        OptionElementVector opt_element_vector;

        if (cur_options != nullptr)
        {
            // Re-insert the dummy command name string which will have been
            // stripped off:
            input.Unshift ("dummy-string");
            cursor_index++;


            // I stick an element on the end of the input, because if the last element is
            // option that requires an argument, getopt_long_only will freak out.

            input.AppendArgument ("<FAKE-VALUE>");

            input.ParseArgsForCompletion (*cur_options, opt_element_vector, cursor_index);

            input.DeleteArgumentAtIndex(input.GetArgumentCount() - 1);

            bool handled_by_options;
            handled_by_options = cur_options->HandleOptionCompletion (input,
                                                                      opt_element_vector,
                                                                      cursor_index,
                                                                      cursor_char_position,
                                                                      match_start_point,
                                                                      max_return_elements,
                                                                      word_complete,
                                                                      matches);
            if (handled_by_options)
                return matches.GetSize();
        }

        // If we got here, the last word is not an option or an option argument.
        return HandleArgumentCompletion (input,
                                         cursor_index,
                                         cursor_char_position,
                                         opt_element_vector,
                                         match_start_point,
                                         max_return_elements,
                                         word_complete,
                                         matches);
    }
}

bool
CommandObject::HelpTextContainsWord (const char *search_word)
{
    std::string options_usage_help;

    bool found_word = false;

    const char *short_help = GetHelp();
    const char *long_help = GetHelpLong();
    const char *syntax_help = GetSyntax();
    
    if (short_help && strcasestr (short_help, search_word))
        found_word = true;
    else if (long_help && strcasestr (long_help, search_word))
        found_word = true;
    else if (syntax_help && strcasestr (syntax_help, search_word))
        found_word = true;

    if (!found_word
        && GetOptions() != nullptr)
    {
        StreamString usage_help;
        GetOptions()->GenerateOptionUsage (usage_help, this);
        if (usage_help.GetSize() > 0)
        {
            const char *usage_text = usage_help.GetData();
            if (strcasestr (usage_text, search_word))
              found_word = true;
        }
    }

    return found_word;
}

int
CommandObject::GetNumArgumentEntries  ()
{
    return m_arguments.size();
}

CommandObject::CommandArgumentEntry *
CommandObject::GetArgumentEntryAtIndex (int idx)
{
    if (static_cast<size_t>(idx) < m_arguments.size())
        return &(m_arguments[idx]);

    return nullptr;
}

CommandObject::ArgumentTableEntry *
CommandObject::FindArgumentDataByType (CommandArgumentType arg_type)
{
    const ArgumentTableEntry *table = CommandObject::GetArgumentTable();

    for (int i = 0; i < eArgTypeLastArg; ++i)
        if (table[i].arg_type == arg_type)
            return (ArgumentTableEntry *) &(table[i]);

    return nullptr;
}

void
CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
{
    const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
    ArgumentTableEntry *entry = (ArgumentTableEntry *) &(table[arg_type]);
    
    // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...

    if (entry->arg_type != arg_type)
        entry = CommandObject::FindArgumentDataByType (arg_type);

    if (!entry)
        return;

    StreamString name_str;
    name_str.Printf ("<%s>", entry->arg_name);

    if (entry->help_function)
    {
        const char* help_text = entry->help_function();
        if (!entry->help_function.self_formatting)
        {
            interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", help_text,
                                                 name_str.GetSize());
        }
        else
        {
            interpreter.OutputHelpText(str, name_str.GetData(), "--", help_text,
                                       name_str.GetSize());
        }
    }
    else
        interpreter.OutputFormattedHelpText (str, name_str.GetData(), "--", entry->help_text, name_str.GetSize());
}

const char *
CommandObject::GetArgumentName (CommandArgumentType arg_type)
{
    ArgumentTableEntry *entry = (ArgumentTableEntry *) &(CommandObject::GetArgumentTable()[arg_type]);

    // The table is *supposed* to be kept in arg_type order, but someone *could* have messed it up...

    if (entry->arg_type != arg_type)
        entry = CommandObject::FindArgumentDataByType (arg_type);

    if (entry)
        return entry->arg_name;

    StreamString str;
    str << "Arg name for type (" << arg_type << ") not in arg table!";
    return str.GetData();
}

bool
CommandObject::IsPairType (ArgumentRepetitionType arg_repeat_type)
{
    if ((arg_repeat_type == eArgRepeatPairPlain)
        ||  (arg_repeat_type == eArgRepeatPairOptional)
        ||  (arg_repeat_type == eArgRepeatPairPlus)
        ||  (arg_repeat_type == eArgRepeatPairStar)
        ||  (arg_repeat_type == eArgRepeatPairRange)
        ||  (arg_repeat_type == eArgRepeatPairRangeOptional))
        return true;

    return false;
}

static CommandObject::CommandArgumentEntry
OptSetFiltered(uint32_t opt_set_mask, CommandObject::CommandArgumentEntry &cmd_arg_entry)
{
    CommandObject::CommandArgumentEntry ret_val;
    for (unsigned i = 0; i < cmd_arg_entry.size(); ++i)
        if (opt_set_mask & cmd_arg_entry[i].arg_opt_set_association)
            ret_val.push_back(cmd_arg_entry[i]);
    return ret_val;
}

// Default parameter value of opt_set_mask is LLDB_OPT_SET_ALL, which means take
// all the argument data into account.  On rare cases where some argument sticks
// with certain option sets, this function returns the option set filtered args.
void
CommandObject::GetFormattedCommandArguments (Stream &str, uint32_t opt_set_mask)
{
    int num_args = m_arguments.size();
    for (int i = 0; i < num_args; ++i)
    {
        if (i > 0)
            str.Printf (" ");
        CommandArgumentEntry arg_entry =
            opt_set_mask == LLDB_OPT_SET_ALL ? m_arguments[i]
                                             : OptSetFiltered(opt_set_mask, m_arguments[i]);
        int num_alternatives = arg_entry.size();

        if ((num_alternatives == 2)
            && IsPairType (arg_entry[0].arg_repetition))
        {
            const char *first_name = GetArgumentName (arg_entry[0].arg_type);
            const char *second_name = GetArgumentName (arg_entry[1].arg_type);
            switch (arg_entry[0].arg_repetition)
            {
                case eArgRepeatPairPlain:
                    str.Printf ("<%s> <%s>", first_name, second_name);
                    break;
                case eArgRepeatPairOptional:
                    str.Printf ("[<%s> <%s>]", first_name, second_name);
                    break;
                case eArgRepeatPairPlus:
                    str.Printf ("<%s> <%s> [<%s> <%s> [...]]", first_name, second_name, first_name, second_name);
                    break;
                case eArgRepeatPairStar:
                    str.Printf ("[<%s> <%s> [<%s> <%s> [...]]]", first_name, second_name, first_name, second_name);
                    break;
                case eArgRepeatPairRange:
                    str.Printf ("<%s_1> <%s_1> ... <%s_n> <%s_n>", first_name, second_name, first_name, second_name);
                    break;
                case eArgRepeatPairRangeOptional:
                    str.Printf ("[<%s_1> <%s_1> ... <%s_n> <%s_n>]", first_name, second_name, first_name, second_name);
                    break;
                // Explicitly test for all the rest of the cases, so if new types get added we will notice the
                // missing case statement(s).
                case eArgRepeatPlain:
                case eArgRepeatOptional:
                case eArgRepeatPlus:
                case eArgRepeatStar:
                case eArgRepeatRange:
                    // These should not be reached, as they should fail the IsPairType test above.
                    break;
            }
        }
        else
        {
            StreamString names;
            for (int j = 0; j < num_alternatives; ++j)
            {
                if (j > 0)
                    names.Printf (" | ");
                names.Printf ("%s", GetArgumentName (arg_entry[j].arg_type));
            }
            switch (arg_entry[0].arg_repetition)
            {
                case eArgRepeatPlain:
                    str.Printf ("<%s>", names.GetData());
                    break;
                case eArgRepeatPlus:
                    str.Printf ("<%s> [<%s> [...]]", names.GetData(), names.GetData());
                    break;
                case eArgRepeatStar:
                    str.Printf ("[<%s> [<%s> [...]]]", names.GetData(), names.GetData());
                    break;
                case eArgRepeatOptional:
                    str.Printf ("[<%s>]", names.GetData());
                    break;
                case eArgRepeatRange:
                    str.Printf ("<%s_1> .. <%s_n>", names.GetData(), names.GetData());
                    break;
                // Explicitly test for all the rest of the cases, so if new types get added we will notice the
                // missing case statement(s).
                case eArgRepeatPairPlain:
                case eArgRepeatPairOptional:
                case eArgRepeatPairPlus:
                case eArgRepeatPairStar:
                case eArgRepeatPairRange:
                case eArgRepeatPairRangeOptional:
                    // These should not be hit, as they should pass the IsPairType test above, and control should
                    // have gone into the other branch of the if statement.
                    break;
            }
        }
    }
}

CommandArgumentType
CommandObject::LookupArgumentName (const char *arg_name)
{
    CommandArgumentType return_type = eArgTypeLastArg;

    std::string arg_name_str (arg_name);
    size_t len = arg_name_str.length();
    if (arg_name[0] == '<'
        && arg_name[len-1] == '>')
        arg_name_str = arg_name_str.substr (1, len-2);

    const ArgumentTableEntry *table = GetArgumentTable();
    for (int i = 0; i < eArgTypeLastArg; ++i)
        if (arg_name_str.compare (table[i].arg_name) == 0)
            return_type = g_arguments_data[i].arg_type;

    return return_type;
}

static const char *
RegisterNameHelpTextCallback ()
{
    return "Register names can be specified using the architecture specific names.  "
    "They can also be specified using generic names.  Not all generic entities have "
    "registers backing them on all architectures.  When they don't the generic name "
    "will return an error.\n"
    "The generic names defined in lldb are:\n"
    "\n"
    "pc       - program counter register\n"
    "ra       - return address register\n"
    "fp       - frame pointer register\n"
    "sp       - stack pointer register\n"
    "flags    - the flags register\n"
    "arg{1-6} - integer argument passing registers.\n";
}

static const char *
BreakpointIDHelpTextCallback ()
{
    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).";
}

static const char *
BreakpointIDRangeHelpTextCallback ()
{
    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.";
}

static const char *
BreakpointNameHelpTextCallback ()
{
    return "A name that can be added to a breakpoint when it is created, or later "
    "on with the \"breakpoint name add\" command.  "
    "Breakpoint names can be used to specify breakpoints in all the places breakpoint ID's "
    "and breakpoint ID ranges can be used.  As such they provide a convenient way to group breakpoints, "
    "and to operate on breakpoints you create without having to track the breakpoint number.  "
    "Note, the attributes you set when using a breakpoint name in a breakpoint command don't "
    "adhere to the name, but instead are set individually on all the breakpoints currently tagged with that name.  Future breakpoints "
    "tagged with that name will not pick up the attributes previously given using that name.  "
    "In order to distinguish breakpoint names from breakpoint ID's and ranges, "
    "names must start with a letter from a-z or A-Z and cannot contain spaces, \".\" or \"-\".  "
    "Also, breakpoint names can only be applied to breakpoints, not to breakpoint locations.";
}

static const char *
GDBFormatHelpTextCallback ()
{
    return "A GDB format consists of a repeat count, a format letter and a size letter. "
    "The repeat count is optional and defaults to 1. The format letter is optional "
    "and defaults to the previous format that was used. The size letter is optional "
    "and defaults to the previous size that was used.\n"
    "\n"
    "Format letters include:\n"
    "o - octal\n"
    "x - hexadecimal\n"
    "d - decimal\n"
    "u - unsigned decimal\n"
    "t - binary\n"
    "f - float\n"
    "a - address\n"
    "i - instruction\n"
    "c - char\n"
    "s - string\n"
    "T - OSType\n"
    "A - float as hex\n"
    "\n"
    "Size letters include:\n"
    "b - 1 byte  (byte)\n"
    "h - 2 bytes (halfword)\n"
    "w - 4 bytes (word)\n"
    "g - 8 bytes (giant)\n"
    "\n"
    "Example formats:\n"
    "32xb - show 32 1 byte hexadecimal integer values\n"
    "16xh - show 16 2 byte hexadecimal integer values\n"
    "64   - show 64 2 byte hexadecimal integer values (format and size from the last format)\n"
    "dw   - show 1 4 byte decimal integer value\n"
    ;
} 

static const char *
FormatHelpTextCallback ()
{
    
    static char* help_text_ptr = nullptr;
    
    if (help_text_ptr)
        return help_text_ptr;
    
    StreamString sstr;
    sstr << "One of the format names (or one-character names) that can be used to show a variable's value:\n";
    for (Format f = eFormatDefault; f < kNumFormats; f = Format(f+1))
    {
        if (f != eFormatDefault)
            sstr.PutChar('\n');
        
        char format_char = FormatManager::GetFormatAsFormatChar(f);
        if (format_char)
            sstr.Printf("'%c' or ", format_char);
        
        sstr.Printf ("\"%s\"", FormatManager::GetFormatAsCString(f));
    }
    
    sstr.Flush();
    
    std::string data = sstr.GetString();
    
    help_text_ptr = new char[data.length()+1];
    
    data.copy(help_text_ptr, data.length());
    
    return help_text_ptr;
}

static const char *
LanguageTypeHelpTextCallback ()
{
    static char* help_text_ptr = nullptr;
    
    if (help_text_ptr)
        return help_text_ptr;
    
    StreamString sstr;
    sstr << "One of the following languages:\n";
    
    for (unsigned int l = eLanguageTypeUnknown; l < eNumLanguageTypes; ++l)
    {
        sstr << "  " << LanguageRuntime::GetNameForLanguageType(static_cast<LanguageType>(l)) << "\n";
    }
    
    sstr.Flush();
    
    std::string data = sstr.GetString();
    
    help_text_ptr = new char[data.length()+1];
    
    data.copy(help_text_ptr, data.length());
    
    return help_text_ptr;
}

static const char *
SummaryStringHelpTextCallback()
{
    return
        "A summary string is a way to extract information from variables in order to present them using a summary.\n"
        "Summary strings contain static text, variables, scopes and control sequences:\n"
        "  - Static text can be any sequence of non-special characters, i.e. anything but '{', '}', '$', or '\\'.\n"
        "  - Variables are sequences of characters beginning with ${, ending with } and that contain symbols in the format described below.\n"
        "  - 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"
        "  - Control sequences are the usual C/C++ '\\a', '\\n', ..., plus '\\$', '\\{' and '\\}'.\n"
        "A summary string works by copying static text verbatim, turning control sequences into their character counterpart, expanding variables and trying to expand scopes.\n"
        "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"
        "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"
        " (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"
        " ${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."
        " 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"
        "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."
        "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"
        " path refers to:\n"
        "  - 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"
        " and displayed as an individual variable\n"
        "  - 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"
        " 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"
        "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"
        "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"
        " special symbols only allowed as part of a variable:\n"
        "    %V: show the value of the object by default\n"
        "    %S: show the summary of the object by default\n"
        "    %@: show the runtime-provided object description (for Objective-C, it calls NSPrintForDebugger; for C/C++ it does nothing)\n"
        "    %L: show the location of the object (memory address or a register name)\n"
        "    %#: show the number of children of the object\n"
        "    %T: show the type of the object\n"
        "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"
        " 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"
        " count the number of actual elements stored in an std::list:\n"
        "type summary add -s \"${svar%#}\" -x \"std::list<\"";
}

static const char *
ExprPathHelpTextCallback()
{
    return
    "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"
    "For instance, given a class:\n"
    "  class foo {\n"
    "      int a;\n"
    "      int b; .\n"
    "      foo* next;\n"
    "  };\n"
    "the expression to read item b in the item pointed to by next for foo aFoo would be aFoo.next->b.\n"
    "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"
    "Expression paths in LLDB include dot (.) and arrow (->) operators, and most commands using expression paths have ways to also accept the star (*) operator.\n"
    "The meaning of these operators is the same as the usual one given to them by the C/C++ standards.\n"
    "LLDB also has support for indexing ([ ]) in expression paths, and extends the traditional meaning of the square brackets operator to allow bitfield extraction:\n"
    "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"
    " 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"
    " 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"
    " meaning of array slicing (taking elements n thru m inside the array or pointed-to memory).";
}

void
CommandObject::GenerateHelpText (CommandReturnObject &result)
{
    GenerateHelpText(result.GetOutputStream());
    
    result.SetStatus (eReturnStatusSuccessFinishNoResult);
}

void
CommandObject::GenerateHelpText (Stream &output_strm)
{
    CommandInterpreter& interpreter = GetCommandInterpreter();
    if (GetOptions() != nullptr)
    {
        if (WantsRawCommandString())
        {
            std::string help_text (GetHelp());
            help_text.append ("  This command takes 'raw' input (no need to quote stuff).");
            interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
        }
        else
            interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
        output_strm.Printf ("\nSyntax: %s\n", GetSyntax());
        GetOptions()->GenerateOptionUsage (output_strm, this);
        const char *long_help = GetHelpLong();
        if ((long_help != nullptr)
            && (strlen (long_help) > 0))
            output_strm.Printf ("\n%s", long_help);
        if (WantsRawCommandString() && !WantsCompletion())
        {
            // Emit the message about using ' -- ' between the end of the command options and the raw input
            // conditionally, i.e., only if the command object does not want completion.
            interpreter.OutputFormattedHelpText (output_strm, "", "",
                                                 "\nIMPORTANT NOTE:  Because this command takes 'raw' input, if you use any command options"
                                                 " you must use ' -- ' between the end of the command options and the beginning of the raw input.", 1);
        }
        else if (GetNumArgumentEntries() > 0
                 && GetOptions()
                 && GetOptions()->NumCommandOptions() > 0)
        {
            // Also emit a warning about using "--" in case you are using a command that takes options and arguments.
            interpreter.OutputFormattedHelpText (output_strm, "", "",
                                                 "\nThis command takes options and free-form arguments.  If your arguments resemble"
                                                 " option specifiers (i.e., they start with a - or --), you must use ' -- ' between"
                                                 " the end of the command options and the beginning of the arguments.", 1);
        }
    }
    else if (IsMultiwordObject())
    {
        if (WantsRawCommandString())
        {
            std::string help_text (GetHelp());
            help_text.append ("  This command takes 'raw' input (no need to quote stuff).");
            interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
        }
        else
            interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
        GenerateHelpText (output_strm);
    }
    else
    {
        const char *long_help = GetHelpLong();
        if ((long_help != nullptr)
            && (strlen (long_help) > 0))
            output_strm.Printf ("%s", long_help);
        else if (WantsRawCommandString())
        {
            std::string help_text (GetHelp());
            help_text.append ("  This command takes 'raw' input (no need to quote stuff).");
            interpreter.OutputFormattedHelpText (output_strm, "", "", help_text.c_str(), 1);
        }
        else
            interpreter.OutputFormattedHelpText (output_strm, "", "", GetHelp(), 1);
        output_strm.Printf ("\nSyntax: %s\n", GetSyntax());
    }
}

void
CommandObject::AddIDsArgumentData(CommandArgumentEntry &arg, CommandArgumentType ID, CommandArgumentType IDRange)
{
    CommandArgumentData id_arg;
    CommandArgumentData id_range_arg;

    // Create the first variant for the first (and only) argument for this command.
    id_arg.arg_type = ID;
    id_arg.arg_repetition = eArgRepeatOptional;

    // Create the second variant for the first (and only) argument for this command.
    id_range_arg.arg_type = IDRange;
    id_range_arg.arg_repetition = eArgRepeatOptional;

    // The first (and only) argument for this command could be either an id or an id_range.
    // Push both variants into the entry for the first argument for this command.
    arg.push_back(id_arg);
    arg.push_back(id_range_arg);
}

const char * 
CommandObject::GetArgumentTypeAsCString (const lldb::CommandArgumentType arg_type)
{
    if (arg_type >=0 && arg_type < eArgTypeLastArg)
        return g_arguments_data[arg_type].arg_name;
    return nullptr;

}

const char * 
CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
{
    if (arg_type >=0 && arg_type < eArgTypeLastArg)
        return g_arguments_data[arg_type].help_text;
    return nullptr;
}

Target *
CommandObject::GetDummyTarget()
{
    return m_interpreter.GetDebugger().GetDummyTarget();
}

Target *
CommandObject::GetSelectedOrDummyTarget(bool prefer_dummy)
{
    return m_interpreter.GetDebugger().GetSelectedOrDummyTarget(prefer_dummy);
}

bool
CommandObjectParsed::Execute (const char *args_string, CommandReturnObject &result)
{
    bool handled = false;
    Args cmd_args (args_string);
    if (HasOverrideCallback())
    {
        Args full_args (GetCommandName ());
        full_args.AppendArguments(cmd_args);
        handled = InvokeOverrideCallback (full_args.GetConstArgumentVector(), result);
    }
    if (!handled)
    {
        for (size_t i = 0; i < cmd_args.GetArgumentCount();  ++i)
        {
            const char *tmp_str = cmd_args.GetArgumentAtIndex (i);
            if (tmp_str[0] == '`')  // back-quote
                cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
        }

        if (CheckRequirements(result))
        {
            if (ParseOptions (cmd_args, result))
            {
                // Call the command-specific version of 'Execute', passing it the already processed arguments.
                handled = DoExecute (cmd_args, result);
            }
        }

        Cleanup();
    }
    return handled;
}

bool
CommandObjectRaw::Execute (const char *args_string, CommandReturnObject &result)
{
    bool handled = false;
    if (HasOverrideCallback())
    {
        std::string full_command (GetCommandName ());
        full_command += ' ';
        full_command += args_string;
        const char *argv[2] = { nullptr, nullptr };
        argv[0] = full_command.c_str();
        handled = InvokeOverrideCallback (argv, result);
    }
    if (!handled)
    {
        if (CheckRequirements(result))
            handled = DoExecute (args_string, result);
        
        Cleanup();
    }
    return handled;
}

static
const char *arch_helper()
{
    static StreamString g_archs_help;
    if (g_archs_help.Empty())
    {
        StringList archs;
        ArchSpec::AutoComplete(nullptr, archs);
        g_archs_help.Printf("These are the supported architecture names:\n");
        archs.Join("\n", g_archs_help);
    }
    return g_archs_help.GetData();
}

CommandObject::ArgumentTableEntry
CommandObject::g_arguments_data[] =
{
    { eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid address in the target program's execution space." },
    { eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "An expression that resolves to an address." },
    { eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of an abbreviation (alias) for a debugger command." },
    { 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.)" },
    { eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." },
    { eArgTypeBoolean, "boolean", CommandCompletions::eNoCompletion, { nullptr, false }, "A Boolean value: 'true' or 'false'" },
    { eArgTypeBreakpointID, "breakpt-id", CommandCompletions::eNoCompletion, { BreakpointIDHelpTextCallback, false }, nullptr },
    { eArgTypeBreakpointIDRange, "breakpt-id-list", CommandCompletions::eNoCompletion, { BreakpointIDRangeHelpTextCallback, false }, nullptr },
    { eArgTypeBreakpointName, "breakpoint-name", CommandCompletions::eNoCompletion, { BreakpointNameHelpTextCallback, false }, nullptr },
    { eArgTypeByteSize, "byte-size", CommandCompletions::eNoCompletion, { nullptr, false }, "Number of bytes to use." },
    { eArgTypeClassName, "class-name", CommandCompletions::eNoCompletion, { nullptr, false }, "Then name of a class from the debug information in the program." },
    { eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A debugger command (may be multiple words), without any options or arguments." },
    { eArgTypeCount, "count", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
    { eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { nullptr, false }, "A directory name." },
    { 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" },
    { eArgTypeDescriptionVerbosity, "description-verbosity", CommandCompletions::eNoCompletion, { nullptr, false }, "How verbose the output of 'po' should be." },
    { eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, nullptr },
    { eArgTypeExprFormat, "expression-format", CommandCompletions::eNoCompletion, { nullptr, false }, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]" },
    { eArgTypeFilename, "filename", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "The name of a file (can include path)." },
    { eArgTypeFormat, "format", CommandCompletions::eNoCompletion, { FormatHelpTextCallback, true }, nullptr },
    { eArgTypeFrameIndex, "frame-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into a thread's list of frames." },
    { eArgTypeFullName, "fullname", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function." },
    { eArgTypeFunctionOrSymbol, "function-or-symbol", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a function or symbol." },
    { eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, nullptr },
    { eArgTypeHelpText, "help-text", CommandCompletions::eNoCompletion, { nullptr, false }, "Text to be used as help for some other entity in LLDB" },
    { eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { nullptr, false }, "An index into a list." },
    { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { LanguageTypeHelpTextCallback, true }, nullptr },
    { eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { nullptr, false }, "Line number in a source file." },
    { 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." },
    { 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)." },
    { eArgTypeMethod, "method", CommandCompletions::eNoCompletion, { nullptr, false }, "A C++ method name." },
    { eArgTypeName, "name", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeNewPathPrefix, "new-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeNumLines, "num-lines", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of lines to use." },
    { eArgTypeNumberPerLine, "number-per-line", CommandCompletions::eNoCompletion, { nullptr, false }, "The number of items per line to display." },
    { eArgTypeOffset, "offset", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeOldPathPrefix, "old-path-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeOneLiner, "one-line-command", CommandCompletions::eNoCompletion, { nullptr, false }, "A command that is entered as a single line of text." },
    { eArgTypePath, "path", CommandCompletions::eDiskFileCompletion, { nullptr, false }, "Path." },
    { eArgTypePermissionsNumber, "perms-numeric", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as an octal number (e.g. 755)." },
    { eArgTypePermissionsString, "perms=string", CommandCompletions::eNoCompletion, { nullptr, false }, "Permissions given as a string value (e.g. rw-r-xr--)." },
    { eArgTypePid, "pid", CommandCompletions::eNoCompletion, { nullptr, false }, "The process ID number." },
    { eArgTypePlugin, "plugin", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeProcessName, "process-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the process." },
    { eArgTypePythonClass, "python-class", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python class." },
    { eArgTypePythonFunction, "python-function", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a Python function." },
    { eArgTypePythonScript, "python-script", CommandCompletions::eNoCompletion, { nullptr, false }, "Source code written in Python." },
    { eArgTypeQueueName, "queue-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of the thread queue." },
    { eArgTypeRegisterName, "register-name", CommandCompletions::eNoCompletion, { RegisterNameHelpTextCallback, true }, nullptr },
    { eArgTypeRegularExpression, "regular-expression", CommandCompletions::eNoCompletion, { nullptr, false }, "A regular expression." },
    { eArgTypeRunArgs, "run-args", CommandCompletions::eNoCompletion, { nullptr, false }, "Arguments to be passed to the target program when it starts executing." },
    { eArgTypeRunMode, "run-mode", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeScriptedCommandSynchronicity, "script-cmd-synchronicity", CommandCompletions::eNoCompletion, { nullptr, false }, "The synchronicity to use to run scripted commands with regard to LLDB event system." },
    { eArgTypeScriptLang, "script-language", CommandCompletions::eNoCompletion, { nullptr, false }, "The scripting language to be used for script-based commands.  Currently only Python is valid." },
    { eArgTypeSearchWord, "search-word", CommandCompletions::eNoCompletion, { nullptr, false }, "The word for which you wish to search for information about." },
    { eArgTypeSelector, "selector", CommandCompletions::eNoCompletion, { nullptr, false }, "An Objective-C selector name." },
    { 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)." },
    { 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)." },
    { eArgTypeSettingPrefix, "setting-prefix", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a settable internal debugger variable up to a dot ('.'), e.g. 'target.process.'" },
    { 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." },
    { eArgTypeShlibName, "shlib-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a shared library." },
    { eArgTypeSourceFile, "source-file", CommandCompletions::eSourceFileCompletion, { nullptr, false }, "The name of a source file.." },
    { eArgTypeSortOrder, "sort-order", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify a sort order when dumping lists." },
    { eArgTypeStartAddress, "start-address", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeSummaryString, "summary-string", CommandCompletions::eNoCompletion, { SummaryStringHelpTextCallback, true }, nullptr },
    { eArgTypeSymbol, "symbol", CommandCompletions::eSymbolCompletion, { nullptr, false }, "Any symbol name (function name, variable, argument, etc.)" },
    { eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Thread ID number." },
    { eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion, { nullptr, false }, "Index into the process' list of threads." },
    { eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The thread's name." },
    { eArgTypeUnsignedInteger, "unsigned-integer", CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
    { eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, { nullptr, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or 9)." },
    { eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, { nullptr, false }, "The name of a variable in your program." },
    { eArgTypeValue, "value", CommandCompletions::eNoCompletion, { nullptr, false }, "A value could be anything, depending on where and how it is used." },
    { eArgTypeWidth, "width", CommandCompletions::eNoCompletion, { nullptr, false }, "Help text goes here." },
    { eArgTypeNone, "none", CommandCompletions::eNoCompletion, { nullptr, false }, "No help available for this." },
    { 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." },
    { eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." },
    { eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." },
    { eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." }
};

const CommandObject::ArgumentTableEntry*
CommandObject::GetArgumentTable ()
{
    // If this assertion fires, then the table above is out of date with the CommandArgumentType enumeration
    assert ((sizeof (CommandObject::g_arguments_data) / sizeof (CommandObject::ArgumentTableEntry)) == eArgTypeLastArg);
    return CommandObject::g_arguments_data;
}


