labath created this revision.
labath added reviewers: clayborg, zturner.
labath added a subscriber: lldb-commits.

This replaces the hand-rolled getopt option parser in lldb driver with the one 
in llvm. This
results in a lot less code, as the llvm's parser does much of the work (e.g., 
formatting of
--help output) for us, and side-steps the problem of using the internal getopt 
implementation in
liblldb on platforms which don't have a system getopt (windows, netbsd).

This change has tiny behaviour changes, which I try to enumerate here:
- boolean arguments can no longer be specified twice (e.g., --no-lldbinit 
--no-lldbinit will
  result in an error). I needed to tweak TestFormats to account for this. Can 
be changed, but I'm
  not sure if there is any need for it.
- I have removed the --script-language option, as it seemed to be ignored 
anyway.
- --help output has changed a bit and now reads (note one has to pass 
--help-hidden to see
  short option letters. again can be changed, but i think it makes the initial 
help more
  readable):

USAGE: lldb [options] <program-and-arguments>

OPTIONS:

General options:

  -arch=<string>                 - Tells the debugger to use the specified 
architecture when starting and running the program.  <string> must be one of 
the architectures for which the program was compiled.
  -attach-name=<string>          - Tells the debugger to attach to a process 
with the given name.
  -attach-pid=<uint>             - Tells the debugger to attach to a process 
with the given pid
  -batch                         - Tells the debugger to running the commands 
from -s, -S, -o & -O, and then quit.  However if any run command stopped due to 
a signal or crash, the debugger will return to the interactive prompt at the 
place of the crash.
  -core=<string>                 - Tells the debugger to use the file <string> 
as the core file.
  -debug                         - Tells the debugger to print out extra 
information for debugging itself.
  -editor                        - Tells the debugger to open source files 
using the host's "external editor" mechanism.
  -file=<string>                 - Tells the debugger to use the file <string> 
as the program to be debugged.
  -no-lldbinit                   - Do not automatically parse any '.lldbinit' 
files.
  -no-use-colors                 - Do not use colors.
  -one-line=<string>             - Tells the debugger to execute this one-line 
lldb command after any file provided on the command line has been loaded.
  -one-line-before-file=<string> - Tells the debugger to execute this one-line 
lldb command before any file provided on the command line has been loaded.
  -one-line-on-crash=<string>    - When in batch mode, tells the debugger to 
execute this one-line lldb command if the target crashes.
  -repl=<string>                 - Runs lldb in REPL mode with a stub process.
  -repl-langauge=<string>        - Chooses the language for the REPL.
  -source=<string>               - Tells the debugger to read in and execute 
the lldb commands in the given file, after any file provided on the command 
line has been loaded.
  -source-before-file=<string>   - Tells the debugger to read in and execute 
the lldb commands in the given file, before any file provided on the command 
line has been loaded.
  -source-on-crash=<string>      - When in batch mode, tells the debugger to 
source this file of lldb commands if the target crashes.
  -source-quietly                - Don't echo the commands when executing them.
  -wait-for                      - Tells the debugger to wait for a process 
with the given pid or name to launch before attaching.

Generic Options:

  -help                          - Display available options (-help-hidden for 
more)
  -help-list                     - Display list of available options 
(-help-list-hidden for more)
  -version                       - Display the version of this program

If you don't provide -file then the first argument will be the file to be
debugged which means that 'lldb -- <filename> [<ARG1> [<ARG2>]]' also
works.  But remember to end the options with "--" if any of your
arguments begin with "-".

Multiple "-source" and "-one-line" options can be provided.  They will be
processed from left to right in order, with the source files and commands
interleaved.

http://reviews.llvm.org/D17724

Files:
  packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py
  packages/Python/lldbsuite/test/driver/batch_mode/source.file
  packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
  tools/driver/Driver.cpp
  tools/driver/Driver.h
  tools/driver/Platform.h

Index: tools/driver/Platform.h
===================================================================
--- tools/driver/Platform.h
+++ tools/driver/Platform.h
@@ -12,9 +12,6 @@
 
 #if defined( _WIN32 )
 
-    // this will stop signal.h being included
-    #define _INC_SIGNAL
-    #include "lldb/Host/HostGetOpt.h"
     #include <io.h>
 #if defined( _MSC_VER )
     #include <eh.h>
Index: tools/driver/Driver.h
===================================================================
--- tools/driver/Driver.h
+++ tools/driver/Driver.h
@@ -18,6 +18,8 @@
 #include <string>
 #include <vector>
 
+#include "llvm/Support/CommandLine.h"
+
 #include "lldb/API/SBDefines.h"
 #include "lldb/API/SBBroadcaster.h"
 #include "lldb/API/SBDebugger.h"
@@ -47,24 +49,11 @@
     ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &do_exit);
 
     const char *
-    GetFilename() const;
-
-    const char *
-    GetCrashLogFilename() const;
-
-    const char *
     GetArchName() const;
 
-    lldb::ScriptLanguage
-    GetScriptLanguage() const;
-
     void
     WriteCommandsForSourcing (CommandPlacement placement, lldb::SBStream &strm);
     
-    bool
-    GetDebugMode() const;
-
-
     class OptionData
     {
     public:
@@ -75,13 +64,13 @@
         Clear();
 
         void
-        AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, lldb::SBError &error);
-    
+        AddInitialCommand(const std::string &command, CommandPlacement placement, bool is_file, lldb::SBError &error);
+
         //static OptionDefinition m_cmd_option_table[];
 
         struct InitialCmdEntry
         {
-            InitialCmdEntry (const char *in_contents, bool in_is_file, bool is_cwd_lldbinit_file_read, bool in_quiet = false) :
+            InitialCmdEntry (const std::string &in_contents, bool in_is_file, bool is_cwd_lldbinit_file_read, bool in_quiet = false) :
                 contents (in_contents),
                 is_file  (in_is_file),
                 is_cwd_lldbinit_file_read (is_cwd_lldbinit_file_read),
@@ -94,28 +83,10 @@
             bool        source_quietly;
         };
 
-        std::vector<std::string> m_args;
-        lldb::ScriptLanguage m_script_lang;
-        std::string m_core_file;
-        std::string m_crash_log;
         std::vector<InitialCmdEntry> m_initial_commands;
         std::vector<InitialCmdEntry> m_after_file_commands;
         std::vector<InitialCmdEntry> m_after_crash_commands;
-        bool m_debug_mode;
-        bool m_source_quietly;
-        bool m_print_version;
-        bool m_print_python_path;
-        bool m_print_help;
-        bool m_wait_for;
-        bool m_repl;
         lldb::LanguageType m_repl_lang;
-        std::string m_repl_options;
-        std::string m_process_name;
-        lldb::pid_t m_process_pid;
-        bool m_use_external_editor;  // FIXME: When we have set/show variables we can remove this from here.
-        bool m_batch;
-        typedef std::set<char> OptionSet;
-        OptionSet m_seen_options;
     };
 
 
@@ -143,6 +114,9 @@
 
     void
     ReadyForCommand ();
+
+    lldb::SBError
+    ParsePositionalArgPair(const llvm::cl::list<std::string> &source, const llvm::cl::list<std::string> &one_line, CommandPlacement placement);
 };
 
 #endif // lldb_Driver_h_
Index: tools/driver/Driver.cpp
===================================================================
--- tools/driver/Driver.cpp
+++ tools/driver/Driver.cpp
@@ -47,6 +47,7 @@
 #include "llvm/Support/DataTypes.h"
 #endif
 
+using namespace llvm;
 using namespace lldb;
 
 static void reset_stdin_termios ();
@@ -67,6 +68,12 @@
     }
 }
 
+static void print_version()
+{
+    assert(g_driver);
+    puts(g_driver->GetDebugger().GetVersionString());
+}
+
 typedef struct
 {
     uint32_t usage_mask;                     // Used to mark options that can be used together.  If (1 << n & usage_mask) != 0
@@ -84,64 +91,107 @@
 #define LLDB_3_TO_5 LLDB_OPT_SET_3|LLDB_OPT_SET_4|LLDB_OPT_SET_5
 #define LLDB_4_TO_5 LLDB_OPT_SET_4|LLDB_OPT_SET_5
 
-static OptionDefinition g_options[] =
+namespace options
 {
-    { LLDB_OPT_SET_1,    true , "help"           , 'h', no_argument      , 0,  eArgTypeNone,
-        "Prints out the usage information for the LLDB debugger." },
-    { LLDB_OPT_SET_2,    true , "version"        , 'v', no_argument      , 0,  eArgTypeNone,
-        "Prints out the current version number of the LLDB debugger." },
-    { LLDB_OPT_SET_3,    true , "arch"           , 'a', required_argument, 0,  eArgTypeArchitecture,
-        "Tells the debugger to use the specified architecture when starting and running the program.  <architecture> must "
-        "be one of the architectures for which the program was compiled." },
-    { LLDB_OPT_SET_3,    true , "file"           , 'f', required_argument, 0,  eArgTypeFilename,
-        "Tells the debugger to use the file <filename> as the program to be debugged." },
-    { LLDB_OPT_SET_3,    false, "core"           , 'c', required_argument, 0,  eArgTypeFilename,
-        "Tells the debugger to use the fullpath to <path> as the core file." },
-    { LLDB_OPT_SET_5,    true , "attach-pid"     , 'p', required_argument, 0,  eArgTypePid,
-        "Tells the debugger to attach to a process with the given pid." },
-    { LLDB_OPT_SET_4,    true , "attach-name"    , 'n', required_argument, 0,  eArgTypeProcessName,
-        "Tells the debugger to attach to a process with the given name." },
-    { LLDB_OPT_SET_4,    true , "wait-for"       , 'w', no_argument      , 0,  eArgTypeNone,
-        "Tells the debugger to wait for a process with the given pid or name to launch before attaching." },
-    { LLDB_3_TO_5,       false, "source"         , 's', required_argument, 0,  eArgTypeFilename,
-        "Tells the debugger to read in and execute the lldb commands in the given file, after any file provided on the command line has been loaded." },
-    { LLDB_3_TO_5,       false, "one-line"         , 'o', required_argument, 0,  eArgTypeNone,
-        "Tells the debugger to execute this one-line lldb command after any file provided on the command line has been loaded." },
-    { LLDB_3_TO_5,       false, "source-before-file"         , 'S', required_argument, 0,  eArgTypeFilename,
-        "Tells the debugger to read in and execute the lldb commands in the given file, before any file provided on the command line has been loaded." },
-    { LLDB_3_TO_5,       false, "one-line-before-file"         , 'O', required_argument, 0,  eArgTypeNone,
-        "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
-    { LLDB_3_TO_5,       false, "one-line-on-crash"         , 'k', required_argument, 0,  eArgTypeNone,
-        "When in batch mode, tells the debugger to execute this one-line lldb command if the target crashes." },
-    { LLDB_3_TO_5,       false, "source-on-crash"         , 'K', required_argument, 0,  eArgTypeFilename,
-        "When in batch mode, tells the debugger to source this file of lldb commands if the target crashes." },
-    { LLDB_3_TO_5,       false, "source-quietly"          , 'Q', no_argument      , 0,  eArgTypeNone,
-        "Tells the debugger to execute this one-line lldb command before any file provided on the command line has been loaded." },
-    { LLDB_3_TO_5,       false, "batch"          , 'b', no_argument      , 0,  eArgTypeNone,
-        "Tells the debugger to running the commands from -s, -S, -o & -O, and then quit.  However if any run command stopped due to a signal or crash, "
-        "the debugger will return to the interactive prompt at the place of the crash." },
-    { LLDB_3_TO_5,       false, "editor"         , 'e', no_argument      , 0,  eArgTypeNone,
-        "Tells the debugger to open source files using the host's \"external editor\" mechanism." },
-    { LLDB_3_TO_5,       false, "no-lldbinit"    , 'x', no_argument      , 0,  eArgTypeNone,
-        "Do not automatically parse any '.lldbinit' files." },
-    { LLDB_3_TO_5,       false, "no-use-colors"  , 'X', no_argument      , 0,  eArgTypeNone,
-        "Do not use colors." },
-    { LLDB_OPT_SET_6,    true , "python-path"    , 'P', no_argument      , 0,  eArgTypeNone,
-        "Prints out the path to the lldb.py file for this version of lldb." },
-    { LLDB_3_TO_5,       false, "script-language", 'l', required_argument, 0,  eArgTypeScriptLang,
-        "Tells the debugger to use the specified scripting language for user-defined scripts, rather than the default.  "
-        "Valid scripting languages that can be specified include Python, Perl, Ruby and Tcl.  Currently only the Python "
-        "extensions have been implemented." },
-    { LLDB_3_TO_5,       false, "debug"          , 'd', no_argument      , 0,  eArgTypeNone,
-        "Tells the debugger to print out extra information for debugging itself." },
-    { LLDB_OPT_SET_7,  true , "repl"               , 'r', optional_argument, 0,  eArgTypeNone,
-        "Runs lldb in REPL mode with a stub process." },
-    { LLDB_OPT_SET_7,  true , "repl-language"      , 'R', required_argument, 0,  eArgTypeNone,
-        "Chooses the language for the REPL." },
-    { 0,                 false, NULL             , 0  , 0                , 0,  eArgTypeNone,         NULL }
-};
-
-static const uint32_t last_option_set_with_args = 2;
+// These will be created at runtime in: Driver::ParseArgs
+std::unique_ptr<cl::alias> v;
+std::unique_ptr<cl::alias> h;
+std::unique_ptr<cl::opt<bool>> debug;
+std::unique_ptr<cl::alias> d;
+
+
+cl::opt<std::string> arch("arch", cl::desc("Tells the debugger to use the specified architecture when starting and "
+                                           "running the program.  <string> must be one of the architectures "
+                                           "for which the program was compiled."));
+cl::alias a("a", cl::desc("Alias for -arch."), cl::aliasopt(arch));
+
+cl::opt<std::string> file("file", cl::desc("Tells the debugger to use the file <string> as the program to be debugged."));
+cl::alias f("f", cl::desc("Alias for -file."), cl::aliasopt(file));
+
+cl::opt<std::string> core("core", cl::desc("Tells the debugger to use the file <string> as the core file."));
+cl::alias c("c", cl::desc("Alias for -core."), cl::aliasopt(core));
+
+cl::opt<unsigned long long> attach_pid("attach-pid",
+                                       cl::desc("Tells the debugger to attach to a process with the given pid"),
+                                       cl::init(LLDB_INVALID_PROCESS_ID));
+cl::alias p("p", cl::desc("Alias for -attach-pid."), cl::aliasopt(attach_pid));
+
+cl::opt<std::string> attach_name("attach-name",
+                                 cl::desc("Tells the debugger to attach to a process with the given name."));
+cl::alias n("n", cl::desc("Alias for -attach-name."), cl::aliasopt(attach_name));
+
+cl::opt<bool> wait_for("wait-for", cl::desc("Tells the debugger to wait for a process with the given pid or name to launch before attaching."), cl::ValueDisallowed);
+cl::alias w("w", cl::desc("Alias for -wait-for."), cl::aliasopt(wait_for));
+
+cl::list<std::string> source("source",
+                             cl::desc("Tells the debugger to read in and execute the lldb commands in the given file, "
+                                      "after any file provided on the command line has been loaded."));
+cl::alias s("s", cl::desc("Alias for -source"), cl::aliasopt(source));
+
+cl::list<std::string> one_line("one-line", cl::desc("Tells the debugger to execute this one-line lldb command after "
+                                                    "any file provided on the command line has been loaded."));
+cl::alias o("o", cl::desc("Alias for -one-line."), cl::aliasopt(one_line));
+
+cl::list<std::string>
+    source_before_file("source-before-file",
+                       cl::desc("Tells the debugger to read in and execute the lldb commands in the given file, before "
+                                "any file provided on the command line has been loaded."));
+cl::alias S("S", cl::desc("Alias for -source-before-file."), cl::aliasopt(source_before_file));
+
+cl::list<std::string> one_line_before_file("one-line-before-file",
+                                           cl::desc("Tells the debugger to execute this one-line lldb command before "
+                                                    "any file provided on the command line has been loaded."));
+cl::alias O("O", cl::desc("Alias for -one-line-before-file."), cl::aliasopt(one_line_before_file));
+
+cl::list<std::string> one_line_on_crash(
+    "one-line-on-crash",
+    cl::desc("When in batch mode, tells the debugger to execute this one-line lldb command if the target crashes."));
+cl::alias k("k", cl::desc("Alias for -one-line-on-crash."), cl::aliasopt(one_line_on_crash));
+
+cl::list<std::string> source_on_crash(
+    "source-on-crash",
+    cl::desc("When in batch mode, tells the debugger to source this file of lldb commands if the target crashes."));
+cl::alias K("K", cl::desc("Alias for -source-on-crash."), cl::aliasopt(source_on_crash));
+
+cl::opt<bool> source_quietly("source-quietly", cl::desc("Don't echo the commands when executing them."));
+cl::alias Q("Q", cl::desc("Alias for -source-quietly."), cl::aliasopt(source_quietly));
+
+cl::opt<bool> batch("batch", cl::desc("Tells the debugger to running the commands from -s, -S, -o & -O, and then quit. "
+                                      " However if any run command stopped due to a signal or crash, the debugger will "
+                                      "return to the interactive prompt at the place of the crash."));
+cl::alias b("b", cl::desc("Alias for -batch."), cl::aliasopt(batch));
+
+cl::opt<bool> editor("editor", cl::desc(
+        "Tells the debugger to open source files using the host's \"external editor\" mechanism."));
+cl::alias e("e", cl::desc("Alias for -editor."), cl::aliasopt(editor));
+
+cl::opt<bool> no_lldbinit("no-lldbinit", cl::desc("Do not automatically parse any '.lldbinit' files."));
+cl::alias x("x", cl::desc("Alias for -no-lldbinit."), cl::aliasopt(no_lldbinit));
+
+cl::opt<bool> no_use_colors("no-use-colors", cl::desc("Do not use colors."));
+cl::alias X("X", cl::desc("Alias for -no-use-colors."), cl::aliasopt(no_use_colors));
+
+cl::opt<bool> python_path("python-path", cl::desc(
+        "Prints out the path to the lldb.py file for this version of lldb."), cl::Hidden);
+cl::alias P("P", cl::desc("Alias for -python-path."), cl::aliasopt(python_path));
+
+cl::opt<std::string> repl("repl", cl::desc("Runs lldb in REPL mode with a stub process."), cl::ValueOptional);
+cl::alias r("r", cl::desc("Alias for -repl."), cl::aliasopt(repl));
+
+cl::opt<std::string> repl_language("repl-langauge", cl::desc("Chooses the language for the REPL."));
+cl::alias R("R", cl::desc("Alias for -repl-language."), cl::aliasopt(repl_language));
+
+cl::list<std::string> args(cl::Positional, cl::desc("<program-and-arguments>"), cl::ZeroOrMore);
+
+cl::extrahelp help("\nIf you don't provide -file then the first argument will be the file to be"
+                   "\ndebugged which means that 'lldb -- <filename> [<ARG1> [<ARG2>]]' also"
+                   "\nworks.  But remember to end the options with \"--\" if any of your"
+                   "\narguments begin with \"-\"."
+                   "\n"
+                   "\nMultiple \"-source\" and \"-one-line\" options can be provided.  They will be"
+                   "\nprocessed from left to right in order, with the source files and commands"
+                   "\ninterleaved.\n\n");
+}
 
 Driver::Driver () :
     SBBroadcaster ("Driver"),
@@ -215,219 +265,11 @@
     }
 }
 
