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

#include "CommandObjectBreakpoint.h"
#include "CommandObjectBreakpointCommand.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Target.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"

using namespace lldb;
using namespace lldb_private;

static void
AddBreakpointDescription (StreamString *s, Breakpoint *bp, lldb::DescriptionLevel level)
{
    s->IndentMore();
    bp->GetDescription (s, level, true);
    s->IndentLess();
    s->EOL();
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointSet::CommandOptions
//-------------------------------------------------------------------------
#pragma mark Set::CommandOptions

CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
    Options (),
    m_filename (),
    m_line_num (0),
    m_column (0),
    m_ignore_inlines (false),
    m_func_name (),
    m_func_name_type_mask (0),
    m_func_regexp (),
    m_modules (),
    m_load_addr(),
    m_ignore_count (0),
    m_thread_id(LLDB_INVALID_THREAD_ID),
    m_thread_index (UINT32_MAX),
    m_thread_name(),
    m_queue_name()
{
}

CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
{
}

lldb::OptionDefinition
CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, "<shlib-name>",
        "Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},

    { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument,   NULL, 0, "<n>",
        "Set the number of times this breakpoint is sKipped before stopping." },

    { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
        "The breakpoint stops only for the thread whose indeX matches this argument."},

    { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
        "The breakpoint stops only for the thread whose TID matches this argument."},

    { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
        "The breakpoint stops only for the thread whose thread name matches this argument."},

    { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
        "The breakpoint stops only for threads in the queue whose name is given by this argument."},

    { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
        "Set the breakpoint by source location in this particular file."},

    { LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, "<linenum>",
        "Set the breakpoint by source location at this particular line."},

    // Comment out this option for the moment, as we don't actually use it, but will in the future.
    // This way users won't see it, but the infrastructure is left in place.
    //    { 0, false, "column",     'c', required_argument, NULL, "<column>",
    //    "Set the breakpoint by source location at this particular column."},

    { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, "<address>",
        "Set the breakpoint by address, at the specified address."},

    { LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<name>",
        "Set the breakpoint by function name - for C++ this means namespaces and arguments will be ignored." },

    { LLDB_OPT_SET_4, true, "fullname", 'F', required_argument, NULL, CommandCompletions::eSymbolCompletion, "<fullname>",
        "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguemnts, and "
        "for Objective C this means a full function prototype with class and selector." },

    { LLDB_OPT_SET_5, true, "selector", 'S', required_argument, NULL, 0, "<selector>",
        "Set the breakpoint by ObjC selector name." },

    { LLDB_OPT_SET_6, true, "method", 'M', required_argument, NULL, 0, "<method>",
        "Set the breakpoint by C++ method names." },

    { LLDB_OPT_SET_7, true, "func_regex", 'r', required_argument, NULL, 0, "<regular-expression>",
        "Set the breakpoint by function name, evaluating a regular-expression to find the function name(s)." },

    { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
};

const lldb::OptionDefinition*
CommandObjectBreakpointSet::CommandOptions::GetDefinitions ()
{
    return g_option_table;
}

Error
CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
{
    Error error;
    char short_option = (char) m_getopt_table[option_idx].val;

    switch (short_option)
    {
        case 'a':
            m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 0);
            if (m_load_addr == LLDB_INVALID_ADDRESS)
                m_load_addr = Args::StringToUInt64(optarg, LLDB_INVALID_ADDRESS, 16);

            if (m_load_addr == LLDB_INVALID_ADDRESS)
                error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", optarg);
            break;

        case 'c':
            m_column = Args::StringToUInt32 (option_arg, 0);
            break;

        case 'f':
            m_filename = option_arg;
            break;

        case 'l':
            m_line_num = Args::StringToUInt32 (option_arg, 0);
            break;

        case 'n':
            m_func_name = option_arg;
            m_func_name_type_mask |= eFunctionNameTypeBase;
            break;

        case 'F':
            m_func_name = option_arg;
            m_func_name_type_mask |= eFunctionNameTypeFull;
            break;

        case 'S':
            m_func_name = option_arg;
            m_func_name_type_mask |= eFunctionNameTypeSelector;
            break;

        case 'M':
            m_func_name = option_arg;
            m_func_name_type_mask |= eFunctionNameTypeMethod;
            break;

        case 'r':
            m_func_regexp = option_arg;
            break;

        case 's':
            {
                m_modules.push_back (std::string (option_arg));
                break;
            }
        case 'k':
        {
            m_ignore_count = Args::StringToUInt32(optarg, UINT32_MAX, 0);
            if (m_ignore_count == UINT32_MAX)
               error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
        }
        break;
        case 't' :
        {
            m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
            if (m_thread_id == LLDB_INVALID_THREAD_ID)
               error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
        }
        break;
        case 'T':
            m_thread_name = option_arg;
            break;
        case 'q':
            m_queue_name = option_arg;
            break;
        case 'x':
        {
            m_thread_index = Args::StringToUInt32(optarg, UINT32_MAX, 0);
            if (m_thread_id == UINT32_MAX)
               error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
            
        }
        break;
        default:
            error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
            break;
    }

    return error;
}

