Index: include/lldb/Core/IOHandler.h =================================================================== --- include/lldb/Core/IOHandler.h +++ include/lldb/Core/IOHandler.h @@ -421,16 +421,14 @@ private: #ifndef LLDB_DISABLE_LIBEDIT - static bool IsInputCompleteCallback(Editline *editline, StringList &lines, - void *baton); + bool IsInputCompleteCallback(Editline *editline, StringList &lines); - static int FixIndentationCallback(Editline *editline, const StringList &lines, - int cursor_position, void *baton); + int FixIndentationCallback(Editline *editline, const StringList &lines, + int cursor_position); - static int AutoCompleteCallback(const char *current_line, const char *cursor, - const char *last_char, - int skip_first_n_matches, int max_matches, - StringList &matches, void *baton); + int AutoCompleteCallback(const char *current_line, const char *cursor, + const char *last_char, int skip_first_n_matches, + int max_matches, StringList &matches); #endif protected: Index: include/lldb/Host/Editline.h =================================================================== --- include/lldb/Host/Editline.h +++ include/lldb/Host/Editline.h @@ -42,6 +42,7 @@ #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/lldb-private.h" +#include "llvm/ADT/FunctionExtras.h" #if defined(_WIN32) #include "lldb/Host/windows/editlinewin.h" @@ -56,6 +57,7 @@ #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Predicate.h" +#include "lldb/Utility/StringList.h" // for StringList namespace lldb_private { namespace line_editor { @@ -81,27 +83,23 @@ using EditLineGetCharType = char; #endif -typedef int (*EditlineGetCharCallbackType)(::EditLine *editline, +using EditlineGetCharCallbackType = int (*)(::EditLine *editline, EditLineGetCharType *c); -typedef unsigned char (*EditlineCommandCallbackType)(::EditLine *editline, +using EditlineCommandCallbackType = unsigned char (*)(::EditLine *editline, int ch); -typedef const char *(*EditlinePromptCallbackType)(::EditLine *editline); +using EditlinePromptCallbackType = const char *(*)(::EditLine *editline); class EditlineHistory; -typedef std::shared_ptr EditlineHistorySP; +using EditlineHistorySP = std::shared_ptr; -typedef bool (*IsInputCompleteCallbackType)(Editline *editline, - StringList &lines, void *baton); - -typedef int (*FixIndentationCallbackType)(Editline *editline, - const StringList &lines, - int cursor_position, void *baton); - -typedef int (*CompleteCallbackType)(const char *current_line, - const char *cursor, const char *last_char, - int skip_first_n_matches, int max_matches, - StringList &matches, void *baton); +using IsInputCompleteCallbackType = + llvm::unique_function; +using FixIndentationCallbackType = + llvm::unique_function; +using CompleteCallbackType = + llvm::unique_function; /// Status used to decide when and how to start editing another line in /// multi-line sessions @@ -181,18 +179,23 @@ bool Cancel(); /// Register a callback for the tab key - void SetAutoCompleteCallback(CompleteCallbackType callback, void *baton); + void SetAutoCompleteCallback(CompleteCallbackType callback) { + m_completion_callback = std::move(callback); + } /// Register a callback for testing whether multi-line input is complete - void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback, - void *baton); + void SetIsInputCompleteCallback(IsInputCompleteCallbackType callback) { + m_is_input_complete_callback = std::move(callback); + } /// Register a callback for determining the appropriate indentation for a line /// when creating a newline. An optional set of insertable characters can - /// also - /// trigger the callback. - bool SetFixIndentationCallback(FixIndentationCallbackType callback, - void *baton, const char *indent_chars); + /// also trigger the callback. + void SetFixIndentationCallback(FixIndentationCallbackType callback, + const char *indent_chars) { + m_fix_indentation_callback = std::move(callback); + m_fix_indentation_callback_chars = indent_chars; + } /// Prompts for and reads a single line of user input. bool GetLine(std::string &line, bool &interrupted); @@ -351,13 +354,10 @@ FILE *m_output_file; FILE *m_error_file; ConnectionFileDescriptor m_input_connection; - IsInputCompleteCallbackType m_is_input_complete_callback = nullptr; - void *m_is_input_complete_callback_baton = nullptr; - FixIndentationCallbackType m_fix_indentation_callback = nullptr; - void *m_fix_indentation_callback_baton = nullptr; + IsInputCompleteCallbackType m_is_input_complete_callback; + FixIndentationCallbackType m_fix_indentation_callback; const char *m_fix_indentation_callback_chars = nullptr; - CompleteCallbackType m_completion_callback = nullptr; - void *m_completion_callback_baton = nullptr; + CompleteCallbackType m_completion_callback; std::mutex m_output_mutex; }; Index: source/Core/IOHandler.cpp =================================================================== --- source/Core/IOHandler.cpp +++ source/Core/IOHandler.cpp @@ -309,15 +309,30 @@ m_editline_ap.reset(new Editline(editline_name, GetInputFILE(), GetOutputFILE(), GetErrorFILE(), m_color_prompts)); - m_editline_ap->SetIsInputCompleteCallback(IsInputCompleteCallback, this); - m_editline_ap->SetAutoCompleteCallback(AutoCompleteCallback, this); + m_editline_ap->SetIsInputCompleteCallback( + [this] (Editline *editline, StringList& lines) { + return this->IsInputCompleteCallback(editline, lines); + }); + + m_editline_ap->SetAutoCompleteCallback( + [this] (const char *current_line, const char *cursor, + const char *last_char, int skip_first_n_matches, + int max_matches, StringList &matches) { + return this->AutoCompleteCallback(current_line, cursor, last_char, + skip_first_n_matches, max_matches, + matches); + }); + // See if the delegate supports fixing indentation const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters(); if (indent_chars) { // The delegate does support indentation, hook it up so when any // indentation character is typed, the delegate gets a chance to fix it - m_editline_ap->SetFixIndentationCallback(FixIndentationCallback, this, - indent_chars); + m_editline_ap->SetFixIndentationCallback( + [this] (Editline *editline, const StringList &lines, + int cursor_position) { + return this->FixIndentationCallback(editline, lines, cursor_position); + }, indent_chars); } } #endif @@ -416,20 +431,15 @@ #ifndef LLDB_DISABLE_LIBEDIT bool IOHandlerEditline::IsInputCompleteCallback(Editline *editline, - StringList &lines, - void *baton) { - IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton; - return editline_reader->m_delegate.IOHandlerIsInputComplete(*editline_reader, - lines); + StringList &lines) { + return m_delegate.IOHandlerIsInputComplete(*this, lines); } int IOHandlerEditline::FixIndentationCallback(Editline *editline, const StringList &lines, - int cursor_position, - void *baton) { - IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton; - return editline_reader->m_delegate.IOHandlerFixIndentation( - *editline_reader, lines, cursor_position); + int cursor_position) { + return m_delegate.IOHandlerFixIndentation( + *this, lines, cursor_position); } int IOHandlerEditline::AutoCompleteCallback(const char *current_line, @@ -437,13 +447,10 @@ const char *last_char, int skip_first_n_matches, int max_matches, - StringList &matches, void *baton) { - IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton; - if (editline_reader) - return editline_reader->m_delegate.IOHandlerComplete( - *editline_reader, current_line, cursor, last_char, skip_first_n_matches, - max_matches, matches); - return 0; + StringList &matches) { + return m_delegate.IOHandlerComplete( + *this, current_line, cursor, last_char, skip_first_n_matches, + max_matches, matches); } #endif Index: source/Host/common/Editline.cpp =================================================================== --- source/Host/common/Editline.cpp +++ source/Host/common/Editline.cpp @@ -576,8 +576,7 @@ lines.AppendString(new_line_fragment); #endif - int indent_correction = m_fix_indentation_callback( - this, lines, 0, m_fix_indentation_callback_baton); + int indent_correction = m_fix_indentation_callback(this, lines, 0); new_line_fragment = FixIndentation(new_line_fragment, indent_correction); m_revert_cursor_index = GetIndentation(new_line_fragment); } @@ -612,8 +611,7 @@ info->cursor == info->lastchar) { if (m_is_input_complete_callback) { auto lines = GetInputAsStringList(); - if (!m_is_input_complete_callback(this, lines, - m_is_input_complete_callback_baton)) { + if (!m_is_input_complete_callback(this, lines)) { return BreakLineCommand(ch); } @@ -746,8 +744,7 @@ if (m_fix_indentation_callback) { StringList lines = GetInputAsStringList(); lines.AppendString(""); - indentation = m_fix_indentation_callback( - this, lines, 0, m_fix_indentation_callback_baton); + indentation = m_fix_indentation_callback(this, lines, 0); } m_input_lines.insert( m_input_lines.end(), @@ -792,8 +789,8 @@ // Save the edits and determine the correct indentation level SaveEditedLine(); StringList lines = GetInputAsStringList(m_current_line_index + 1); - int indent_correction = m_fix_indentation_callback( - this, lines, cursor_position, m_fix_indentation_callback_baton); + int indent_correction = m_fix_indentation_callback(this, lines, + cursor_position); // If it is already correct no special work is needed if (indent_correction == 0) @@ -854,7 +851,7 @@ } unsigned char Editline::TabCommand(int ch) { - if (m_completion_callback == nullptr) + if (!m_completion_callback) return CC_ERROR; const LineInfo *line_info = el_line(m_editline); @@ -865,7 +862,7 @@ line_info->buffer, line_info->cursor, line_info->lastchar, 0, // Don't skip any matches (start at match zero) -1, // Get all the matches - completions, m_completion_callback_baton); + completions); if (num_completions == 0) return CC_ERROR; @@ -1238,27 +1235,6 @@ return result; } -void Editline::SetAutoCompleteCallback(CompleteCallbackType callback, - void *baton) { - m_completion_callback = callback; - m_completion_callback_baton = baton; -} - -void Editline::SetIsInputCompleteCallback(IsInputCompleteCallbackType callback, - void *baton) { - m_is_input_complete_callback = callback; - m_is_input_complete_callback_baton = baton; -} - -bool Editline::SetFixIndentationCallback(FixIndentationCallbackType callback, - void *baton, - const char *indent_chars) { - m_fix_indentation_callback = callback; - m_fix_indentation_callback_baton = baton; - m_fix_indentation_callback_chars = indent_chars; - return false; -} - bool Editline::GetLine(std::string &line, bool &interrupted) { ConfigureEditor(false); m_input_lines = std::vector(); Index: unittests/Editline/EditlineTest.cpp =================================================================== --- unittests/Editline/EditlineTest.cpp +++ unittests/Editline/EditlineTest.cpp @@ -78,8 +78,8 @@ void ConsumeAllOutput(); private: - static bool IsInputComplete(lldb_private::Editline *editline, - lldb_private::StringList &lines, void *baton); + bool IsInputComplete(lldb_private::Editline *editline, + lldb_private::StringList &lines); std::unique_ptr _editline_sp; @@ -129,7 +129,10 @@ _editline_sp->SetPrompt("> "); // Hookup our input complete callback. - _editline_sp->SetIsInputCompleteCallback(IsInputComplete, this); + auto input_complete_cb = [this] (Editline *editline, StringList &lines) { + return this->IsInputComplete(editline, lines); + }; + _editline_sp->SetIsInputCompleteCallback(input_complete_cb); } void EditlineAdapter::CloseInput() { @@ -190,8 +193,7 @@ } bool EditlineAdapter::IsInputComplete(lldb_private::Editline *editline, - lldb_private::StringList &lines, - void *baton) { + lldb_private::StringList &lines) { // We'll call ourselves complete if we've received a balanced set of braces. int start_block_count = 0; int brace_balance = 0;