summaryrefslogtreecommitdiff
path: root/include/lldb/Core/IOHandler.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Core/IOHandler.h')
-rw-r--r--include/lldb/Core/IOHandler.h315
1 files changed, 250 insertions, 65 deletions
diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h
index f477ebd48007..02e6bde1edb6 100644
--- a/include/lldb/Core/IOHandler.h
+++ b/include/lldb/Core/IOHandler.h
@@ -19,9 +19,11 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Flags.h"
+#include "lldb/Core/Stream.h"
#include "lldb/Core/StringList.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Host/Mutex.h"
+#include "lldb/Host/Predicate.h"
namespace curses
{
@@ -34,9 +36,23 @@ namespace lldb_private {
class IOHandler
{
public:
- IOHandler (Debugger &debugger);
+ enum class Type {
+ CommandInterpreter,
+ CommandList,
+ Confirm,
+ Curses,
+ Expression,
+ ProcessIO,
+ PythonInterpreter,
+ PythonCode,
+ Other
+ };
+
+ IOHandler (Debugger &debugger,
+ IOHandler::Type type);
IOHandler (Debugger &debugger,
+ IOHandler::Type type,
const lldb::StreamFileSP &input_sp,
const lldb::StreamFileSP &output_sp,
const lldb::StreamFileSP &error_sp,
@@ -97,6 +113,12 @@ namespace lldb_private {
return m_done;
}
+ Type
+ GetType () const
+ {
+ return m_type;
+ }
+
virtual void
Activate ()
{
@@ -128,7 +150,19 @@ namespace lldb_private {
{
return ConstString();
}
+
+ virtual const char *
+ GetCommandPrefix ()
+ {
+ return NULL;
+ }
+ virtual const char *
+ GetHelpPrologue()
+ {
+ return NULL;
+ }
+
int
GetInputFD();
@@ -206,13 +240,21 @@ namespace lldb_private {
//------------------------------------------------------------------
bool
GetIsRealTerminal ();
-
+
+ void
+ SetPopped (bool b);
+
+ void
+ WaitForPop ();
+
protected:
Debugger &m_debugger;
lldb::StreamFileSP m_input_sp;
lldb::StreamFileSP m_output_sp;
lldb::StreamFileSP m_error_sp;
+ Predicate<bool> m_popped;
Flags m_flags;
+ Type m_type;
void *m_user_data;
bool m_done;
bool m_active;
@@ -254,7 +296,12 @@ namespace lldb_private {
IOHandlerActivated (IOHandler &io_handler)
{
}
-
+
+ virtual void
+ IOHandlerDeactivated (IOHandler &io_handler)
+ {
+ }
+
virtual int
IOHandlerComplete (IOHandler &io_handler,
const char *current_line,
@@ -264,6 +311,44 @@ namespace lldb_private {
int max_matches,
StringList &matches);
+ virtual const char *
+ IOHandlerGetFixIndentationCharacters ()
+ {
+ return NULL;
+ }
+
+ //------------------------------------------------------------------
+ /// Called when a new line is created or one of an identifed set of
+ /// indentation characters is typed.
+ ///
+ /// This function determines how much indentation should be added
+ /// or removed to match the recommended amount for the final line.
+ ///
+ /// @param[in] io_handler
+ /// The IOHandler that responsible for input.
+ ///
+ /// @param[in] lines
+ /// The current input up to the line to be corrected. Lines
+ /// following the line containing the cursor are not included.
+ ///
+ /// @param[in] cursor_position
+ /// The number of characters preceeding the cursor on the final
+ /// line at the time.
+ ///
+ /// @return
+ /// Returns an integer describing the number of spaces needed
+ /// to correct the indentation level. Positive values indicate
+ /// that spaces should be added, while negative values represent
+ /// spaces that should be removed.
+ //------------------------------------------------------------------
+ virtual int
+ IOHandlerFixIndentation (IOHandler &io_handler,
+ const StringList &lines,
+ int cursor_position)
+ {
+ return 0;
+ }
+
//------------------------------------------------------------------
/// Called when a line or lines have been retrieved.
///
@@ -275,40 +360,55 @@ namespace lldb_private {
//------------------------------------------------------------------
virtual void
IOHandlerInputComplete (IOHandler &io_handler, std::string &data) = 0;
-
+
+ virtual void
+ IOHandlerInputInterrupted (IOHandler &io_handler, std::string &data)
+ {
+ }
+
//------------------------------------------------------------------
- /// Called when a line in \a lines has been updated when doing
- /// multi-line input.
+ /// Called to determine whether typing enter after the last line in
+ /// \a lines should end input. This function will not be called on
+ /// IOHandler objects that are getting single lines.
+ /// @param[in] io_handler
+ /// The IOHandler that responsible for updating the lines.
+ ///
+ /// @param[in] lines
+ /// The current multi-line content. May be altered to provide
+ /// alternative input when complete.
///
/// @return
- /// Return an enumeration to indicate the status of the current
- /// line:
- /// Success - The line is good and should be added to the
- /// multiple lines
- /// Error - There is an error with the current line and it
- /// need to be re-edited before it is acceptable
- /// Done - The lines collection is complete and ready to be
- /// returned.
+ /// Return an boolean to indicate whether input is complete,
+ /// true indicates that no additional input is necessary, while
+ /// false indicates that more input is required.
//------------------------------------------------------------------
- virtual LineStatus
- IOHandlerLinesUpdated (IOHandler &io_handler,
- StringList &lines,
- uint32_t line_idx,
- Error &error)
+ virtual bool
+ IOHandlerIsInputComplete (IOHandler &io_handler,
+ StringList &lines)
{
- return LineStatus::Done; // Stop getting lines on the first line that is updated
- // subclasses should do something more intelligent here.
- // This function will not be called on IOHandler objects
- // that are getting single lines.
+ // Impose no requirements for input to be considered
+ // complete. subclasses should do something more intelligent.
+ return true;
}
-
virtual ConstString
IOHandlerGetControlSequence (char ch)
{
return ConstString();
}
+ virtual const char *
+ IOHandlerGetCommandPrefix ()
+ {
+ return NULL;
+ }
+
+ virtual const char *
+ IOHandlerGetHelpPrologue ()
+ {
+ return NULL;
+ }
+
//------------------------------------------------------------------
// Intercept the IOHandler::Interrupt() calls and do something.
//
@@ -356,30 +456,21 @@ namespace lldb_private {
return ConstString();
}
- virtual LineStatus
- IOHandlerLinesUpdated (IOHandler &io_handler,
- StringList &lines,
- uint32_t line_idx,
- Error &error)
+ virtual bool
+ IOHandlerIsInputComplete (IOHandler &io_handler,
+ StringList &lines)
{
- if (line_idx == UINT32_MAX)
+ // Determine whether the end of input signal has been entered
+ const size_t num_lines = lines.GetSize();
+ if (num_lines > 0 && lines[num_lines - 1] == m_end_line)
{
- // Remove the last empty line from "lines" so it doesn't appear
- // in our final expression and return true to indicate we are done
+ // Remove the terminal line from "lines" so it doesn't appear in
+ // the resulting input and return true to indicate we are done
// getting lines
lines.PopBack();
- return LineStatus::Done;
- }
- else if (line_idx + 1 == lines.GetSize())
- {
- // The last line was edited, if this line is empty, then we are done
- // getting our multiple lines.
- if (lines[line_idx] == m_end_line)
- {
- return LineStatus::Done;
- }
+ return true;
}
- return LineStatus::Success;
+ return false;
}
protected:
const std::string m_end_line;
@@ -390,20 +481,26 @@ namespace lldb_private {
{
public:
IOHandlerEditline (Debugger &debugger,
+ IOHandler::Type type,
const char *editline_name, // Used for saving history files
const char *prompt,
+ const char *continuation_prompt,
bool multi_line,
+ bool color_prompts,
uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start'
IOHandlerDelegate &delegate);
IOHandlerEditline (Debugger &debugger,
+ IOHandler::Type type,
const lldb::StreamFileSP &input_sp,
const lldb::StreamFileSP &output_sp,
const lldb::StreamFileSP &error_sp,
uint32_t flags,
const char *editline_name, // Used for saving history files
const char *prompt,
+ const char *continuation_prompt,
bool multi_line,
+ bool color_prompts,
uint32_t line_number_start, // If non-zero show line numbers starting at 'line_number_start'
IOHandlerDelegate &delegate);
@@ -429,11 +526,10 @@ namespace lldb_private {
GotEOF();
virtual void
- Activate ()
- {
- IOHandler::Activate();
- m_delegate.IOHandlerActivated(*this);
- }
+ Activate ();
+
+ virtual void
+ Deactivate ();
virtual ConstString
GetControlSequence (char ch)
@@ -442,11 +538,29 @@ namespace lldb_private {
}
virtual const char *
+ GetCommandPrefix ()
+ {
+ return m_delegate.IOHandlerGetCommandPrefix ();
+ }
+
+ virtual const char *
+ GetHelpPrologue ()
+ {
+ return m_delegate.IOHandlerGetHelpPrologue ();
+ }
+
+ virtual const char *
GetPrompt ();
virtual bool
SetPrompt (const char *prompt);
-
+
+ const char *
+ GetContinuationPrompt ();
+
+ void
+ SetContinuationPrompt (const char *prompt);
+
bool
GetLine (std::string &line, bool &interrupted);
@@ -456,14 +570,40 @@ namespace lldb_private {
void
SetBaseLineNumber (uint32_t line);
- private:
- static LineStatus
- LineCompletedCallback (Editline *editline,
- StringList &lines,
- uint32_t line_idx,
- Error &error,
- void *baton);
+ bool
+ GetInterruptExits ()
+ {
+ return m_interrupt_exits;
+ }
+ void
+ SetInterruptExits (bool b)
+ {
+ m_interrupt_exits = b;
+ }
+
+ const StringList *
+ GetCurrentLines () const
+ {
+ return m_current_lines_ptr;
+ }
+
+ uint32_t
+ GetCurrentLineIndex () const;
+
+ private:
+#ifndef LLDB_DISABLE_LIBEDIT
+ static bool
+ IsInputCompleteCallback (Editline *editline,
+ StringList &lines,
+ void *baton);
+
+ static int
+ FixIndentationCallback (Editline *editline,
+ const StringList &lines,
+ int cursor_position,
+ void *baton);
+
static int AutoCompleteCallback (const char *current_line,
const char *cursor,
const char *last_char,
@@ -471,18 +611,28 @@ namespace lldb_private {
int max_matches,
StringList &matches,
void *baton);
+#endif
protected:
+#ifndef LLDB_DISABLE_LIBEDIT
std::unique_ptr<Editline> m_editline_ap;
+#endif
IOHandlerDelegate &m_delegate;
std::string m_prompt;
+ std::string m_continuation_prompt;
+ StringList *m_current_lines_ptr;
uint32_t m_base_line_number; // If non-zero, then show line numbers in prompt
- bool m_multi_line;
+ uint32_t m_curr_line_idx;
+ bool m_multi_line;
+ bool m_color_prompts;
+ bool m_interrupt_exits;
};
+ // The order of base classes is important. Look at the constructor of IOHandlerConfirm
+ // to see how.
class IOHandlerConfirm :
- public IOHandlerEditline,
- public IOHandlerDelegate
+ public IOHandlerDelegate,
+ public IOHandlerEditline
{
public:
IOHandlerConfirm (Debugger &debugger,
@@ -607,7 +757,8 @@ namespace lldb_private {
if (sp)
{
Mutex::Locker locker (m_mutex);
- m_stack.push (sp);
+ sp->SetPopped (false);
+ m_stack.push_back (sp);
// Set m_top the non-locking IsTop() call
m_top = sp.get();
}
@@ -627,7 +778,7 @@ namespace lldb_private {
{
Mutex::Locker locker (m_mutex);
if (!m_stack.empty())
- sp = m_stack.top();
+ sp = m_stack.back();
}
return sp;
}
@@ -637,12 +788,16 @@ namespace lldb_private {
{
Mutex::Locker locker (m_mutex);
if (!m_stack.empty())
- m_stack.pop();
+ {
+ lldb::IOHandlerSP sp (m_stack.back());
+ m_stack.pop_back();
+ sp->SetPopped (true);
+ }
// Set m_top the non-locking IsTop() call
if (m_stack.empty())
m_top = NULL;
else
- m_top = m_stack.top().get();
+ m_top = m_stack.back().get();
}
Mutex &
@@ -657,6 +812,19 @@ namespace lldb_private {
return m_top == io_handler_sp.get();
}
+ bool
+ CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type)
+ {
+ Mutex::Locker locker (m_mutex);
+ const size_t num_io_handlers = m_stack.size();
+ if (num_io_handlers >= 2 &&
+ m_stack[num_io_handlers-1]->GetType() == top_type &&
+ m_stack[num_io_handlers-2]->GetType() == second_top_type)
+ {
+ return true;
+ }
+ return false;
+ }
ConstString
GetTopIOHandlerControlSequence (char ch)
{
@@ -665,9 +833,26 @@ namespace lldb_private {
return ConstString();
}
- protected:
+ const char *
+ GetTopIOHandlerCommandPrefix()
+ {
+ if (m_top)
+ return m_top->GetCommandPrefix();
+ return NULL;
+ }
+
+ const char *
+ GetTopIOHandlerHelpPrologue()
+ {
+ if (m_top)
+ return m_top->GetHelpPrologue();
+ return NULL;
+ }
+
+ protected:
- std::stack<lldb::IOHandlerSP> m_stack;
+ typedef std::vector<lldb::IOHandlerSP> collection;
+ collection m_stack;
mutable Mutex m_mutex;
IOHandler *m_top;