void
CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
{
    Options::ResetOptionValues();

    m_filename.clear();
    m_line_num = 0;
    m_column = 0;
    m_func_name.clear();
    m_func_name_type_mask = 0;
    m_func_regexp.clear();
    m_load_addr = LLDB_INVALID_ADDRESS;
    m_modules.clear();
    m_ignore_count = 0;
    m_thread_id = LLDB_INVALID_THREAD_ID;
    m_thread_index = UINT32_MAX;
    m_thread_name.clear();
    m_queue_name.clear();
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointSet
//-------------------------------------------------------------------------
#pragma mark Set

CommandObjectBreakpointSet::CommandObjectBreakpointSet () :
    CommandObject ("breakpoint set", "Sets a breakpoint or set of breakpoints in the executable.", 
                   "breakpoint set <cmd-options>")
{
}

CommandObjectBreakpointSet::~CommandObjectBreakpointSet ()
{
}

Options *
CommandObjectBreakpointSet::GetOptions ()
{
    return &m_options;
}

bool
CommandObjectBreakpointSet::Execute
(
    CommandInterpreter &interpreter,
    Args& command,
    CommandReturnObject &result
)
{
    Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == NULL)
    {
        result.AppendError ("Invalid target, set executable file using 'file' command.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    // The following are the various types of breakpoints that could be set:
    //   1).  -f -l -p  [-s -g]   (setting breakpoint by source location)
    //   2).  -a  [-s -g]         (setting breakpoint by address)
    //   3).  -n  [-s -g]         (setting breakpoint by function name)
    //   4).  -r  [-s -g]         (setting breakpoint by function name regular expression)

    BreakpointSetType break_type = eSetTypeInvalid;

    if (m_options.m_line_num != 0)
        break_type = eSetTypeFileAndLine;
    else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
        break_type = eSetTypeAddress;
    else if (!m_options.m_func_name.empty())
        break_type = eSetTypeFunctionName;
    else if  (!m_options.m_func_regexp.empty())
        break_type = eSetTypeFunctionRegexp;

    ModuleSP module_sp = target->GetExecutableModule();
    Breakpoint *bp = NULL;
    FileSpec module;
    bool use_module = false;
    int num_modules = m_options.m_modules.size();

    if ((num_modules > 0) && (break_type != eSetTypeAddress))
        use_module = true;
     
    switch (break_type)
    {
        case eSetTypeFileAndLine: // Breakpoint by source position
        {
            FileSpec file;
            if (m_options.m_filename.empty())
            {
                StackFrame *cur_frame = interpreter.GetDebugger().GetExecutionContext().frame;
                if (cur_frame == NULL)
                {
                    result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
                    result.SetStatus (eReturnStatusFailed);
                    break;
                }
                else if (!cur_frame->HasDebugInformation())
                {
                    result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
                    result.SetStatus (eReturnStatusFailed);
                    break;
                }
                else
                {
                    const SymbolContext &context = cur_frame->GetSymbolContext(true);
                    if (context.line_entry.file)
                    {
                        file = context.line_entry.file;
                    }
                    else if (context.comp_unit != NULL)
                    {    file = context.comp_unit;
                    }
                    else
                    {
                        result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
                        result.SetStatus (eReturnStatusFailed);
                        break;
                    }
                }
            }
            else
            {
                file.SetFile(m_options.m_filename.c_str());
            }

            if (use_module)
            {
                for (int i = 0; i < num_modules; ++i)
                {
                    module.SetFile(m_options.m_modules[i].c_str());
                    bp = target->CreateBreakpoint (&module,
                                                   file,
                                                   m_options.m_line_num,
                                                   m_options.m_ignore_inlines).get();
                    if (bp)
                    {
                        StreamString &output_stream = result.GetOutputStream();
                        output_stream.Printf ("Breakpoint created: ");
                        bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
                        output_stream.EOL();
                        result.SetStatus (eReturnStatusSuccessFinishResult);
                    }
                    else
                    {
                        result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
                                                    m_options.m_modules[i].c_str());
                        result.SetStatus (eReturnStatusFailed);
                    }
                }
            }
            else
                bp = target->CreateBreakpoint (NULL,
                                               file,
                                               m_options.m_line_num,
                                               m_options.m_ignore_inlines).get();
        }
        break;
        case eSetTypeAddress: // Breakpoint by address
            bp = target->CreateBreakpoint (m_options.m_load_addr, false).get();
            break;

        case eSetTypeFunctionName: // Breakpoint by function name
            {
                uint32_t name_type_mask = m_options.m_func_name_type_mask;
                
                if (name_type_mask == 0)
                {
                
                    if (m_options.m_func_name.find('(') != std::string::npos ||
                        m_options.m_func_name.find("-[") == 0 ||
                        m_options.m_func_name.find("+[") == 0)
                        name_type_mask |= eFunctionNameTypeFull;
                    else
                        name_type_mask |= eFunctionNameTypeBase;
                }
                    
                
                if (use_module)
                {
                    for (int i = 0; i < num_modules; ++i)
                    {
                        module.SetFile(m_options.m_modules[i].c_str());
                        bp = target->CreateBreakpoint (&module, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
                        if (bp)
                        {
                            StreamString &output_stream = result.GetOutputStream();
                            output_stream.Printf ("Breakpoint created: ");
                            bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
                            output_stream.EOL();
                            result.SetStatus (eReturnStatusSuccessFinishResult);
                        }
                        else
                        {
                            result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
                                                        m_options.m_modules[i].c_str());
                            result.SetStatus (eReturnStatusFailed);
                        }
                    }
                }
                else
                    bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
            }
            break;

        case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
            {
                RegularExpression regexp(m_options.m_func_regexp.c_str());
                if (use_module)
                {
                    for (int i = 0; i < num_modules; ++i)
                    {
                        module.SetFile(m_options.m_modules[i].c_str());
                        bp = target->CreateBreakpoint (&module, regexp).get();
                        if (bp)
                        {
                            StreamString &output_stream = result.GetOutputStream();
                            output_stream.Printf ("Breakpoint created: ");
                            bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
                            output_stream.EOL();
                            result.SetStatus (eReturnStatusSuccessFinishResult);
                        }
                        else
                        {
                            result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
                                                        m_options.m_modules[i].c_str());
                            result.SetStatus (eReturnStatusFailed);
                        }
                    }
                }
                else
                    bp = target->CreateBreakpoint (NULL, regexp).get();
            }
            break;

        default:
            break;
    }

    // Now set the various options that were passed in:
    if (bp)
    {
        if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
            bp->SetThreadID (m_options.m_thread_id);
            
        if (m_options.m_thread_index != UINT32_MAX)
            bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
        
        if (!m_options.m_thread_name.empty())
            bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
        
        if (!m_options.m_queue_name.empty())
            bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
            
        if (m_options.m_ignore_count != 0)
            bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
    }
    
    if (bp && !use_module)
    {
        StreamString &output_stream = result.GetOutputStream();
        output_stream.Printf ("Breakpoint created: ");
        bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
        output_stream.EOL();
        result.SetStatus (eReturnStatusSuccessFinishResult);
    }
    else if (!bp)
    {
        result.AppendError ("Breakpoint creation failed: No breakpoint created.");
        result.SetStatus (eReturnStatusFailed);
    }

    return result.Succeeded();
}

