Author: Neal Sidhwaney Date: 2021-08-05T02:55:10-07:00 New Revision: 55fd6f292fac7294fcd302e79065eb4fd7a89dfc
URL: https://github.com/llvm/llvm-project/commit/55fd6f292fac7294fcd302e79065eb4fd7a89dfc DIFF: https://github.com/llvm/llvm-project/commit/55fd6f292fac7294fcd302e79065eb4fd7a89dfc.diff LOG: Revert "D106035: Remove conditional compilation for WCHAR support in libedit" This reverts commit 7529f0e3e1427fea93a6a66a2aed5394710e5fb5. Added: Modified: lldb/cmake/modules/LLDBConfig.cmake lldb/include/lldb/Host/Editline.h lldb/source/Host/common/Editline.cpp Removed: ################################################################################ diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index d43891cf43fcd..b62cd7d24438f 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -116,10 +116,19 @@ if ((NOT MSVC) OR MSVC12) add_definitions( -DHAVE_ROUND ) endif() +# Check if we libedit capable of handling wide characters (built with +# '--enable-widec'). if (LLDB_ENABLE_LIBEDIT) set(CMAKE_REQUIRED_LIBRARIES ${LibEdit_LIBRARIES}) set(CMAKE_REQUIRED_INCLUDES ${LibEdit_INCLUDE_DIRS}) + check_symbol_exists(el_winsertstr histedit.h LLDB_EDITLINE_USE_WCHAR) set(CMAKE_EXTRA_INCLUDE_FILES histedit.h) + check_type_size(el_rfunc_t LLDB_EL_RFUNC_T_SIZE) + if (LLDB_EL_RFUNC_T_SIZE STREQUAL "") + set(LLDB_HAVE_EL_RFUNC_T 0) + else() + set(LLDB_HAVE_EL_RFUNC_T 1) + endif() set(CMAKE_REQUIRED_LIBRARIES) set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_EXTRA_INCLUDE_FILES) diff --git a/lldb/include/lldb/Host/Editline.h b/lldb/include/lldb/Host/Editline.h index 4a1e0b5f4dae9..876f6052311e9 100644 --- a/lldb/include/lldb/Host/Editline.h +++ b/lldb/include/lldb/Host/Editline.h @@ -31,6 +31,9 @@ #include "lldb/Host/Config.h" +#if LLDB_EDITLINE_USE_WCHAR +#include <codecvt> +#endif #include <locale> #include <sstream> #include <vector> @@ -57,7 +60,29 @@ namespace lldb_private { namespace line_editor { -using EditlineGetCharCallbackType = int (*)(::EditLine *editline, wchar_t *c); +// type alias's to help manage 8 bit and wide character versions of libedit +#if LLDB_EDITLINE_USE_WCHAR +using EditLineStringType = std::wstring; +using EditLineStringStreamType = std::wstringstream; +using EditLineCharType = wchar_t; +#else +using EditLineStringType = std::string; +using EditLineStringStreamType = std::stringstream; +using EditLineCharType = char; +#endif + +// At one point the callback type of el_set getchar callback changed from char +// to wchar_t. It is not possible to detect diff erentiate between the two +// versions exactly, but this is a pretty good approximation and allows us to +// build against almost any editline version out there. +#if LLDB_EDITLINE_USE_WCHAR || defined(EL_CLIENTDATA) || LLDB_HAVE_EL_RFUNC_T +using EditLineGetCharType = wchar_t; +#else +using EditLineGetCharType = char; +#endif + +using EditlineGetCharCallbackType = int (*)(::EditLine *editline, + EditLineGetCharType *c); using EditlineCommandCallbackType = unsigned char (*)(::EditLine *editline, int ch); using EditlinePromptCallbackType = const char *(*)(::EditLine *editline); @@ -243,7 +268,7 @@ class Editline { /// taking into account both /// the preceding prompt and a single trailing space occupied by a cursor when /// at the end of the line. - int CountRowsForLine(const std::string &content); + int CountRowsForLine(const EditLineStringType &content); /// Save the line currently being edited void SaveEditedLine(); @@ -256,7 +281,7 @@ class Editline { /// Character reading implementation for EditLine that supports our multi-line /// editing trickery. - int GetCharacter(wchar_t *c); + int GetCharacter(EditLineGetCharType *c); /// Prompt implementation for EditLine. const char *Prompt(); @@ -315,7 +340,7 @@ class Editline { /// single or multi-line editing. void ConfigureEditor(bool multiline); - bool CompleteCharacter(char ch, wchar_t &out); + bool CompleteCharacter(char ch, EditLineGetCharType &out); void ApplyTerminalSizeChange(); @@ -323,17 +348,21 @@ class Editline { // verbose to put the editline calls into a function, but it // provides type safety, since the editline functions take varargs // parameters. - void AddFunctionToEditLine(const char *command, const char *helptext, + void AddFunctionToEditLine(const EditLineCharType *command, + const EditLineCharType *helptext, EditlineCommandCallbackType callbackFn); void SetEditLinePromptCallback(EditlinePromptCallbackType callbackFn); void SetGetCharacterFunction(EditlineGetCharCallbackType callbackFn); +#if LLDB_EDITLINE_USE_WCHAR + std::wstring_convert<std::codecvt_utf8<wchar_t>> m_utf8conv; +#endif ::EditLine *m_editline = nullptr; EditlineHistorySP m_history_sp; bool m_in_history = false; - std::vector<std::string> m_live_history_lines; + std::vector<EditLineStringType> m_live_history_lines; bool m_multiline_enabled = false; - std::vector<std::string> m_input_lines; + std::vector<EditLineStringType> m_input_lines; EditorStatus m_editor_status; bool m_color_prompts = true; int m_terminal_width = 0; diff --git a/lldb/source/Host/common/Editline.cpp b/lldb/source/Host/common/Editline.cpp index a3c6a2a8b139d..a5598c387b8c7 100644 --- a/lldb/source/Host/common/Editline.cpp +++ b/lldb/source/Host/common/Editline.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include <climits> -#include <codecvt> #include <iomanip> #include "lldb/Host/Editline.h" @@ -62,12 +61,40 @@ int setupterm(char *term, int fildes, int *errret); #define ANSI_UP_N_ROWS ESCAPE "[%dA" #define ANSI_DOWN_N_ROWS ESCAPE "[%dB" +#if LLDB_EDITLINE_USE_WCHAR + +#define EditLineConstString(str) L##str +#define EditLineStringFormatSpec "%ls" + +#else + #define EditLineConstString(str) str #define EditLineStringFormatSpec "%s" -bool IsOnlySpaces(const std::string &content) { - for (char ch : content) { - if (ch != ' ') +// use #defines so wide version functions and structs will resolve to old +// versions for case of libedit not built with wide char support +#define history_w history +#define history_winit history_init +#define history_wend history_end +#define HistoryW History +#define HistEventW HistEvent +#define LineInfoW LineInfo + +#define el_wgets el_gets +#define el_wgetc el_getc +#define el_wpush el_push +#define el_wparse el_parse +#define el_wset el_set +#define el_wget el_get +#define el_wline el_line +#define el_winsertstr el_insertstr +#define el_wdeletestr el_deletestr + +#endif // #if LLDB_EDITLINE_USE_WCHAR + +bool IsOnlySpaces(const EditLineStringType &content) { + for (wchar_t ch : content) { + if (ch != EditLineCharType(' ')) return false; } return true; @@ -105,16 +132,17 @@ static int GetOperation(HistoryOperation op) { llvm_unreachable("Fully covered switch!"); } -std::string CombineLines(const std::vector<std::string> &lines) { - std::stringstream combined_stream; - for (const std::string &line : lines) { + +EditLineStringType CombineLines(const std::vector<EditLineStringType> &lines) { + EditLineStringStreamType combined_stream; + for (EditLineStringType line : lines) { combined_stream << line.c_str() << "\n"; } return combined_stream.str(); } -std::vector<std::string> SplitLines(const std::string &input) { - std::vector<std::string> result; +std::vector<EditLineStringType> SplitLines(const EditLineStringType &input) { + std::vector<EditLineStringType> result; size_t start = 0; while (start < input.length()) { size_t end = input.find('\n', start); @@ -133,18 +161,23 @@ std::vector<std::string> SplitLines(const std::string &input) { return result; } -std::string FixIndentation(const std::string &line, int indent_correction) { +EditLineStringType FixIndentation(const EditLineStringType &line, + int indent_correction) { if (indent_correction == 0) return line; if (indent_correction < 0) return line.substr(-indent_correction); - return std::string(indent_correction, ' ') + line; + return EditLineStringType(indent_correction, EditLineCharType(' ')) + line; } -int GetIndentation(const std::string &line) { - auto firstNonSpace = std::find_if(line.begin(), line.end(), - [](const char ch) { return ch != ' '; }); - return firstNonSpace - line.begin(); +int GetIndentation(const EditLineStringType &line) { + int space_count = 0; + for (EditLineCharType ch : line) { + if (ch != EditLineCharType(' ')) + break; + ++space_count; + } + return space_count; } bool IsInputPending(FILE *file) { @@ -173,10 +206,10 @@ class EditlineHistory { // these objects EditlineHistory(const std::string &prefix, uint32_t size, bool unique_entries) : m_history(nullptr), m_event(), m_prefix(prefix), m_path() { - m_history = history_init(); - history(m_history, &m_event, H_SETSIZE, size); + m_history = history_winit(); + history_w(m_history, &m_event, H_SETSIZE, size); if (unique_entries) - history(m_history, &m_event, H_SETUNIQUE, 1); + history_w(m_history, &m_event, H_SETUNIQUE, 1); } const char *GetHistoryFilePath() { @@ -189,7 +222,11 @@ class EditlineHistory { // LLDB stores its history in ~/.lldb/. If for some reason this directory // isn't writable or cannot be created, history won't be available. if (!llvm::sys::fs::create_directory(lldb_history_file)) { +#if LLDB_EDITLINE_USE_WCHAR + std::string filename = m_prefix + "-widehistory"; +#else std::string filename = m_prefix + "-history"; +#endif llvm::sys::path::append(lldb_history_file, filename); m_path = std::string(lldb_history_file.str()); } @@ -206,7 +243,7 @@ class EditlineHistory { Save(); if (m_history) { - history_end(m_history); + history_wend(m_history); m_history = nullptr; } } @@ -231,18 +268,18 @@ class EditlineHistory { bool IsValid() const { return m_history != nullptr; } - History *GetHistoryPtr() { return m_history; } + HistoryW *GetHistoryPtr() { return m_history; } - void Enter(const char *line_cstr) { + void Enter(const EditLineCharType *line_cstr) { if (m_history) - history(m_history, &m_event, H_ENTER, line_cstr); + history_w(m_history, &m_event, H_ENTER, line_cstr); } bool Load() { if (m_history) { const char *path = GetHistoryFilePath(); if (path) { - history(m_history, &m_event, H_LOAD, path); + history_w(m_history, &m_event, H_LOAD, path); return true; } } @@ -253,7 +290,7 @@ class EditlineHistory { if (m_history) { const char *path = GetHistoryFilePath(); if (path) { - history(m_history, &m_event, H_SAVE, path); + history_w(m_history, &m_event, H_SAVE, path); return true; } } @@ -261,8 +298,8 @@ class EditlineHistory { } protected: - History *m_history; // The history object - HistEvent m_event; // The history event needed to contain all history events + HistoryW *m_history; // The history object + HistEventW m_event; // The history event needed to contain all history events std::string m_prefix; // The prefix name (usually the editline program name) // to use when loading/saving history std::string m_path; // Path to the history file @@ -320,9 +357,9 @@ bool Editline::IsEmacs() { } bool Editline::IsOnlySpaces() { - const LineInfo *info = el_line(m_editline); - for (const char *character = info->buffer; character < info->lastchar; - character++) { + const LineInfoW *info = el_wline(m_editline); + for (const EditLineCharType *character = info->buffer; + character < info->lastchar; character++) { if (*character != ' ') return false; } @@ -351,7 +388,7 @@ int Editline::GetLineIndexForLocation(CursorLocation location, int cursor_row) { } void Editline::MoveCursor(CursorLocation from, CursorLocation to) { - const LineInfo *info = el_line(m_editline); + const LineInfoW *info = el_wline(m_editline); int editline_cursor_position = (int)((info->cursor - info->buffer) + GetPromptWidth()); int editline_cursor_row = editline_cursor_position / m_terminal_width; @@ -386,10 +423,9 @@ void Editline::DisplayInput(int firstIndex) { const char *unfaint = m_color_prompts ? ANSI_UNFAINT : ""; for (int index = firstIndex; index < line_count; index++) { - fprintf(m_output_file, - "%s" - "%s" - "%s%s ", + fprintf(m_output_file, "%s" + "%s" + "%s" EditLineStringFormatSpec " ", faint, PromptForIndex(index).c_str(), unfaint, m_input_lines[index].c_str()); if (index < line_count - 1) @@ -397,7 +433,7 @@ void Editline::DisplayInput(int firstIndex) { } } -int Editline::CountRowsForLine(const std::string &content) { +int Editline::CountRowsForLine(const EditLineStringType &content) { std::string prompt = PromptForIndex(0); // Prompt width is constant during an edit session int line_length = (int)(content.length() + prompt.length()); @@ -405,17 +441,21 @@ int Editline::CountRowsForLine(const std::string &content) { } void Editline::SaveEditedLine() { - const LineInfo *info = el_line(m_editline); + const LineInfoW *info = el_wline(m_editline); m_input_lines[m_current_line_index] = - std::string(info->buffer, info->lastchar - info->buffer); + EditLineStringType(info->buffer, info->lastchar - info->buffer); } StringList Editline::GetInputAsStringList(int line_count) { StringList lines; - for (std::string line : m_input_lines) { + for (EditLineStringType line : m_input_lines) { if (line_count == 0) break; +#if LLDB_EDITLINE_USE_WCHAR + lines.AppendString(m_utf8conv.to_bytes(line)); +#else lines.AppendString(line); +#endif --line_count; } return lines; @@ -426,9 +466,9 @@ unsigned char Editline::RecallHistory(HistoryOperation op) { if (!m_history_sp || !m_history_sp->IsValid()) return CC_ERROR; - History *pHistory = m_history_sp->GetHistoryPtr(); - HistEvent history_event; - std::vector<std::string> new_input_lines; + HistoryW *pHistory = m_history_sp->GetHistoryPtr(); + HistEventW history_event; + std::vector<EditLineStringType> new_input_lines; // Treat moving from the "live" entry diff erently if (!m_in_history) { @@ -436,8 +476,8 @@ unsigned char Editline::RecallHistory(HistoryOperation op) { case HistoryOperation::Newer: return CC_ERROR; // Can't go newer than the "live" entry case HistoryOperation::Older: { - if (history(pHistory, &history_event, - GetOperation(HistoryOperation::Newest)) == -1) + if (history_w(pHistory, &history_event, + GetOperation(HistoryOperation::Newest)) == -1) return CC_ERROR; // Save any edits to the "live" entry in case we return by moving forward // in history (it would be more bash-like to save over any current entry, @@ -451,7 +491,7 @@ unsigned char Editline::RecallHistory(HistoryOperation op) { llvm_unreachable("unsupported history direction"); } } else { - if (history(pHistory, &history_event, GetOperation(op)) == -1) { + if (history_w(pHistory, &history_event, GetOperation(op)) == -1) { switch (op) { case HistoryOperation::Older: // Can't move earlier than the earliest entry. @@ -493,8 +533,8 @@ unsigned char Editline::RecallHistory(HistoryOperation op) { return CC_NEWLINE; } -int Editline::GetCharacter(wchar_t *c) { - const LineInfo *info = el_line(m_editline); +int Editline::GetCharacter(EditLineGetCharType *c) { + const LineInfoW *info = el_wline(m_editline); // Paint a faint version of the desired prompt over the version libedit draws // (will only be requested if colors are supported) @@ -581,15 +621,16 @@ const char *Editline::Prompt() { unsigned char Editline::BreakLineCommand(int ch) { // Preserve any content beyond the cursor, truncate and save the current line - const LineInfo *info = el_line(m_editline); - auto current_line = std::string(info->buffer, info->cursor - info->buffer); + const LineInfoW *info = el_wline(m_editline); + auto current_line = + EditLineStringType(info->buffer, info->cursor - info->buffer); auto new_line_fragment = - std::string(info->cursor, info->lastchar - info->cursor); + EditLineStringType(info->cursor, info->lastchar - info->cursor); m_input_lines[m_current_line_index] = current_line; // Ignore whitespace-only extra fragments when breaking a line if (::IsOnlySpaces(new_line_fragment)) - new_line_fragment = ""; + new_line_fragment = EditLineConstString(""); // Establish the new cursor position at the start of a line when inserting a // line break @@ -600,7 +641,11 @@ unsigned char Editline::BreakLineCommand(int ch) { // Apply smart indentation if (m_fix_indentation_callback) { StringList lines = GetInputAsStringList(m_current_line_index + 1); +#if LLDB_EDITLINE_USE_WCHAR + lines.AppendString(m_utf8conv.to_bytes(new_line_fragment)); +#else lines.AppendString(new_line_fragment); +#endif int indent_correction = m_fix_indentation_callback(this, lines, 0); new_line_fragment = FixIndentation(new_line_fragment, indent_correction); @@ -632,7 +677,7 @@ unsigned char Editline::EndOrAddLineCommand(int ch) { // If this is the end of the last line, consider whether to add a line // instead - const LineInfo *info = el_line(m_editline); + const LineInfoW *info = el_wline(m_editline); if (m_current_line_index == m_input_lines.size() - 1 && info->cursor == info->lastchar) { if (m_is_input_complete_callback) { @@ -644,7 +689,12 @@ unsigned char Editline::EndOrAddLineCommand(int ch) { // The completion test is allowed to change the input lines when complete m_input_lines.clear(); for (unsigned index = 0; index < lines.GetSize(); index++) { +#if LLDB_EDITLINE_USE_WCHAR + m_input_lines.insert(m_input_lines.end(), + m_utf8conv.from_bytes(lines[index])); +#else m_input_lines.insert(m_input_lines.end(), lines[index]); +#endif } } } @@ -655,7 +705,7 @@ unsigned char Editline::EndOrAddLineCommand(int ch) { } unsigned char Editline::DeleteNextCharCommand(int ch) { - LineInfo *info = const_cast<LineInfo *>(el_line(m_editline)); + LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline)); // Just delete the next character normally if possible if (info->cursor < info->lastchar) { @@ -679,8 +729,8 @@ unsigned char Editline::DeleteNextCharCommand(int ch) { MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt); // Insert the next line of text at the cursor and restore the cursor position - const char *cursor = info->cursor; - el_insertstr(m_editline, m_input_lines[m_current_line_index + 1].c_str()); + const EditLineCharType *cursor = info->cursor; + el_winsertstr(m_editline, m_input_lines[m_current_line_index + 1].c_str()); info->cursor = cursor; SaveEditedLine(); @@ -694,7 +744,7 @@ unsigned char Editline::DeleteNextCharCommand(int ch) { } unsigned char Editline::DeletePreviousCharCommand(int ch) { - const LineInfo *info = el_line(m_editline); + LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline)); // Just delete the previous character normally when not at the start of a // line @@ -723,7 +773,7 @@ unsigned char Editline::DeletePreviousCharCommand(int ch) { // Put the cursor back where libedit expects it to be before returning to // editing by telling libedit about the newly inserted text MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt); - el_insertstr(m_editline, priorLine.c_str()); + el_winsertstr(m_editline, priorLine.c_str()); return CC_REDISPLAY; } @@ -767,13 +817,15 @@ unsigned char Editline::NextLineCommand(int ch) { lines.AppendString(""); indentation = m_fix_indentation_callback(this, lines, 0); } - m_input_lines.insert(m_input_lines.end(), std::string(indentation, ' ')); + m_input_lines.insert( + m_input_lines.end(), + EditLineStringType(indentation, EditLineCharType(' '))); } // Move down past the current line using newlines to force scrolling if // needed SetCurrentLine(m_current_line_index + 1); - const LineInfo *info = el_line(m_editline); + const LineInfoW *info = el_wline(m_editline); int cursor_position = (int)((info->cursor - info->buffer) + GetPromptWidth()); int cursor_row = cursor_position / m_terminal_width; for (int line_count = 0; line_count < m_current_line_rows - cursor_row; @@ -800,9 +852,9 @@ unsigned char Editline::FixIndentationCommand(int ch) { return CC_NORM; // Insert the character typed before proceeding - char inserted[] = {(char)ch, 0}; - el_insertstr(m_editline, inserted); - const LineInfo *info = el_line(m_editline); + EditLineCharType inserted[] = {(EditLineCharType)ch, 0}; + el_winsertstr(m_editline, inserted); + LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline)); int cursor_position = info->cursor - info->buffer; // Save the edits and determine the correct indentation level @@ -822,7 +874,11 @@ unsigned char Editline::FixIndentationCommand(int ch) { } else { currentLine = currentLine.erase(0, -indent_correction); } +#if LLDB_EDITLINE_USE_WCHAR + m_input_lines[m_current_line_index] = m_utf8conv.from_bytes(currentLine); +#else m_input_lines[m_current_line_index] = currentLine; +#endif // Update the display to reflect the change MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt); @@ -837,9 +893,9 @@ unsigned char Editline::FixIndentationCommand(int ch) { } unsigned char Editline::RevertLineCommand(int ch) { - el_insertstr(m_editline, m_input_lines[m_current_line_index].c_str()); + el_winsertstr(m_editline, m_input_lines[m_current_line_index].c_str()); if (m_revert_cursor_index >= 0) { - LineInfo *info = const_cast<LineInfo *>(el_line(m_editline)); + LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline)); info->cursor = info->buffer + m_revert_cursor_index; if (info->cursor > info->lastchar) { info->cursor = info->lastchar; @@ -1046,9 +1102,10 @@ unsigned char Editline::TypedCharacter(int ch) { return CC_REDISPLAY; } -void Editline::AddFunctionToEditLine(const char *command, const char *helptext, +void Editline::AddFunctionToEditLine(const EditLineCharType *command, + const EditLineCharType *helptext, EditlineCommandCallbackType callbackFn) { - el_set(m_editline, EL_ADDFN, command, helptext, callbackFn); + el_wset(m_editline, EL_ADDFN, command, helptext, callbackFn); } void Editline::SetEditLinePromptCallback( @@ -1081,13 +1138,13 @@ void Editline::ConfigureEditor(bool multiline) { if (!m_history_sp->Load()) { fputs("Could not load history file\n.", m_output_file); } - el_set(m_editline, EL_HIST, history, m_history_sp->GetHistoryPtr()); + el_wset(m_editline, EL_HIST, history, m_history_sp->GetHistoryPtr()); } el_set(m_editline, EL_CLIENTDATA, this); el_set(m_editline, EL_SIGNAL, 0); el_set(m_editline, EL_EDITOR, "emacs"); - SetGetCharacterFunction([](EditLine *editline, wchar_t *c) { + SetGetCharacterFunction([](EditLine *editline, EditLineGetCharType *c) { return Editline::InstanceFor(editline)->GetCharacter(c); }); @@ -1098,56 +1155,68 @@ void Editline::ConfigureEditor(bool multiline) { // Commands used for multiline support, registered whether or not they're // used AddFunctionToEditLine( - "lldb-break-line", "Insert a line break", [](EditLine *editline, int ch) { + EditLineConstString("lldb-break-line"), + EditLineConstString("Insert a line break"), + [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->BreakLineCommand(ch); }); AddFunctionToEditLine( - "lldb-end-or-add-line", "End editing or continue when incomplete", + EditLineConstString("lldb-end-or-add-line"), + EditLineConstString("End editing or continue when incomplete"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->EndOrAddLineCommand(ch); }); AddFunctionToEditLine( - "lldb-delete-next-char", "Delete next character", + EditLineConstString("lldb-delete-next-char"), + EditLineConstString("Delete next character"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->DeleteNextCharCommand(ch); }); AddFunctionToEditLine( - "lldb-delete-previous-char", "Delete previous character", + EditLineConstString("lldb-delete-previous-char"), + EditLineConstString("Delete previous character"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->DeletePreviousCharCommand(ch); }); AddFunctionToEditLine( - "lldb-previous-line", "Move to previous line", + EditLineConstString("lldb-previous-line"), + EditLineConstString("Move to previous line"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->PreviousLineCommand(ch); }); AddFunctionToEditLine( - "lldb-next-line", "Move to next line", [](EditLine *editline, int ch) { + EditLineConstString("lldb-next-line"), + EditLineConstString("Move to next line"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->NextLineCommand(ch); }); AddFunctionToEditLine( - "lldb-previous-history", "Move to previous history", + EditLineConstString("lldb-previous-history"), + EditLineConstString("Move to previous history"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->PreviousHistoryCommand(ch); }); AddFunctionToEditLine( - "lldb-next-history", "Move to next history", + EditLineConstString("lldb-next-history"), + EditLineConstString("Move to next history"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->NextHistoryCommand(ch); }); AddFunctionToEditLine( - "lldb-buffer-start", "Move to start of buffer", + EditLineConstString("lldb-buffer-start"), + EditLineConstString("Move to start of buffer"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->BufferStartCommand(ch); }); AddFunctionToEditLine( - "lldb-buffer-end", "Move to end of buffer", + EditLineConstString("lldb-buffer-end"), + EditLineConstString("Move to end of buffer"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->BufferEndCommand(ch); }); AddFunctionToEditLine( - "lldb-fix-indentation", "Fix line indentation", + EditLineConstString("lldb-fix-indentation"), + EditLineConstString("Fix line indentation"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->FixIndentationCommand(ch); }); @@ -1161,9 +1230,11 @@ void Editline::ConfigureEditor(bool multiline) { int ch) { return Editline::InstanceFor(editline)->TabCommand(ch); }; - AddFunctionToEditLine("lldb-complete", "Invoke completion", + AddFunctionToEditLine(EditLineConstString("lldb-complete"), + EditLineConstString("Invoke completion"), complete_callback); - AddFunctionToEditLine("lldb_complete", "Invoke completion", + AddFunctionToEditLine(EditLineConstString("lldb_complete"), + EditLineConstString("Invoke completion"), complete_callback); // General bindings we don't mind being overridden @@ -1173,7 +1244,8 @@ void Editline::ConfigureEditor(bool multiline) { if (m_suggestion_callback) { AddFunctionToEditLine( - "lldb-apply-complete", "Adopt autocompletion", + EditLineConstString("lldb-apply-complete"), + EditLineConstString("Adopt autocompletion"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->ApplyAutosuggestCommand(ch); }); @@ -1182,7 +1254,8 @@ void Editline::ConfigureEditor(bool multiline) { NULL); // Apply a part that is suggested automatically AddFunctionToEditLine( - "lldb-typed-character", "Typed character", + EditLineConstString("lldb-typed-character"), + EditLineConstString("Typed character"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->TypedCharacter(ch); }); @@ -1221,7 +1294,8 @@ void Editline::ConfigureEditor(bool multiline) { // Register an internal binding that external developers shouldn't use AddFunctionToEditLine( - "lldb-revert-line", "Revert line to saved state", + EditLineConstString("lldb-revert-line"), + EditLineConstString("Revert line to saved state"), [](EditLine *editline, int ch) { return Editline::InstanceFor(editline)->RevertLineCommand(ch); }); @@ -1373,7 +1447,7 @@ void Editline::ApplyTerminalSizeChange() { if (el_get(m_editline, EL_GETTC, "co", &columns, nullptr) == 0) { m_terminal_width = columns; if (m_current_line_rows != -1) { - const LineInfo *info = el_line(m_editline); + const LineInfoW *info = el_wline(m_editline); int lineLength = (int)((info->lastchar - info->buffer) + GetPromptWidth()); m_current_line_rows = (lineLength / columns) + 1; @@ -1413,8 +1487,8 @@ bool Editline::Cancel() { bool Editline::GetLine(std::string &line, bool &interrupted) { ConfigureEditor(false); - m_input_lines = std::vector<std::string>(); - m_input_lines.insert(m_input_lines.begin(), ""); + m_input_lines = std::vector<EditLineStringType>(); + m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); std::lock_guard<std::mutex> guard(m_output_mutex); @@ -1431,7 +1505,7 @@ bool Editline::GetLine(std::string &line, bool &interrupted) { m_revert_cursor_index = -1; int count; - auto input = el_gets(m_editline, &count); + auto input = el_wgets(m_editline, &count); interrupted = m_editor_status == EditorStatus::Interrupted; if (!interrupted) { @@ -1440,7 +1514,11 @@ bool Editline::GetLine(std::string &line, bool &interrupted) { m_editor_status = EditorStatus::EndOfInput; } else { m_history_sp->Enter(input); +#if LLDB_EDITLINE_USE_WCHAR + line = m_utf8conv.to_bytes(SplitLines(input)[0]); +#else line = SplitLines(input)[0]; +#endif m_editor_status = EditorStatus::Complete; } } @@ -1454,8 +1532,8 @@ bool Editline::GetLines(int first_line_number, StringList &lines, // Print the initial input lines, then move the cursor back up to the start // of input SetBaseLineNumber(first_line_number); - m_input_lines = std::vector<std::string>(); - m_input_lines.insert(m_input_lines.begin(), ""); + m_input_lines = std::vector<EditLineStringType>(); + m_input_lines.insert(m_input_lines.begin(), EditLineConstString("")); std::lock_guard<std::mutex> guard(m_output_mutex); // Begin the line editing loop @@ -1469,8 +1547,9 @@ bool Editline::GetLines(int first_line_number, StringList &lines, while (m_editor_status == EditorStatus::Editing) { int count; m_current_line_rows = -1; - el_push(m_editline, "\x1b[^"); // Revert to the existing line content - el_gets(m_editline, &count); + el_wpush(m_editline, EditLineConstString( + "\x1b[^")); // Revert to the existing line content + el_wgets(m_editline, &count); } interrupted = m_editor_status == EditorStatus::Interrupted; @@ -1497,7 +1576,14 @@ void Editline::PrintAsync(Stream *stream, const char *s, size_t len) { } } -bool Editline::CompleteCharacter(char ch, wchar_t &out) { +bool Editline::CompleteCharacter(char ch, EditLineGetCharType &out) { +#if !LLDB_EDITLINE_USE_WCHAR + if (ch == (char)EOF) + return false; + + out = (unsigned char)ch; + return true; +#else std::codecvt_utf8<wchar_t> cvt; llvm::SmallString<4> input; for (;;) { @@ -1523,4 +1609,5 @@ bool Editline::CompleteCharacter(char ch, wchar_t &out) { break; } } +#endif } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits