This adds a "batch mode" to lldb kinda like the gdb batch mode.  It will quit the debugger
after all the commands have been executed except if one of the commands was an execution control
command that stopped because of a signal or exception.

Also adds a variant of SBCommandInterpreter::HandleCommand that takes an SBExecutionContext.  That
way you can run an lldb command targeted at a particular target, thread or process w/o having to 
select same before running the command.

Also exposes CommandInterpreter::HandleCommandsFromFile to the SBCommandInterpreter API, since that
seemed generally useful.

llvm-svn: 219654
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index e4fdc77..cec56b4 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -109,7 +109,10 @@
     { 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, "source-quietly"          , 'Q', no_argument      , 0,  eArgTypeNone,
-        "Tells the debugger suppress output from commands provided in the -s, -S, -O and -o commands." },
+        "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,
@@ -406,6 +409,7 @@
     m_process_name(),
     m_process_pid(LLDB_INVALID_PROCESS_ID),
     m_use_external_editor(false),
+    m_batch(false),
     m_seen_options()
 {
 }
@@ -429,6 +433,7 @@
     m_use_external_editor = false;
     m_wait_for = false;
     m_process_name.erase();
+    m_batch = false;
     m_process_pid = LLDB_INVALID_PROCESS_ID;
 }
 
@@ -641,6 +646,10 @@
                         m_option_data.m_print_python_path = true;
                         break;
 
+                    case 'b':
+                        m_option_data.m_batch = true;
+                        break;
+
                     case 'c':
                         {
                             SBFileSpec file(optarg);
@@ -924,6 +933,7 @@
 
     // The command file might have requested that we quit, this variable will track that.
     bool quit_requested = false;
+    bool stopped_for_crash = false;
     if (commands_data && commands_size)
     {
         enum PIPES { READ, WRITE }; // Constants 0 and 1 for READ and WRITE
@@ -973,8 +983,15 @@
                     
                     SBCommandInterpreterRunOptions options;
                     options.SetStopOnError (true);
-                    
-                    m_debugger.RunCommandInterpreter(handle_events, spawn_thread, options, num_errors, quit_requested);
+                    if (m_option_data.m_batch)
+                        options.SetStopOnCrash (true);
+
+                    m_debugger.RunCommandInterpreter(handle_events,
+                                                     spawn_thread,
+                                                     options,
+                                                     num_errors,
+                                                     quit_requested,
+                                                     stopped_for_crash);
                     m_debugger.SetAsync(old_async);
                 }
                 else
@@ -1030,7 +1047,13 @@
     // interpreter again in interactive mode and let the debugger
     // take ownership of stdin
 
-    if (!quit_requested)
+    bool go_interactive = true;
+    if (quit_requested)
+        go_interactive = false;
+    else if (m_option_data.m_batch && !stopped_for_crash)
+        go_interactive = false;
+
+    if (go_interactive)
     {
         m_debugger.SetInputFileHandle (stdin, true);
         m_debugger.RunCommandInterpreter(handle_events, spawn_thread);