//-------------------------------------------------------------------------
// CommandObjectMultiwordBreakpoint
//-------------------------------------------------------------------------
#pragma mark MultiwordBreakpoint

CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInterpreter &interpreter) :
    CommandObjectMultiword ("breakpoint",
                              "A set of commands for operating on breakpoints. Also see regexp-break.",
                              "breakpoint <command> [<command-options>]")
{
    bool status;

    CommandObjectSP list_command_object (new CommandObjectBreakpointList ());
    CommandObjectSP delete_command_object (new CommandObjectBreakpointDelete ());
    CommandObjectSP enable_command_object (new CommandObjectBreakpointEnable ());
    CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
    CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
    CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
    CommandObjectSP modify_command_object (new CommandObjectBreakpointModify());

    command_command_object->SetCommandName ("breakpoint command");
    enable_command_object->SetCommandName("breakpoint enable");
    disable_command_object->SetCommandName("breakpoint disable");
    list_command_object->SetCommandName ("breakpoint list");
    modify_command_object->SetCommandName ("breakpoint modify");
    set_command_object->SetCommandName("breakpoint set");

    status = LoadSubCommand (interpreter, "list",       list_command_object);
    status = LoadSubCommand (interpreter, "enable",     enable_command_object);
    status = LoadSubCommand (interpreter, "disable",    disable_command_object);
    status = LoadSubCommand (interpreter, "delete",     delete_command_object);
    status = LoadSubCommand (interpreter, "set",        set_command_object);
    status = LoadSubCommand (interpreter, "command",    command_command_object);
    status = LoadSubCommand (interpreter, "modify",     modify_command_object);
}

CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
{
}

void
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (Args &args, Target *target, CommandReturnObject &result,
                                                         BreakpointIDList *valid_ids)
{
    // args can be strings representing 1). integers (for breakpoint ids)
    //                                  2). the full breakpoint & location canonical representation
    //                                  3). the word "to" or a hyphen, representing a range (in which case there
    //                                      had *better* be an entry both before & after of one of the first two types.

    Args temp_args;

    // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
    // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
    // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.

    BreakpointIDList::FindAndReplaceIDRanges (args, target, result, temp_args);

    // NOW, convert the list of breakpoint id strings in TEMP_ARGS into an actual BreakpointIDList:

    valid_ids->InsertStringArray (temp_args.GetConstArgumentVector(), temp_args.GetArgumentCount(), result);

    // At this point,  all of the breakpoint ids that the user passed in have been converted to breakpoint IDs
    // and put into valid_ids.

    if (result.Succeeded())
    {
        // Now that we've converted everything from args into a list of breakpoint ids, go through our tentative list
        // of breakpoint id's and verify that they correspond to valid/currently set breakpoints.

        const size_t count = valid_ids->GetSize();
        for (size_t i = 0; i < count; ++i)
        {
            BreakpointID cur_bp_id = valid_ids->GetBreakpointIDAtIndex (i);
            Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
            if (breakpoint != NULL)
            {
                int num_locations = breakpoint->GetNumLocations();
                if (cur_bp_id.GetLocationID() > num_locations)
                {
                    StreamString id_str;
                    BreakpointID::GetCanonicalReference (&id_str, 
                                                         cur_bp_id.GetBreakpointID(),
                                                         cur_bp_id.GetLocationID());
                    i = valid_ids->GetSize() + 1;
                    result.AppendErrorWithFormat ("'%s' is not a currently valid breakpoint/location id.\n",
                                                 id_str.GetData());
                    result.SetStatus (eReturnStatusFailed);
                }
            }
            else
            {
                i = valid_ids->GetSize() + 1;
                result.AppendErrorWithFormat ("'%d' is not a currently valid breakpoint id.\n", cur_bp_id.GetBreakpointID());
                result.SetStatus (eReturnStatusFailed);
            }
        }
    }
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointList::Options
//-------------------------------------------------------------------------
#pragma mark List::CommandOptions

CommandObjectBreakpointList::CommandOptions::CommandOptions() :
    Options (),
    m_level (lldb::eDescriptionLevelFull)  // Breakpoint List defaults to brief descriptions
{
}

CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
{
}

lldb::OptionDefinition
CommandObjectBreakpointList::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_ALL, false, "internal", 'i', no_argument, NULL, 0, NULL,
        "Show debugger internal breakpoints" },

    { LLDB_OPT_SET_1, false, "brief",    'b', no_argument, NULL, 0, NULL,
        "Give a brief description of the breakpoint (no location info)."},

    // FIXME: We need to add an "internal" command, and then add this sort of thing to it.
    // But I need to see it for now, and don't want to wait.
    { LLDB_OPT_SET_2, false, "full",    'f', no_argument, NULL, 0, NULL,
        "Give a full description of the breakpoint and its locations."},

    { LLDB_OPT_SET_3, false, "verbose", 'v', no_argument, NULL, 0, NULL,
        "Explain everything we know about the breakpoint (for debugging debugger bugs)." },

    { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
};

