//===-- 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/Interpreter/CommandObject.h"

#include <string>
#include <sstream>
#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/Target/Language.h"

#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.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 & (eCommandRequiresTarget   |
                 eCommandRequiresProcess  |
                 eCommandRequiresThread   |
                 eCommandRequiresFrame    |
                 eCommandTryTargetAPILock ))
    {

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

        if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope())
        {
            if (!m_exe_ctx.HasTargetScope())
                result.AppendError (GetInvalidTargetDescription());
            else
                result.AppendError (GetInvalidProcessDescription());
            return false;
        }
        
        if ((flags & eCommandRequiresThread) && !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 & eCommandRequiresFrame) && !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 & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
        {
            result.AppendError (GetInvalidRegContextDescription());
            return false;
        }

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

    if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused))
    {
        Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
        if (process == nullptr)
        {
            // A process that is not running is considered paused.
            if (GetFlags().Test(eCommandProcessMustBeLaunched))
            {
                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(eCommandProcessMustBeLaunched))
                {
                    result.AppendError ("Process must be launched.");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                break;

            case eStateRunning:
            case eStateStepping:
                if (GetFlags().Test(eCommandProcessMustBePaused))
                {
                    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 implementation 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;
}

const 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 &(table[i]);

    return nullptr;
}

void
CommandObject::GetArgumentHelp (Stream &str, CommandArgumentType arg_type, CommandInterpreter &interpreter)
{
    const ArgumentTableEntry* table = CommandObject::GetArgumentTable();
    const ArgumentTableEntry *entry = &(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)
{
    const ArgumentTableEntry *entry = &(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";

    Language::PrintAllLanguages(sstr, "  ", "\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::FormatLongHelpText (Stream &output_strm, const char *long_help)
{
    CommandInterpreter& interpreter = GetCommandInterpreter();
    std::stringstream lineStream (long_help);
    std::string line;
    while (std::getline (lineStream, line)) {
        if (line.empty()) {
            output_strm << "\n";
            continue;
        }
        size_t result = line.find_first_not_of (" \t");
        if (result == std::string::npos) {
            result = 0;
        }
        std::string whitespace_prefix = line.substr (0, result);
        std::string remainder = line.substr (result);
        interpreter.OutputFormattedHelpText(output_strm, whitespace_prefix.c_str(), remainder.c_str());
    }
}

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))
            FormatLongHelpText (output_strm, 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))
            FormatLongHelpText (output_strm, 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)
{
    assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentTypeAsCString");
    return g_arguments_data[arg_type].arg_name;
}

const char * 
CommandObject::GetArgumentDescriptionAsCString (const lldb::CommandArgumentType arg_type)
{
    assert(arg_type < eArgTypeLastArg && "Invalid argument type passed to GetArgumentDescriptionAsCString");
    return g_arguments_data[arg_type].help_text;
}

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." },
    { eArgTypeTypeName, "type-name", CommandCompletions::eNoCompletion, { nullptr, false }, "A type 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;
}


