Author: labath Date: Fri Jan 6 03:27:38 2017 New Revision: 291220 URL: http://llvm.org/viewvc/llvm-project?rev=291220&view=rev Log: Consolidate file handle usage in Editline.cpp
Summary: 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. Reviewers: clayborg, zturner Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D28356 Modified: lldb/trunk/include/lldb/Host/Editline.h lldb/trunk/source/Host/common/Editline.cpp Modified: lldb/trunk/include/lldb/Host/Editline.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Editline.h?rev=291220&r1=291219&r2=291220&view=diff ============================================================================== --- lldb/trunk/include/lldb/Host/Editline.h (original) +++ lldb/trunk/include/lldb/Host/Editline.h Fri Jan 6 03:27:38 2017 @@ -322,6 +322,8 @@ private: /// 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; Modified: lldb/trunk/source/Host/common/Editline.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Editline.cpp?rev=291220&r1=291219&r2=291220&view=diff ============================================================================== --- lldb/trunk/source/Host/common/Editline.cpp (original) +++ lldb/trunk/source/Host/common/Editline.cpp Fri Jan 6 03:27:38 2017 @@ -526,17 +526,8 @@ int Editline::GetCharacter(EditLineCharT } 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 @@ void Editline::PrintAsync(Stream *stream 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 +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits