//===-- CommandInterpreter.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 <string>
#include <vector>
#include <stdlib.h>

#include "CommandObjectScript.h"
#include "lldb/Interpreter/CommandObjectRegexCommand.h"

#include "../Commands/CommandObjectApropos.h"
#include "../Commands/CommandObjectArgs.h"
#include "../Commands/CommandObjectBreakpoint.h"
#include "../Commands/CommandObjectDisassemble.h"
#include "../Commands/CommandObjectExpression.h"
#include "../Commands/CommandObjectFrame.h"
#include "../Commands/CommandObjectGUI.h"
#include "../Commands/CommandObjectHelp.h"
#include "../Commands/CommandObjectLog.h"
#include "../Commands/CommandObjectMemory.h"
#include "../Commands/CommandObjectPlatform.h"
#include "../Commands/CommandObjectPlugin.h"
#include "../Commands/CommandObjectProcess.h"
#include "../Commands/CommandObjectQuit.h"
#include "../Commands/CommandObjectRegister.h"
#include "../Commands/CommandObjectSettings.h"
#include "../Commands/CommandObjectSource.h"
#include "../Commands/CommandObjectCommands.h"
#include "../Commands/CommandObjectSyntax.h"
#include "../Commands/CommandObjectTarget.h"
#include "../Commands/CommandObjectThread.h"
#include "../Commands/CommandObjectType.h"
#include "../Commands/CommandObjectVersion.h"
#include "../Commands/CommandObjectWatchpoint.h"


#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/Timer.h"

#include "lldb/Host/Editline.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"

#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/ScriptInterpreterNone.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"


#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/TargetList.h"

#include "lldb/Utility/CleanUp.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Path.h"

using namespace lldb;
using namespace lldb_private;


static PropertyDefinition
g_properties[] =
{
    { "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." },
    { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." },
    { "stop-command-source-on-error", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, "If true, LLDB will stop running a 'command source' script upon encountering an error." },
    { nullptr                  , OptionValue::eTypeInvalid, true, 0    , nullptr, nullptr, nullptr }
};

enum
{
    ePropertyExpandRegexAliases = 0,
    ePropertyPromptOnQuit = 1,
    ePropertyStopCmdSourceOnError = 2
};

ConstString &
CommandInterpreter::GetStaticBroadcasterClass ()
{
    static ConstString class_name ("lldb.commandInterpreter");
    return class_name;
}

CommandInterpreter::CommandInterpreter
(
    Debugger &debugger,
    ScriptLanguage script_language,
    bool synchronous_execution
) :
    Broadcaster (&debugger, "lldb.command-interpreter"),
    Properties(OptionValuePropertiesSP(new OptionValueProperties(ConstString("interpreter")))),
    IOHandlerDelegate (IOHandlerDelegate::Completion::LLDBCommand),
    m_debugger (debugger),
    m_synchronous_execution (synchronous_execution),
    m_skip_lldbinit_files (false),
    m_skip_app_init_files (false),
    m_script_interpreter_ap (),
    m_command_io_handler_sp (),
    m_comment_char ('#'),
    m_batch_command_mode (false),
    m_truncation_warning(eNoTruncation),
    m_command_source_depth (0)
{
    debugger.SetScriptLanguage (script_language);
    SetEventName (eBroadcastBitThreadShouldExit, "thread-should-exit");
    SetEventName (eBroadcastBitResetPrompt, "reset-prompt");
    SetEventName (eBroadcastBitQuitCommandReceived, "quit");    
    CheckInWithManager ();
    m_collection_sp->Initialize (g_properties);
}

bool
CommandInterpreter::GetExpandRegexAliases () const
{
    const uint32_t idx = ePropertyExpandRegexAliases;
    return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0);
}

bool
CommandInterpreter::GetPromptOnQuit () const
{
    const uint32_t idx = ePropertyPromptOnQuit;
    return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0);
}

bool
CommandInterpreter::GetStopCmdSourceOnError () const
{
    const uint32_t idx = ePropertyStopCmdSourceOnError;
    return m_collection_sp->GetPropertyAtIndexAsBoolean (nullptr, idx, g_properties[idx].default_uint_value != 0);
}

void
CommandInterpreter::Initialize ()
{
    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

    CommandReturnObject result;

    LoadCommandDictionary ();

    // Set up some initial aliases.
    CommandObjectSP cmd_obj_sp = GetCommandSPExact ("quit", false);
    if (cmd_obj_sp)
    {
        AddAlias ("q", cmd_obj_sp);
        AddAlias ("exit", cmd_obj_sp);
    }
    
    cmd_obj_sp = GetCommandSPExact ("_regexp-attach",false);
    if (cmd_obj_sp)
    {
        AddAlias ("attach", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("process detach",false);
    if (cmd_obj_sp)
    {
        AddAlias ("detach", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("process continue", false);
    if (cmd_obj_sp)
    {
        AddAlias ("c", cmd_obj_sp);
        AddAlias ("continue", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("_regexp-break",false);
    if (cmd_obj_sp)
        AddAlias ("b", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("_regexp-tbreak",false);
    if (cmd_obj_sp)
        AddAlias ("tbreak", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("thread step-inst", false);
    if (cmd_obj_sp)
    {
        AddAlias ("stepi", cmd_obj_sp);
        AddAlias ("si", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("thread step-inst-over", false);
    if (cmd_obj_sp)
    {
        AddAlias ("nexti", cmd_obj_sp);
        AddAlias ("ni", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("thread step-in", false);
    if (cmd_obj_sp)
    {
        AddAlias ("s", cmd_obj_sp);
        AddAlias ("step", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("thread step-over", false);
    if (cmd_obj_sp)
    {
        AddAlias ("n", cmd_obj_sp);
        AddAlias ("next", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("thread step-out", false);
    if (cmd_obj_sp)
    {
        AddAlias ("finish", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("frame select", false);
    if (cmd_obj_sp)
    {
        AddAlias ("f", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("thread select", false);
    if (cmd_obj_sp)
    {
        AddAlias ("t", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("_regexp-jump",false);
    if (cmd_obj_sp)
    {
        AddAlias ("j", cmd_obj_sp);
        AddAlias ("jump", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("_regexp-list", false);
    if (cmd_obj_sp)
    {
        AddAlias ("l", cmd_obj_sp);
        AddAlias ("list", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("_regexp-env", false);
    if (cmd_obj_sp)
    {
        AddAlias ("env", cmd_obj_sp);
    }

    cmd_obj_sp = GetCommandSPExact ("memory read", false);
    if (cmd_obj_sp)
        AddAlias ("x", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("_regexp-up", false);
    if (cmd_obj_sp)
        AddAlias ("up", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("_regexp-down", false);
    if (cmd_obj_sp)
        AddAlias ("down", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("_regexp-display", false);
    if (cmd_obj_sp)
        AddAlias ("display", cmd_obj_sp);
        
    cmd_obj_sp = GetCommandSPExact ("disassemble", false);
    if (cmd_obj_sp)
        AddAlias ("dis", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("disassemble", false);
    if (cmd_obj_sp)
        AddAlias ("di", cmd_obj_sp);



    cmd_obj_sp = GetCommandSPExact ("_regexp-undisplay", false);
    if (cmd_obj_sp)
        AddAlias ("undisplay", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("_regexp-bt", false);
    if (cmd_obj_sp)
        AddAlias ("bt", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("target create", false);
    if (cmd_obj_sp)
        AddAlias ("file", cmd_obj_sp);

    cmd_obj_sp = GetCommandSPExact ("target modules", false);
    if (cmd_obj_sp)
        AddAlias ("image", cmd_obj_sp);


    OptionArgVectorSP alias_arguments_vector_sp (new OptionArgVector);
    
    cmd_obj_sp = GetCommandSPExact ("expression", false);
    if (cmd_obj_sp)
    {        
        ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
        AddAlias ("p", cmd_obj_sp);
        AddAlias ("print", cmd_obj_sp);
        AddAlias ("call", cmd_obj_sp);
        AddOrReplaceAliasOptions ("p", alias_arguments_vector_sp);
        AddOrReplaceAliasOptions ("print", alias_arguments_vector_sp);
        AddOrReplaceAliasOptions ("call", alias_arguments_vector_sp);

        alias_arguments_vector_sp.reset (new OptionArgVector);
        ProcessAliasOptionsArgs (cmd_obj_sp, "-O -- ", alias_arguments_vector_sp);
        AddAlias ("po", cmd_obj_sp);
        AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp);
    }
    
    cmd_obj_sp = GetCommandSPExact ("process kill", false);
    if (cmd_obj_sp)
    {
        AddAlias ("kill", cmd_obj_sp);
    }
    
    cmd_obj_sp = GetCommandSPExact ("process launch", false);
    if (cmd_obj_sp)
    {
        alias_arguments_vector_sp.reset (new OptionArgVector);
#if defined (__arm__) || defined (__arm64__) || defined (__aarch64__)
        ProcessAliasOptionsArgs (cmd_obj_sp, "--", alias_arguments_vector_sp);
#else
        ProcessAliasOptionsArgs (cmd_obj_sp, "--shell=" LLDB_DEFAULT_SHELL " --", alias_arguments_vector_sp);
#endif
        AddAlias ("r", cmd_obj_sp);
        AddAlias ("run", cmd_obj_sp);
        AddOrReplaceAliasOptions ("r", alias_arguments_vector_sp);
        AddOrReplaceAliasOptions ("run", alias_arguments_vector_sp);
    }
    
    cmd_obj_sp = GetCommandSPExact ("target symbols add", false);
    if (cmd_obj_sp)
    {
        AddAlias ("add-dsym", cmd_obj_sp);
    }
    
    cmd_obj_sp = GetCommandSPExact ("breakpoint set", false);
    if (cmd_obj_sp)
    {
        alias_arguments_vector_sp.reset (new OptionArgVector);
        ProcessAliasOptionsArgs (cmd_obj_sp, "--func-regex %1", alias_arguments_vector_sp);
        AddAlias ("rbreak", cmd_obj_sp);
        AddOrReplaceAliasOptions("rbreak", alias_arguments_vector_sp);
    }
}

void
CommandInterpreter::Clear()
{
    m_command_io_handler_sp.reset();
    
    if (m_script_interpreter_ap)
        m_script_interpreter_ap->Clear();
}

const char *
CommandInterpreter::ProcessEmbeddedScriptCommands (const char *arg)
{
    // This function has not yet been implemented.

    // Look for any embedded script command
    // If found,
    //    get interpreter object from the command dictionary,
    //    call execute_one_command on it,
    //    get the results as a string,
    //    substitute that string for current stuff.

    return arg;
}


void
CommandInterpreter::LoadCommandDictionary ()
{
    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

    lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage();
    
    m_command_dict["apropos"]   = CommandObjectSP (new CommandObjectApropos (*this));
    m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
    m_command_dict["command"]   = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
    m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
    m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
    m_command_dict["frame"]     = CommandObjectSP (new CommandObjectMultiwordFrame (*this));
    m_command_dict["gui"]       = CommandObjectSP (new CommandObjectGUI (*this));
    m_command_dict["help"]      = CommandObjectSP (new CommandObjectHelp (*this));
    m_command_dict["log"]       = CommandObjectSP (new CommandObjectLog (*this));
    m_command_dict["memory"]    = CommandObjectSP (new CommandObjectMemory (*this));
    m_command_dict["platform"]  = CommandObjectSP (new CommandObjectPlatform (*this));
    m_command_dict["plugin"]    = CommandObjectSP (new CommandObjectPlugin (*this));
    m_command_dict["process"]   = CommandObjectSP (new CommandObjectMultiwordProcess (*this));
    m_command_dict["quit"]      = CommandObjectSP (new CommandObjectQuit (*this));
    m_command_dict["register"]  = CommandObjectSP (new CommandObjectRegister (*this));
    m_command_dict["script"]    = CommandObjectSP (new CommandObjectScript (*this, script_language));
    m_command_dict["settings"]  = CommandObjectSP (new CommandObjectMultiwordSettings (*this));
    m_command_dict["source"]    = CommandObjectSP (new CommandObjectMultiwordSource (*this));
    m_command_dict["target"]    = CommandObjectSP (new CommandObjectMultiwordTarget (*this));
    m_command_dict["thread"]    = CommandObjectSP (new CommandObjectMultiwordThread (*this));
    m_command_dict["type"]      = CommandObjectSP (new CommandObjectType (*this));
    m_command_dict["version"]   = CommandObjectSP (new CommandObjectVersion (*this));
    m_command_dict["watchpoint"]= CommandObjectSP (new CommandObjectMultiwordWatchpoint (*this));

    const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"},
                                      {"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"},
                                      {"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
                                      {"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
                                      {"^(-.*)$", "breakpoint set %1"},
                                      {"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"},
                                      {"^\\&(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1' --skip-prologue=0"},
                                      {"^[\"']?(.*[^[:space:]\"'])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"}};
    
    size_t num_regexes = llvm::array_lengthof(break_regexes);
        
    std::unique_ptr<CommandObjectRegexCommand>
    break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                      "_regexp-break",
                                                      "Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
                                                      "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
                                                      2,
                                                      CommandCompletions::eSymbolCompletion |
                                                      CommandCompletions::eSourceFileCompletion));

    if (break_regex_cmd_ap.get())
    {
        bool success = true;
        for (size_t i = 0; i < num_regexes; i++)
        {
            success = break_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], break_regexes[i][1]);
            if (!success)
                break;
        }
        success = break_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full");

        if (success)
        {
            CommandObjectSP break_regex_cmd_sp(break_regex_cmd_ap.release());
            m_command_dict[break_regex_cmd_sp->GetCommandName ()] = break_regex_cmd_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    tbreak_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                      "_regexp-tbreak",
                                                      "Set a one shot breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
                                                      "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
                                                       2,
                                                       CommandCompletions::eSymbolCompletion |
                                                       CommandCompletions::eSourceFileCompletion));

    if (tbreak_regex_cmd_ap.get())
    {
        bool success = true;
        for (size_t i = 0; i < num_regexes; i++)
        {
            // If you add a resultant command string longer than 1024 characters be sure to increase the size of this buffer.
            char buffer[1024];
            int num_printed = snprintf(buffer, 1024, "%s %s", break_regexes[i][1], "-o");
            assert (num_printed < 1024);
            success = tbreak_regex_cmd_ap->AddRegexCommand (break_regexes[i][0], buffer);
            if (!success)
                break;
        }
        success = tbreak_regex_cmd_ap->AddRegexCommand("^$", "breakpoint list --full");

        if (success)
        {
            CommandObjectSP tbreak_regex_cmd_sp(tbreak_regex_cmd_ap.release());
            m_command_dict[tbreak_regex_cmd_sp->GetCommandName ()] = tbreak_regex_cmd_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    attach_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                       "_regexp-attach",
                                                       "Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.",
                                                       "_regexp-attach [<pid>]\n_regexp-attach [<process-name>]",
                                                       2));
    if (attach_regex_cmd_ap.get())
    {
        if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") &&
            attach_regex_cmd_ap->AddRegexCommand("^(-.*|.* -.*)$", "process attach %1") && // Any options that are specified get passed to 'process attach'
            attach_regex_cmd_ap->AddRegexCommand("^(.+)$", "process attach --name '%1'") &&
            attach_regex_cmd_ap->AddRegexCommand("^$", "process attach"))
        {
            CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_ap.release());
            m_command_dict[attach_regex_cmd_sp->GetCommandName ()] = attach_regex_cmd_sp;
        }
    }
    
    std::unique_ptr<CommandObjectRegexCommand>
    down_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                     "_regexp-down",
                                                     "Go down \"n\" frames in the stack (1 frame by default).",
                                                     "_regexp-down [n]", 2));
    if (down_regex_cmd_ap.get())
    {
        if (down_regex_cmd_ap->AddRegexCommand("^$", "frame select -r -1") &&
            down_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r -%1"))
        {
            CommandObjectSP down_regex_cmd_sp(down_regex_cmd_ap.release());
            m_command_dict[down_regex_cmd_sp->GetCommandName ()] = down_regex_cmd_sp;
        }
    }
    
    std::unique_ptr<CommandObjectRegexCommand>
    up_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                   "_regexp-up",
                                                   "Go up \"n\" frames in the stack (1 frame by default).",
                                                   "_regexp-up [n]", 2));
    if (up_regex_cmd_ap.get())
    {
        if (up_regex_cmd_ap->AddRegexCommand("^$", "frame select -r 1") &&
            up_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "frame select -r %1"))
        {
            CommandObjectSP up_regex_cmd_sp(up_regex_cmd_ap.release());
            m_command_dict[up_regex_cmd_sp->GetCommandName ()] = up_regex_cmd_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    display_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                        "_regexp-display",
                                                        "Add an expression evaluation stop-hook.",
                                                        "_regexp-display expression", 2));
    if (display_regex_cmd_ap.get())
    {
        if (display_regex_cmd_ap->AddRegexCommand("^(.+)$", "target stop-hook add -o \"expr -- %1\""))
        {
            CommandObjectSP display_regex_cmd_sp(display_regex_cmd_ap.release());
            m_command_dict[display_regex_cmd_sp->GetCommandName ()] = display_regex_cmd_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    undisplay_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                          "_regexp-undisplay",
                                                          "Remove an expression evaluation stop-hook.",
                                                          "_regexp-undisplay stop-hook-number", 2));
    if (undisplay_regex_cmd_ap.get())
    {
        if (undisplay_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "target stop-hook delete %1"))
        {
            CommandObjectSP undisplay_regex_cmd_sp(undisplay_regex_cmd_ap.release());
            m_command_dict[undisplay_regex_cmd_sp->GetCommandName ()] = undisplay_regex_cmd_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    connect_gdb_remote_cmd_ap(new CommandObjectRegexCommand (*this,
                                                             "gdb-remote",
                                                             "Connect to a remote GDB server.  If no hostname is provided, localhost is assumed.",
                                                             "gdb-remote [<hostname>:]<portnum>", 2));
    if (connect_gdb_remote_cmd_ap.get())
    {
        if (connect_gdb_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin gdb-remote connect://%1") &&
            connect_gdb_remote_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "process connect --plugin gdb-remote connect://localhost:%1"))
        {
            CommandObjectSP command_sp(connect_gdb_remote_cmd_ap.release());
            m_command_dict[command_sp->GetCommandName ()] = command_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    connect_kdp_remote_cmd_ap(new CommandObjectRegexCommand (*this,
                                                             "kdp-remote",
                                                             "Connect to a remote KDP server.  udp port 41139 is the default port number.",
                                                             "kdp-remote <hostname>[:<portnum>]", 2));
    if (connect_kdp_remote_cmd_ap.get())
    {
        if (connect_kdp_remote_cmd_ap->AddRegexCommand("^([^:]+:[[:digit:]]+)$", "process connect --plugin kdp-remote udp://%1") &&
            connect_kdp_remote_cmd_ap->AddRegexCommand("^(.+)$", "process connect --plugin kdp-remote udp://%1:41139"))
        {
            CommandObjectSP command_sp(connect_kdp_remote_cmd_ap.release());
            m_command_dict[command_sp->GetCommandName ()] = command_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    bt_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                     "_regexp-bt",
                                                     "Show a backtrace.  An optional argument is accepted; if that argument is a number, it specifies the number of frames to display.  If that argument is 'all', full backtraces of all threads are displayed.",
                                                     "bt [<digit>|all]", 2));
    if (bt_regex_cmd_ap.get())
    {
        // accept but don't document "bt -c <number>" -- before bt was a regex command if you wanted to backtrace
        // three frames you would do "bt -c 3" but the intention is to have this emulate the gdb "bt" command and
        // so now "bt 3" is the preferred form, in line with gdb.
        if (bt_regex_cmd_ap->AddRegexCommand("^([[:digit:]]+)$", "thread backtrace -c %1") &&
            bt_regex_cmd_ap->AddRegexCommand("^-c ([[:digit:]]+)$", "thread backtrace -c %1") &&
            bt_regex_cmd_ap->AddRegexCommand("^all$", "thread backtrace all") &&
            bt_regex_cmd_ap->AddRegexCommand("^$", "thread backtrace"))
        {
            CommandObjectSP command_sp(bt_regex_cmd_ap.release());
            m_command_dict[command_sp->GetCommandName ()] = command_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    list_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                     "_regexp-list",
                                                     "Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands.",
                                                     "_regexp-list [<line>]\n_regexp-list [<file>:<line>]\n_regexp-list [<file>:<line>]",
                                                     2,
                                                     CommandCompletions::eSourceFileCompletion));
    if (list_regex_cmd_ap.get())
    {
        if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") &&
            list_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "source list --file '%1' --line %2") &&
            list_regex_cmd_ap->AddRegexCommand("^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "source list --address %1") &&
            list_regex_cmd_ap->AddRegexCommand("^-[[:space:]]*$", "source list --reverse") &&
            list_regex_cmd_ap->AddRegexCommand("^-([[:digit:]]+)[[:space:]]*$", "source list --reverse --count %1") &&
            list_regex_cmd_ap->AddRegexCommand("^(.+)$", "source list --name \"%1\"") &&
            list_regex_cmd_ap->AddRegexCommand("^$", "source list"))
        {
            CommandObjectSP list_regex_cmd_sp(list_regex_cmd_ap.release());
            m_command_dict[list_regex_cmd_sp->GetCommandName ()] = list_regex_cmd_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    env_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                    "_regexp-env",
                                                    "Implements a shortcut to viewing and setting environment variables.",
                                                    "_regexp-env\n_regexp-env FOO=BAR", 2));
    if (env_regex_cmd_ap.get())
    {
        if (env_regex_cmd_ap->AddRegexCommand("^$", "settings show target.env-vars") &&
            env_regex_cmd_ap->AddRegexCommand("^([A-Za-z_][A-Za-z_0-9]*=.*)$", "settings set target.env-vars %1"))
        {
            CommandObjectSP env_regex_cmd_sp(env_regex_cmd_ap.release());
            m_command_dict[env_regex_cmd_sp->GetCommandName ()] = env_regex_cmd_sp;
        }
    }

    std::unique_ptr<CommandObjectRegexCommand>
    jump_regex_cmd_ap(new CommandObjectRegexCommand (*this,
                                                    "_regexp-jump",
                                                    "Sets the program counter to a new address.",
                                                    "_regexp-jump [<line>]\n"
                                                    "_regexp-jump [<+-lineoffset>]\n"
                                                    "_regexp-jump [<file>:<line>]\n"
                                                    "_regexp-jump [*<addr>]\n", 2));
    if (jump_regex_cmd_ap.get())
    {
        if (jump_regex_cmd_ap->AddRegexCommand("^\\*(.*)$", "thread jump --addr %1") &&
            jump_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "thread jump --line %1") &&
            jump_regex_cmd_ap->AddRegexCommand("^([^:]+):([0-9]+)$", "thread jump --file %1 --line %2") &&
            jump_regex_cmd_ap->AddRegexCommand("^([+\\-][0-9]+)$", "thread jump --by %1"))
        {
            CommandObjectSP jump_regex_cmd_sp(jump_regex_cmd_ap.release());
            m_command_dict[jump_regex_cmd_sp->GetCommandName ()] = jump_regex_cmd_sp;
        }
    }

}

int
CommandInterpreter::GetCommandNamesMatchingPartialString (const char *cmd_str, bool include_aliases,
                                                          StringList &matches)
{
    CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_str, matches);

    if (include_aliases)
    {
        CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_str, matches);
    }

    return matches.GetSize();
}

CommandObjectSP
CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches)
{
    CommandObject::CommandMap::iterator pos;
    CommandObjectSP command_sp;

    std::string cmd(cmd_cstr);

    if (HasCommands())
    {
        pos = m_command_dict.find(cmd);
        if (pos != m_command_dict.end())
            command_sp = pos->second;
    }

    if (include_aliases && HasAliases())
    {
        pos = m_alias_dict.find(cmd);
        if (pos != m_alias_dict.end())
            command_sp = pos->second;
    }

    if (HasUserCommands())
    {
        pos = m_user_dict.find(cmd);
        if (pos != m_user_dict.end())
            command_sp = pos->second;
    }

    if (!exact && !command_sp)
    {
        // We will only get into here if we didn't find any exact matches.
        
        CommandObjectSP user_match_sp, alias_match_sp, real_match_sp;

        StringList local_matches;
        if (matches == nullptr)
            matches = &local_matches;

        unsigned int num_cmd_matches = 0;
        unsigned int num_alias_matches = 0;
        unsigned int num_user_matches = 0;
        
        // Look through the command dictionaries one by one, and if we get only one match from any of
        // them in toto, then return that, otherwise return an empty CommandObjectSP and the list of matches.
        
        if (HasCommands())
        {
            num_cmd_matches = CommandObject::AddNamesMatchingPartialString (m_command_dict, cmd_cstr, *matches);
        }

        if (num_cmd_matches == 1)
        {
            cmd.assign(matches->GetStringAtIndex(0));
            pos = m_command_dict.find(cmd);
            if (pos != m_command_dict.end())
                real_match_sp = pos->second;
        }

        if (include_aliases && HasAliases())
        {
            num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd_cstr, *matches);

        }

        if (num_alias_matches == 1)
        {
            cmd.assign(matches->GetStringAtIndex (num_cmd_matches));
            pos = m_alias_dict.find(cmd);
            if (pos != m_alias_dict.end())
                alias_match_sp = pos->second;
        }

        if (HasUserCommands())
        {
            num_user_matches = CommandObject::AddNamesMatchingPartialString (m_user_dict, cmd_cstr, *matches);
        }

        if (num_user_matches == 1)
        {
            cmd.assign (matches->GetStringAtIndex (num_cmd_matches + num_alias_matches));

            pos = m_user_dict.find (cmd);
            if (pos != m_user_dict.end())
                user_match_sp = pos->second;
        }
        
        // If we got exactly one match, return that, otherwise return the match list.
        
        if (num_user_matches + num_cmd_matches + num_alias_matches == 1)
        {
            if (num_cmd_matches)
                return real_match_sp;
            else if (num_alias_matches)
                return alias_match_sp;
            else
                return user_match_sp;
        }
    }
    else if (matches && command_sp)
    {
        matches->AppendString (cmd_cstr);
    }


    return command_sp;
}

bool
CommandInterpreter::AddCommand (const char *name, const lldb::CommandObjectSP &cmd_sp, bool can_replace)
{
    if (name && name[0])
    {
        std::string name_sstr(name);
        bool found = (m_command_dict.find (name_sstr) != m_command_dict.end());
        if (found && !can_replace)
            return false;
        if (found && m_command_dict[name_sstr]->IsRemovable() == false)
            return false;
        m_command_dict[name_sstr] = cmd_sp;
        return true;
    }
    return false;
}

bool
CommandInterpreter::AddUserCommand (std::string name, 
                                    const lldb::CommandObjectSP &cmd_sp,
                                    bool can_replace)
{
    if (!name.empty())
    {
        
        const char* name_cstr = name.c_str();
        
        // do not allow replacement of internal commands
        if (CommandExists(name_cstr))
        {
            if (can_replace == false)
                return false;
            if (m_command_dict[name]->IsRemovable() == false)
                return false;
        }
        
        if (UserCommandExists(name_cstr))
        {
            if (can_replace == false)
                return false;
            if (m_user_dict[name]->IsRemovable() == false)
                return false;
        }
        
        m_user_dict[name] = cmd_sp;
        return true;
    }
    return false;
}

CommandObjectSP
CommandInterpreter::GetCommandSPExact (const char *cmd_cstr, bool include_aliases)
{
    Args cmd_words (cmd_cstr); // Break up the command string into words, in case it's a multi-word command.
    CommandObjectSP ret_val;   // Possibly empty return value.
    
    if (cmd_cstr == nullptr)
        return ret_val;
    
    if (cmd_words.GetArgumentCount() == 1)
        return GetCommandSP(cmd_cstr, include_aliases, true, nullptr);
    else
    {
        // We have a multi-word command (seemingly), so we need to do more work.
        // First, get the cmd_obj_sp for the first word in the command.
        CommandObjectSP cmd_obj_sp = GetCommandSP (cmd_words.GetArgumentAtIndex (0), include_aliases, true, nullptr);
        if (cmd_obj_sp.get() != nullptr)
        {
            // Loop through the rest of the words in the command (everything passed in was supposed to be part of a 
            // command name), and find the appropriate sub-command SP for each command word....
            size_t end = cmd_words.GetArgumentCount();
            for (size_t j= 1; j < end; ++j)
            {
                if (cmd_obj_sp->IsMultiwordObject())
                {
                    cmd_obj_sp = cmd_obj_sp->GetSubcommandSP (cmd_words.GetArgumentAtIndex (j));
                    if (cmd_obj_sp.get() == nullptr)
                        // The sub-command name was invalid.  Fail and return the empty 'ret_val'.
                        return ret_val;
                }
                else
                    // We have more words in the command name, but we don't have a multiword object. Fail and return 
                    // empty 'ret_val'.
                    return ret_val;
            }
            // We successfully looped through all the command words and got valid command objects for them.  Assign the 
            // last object retrieved to 'ret_val'.
            ret_val = cmd_obj_sp;
        }
    }
    return ret_val;
}

CommandObject *
CommandInterpreter::GetCommandObjectExact (const char *cmd_cstr, bool include_aliases)
{
    return GetCommandSPExact (cmd_cstr, include_aliases).get();
}

CommandObject *
CommandInterpreter::GetCommandObject (const char *cmd_cstr, StringList *matches)
{
    CommandObject *command_obj = GetCommandSP (cmd_cstr, false, true, matches).get();

    // If we didn't find an exact match to the command string in the commands, look in
    // the aliases.
    
    if (command_obj)
        return command_obj;

    command_obj = GetCommandSP (cmd_cstr, true, true, matches).get();

    if (command_obj)
        return command_obj;
    
    // If there wasn't an exact match then look for an inexact one in just the commands
    command_obj = GetCommandSP(cmd_cstr, false, false, nullptr).get();

    // Finally, if there wasn't an inexact match among the commands, look for an inexact
    // match in both the commands and aliases.
    
    if (command_obj)
    {
        if (matches)
            matches->AppendString(command_obj->GetCommandName());
        return command_obj;
    }
    
    return GetCommandSP(cmd_cstr, true, false, matches).get();
}

bool
CommandInterpreter::CommandExists (const char *cmd)
{
    return m_command_dict.find(cmd) != m_command_dict.end();
}

bool
CommandInterpreter::ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp, 
                                            const char *options_args, 
                                            OptionArgVectorSP &option_arg_vector_sp)
{
    bool success = true;
    OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
    
    if (!options_args || (strlen (options_args) < 1))
        return true;

    std::string options_string (options_args);
    Args args (options_args);
    CommandReturnObject result;
    // Check to see if the command being aliased can take any command options.
    Options *options = cmd_obj_sp->GetOptions ();
    if (options)
    {
        // See if any options were specified as part of the alias;  if so, handle them appropriately.
        options->NotifyOptionParsingStarting ();
        args.Unshift ("dummy_arg");
        args.ParseAliasOptions (*options, result, option_arg_vector, options_string);
        args.Shift ();
        if (result.Succeeded())
            options->VerifyPartialOptions (result);
        if (!result.Succeeded() && result.GetStatus() != lldb::eReturnStatusStarted)
        {
            result.AppendError ("Unable to create requested alias.\n");
            return false;
        }
    }
    
    if (!options_string.empty())
    {
        if (cmd_obj_sp->WantsRawCommandString ())
            option_arg_vector->push_back (OptionArgPair ("<argument>",
                                                          OptionArgValue (-1,
                                                                          options_string)));
        else
        {
            const size_t argc = args.GetArgumentCount();
            for (size_t i = 0; i < argc; ++i)
                if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
                    option_arg_vector->push_back 
                                (OptionArgPair ("<argument>",
                                                OptionArgValue (-1,
                                                                std::string (args.GetArgumentAtIndex (i)))));
        }
    }
        
    return success;
}

bool
CommandInterpreter::GetAliasFullName (const char *cmd, std::string &full_name)
{
    bool exact_match  = (m_alias_dict.find(cmd) != m_alias_dict.end());
    if (exact_match)
    {
        full_name.assign(cmd);
        return exact_match;
    }
    else
    {
        StringList matches;
        size_t num_alias_matches;
        num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd, matches);
        if (num_alias_matches == 1)
        {
            // Make sure this isn't shadowing a command in the regular command space:
            StringList regular_matches;
            const bool include_aliases = false;
            const bool exact = false;
            CommandObjectSP cmd_obj_sp(GetCommandSP (cmd, include_aliases, exact, &regular_matches));
            if (cmd_obj_sp || regular_matches.GetSize() > 0)
                return false;
            else
            {
                full_name.assign (matches.GetStringAtIndex(0));
                return true;
            }
        }
        else
            return false;
    }
}

bool
CommandInterpreter::AliasExists (const char *cmd)
{
    return m_alias_dict.find(cmd) != m_alias_dict.end();
}

bool
CommandInterpreter::UserCommandExists (const char *cmd)
{
    return m_user_dict.find(cmd) != m_user_dict.end();
}

void
CommandInterpreter::AddAlias (const char *alias_name, CommandObjectSP& command_obj_sp)
{
    command_obj_sp->SetIsAlias (true);
    m_alias_dict[alias_name] = command_obj_sp;
}

bool
CommandInterpreter::RemoveAlias (const char *alias_name)
{
    CommandObject::CommandMap::iterator pos = m_alias_dict.find(alias_name);
    if (pos != m_alias_dict.end())
    {
        m_alias_dict.erase(pos);
        return true;
    }
    return false;
}
bool
CommandInterpreter::RemoveUser (const char *alias_name)
{
    CommandObject::CommandMap::iterator pos = m_user_dict.find(alias_name);
    if (pos != m_user_dict.end())
    {
        m_user_dict.erase(pos);
        return true;
    }
    return false;
}

void
CommandInterpreter::GetAliasHelp (const char *alias_name, const char *command_name, StreamString &help_string)
{
    help_string.Printf ("'%s", command_name);
    OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);

    if (option_arg_vector_sp)
    {
        OptionArgVector *options = option_arg_vector_sp.get();
        for (size_t i = 0; i < options->size(); ++i)
        {
            OptionArgPair cur_option = (*options)[i];
            std::string opt = cur_option.first;
            OptionArgValue value_pair = cur_option.second;
            std::string value = value_pair.second;
            if (opt.compare("<argument>") == 0)
            {
                help_string.Printf (" %s", value.c_str());
            }
            else
            {
                help_string.Printf (" %s", opt.c_str());
                if ((value.compare ("<no-argument>") != 0)
                    && (value.compare ("<need-argument") != 0))
                {
                    help_string.Printf (" %s", value.c_str());
                }
            }
        }
    }

    help_string.Printf ("'");
}

size_t
CommandInterpreter::FindLongestCommandWord (CommandObject::CommandMap &dict)
{
    CommandObject::CommandMap::const_iterator pos;
    CommandObject::CommandMap::const_iterator end = dict.end();
    size_t max_len = 0;

    for (pos = dict.begin(); pos != end; ++pos)
    {
        size_t len = pos->first.size();
        if (max_len < len)
            max_len = len;
    }
    return max_len;
}

void
CommandInterpreter::GetHelp (CommandReturnObject &result,
                             uint32_t cmd_types)
{
    CommandObject::CommandMap::const_iterator pos;
    size_t max_len = FindLongestCommandWord (m_command_dict);
    
    if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
    {
    
        result.AppendMessage("The following is a list of built-in, permanent debugger commands:");
        result.AppendMessage("");

        for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
        {
            OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
                                     max_len);
        }
        result.AppendMessage("");

    }

    if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases ))
    {
        result.AppendMessage("The following is a list of your current command abbreviations "
                             "(see 'help command alias' for more info):");
        result.AppendMessage("");
        max_len = FindLongestCommandWord (m_alias_dict);

        for (pos = m_alias_dict.begin(); pos != m_alias_dict.end(); ++pos)
        {
            StreamString sstr;
            StreamString translation_and_help;
            std::string entry_name = pos->first;
            std::string second_entry = pos->second.get()->GetCommandName();
            GetAliasHelp (pos->first.c_str(), pos->second->GetCommandName(), sstr);
            
            translation_and_help.Printf ("(%s)  %s", sstr.GetData(), pos->second->GetHelp());
            OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", 
                                     translation_and_help.GetData(), max_len);
        }
        result.AppendMessage("");
    }

    if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef ))
    {
        result.AppendMessage ("The following is a list of your current user-defined commands:");
        result.AppendMessage("");
        max_len = FindLongestCommandWord (m_user_dict);
        for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
        {
            OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(),
                                     max_len);
        }
        result.AppendMessage("");
    }

    result.AppendMessage("For more information on any particular command, try 'help <command-name>'.");
}

CommandObject *
CommandInterpreter::GetCommandObjectForCommand (std::string &command_string)
{
    // This function finds the final, lowest-level, alias-resolved command object whose 'Execute' function will
    // eventually be invoked by the given command line.
    
    CommandObject *cmd_obj = nullptr;
    std::string white_space (" \t\v");
    size_t start = command_string.find_first_not_of (white_space);
    size_t end = 0;
    bool done = false;
    while (!done)
    {
        if (start != std::string::npos)
        {
            // Get the next word from command_string.
            end = command_string.find_first_of (white_space, start);
            if (end == std::string::npos)
                end = command_string.size();
            std::string cmd_word = command_string.substr (start, end - start);
            
            if (cmd_obj == nullptr)
                // Since cmd_obj is NULL we are on our first time through this loop. Check to see if cmd_word is a valid 
                // command or alias.
                cmd_obj = GetCommandObject (cmd_word.c_str());
            else if (cmd_obj->IsMultiwordObject ())
            {
                // Our current object is a multi-word object; see if the cmd_word is a valid sub-command for our object.
                CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (cmd_word.c_str());
                if (sub_cmd_obj)
                    cmd_obj = sub_cmd_obj;
                else // cmd_word was not a valid sub-command word, so we are donee
                    done = true;
            }
            else  
                // We have a cmd_obj and it is not a multi-word object, so we are done.
                done = true;

            // If we didn't find a valid command object, or our command object is not a multi-word object, or
            // we are at the end of the command_string, then we are done.  Otherwise, find the start of the
            // next word.
            
            if (!cmd_obj || !cmd_obj->IsMultiwordObject() || end >= command_string.size())
                done = true;
            else
                start = command_string.find_first_not_of (white_space, end);
        }
        else
            // Unable to find any more words.
            done = true;
    }
    
    if (end == command_string.size())
        command_string.clear();
    else
        command_string = command_string.substr(end);
    
    return cmd_obj;
}

static const char *k_white_space = " \t\v";
static const char *k_valid_command_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
static void
StripLeadingSpaces (std::string &s)
{
    if (!s.empty())
    {
        size_t pos = s.find_first_not_of (k_white_space);
        if (pos == std::string::npos)
            s.clear();
        else if (pos == 0)
            return;
        s.erase (0, pos);
    }
}

static size_t
FindArgumentTerminator (const std::string &s)
{
    const size_t s_len = s.size();
    size_t offset = 0;
    while (offset < s_len)
    {
        size_t pos = s.find ("--", offset);
        if (pos == std::string::npos)
            break;
        if (pos > 0)
        {
            if (isspace(s[pos-1]))
            {
                // Check if the string ends "\s--" (where \s is a space character)
                // or if we have "\s--\s".
                if ((pos + 2 >= s_len) || isspace(s[pos+2]))
                {
                    return pos;
                }
            }
        }
        offset = pos + 2;
    }
    return std::string::npos;
}

static bool
ExtractCommand (std::string &command_string, std::string &command, std::string &suffix, char &quote_char)
{
    command.clear();
    suffix.clear();
    StripLeadingSpaces (command_string);

    bool result = false;
    quote_char = '\0';
    
    if (!command_string.empty())
    {
        const char first_char = command_string[0];
        if (first_char == '\'' || first_char == '"')
        {
            quote_char = first_char;
            const size_t end_quote_pos = command_string.find (quote_char, 1);
            if (end_quote_pos == std::string::npos)
            {
                command.swap (command_string);
                command_string.erase ();
            }
            else
            {
                command.assign (command_string, 1, end_quote_pos - 1);
                if (end_quote_pos + 1 < command_string.size())
                    command_string.erase (0, command_string.find_first_not_of (k_white_space, end_quote_pos + 1));
                else
                    command_string.erase ();
            }
        }
        else
        {
            const size_t first_space_pos = command_string.find_first_of (k_white_space);
            if (first_space_pos == std::string::npos)
            {
                command.swap (command_string);
                command_string.erase();
            }
            else
            {
                command.assign (command_string, 0, first_space_pos);
                command_string.erase(0, command_string.find_first_not_of (k_white_space, first_space_pos));
            }
        }
        result = true;
    }
    
    
    if (!command.empty())
    {
        // actual commands can't start with '-' or '_'
        if (command[0] != '-' && command[0] != '_')
        {
            size_t pos = command.find_first_not_of(k_valid_command_chars);
            if (pos > 0 && pos != std::string::npos)
            {
                suffix.assign (command.begin() + pos, command.end());
                command.erase (pos);
            }
        }
    }

    return result;
}

CommandObject *
CommandInterpreter::BuildAliasResult (const char *alias_name, 
                                      std::string &raw_input_string, 
                                      std::string &alias_result,
                                      CommandReturnObject &result)
{
    CommandObject *alias_cmd_obj = nullptr;
    Args cmd_args (raw_input_string.c_str());
    alias_cmd_obj = GetCommandObject (alias_name);
    StreamString result_str;
    
    if (alias_cmd_obj)
    {
        std::string alias_name_str = alias_name;
        if ((cmd_args.GetArgumentCount() == 0)
            || (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0))
            cmd_args.Unshift (alias_name);
            
        result_str.Printf ("%s", alias_cmd_obj->GetCommandName ());
        OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);

        if (option_arg_vector_sp.get())
        {
            OptionArgVector *option_arg_vector = option_arg_vector_sp.get();

            for (size_t i = 0; i < option_arg_vector->size(); ++i)
            {
                OptionArgPair option_pair = (*option_arg_vector)[i];
                OptionArgValue value_pair = option_pair.second;
                int value_type = value_pair.first;
                std::string option = option_pair.first;
                std::string value = value_pair.second;
                if (option.compare ("<argument>") == 0)
                    result_str.Printf (" %s", value.c_str());
                else
                {
                    result_str.Printf (" %s", option.c_str());
                    if (value_type != OptionParser::eOptionalArgument)
                        result_str.Printf (" ");
                    if (value.compare ("<OptionParser::eNoArgument>") != 0)
                    {
                        int index = GetOptionArgumentPosition (value.c_str());
                        if (index == 0)
                            result_str.Printf ("%s", value.c_str());
                        else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount())
                        {
                            
                            result.AppendErrorWithFormat
                            ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
                             index);
                            result.SetStatus (eReturnStatusFailed);
                            return alias_cmd_obj;
                        }
                        else
                        {
                            size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
                            if (strpos != std::string::npos)
                                raw_input_string = raw_input_string.erase (strpos, 
                                                                          strlen (cmd_args.GetArgumentAtIndex (index)));
                            result_str.Printf ("%s", cmd_args.GetArgumentAtIndex (index));
                        }
                    }
                }
            }
        }
        
        alias_result = result_str.GetData();
    }
    return alias_cmd_obj;
}

Error
CommandInterpreter::PreprocessCommand (std::string &command)
{
    // The command preprocessor needs to do things to the command 
    // line before any parsing of arguments or anything else is done.
    // The only current stuff that gets proprocessed is anyting enclosed
    // in backtick ('`') characters is evaluated as an expression and
    // the result of the expression must be a scalar that can be substituted
    // into the command. An example would be:
    // (lldb) memory read `$rsp + 20`
    Error error; // Error for any expressions that might not evaluate
    size_t start_backtick;
    size_t pos = 0;
    while ((start_backtick = command.find ('`', pos)) != std::string::npos)
    {
        if (start_backtick > 0 && command[start_backtick-1] == '\\')
        {
            // The backtick was preceeded by a '\' character, remove the slash
            // and don't treat the backtick as the start of an expression
            command.erase(start_backtick-1, 1);
            // No need to add one to start_backtick since we just deleted a char
            pos = start_backtick; 
        }
        else
        {
            const size_t expr_content_start = start_backtick + 1;
            const size_t end_backtick = command.find ('`', expr_content_start);
            if (end_backtick == std::string::npos)
                return error;
            else if (end_backtick == expr_content_start)
            {
                // Empty expression (two backticks in a row)
                command.erase (start_backtick, 2);
            }
            else
            {
                std::string expr_str (command, expr_content_start, end_backtick - expr_content_start);
                
                ExecutionContext exe_ctx(GetExecutionContext());
                Target *target = exe_ctx.GetTargetPtr();
                // Get a dummy target to allow for calculator mode while processing backticks.
                // This also helps break the infinite loop caused when target is null.
                if (!target)
                    target = Host::GetDummyTarget(GetDebugger()).get();
                if (target)
                {
                    ValueObjectSP expr_result_valobj_sp;
                    
                    EvaluateExpressionOptions options;
                    options.SetCoerceToId(false);
                    options.SetUnwindOnError(true);
                    options.SetIgnoreBreakpoints(true);
                    options.SetKeepInMemory(false);
                    options.SetTryAllThreads(true);
                    options.SetTimeoutUsec(0);
                    
                    ExpressionResults expr_result = target->EvaluateExpression (expr_str.c_str(), 
                                                                               exe_ctx.GetFramePtr(),
                                                                               expr_result_valobj_sp,
                                                                               options);
                    
                    if (expr_result == eExpressionCompleted)
                    {
                        Scalar scalar;
                        if (expr_result_valobj_sp->ResolveValue (scalar))
                        {
                            command.erase (start_backtick, end_backtick - start_backtick + 1);
                            StreamString value_strm;
                            const bool show_type = false;
                            scalar.GetValue (&value_strm, show_type);
                            size_t value_string_size = value_strm.GetSize();
                            if (value_string_size)
                            {
                                command.insert (start_backtick, value_strm.GetData(), value_string_size);
                                pos = start_backtick + value_string_size;
                                continue;
                            }
                            else
                            {
                                error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
                            }
                        }
                        else
                        {
                            error.SetErrorStringWithFormat("expression value didn't result in a scalar value for the expression '%s'", expr_str.c_str());
                        }
                    }
                    else
                    {
                        if (expr_result_valobj_sp)
                            error = expr_result_valobj_sp->GetError();
                        if (error.Success())
                        {

                            switch (expr_result)
                            {
                                case eExpressionSetupError: 
                                    error.SetErrorStringWithFormat("expression setup error for the expression '%s'", expr_str.c_str());
                                    break;
                                case eExpressionParseError:
                                    error.SetErrorStringWithFormat ("expression parse error for the expression '%s'", expr_str.c_str());
                                    break;
                                case eExpressionResultUnavailable:
                                    error.SetErrorStringWithFormat ("expression error fetching result for the expression '%s'", expr_str.c_str());
                                case eExpressionCompleted:
                                    break;
                                case eExpressionDiscarded:
                                    error.SetErrorStringWithFormat("expression discarded for the expression '%s'", expr_str.c_str());
                                    break;
                                case eExpressionInterrupted:
                                    error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str());
                                    break;
                                case eExpressionHitBreakpoint:
                                    error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str());
                                    break;
                                case eExpressionTimedOut:
                                    error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str());
                                    break;
                                case eExpressionStoppedForDebug:
                                    error.SetErrorStringWithFormat("expression stop at entry point for debugging for the expression '%s'", expr_str.c_str());
                                    break;
                            }
                        }
                    }
                }
            }
            if (error.Fail())
                break;
        }
    }
    return error;
}


bool
CommandInterpreter::HandleCommand (const char *command_line, 
                                   LazyBool lazy_add_to_history,
                                   CommandReturnObject &result,
                                   ExecutionContext *override_context,
                                   bool repeat_on_empty_command,
                                   bool no_context_switching)

{

    bool done = false;
    CommandObject *cmd_obj = nullptr;
    bool wants_raw_input = false;
    std::string command_string (command_line);
    std::string original_command_string (command_line);
    
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
    Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line);
    
    // Make a scoped cleanup object that will clear the crash description string 
    // on exit of this function.
    lldb_utility::CleanUp <const char *> crash_description_cleanup(nullptr, Host::SetCrashDescription);

    if (log)
        log->Printf ("Processing command: %s", command_line);

    Timer scoped_timer (__PRETTY_FUNCTION__, "Handling command: %s.", command_line);
    
    if (!no_context_switching)
        UpdateExecutionContext (override_context);
    
    bool add_to_history;
    if (lazy_add_to_history == eLazyBoolCalculate)
        add_to_history = (m_command_source_depth == 0);
    else
        add_to_history = (lazy_add_to_history == eLazyBoolYes);
    
    bool empty_command = false;
    bool comment_command = false;
    if (command_string.empty())
        empty_command = true;
    else
    {
        const char *k_space_characters = "\t\n\v\f\r ";

        size_t non_space = command_string.find_first_not_of (k_space_characters);
        // Check for empty line or comment line (lines whose first
        // non-space character is the comment character for this interpreter)
        if (non_space == std::string::npos)
            empty_command = true;
        else if (command_string[non_space] == m_comment_char)
             comment_command = true;
        else if (command_string[non_space] == CommandHistory::g_repeat_char)
        {
            const char *history_string = m_command_history.FindString(command_string.c_str() + non_space);
            if (history_string == nullptr)
            {
                result.AppendErrorWithFormat ("Could not find entry: %s in history", command_string.c_str());
                result.SetStatus(eReturnStatusFailed);
                return false;
            }
            add_to_history = false;
            command_string = history_string;
            original_command_string = history_string;
        }
    }
    
    if (empty_command)
    {
        if (repeat_on_empty_command)
        {
            if (m_command_history.IsEmpty())
            {
                result.AppendError ("empty command");
                result.SetStatus(eReturnStatusFailed);
                return false;
            }
            else
            {
                command_line = m_repeat_command.c_str();
                command_string = command_line;
                original_command_string = command_line;
                if (m_repeat_command.empty())
                {
                    result.AppendErrorWithFormat("No auto repeat.\n");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            add_to_history = false;
        }
        else
        {
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
            return true;
        }
    }
    else if (comment_command)
    {
        result.SetStatus (eReturnStatusSuccessFinishNoResult);
        return true;
    }
    
    
    Error error (PreprocessCommand (command_string));
    
    if (error.Fail())
    {
        result.AppendError (error.AsCString());
        result.SetStatus(eReturnStatusFailed);
        return false;
    }
    // Phase 1.
    
    // Before we do ANY kind of argument processing, etc. we need to figure out what the real/final command object
    // is for the specified command, and whether or not it wants raw input.  This gets complicated by the fact that
    // the user could have specified an alias, and in translating the alias there may also be command options and/or
    // even data (including raw text strings) that need to be found and inserted into the command line as part of
    // the translation.  So this first step is plain look-up & replacement, resulting in three things:  1). the command
    // object whose Execute method will actually be called; 2). a revised command string, with all substitutions &
    // replacements taken care of; 3). whether or not the Execute function wants raw input or not.

    StreamString revised_command_line;
    size_t actual_cmd_name_len = 0;
    std::string next_word;
    StringList matches;
    while (!done)
    {
        char quote_char = '\0';
        std::string suffix;
        ExtractCommand (command_string, next_word, suffix, quote_char);
        if (cmd_obj == nullptr)
        {
            std::string full_name;
            if (GetAliasFullName(next_word.c_str(), full_name))
            {
                std::string alias_result;
                cmd_obj = BuildAliasResult (full_name.c_str(), command_string, alias_result, result);
                revised_command_line.Printf ("%s", alias_result.c_str());
                if (cmd_obj)
                {
                    wants_raw_input = cmd_obj->WantsRawCommandString ();
                    actual_cmd_name_len = strlen (cmd_obj->GetCommandName());
                }
            }
            else
            {
                cmd_obj = GetCommandObject (next_word.c_str(), &matches);
                if (cmd_obj)
                {
                    actual_cmd_name_len += next_word.length();
                    revised_command_line.Printf ("%s", next_word.c_str());
                    wants_raw_input = cmd_obj->WantsRawCommandString ();
                }
                else
                {
                    revised_command_line.Printf ("%s", next_word.c_str());
                }
            }
        }
        else
        {
            if (cmd_obj->IsMultiwordObject ())
            {
                CommandObject *sub_cmd_obj = cmd_obj->GetSubcommandObject (next_word.c_str());
                if (sub_cmd_obj)
                {
                    actual_cmd_name_len += next_word.length() + 1;
                    revised_command_line.Printf (" %s", next_word.c_str());
                    cmd_obj = sub_cmd_obj;
                    wants_raw_input = cmd_obj->WantsRawCommandString ();
                }
                else
                {
                    if (quote_char)
                        revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
                    else
                        revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str());
                    done = true;
                }
            }
            else
            {
                if (quote_char)
                    revised_command_line.Printf (" %c%s%s%c", quote_char, next_word.c_str(), suffix.c_str(), quote_char);
                else
                    revised_command_line.Printf (" %s%s", next_word.c_str(), suffix.c_str());
                done = true;
            }
        }

        if (cmd_obj == nullptr)
        {
            const size_t num_matches = matches.GetSize();
            if (matches.GetSize() > 1) {
                StreamString error_msg;
                error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());

                for (uint32_t i = 0; i < num_matches; ++i) {
                    error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i));
                }
                result.AppendRawError (error_msg.GetString().c_str());
            } else {
                // We didn't have only one match, otherwise we wouldn't get here.
                assert(num_matches == 0);
                result.AppendErrorWithFormat ("'%s' is not a valid command.\n", next_word.c_str());
            }
            result.SetStatus (eReturnStatusFailed);
            return false;
        }

        if (cmd_obj->IsMultiwordObject ())
        {
            if (!suffix.empty())
            {

                result.AppendErrorWithFormat ("command '%s' did not recognize '%s%s%s' as valid (subcommand might be invalid).\n",
                                              cmd_obj->GetCommandName(),
                                              next_word.empty() ? "" : next_word.c_str(),
                                              next_word.empty() ? " -- " : " ",
                                              suffix.c_str());
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
        }
        else
        {
            // If we found a normal command, we are done
            done = true;
            if (!suffix.empty())
            {
                switch (suffix[0])
                {
                case '/':
                    // GDB format suffixes
                    {
                        Options *command_options = cmd_obj->GetOptions();
                        if (command_options && command_options->SupportsLongOption("gdb-format"))
                        {
                            std::string gdb_format_option ("--gdb-format=");
                            gdb_format_option += (suffix.c_str() + 1);
    
                            bool inserted = false;
                            std::string &cmd = revised_command_line.GetString();
                            size_t arg_terminator_idx = FindArgumentTerminator (cmd);
                            if (arg_terminator_idx != std::string::npos)
                            {
                                // Insert the gdb format option before the "--" that terminates options
                                gdb_format_option.append(1,' ');
                                cmd.insert(arg_terminator_idx, gdb_format_option);
                                inserted = true;
                            }

                            if (!inserted)
                                revised_command_line.Printf (" %s", gdb_format_option.c_str());
                        
                            if (wants_raw_input && FindArgumentTerminator(cmd) == std::string::npos)
                                revised_command_line.PutCString (" --");
                        }
                        else
                        {
                            result.AppendErrorWithFormat ("the '%s' command doesn't support the --gdb-format option\n", 
                                                          cmd_obj->GetCommandName());
                            result.SetStatus (eReturnStatusFailed);
                            return false;
                        }
                    }
                    break;

                default:
                    result.AppendErrorWithFormat ("unknown command shorthand suffix: '%s'\n", 
                                                  suffix.c_str());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
        
                }
            }
        }
        if (command_string.length() == 0)
            done = true;
            
    }

    if (!command_string.empty())
        revised_command_line.Printf (" %s", command_string.c_str());

    // End of Phase 1.
    // At this point cmd_obj should contain the CommandObject whose Execute method will be called, if the command
    // specified was valid; revised_command_line contains the complete command line (including command name(s)),
    // fully translated with all substitutions & translations taken care of (still in raw text format); and
    // wants_raw_input specifies whether the Execute method expects raw input or not.

 
    if (log)
    {
        log->Printf ("HandleCommand, cmd_obj : '%s'", cmd_obj ? cmd_obj->GetCommandName() : "<not found>");
        log->Printf ("HandleCommand, revised_command_line: '%s'", revised_command_line.GetData());
        log->Printf ("HandleCommand, wants_raw_input:'%s'", wants_raw_input ? "True" : "False");
    }

    // Phase 2.
    // Take care of things like setting up the history command & calling the appropriate Execute method on the
    // CommandObject, with the appropriate arguments.
    
    if (cmd_obj != nullptr)
    {
        if (add_to_history)
        {
            Args command_args (revised_command_line.GetData());
            const char *repeat_command = cmd_obj->GetRepeatCommand(command_args, 0);
            if (repeat_command != nullptr)
                m_repeat_command.assign(repeat_command);
            else
                m_repeat_command.assign(original_command_string.c_str());
            
            m_command_history.AppendString (original_command_string);
        }
        
        command_string = revised_command_line.GetData();
        std::string command_name (cmd_obj->GetCommandName());
        std::string remainder;
        if (actual_cmd_name_len < command_string.length()) 
            remainder = command_string.substr (actual_cmd_name_len);  // Note: 'actual_cmd_name_len' may be considerably shorter
                                                           // than cmd_obj->GetCommandName(), because name completion
                                                           // allows users to enter short versions of the names,
                                                           // e.g. 'br s' for 'breakpoint set'.
        
        // Remove any initial spaces
        std::string white_space (" \t\v");
        size_t pos = remainder.find_first_not_of (white_space);
        if (pos != 0 && pos != std::string::npos)
            remainder.erase(0, pos);

        if (log)
            log->Printf ("HandleCommand, command line after removing command name(s): '%s'", remainder.c_str());
    
        cmd_obj->Execute (remainder.c_str(), result);
    }
    else
    {
        // We didn't find the first command object, so complete the first argument.
        Args command_args (revised_command_line.GetData());
        StringList matches;
        int num_matches;
        int cursor_index = 0;
        int cursor_char_position = strlen (command_args.GetArgumentAtIndex(0));
        bool word_complete;
        num_matches = HandleCompletionMatches (command_args, 
                                               cursor_index,
                                               cursor_char_position,
                                               0, 
                                               -1, 
                                               word_complete,
                                               matches);
        
        if (num_matches > 0)
        {
            std::string error_msg;
            error_msg.assign ("ambiguous command '");
            error_msg.append(command_args.GetArgumentAtIndex(0));
            error_msg.append ("'.");
            
            error_msg.append (" Possible completions:");
            for (int i = 0; i < num_matches; i++)
            {
                error_msg.append ("\n\t");
                error_msg.append (matches.GetStringAtIndex (i));
            }
            error_msg.append ("\n");
            result.AppendRawError (error_msg.c_str());
        }
        else
            result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0));
        
        result.SetStatus (eReturnStatusFailed);
    }
    
    if (log)
      log->Printf ("HandleCommand, command %s", (result.Succeeded() ? "succeeded" : "did not succeed"));

    return result.Succeeded();
}

