[Lldb-commits] [PATCH] D28356: Consolidate file handle usage in Editline.cpp

Pavel Labath via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Thu Jan 5 07:47:01 PST 2017


labath created this revision.
labath added reviewers: clayborg, zturner.
labath added a subscriber: lldb-commits.

To implement wide character reading, editline was mixing FILE*-based access with
a Connection-based one (plus it did some selects on the raw FD), which is very
fragile. Here, I replace it with one which uses only a Connection-based reads.
The code is somewhat longer as I had to read characters one by one to detect the
end of the multibyte sequence.

I've verified that international characters still work in lldb command line on
OSX.


https://reviews.llvm.org/D28356

Files:
  include/lldb/Host/Editline.h
  source/Host/common/Editline.cpp


Index: source/Host/common/Editline.cpp
===================================================================
--- source/Host/common/Editline.cpp
+++ source/Host/common/Editline.cpp
@@ -526,17 +526,8 @@
     }
 
     if (read_count) {
-#if LLDB_EDITLINE_USE_WCHAR
-      // After the initial interruptible read, this is guaranteed not to block
-      ungetc(ch, m_input_file);
-      *c = fgetwc(m_input_file);
-      if (*c != WEOF)
-        return 1;
-#else
-      *c = ch;
-      if (ch != (char)EOF)
+      if (CompleteCharacter(ch, *c))
         return 1;
-#endif
     } else {
       switch (status) {
       case lldb::eConnectionStatusSuccess: // Success
@@ -1367,3 +1358,39 @@
     MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
   }
 }
+
+bool Editline::CompleteCharacter(char ch, EditLineCharType &out) {
+#if !LLDB_EDITLINE_USE_WCHAR
+  if (ch == (char)EOF)
+    return false;
+
+  out = ch;
+  return true;
+#else
+  std::codecvt_utf8<wchar_t> cvt;
+  llvm::SmallString<4> input;
+  for (;;) {
+    const char *from_next;
+    wchar_t *to_next;
+    std::mbstate_t state = std::mbstate_t();
+    input.push_back(ch);
+    switch (cvt.in(state, input.begin(), input.end(), from_next, &out, &out + 1,
+                   to_next)) {
+    case std::codecvt_base::ok:
+      return out != WEOF;
+
+    case std::codecvt_base::error:
+    case std::codecvt_base::noconv:
+      return false;
+
+    case std::codecvt_base::partial:
+      lldb::ConnectionStatus status;
+      size_t read_count = m_input_connection.Read(
+          &ch, 1, std::chrono::seconds(0), status, nullptr);
+      if (read_count == 0)
+        return false;
+      break;
+    }
+  }
+#endif
+}
Index: include/lldb/Host/Editline.h
===================================================================
--- include/lldb/Host/Editline.h
+++ include/lldb/Host/Editline.h
@@ -322,6 +322,8 @@
   /// single or multi-line editing.
   void ConfigureEditor(bool multiline);
 
+  bool CompleteCharacter(char ch, EditLineCharType &out);
+
 private:
 #if LLDB_EDITLINE_USE_WCHAR
   std::wstring_convert<std::codecvt_utf8<wchar_t>> m_utf8conv;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D28356.83237.patch
Type: text/x-patch
Size: 2133 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20170105/bb84d3c8/attachment-0001.bin>


More information about the lldb-commits mailing list