-void
-ShowUsage (FILE *out, OptionDefinition *option_table, Driver::OptionData data)
-{
-    uint32_t screen_width = 80;
-    uint32_t indent_level = 0;
-    const char *name = "lldb";
-    
-    fprintf (out, "\nUsage:\n\n");
-
-    indent_level += 2;
-
-
-    // First, show each usage level set of options, e.g. <cmd> [options-for-level-0]
-    //                                                   <cmd> [options-for-level-1]
-    //                                                   etc.
-
-    uint32_t num_options;
-    uint32_t num_option_sets = 0;
-    
-    for (num_options = 0; option_table[num_options].long_option != NULL; ++num_options)
-    {
-        uint32_t this_usage_mask = option_table[num_options].usage_mask;
-        if (this_usage_mask == LLDB_OPT_SET_ALL)
-        {
-            if (num_option_sets == 0)
-                num_option_sets = 1;
-        }
-        else
-        {
-            for (uint32_t j = 0; j < LLDB_MAX_NUM_OPTION_SETS; j++)
-            {
-                if (this_usage_mask & 1 << j)
-                {
-                    if (num_option_sets <= j)
-                        num_option_sets = j + 1;
-                }
-            }
-        }
-    }
-
-    for (uint32_t opt_set = 0; opt_set < num_option_sets; opt_set++)
-    {
-        uint32_t opt_set_mask;
-        
-        opt_set_mask = 1 << opt_set;
-        
-        if (opt_set > 0)
-            fprintf (out, "\n");
-        fprintf (out, "%*s%s", indent_level, "", name);
-        bool is_help_line = false;
-        
-        for (uint32_t i = 0; i < num_options; ++i)
-        {
-            if (option_table[i].usage_mask & opt_set_mask)
-            {
-                CommandArgumentType arg_type = option_table[i].argument_type;
-                const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
-                // This is a bit of a hack, but there's no way to say certain options don't have arguments yet...
-                // so we do it by hand here.
-                if (option_table[i].short_option == 'h')
-                    is_help_line = true;
-                    
-                if (option_table[i].required)
-                {
-                    if (option_table[i].option_has_arg == required_argument)
-                        fprintf (out, " -%c <%s>", option_table[i].short_option, arg_name);
-                    else if (option_table[i].option_has_arg == optional_argument)
-                        fprintf (out, " -%c [<%s>]", option_table[i].short_option, arg_name);
-                    else
-                        fprintf (out, " -%c", option_table[i].short_option);
-                }
-                else
-                {
-                    if (option_table[i].option_has_arg == required_argument)
-                        fprintf (out, " [-%c <%s>]", option_table[i].short_option, arg_name);
-                    else if (option_table[i].option_has_arg == optional_argument)
-                        fprintf (out, " [-%c [<%s>]]", option_table[i].short_option, arg_name);
-                    else
-                        fprintf (out, " [-%c]", option_table[i].short_option);
-                }
-            }
-        }
-        if (!is_help_line && (opt_set <= last_option_set_with_args))
-            fprintf (out, " [[--] <PROGRAM-ARG-1> [<PROGRAM_ARG-2> ...]]");
-    }
-
-    fprintf (out, "\n\n");
-
-    // Now print out all the detailed information about the various options:  long form, short form and help text:
-    //   -- long_name <argument>
-    //   - short <argument>
-    //   help text
-
-    // This variable is used to keep track of which options' info we've printed out, because some options can be in
-    // more than one usage level, but we only want to print the long form of its information once.
-
-    Driver::OptionData::OptionSet options_seen;
-    Driver::OptionData::OptionSet::iterator pos;
-
-    indent_level += 5;
-
-    for (uint32_t i = 0; i < num_options; ++i)
-    {
-        // Only print this option if we haven't already seen it.
-        pos = options_seen.find (option_table[i].short_option);
-        if (pos == options_seen.end())
-        {
-            CommandArgumentType arg_type = option_table[i].argument_type;
-            const char *arg_name = SBCommandInterpreter::GetArgumentTypeAsCString (arg_type);
-
-            options_seen.insert (option_table[i].short_option);
-            fprintf (out, "%*s-%c ", indent_level, "", option_table[i].short_option);
-            if (arg_type != eArgTypeNone)
-                fprintf (out, "<%s>", arg_name);
-            fprintf (out, "\n");
-            fprintf (out, "%*s--%s ", indent_level, "", option_table[i].long_option);
-            if (arg_type != eArgTypeNone)
-                fprintf (out, "<%s>", arg_name);
-            fprintf (out, "\n");
-            indent_level += 5;
-            OutputFormattedUsageText (out, indent_level, option_table[i].usage_text, screen_width);
-            indent_level -= 5;
-            fprintf (out, "\n");
-        }
-    }
-
-    indent_level -= 5;
-    
-    fprintf (out, "\n%*sNotes:\n",
-             indent_level, "");
-    indent_level += 5;
-    
-    fprintf (out, "\n%*sMultiple \"-s\" and \"-o\" options can be provided.  They will be processed"
-                  "\n%*sfrom left to right in order, with the source files and commands"
-                  "\n%*sinterleaved.  The same is true of the \"-S\" and \"-O\" options.  The before"
-                  "\n%*sfile and after file sets can intermixed freely, the command parser will"
-                  "\n%*ssort them out.  The order of the file specifiers (\"-c\", \"-f\", etc.) is"
-                  "\n%*snot significant in this regard.\n\n",
-             indent_level, "", 
-             indent_level, "", 
-             indent_level, "",
-             indent_level, "",
-             indent_level, "",
-             indent_level, "");
-    
-    fprintf (out, "\n%*sIf you don't provide -f then the first argument will be the file to be"
-                  "\n%*sdebugged which means that '%s -- <filename> [<ARG1> [<ARG2>]]' also"
-                  "\n%*sworks.  But remember to end the options with \"--\" if any of your"
-                  "\n%*sarguments have a \"-\" in them.\n\n",
-             indent_level, "", 
-             indent_level, "",
-             name, 
-             indent_level, "",
-             indent_level, "");
-}
-
-void
-BuildGetOptTable (OptionDefinition *expanded_option_table, std::vector<struct option> &getopt_table, 
-                  uint32_t num_options)
-{
-    if (num_options == 0)
-        return;
-
-    uint32_t i;
-    uint32_t j;
-    std::bitset<256> option_seen;
-
-    getopt_table.resize (num_options + 1);
-
-    for (i = 0, j = 0; i < num_options; ++i)
-    {
-        char short_opt = expanded_option_table[i].short_option;
-        
-        if (option_seen.test(short_opt) == false)
-        {
-            getopt_table[j].name    = expanded_option_table[i].long_option;
-            getopt_table[j].has_arg = expanded_option_table[i].option_has_arg;
-            getopt_table[j].flag    = NULL;
-            getopt_table[j].val     = expanded_option_table[i].short_option;
-            option_seen.set(short_opt);
-            ++j;
-        }
-    }
-
-    getopt_table[j].name    = NULL;
-    getopt_table[j].has_arg = 0;
-    getopt_table[j].flag    = NULL;
-    getopt_table[j].val     = 0;
-
-}
-
 Driver::OptionData::OptionData () :