int
CommandInterpreter::HandleCompletionMatches (Args &parsed_line,
                                             int &cursor_index,
                                             int &cursor_char_position,
                                             int match_start_point,
                                             int max_return_elements,
                                             bool &word_complete,
                                             StringList &matches)
{
    int num_command_matches = 0;
    bool look_for_subcommand = false;
    
    // For any of the command completions a unique match will be a complete word.
    word_complete = true;

    if (cursor_index == -1)
    {
        // We got nothing on the command line, so return the list of commands
        bool include_aliases = true;
        num_command_matches = GetCommandNamesMatchingPartialString ("", include_aliases, matches);
    }
    else if (cursor_index == 0)
    {
        // The cursor is in the first argument, so just do a lookup in the dictionary.
        CommandObject *cmd_obj = GetCommandObject (parsed_line.GetArgumentAtIndex(0), &matches);
        num_command_matches = matches.GetSize();

        if (num_command_matches == 1
            && cmd_obj && cmd_obj->IsMultiwordObject()
            && matches.GetStringAtIndex(0) != nullptr
            && strcmp (parsed_line.GetArgumentAtIndex(0), matches.GetStringAtIndex(0)) == 0)
        {
            if (parsed_line.GetArgumentCount() == 1)
            {
                word_complete = true;
            }
            else
            {
                look_for_subcommand = true;
                num_command_matches = 0;
                matches.DeleteStringAtIndex(0);
                parsed_line.AppendArgument ("");
                cursor_index++;
                cursor_char_position = 0;
            }
        }
    }

    if (cursor_index > 0 || look_for_subcommand)
    {
        // We are completing further on into a commands arguments, so find the command and tell it
        // to complete the command.
        // First see if there is a matching initial command:
        CommandObject *command_object = GetCommandObject (parsed_line.GetArgumentAtIndex(0));
        if (command_object == nullptr)
        {
            return 0;
        }
        else
        {
            parsed_line.Shift();
            cursor_index--;
            num_command_matches = command_object->HandleCompletion (parsed_line, 
                                                                    cursor_index, 
                                                                    cursor_char_position,
                                                                    match_start_point, 
                                                                    max_return_elements,
                                                                    word_complete, 
                                                                    matches);
        }
    }

    return num_command_matches;

}

