diff options
author | Greg Clayton <gclayton@apple.com> | 2014-01-27 23:43:24 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2014-01-27 23:43:24 +0000 |
commit | 44d937820b451296f80449ac3de296345e80f183 (patch) | |
tree | 00d14538eded9f7e8bd075128d6ad5fd5ac1caed /lldb/source/Commands/CommandObjectBreakpointCommand.cpp | |
parent | f1cb16e481a60dbac58affcf8c8e423dac3937cb (diff) | |
download | bcm5719-llvm-44d937820b451296f80449ac3de296345e80f183.tar.gz bcm5719-llvm-44d937820b451296f80449ac3de296345e80f183.zip |
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
Diffstat (limited to 'lldb/source/Commands/CommandObjectBreakpointCommand.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpointCommand.cpp | 156 |
1 files changed, 39 insertions, 117 deletions
diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index e540461dada..532d6cedc83 100644 --- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -16,6 +16,7 @@ #include "CommandObjectBreakpointCommand.h" #include "CommandObjectBreakpoint.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 @@ using namespace lldb_private; //------------------------------------------------------------------------- -class CommandObjectBreakpointCommandAdd : public CommandObjectParsed +class CommandObjectBreakpointCommandAdd : + public CommandObjectParsed, + public IOHandlerDelegateMultiline { public: @@ -43,6 +46,7 @@ public: "add", "Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit.", NULL), + IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand), m_options (interpreter) { SetHelpLong ( @@ -207,42 +211,47 @@ one command per line.\n" ); return &m_options; } - void - CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options, - CommandReturnObject &result) + virtual void + IOHandlerActivated (IOHandler &io_handler) { - InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); - std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); - if (reader_sp && data_ap.get()) + StreamFileSP output_sp(io_handler.GetOutputStreamFile()); + if (output_sp) { - BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); - bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); - - Error err (reader_sp->Initialize (CommandObjectBreakpointCommandAdd::GenerateBreakpointCommandCallback, - bp_options, // baton - 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); - } + output_sp->PutCString(g_reader_instructions); + output_sp->Flush(); } - else + } + + + virtual void + IOHandlerInputComplete (IOHandler &io_handler, std::string &line) + { + io_handler.SetIsDone(true); + + BreakpointOptions *bp_options = (BreakpointOptions *) io_handler.GetUserData(); + if (bp_options) { - result.AppendError("out of memory"); - result.SetStatus (eReturnStatusFailed); + std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData()); + if (data_ap.get()) + { + data_ap->user_source.SplitIntoLines (line.c_str(), line.size()); + BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release())); + bp_options->SetCallback (BreakpointOptionsCallbackFunction, baton_sp); + } } } + void + CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options, + CommandReturnObject &result) + { + m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt + *this, // IOHandlerDelegate + true, // Run IOHandler in async mode + bp_options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions + } + /// Set a one-liner as the callback for the breakpoint. void SetBreakpointCommandCallback (BreakpointOptions *bp_options, @@ -262,93 +271,6 @@ one command per line.\n" ); return; } - - static size_t - GenerateBreakpointCommandCallback (void *baton, - 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 && baton) - { - BreakpointOptions *bp_options = (BreakpointOptions *) baton; - if (bp_options) - { - Baton *bp_options_baton = bp_options->GetBaton(); - if (bp_options_baton) - ((BreakpointOptions::CommandData *)bp_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 breakpoint command. - reader.SetIsDone (true); - BreakpointOptions *bp_options = (BreakpointOptions *) baton; - if (bp_options) - { - Baton *bp_options_baton = bp_options->GetBaton (); - if (bp_options_baton) - { - ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->user_source.Clear(); - ((BreakpointOptions::CommandData *) bp_options_baton->m_data)->script_source.clear(); - } - } - if (!batch_mode) - { - out_stream->Printf ("Warning: No command attached to breakpoint.\n"); - out_stream->Flush(); - } - } - break; - - case eInputReaderEndOfFile: - reader.SetIsDone (true); - break; - - case eInputReaderDone: - break; - } - - return bytes_len; - } static bool BreakpointOptionsCallbackFunction (void *baton, @@ -623,7 +545,7 @@ private: }; const char * -CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end."; +CommandObjectBreakpointCommandAdd::g_reader_instructions = "Enter your debugger command(s). Type 'DONE' to end.\n"; // 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. |