-    m_args(),
-    m_script_lang (lldb::eScriptLanguageDefault),
-    m_core_file (),
-    m_crash_log (),
     m_initial_commands (),
     m_after_file_commands (),
     m_after_crash_commands(),
-    m_debug_mode (false),
-    m_source_quietly(false),
-    m_print_version (false),
-    m_print_python_path (false),
-    m_print_help (false),
-    m_wait_for(false),
-    m_repl (false),
-    m_repl_lang (eLanguageTypeUnknown),
-    m_repl_options (),
-    m_process_name(),
-    m_process_pid(LLDB_INVALID_PROCESS_ID),
-    m_use_external_editor(false),
-    m_batch(false),
-    m_seen_options()
+    m_repl_lang (eLanguageTypeUnknown)
 {
 }
 
@@ -438,8 +280,6 @@
 void
 Driver::OptionData::Clear ()
 {
-    m_args.clear ();
-    m_script_lang = lldb::eScriptLanguageDefault;
     m_initial_commands.clear ();
     m_after_file_commands.clear ();
 
@@ -463,22 +303,11 @@
         m_after_file_commands.push_back (entry);
     }
     
-    m_debug_mode = false;
-    m_source_quietly = false;
-    m_print_help = false;
-    m_print_version = false;
-    m_print_python_path = false;
-    m_use_external_editor = false;
-    m_wait_for = false;
-    m_process_name.erase();
-    m_batch = false;
     m_after_crash_commands.clear();
-
-    m_process_pid = LLDB_INVALID_PROCESS_ID;
 }
 
 void
-Driver::OptionData::AddInitialCommand (const char *command, CommandPlacement placement, bool is_file, SBError &error)
+Driver::OptionData::AddInitialCommand (const std::string &command, CommandPlacement placement, bool is_file, SBError &error)
 {
     std::vector<InitialCmdEntry> *command_set;
     switch (placement)
@@ -496,7 +325,7 @@
 
     if (is_file)
     {
-        SBFileSpec file(command);
+        SBFileSpec file(command.c_str());
         if (file.Exists())
             command_set->push_back (InitialCmdEntry(command, is_file, false));
         else if (file.ResolveExecutableLocation())
@@ -518,28 +347,6 @@
     m_option_data.Clear ();
 }
 
-const char *
-Driver::GetFilename() const
-{
-    if (m_option_data.m_args.empty())
-        return NULL;
-    return m_option_data.m_args.front().c_str();
-}
-
-const char *
-Driver::GetCrashLogFilename() const
-{
-    if (m_option_data.m_crash_log.empty())
-        return NULL;
-    return m_option_data.m_crash_log.c_str();
-}
-
-lldb::ScriptLanguage
-Driver::GetScriptLanguage() const
-{
-    return m_option_data.m_script_lang;
-}
-
 void
 Driver::WriteCommandsForSourcing (CommandPlacement placement, SBStream &strm)
 {
@@ -586,20 +393,36 @@
                     return;
                 }
             }
-            bool source_quietly = m_option_data.m_source_quietly || command_entry.source_quietly;
+            bool source_quietly = options::source_quietly || command_entry.source_quietly;
             strm.Printf("command source -s %i '%s'\n", source_quietly, command);
         }
         else
             strm.Printf("%s\n", command);
     }
 }
 
-bool
-Driver::GetDebugMode() const
+// This loop makes sure we process -s and -o options in the order they were specified.
+lldb::SBError
+Driver::ParsePositionalArgPair(const llvm::cl::list<std::string> &source, const llvm::cl::list<std::string> &one_line, CommandPlacement placement)
 {
-    return m_option_data.m_debug_mode;
-}
+    unsigned source_ind = 0, one_line_ind = 0;
+    while (source_ind < source.size() || one_line_ind < one_line.size())
+    {
+        unsigned source_pos =
+            source_ind < source.size() ? source.getPosition(source_ind) : std::numeric_limits<unsigned>::max();
+        unsigned one_line_pos =
+            one_line_ind < one_line.size() ? one_line.getPosition(one_line_ind) : std::numeric_limits<unsigned>::max();
 
+        SBError error;
+        if (source_pos < one_line_pos)
+            m_option_data.AddInitialCommand(source[source_ind++], placement, true, error);
+        else
+            m_option_data.AddInitialCommand(one_line[one_line_ind++], placement, false, error);
+        if (error.Fail())
+            return error;
+    }
+    return SBError();
+}
 
 // Check the arguments that were passed to this program to make sure they are valid and to get their
 // argument values (if any).  Return a boolean value indicating whether or not to start up the full
@@ -611,271 +434,96 @@
 {
     ResetOptionValues ();
 
-    SBCommandReturnObject result;
+    cl::SetVersionPrinter(print_version);
+    StringMap<cl::Option *> &option_map = cl::getRegisteredOptions();
 
-    SBError error;
-    std::string option_string;
-    struct option *long_options = NULL;
-    std::vector<struct option> long_options_vector;
-    uint32_t num_options;
+    // LLVM already adds a -debug option in Debug builds. We need to remove that one before
+    // inserting our option.
+    auto debug_it = option_map.find("debug");
+    if (debug_it != option_map.end())
+        option_map.erase(debug_it);
 
-    for (num_options = 0; g_options[num_options].long_option != NULL; ++num_options)
-        /* Do Nothing. */;
+    options::debug.reset(new cl::opt<bool>(
+        "debug", cl::desc("Tells the debugger to print out extra information for debugging itself.")));
+    options::d.reset(new cl::alias("d", cl::desc("Alias for -debug."), cl::aliasopt(*options::debug)));
 
-    if (num_options == 0)
-    {
-        if (argc > 1)
-            error.SetErrorStringWithFormat ("invalid number of options");
-        return error;
-    }
+    // Add short-hand aliases for -help and -version.
+    cl::Option& version = *option_map.lookup("version");
+    options::v.reset(
+        new cl::alias("v", cl::desc("Alias for -version."), cl::aliasopt(version), cl::cat(*version.Category)));
 
-    BuildGetOptTable (g_options, long_options_vector, num_options);
+    cl::Option& help = *option_map.lookup("help");
+    options::h.reset(
+        new cl::alias("h", cl::desc("Alias for -help."), cl::aliasopt(help), cl::cat(*help.Category)));
 
-    if (long_options_vector.empty())
-        long_options = NULL;
-    else
-        long_options = &long_options_vector.front();
+    cl::ParseCommandLineOptions(argc, argv);
 
-    if (long_options == NULL)
-    {
-        error.SetErrorStringWithFormat ("invalid long options");
-        return error;
-    }
+    SBCommandReturnObject result;
+
+    SBError error;
 
-    // Build the option_string argument for call to getopt_long_only.
+    // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
+    // know at that point whether we should read in init files.  So we don't read them in in the
+    // Driver constructor, then set the flags back to "read them in" here, if the command-line
+    // flag was *not* provided. Finally we have to read them in by hand later in the main loop.
+    m_debugger.SkipLLDBInitFiles(options::no_lldbinit);
+    m_debugger.SkipAppInitFiles(options::no_lldbinit);
 
-    for (int i = 0; long_options[i].name != NULL; ++i)
+    if (options::arch.getNumOccurrences() > 0)
     {
-        if (long_options[i].flag == NULL)
+        if (!m_debugger.SetDefaultArchitecture(options::arch.c_str()))
         {
-            option_string.push_back ((char) long_options[i].val);
-            switch (long_options[i].has_arg)
-            {
-                default:
-                case no_argument:
-                    break;
-                case required_argument:
-                    option_string.push_back (':');
-                    break;
-                case optional_argument:
-                    option_string.append ("::");
-                    break;
-            }
+            error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'",
+                                           options::arch.c_str());
+            return error;
         }
     }
 