int
CommandInterpreter::HandleCompletion (const char *current_line,
                                      const char *cursor,
                                      const char *last_char,
                                      int match_start_point,
                                      int max_return_elements,
                                      StringList &matches)
{
    // We parse the argument up to the cursor, so the last argument in parsed_line is
    // the one containing the cursor, and the cursor is after the last character.

    Args parsed_line(current_line, last_char - current_line);
    Args partial_parsed_line(current_line, cursor - current_line);

    // Don't complete comments, and if the line we are completing is just the history repeat character, 
    // substitute the appropriate history line.
    const char *first_arg = parsed_line.GetArgumentAtIndex(0);
    if (first_arg)
    {
        if (first_arg[0] == m_comment_char)
            return 0;
        else if (first_arg[0] == CommandHistory::g_repeat_char)
        {
            const char *history_string = m_command_history.FindString (first_arg);
            if (history_string != nullptr)
            {
                matches.Clear();
                matches.InsertStringAtIndex(0, history_string);
                return -2;
            }
            else
                return 0;

        }
    }
    
    
    int num_args = partial_parsed_line.GetArgumentCount();
    int cursor_index = partial_parsed_line.GetArgumentCount() - 1;
    int cursor_char_position;

    if (cursor_index == -1)
        cursor_char_position = 0;
    else
        cursor_char_position = strlen (partial_parsed_line.GetArgumentAtIndex(cursor_index));
        
    if (cursor > current_line && cursor[-1] == ' ')
    {
        // We are just after a space.  If we are in an argument, then we will continue
        // parsing, but if we are between arguments, then we have to complete whatever the next
        // element would be.
        // We can distinguish the two cases because if we are in an argument (e.g. because the space is
        // protected by a quote) then the space will also be in the parsed argument...
        
        const char *current_elem = partial_parsed_line.GetArgumentAtIndex(cursor_index);
        if (cursor_char_position == 0 || current_elem[cursor_char_position - 1] != ' ')
        {
            parsed_line.InsertArgumentAtIndex(cursor_index + 1, "", '\0');
            cursor_index++;
            cursor_char_position = 0;
        }
    }

    int num_command_matches;

    matches.Clear();

    // Only max_return_elements == -1 is supported at present:
    assert (max_return_elements == -1);
    bool word_complete;
    num_command_matches = HandleCompletionMatches (parsed_line, 
                                                   cursor_index, 
                                                   cursor_char_position, 
                                                   match_start_point,
                                                   max_return_elements,
                                                   word_complete,
                                                   matches);

    if (num_command_matches <= 0)
            return num_command_matches;

    if (num_args == 0)
    {
        // If we got an empty string, insert nothing.
        matches.InsertStringAtIndex(0, "");
    }
    else
    {
        // Now figure out if there is a common substring, and if so put that in element 0, otherwise
        // put an empty string in element 0.
        std::string command_partial_str;
        if (cursor_index >= 0)
            command_partial_str.assign(parsed_line.GetArgumentAtIndex(cursor_index), 
                                       parsed_line.GetArgumentAtIndex(cursor_index) + cursor_char_position);

        std::string common_prefix;
        matches.LongestCommonPrefix (common_prefix);
        const size_t partial_name_len = command_partial_str.size();

        // If we matched a unique single command, add a space...
        // Only do this if the completer told us this was a complete word, however...
        if (num_command_matches == 1 && word_complete)
        {
            char quote_char = parsed_line.GetArgumentQuoteCharAtIndex(cursor_index);
            if (quote_char != '\0')
                common_prefix.push_back(quote_char);

            common_prefix.push_back(' ');
        }
        common_prefix.erase (0, partial_name_len);
        matches.InsertStringAtIndex(0, common_prefix.c_str());
    }
    return num_command_matches;
}


