[Lldb-commits] [lldb] 55fd6f2 - Revert "D106035: Remove conditional compilation for WCHAR support in libedit"

Neal Sidhwaney via lldb-commits lldb-commits at lists.llvm.org
Thu Aug 5 02:57:29 PDT 2021


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
 }


        


More information about the lldb-commits mailing list