-    // This is kind of a pain, but since we make the debugger in the Driver's constructor, we can't
-    // know at that point whether we should read in init files yet.  So we don't read them in in the
-    // Driver constructor, then set the flags back to "read them in" here, and then if we see the
-    // "-n" flag, we'll turn it off again.  Finally we have to read them in by hand later in the
-    // main loop.
-    
-    m_debugger.SkipLLDBInitFiles (false);
-    m_debugger.SkipAppInitFiles (false);
-
-    // Prepare for & make calls to getopt_long_only.
-#if __GLIBC__
-    optind = 0;
-#else
-    optreset = 1;
-    optind = 1;
-#endif
-    int val;
-    while (1)
+    if (options::file.getNumOccurrences() > 0)
     {
-        int long_options_index = -1;
-        val = ::getopt_long_only (argc, const_cast<char **>(argv), option_string.c_str(), long_options, &long_options_index);
-
-        if (val == -1)
-            break;
-        else if (val == '?')
+        SBFileSpec file(options::file.c_str());
+        if (! file.Exists() && !file.ResolveExecutableLocation())
         {
-            m_option_data.m_print_help = true;
-            error.SetErrorStringWithFormat ("unknown or ambiguous option");
-            break;
+            error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'",
+                                           options::file.c_str());
+            return error;
         }
-        else if (val == 0)
-            continue;
-        else
+        char path[PATH_MAX];
+        file.GetPath(path, sizeof(path));
+        // Store program path as the first argument
+        options::args.insert(options::args.begin(), path);
+    }
+
+    if (options::core.getNumOccurrences() > 0)
+    {
+        SBFileSpec file(options::core.c_str());
+        if (! file.Exists())
         {
-            m_option_data.m_seen_options.insert ((char) val);
-            if (long_options_index == -1)
-            {
-                for (int i = 0;
-                     long_options[i].name || long_options[i].has_arg || long_options[i].flag || long_options[i].val;
-                     ++i)
-                {
-                    if (long_options[i].val == val)
-                    {
-                        long_options_index = i;
-                        break;
-                    }
-                }
-            }
+            error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'",
+                                           options::core.c_str());
+            return error;
+        }
+    }
 
-            if (long_options_index >= 0)
-            {
-                const int short_option = g_options[long_options_index].short_option;
+    ParsePositionalArgPair(options::source, options::one_line, eCommandPlacementAfterFile);
+    ParsePositionalArgPair(options::source_before_file, options::one_line_before_file, eCommandPlacementBeforeFile);
+    ParsePositionalArgPair(options::source_on_crash, options::one_line_on_crash, eCommandPlacementAfterCrash);
 
-                switch (short_option)
-                {
-                    case 'h':
-                        m_option_data.m_print_help = true;
-                        break;
-
-                    case 'v':
-                        m_option_data.m_print_version = true;
-                        break;
-
-                    case 'P':
-                        m_option_data.m_print_python_path = true;
-                        break;
-
-                    case 'b':
-                        m_option_data.m_batch = true;
-                        break;
-
-                    case 'c':
-                        {
-                            SBFileSpec file(optarg);
-                            if (file.Exists())
-                            {
-                                m_option_data.m_core_file = optarg;
-                            }
-                            else
-                                error.SetErrorStringWithFormat("file specified in --core (-c) option doesn't exist: '%s'", optarg);
-                        }
-                        break;
-                    
-                    case 'e':
-                        m_option_data.m_use_external_editor = true;
-                        break;
-
-                    case 'x':
-                        m_debugger.SkipLLDBInitFiles (true);
-                        m_debugger.SkipAppInitFiles (true);
-                        break;
-
-                    case 'X':
-                        m_debugger.SetUseColor (false);
-                        break;
-
-                    case 'f':
-                        {
-                            SBFileSpec file(optarg);
-                            if (file.Exists())
-                            {
-                                m_option_data.m_args.push_back (optarg);
-                            }
-                            else if (file.ResolveExecutableLocation())
-                            {
-                                char path[PATH_MAX];
-                                file.GetPath (path, sizeof(path));
-                                m_option_data.m_args.push_back (path);
-                            }
-                            else
-                                error.SetErrorStringWithFormat("file specified in --file (-f) option doesn't exist: '%s'", optarg);
-                        }
-                        break;
-
-                    case 'a':
-                        if (!m_debugger.SetDefaultArchitecture (optarg))
-                            error.SetErrorStringWithFormat("invalid architecture in the -a or --arch option: '%s'", optarg);
-                        break;
-
-                    case 'l':
-                        m_option_data.m_script_lang = m_debugger.GetScriptingLanguage (optarg);
-                        break;
-
-                    case 'd':
-                        m_option_data.m_debug_mode = true;
-                        break;
-
-                    case 'Q':
-                        m_option_data.m_source_quietly = true;
-                        break;
-
-                    case 'K':
-                        m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, true, error);
-                        break;
-                    case 'k':
-                        m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterCrash, false, error);
-                        break;
-
-                    case 'n':
-                        m_option_data.m_process_name = optarg;
-                        break;
-                    
-                    case 'w':
-                        m_option_data.m_wait_for = true;
-                        break;
-                        
-                    case 'p':
-                        {
-                            char *remainder;
-                            m_option_data.m_process_pid = strtol (optarg, &remainder, 0);
-                            if (remainder == optarg || *remainder != '\0')
-                                error.SetErrorStringWithFormat ("Could not convert process PID: \"%s\" into a pid.",
-                                                                optarg);
-                        }
-                        break;
-                        
-                    case 'r':
-                        m_option_data.m_repl = true;
-                        if (optarg && optarg[0])
-                            m_option_data.m_repl_options = optarg;
-                        else
-                            m_option_data.m_repl_options.clear();
-                        break;
-                    
-                    case 'R':
-                        m_option_data.m_repl_lang = SBLanguageRuntime::GetLanguageTypeFromString (optarg);
-                        if (m_option_data.m_repl_lang == eLanguageTypeUnknown)
-                        {
-                            error.SetErrorStringWithFormat ("Unrecognized language name: \"%s\"", optarg);
-                        }
-                        break;
-
-                    case 's':
-                        m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, true, error);
-                        break;
-                    case 'o':
-                        m_option_data.AddInitialCommand(optarg, eCommandPlacementAfterFile, false, error);
-                        break;
-                    case 'S':
-                        m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, true, error);
-                        break;
-                    case 'O':
-                        m_option_data.AddInitialCommand(optarg, eCommandPlacementBeforeFile, false, error);
-                        break;
-                    default:
-                        m_option_data.m_print_help = true;
-                        error.SetErrorStringWithFormat ("unrecognized option %c", short_option);
-                        break;
-                }
-            }
-            else
-            {
-                error.SetErrorStringWithFormat ("invalid option with value %i", val);
-            }
-            if (error.Fail())
-            {
-                return error;
-            }
+    if(options::no_use_colors)
+        m_debugger.SetUseColor (false);
+
+    if (options::repl_language.getNumOccurrences() > 0)
+    {
+        m_option_data.m_repl_lang = SBLanguageRuntime::GetLanguageTypeFromString(optarg);
+        if (m_option_data.m_repl_lang == eLanguageTypeUnknown)
+        {
+            error.SetErrorStringWithFormat("Unrecognized language name: \"%s\"", optarg);
+            return error;
         }
     }