CommandInterpreter::~CommandInterpreter ()
{
}

void
CommandInterpreter::UpdatePrompt (const char *new_prompt)
{
    EventSP prompt_change_event_sp (new Event(eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));;
    BroadcastEvent (prompt_change_event_sp);
    if (m_command_io_handler_sp)
        m_command_io_handler_sp->SetPrompt(new_prompt);
}


bool 
CommandInterpreter::Confirm (const char *message, bool default_answer)
{
    // Check AutoConfirm first:
    if (m_debugger.GetAutoConfirm())
        return default_answer;
    
    IOHandlerConfirm *confirm = new IOHandlerConfirm(m_debugger,
                                                     message,
                                                     default_answer);
    IOHandlerSP io_handler_sp (confirm);
    m_debugger.RunIOHandler (io_handler_sp);
    return confirm->GetResponse();
}
    
OptionArgVectorSP
CommandInterpreter::GetAliasOptions (const char *alias_name)
{
    OptionArgMap::iterator pos;
    OptionArgVectorSP ret_val;

    std::string alias (alias_name);

    if (HasAliasOptions())
    {
        pos = m_alias_options.find (alias);
        if (pos != m_alias_options.end())
          ret_val = pos->second;
    }

    return ret_val;
}

void
CommandInterpreter::RemoveAliasOptions (const char *alias_name)
{
    OptionArgMap::iterator pos = m_alias_options.find(alias_name);
    if (pos != m_alias_options.end())
    {
        m_alias_options.erase (pos);
    }
}

