124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- Driver.cpp ----------------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "Driver.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <getopt.h>
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <libgen.h>
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <sys/ioctl.h>
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <termios.h>
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <unistd.h>
17f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include <string.h>
18f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include <stdlib.h>
19f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include <limits.h>
20d6e167d0fe8666347554226424bb39e36686e0d6Eli Friedman#include <fcntl.h>
215f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea#include <inttypes.h>
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <string>
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "IOChannel.h"
2628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham#include "lldb/API/SBBreakpoint.h"
27f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBCommandInterpreter.h"
28f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBCommandReturnObject.h"
29f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBCommunication.h"
30f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBDebugger.h"
31f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBEvent.h"
32f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBHostOS.h"
33f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBListener.h"
342e8cb8a7342a2ea672792067d712a794e215a3a7Jim Ingham#include "lldb/API/SBStream.h"
35f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBTarget.h"
36f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBThread.h"
37f2f321d826c21c674ca5787b18e8b3e0edaa214bEli Friedman#include "lldb/API/SBProcess.h"
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic void reset_stdin_termios ();
427cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Claytonstatic bool g_old_stdin_termios_is_valid = false;
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic struct termios g_old_stdin_termios;
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Ticestatic char *g_debugger_name =  (char *) "";
46c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Ticestatic Driver *g_driver = NULL;
47b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// In the Driver::MainLoop, we change the terminal settings.  This function is
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// added as an atexit handler to make sure we clean them up.
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic void
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerreset_stdin_termios ()
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
537cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton    if (g_old_stdin_termios_is_valid)
547cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton    {
557cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton        g_old_stdin_termios_is_valid = false;
567cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton        ::tcsetattr (STDIN_FILENO, TCSANOW, &g_old_stdin_termios);
577cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton    }
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
60b344843f75ef893762c93fd0a22d2d45712ce74dGreg Claytontypedef struct
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
62b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    uint32_t usage_mask;                     // Used to mark options that can be used together.  If (1 << n & usage_mask) != 0
63b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton                                             // then this option belongs to option set n.
64b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    bool required;                           // This option is required (in the current usage level)
65b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    const char * long_option;                // Full name for this option.
666475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton    int short_option;                        // Single character for this option.
67b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    int option_has_arg;                      // no_argument, required_argument or optional_argument
685e342f50b42b265d8568e1c926328858e74b2c0aGreg Clayton    uint32_t completion_type;                // Cookie the option class can use to do define the argument completion.
69b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    lldb::CommandArgumentType argument_type; // Type of argument this option takes
70b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton    const char *  usage_text;                // Full text explaining what this options does and what (if any) argument to
71b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton                                             // pass it.
72b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton} OptionDefinition;
73b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton
7483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham#define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
7583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham#define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
7683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham
77b344843f75ef893762c93fd0a22d2d45712ce74dGreg Claytonstatic OptionDefinition g_options[] =
78b344843f75ef893762c93fd0a22d2d45712ce74dGreg Clayton{
79f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_OPT_SET_1,    true , "help"           , 'h', no_argument      , 0,  eArgTypeNone,
80dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Prints out the usage information for the LLDB debugger." },
81f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_OPT_SET_2,    true , "version"        , 'v', no_argument      , 0,  eArgTypeNone,
82dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Prints out the current version number of the LLDB debugger." },
83f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_OPT_SET_3,    true , "arch"           , 'a', required_argument, 0,  eArgTypeArchitecture,
84dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to use the specified architecture when starting and running the program.  <architecture> must "
85dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "be one of the architectures for which the program was compiled." },
86f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_OPT_SET_3,    true , "file"           , 'f', required_argument, 0,  eArgTypeFilename,
87dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to use the file <filename> as the program to be debugged." },
887b771d2bc07469dfad2828cfb0bbd21713304810Jason Molenda    { LLDB_OPT_SET_3,    false, "core"           , 'c', required_argument, 0,  eArgTypeFilename,
896c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen        "Tells the debugger to use the fullpath to <path> as the core file." },
90f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_OPT_SET_4,    true , "attach-name"    , 'n', required_argument, 0,  eArgTypeProcessName,
91dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to attach to a process with the given name." },
92f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_OPT_SET_4,    true , "wait-for"       , 'w', no_argument      , 0,  eArgTypeNone,
93dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
94f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_OPT_SET_5,    true , "attach-pid"     , 'p', required_argument, 0,  eArgTypePid,
95dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to attach to a process with the given pid." },
96f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_3_TO_5,       false, "script-language", 'l', required_argument, 0,  eArgTypeScriptLang,
97dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default.  "
98dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl.  Currently only the Python "
99dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "extensions have been implemented." },
100f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_3_TO_5,       false, "debug"          , 'd', no_argument      , 0,  eArgTypeNone,
101dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to print out extra information for debugging itself." },
102f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_3_TO_5,       false, "source"         , 's', required_argument, 0,  eArgTypeFilename,
103dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to read in and execute the file <file>, which should contain lldb commands." },
104f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_3_TO_5,       false, "editor"         , 'e', no_argument      , 0,  eArgTypeNone,
105dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
106f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { LLDB_3_TO_5,       false, "no-lldbinit"    , 'x', no_argument      , 0,  eArgTypeNone,
107dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham        "Do not automatically parse any '.lldbinit' files." },
10817d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain    { LLDB_3_TO_5,       false, "no-use-colors"  , 'o', no_argument      , 0,  eArgTypeNone,
10917d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain        "Do not use colors." },
11017d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain    { LLDB_OPT_SET_6,    true , "python-path"    , 'P', no_argument      , 0,  eArgTypeNone,
111aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham        "Prints out the path to the lldb.py file for this version of lldb." },
112f99355834bee84e48e2b6205ed13d307faa74405Filipe Cabecinhas    { 0,                 false, NULL             , 0  , 0                , 0,  eArgTypeNone,         NULL }
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Inghamstatic const uint32_t last_option_set_with_args = 2;
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::Driver () :
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SBBroadcaster ("Driver"),
119558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham    m_debugger (SBDebugger::Create(false)),
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_editline_pty (),
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_editline_slave_fh (NULL),
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_editline_reader (),
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_io_channel_ap (),
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_option_data (),
1254084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton    m_executing_user_command (false),
12609eb052b6340c2e0b7062cbba72f71db960c61caDaniel Malea    m_waiting_for_command (false),
12709eb052b6340c2e0b7062cbba72f71db960c61caDaniel Malea    m_done(false)
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
129421ca5014ea0e163998b9a8e0d777d3adb5c872eGreg Clayton    // We want to be able to handle CTRL+D in the terminal to have it terminate
130421ca5014ea0e163998b9a8e0d777d3adb5c872eGreg Clayton    // certain input
131421ca5014ea0e163998b9a8e0d777d3adb5c872eGreg Clayton    m_debugger.SetCloseInputOnEOF (false);
132b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice    g_debugger_name = (char *) m_debugger.GetInstanceName();
133b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice    if (g_debugger_name == NULL)
134b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice        g_debugger_name = (char *) "";
135c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice    g_driver = this;
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::~Driver ()
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
140c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice    g_driver = NULL;
141c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice    g_debugger_name = NULL;
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::CloseIOChannelFile ()
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
1475d44dcc0f5558db037d13ebf4e772c9a8fb673cfJohnny Chen    // Write an End of File sequence to the file descriptor to ensure any
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // read functions can exit.
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char eof_str[] = "\x04";
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::write (m_editline_pty.GetMasterFileDescriptor(), eof_str, strlen(eof_str));
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_editline_pty.CloseMasterFileDescriptor();
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_editline_slave_fh)
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::fclose (m_editline_slave_fh);
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_editline_slave_fh = NULL;
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// This function takes INDENT, which tells how many spaces to output at the front
16254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// of each line; TEXT, which is the text that is to be output. It outputs the
16354e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// text, on multiple lines if necessary, to RESULT, with INDENT spaces at the
16454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// front of each line.  It breaks lines on spaces, tabs or newlines, shortening
16554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// the line if necessary to not break in the middle of a word. It assumes that
16654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton// each output line should contain a maximum of OUTPUT_MAX_COLUMNS characters.
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
16954e7afa84d945f9137f9372ecde432f9e1a702fcGreg ClaytonOutputFormattedUsageText (FILE *out, int indent, const char *text, int output_max_columns)
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int len = strlen (text);
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::string text_string (text);
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Force indentation to be reasonable.
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (indent >= output_max_columns)
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        indent = 0;
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Will it all fit on one line?
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (len + indent < output_max_columns)
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Output as a single line
18254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton        fprintf (out, "%*s%s\n", indent, "", text);
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We need to break it up into multiple lines.
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int text_width = output_max_columns - indent - 1;
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int start = 0;
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int end = start;
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int final_end = len;
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int sub_len;
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (end < final_end)
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              // Dont start the 'text' on a space, since we're already outputting the indentation.
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              while ((start < final_end) && (text[start] == ' '))
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                  start++;
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              end = start + text_width;
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              if (end > final_end)
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                  end = final_end;
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              else
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              {
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                  // If we're not at the end of the text, make sure we break the line on white space.
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                  while (end > start
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                         && text[end] != ' ' && text[end] != '\t' && text[end] != '\n')
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                      end--;
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              }
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              sub_len = end - start;
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              std::string substring = text_string.substr (start, sub_len);
21054e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton              fprintf (out, "%*s%s\n", indent, "", substring.c_str());
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner              start = end + 1;
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
217b344843f75ef893762c93fd0a22d2d45712ce74dGreg ClaytonShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t screen_width = 80;
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t indent_level = 0;
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *name = "lldb";
22234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    fprintf (out, "\nUsage:\n\n");
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    indent_level += 2;
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //                                                   <cmd> [options-for-level-1]
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //                                                   etc.
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t num_options;
23334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    uint32_t num_option_sets = 0;
23434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
23534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
23734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        uint32_t this_usage_mask = option_table[num_options].usage_mask;
23834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        if (this_usage_mask == LLDB_OPT_SET_ALL)
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
24034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            if (num_option_sets == 0)
24134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                num_option_sets = 1;
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
24334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        else
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
24554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton            for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
24634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            {
24734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                if (this_usage_mask & 1 << j)
24834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                {
24934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    if (num_option_sets <= j)
25034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                        num_option_sets = j + 1;
25134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                }
25234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            }
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
25434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    }
25534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
25634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
25734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    {
25834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        uint32_t opt_set_mask;
25934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
26034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        opt_set_mask = 1 << opt_set;
26134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
26234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        if (opt_set > 0)
26334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            fprintf (out, "\n");
26454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton        fprintf (out, "%*s%s", indent_level, "", name);
2656ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham        bool is_help_line = false;
26634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
26734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham        for (uint32_t i = 0; i < num_options; ++i)
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
26934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            if (option_table[i].usage_mask & opt_set_mask)
27034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            {
2714d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice                CommandArgumentType arg_type = option_table[i].argument_type;
272aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton                const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
2736ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham                // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
2746ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham                // so we do it by hand here.
2756ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham                if (option_table[i].short_option == 'h')
2766ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham                    is_help_line = true;
2776ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham
27834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                if (option_table[i].required)
27934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                {
28034e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    if (option_table[i].option_has_arg == required_argument)
281aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton                        fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
28234e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    else if (option_table[i].option_has_arg == optional_argument)
283aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton                        fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
28434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    else
28534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                        fprintf (out, " -%c", option_table[i].short_option);
28634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                }
28734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                else
28834e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                {
28934e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    if (option_table[i].option_has_arg == required_argument)
290aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton                        fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
29134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    else if (option_table[i].option_has_arg == optional_argument)
292aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton                        fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
29334e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                    else
29434e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                        fprintf (out, " [-%c]", option_table[i].short_option);
29534e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham                }
29634e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham            }
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
29883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham        if (!is_help_line && (opt_set <= last_option_set_with_args))
2996ae254432fed5ba37a8114e8a51702accaae5bb9Jim Ingham            fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    fprintf (out, "\n\n");
30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Now print out all the detailed information about the various options:  long form, short form and help text:
30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //   -- long_name <argument>
30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //   - short <argument>
30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //   help text
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // This variable is used to keep track of which options' info we've printed out, because some options can be in
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // more than one usage level, but we only want to print the long form of its information once.
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Driver::OptionData::OptionSet options_seen;
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Driver::OptionData::OptionSet::iterator pos;
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    indent_level += 5;
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31734e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham    for (uint32_t i = 0; i < num_options; ++i)
31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Only print this option if we haven't already seen it.
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos = options_seen.find (option_table[i].short_option);
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (pos == options_seen.end())
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
3234d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice            CommandArgumentType arg_type = option_table[i].argument_type;
324aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton            const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
3254d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            options_seen.insert (option_table[i].short_option);
32754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton            fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
3284d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice            if (arg_type != eArgTypeNone)
329aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton                fprintf (out, "<%s>", arg_name);
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            fprintf (out, "\n");
33154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton            fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
3324d6675c8e1cab6360f59865229835ae137d6f68aCaroline Tice            if (arg_type != eArgTypeNone)
333aa378b1f53f8b557ceab403e31e6c9ef9a20b77dGreg Clayton                fprintf (out, "<%s>", arg_name);
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            fprintf (out, "\n");
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            indent_level += 5;
33654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton            OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            indent_level -= 5;
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            fprintf (out, "\n");
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    indent_level -= 5;
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
344cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham    fprintf (out, "\n%*s(If you don't provide -f then the first argument will be the file to be debugged"
345cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham                  "\n%*s so '%s -- <filename> [<ARG1> [<ARG2>]]' also works."
346cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham                  "\n%*s Remember to end the options with \"--\" if any of your arguments have a \"-\" in them.)\n\n",
347cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham             indent_level, "",
348cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham             indent_level, "",
349cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham             name,
350cf0de2677d7c01d9117c782f67b85fa29d115c2aJim Ingham             indent_level, "");
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
354b344843f75ef893762c93fd0a22d2d45712ce74dGreg ClaytonBuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table,
355bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice                  uint32_t num_options)
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (num_options == 0)
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t i;
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t j;
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::bitset<256> option_seen;
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
364bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    getopt_table.resize (num_options + 1);
365bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (i = 0, j = 0; i < num_options; ++i)
36754e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    {
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        char short_opt = expanded_option_table[i].short_option;
36954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (option_seen.test(short_opt) == false)
37154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton        {
372bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice            getopt_table[j].name    = expanded_option_table[i].long_option;
373bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice            getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
374bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice            getopt_table[j].flag    = NULL;
375bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice            getopt_table[j].val     = expanded_option_table[i].short_option;
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            option_seen.set(short_opt);
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ++j;
37854e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton        }
37954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    }
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
381bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    getopt_table[j].name    = NULL;
382bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    getopt_table[j].has_arg = 0;
383bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    getopt_table[j].flag    = NULL;
384bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    getopt_table[j].val     = 0;
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38863094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::OptionData::OptionData () :
3894dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton    m_args(),
39063094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_script_lang (lldb::eScriptLanguageDefault),
3916c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen    m_core_file (),
39254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    m_crash_log (),
39363094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_source_command_files (),
39463094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_debug_mode (false),
39554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    m_print_version (false),
396aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham    m_print_python_path (false),
39763094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_print_help (false),
39883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    m_wait_for(false),
39983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    m_process_name(),
40083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    m_process_pid(LLDB_INVALID_PROCESS_ID),
40197c8957257a3e0b3ce6f46f8e5a28c965e30f357Daniel Dunbar    m_use_external_editor(false),
402dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson    m_seen_options()
40363094e0bb161580564954dee512955c1c79d3476Greg Clayton{
40463094e0bb161580564954dee512955c1c79d3476Greg Clayton}
40563094e0bb161580564954dee512955c1c79d3476Greg Clayton
40663094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::OptionData::~OptionData ()
40763094e0bb161580564954dee512955c1c79d3476Greg Clayton{
40863094e0bb161580564954dee512955c1c79d3476Greg Clayton}
40963094e0bb161580564954dee512955c1c79d3476Greg Clayton
41063094e0bb161580564954dee512955c1c79d3476Greg Claytonvoid
41163094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::OptionData::Clear ()
41263094e0bb161580564954dee512955c1c79d3476Greg Clayton{
4134dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton    m_args.clear ();
41463094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_script_lang = lldb::eScriptLanguageDefault;
41563094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_source_command_files.clear ();
41663094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_debug_mode = false;
41763094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_print_help = false;
41863094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_print_version = false;
419aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham    m_print_python_path = false;
42074989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham    m_use_external_editor = false;
42183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    m_wait_for = false;
42283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    m_process_name.erase();
42383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    m_process_pid = LLDB_INVALID_PROCESS_ID;
42463094e0bb161580564954dee512955c1c79d3476Greg Clayton}
42563094e0bb161580564954dee512955c1c79d3476Greg Clayton
42663094e0bb161580564954dee512955c1c79d3476Greg Claytonvoid
42763094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::ResetOptionValues ()
42863094e0bb161580564954dee512955c1c79d3476Greg Clayton{
42963094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_option_data.Clear ();
43063094e0bb161580564954dee512955c1c79d3476Greg Clayton}
43163094e0bb161580564954dee512955c1c79d3476Greg Clayton
43263094e0bb161580564954dee512955c1c79d3476Greg Claytonconst char *
43363094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetFilename() const
43463094e0bb161580564954dee512955c1c79d3476Greg Clayton{
4354dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton    if (m_option_data.m_args.empty())
43663094e0bb161580564954dee512955c1c79d3476Greg Clayton        return NULL;
4374dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton    return m_option_data.m_args.front().c_str();
43863094e0bb161580564954dee512955c1c79d3476Greg Clayton}
43963094e0bb161580564954dee512955c1c79d3476Greg Clayton
44063094e0bb161580564954dee512955c1c79d3476Greg Claytonconst char *
44163094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetCrashLogFilename() const
44263094e0bb161580564954dee512955c1c79d3476Greg Clayton{
44363094e0bb161580564954dee512955c1c79d3476Greg Clayton    if (m_option_data.m_crash_log.empty())
44463094e0bb161580564954dee512955c1c79d3476Greg Clayton        return NULL;
44563094e0bb161580564954dee512955c1c79d3476Greg Clayton    return m_option_data.m_crash_log.c_str();
44663094e0bb161580564954dee512955c1c79d3476Greg Clayton}
44763094e0bb161580564954dee512955c1c79d3476Greg Clayton
44863094e0bb161580564954dee512955c1c79d3476Greg Claytonlldb::ScriptLanguage
44963094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetScriptLanguage() const
45063094e0bb161580564954dee512955c1c79d3476Greg Clayton{
45163094e0bb161580564954dee512955c1c79d3476Greg Clayton    return m_option_data.m_script_lang;
45263094e0bb161580564954dee512955c1c79d3476Greg Clayton}
45363094e0bb161580564954dee512955c1c79d3476Greg Clayton
45463094e0bb161580564954dee512955c1c79d3476Greg Claytonsize_t
45563094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetNumSourceCommandFiles () const
45663094e0bb161580564954dee512955c1c79d3476Greg Clayton{
45763094e0bb161580564954dee512955c1c79d3476Greg Clayton    return m_option_data.m_source_command_files.size();
45863094e0bb161580564954dee512955c1c79d3476Greg Clayton}
45963094e0bb161580564954dee512955c1c79d3476Greg Clayton
46063094e0bb161580564954dee512955c1c79d3476Greg Claytonconst char *
46163094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetSourceCommandFileAtIndex (uint32_t idx) const
46263094e0bb161580564954dee512955c1c79d3476Greg Clayton{
46363094e0bb161580564954dee512955c1c79d3476Greg Clayton    if (idx < m_option_data.m_source_command_files.size())
46463094e0bb161580564954dee512955c1c79d3476Greg Clayton        return m_option_data.m_source_command_files[idx].c_str();
46563094e0bb161580564954dee512955c1c79d3476Greg Clayton    return NULL;
46663094e0bb161580564954dee512955c1c79d3476Greg Clayton}
46763094e0bb161580564954dee512955c1c79d3476Greg Clayton
46863094e0bb161580564954dee512955c1c79d3476Greg Claytonbool
46963094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::GetDebugMode() const
47063094e0bb161580564954dee512955c1c79d3476Greg Clayton{
47163094e0bb161580564954dee512955c1c79d3476Greg Clayton    return m_option_data.m_debug_mode;
47263094e0bb161580564954dee512955c1c79d3476Greg Clayton}
47363094e0bb161580564954dee512955c1c79d3476Greg Clayton
47463094e0bb161580564954dee512955c1c79d3476Greg Clayton
47563094e0bb161580564954dee512955c1c79d3476Greg Clayton// Check the arguments that were passed to this program to make sure they are valid and to get their
47663094e0bb161580564954dee512955c1c79d3476Greg Clayton// argument values (if any).  Return a boolean value indicating whether or not to start up the full
47763094e0bb161580564954dee512955c1c79d3476Greg Clayton// debugger (i.e. the Command Interpreter) or not.  Return FALSE if the arguments were invalid OR
47863094e0bb161580564954dee512955c1c79d3476Greg Clayton// if the user only wanted help or version information.
47963094e0bb161580564954dee512955c1c79d3476Greg Clayton
48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerSBError
48163094e0bb161580564954dee512955c1c79d3476Greg ClaytonDriver::ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &exit)
48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
48363094e0bb161580564954dee512955c1c79d3476Greg Clayton    ResetOptionValues ();
48463094e0bb161580564954dee512955c1c79d3476Greg Clayton
48563094e0bb161580564954dee512955c1c79d3476Greg Clayton    SBCommandReturnObject result;
48663094e0bb161580564954dee512955c1c79d3476Greg Clayton
48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SBError error;
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::string option_string;
48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct option *long_options = NULL;
490bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    std::vector<struct option> long_options_vector;
49154e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    uint32_t num_options;
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49354e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton    for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
49454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton        /* Do Nothing. */;
49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (num_options == 0)
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (argc > 1)
49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            error.SetErrorStringWithFormat ("invalid number of options");
50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return error;
50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
503bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    BuildGetOptTable (g_options, long_options_vector, num_options);
50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
505bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    if (long_options_vector.empty())
506bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice        long_options = NULL;
507bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice    else
508bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice        long_options = &long_options_vector.front();
50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (long_options == NULL)
51124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        error.SetErrorStringWithFormat ("invalid long options");
51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return error;
51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5163f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton    // Build the option_string argument for call to getopt_long_only.
51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (int i = 0; long_options[i].name != NULL; ++i)
51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (long_options[i].flag == NULL)
52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            option_string.push_back ((char) long_options[i].val);
52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            switch (long_options[i].has_arg)
52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                default:
52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case no_argument:
52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case required_argument:
52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    option_string.push_back (':');
53024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
53124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case optional_argument:
53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    option_string.append ("::");
53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
538558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham    // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
539558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham    // know at that point whether we should read in init files yet.  So we don't read them in in the
540558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham    // Driver constructor, then set the flags back to "read them in" here, and then if we see the
541558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham    // "-n" flag, we'll turn it off again.  Finally we have to read them in by hand later in the
542558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham    // main loop.
543558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham
544558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham    m_debugger.SkipLLDBInitFiles (false);
545558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham    m_debugger.SkipAppInitFiles (false);
546558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham
5473f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton    // Prepare for & make calls to getopt_long_only.
548ef2bc8787c6b12bd69dc45dd38ab2f1eb2673778Eli Friedman#if __GLIBC__
549ef2bc8787c6b12bd69dc45dd38ab2f1eb2673778Eli Friedman    optind = 0;
550ef2bc8787c6b12bd69dc45dd38ab2f1eb2673778Eli Friedman#else
55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    optreset = 1;
55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    optind = 1;
553ef2bc8787c6b12bd69dc45dd38ab2f1eb2673778Eli Friedman#endif
55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    int val;
55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (1)
55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int long_options_index = -1;
5583f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton        val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
55924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
56024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (val == -1)
56124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
56224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else if (val == '?')
56324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
56463094e0bb161580564954dee512955c1c79d3476Greg Clayton            m_option_data.m_print_help = true;
56524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            error.SetErrorStringWithFormat ("unknown or ambiguous option");
56624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
56724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
56824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else if (val == 0)
56924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            continue;
57024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
57124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
57263094e0bb161580564954dee512955c1c79d3476Greg Clayton            m_option_data.m_seen_options.insert ((char) val);
57324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (long_options_index == -1)
57424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
57524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                for (int i = 0;
57624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                     long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
57724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                     ++i)
57824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
57924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (long_options[i].val == val)
58024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
58124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        long_options_index = i;
58224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        break;
58324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
58424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
58524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
58624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
58724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (long_options_index >= 0)
58824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
5896475c42148a8ea1ca86e5db465db7eca742d897dGreg Clayton                const int short_option = g_options[long_options_index].short_option;
59024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
59163094e0bb161580564954dee512955c1c79d3476Greg Clayton                switch (short_option)
59263094e0bb161580564954dee512955c1c79d3476Greg Clayton                {
59363094e0bb161580564954dee512955c1c79d3476Greg Clayton                    case 'h':
59463094e0bb161580564954dee512955c1c79d3476Greg Clayton                        m_option_data.m_print_help = true;
59563094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
59624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
59763094e0bb161580564954dee512955c1c79d3476Greg Clayton                    case 'v':
59863094e0bb161580564954dee512955c1c79d3476Greg Clayton                        m_option_data.m_print_version = true;
59963094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
60024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
601aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham                    case 'P':
602aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham                        m_option_data.m_print_python_path = true;
603aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham                        break;
604aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham
60563094e0bb161580564954dee512955c1c79d3476Greg Clayton                    case 'c':
6066c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                        {
6076c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                            SBFileSpec file(optarg);
6086c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                            if (file.Exists())
6096c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                            {
6106c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                                m_option_data.m_core_file = optarg;
6116c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                            }
6126c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                            else
6136c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                                error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
6146c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                        }
61563094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
6166c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen
61774989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham                    case 'e':
61874989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham                        m_option_data.m_use_external_editor = true;
61974989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham                        break;
620887aa2898314218406275a34cbec30c11cd00acdGreg Clayton
62183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    case 'x':
622887aa2898314218406275a34cbec30c11cd00acdGreg Clayton                        m_debugger.SkipLLDBInitFiles (true);
623558dd5bc8b25722fa5b5106586b97ecf99e0026eJim Ingham                        m_debugger.SkipAppInitFiles (true);
624887aa2898314218406275a34cbec30c11cd00acdGreg Clayton                        break;
625887aa2898314218406275a34cbec30c11cd00acdGreg Clayton
62617d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain                    case 'o':
62717d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain                        m_debugger.SetUseColor (false);
62817d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain                        break;
62917d5a0358d60922707fdab6ec9c3251ca44dd614Michael Sartain
63063094e0bb161580564954dee512955c1c79d3476Greg Clayton                    case 'f':
63163094e0bb161580564954dee512955c1c79d3476Greg Clayton                        {
63263094e0bb161580564954dee512955c1c79d3476Greg Clayton                            SBFileSpec file(optarg);
63363094e0bb161580564954dee512955c1c79d3476Greg Clayton                            if (file.Exists())
6344dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                            {
6354dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                                m_option_data.m_args.push_back (optarg);
6364dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                            }
637eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                            else if (file.ResolveExecutableLocation())
638eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                            {
639eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                                char path[PATH_MAX];
640ee6e790171b9a04023d0ea22603f0ac0ecb9a2c6Johnny Chen                                file.GetPath (path, sizeof(path));
6414dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                                m_option_data.m_args.push_back (path);
642eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                            }
64363094e0bb161580564954dee512955c1c79d3476Greg Clayton                            else
64463094e0bb161580564954dee512955c1c79d3476Greg Clayton                                error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
64563094e0bb161580564954dee512955c1c79d3476Greg Clayton                        }
64663094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
64724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
64863094e0bb161580564954dee512955c1c79d3476Greg Clayton                    case 'a':
64963094e0bb161580564954dee512955c1c79d3476Greg Clayton                        if (!m_debugger.SetDefaultArchitecture (optarg))
65063094e0bb161580564954dee512955c1c79d3476Greg Clayton                            error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
65163094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
65224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
65363094e0bb161580564954dee512955c1c79d3476Greg Clayton                    case 'l':
65463094e0bb161580564954dee512955c1c79d3476Greg Clayton                        m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
65563094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
65624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
65763094e0bb161580564954dee512955c1c79d3476Greg Clayton                    case 'd':
65863094e0bb161580564954dee512955c1c79d3476Greg Clayton                        m_option_data.m_debug_mode = true;
65963094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
66024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
66183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    case 'n':
66283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        m_option_data.m_process_name = optarg;
66383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        break;
66483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham
66583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    case 'w':
66683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        m_option_data.m_wait_for = true;
66783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        break;
66883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham
66983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    case 'p':
67083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        {
67183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                            char *remainder;
67283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                            m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
67383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                            if (remainder == optarg || *remainder != '\0')
67483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                                error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
67583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                                                                optarg);
67683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        }
67783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        break;
67863094e0bb161580564954dee512955c1c79d3476Greg Clayton                    case 's':
67963094e0bb161580564954dee512955c1c79d3476Greg Clayton                        {
68063094e0bb161580564954dee512955c1c79d3476Greg Clayton                            SBFileSpec file(optarg);
68163094e0bb161580564954dee512955c1c79d3476Greg Clayton                            if (file.Exists())
68263094e0bb161580564954dee512955c1c79d3476Greg Clayton                                m_option_data.m_source_command_files.push_back (optarg);
683eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                            else if (file.ResolveExecutableLocation())
684eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                            {
685eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                                char final_path[PATH_MAX];
686ee6e790171b9a04023d0ea22603f0ac0ecb9a2c6Johnny Chen                                file.GetPath (final_path, sizeof(final_path));
687eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                                std::string path_str (final_path);
688eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                                m_option_data.m_source_command_files.push_back (path_str);
689eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice                            }
69063094e0bb161580564954dee512955c1c79d3476Greg Clayton                            else
69163094e0bb161580564954dee512955c1c79d3476Greg Clayton                                error.SetErrorStringWithFormat("file specified in --source (-s) option doesn't exist: '%s'", optarg);
69263094e0bb161580564954dee512955c1c79d3476Greg Clayton                        }
69363094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
69424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
69563094e0bb161580564954dee512955c1c79d3476Greg Clayton                    default:
69663094e0bb161580564954dee512955c1c79d3476Greg Clayton                        m_option_data.m_print_help = true;
69763094e0bb161580564954dee512955c1c79d3476Greg Clayton                        error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
69863094e0bb161580564954dee512955c1c79d3476Greg Clayton                        break;
69963094e0bb161580564954dee512955c1c79d3476Greg Clayton                }
70024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
70163094e0bb161580564954dee512955c1c79d3476Greg Clayton            else
70224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
70363094e0bb161580564954dee512955c1c79d3476Greg Clayton                error.SetErrorStringWithFormat ("invalid option with value %i", val);
70424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
70563094e0bb161580564954dee512955c1c79d3476Greg Clayton            if (error.Fail())
706bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice            {
70763094e0bb161580564954dee512955c1c79d3476Greg Clayton                return error;
708bd5c63ef58a9ebed5b458ddbb77eb334b84787bdCaroline Tice            }
70963094e0bb161580564954dee512955c1c79d3476Greg Clayton        }
71024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
71134e9a98dcff785b0693594b6d6753f560abf8be2Jim Ingham
71263094e0bb161580564954dee512955c1c79d3476Greg Clayton    if (error.Fail() || m_option_data.m_print_help)
71324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
71424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ShowUsage (out_fh, g_options, m_option_data);
7159caa94672c3a70e76316edfd29fa52d4a1ff6729Greg Clayton        exit = true;
71624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
71724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else if (m_option_data.m_print_version)
71824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
71963094e0bb161580564954dee512955c1c79d3476Greg Clayton        ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
72063094e0bb161580564954dee512955c1c79d3476Greg Clayton        exit = true;
72124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
722aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham    else if (m_option_data.m_print_python_path)
723aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham    {
724aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham        SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
725aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham        if (python_file_spec.IsValid())
726aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham        {
727aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham            char python_path[PATH_MAX];
728aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham            size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
729aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham            if (num_chars < PATH_MAX)
730aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham            {
731aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham                ::fprintf (out_fh, "%s\n", python_path);
732aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham            }
733aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham            else
734aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham                ::fprintf (out_fh, "<PATH TOO LONG>\n");
735aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham        }
736aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham        else
737aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham            ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
738aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham        exit = true;
739aa93c931a4c1275b2fecec23ef34f231afda4773Jim Ingham    }
74083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
74124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7424dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        // Any arguments that are left over after option parsing are for
7434dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        // the program. If a file was specified with -f then the filename
7444dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        // is already in the m_option_data.m_args array, and any remaining args
7454dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        // are arguments for the inferior program. If no file was specified with
7464dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        // -f, then what is left is the program name followed by any arguments.
7474dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton
7483f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton        // Skip any options we consumed with getopt_long_only
7494dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        argc -= optind;
7504dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        argv += optind;
7514dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton
7524dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        if (argc > 0)
7534dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        {
7544dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton            for (int arg_idx=0; arg_idx<argc; ++arg_idx)
7554dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton            {
7564dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                const char *arg = argv[arg_idx];
7574dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                if (arg)
7584dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                    m_option_data.m_args.push_back (arg);
7594dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton            }
7604dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton        }
7614dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton
76224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
76383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    else
76483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    {
7653f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton        // Skip any options we consumed with getopt_long_only
76683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham        argc -= optind;
7674a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton        //argv += optind; // Commented out to keep static analyzer happy
76883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham
76983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham        if (argc > 0)
77083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham            ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
77183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham    }
77224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
77363094e0bb161580564954dee512955c1c79d3476Greg Clayton    return error;
77424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
77524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
776757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticesize_t
77724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::GetProcessSTDOUT ()
77824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
77924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  The process has stuff waiting for stdout; get it and write it out to the appropriate place.
78024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char stdio_buffer[1024];
78124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    size_t len;
782757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    size_t total_bytes = 0;
783c833295baeec641086f536e78050388af36784f8Jim Ingham    while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
784757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    {
7854084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        m_io_channel_ap->OutWrite (stdio_buffer, len, NO_ASYNC);
786757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        total_bytes += len;
787757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    }
788757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    return total_bytes;
78924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
79024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
791757500e29b7856823f2f4aedd30f206ec009147eCaroline Ticesize_t
79224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::GetProcessSTDERR ()
79324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
79424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  The process has stuff waiting for stderr; get it and write it out to the appropriate place.
79524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char stdio_buffer[1024];
79624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    size_t len;
797757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    size_t total_bytes = 0;
798c833295baeec641086f536e78050388af36784f8Jim Ingham    while ((len = m_debugger.GetSelectedTarget().GetProcess().GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
799757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    {
8004084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        m_io_channel_ap->ErrWrite (stdio_buffer, len, NO_ASYNC);
801757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice        total_bytes += len;
802757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    }
803757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice    return total_bytes;
80424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
80524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
80624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
807c833295baeec641086f536e78050388af36784f8Jim InghamDriver::UpdateSelectedThread ()
80824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
80924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    using namespace lldb;
810c833295baeec641086f536e78050388af36784f8Jim Ingham    SBProcess process(m_debugger.GetSelectedTarget().GetProcess());
81124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (process.IsValid())
81224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
813c833295baeec641086f536e78050388af36784f8Jim Ingham        SBThread curr_thread (process.GetSelectedThread());
81424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SBThread thread;
81524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        StopReason curr_thread_stop_reason = eStopReasonInvalid;
81624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        curr_thread_stop_reason = curr_thread.GetStopReason();
81724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
81824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!curr_thread.IsValid() ||
81924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            curr_thread_stop_reason == eStopReasonInvalid ||
82024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            curr_thread_stop_reason == eStopReasonNone)
82124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
82224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Prefer a thread that has just completed its plan over another thread as current thread.
82324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            SBThread plan_thread;
82424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            SBThread other_thread;
82524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            const size_t num_threads = process.GetNumThreads();
82624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            size_t i;
82724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            for (i = 0; i < num_threads; ++i)
82824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
82924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                thread = process.GetThreadAtIndex(i);
83024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                StopReason thread_stop_reason = thread.GetStopReason();
83124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                switch (thread_stop_reason)
83224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
83324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case eStopReasonInvalid:
83424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case eStopReasonNone:
83524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
83624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
83724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case eStopReasonTrace:
83824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case eStopReasonBreakpoint:
83924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case eStopReasonWatchpoint:
84024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case eStopReasonSignal:
84124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case eStopReasonException:
8420bce9a22354df3f00e68ffd912119a0741753b7fGreg Clayton                case eStopReasonExec:
843278f16e1dd4097bf3dd12b0f63f1fac0f11c4006Andrew Kaylor                case eStopReasonThreadExiting:
84424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (!other_thread.IsValid())
84524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        other_thread = thread;
84624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
84724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case eStopReasonPlanComplete:
84824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (!plan_thread.IsValid())
84924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        plan_thread = thread;
85024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
85124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
85224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
85324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (plan_thread.IsValid())
854c833295baeec641086f536e78050388af36784f8Jim Ingham                process.SetSelectedThread (plan_thread);
85524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else if (other_thread.IsValid())
856c833295baeec641086f536e78050388af36784f8Jim Ingham                process.SetSelectedThread (other_thread);
85724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
85824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
85924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (curr_thread.IsValid())
86024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    thread = curr_thread;
86124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else
86224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    thread = process.GetThreadAtIndex(0);
86324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
86424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (thread.IsValid())
865c833295baeec641086f536e78050388af36784f8Jim Ingham                    process.SetSelectedThread (thread);
86624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
86724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
86824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
86924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
87024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
87128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham// This function handles events that were broadcast by the process.
87228e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Inghamvoid
87328e23861bedbeb5e46be7d2af4c33bf5132422c6Jim InghamDriver::HandleBreakpointEvent (const SBEvent &event)
87428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham{
87528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    using namespace lldb;
87628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    const uint32_t event_type = SBBreakpoint::GetBreakpointEventTypeFromEvent (event);
87728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham
87828e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    if (event_type & eBreakpointEventTypeAdded
87928e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        || event_type & eBreakpointEventTypeRemoved
88028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        || event_type & eBreakpointEventTypeEnabled
88128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        || event_type & eBreakpointEventTypeDisabled
88228e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        || event_type & eBreakpointEventTypeCommandChanged
88328e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        || event_type & eBreakpointEventTypeConditionChanged
88428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        || event_type & eBreakpointEventTypeIgnoreChanged
88528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        || event_type & eBreakpointEventTypeLocationsResolved)
88628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    {
88728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        // Don't do anything about these events, since the breakpoint commands already echo these actions.
88828e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    }
88928e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    else if (event_type & eBreakpointEventTypeLocationsAdded)
89028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    {
89128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        char message[256];
89228e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        uint32_t num_new_locations = SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
89328e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        if (num_new_locations > 0)
89428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        {
89528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham            SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event);
8964722b10307668368bf0f12fa6b8691e4f4cb5488Jim Ingham            int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n",
89728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham                                          num_new_locations,
89831f175eacd5b7bd82694726c22464d6e4a84d1d5Jason Molenda                                          num_new_locations == 1 ? "" : "s",
89928e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham                                          breakpoint.GetID());
90028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham            m_io_channel_ap->OutWrite(message, message_len, ASYNC);
90128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham        }
90228e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    }
90328e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    else if (event_type & eBreakpointEventTypeLocationsRemoved)
90428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    {
90528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham       // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
90628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    }
90728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    else if (event_type & eBreakpointEventTypeLocationsResolved)
90828e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    {
90928e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham       // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
91028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham    }
91128e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham}
91224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
91324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This function handles events that were broadcast by the process.
91424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
91524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::HandleProcessEvent (const SBEvent &event)
91624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
91724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    using namespace lldb;
91824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t event_type = event.GetType();
91924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
92024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (event_type & SBProcess::eBroadcastBitSTDOUT)
92124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
92224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // The process has stdout available, get it and write it out to the
92324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // appropriate place.
9244a348081030cdd2af758fddc869518357d9befd3Caroline Tice        GetProcessSTDOUT ();
92524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
92624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else if (event_type & SBProcess::eBroadcastBitSTDERR)
92724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
92824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // The process has stderr available, get it and write it out to the
92924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // appropriate place.
9304a348081030cdd2af758fddc869518357d9befd3Caroline Tice        GetProcessSTDERR ();
93124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
93224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else if (event_type & SBProcess::eBroadcastBitStateChanged)
93324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
93424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Drain all stout and stderr so we don't see any output come after
93524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // we print our prompts
9364a348081030cdd2af758fddc869518357d9befd3Caroline Tice        GetProcessSTDOUT ();
9374a348081030cdd2af758fddc869518357d9befd3Caroline Tice        GetProcessSTDERR ();
93824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Something changed in the process;  get the event and report the process's current status and location to
93924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // the user.
94024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        StateType event_state = SBProcess::GetStateFromEvent (event);
94124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (event_state == eStateInvalid)
94224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return;
94324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
94424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SBProcess process (SBProcess::GetProcessFromEvent (event));
94524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        assert (process.IsValid());
94624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
94724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (event_state)
94824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
94924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateInvalid:
95024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateUnloaded:
951e71e258286a1713dbb2d366d8b81ff2f28e0216fGreg Clayton        case eStateConnected:
95224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateAttaching:
95324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateLaunching:
95424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateStepping:
95524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateDetached:
95624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
95724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                char message[1024];
9585f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " %s\n", process.GetProcessID(),
95963094e0bb161580564954dee512955c1c79d3476Greg Clayton                                              m_debugger.StateAsCString (event_state));
9604a348081030cdd2af758fddc869518357d9befd3Caroline Tice                m_io_channel_ap->OutWrite(message, message_len, ASYNC);
96124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
96224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
96324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
96424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateRunning:
96524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Don't be chatty when we run...
96624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
96724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
96824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateExited:
969757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice            {
970757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice                SBCommandReturnObject result;
971757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice                m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
9724a348081030cdd2af758fddc869518357d9befd3Caroline Tice                m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
9734a348081030cdd2af758fddc869518357d9befd3Caroline Tice                m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
974757500e29b7856823f2f4aedd30f206ec009147eCaroline Tice            }
97524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
97624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
97724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateStopped:
97824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateCrashed:
97924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case eStateSuspended:
98024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Make sure the program hasn't been auto-restarted:
98124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (SBProcess::GetRestartedFromEvent (event))
98224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
98389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                size_t num_reasons = SBProcess::GetNumRestartedReasonsFromEvent(event);
98489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                if (num_reasons > 0)
98589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                {
98624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // FIXME: Do we want to report this, or would that just be annoyingly chatty?
98789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    if (num_reasons == 1)
98889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    {
98989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        char message[1024];
99089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, 0);
99189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted: %s\n",
99289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                                              process.GetProcessID(), reason ? reason : "<UNKNOWN REASON>");
99389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        m_io_channel_ap->OutWrite(message, message_len, ASYNC);
99489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    }
99589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    else
99689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    {
99789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        char message[1024];
99889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted, reasons:\n",
99924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                              process.GetProcessID());
100089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        m_io_channel_ap->OutWrite(message, message_len, ASYNC);
100189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        for (size_t i = 0; i < num_reasons; i++)
100289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        {
100389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                            const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, i);
100489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                            int message_len = ::snprintf(message, sizeof(message), "\t%s\n", reason ? reason : "<UNKNOWN REASON>");
100589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                            m_io_channel_ap->OutWrite(message, message_len, ASYNC);
100689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                        }
100789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    }
100889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                }
100924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
101024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
101124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
1012f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                if (GetDebugger().GetSelectedTarget() == process.GetTarget())
1013f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                {
1014f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    SBCommandReturnObject result;
1015f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    UpdateSelectedThread ();
1016f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    m_debugger.GetCommandInterpreter().HandleCommand("process status", result, false);
1017f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    m_io_channel_ap->ErrWrite (result.GetError(), result.GetErrorSize(), ASYNC);
1018f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    m_io_channel_ap->OutWrite (result.GetOutput(), result.GetOutputSize(), ASYNC);
1019f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                }
1020f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                else
1021f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                {
1022f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    SBStream out_stream;
1023f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    uint32_t target_idx = GetDebugger().GetIndexOfTarget(process.GetTarget());
1024f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    if (target_idx != UINT32_MAX)
1025f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                        out_stream.Printf ("Target %d: (", target_idx);
1026f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    else
1027f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                        out_stream.Printf ("Target <unknown index>: (");
1028f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    process.GetTarget().GetDescription (out_stream, eDescriptionLevelBrief);
1029f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    out_stream.Printf (") stopped.\n");
1030f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                    m_io_channel_ap->OutWrite (out_stream.GetData(), out_stream.GetSize(), ASYNC);
1031f92ddcc2fda5ca564acc37d2fecd4b577dfc2bdeJim Ingham                }
103224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
103324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
103424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
103524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
103624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
103724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
103894a5d0de4433dce556db59758f3d6124eb0e1a2aJim Inghamvoid
103994a5d0de4433dce556db59758f3d6124eb0e1a2aJim InghamDriver::HandleThreadEvent (const SBEvent &event)
104094a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham{
104194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham    // At present the only thread event we handle is the Frame Changed event, and all we do for that is just
104294a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham    // reprint the thread status for that thread.
104394a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham    using namespace lldb;
104494a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham    const uint32_t event_type = event.GetType();
10452e2812388b75d3c62c9518cc1a6550ce29325aa6Jim Ingham    if (event_type == SBThread::eBroadcastBitStackChanged
10462e2812388b75d3c62c9518cc1a6550ce29325aa6Jim Ingham        || event_type == SBThread::eBroadcastBitThreadSelected)
104794a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham    {
104894a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham        SBThread thread = SBThread::GetThreadFromEvent (event);
104994a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham        if (thread.IsValid())
105094a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham        {
105194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham            SBStream out_stream;
105294a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham            thread.GetStatus(out_stream);
105394a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham            m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC);
105494a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham        }
105594a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham    }
105694a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham}
105794a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham
105824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
105924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
106024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
106124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::HandleIOEvent (const SBEvent &event)
106224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
106324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool quit = false;
106424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
106524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const uint32_t event_type = event.GetType();
106624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
106724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (event_type & IOChannel::eBroadcastBitHasUserInput)
106824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
106924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We got some input (i.e. a command string) from the user; pass it off to the command interpreter for
107024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // handling.
107124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
107224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const char *command_string = SBEvent::GetCStringFromEvent(event);
107324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (command_string == NULL)
107454e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton            command_string = "";
107524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SBCommandReturnObject result;
10762e8cb8a7342a2ea672792067d712a794e215a3a7Jim Ingham
1077845d6dac85acc72334aeef730f088168fe0eaf36Caroline Tice        // We don't want the result to bypass the OutWrite function in IOChannel, as this can result in odd
1078845d6dac85acc72334aeef730f088168fe0eaf36Caroline Tice        // output orderings and problems with the prompt.
10794084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton
10804084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        // Note that we are in the process of executing a command
10814084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        m_executing_user_command = true;
10824084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton
10832e8cb8a7342a2ea672792067d712a794e215a3a7Jim Ingham        m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, true);
10842e8cb8a7342a2ea672792067d712a794e215a3a7Jim Ingham
10854084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        // Note that we are back from executing a user command
10864084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        m_executing_user_command = false;
10874084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton
10884084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        // Display any STDOUT/STDERR _prior_ to emitting the command result text
10894084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        GetProcessSTDOUT ();
10904084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        GetProcessSTDERR ();
10914084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton
1092c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata        const bool only_if_no_immediate = true;
1093c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata
10944084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        // Now emit the command output text from the command we just executed
1095b8fda50a3e97699af76a406f03d139ee1bd94d01Enrico Granata        const size_t output_size = result.GetOutputSize();
1096c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata        if (output_size > 0)
1097c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata            m_io_channel_ap->OutWrite (result.GetOutput(only_if_no_immediate), output_size, NO_ASYNC);
1098c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata
10994084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        // Now emit the command error text from the command we just executed
1100b8fda50a3e97699af76a406f03d139ee1bd94d01Enrico Granata        const size_t error_size = result.GetErrorSize();
1101c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata        if (error_size > 0)
1102c2bc7944f7c2f10114426f447259a35acb0b1e18Enrico Granata            m_io_channel_ap->OutWrite (result.GetError(only_if_no_immediate), error_size, NO_ASYNC);
1103845d6dac85acc72334aeef730f088168fe0eaf36Caroline Tice
110424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We are done getting and running our command, we can now clear the
110524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // m_waiting_for_command so we can get another one.
110624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_waiting_for_command = false;
110724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
110824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // If our editline input reader is active, it means another input reader
110924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // got pushed onto the input reader and caused us to become deactivated.
111024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // When the input reader above us gets popped, we will get re-activated
111124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // and our prompt will refresh in our callback
111224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_editline_reader.IsActive())
111324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
111424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ReadyForCommand ();
111524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
111624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
111724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else if (event_type & IOChannel::eBroadcastBitUserInterrupt)
111824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
111924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // This is here to handle control-c interrupts from the user.  It has not yet really been implemented.
112024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // TO BE DONE:  PROPERLY HANDLE CONTROL-C FROM USER
112124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //m_io_channel_ap->CancelInput();
112224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Anything else?  Send Interrupt to process?
112324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
112424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
112524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner             (event_type & IOChannel::eBroadcastBitThreadDidExit))
112624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
112724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // If the IOChannel thread is trying to go away, then it is definitely
112824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // time to end the debugging session.
112924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        quit = true;
113024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
113124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
113224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return quit;
113324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
113424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
113524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
113624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::MasterThreadBytesReceived (void *baton, const void *src, size_t src_len)
113724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
113824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Driver *driver = (Driver*)baton;
113924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    driver->GetFromMaster ((const char *)src, src_len);
114024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
114124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
114224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
114324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::GetFromMaster (const char *src, size_t src_len)
114424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
114524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Echo the characters back to the Debugger's stdout, that way if you
114624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // type characters while a command is running, you'll see what you've typed.
114763094e0bb161580564954dee512955c1c79d3476Greg Clayton    FILE *out_fh = m_debugger.GetOutputFileHandle();
114824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (out_fh)
114924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::fwrite (src, 1, src_len, out_fh);
115024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
115124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
115224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
115324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::EditLineInputReaderCallback
115424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner(
115524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void *baton,
115624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SBInputReader *reader,
115724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    InputReaderAction notification,
115824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const char *bytes,
115924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    size_t bytes_len
116024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner)
116124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
116224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Driver *driver = (Driver *)baton;
116324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
116424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    switch (notification)
116524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
116624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    case eInputReaderActivate:
116724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        break;
116824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
116924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    case eInputReaderReactivate:
11704084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton        if (driver->m_executing_user_command == false)
11714084fe70b71aef8d9d90186f9f54cd8a4d4c6861Greg Clayton            driver->ReadyForCommand();
117224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        break;
117324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
117424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    case eInputReaderDeactivate:
117524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        break;
11764a348081030cdd2af758fddc869518357d9befd3Caroline Tice
11774a348081030cdd2af758fddc869518357d9befd3Caroline Tice    case eInputReaderAsynchronousOutputWritten:
11784a348081030cdd2af758fddc869518357d9befd3Caroline Tice        if (driver->m_io_channel_ap.get() != NULL)
11794a348081030cdd2af758fddc869518357d9befd3Caroline Tice            driver->m_io_channel_ap->RefreshPrompt();
11804a348081030cdd2af758fddc869518357d9befd3Caroline Tice        break;
118124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1182c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice    case eInputReaderInterrupt:
1183c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        if (driver->m_io_channel_ap.get() != NULL)
1184c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        {
11855d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham            SBProcess process(driver->GetDebugger().GetSelectedTarget().GetProcess());
11860d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham            if (!driver->m_io_channel_ap->EditLineHasCharacters()
11875d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham                &&  process.IsValid()
11885d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham                && (process.GetState() == lldb::eStateRunning || process.GetState() == lldb::eStateAttaching))
11890d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham            {
11905d90ade8e8e0d776fe8e1b9e88fc1c86d02e8e4eJim Ingham                process.SendAsyncInterrupt ();
11910d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham            }
11920d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham            else
11930d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham            {
11940d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham                driver->m_io_channel_ap->OutWrite ("^C\n", 3, NO_ASYNC);
11950d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham                // I wish I could erase the entire input line, but there's no public API for that.
11960d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham                driver->m_io_channel_ap->EraseCharsBeforeCursor();
11970d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham                driver->m_io_channel_ap->RefreshPrompt();
11980d99969ff26d108ec04f8830913e41e7f151db56Jim Ingham            }
1199c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        }
1200c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        break;
1201c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice
1202c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice    case eInputReaderEndOfFile:
1203c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        if (driver->m_io_channel_ap.get() != NULL)
1204c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        {
12054a348081030cdd2af758fddc869518357d9befd3Caroline Tice            driver->m_io_channel_ap->OutWrite ("^D\n", 3, NO_ASYNC);
1206c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice            driver->m_io_channel_ap->RefreshPrompt ();
1207c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        }
1208c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        write (driver->m_editline_pty.GetMasterFileDescriptor(), "quit\n", 5);
1209c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        break;
1210c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice
121124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    case eInputReaderGotToken:
121224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        write (driver->m_editline_pty.GetMasterFileDescriptor(), bytes, bytes_len);
121324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        break;
121424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
121524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    case eInputReaderDone:
121624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        break;
121724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
121824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return bytes_len;
121924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
122024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
122124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
122224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::MainLoop ()
122324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
122424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char error_str[1024];
122524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_editline_pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, error_str, sizeof(error_str)) == false)
122624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
122724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::fprintf (stderr, "error: failed to open driver pseudo terminal : %s", error_str);
122824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        exit(1);
122924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
123024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
123124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
123224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const char *driver_slave_name = m_editline_pty.GetSlaveName (error_str, sizeof(error_str));
123324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (driver_slave_name == NULL)
123424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
123524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ::fprintf (stderr, "error: failed to get slave name for driver pseudo terminal : %s", error_str);
123624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            exit(2);
123724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
123824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
123924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
124024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_editline_slave_fh = ::fopen (driver_slave_name, "r+");
124124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (m_editline_slave_fh == NULL)
124224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
124324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                SBError error;
124424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                error.SetErrorToErrno();
124524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                ::fprintf (stderr, "error: failed to get open slave for driver pseudo terminal : %s",
124624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                           error.GetCString());
124724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                exit(3);
124824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
124924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
125024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ::setbuf (m_editline_slave_fh, NULL);
125124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
125224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
125324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12544a348081030cdd2af758fddc869518357d9befd3Caroline Tice    lldb_utility::PseudoTerminal editline_output_pty;
12554a348081030cdd2af758fddc869518357d9befd3Caroline Tice    FILE *editline_output_slave_fh = NULL;
12564a348081030cdd2af758fddc869518357d9befd3Caroline Tice
12574a348081030cdd2af758fddc869518357d9befd3Caroline Tice    if (editline_output_pty.OpenFirstAvailableMaster (O_RDWR|O_NOCTTY, error_str, sizeof (error_str)) == false)
12584a348081030cdd2af758fddc869518357d9befd3Caroline Tice    {
12594a348081030cdd2af758fddc869518357d9befd3Caroline Tice        ::fprintf (stderr, "error: failed to open output pseudo terminal : %s", error_str);
12604a348081030cdd2af758fddc869518357d9befd3Caroline Tice        exit(1);
12614a348081030cdd2af758fddc869518357d9befd3Caroline Tice    }
12624a348081030cdd2af758fddc869518357d9befd3Caroline Tice    else
12634a348081030cdd2af758fddc869518357d9befd3Caroline Tice    {
12644a348081030cdd2af758fddc869518357d9befd3Caroline Tice        const char *output_slave_name = editline_output_pty.GetSlaveName (error_str, sizeof(error_str));
12654a348081030cdd2af758fddc869518357d9befd3Caroline Tice        if (output_slave_name == NULL)
12664a348081030cdd2af758fddc869518357d9befd3Caroline Tice        {
12674a348081030cdd2af758fddc869518357d9befd3Caroline Tice            ::fprintf (stderr, "error: failed to get slave name for output pseudo terminal : %s", error_str);
12684a348081030cdd2af758fddc869518357d9befd3Caroline Tice            exit(2);
12694a348081030cdd2af758fddc869518357d9befd3Caroline Tice        }
12704a348081030cdd2af758fddc869518357d9befd3Caroline Tice        else
12714a348081030cdd2af758fddc869518357d9befd3Caroline Tice        {
12724a348081030cdd2af758fddc869518357d9befd3Caroline Tice            editline_output_slave_fh = ::fopen (output_slave_name, "r+");
12734a348081030cdd2af758fddc869518357d9befd3Caroline Tice            if (editline_output_slave_fh == NULL)
12744a348081030cdd2af758fddc869518357d9befd3Caroline Tice            {
12754a348081030cdd2af758fddc869518357d9befd3Caroline Tice                SBError error;
12764a348081030cdd2af758fddc869518357d9befd3Caroline Tice                error.SetErrorToErrno();
12774a348081030cdd2af758fddc869518357d9befd3Caroline Tice                ::fprintf (stderr, "error: failed to get open slave for output pseudo terminal : %s",
12784a348081030cdd2af758fddc869518357d9befd3Caroline Tice                           error.GetCString());
12794a348081030cdd2af758fddc869518357d9befd3Caroline Tice                exit(3);
12804a348081030cdd2af758fddc869518357d9befd3Caroline Tice            }
12814a348081030cdd2af758fddc869518357d9befd3Caroline Tice            ::setbuf (editline_output_slave_fh, NULL);
12824a348081030cdd2af758fddc869518357d9befd3Caroline Tice        }
12834a348081030cdd2af758fddc869518357d9befd3Caroline Tice    }
128424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
128524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner   // struct termios stdin_termios;
128624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
128724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (::tcgetattr(STDIN_FILENO, &g_old_stdin_termios) == 0)
12887cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton    {
12897cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton        g_old_stdin_termios_is_valid = true;
129024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        atexit (reset_stdin_termios);
12917cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton    }
129224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
129324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::setbuf (stdin, NULL);
129424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ::setbuf (stdout, NULL);
129524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
129663094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_debugger.SetErrorFileHandle (stderr, false);
129763094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_debugger.SetOutputFileHandle (stdout, false);
129863094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_debugger.SetInputFileHandle (stdin, true);
129974989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham
130074989e88af7e04f3fe0bb3a800163113d7e0ca12Jim Ingham    m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
130124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
130224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // You have to drain anything that comes to the master side of the PTY.  master_out_comm is
130324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // for that purpose.  The reason you need to do this is a curious reason...  editline will echo
130424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // characters to the PTY when it gets characters while el_gets is not running, and then when
130524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // you call el_gets (or el_getc) it will try to reset the terminal back to raw mode which blocks
130624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // if there are unconsumed characters in the out buffer.
130724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // However, you don't need to do anything with the characters, since editline will dump these
130824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // unconsumed characters after printing the prompt again in el_gets.
130924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1310eecb0f3b5021e37311f9588f14bcab38a35b8e9aGreg Clayton    SBCommunication master_out_comm("driver.editline");
1311eecb0f3b5021e37311f9588f14bcab38a35b8e9aGreg Clayton    master_out_comm.SetCloseOnEOF (false);
131224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    master_out_comm.AdoptFileDesriptor(m_editline_pty.GetMasterFileDescriptor(), false);
131324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    master_out_comm.SetReadThreadBytesReceivedCallback(Driver::MasterThreadBytesReceived, this);
131424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
131524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (master_out_comm.ReadThreadStart () == false)
131624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
131724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::fprintf (stderr, "error: failed to start master out read thread");
131824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        exit(5);
131924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
132024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
132163094e0bb161580564954dee512955c1c79d3476Greg Clayton    SBCommandInterpreter sb_interpreter = m_debugger.GetCommandInterpreter();
132224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13234a348081030cdd2af758fddc869518357d9befd3Caroline Tice    m_io_channel_ap.reset (new IOChannel(m_editline_slave_fh, editline_output_slave_fh, stdout, stderr, this));
13244a348081030cdd2af758fddc869518357d9befd3Caroline Tice
13254a348081030cdd2af758fddc869518357d9befd3Caroline Tice    SBCommunication out_comm_2("driver.editline_output");
13264a348081030cdd2af758fddc869518357d9befd3Caroline Tice    out_comm_2.SetCloseOnEOF (false);
13274a348081030cdd2af758fddc869518357d9befd3Caroline Tice    out_comm_2.AdoptFileDesriptor (editline_output_pty.GetMasterFileDescriptor(), false);
13284a348081030cdd2af758fddc869518357d9befd3Caroline Tice    out_comm_2.SetReadThreadBytesReceivedCallback (IOChannel::LibeditOutputBytesReceived, m_io_channel_ap.get());
13294a348081030cdd2af758fddc869518357d9befd3Caroline Tice
13304a348081030cdd2af758fddc869518357d9befd3Caroline Tice    if (out_comm_2.ReadThreadStart () == false)
13314a348081030cdd2af758fddc869518357d9befd3Caroline Tice    {
13324a348081030cdd2af758fddc869518357d9befd3Caroline Tice        ::fprintf (stderr, "error: failed to start libedit output read thread");
13334a348081030cdd2af758fddc869518357d9befd3Caroline Tice        exit (5);
13344a348081030cdd2af758fddc869518357d9befd3Caroline Tice    }
13354a348081030cdd2af758fddc869518357d9befd3Caroline Tice
133624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
133724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct winsize window_size;
133824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (isatty (STDIN_FILENO)
133924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
134024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
13416e4c5ce0f697eb9899a54854a2a9004e961b0de2Caroline Tice        if (window_size.ws_col > 0)
1342238c0a1e7b733cee539258faa656159c63f9e893Greg Clayton            m_debugger.SetTerminalWidth (window_size.ws_col);
134324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
134424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
134524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Since input can be redirected by the debugger, we must insert our editline
134624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // input reader in the queue so we know when our reader should be active
134724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // and so we can receive bytes only when we are supposed to.
134863094e0bb161580564954dee512955c1c79d3476Greg Clayton    SBError err (m_editline_reader.Initialize (m_debugger,
134963094e0bb161580564954dee512955c1c79d3476Greg Clayton                                               Driver::EditLineInputReaderCallback, // callback
135024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                               this,                              // baton
135124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                               eInputReaderGranularityByte,       // token_size
135224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                               NULL,                              // end token - NULL means never done
135324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                               NULL,                              // prompt - taken care of elsewhere
135424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                               false));                           // echo input - don't need Debugger
135524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                                                  // to do this, we handle it elsewhere
135624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
135724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (err.Fail())
135824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
135924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ::fprintf (stderr, "error: %s", err.GetCString());
136024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        exit (6);
136124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
136224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
136363094e0bb161580564954dee512955c1c79d3476Greg Clayton    m_debugger.PushInputReader (m_editline_reader);
136424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
136563094e0bb161580564954dee512955c1c79d3476Greg Clayton    SBListener listener(m_debugger.GetListener());
136624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (listener.IsValid())
136724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
136824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
136994a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham        listener.StartListeningForEventClass(m_debugger,
137094a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham                                         SBTarget::GetBroadcasterClassName(),
137194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham                                         SBTarget::eBroadcastBitBreakpointChanged);
137294a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham        listener.StartListeningForEventClass(m_debugger,
137394a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham                                         SBThread::GetBroadcasterClassName(),
13742e2812388b75d3c62c9518cc1a6550ce29325aa6Jim Ingham                                         SBThread::eBroadcastBitStackChanged |
13752e2812388b75d3c62c9518cc1a6550ce29325aa6Jim Ingham                                         SBThread::eBroadcastBitThreadSelected);
137624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        listener.StartListeningForEvents (*m_io_channel_ap,
137724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                          IOChannel::eBroadcastBitHasUserInput |
137824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                          IOChannel::eBroadcastBitUserInterrupt |
137924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                          IOChannel::eBroadcastBitThreadShouldExit |
138024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                          IOChannel::eBroadcastBitThreadDidStart |
138124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                          IOChannel::eBroadcastBitThreadDidExit);
138224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
138324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_io_channel_ap->Start ())
138424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
138524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            bool iochannel_thread_exited = false;
138624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
138724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            listener.StartListeningForEvents (sb_interpreter.GetBroadcaster(),
1388388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                                              SBCommandInterpreter::eBroadcastBitQuitCommandReceived |
1389388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                                              SBCommandInterpreter::eBroadcastBitAsynchronousOutputData |
1390388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                                              SBCommandInterpreter::eBroadcastBitAsynchronousErrorData);
139124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
139224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Before we handle any options from the command line, we parse the
139324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // .lldbinit file in the user's home directory.
139424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            SBCommandReturnObject result;
139524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            sb_interpreter.SourceInitFileInHomeDirectory(result);
139624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (GetDebugMode())
139724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
139863094e0bb161580564954dee512955c1c79d3476Greg Clayton                result.PutError (m_debugger.GetErrorFileHandle());
139963094e0bb161580564954dee512955c1c79d3476Greg Clayton                result.PutOutput (m_debugger.GetOutputFileHandle());
140024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
140124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
140224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Now we handle options we got from the command line
140324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            char command_string[PATH_MAX * 2];
140424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            const size_t num_source_command_files = GetNumSourceCommandFiles();
14051581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata            const bool dump_stream_only_if_no_immediate = true;
140624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (num_source_command_files > 0)
140724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
140824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                for (size_t i=0; i < num_source_command_files; ++i)
140924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
141024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    const char *command_file = GetSourceCommandFileAtIndex(i);
14117c9842487cd2a61f12669624f4ba38bb5c8617eaJohnny Chen                    ::snprintf (command_string, sizeof(command_string), "command source '%s'", command_file);
141263094e0bb161580564954dee512955c1c79d3476Greg Clayton                    m_debugger.GetCommandInterpreter().HandleCommand (command_string, result, false);
141324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (GetDebugMode())
141424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
141563094e0bb161580564954dee512955c1c79d3476Greg Clayton                        result.PutError (m_debugger.GetErrorFileHandle());
141663094e0bb161580564954dee512955c1c79d3476Greg Clayton                        result.PutOutput (m_debugger.GetOutputFileHandle());
141724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
14181581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata
14191581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata                    // if the command sourcing generated an error - dump the result object
1420c8aa9c9b5b9c584daa94cba7592bebea6ce6dfabEnrico Granata                    if (result.Succeeded() == false)
14211581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata                    {
14221581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata                        const size_t output_size = result.GetOutputSize();
14231581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata                        if (output_size > 0)
14241581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata                            m_io_channel_ap->OutWrite (result.GetOutput(dump_stream_only_if_no_immediate), output_size, NO_ASYNC);
1425c8aa9c9b5b9c584daa94cba7592bebea6ce6dfabEnrico Granata                        const size_t error_size = result.GetErrorSize();
1426c8aa9c9b5b9c584daa94cba7592bebea6ce6dfabEnrico Granata                        if (error_size > 0)
1427c8aa9c9b5b9c584daa94cba7592bebea6ce6dfabEnrico Granata                            m_io_channel_ap->OutWrite (result.GetError(dump_stream_only_if_no_immediate), error_size, NO_ASYNC);
14281581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata                    }
14291581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata
14301581d7d8a976cc63ce44789c07b1b35a80786dfbEnrico Granata                    result.Clear();
143124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
143224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
143324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14346c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen            // Was there a core file specified?
14356c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen            std::string core_file_spec("");
14366c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen            if (!m_option_data.m_core_file.empty())
14376c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                core_file_spec.append("--core ").append(m_option_data.m_core_file);
14386c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen
14394dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton            const size_t num_args = m_option_data.m_args.size();
14404dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton            if (num_args > 0)
144124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
144224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                char arch_name[64];
144363094e0bb161580564954dee512955c1c79d3476Greg Clayton                if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
14444dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                    ::snprintf (command_string,
14454dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                                sizeof (command_string),
14466c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                                "target create --arch=%s %s \"%s\"",
14474dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                                arch_name,
14486c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                                core_file_spec.c_str(),
14494dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                                m_option_data.m_args[0].c_str());
145024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else
14514dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                    ::snprintf (command_string,
14524dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                                sizeof(command_string),
14536c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                                "target create %s \"%s\"",
14546c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                                core_file_spec.c_str(),
14554dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                                m_option_data.m_args[0].c_str());
145624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
145763094e0bb161580564954dee512955c1c79d3476Greg Clayton                m_debugger.HandleCommand (command_string);
14584dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton
14594dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                if (num_args > 1)
14604dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                {
1461abb3302051246273eb92cca203c9a1b9d9736e05Greg Clayton                    m_debugger.HandleCommand ("settings clear target.run-args");
14624dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                    char arg_cstr[1024];
14634dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                    for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
14644dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                    {
146583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        ::snprintf (arg_cstr,
146683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                                    sizeof(arg_cstr),
1467abb3302051246273eb92cca203c9a1b9d9736e05Greg Clayton                                    "settings append target.run-args \"%s\"",
146883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                                    m_option_data.m_args[arg_idx].c_str());
14694dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                        m_debugger.HandleCommand (arg_cstr);
14704dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                    }
14714dc1892eefc8ccaceec79c09b63fa198b40b4ab9Greg Clayton                }
147224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
14736c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen            else if (!core_file_spec.empty())
14746c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen            {
14756c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                ::snprintf (command_string,
14766c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                            sizeof(command_string),
14776c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                            "target create %s",
14786c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                            core_file_spec.c_str());
14796c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen                m_debugger.HandleCommand (command_string);;
14806c061beb3f9b60380b9638a4eacb3bc46ad38fc5Johnny Chen            }
148124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
148224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Now that all option parsing is done, we try and parse the .lldbinit
148324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // file in the current working directory
148424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            sb_interpreter.SourceInitFileInCurrentWorkingDirectory (result);
148524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (GetDebugMode())
148624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
148763094e0bb161580564954dee512955c1c79d3476Greg Clayton                result.PutError(m_debugger.GetErrorFileHandle());
148863094e0bb161580564954dee512955c1c79d3476Greg Clayton                result.PutOutput(m_debugger.GetOutputFileHandle());
148924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
149024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
149124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            SBEvent event;
149224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
149324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Make sure the IO channel is started up before we try to tell it we
149424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // are ready for input
149524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            listener.WaitForEventForBroadcasterWithType (UINT32_MAX,
149624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                         *m_io_channel_ap,
149724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                         IOChannel::eBroadcastBitThreadDidStart,
149824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                         event);
149983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham            // If we were asked to attach, then do that here:
150083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham            // I'm going to use the command string rather than directly
150183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham            // calling the API's because then I don't have to recode the
150283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham            // event handling here.
150383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham            if (!m_option_data.m_process_name.empty()
150483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                || m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
150583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham            {
150683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                std::string command_str("process attach ");
150783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                if (m_option_data.m_process_pid != LLDB_INVALID_PROCESS_ID)
150883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                {
150983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    command_str.append("-p ");
151083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    char pid_buffer[32];
15115f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea                    ::snprintf (pid_buffer, sizeof(pid_buffer), "%" PRIu64, m_option_data.m_process_pid);
151283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    command_str.append(pid_buffer);
151383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                }
151483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                else
151583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                {
151683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    command_str.append("-n \"");
151783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    command_str.append(m_option_data.m_process_name);
151883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    command_str.push_back('\"');
151983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    if (m_option_data.m_wait_for)
152083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                        command_str.append(" -w");
152183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                }
152283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham
152383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                if (m_debugger.GetOutputFileHandle())
152483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                    ::fprintf (m_debugger.GetOutputFileHandle(),
152583dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                               "Attaching to process with:\n    %s\n",
152683dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                               command_str.c_str());
152783dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham
152883dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                // Force the attach to be synchronous:
152983dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                bool orig_async = m_debugger.GetAsync();
153083dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                m_debugger.SetAsync(true);
153183dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                m_debugger.HandleCommand(command_str.c_str());
153283dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham                m_debugger.SetAsync(orig_async);
153383dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham            }
153483dd2039d86b79e9cd5cf320bdb50c838fcb7b9cJim Ingham
153524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            ReadyForCommand ();
153624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1537f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton            while (!GetIsDone())
153824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
153924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                listener.WaitForEvent (UINT32_MAX, event);
154024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (event.IsValid())
154124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
154224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (event.GetBroadcaster().IsValid())
154324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    {
154424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        uint32_t event_type = event.GetType();
154524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        if (event.BroadcasterMatchesRef (*m_io_channel_ap))
154624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
154724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            if ((event_type & IOChannel::eBroadcastBitThreadShouldExit) ||
154824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                (event_type & IOChannel::eBroadcastBitThreadDidExit))
154924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            {
1550f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                                SetIsDone();
155124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                if (event_type & IOChannel::eBroadcastBitThreadDidExit)
155224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    iochannel_thread_exited = true;
155324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            }
155424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            else
1555f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                            {
1556f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                                if (HandleIOEvent (event))
1557f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                                    SetIsDone();
1558f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                            }
155924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
156028e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham                        else if (SBProcess::EventIsProcessEvent (event))
156124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
156224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            HandleProcessEvent (event);
156324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
156428e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham                        else if (SBBreakpoint::EventIsBreakpointEvent (event))
156528e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham                        {
156628e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham                            HandleBreakpointEvent (event);
156728e23861bedbeb5e46be7d2af4c33bf5132422c6Jim Ingham                        }
156894a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham                        else if (SBThread::EventIsThreadEvent (event))
156994a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham                        {
157094a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham                            HandleThreadEvent (event);
157194a5d0de4433dce556db59758f3d6124eb0e1a2aJim Ingham                        }
157224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
157324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        {
1574f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                            // TODO: deprecate the eBroadcastBitQuitCommandReceived event
1575f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                            // now that we have SBCommandInterpreter::SetCommandOverrideCallback()
1576f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                            // that can take over a command
157724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                            if (event_type & SBCommandInterpreter::eBroadcastBitQuitCommandReceived)
1578db9d6f47ab38e25c3efcbfa05780bf9a127fd259Greg Clayton                            {
1579f125250ba7bcaa2ea5ee95539a309e3fd2f8b5d7Greg Clayton                                SetIsDone();
1580db9d6f47ab38e25c3efcbfa05780bf9a127fd259Greg Clayton                            }
1581388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                            else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousErrorData)
1582388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                            {
1583388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                                const char *data = SBEvent::GetCStringFromEvent (event);
1584388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                                m_io_channel_ap->ErrWrite (data, strlen(data), ASYNC);
1585388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                            }
1586388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                            else if (event_type & SBCommandInterpreter::eBroadcastBitAsynchronousOutputData)
1587388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                            {
1588388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                                const char *data = SBEvent::GetCStringFromEvent (event);
1589388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                                m_io_channel_ap->OutWrite (data, strlen(data), ASYNC);
1590388ca8fef002edf49d66126efa8f4dff7176edc1Caroline Tice                            }
159124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        }
159224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    }
159324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
159424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
159524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15963cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain            master_out_comm.SetReadThreadBytesReceivedCallback(NULL, NULL);
15977cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton            master_out_comm.Disconnect();
15983cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain            master_out_comm.ReadThreadStop();
15993cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain
16003cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain            out_comm_2.SetReadThreadBytesReceivedCallback(NULL, NULL);
16017cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton            out_comm_2.Disconnect();
16023cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain            out_comm_2.ReadThreadStop();
16033cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain
16043cc1b9c78b84a3796ecb7ba1f57335e952a4b746Michael Sartain            editline_output_pty.CloseMasterFileDescriptor();
16057cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton            reset_stdin_termios();
16067cd8cd51421be28c7c615e141e87cf53bf2e21a0Greg Clayton            fclose (stdin);
160724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
160824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            CloseIOChannelFile ();
160924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
161024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (!iochannel_thread_exited)
161124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
1612bef1583b89e73de77c8b0897fcf42b5b1fcabe4cGreg Clayton                event.Clear();
161324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                listener.GetNextEventForBroadcasterWithType (*m_io_channel_ap,
161424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                             IOChannel::eBroadcastBitThreadDidExit,
161524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                                             event);
161624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (!event.IsValid())
161724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
161824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    // Send end EOF to the driver file descriptor
161924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    m_io_channel_ap->Stop();
162024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
162124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
162224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1623dbcf98c194742f911c963854084c66aa49a5e513Jim Ingham            SBDebugger::Destroy (m_debugger);
162424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
162524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
162624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
162724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
162824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
162924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
163024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDriver::ReadyForCommand ()
163124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
163224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_waiting_for_command == false)
163324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
163424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_waiting_for_command = true;
163524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        BroadcastEventByType (Driver::eBroadcastBitReadyForInput, true);
163624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
163724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
163824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16392eaca13a907b3c2ce41602b646d073851dc696ebJim Inghamvoid
16402eaca13a907b3c2ce41602b646d073851dc696ebJim InghamDriver::ResizeWindow (unsigned short col)
16412eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham{
16422eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham    GetDebugger().SetTerminalWidth (col);
16432eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham    if (m_io_channel_ap.get() != NULL)
16442eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham    {
16452eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham        m_io_channel_ap->ElResize();
16462eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham    }
16472eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham}
164824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1649b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Ticevoid
1650b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Ticesigwinch_handler (int signo)
1651b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice{
1652b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice    struct winsize window_size;
1653b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice    if (isatty (STDIN_FILENO)
1654b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice        && ::ioctl (STDIN_FILENO, TIOCGWINSZ, &window_size) == 0)
1655b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice    {
1656c76486cc024511ab8e96baea752e98f49c2b1da4Jim Ingham        if ((window_size.ws_col > 0) && g_driver != NULL)
1657b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice        {
16582eaca13a907b3c2ce41602b646d073851dc696ebJim Ingham            g_driver->ResizeWindow (window_size.ws_col);
1659b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice        }
1660b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice    }
1661b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice}
1662b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice
1663c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Ticevoid
1664c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Ticesigint_handler (int signo)
1665c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice{
1666c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice	static bool g_interrupt_sent = false;
1667c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice    if (g_driver)
1668c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice	{
1669c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice		if (!g_interrupt_sent)
1670c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice		{
1671c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice			g_interrupt_sent = true;
1672c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice        	g_driver->GetDebugger().DispatchInputInterrupt();
1673c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice			g_interrupt_sent = false;
1674c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice			return;
1675c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice		}
1676c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice	}
1677c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice
1678c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice	exit (signo);
1679c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice}
1680c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice
1681b1087a27f7babc43f332c9d49ac4554892133a41Jim Inghamvoid
1682b1087a27f7babc43f332c9d49ac4554892133a41Jim Inghamsigtstp_handler (int signo)
1683b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham{
1684b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    g_driver->GetDebugger().SaveInputTerminalState();
1685b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    signal (signo, SIG_DFL);
1686b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    kill (getpid(), signo);
1687b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    signal (signo, sigtstp_handler);
1688b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham}
1689b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham
1690b1087a27f7babc43f332c9d49ac4554892133a41Jim Inghamvoid
1691b1087a27f7babc43f332c9d49ac4554892133a41Jim Inghamsigcont_handler (int signo)
1692b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham{
1693b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    g_driver->GetDebugger().RestoreInputTerminalState();
1694b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    signal (signo, SIG_DFL);
1695b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    kill (getpid(), signo);
1696b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    signal (signo, sigcont_handler);
1697b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham}
1698b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham
169924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerint
1700b2b604f51ef03beb85d3c8d997ec25d85dea26faJim Inghammain (int argc, char const *argv[], const char *envp[])
170124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
170224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SBDebugger::Initialize();
170324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
170495e33b7b4b832ff5a8dfd0720fe6a100be894df6Greg Clayton    SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
170524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
170636f63a92bae332929e1a047b59ed6df651d8537fGreg Clayton    signal (SIGPIPE, SIG_IGN);
1707b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice    signal (SIGWINCH, sigwinch_handler);
1708c4f55fee15b66ea53da092ca50400ac5d8b0692dCaroline Tice    signal (SIGINT, sigint_handler);
1709b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    signal (SIGTSTP, sigtstp_handler);
1710b1087a27f7babc43f332c9d49ac4554892133a41Jim Ingham    signal (SIGCONT, sigcont_handler);
1711b8314fe67960cfcc5d9e9232be4c1914c9ef0ce3Caroline Tice
171263094e0bb161580564954dee512955c1c79d3476Greg Clayton    // Create a scope for driver so that the driver object will destroy itself
171363094e0bb161580564954dee512955c1c79d3476Greg Clayton    // before SBDebugger::Terminate() is called.
171424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
171563094e0bb161580564954dee512955c1c79d3476Greg Clayton        Driver driver;
171663094e0bb161580564954dee512955c1c79d3476Greg Clayton
171763094e0bb161580564954dee512955c1c79d3476Greg Clayton        bool exit = false;
171863094e0bb161580564954dee512955c1c79d3476Greg Clayton        SBError error (driver.ParseArgs (argc, argv, stdout, exit));
171963094e0bb161580564954dee512955c1c79d3476Greg Clayton        if (error.Fail())
172063094e0bb161580564954dee512955c1c79d3476Greg Clayton        {
172163094e0bb161580564954dee512955c1c79d3476Greg Clayton            const char *error_cstr = error.GetCString ();
172263094e0bb161580564954dee512955c1c79d3476Greg Clayton            if (error_cstr)
172363094e0bb161580564954dee512955c1c79d3476Greg Clayton                ::fprintf (stderr, "error: %s\n", error_cstr);
172463094e0bb161580564954dee512955c1c79d3476Greg Clayton        }
172563094e0bb161580564954dee512955c1c79d3476Greg Clayton        else if (!exit)
172663094e0bb161580564954dee512955c1c79d3476Greg Clayton        {
172763094e0bb161580564954dee512955c1c79d3476Greg Clayton            driver.MainLoop ();
172863094e0bb161580564954dee512955c1c79d3476Greg Clayton        }
172924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
173024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
173124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    SBDebugger::Terminate();
173224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 0;
173324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
1734