const lldb::OptionDefinition*
CommandObjectBreakpointList::CommandOptions::GetDefinitions ()
{
    return g_option_table;
}

Error
CommandObjectBreakpointList::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
{
    Error error;
    char short_option = (char) m_getopt_table[option_idx].val;

    switch (short_option)
    {
        case 'b':
            m_level = lldb::eDescriptionLevelBrief;
            break;
        case 'f':
            m_level = lldb::eDescriptionLevelFull;
            break;
        case 'v':
            m_level = lldb::eDescriptionLevelVerbose;
            break;
        case 'i':
            m_internal = true;
            break;
        default:
            error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
            break;
    }

    return error;
}

void
CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
{
    Options::ResetOptionValues();

    m_level = lldb::eDescriptionLevelFull;
    m_internal = false;
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointList
//-------------------------------------------------------------------------
#pragma mark List

CommandObjectBreakpointList::CommandObjectBreakpointList () :
    CommandObject ("breakpoint list",
                     "List some or all breakpoints at configurable levels of detail.",
                     "breakpoint list [<breakpoint-id>]")
{
}

CommandObjectBreakpointList::~CommandObjectBreakpointList ()
{
}

Options *
CommandObjectBreakpointList::GetOptions ()
{
    return &m_options;
}

bool
CommandObjectBreakpointList::Execute
(
    CommandInterpreter &interpreter,
    Args& args,
    CommandReturnObject &result
)
{
    Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == NULL)
    {
        result.AppendError ("Invalid target, set executable file using 'file' command.");
        result.SetStatus (eReturnStatusSuccessFinishNoResult);
        return true;
    }

    const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
    Mutex::Locker locker;
    target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);

    size_t num_breakpoints = breakpoints.GetSize();

    if (num_breakpoints == 0)
    {
        result.AppendMessage ("No breakpoints currently set.");
        result.SetStatus (eReturnStatusSuccessFinishNoResult);
        return true;
    }

    StreamString &output_stream = result.GetOutputStream();

    if (args.GetArgumentCount() == 0)
    {
        // No breakpoint selected; show info about all currently set breakpoints.
        result.AppendMessage ("Current breakpoints:");
        for (size_t i = 0; i < num_breakpoints; ++i)
        {
            Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (i).get();
            AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
        }
        result.SetStatus (eReturnStatusSuccessFinishNoResult);
    }
    else
    {
        // Particular breakpoints selected; show info about that breakpoint.
        BreakpointIDList valid_bp_ids;
        CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);

        if (result.Succeeded())
        {
            for (size_t i = 0; i < valid_bp_ids.GetSize(); ++i)
            {
                BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
                Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
                AddBreakpointDescription (&output_stream, breakpoint, m_options.m_level);
            }
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
        }
        else
        {
            result.AppendError ("Invalid breakpoint id.");
            result.SetStatus (eReturnStatusFailed);
        }
    }

    return result.Succeeded();
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointEnable
//-------------------------------------------------------------------------
#pragma mark Enable

CommandObjectBreakpointEnable::CommandObjectBreakpointEnable () :
    CommandObject ("enable",
                     "Enable the specified disabled breakpoint(s).  If no breakpoints are specified, enable all of them.",
                     "breakpoint enable [<breakpoint-id> | <breakpoint-id-list>]")
{
    // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
    // potential invocation methods, we need to be a little tricky about generating the syntax string.
    //StreamString tmp_string;
    //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
    //m_cmd_syntax.assign (tmp_string.GetData(), tmp_string.GetSize());
}


CommandObjectBreakpointEnable::~CommandObjectBreakpointEnable ()
{
}