void
CommandInterpreter::AddOrReplaceAliasOptions (const char *alias_name, OptionArgVectorSP &option_arg_vector_sp)
{
    m_alias_options[alias_name] = option_arg_vector_sp;
}

bool
CommandInterpreter::HasCommands ()
{
    return (!m_command_dict.empty());
}

bool
CommandInterpreter::HasAliases ()
{
    return (!m_alias_dict.empty());
}

bool
CommandInterpreter::HasUserCommands ()
{
    return (!m_user_dict.empty());
}

bool
CommandInterpreter::HasAliasOptions ()
{
    return (!m_alias_options.empty());
}

void
CommandInterpreter::BuildAliasCommandArgs (CommandObject *alias_cmd_obj,
                                           const char *alias_name,
                                           Args &cmd_args,
                                           std::string &raw_input_string,
                                           CommandReturnObject &result)
{
    OptionArgVectorSP option_arg_vector_sp = GetAliasOptions (alias_name);
    
    bool wants_raw_input = alias_cmd_obj->WantsRawCommandString();

    // Make sure that the alias name is the 0th element in cmd_args
    std::string alias_name_str = alias_name;
    if (alias_name_str.compare (cmd_args.GetArgumentAtIndex(0)) != 0)
        cmd_args.Unshift (alias_name);
    
    Args new_args (alias_cmd_obj->GetCommandName());
    if (new_args.GetArgumentCount() == 2)
        new_args.Shift();
    
    if (option_arg_vector_sp.get())
    {
        if (wants_raw_input)
        {
            // We have a command that both has command options and takes raw input.  Make *sure* it has a
            // " -- " in the right place in the raw_input_string.
            size_t pos = raw_input_string.find(" -- ");
            if (pos == std::string::npos)
            {
                // None found; assume it goes at the beginning of the raw input string
                raw_input_string.insert (0, " -- ");
            }
        }

        OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
        const size_t old_size = cmd_args.GetArgumentCount();
        std::vector<bool> used (old_size + 1, false);
        
        used[0] = true;

        for (size_t i = 0; i < option_arg_vector->size(); ++i)
        {
            OptionArgPair option_pair = (*option_arg_vector)[i];
            OptionArgValue value_pair = option_pair.second;
            int value_type = value_pair.first;
            std::string option = option_pair.first;
            std::string value = value_pair.second;
            if (option.compare ("<argument>") == 0)
            {
                if (!wants_raw_input
                    || (value.compare("--") != 0)) // Since we inserted this above, make sure we don't insert it twice
                    new_args.AppendArgument (value.c_str());
            }
            else
            {
                if (value_type != OptionParser::eOptionalArgument)
                    new_args.AppendArgument (option.c_str());
                if (value.compare ("<no-argument>") != 0)
                {
                    int index = GetOptionArgumentPosition (value.c_str());
                    if (index == 0)
                    {
                        // value was NOT a positional argument; must be a real value
                        if (value_type != OptionParser::eOptionalArgument)
                            new_args.AppendArgument (value.c_str());
                        else
                        {
                            char buffer[255];
                            ::snprintf (buffer, sizeof (buffer), "%s%s", option.c_str(), value.c_str());
                            new_args.AppendArgument (buffer);
                        }

                    }
                    else if (static_cast<size_t>(index) >= cmd_args.GetArgumentCount())
                    {
                        result.AppendErrorWithFormat
                                    ("Not enough arguments provided; you need at least %d arguments to use this alias.\n",
                                     index);
                        result.SetStatus (eReturnStatusFailed);
                        return;
                    }
                    else
                    {
                        // Find and remove cmd_args.GetArgumentAtIndex(i) from raw_input_string
                        size_t strpos = raw_input_string.find (cmd_args.GetArgumentAtIndex (index));
                        if (strpos != std::string::npos)
                        {
                            raw_input_string = raw_input_string.erase (strpos, strlen (cmd_args.GetArgumentAtIndex (index)));
                        }

                        if (value_type != OptionParser::eOptionalArgument)
                            new_args.AppendArgument (cmd_args.GetArgumentAtIndex (index));
                        else
                        {
                            char buffer[255];
                            ::snprintf (buffer, sizeof(buffer), "%s%s", option.c_str(), 
                                        cmd_args.GetArgumentAtIndex (index));
                            new_args.AppendArgument (buffer);
                        }
                        used[index] = true;
                    }
                }
            }
        }

        for (size_t j = 0; j < cmd_args.GetArgumentCount(); ++j)
        {
            if (!used[j] && !wants_raw_input)
                new_args.AppendArgument (cmd_args.GetArgumentAtIndex (j));
        }

        cmd_args.Clear();
        cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
    }
    else
    {
        result.SetStatus (eReturnStatusSuccessFinishNoResult);
        // This alias was not created with any options; nothing further needs to be done, unless it is a command that
        // wants raw input, in which case we need to clear the rest of the data from cmd_args, since its in the raw
        // input string.
        if (wants_raw_input)
        {
            cmd_args.Clear();
            cmd_args.SetArguments (new_args.GetArgumentCount(), (const char **) new_args.GetArgumentVector());
        }
        return;
    }

    result.SetStatus (eReturnStatusSuccessFinishNoResult);
    return;
}


