Merging the iohandler branch back into main. 

The many many benefits include:
1 - Input/Output/Error streams are now handled as real streams not a push style input
2 - auto completion in python embedded interpreter
3 - multi-line input for "script" and "expression" commands now allow you to edit previous/next lines using up and down arrow keys and this makes multi-line input actually a viable thing to use
4 - it is now possible to use curses to drive LLDB (please try the "gui" command)

We will need to deal with and fix any buildbot failures and tests and arise now that input/output and error are correctly hooked up in all cases.

llvm-svn: 200263
diff --git a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
index e19216d..0083ff1 100644
--- a/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
+++ b/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
@@ -16,6 +16,7 @@
 #include "CommandObjectWatchpointCommand.h"
 #include "CommandObjectWatchpoint.h"
 
+#include "lldb/Core/IOHandler.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Target/Target.h"
@@ -34,7 +35,9 @@
 //-------------------------------------------------------------------------
 
 
-class CommandObjectWatchpointCommandAdd : public CommandObjectParsed
+class CommandObjectWatchpointCommandAdd :
+    public CommandObjectParsed,
+    public IOHandlerDelegateMultiline
 {
 public:
 
@@ -43,6 +46,7 @@
                              "add",
                              "Add a set of commands to a watchpoint, to be executed whenever the watchpoint is hit.",
                              NULL),
+        IOHandlerDelegateMultiline("DONE", IOHandlerDelegate::Completion::LLDBCommand),
         m_options (interpreter)
     {
         SetHelpLong (
@@ -185,40 +189,45 @@
         return &m_options;
     }
 
+    virtual void
+    IOHandlerActivated (IOHandler &io_handler)
+    {
+        StreamFileSP output_sp(io_handler.GetOutputStreamFile());
+        if (output_sp)
+        {
+            output_sp->PutCString("Enter your debugger command(s).  Type 'DONE' to end.\n");
+            output_sp->Flush();
+        }
+    }
+    
+    
+    virtual void
+    IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
+    {
+        io_handler.SetIsDone(true);
+        
+        // The WatchpointOptions object is owned by the watchpoint or watchpoint location
+        WatchpointOptions *wp_options = (WatchpointOptions *) io_handler.GetUserData();
+        if (wp_options)
+        {
+            std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
+            if (data_ap.get())
+            {
+                data_ap->user_source.SplitIntoLines(line);
+                BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
+                wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
+            }
+        }
+    }
+
     void
     CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options, 
                                              CommandReturnObject &result)
     {
-        InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
-        std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
-        if (reader_sp && data_ap.get())
-        {
-            BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
-            wp_options->SetCallback (WatchpointOptionsCallbackFunction, baton_sp);
-
-            Error err (reader_sp->Initialize (CommandObjectWatchpointCommandAdd::GenerateWatchpointCommandCallback,
-                                              wp_options,                   // callback_data
-                                              eInputReaderGranularityLine,  // token size, to pass to callback function
-                                              "DONE",                       // end token
-                                              "> ",                         // prompt
-                                              true));                       // echo input
-            if (err.Success())
-            {
-                m_interpreter.GetDebugger().PushInputReader (reader_sp);
-                result.SetStatus (eReturnStatusSuccessFinishNoResult);
-            }
-            else
-            {
-                result.AppendError (err.AsCString());
-                result.SetStatus (eReturnStatusFailed);
-            }
-        }
-        else
-        {
-            result.AppendError("out of memory");
-            result.SetStatus (eReturnStatusFailed);
-        }
-
+        m_interpreter.GetLLDBCommandsFromIOHandler ("> ",           // Prompt
+                                                    *this,          // IOHandlerDelegate
+                                                    true,           // Run IOHandler in async mode
+                                                    wp_options);    // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
     }
     
     /// Set a one-liner as the callback for the watchpoint.
@@ -240,93 +249,6 @@
 
         return;
     }
-
-    static size_t
-    GenerateWatchpointCommandCallback (void *callback_data, 
-                                       InputReader &reader, 
-                                       lldb::InputReaderAction notification,
-                                       const char *bytes, 
-                                       size_t bytes_len)
-    {
-        StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
-        bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
-        
-        switch (notification)
-        {
-        case eInputReaderActivate:
-            if (!batch_mode)
-            {
-                out_stream->Printf ("%s\n", g_reader_instructions);
-                if (reader.GetPrompt())
-                    out_stream->Printf ("%s", reader.GetPrompt());
-                out_stream->Flush();
-            }
-            break;
-
-        case eInputReaderDeactivate:
-            break;
-
-        case eInputReaderReactivate:
-            if (reader.GetPrompt() && !batch_mode)
-            {
-                out_stream->Printf ("%s", reader.GetPrompt());
-                out_stream->Flush();
-            }
-            break;
-
-        case eInputReaderAsynchronousOutputWritten:
-            break;
-            
-        case eInputReaderGotToken:
-            if (bytes && bytes_len && callback_data)
-            {
-                WatchpointOptions *wp_options = (WatchpointOptions *) callback_data;
-                if (wp_options)
-                {
-                    Baton *wp_options_baton = wp_options->GetBaton();
-                    if (wp_options_baton)
-                        ((WatchpointOptions::CommandData *)wp_options_baton->m_data)->user_source.AppendString (bytes, bytes_len); 
-                }
-            }
-            if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
-            {
-                out_stream->Printf ("%s", reader.GetPrompt());
-                out_stream->Flush();
-            }
-            break;
-            
-        case eInputReaderInterrupt:
-            {
-                // Finish, and cancel the watchpoint command.
-                reader.SetIsDone (true);
-                WatchpointOptions *wp_options = (WatchpointOptions *) callback_data;
-                if (wp_options)
-                {
-                    Baton *wp_options_baton = wp_options->GetBaton ();
-                    if (wp_options_baton)
-                    {
-                        ((WatchpointOptions::CommandData *) wp_options_baton->m_data)->user_source.Clear();
-                        ((WatchpointOptions::CommandData *) wp_options_baton->m_data)->script_source.clear();
-                    }
-                }
-                if (!batch_mode)
-                {
-                    out_stream->Printf ("Warning: No command attached to watchpoint.\n");
-                    out_stream->Flush();
-                }
-            }
-            break;
-            
-        case eInputReaderEndOfFile:
-            reader.SetIsDone (true);
-            break;
-            
-        case eInputReaderDone:
-            break;
-        }
-
-        return bytes_len;
-    }
     
     static bool
     WatchpointOptionsCallbackFunction (void *baton,
@@ -579,12 +501,8 @@
 
 private:
     CommandOptions m_options;
-    static const char *g_reader_instructions;
-
 };
 
-const char *
-CommandObjectWatchpointCommandAdd::g_reader_instructions = "Enter your debugger command(s).  Type 'DONE' to end.";
 
 // FIXME: "script-type" needs to have its contents determined dynamically, so somebody can add a new scripting
 // language to lldb and have it pickable here without having to change this enumeration by hand and rebuild lldb proper.