bool
CommandObjectBreakpointEnable::Execute 
(
    CommandInterpreter &interpreter,
    Args& args, 
    CommandReturnObject &result
)
{
    Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == NULL)
    {
        result.AppendError ("Invalid target, set executable file using 'file' command.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    Mutex::Locker locker;
    target->GetBreakpointList().GetListMutex(locker);

    const BreakpointList &breakpoints = target->GetBreakpointList();

    size_t num_breakpoints = breakpoints.GetSize();

    if (num_breakpoints == 0)
    {
        result.AppendError ("No breakpoints exist to be enabled.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    if (args.GetArgumentCount() == 0)
    {
        // No breakpoint selected; enable all currently set breakpoints.
        target->EnableAllBreakpoints ();
        result.AppendMessageWithFormat ("All breakpoints enabled. (%d breakpoints)\n", num_breakpoints);
        result.SetStatus (eReturnStatusSuccessFinishNoResult);
    }
    else
    {
        // Particular breakpoint selected; enable that breakpoint.
        BreakpointIDList valid_bp_ids;
        CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);

        if (result.Succeeded())
        {
            int enable_count = 0;
            int loc_count = 0;
            const size_t count = valid_bp_ids.GetSize();
            for (size_t i = 0; i < count; ++i)
            {
                BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);

                if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
                {
                    Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
                    if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
                    {
                        BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
                        if (location)
                        {
                            location->SetEnabled (true);
                            ++loc_count;
                        }
                    }
                    else
                    {
                        breakpoint->SetEnabled (true);
                        ++enable_count;
                    }
                }
            }
            result.AppendMessageWithFormat ("%d breakpoints enabled.\n", enable_count + loc_count);
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
        }
    }

    return result.Succeeded();
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointDisable
//-------------------------------------------------------------------------
#pragma mark Disable

CommandObjectBreakpointDisable::CommandObjectBreakpointDisable () :
    CommandObject ("disable",
                   "Disable the specified breakpoint(s) without removing it/them.  If no breakpoints are specified, disable them all.",
                   "disable [<breakpoint-id> | <breakpoint-id-list>]")
{
    // This command object can either be called via 'enable' or 'breakpoint enable'.  Because it has two different
    // potential invocation methods, we need to be a little tricky about generating the syntax string.
    //StreamString tmp_string;
    //tmp_string.Printf ("%s <breakpoint-id>", GetCommandName());
    //m_cmd_syntax.assign(tmp_string.GetData(), tmp_string.GetSize());
}

CommandObjectBreakpointDisable::~CommandObjectBreakpointDisable ()
{
}

bool
CommandObjectBreakpointDisable::Execute
(
    CommandInterpreter &interpreter,
    Args& args, 
    CommandReturnObject &result
)
{
    Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == NULL)
    {
        result.AppendError ("Invalid target, set executable file using 'file' command.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    Mutex::Locker locker;
    target->GetBreakpointList().GetListMutex(locker);

    const BreakpointList &breakpoints = target->GetBreakpointList();
    size_t num_breakpoints = breakpoints.GetSize();

    if (num_breakpoints == 0)
    {
        result.AppendError ("No breakpoints exist to be disabled.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    if (args.GetArgumentCount() == 0)
    {
        // No breakpoint selected; disable all currently set breakpoints.
        target->DisableAllBreakpoints ();
        result.AppendMessageWithFormat ("All breakpoints disabled. (%d breakpoints)\n", num_breakpoints);
        result.SetStatus (eReturnStatusSuccessFinishNoResult);
    }
    else
    {
        // Particular breakpoint selected; disable that breakpoint.
        BreakpointIDList valid_bp_ids;

        CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);

        if (result.Succeeded())
        {
            int disable_count = 0;
            int loc_count = 0;
            const size_t count = valid_bp_ids.GetSize();
            for (size_t i = 0; i < count; ++i)
            {
                BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);

                if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
                {
                    Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
                    if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
                    {
                        BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
                        if (location)
                        {
                            location->SetEnabled (false);
                            ++loc_count;
                        }
                    }
                    else
                    {
                        breakpoint->SetEnabled (false);
                        ++disable_count;
                    }
                }
            }
            result.AppendMessageWithFormat ("%d breakpoints disabled.\n", disable_count + loc_count);
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
        }
    }

    return result.Succeeded();
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointDelete
//-------------------------------------------------------------------------
#pragma mark Delete

CommandObjectBreakpointDelete::CommandObjectBreakpointDelete() :
    CommandObject ("breakpoint delete",
                   "Delete the specified breakpoint(s).  If no breakpoints are specified, delete them all.",
                   "breakpoint delete [<breakpoint-id> | <breakpoint-id-list>]")
{
}


CommandObjectBreakpointDelete::~CommandObjectBreakpointDelete ()
{
}

bool
CommandObjectBreakpointDelete::Execute 
(
    CommandInterpreter &interpreter,
    Args& args, 
    CommandReturnObject &result
)
{
    Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == NULL)
    {
        result.AppendError ("Invalid target, set executable file using 'file' command.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    Mutex::Locker locker;
    target->GetBreakpointList().GetListMutex(locker);
    
    const BreakpointList &breakpoints = target->GetBreakpointList();

    size_t num_breakpoints = breakpoints.GetSize();

    if (num_breakpoints == 0)
    {
        result.AppendError ("No breakpoints exist to be deleted.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    if (args.GetArgumentCount() == 0)
    {
        // No breakpoint selected; disable all currently set breakpoints.
        if (args.GetArgumentCount() != 0)
        {
            result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
            result.SetStatus (eReturnStatusFailed);
            return false;
        }

        target->RemoveAllBreakpoints ();
        result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
        result.SetStatus (eReturnStatusSuccessFinishNoResult);
    }
    else
    {
        // Particular breakpoint selected; disable that breakpoint.
        BreakpointIDList valid_bp_ids;
        CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (args, target, result, &valid_bp_ids);

        if (result.Succeeded())
        {
            int delete_count = 0;
            int disable_count = 0;
            const size_t count = valid_bp_ids.GetSize();
            for (size_t i = 0; i < count; ++i)
            {
                BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);

                if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
                {
                    if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
                    {
                        Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
                        BreakpointLocation *location = breakpoint->FindLocationByID (cur_bp_id.GetLocationID()).get();
                        // It makes no sense to try to delete individual locations, so we disable them instead.
                        if (location)
                        {
                            location->SetEnabled (false);
                            ++disable_count;
                        }
                    }
                    else
                    {
                        target->RemoveBreakpointByID (cur_bp_id.GetBreakpointID());
                        ++delete_count;
                    }
                }
            }
            result.AppendMessageWithFormat ("%d breakpoints deleted; %d breakpoint locations disabled.\n",
                                           delete_count, disable_count);
            result.SetStatus (eReturnStatusSuccessFinishNoResult);
        }
    }
    return result.Succeeded();
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointModify::CommandOptions
//-------------------------------------------------------------------------
#pragma mark Modify::CommandOptions

CommandObjectBreakpointModify::CommandOptions::CommandOptions() :
    Options (),
    m_ignore_count (0),
    m_thread_id(LLDB_INVALID_THREAD_ID),
    m_thread_index (UINT32_MAX),
    m_thread_name(),
    m_queue_name(),
    m_enable_passed (false),
    m_enable_value (false),
    m_name_passed (false),
    m_queue_passed (false)
{
}

CommandObjectBreakpointModify::CommandOptions::~CommandOptions ()
{
}

lldb::OptionDefinition
CommandObjectBreakpointModify::CommandOptions::g_option_table[] =
{
    { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument,   NULL, 0, NULL,
        "Set the number of times this breakpoint is sKipped before stopping." },

    { LLDB_OPT_SET_ALL, false, "thread_index",       'x', required_argument, NULL, NULL, "<thread_index>",
        "The breakpoint stops only for the thread whose indeX matches this argument."},

    { LLDB_OPT_SET_ALL, false, "thread_id",       't', required_argument, NULL, NULL, "<thread_id>",
        "The breakpoint stops only for the thread whose TID matches this argument."},

    { LLDB_OPT_SET_ALL, false, "thread_name",       'T', required_argument, NULL, NULL, "<thread_name>",
        "The breakpoint stops only for the thread whose thread name matches this argument."},

    { LLDB_OPT_SET_ALL, false, "queue_name",       'q', required_argument, NULL, NULL, "<queue_name>",
        "The breakpoint stops only for threads in the queue whose name is given by this argument."},

    { LLDB_OPT_SET_1, false, "enable",       'e', no_argument, NULL, NULL, NULL,
        "Enable the breakpoint."},

    { LLDB_OPT_SET_2, false, "disable",       'd', no_argument, NULL, NULL, NULL,
        "Disable the breakpoint."},


    { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
};

const lldb::OptionDefinition*
CommandObjectBreakpointModify::CommandOptions::GetDefinitions ()
{
    return g_option_table;
}

Error
CommandObjectBreakpointModify::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
{
    Error error;
    char short_option = (char) m_getopt_table[option_idx].val;

    switch (short_option)
    {
        case 'd':
            m_enable_passed = true;
            m_enable_value = false;
            break;
        case 'e':
            m_enable_passed = true;
            m_enable_value = true;
            break;
        case 'k':
        {
            m_ignore_count = Args::StringToUInt32(optarg, UINT32_MAX, 0);
            if (m_ignore_count == UINT32_MAX)
               error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
        }
        break;
        case 't' :
        {
            m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
            if (m_thread_id == LLDB_INVALID_THREAD_ID)
               error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
        }
        break;
        case 'T':
            if (option_arg != NULL)
                m_thread_name = option_arg;
            else
                m_thread_name.clear();
            m_name_passed = true;
            break;
        case 'q':
            if (option_arg != NULL)
                m_queue_name = option_arg;
            else
                m_queue_name.clear();
            m_queue_passed = true;
            break;
        case 'x':
        {
            m_thread_index = Args::StringToUInt32 (optarg, UINT32_MAX, 0);
            if (m_thread_id == UINT32_MAX)
               error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
            
        }
        break;
        default:
            error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
            break;
    }

    return error;
}

void
CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
{
    Options::ResetOptionValues();

    m_ignore_count = 0;
    m_thread_id = LLDB_INVALID_THREAD_ID;
    m_thread_index = UINT32_MAX;
    m_thread_name.clear();
    m_queue_name.clear();
    m_enable_passed = false;
    m_queue_passed = false;
    m_name_passed = false;
}

//-------------------------------------------------------------------------
// CommandObjectBreakpointModify
//-------------------------------------------------------------------------
#pragma mark Modify

CommandObjectBreakpointModify::CommandObjectBreakpointModify () :
    CommandObject ("breakpoint modify", "Modify the options on a breakpoint or set of breakpoints in the executable.", 
                   "breakpoint modify <cmd-options> break-id [break-id ...]")
{
}

CommandObjectBreakpointModify::~CommandObjectBreakpointModify ()
{
}

Options *
CommandObjectBreakpointModify::GetOptions ()
{
    return &m_options;
}

bool
CommandObjectBreakpointModify::Execute
(
    CommandInterpreter &interpreter,
    Args& command,
    CommandReturnObject &result
)
{
    if (command.GetArgumentCount() == 0)
    {
        result.AppendError ("No breakpoints specified.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == NULL)
    {
        result.AppendError ("Invalid target, set executable file using 'file' command.");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    Mutex::Locker locker;
    target->GetBreakpointList().GetListMutex(locker);
    
    BreakpointIDList valid_bp_ids;

    CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);

    if (result.Succeeded())
    {
        const size_t count = valid_bp_ids.GetSize(); 
        for (size_t i = 0; i < count; ++i)
        {
            BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);

            if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
            {
                Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
                if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
                {
                    BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
                    if (location)
                    {
                        if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
                            location->SetThreadID (m_options.m_thread_id);
                            
                        if (m_options.m_thread_index != UINT32_MAX)
                            location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
                        
                        if (m_options.m_name_passed)
                            location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
                        
                        if (m_options.m_queue_passed)
                            location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
                            
                        if (m_options.m_ignore_count != 0)
                            location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
                            
                        if (m_options.m_enable_passed)
                            location->SetEnabled (m_options.m_enable_value);
                    }
                }
                else
                {
                    if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
                        bp->SetThreadID (m_options.m_thread_id);
                        
                    if (m_options.m_thread_index != UINT32_MAX)
                        bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
                    
                    if (m_options.m_name_passed)
                        bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
                    
                    if (m_options.m_queue_passed)
                        bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
                        
                    if (m_options.m_ignore_count != 0)
                        bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
                        
                    if (m_options.m_enable_passed)
                        bp->SetEnabled (m_options.m_enable_value);

                }
            }
        }
    }
    
    return result.Succeeded();
}