int
CommandInterpreter::GetOptionArgumentPosition (const char *in_string)
{
    int position = 0;   // Any string that isn't an argument position, i.e. '%' followed by an integer, gets a position
                        // of zero.

    char *cptr = (char *) in_string;

    // Does it start with '%'
    if (cptr[0] == '%')
    {
        ++cptr;

        // Is the rest of it entirely digits?
        if (isdigit (cptr[0]))
        {
            const char *start = cptr;
            while (isdigit (cptr[0]))
                ++cptr;

            // We've gotten to the end of the digits; are we at the end of the string?
            if (cptr[0] == '\0')
                position = atoi (start);
        }
    }

    return position;
}

void
CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result)
{
    FileSpec init_file;
    if (in_cwd)
    {
        // In the current working directory we don't load any program specific
        // .lldbinit files, we only look for a "./.lldbinit" file.
        if (m_skip_lldbinit_files)
            return;

        init_file.SetFile ("./.lldbinit", true);
    }
    else
    {
        // If we aren't looking in the current working directory we are looking
        // in the home directory. We will first see if there is an application
        // specific ".lldbinit" file whose name is "~/.lldbinit" followed by a 
        // "-" and the name of the program. If this file doesn't exist, we fall
        // back to just the "~/.lldbinit" file. We also obey any requests to not
        // load the init files.
        llvm::SmallString<64> home_dir_path;
        llvm::sys::path::home_directory(home_dir_path);
        FileSpec profilePath(home_dir_path.c_str(), false);
        profilePath.AppendPathComponent(".lldbinit");
        std::string init_file_path = profilePath.GetPath();

        if (m_skip_app_init_files == false)
        {
            FileSpec program_file_spec(HostInfo::GetProgramFileSpec());
            const char *program_name = program_file_spec.GetFilename().AsCString();
    
            if (program_name)
            {
                char program_init_file_name[PATH_MAX];
                ::snprintf (program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path.c_str(), program_name);
                init_file.SetFile (program_init_file_name, true);
                if (!init_file.Exists())
                    init_file.Clear();
            }
        }
        
        if (!init_file && !m_skip_lldbinit_files)
			init_file.SetFile (init_file_path.c_str(), false);
    }

    // If the file exists, tell HandleCommand to 'source' it; this will do the actual broadcasting
    // of the commands back to any appropriate listener (see CommandObjectSource::Execute for more details).

    if (init_file.Exists())
    {
        const bool saved_batch = SetBatchCommandMode (true);
        HandleCommandsFromFile (init_file,
                                nullptr,           // Execution context
                                eLazyBoolYes,   // Stop on continue
                                eLazyBoolNo,    // Stop on error
                                eLazyBoolNo,    // Don't echo commands
                                eLazyBoolNo,    // Don't print command output
                                eLazyBoolNo,    // Don't add the commands that are sourced into the history buffer
                                result);
        SetBatchCommandMode (saved_batch);
    }
    else
    {
        // nothing to be done if the file doesn't exist
        result.SetStatus(eReturnStatusSuccessFinishNoResult);
    }
}

PlatformSP
CommandInterpreter::GetPlatform (bool prefer_target_platform)
{
    PlatformSP platform_sp;
    if (prefer_target_platform)
    {
        ExecutionContext exe_ctx(GetExecutionContext());
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            platform_sp = target->GetPlatform();
    }

    if (!platform_sp)
        platform_sp = m_debugger.GetPlatformList().GetSelectedPlatform();
    return platform_sp;
}

void
CommandInterpreter::HandleCommands (const StringList &commands, 
                                    ExecutionContext *override_context, 
                                    bool stop_on_continue,
                                    bool stop_on_error,
                                    bool echo_commands,
                                    bool print_results,
                                    LazyBool add_to_history,
                                    CommandReturnObject &result)
{
    size_t num_lines = commands.GetSize();
    
    // If we are going to continue past a "continue" then we need to run the commands synchronously.
    // Make sure you reset this value anywhere you return from the function.
    
    bool old_async_execution = m_debugger.GetAsyncExecution();
    
    // If we've been given an execution context, set it at the start, but don't keep resetting it or we will
    // cause series of commands that change the context, then do an operation that relies on that context to fail.
    
    if (override_context != nullptr)
        UpdateExecutionContext (override_context);
            
    if (!stop_on_continue)
    {
        m_debugger.SetAsyncExecution (false);
    }

    for (size_t idx = 0; idx < num_lines; idx++)
    {
        const char *cmd = commands.GetStringAtIndex(idx);
        if (cmd[0] == '\0')
            continue;
            
        if (echo_commands)
        {
            result.AppendMessageWithFormat ("%s %s\n", 
                                            m_debugger.GetPrompt(),
                                            cmd);
        }

        CommandReturnObject tmp_result;
        // If override_context is not NULL, pass no_context_switching = true for
        // HandleCommand() since we updated our context already.
        
        // We might call into a regex or alias command, in which case the add_to_history will get lost.  This
        // m_command_source_depth dingus is the way we turn off adding to the history in that case, so set it up here.
        if (!add_to_history)
            m_command_source_depth++;
        bool success = HandleCommand(cmd, add_to_history, tmp_result,
                                     nullptr, /* override_context */
                                     true, /* repeat_on_empty_command */
                                     override_context != nullptr /* no_context_switching */);
        if (!add_to_history)
            m_command_source_depth--;
        
        if (print_results)
        {
            if (tmp_result.Succeeded())
              result.AppendMessageWithFormat("%s", tmp_result.GetOutputData());
        }
                
        if (!success || !tmp_result.Succeeded())
        {
            const char *error_msg = tmp_result.GetErrorData();
            if (error_msg == nullptr || error_msg[0] == '\0')
                error_msg = "<unknown error>.\n";
            if (stop_on_error)
            {
                result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' failed with %s",
                                                (uint64_t)idx, cmd, error_msg);
                result.SetStatus (eReturnStatusFailed);
                m_debugger.SetAsyncExecution (old_async_execution);
                return;
            }
            else if (print_results)
            {
                result.AppendMessageWithFormat ("Command #%" PRIu64 " '%s' failed with %s",
                                                (uint64_t)idx + 1,
                                                cmd, 
                                                error_msg);
            }
        }
        
        if (result.GetImmediateOutputStream())
            result.GetImmediateOutputStream()->Flush();
        
        if (result.GetImmediateErrorStream())
            result.GetImmediateErrorStream()->Flush();
        
        // N.B. Can't depend on DidChangeProcessState, because the state coming into the command execution
        // could be running (for instance in Breakpoint Commands.
        // So we check the return value to see if it is has running in it.
        if ((tmp_result.GetStatus() == eReturnStatusSuccessContinuingNoResult)
                || (tmp_result.GetStatus() == eReturnStatusSuccessContinuingResult))
        {
            if (stop_on_continue)
            {
                // If we caused the target to proceed, and we're going to stop in that case, set the
                // status in our real result before returning.  This is an error if the continue was not the
                // last command in the set of commands to be run.
                if (idx != num_lines - 1)
                    result.AppendErrorWithFormat("Aborting reading of commands after command #%" PRIu64 ": '%s' continued the target.\n", 
                                                 (uint64_t)idx + 1, cmd);
                else
                    result.AppendMessageWithFormat("Command #%" PRIu64 " '%s' continued the target.\n", (uint64_t)idx + 1, cmd);
                    
                result.SetStatus(tmp_result.GetStatus());
                m_debugger.SetAsyncExecution (old_async_execution);

                return;
            }
        }
        
    }
    
    result.SetStatus (eReturnStatusSuccessFinishResult);
    m_debugger.SetAsyncExecution (old_async_execution);

    return;
}

// Make flags that we can pass into the IOHandler so our delegates can do the right thing
enum {
    eHandleCommandFlagStopOnContinue = (1u << 0),
    eHandleCommandFlagStopOnError    = (1u << 1),
    eHandleCommandFlagEchoCommand    = (1u << 2),
    eHandleCommandFlagPrintResult    = (1u << 3)
};

void
CommandInterpreter::HandleCommandsFromFile (FileSpec &cmd_file, 
                                            ExecutionContext *context, 
                                            LazyBool stop_on_continue,
                                            LazyBool stop_on_error,
                                            LazyBool echo_command,
                                            LazyBool print_result,
                                            LazyBool add_to_history,
                                            CommandReturnObject &result)
{
    if (cmd_file.Exists())
    {
        StreamFileSP input_file_sp (new StreamFile());
        
        std::string cmd_file_path = cmd_file.GetPath();
        Error error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), File::eOpenOptionRead);
        
        if (error.Success())
        {
            Debugger &debugger = GetDebugger();

            uint32_t flags = 0;

            if (stop_on_continue == eLazyBoolCalculate)
            {
                if (m_command_source_flags.empty())
                {
                    // Stop on continue by default
                    flags |= eHandleCommandFlagStopOnContinue;
                }
                else if (m_command_source_flags.back() & eHandleCommandFlagStopOnContinue)
                {
                    flags |= eHandleCommandFlagStopOnContinue;
                }
            }
            else if (stop_on_continue == eLazyBoolYes)
            {
                flags |= eHandleCommandFlagStopOnContinue;
            }

            if (stop_on_error == eLazyBoolCalculate)
            {
                if (m_command_source_flags.empty())
                {
                    if (GetStopCmdSourceOnError())
                        flags |= eHandleCommandFlagStopOnError;
                }
                else if (m_command_source_flags.back() & eHandleCommandFlagStopOnError)
                {
                    flags |= eHandleCommandFlagStopOnError;
                }
            }
            else if (stop_on_error == eLazyBoolYes)
            {
                flags |= eHandleCommandFlagStopOnError;
            }

            if (echo_command == eLazyBoolCalculate)
            {
                if (m_command_source_flags.empty())
                {
                    // Echo command by default
                    flags |= eHandleCommandFlagEchoCommand;
                }
                else if (m_command_source_flags.back() & eHandleCommandFlagEchoCommand)
                {
                    flags |= eHandleCommandFlagEchoCommand;
                }
            }
            else if (echo_command == eLazyBoolYes)
            {
                flags |= eHandleCommandFlagEchoCommand;
            }

            if (print_result == eLazyBoolCalculate)
            {
                if (m_command_source_flags.empty())
                {
                    // Print output by default
                    flags |= eHandleCommandFlagPrintResult;
                }
                else if (m_command_source_flags.back() & eHandleCommandFlagPrintResult)
                {
                    flags |= eHandleCommandFlagPrintResult;
                }
            }
            else if (print_result == eLazyBoolYes)
            {
                flags |= eHandleCommandFlagPrintResult;
            }

            if (flags & eHandleCommandFlagPrintResult)
            {
                debugger.GetOutputFile()->Printf("Executing commands in '%s'.\n", cmd_file_path.c_str());
            }

            // Used for inheriting the right settings when "command source" might have
            // nested "command source" commands
            lldb::StreamFileSP empty_stream_sp;
            m_command_source_flags.push_back(flags);
            IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
                                                              input_file_sp,
                                                              empty_stream_sp, // Pass in an empty stream so we inherit the top input reader output stream
                                                              empty_stream_sp, // Pass in an empty stream so we inherit the top input reader error stream
                                                              flags,
                                                              nullptr, // Pass in NULL for "editline_name" so no history is saved, or written
                                                              debugger.GetPrompt(),
                                                              false, // Not multi-line
                                                              0,
                                                              *this));
            const bool old_async_execution = debugger.GetAsyncExecution();
            
            // Set synchronous execution if we not stopping when we continue
            if ((flags & eHandleCommandFlagStopOnContinue) == 0)
                debugger.SetAsyncExecution (false);

            m_command_source_depth++;
            
            debugger.RunIOHandler(io_handler_sp);
            if (!m_command_source_flags.empty())
                m_command_source_flags.pop_back();
            m_command_source_depth--;
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
            debugger.SetAsyncExecution (old_async_execution);
        }
        else
        {
            result.AppendErrorWithFormat ("error: an error occurred read file '%s': %s\n", cmd_file_path.c_str(), error.AsCString());
            result.SetStatus (eReturnStatusFailed);
        }
        

    }
    else
    {
        result.AppendErrorWithFormat ("Error reading commands from file %s - file not found.\n", 
                                      cmd_file.GetFilename().AsCString());
        result.SetStatus (eReturnStatusFailed);
        return;
    }
}