+
     
-    if (error.Fail() || m_option_data.m_print_help)
-    {
-        ShowUsage (out_fh, g_options, m_option_data);
-        exiting = true;
-    }
-    else if (m_option_data.m_print_version)
-    {
-        ::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
-        exiting = true;
-    }
-    else if (m_option_data.m_print_python_path)
+    if (options::python_path.getNumOccurrences() > 0)
     {
         SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
         if (python_file_spec.IsValid())
@@ -892,39 +540,12 @@
         else
             ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
         exiting = true;
+        return error;
     }
-    else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
-    {
-        // Any arguments that are left over after option parsing are for
-        // the program. If a file was specified with -f then the filename
-        // is already in the m_option_data.m_args array, and any remaining args
-        // are arguments for the inferior program. If no file was specified with
-        // -f, then what is left is the program name followed by any arguments.
-
-        // Skip any options we consumed with getopt_long_only
-        argc -= optind;
-        argv += optind;
-
-        if (argc > 0)
-        {
-            for (int arg_idx=0; arg_idx<argc; ++arg_idx)
-            {
-                const char *arg = argv[arg_idx];
-                if (arg)
-                    m_option_data.m_args.push_back (arg);
-            }
-        }
-        
-    }
-    else
-    {
-        // Skip any options we consumed with getopt_long_only
-        argc -= optind;
-        //argv += optind; // Commented out to keep static analyzer happy
 
-        if (argc > 0)
-            ::fprintf (out_fh, "Warning: program arguments are ignored when attaching.\n");
-    }
+    if ((options::attach_name.getNumOccurrences() > 0 || options::attach_pid.getNumOccurrences() > 0) &&
+        options::args.size() > 0)
+        ::fprintf(out_fh, "Warning: program arguments are ignored when attaching.\n");
 
     return error;
 }
@@ -1043,7 +664,7 @@
     m_debugger.SetOutputFileHandle (stdout, false);
     m_debugger.SetInputFileHandle (stdin, false); // Don't take ownership of STDIN yet...
 
-    m_debugger.SetUseExternalEditor(m_option_data.m_use_external_editor);
+    m_debugger.SetUseExternalEditor(options::editor);
 
     struct winsize window_size;
     if (isatty (STDIN_FILENO)
@@ -1059,7 +680,7 @@
     // .lldbinit file in the user's home directory.
     SBCommandReturnObject result;
     sb_interpreter.SourceInitFileInHomeDirectory(result);
-    if (GetDebugMode())
+    if (options::debug)
     {
         result.PutError (m_debugger.GetErrorFileHandle());
         result.PutOutput (m_debugger.GetOutputFileHandle());
@@ -1071,64 +692,59 @@
     // First source in the commands specified to be run before the file arguments are processed.
     WriteCommandsForSourcing (eCommandPlacementBeforeFile, commands_stream);
         
-    const size_t num_args = m_option_data.m_args.size();
-    if (num_args > 0)
+    if (options::args.size() > 0)
     {
         char arch_name[64];
         if (m_debugger.GetDefaultArchitecture (arch_name, sizeof (arch_name)))
-            commands_stream.Printf("target create --arch=%s %s", arch_name, EscapeString(m_option_data.m_args[0]).c_str());
+            commands_stream.Printf("target create --arch=%s %s", arch_name, EscapeString(options::args[0]).c_str());
         else
-            commands_stream.Printf("target create %s", EscapeString(m_option_data.m_args[0]).c_str());
+            commands_stream.Printf("target create %s", EscapeString(options::args[0]).c_str());
 
-        if (!m_option_data.m_core_file.empty())
+        if (options::core.getNumOccurrences() > 0)
         {
-            commands_stream.Printf(" --core %s", EscapeString(m_option_data.m_core_file).c_str());
+            commands_stream.Printf(" --core %s", EscapeString(options::core).c_str());
         }
         commands_stream.Printf("\n");
         
-        if (num_args > 1)
+        if (options::args.size() > 1)
         {
             commands_stream.Printf ("settings set -- target.run-args ");
-            for (size_t arg_idx = 1; arg_idx < num_args; ++arg_idx)
-                commands_stream.Printf(" %s", EscapeString(m_option_data.m_args[arg_idx]).c_str());
+            for (const std::string &arg : options::args)
+                commands_stream.Printf(" %s", EscapeString(arg).c_str());
             commands_stream.Printf("\n");
         }
     }
-    else if (!m_option_data.m_core_file.empty())
+    else if (options::core.getNumOccurrences() > 0)
+        commands_stream.Printf("target create --core %s\n", EscapeString(options::core).c_str());
+    else if (options::attach_name.getNumOccurrences() > 0)
     {
-        commands_stream.Printf("target create --core %s\n", EscapeString(m_option_data.m_core_file).c_str());
-    }
-    else if (!m_option_data.m_process_name.empty())
-    {
-        commands_stream.Printf ("process attach --name %s", EscapeString(m_option_data.m_process_name).c_str());
+        commands_stream.Printf ("process attach --name %s", EscapeString(options::attach_name).c_str());
         
-        if (m_option_data.m_wait_for)
+        if (options::wait_for)
             commands_stream.Printf(" --waitfor");
 
         commands_stream.Printf("\n");
 
     }
-    else if (LLDB_INVALID_PROCESS_ID != m_option_data.m_process_pid)
-    {
-        commands_stream.Printf ("process attach --pid %" PRIu64 "\n", m_option_data.m_process_pid);
-    }
+    else if (options::attach_pid.getNumOccurrences() > 0)
+        commands_stream.Printf ("process attach --pid %" PRIu64 "\n", uint64_t(options::attach_pid));
 
     WriteCommandsForSourcing(eCommandPlacementAfterFile, commands_stream);
     
-    if (GetDebugMode())
+    if (options::debug)
     {
         result.PutError(m_debugger.GetErrorFileHandle());
         result.PutOutput(m_debugger.GetOutputFileHandle());
     }
     
     bool handle_events = true;
     bool spawn_thread = false;
 
-    if (m_option_data.m_repl)
+    if (options::repl.getNumOccurrences() > 0)
     {
         const char *repl_options = NULL;
-        if (!m_option_data.m_repl_options.empty())
-            repl_options = m_option_data.m_repl_options.c_str();
+        if (!options::repl.empty())
+            repl_options = options::repl.c_str();
         SBError error (m_debugger.RunREPL(m_option_data.m_repl_lang, repl_options));
         if (error.Fail())
         {
@@ -1166,7 +782,7 @@
                 
                 SBCommandInterpreterRunOptions options;
                 options.SetStopOnError (true);
-                if (m_option_data.m_batch)
+                if (options::batch)
                     options.SetStopOnCrash (true);
 
                 m_debugger.RunCommandInterpreter(handle_events,
@@ -1176,7 +792,7 @@
                                                  quit_requested,
                                                  stopped_for_crash);
 
-                if (m_option_data.m_batch && stopped_for_crash && !m_option_data.m_after_crash_commands.empty())
+                if (options::batch && stopped_for_crash && !m_option_data.m_after_crash_commands.empty())
                 {
                     int crash_command_fds[2];
                     SBStream crash_commands_stream;
@@ -1224,7 +840,7 @@
         bool go_interactive = true;
         if (quit_requested)
             go_interactive = false;
-        else if (m_option_data.m_batch && !stopped_for_crash)
+        else if (options::batch && !stopped_for_crash)
             go_interactive = false;
 
         if (go_interactive)
@@ -1301,11 +917,10 @@
 main (int argc, char const *argv[], const char *envp[])
 {
 #ifdef _MSC_VER
-	// disable buffering on windows
-	setvbuf(stdout, NULL, _IONBF, 0);
-	setvbuf(stdin , NULL, _IONBF, 0);
+    // disable buffering on windows
+    setvbuf(stdout, NULL, _IONBF, 0);
+    setvbuf(stdin , NULL, _IONBF, 0);
 #endif
-
     SBDebugger::Initialize();
     
     SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
Index: packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
===================================================================
--- packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
+++ packages/Python/lldbsuite/test/functionalities/format/TestFormats.py
@@ -22,7 +22,7 @@
         self.build()
         import pexpect
         prompt = "(lldb) "
-        child = pexpect.spawn('%s %s -x -o "b main" -o r a.out' % (lldbtest_config.lldbExec, self.lldbOption))
+        child = pexpect.spawn('%s %s -o "b main" -o r a.out' % (lldbtest_config.lldbExec, self.lldbOption))
         # Turn on logging for what the child sends back.
         if self.TraceOn():
             child.logfile_read = sys.stdout
Index: packages/Python/lldbsuite/test/driver/batch_mode/source.file
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/driver/batch_mode/source.file
@@ -0,0 +1 @@
+settings show auto-confirm
Index: packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py
===================================================================
--- packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py
+++ packages/Python/lldbsuite/test/driver/batch_mode/TestBatchMode.py
@@ -167,4 +167,56 @@
         index = self.child.expect([pexpect.EOF, pexpect.TIMEOUT])
         self.assertTrue(index == 0, "lldb didn't close on successful batch completion.")
 
-        
+    @no_debug_info_test
+    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
+    def test_command_order(self):
+        """Test that we handle --source and --one-line commands in the correct order."""
+        self.setTearDownCleanup()
+
+        import pexpect
+        prompt = "(lldb) "
+
+        # Now do it again, and make sure if we don't crash, we quit:
+        run_commands = ' -b --one-line "settings show use-color" --source source.file --one-line "settings show tab-size"'
+        self.child = pexpect.spawn('%s %s %s' % (lldbtest_config.lldbExec, self.lldbOption, run_commands))
+        child = self.child
+        # Turn on logging for what the child sends back.
+        if self.TraceOn():
+            child.logfile_read = sys.stdout
+
+        # We should see the "use-color" from --one-line:
+        self.expect_string ("use-color")
+        # Then "auto-confirm" from --source:
+        self.expect_string ("auto-confirm")
+        # And then "tab-size" from the second --one-line:
+        self.expect_string ("tab-size")
+
+        index = self.child.expect([pexpect.EOF, pexpect.TIMEOUT])
+        self.assertTrue(index == 0, "lldb didn't close on successful batch completion.")
+
+    @skipIfRemote # test not remote-ready llvm.org/pr24813
+    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr22274: need a pexpect replacement for windows")
+    @no_debug_info_test
+    def test_batch_mode_file (self):
+        """Test that we can specify the executable with the --file argument"""
+        self.build()
+        self.setTearDownCleanup()
+
+        import pexpect
+        exe = os.path.join(os.getcwd(), "a.out")
+        prompt = "(lldb) "
+
+        run_commands = ' -b -o "target list" '
+        self.child = pexpect.spawn('%s %s %s --file %s' % (lldbtest_config.lldbExec, self.lldbOption, run_commands, exe))
+        child = self.child
+        # Turn on logging for what the child sends back.
+        if self.TraceOn():
+            child.logfile_read = sys.stdout
+
+        # We should see the "target list":
+        self.expect_string ("target list")
+        # And then the actual target:
+        self.expect_string ("* target #0:")
+
+        index = self.child.expect([pexpect.EOF, pexpect.TIMEOUT])
+        self.assertTrue(index == 0, "lldb didn't close on successful batch completion.")
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to