ScriptInterpreter *
CommandInterpreter::GetScriptInterpreter (bool can_create)
{
    if (m_script_interpreter_ap.get() != nullptr)
        return m_script_interpreter_ap.get();
    
    if (!can_create)
        return nullptr;
 
    // <rdar://problem/11751427>
    // we need to protect the initialization of the script interpreter
    // otherwise we could end up with two threads both trying to create
    // their instance of it, and for some languages (e.g. Python)
    // this is a bulletproof recipe for disaster!
    // this needs to be a function-level static because multiple Debugger instances living in the same process
    // still need to be isolated and not try to initialize Python concurrently
    static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive);
    Mutex::Locker interpreter_lock(g_interpreter_mutex);
    
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
    if (log)
        log->Printf("Initializing the ScriptInterpreter now\n");
    
    lldb::ScriptLanguage script_lang = GetDebugger().GetScriptLanguage();
    switch (script_lang)
    {
        case eScriptLanguagePython:
#ifndef LLDB_DISABLE_PYTHON
            m_script_interpreter_ap.reset (new ScriptInterpreterPython (*this));
            break;
#else
            // Fall through to the None case when python is disabled
#endif
        case eScriptLanguageNone:
            m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this));
            break;
    };
    
    return m_script_interpreter_ap.get();
}



bool
CommandInterpreter::GetSynchronous ()
{
    return m_synchronous_execution;
}

void
CommandInterpreter::SetSynchronous (bool value)
{
    m_synchronous_execution  = value;
}

void
CommandInterpreter::OutputFormattedHelpText (Stream &strm,
                                             const char *word_text,
                                             const char *separator,
                                             const char *help_text,
                                             size_t max_word_len)
{
    const uint32_t max_columns = m_debugger.GetTerminalWidth();

    int indent_size = max_word_len + strlen (separator) + 2;

    strm.IndentMore (indent_size);
    
    StreamString text_strm;
    text_strm.Printf ("%-*s %s %s",  (int)max_word_len, word_text, separator, help_text);
    
    size_t len = text_strm.GetSize();
    const char *text = text_strm.GetData();
    if (text[len - 1] == '\n')
    {
        text_strm.EOL();
        len = text_strm.GetSize();
    }

    if (len  < max_columns)
    {
        // Output it as a single line.
        strm.Printf ("%s", text);
    }
    else
    {
        // We need to break it up into multiple lines.
        bool first_line = true;
        int text_width;
        size_t start = 0;
        size_t end = start;
        const size_t final_end = strlen (text);
        
        while (end < final_end)
        {
            if (first_line)
                text_width = max_columns - 1;
            else
                text_width = max_columns - indent_size - 1;

            // Don't start the 'text' on a space, since we're already outputting the indentation.
            if (!first_line)
            {
                while ((start < final_end) && (text[start] == ' '))
                  start++;
            }

            end = start + text_width;
            if (end > final_end)
                end = final_end;
            else
            {
                // If we're not at the end of the text, make sure we break the line on white space.
                while (end > start
                       && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
                    end--;
                assert (end > 0);
            }

            const size_t sub_len = end - start;
            if (start != 0)
              strm.EOL();
            if (!first_line)
                strm.Indent();
            else
                first_line = false;
            assert (start <= final_end);
            assert (start + sub_len <= final_end);
            if (sub_len > 0)
                strm.Write (text + start, sub_len);
            start = end + 1;
        }
    }
    strm.EOL();
    strm.IndentLess(indent_size);
}

void
CommandInterpreter::OutputHelpText (Stream &strm,
                                    const char *word_text,
                                    const char *separator,
                                    const char *help_text,
                                    uint32_t max_word_len)
{
    int indent_size = max_word_len + strlen (separator) + 2;
    
    strm.IndentMore (indent_size);
    
    StreamString text_strm;
    text_strm.Printf ("%-*s %s %s",  max_word_len, word_text, separator, help_text);
    
    const uint32_t max_columns = m_debugger.GetTerminalWidth();
    
    size_t len = text_strm.GetSize();
    const char *text = text_strm.GetData();
        
    uint32_t chars_left = max_columns;

    for (uint32_t i = 0; i < len; i++)
    {
        if ((text[i] == ' ' && ::strchr((text+i+1), ' ') && chars_left < ::strchr((text+i+1), ' ')-(text+i)) || text[i] == '\n')
        {
            chars_left = max_columns - indent_size;
            strm.EOL();
            strm.Indent();
        }
        else
        {
            strm.PutChar(text[i]);
            chars_left--;
        }
        
    }
    
    strm.EOL();
    strm.IndentLess(indent_size);
}

void
CommandInterpreter::FindCommandsForApropos (const char *search_word, StringList &commands_found,
                                            StringList &commands_help, bool search_builtin_commands, bool search_user_commands)
{
    CommandObject::CommandMap::const_iterator pos;

    if (search_builtin_commands)
    {
        for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos)
        {
            const char *command_name = pos->first.c_str();
            CommandObject *cmd_obj = pos->second.get();

            if (cmd_obj->HelpTextContainsWord (search_word))
            {
                commands_found.AppendString (command_name);
                commands_help.AppendString (cmd_obj->GetHelp());
            }

            if (cmd_obj->IsMultiwordObject())
                cmd_obj->AproposAllSubCommands (command_name,
                                                search_word,
                                                commands_found,
                                                commands_help);
          
        }
    }
    
    if (search_user_commands)
    {
        for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos)
        {
            const char *command_name = pos->first.c_str();
            CommandObject *cmd_obj = pos->second.get();

            if (cmd_obj->HelpTextContainsWord (search_word))
            {
                commands_found.AppendString (command_name);
                commands_help.AppendString (cmd_obj->GetHelp());
            }

            if (cmd_obj->IsMultiwordObject())
                cmd_obj->AproposAllSubCommands (command_name,
                                                search_word,
                                                commands_found,
                                                commands_help);
          
        }
    }
}

void
CommandInterpreter::UpdateExecutionContext (ExecutionContext *override_context)
{
    if (override_context != nullptr)
    {
        m_exe_ctx_ref = *override_context;
    }
    else
    {
        const bool adopt_selected = true;
        m_exe_ctx_ref.SetTargetPtr (m_debugger.GetSelectedTarget().get(), adopt_selected);
    }
}


size_t
CommandInterpreter::GetProcessOutput ()
{
    //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
    char stdio_buffer[1024];
    size_t len;
    size_t total_bytes = 0;
    Error error;
    TargetSP target_sp (m_debugger.GetTargetList().GetSelectedTarget());
    if (target_sp)
    {
        ProcessSP process_sp (target_sp->GetProcessSP());
        if (process_sp)
        {
            while ((len = process_sp->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
            {
                size_t bytes_written = len;
                m_debugger.GetOutputFile()->Write (stdio_buffer, bytes_written);
                total_bytes += len;
            }
            while ((len = process_sp->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
            {
                size_t bytes_written = len;
                m_debugger.GetErrorFile()->Write (stdio_buffer, bytes_written);
                total_bytes += len;
            }
        }
    }
    return total_bytes;
}

void
CommandInterpreter::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
{
    const bool is_interactive = io_handler.GetIsInteractive();
    if (is_interactive == false)
    {
        // When we are not interactive, don't execute blank lines. This will happen
        // sourcing a commands file. We don't want blank lines to repeat the previous
        // command and cause any errors to occur (like redefining an alias, get an error
        // and stop parsing the commands file).
        if (line.empty())
            return;
        
        // When using a non-interactive file handle (like when sourcing commands from a file)
        // we need to echo the command out so we don't just see the command output and no
        // command...
        if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand))
            io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str());
    }

    lldb_private::CommandReturnObject result;
    HandleCommand(line.c_str(), eLazyBoolCalculate, result);
    
    // Now emit the command output text from the command we just executed
    if (io_handler.GetFlags().Test(eHandleCommandFlagPrintResult))
    {
        // Display any STDOUT/STDERR _prior_ to emitting the command result text
        GetProcessOutput ();
        
        if (!result.GetImmediateOutputStream())
        {
            const char *output = result.GetOutputData();
            if (output && output[0])
                io_handler.GetOutputStreamFile()->PutCString(output);
        }
    
        // Now emit the command error text from the command we just executed
        if (!result.GetImmediateErrorStream())
        {
            const char *error = result.GetErrorData();
            if (error && error[0])
                io_handler.GetErrorStreamFile()->PutCString(error);
        }
    }
    
    switch (result.GetStatus())
    {
        case eReturnStatusInvalid:
        case eReturnStatusSuccessFinishNoResult:
        case eReturnStatusSuccessFinishResult:
        case eReturnStatusStarted:
            break;

        case eReturnStatusSuccessContinuingNoResult:
        case eReturnStatusSuccessContinuingResult:
            if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnContinue))
                io_handler.SetIsDone(true);
            break;

        case eReturnStatusFailed:
            if (io_handler.GetFlags().Test(eHandleCommandFlagStopOnError))
                io_handler.SetIsDone(true);
            break;
            
        case eReturnStatusQuit:
            io_handler.SetIsDone(true);
            break;
    }
}

bool
CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler)
{
    ExecutionContext exe_ctx (GetExecutionContext());
    Process *process = exe_ctx.GetProcessPtr();
    
    if (process)
    {
        StateType state = process->GetState();
        if (StateIsRunningState(state))
        {
            process->Halt();
            return true; // Don't do any updating when we are running
        }
    }
    return false;
}

void
CommandInterpreter::GetLLDBCommandsFromIOHandler (const char *prompt,
                                                  IOHandlerDelegate &delegate,
                                                  bool asynchronously,
                                                  void *baton)
{
    Debugger &debugger = GetDebugger();
    IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
                                                      "lldb",       // Name of input reader for history
                                                      prompt,       // Prompt
                                                      true,         // Get multiple lines
                                                      0,            // Don't show line numbers
                                                      delegate));   // IOHandlerDelegate
    
    if (io_handler_sp)
    {
        io_handler_sp->SetUserData (baton);
        if (asynchronously)
            debugger.PushIOHandler(io_handler_sp);
        else
            debugger.RunIOHandler(io_handler_sp);
    }
    
}


void
CommandInterpreter::GetPythonCommandsFromIOHandler (const char *prompt,
                                                    IOHandlerDelegate &delegate,
                                                    bool asynchronously,
                                                    void *baton)
{
    Debugger &debugger = GetDebugger();
    IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger,
                                                      "lldb-python",    // Name of input reader for history
                                                      prompt,           // Prompt
                                                      true,             // Get multiple lines
                                                      0,                // Don't show line numbers
                                                      delegate));       // IOHandlerDelegate
    
    if (io_handler_sp)
    {
        io_handler_sp->SetUserData (baton);
        if (asynchronously)
            debugger.PushIOHandler(io_handler_sp);
        else
            debugger.RunIOHandler(io_handler_sp);
    }

}

bool
CommandInterpreter::IsActive ()
{
    return m_debugger.IsTopIOHandler (m_command_io_handler_sp);
}

void
CommandInterpreter::RunCommandInterpreter(bool auto_handle_events,
                                          bool spawn_thread)
{
    // Only get one line at a time
    const bool multiple_lines = false;
    
    // Always re-create the IOHandlerEditline in case the input
    // changed. The old instance might have had a non-interactive
    // input and now it does or vice versa.
    m_command_io_handler_sp.reset(new IOHandlerEditline (m_debugger,
                                                         m_debugger.GetInputFile(),
                                                         m_debugger.GetOutputFile(),
                                                         m_debugger.GetErrorFile(),
                                                         eHandleCommandFlagEchoCommand | eHandleCommandFlagPrintResult,
                                                         "lldb",
                                                         m_debugger.GetPrompt(),
                                                         multiple_lines,
                                                         0,            // Don't show line numbers
                                                         *this));

    m_debugger.PushIOHandler(m_command_io_handler_sp);
    
    if (auto_handle_events)
        m_debugger.StartEventHandlerThread();
    
    if (spawn_thread)
    {
        m_debugger.StartIOHandlerThread();
    }
    else
    {
        m_debugger.ExecuteIOHanders();
    
        if (auto_handle_events)
            m_debugger.StopEventHandlerThread();
    }

}

