[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
This revision was automatically updated to reflect the committed changes. Closed by commit rGb3faa01ff962: IOHandler: fall back on File::Read if a FILE* isnt available. (authored by lawrence_danna). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 Files: lldb/include/lldb/Core/IOHandler.h lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py lldb/source/Core/IOHandler.cpp Index: lldb/source/Core/IOHandler.cpp === --- lldb/source/Core/IOHandler.cpp +++ lldb/source/Core/IOHandler.cpp @@ -70,6 +70,10 @@ using namespace lldb; using namespace lldb_private; +using llvm::None; +using llvm::Optional; +using llvm::StringRef; + IOHandler::IOHandler(Debugger , IOHandler::Type type) : IOHandler(debugger, type, @@ -306,94 +310,119 @@ m_delegate.IOHandlerDeactivated(*this); } +// Split out a line from the buffer, if there is a full one to get. +static Optional SplitLine(std::string _buffer) { + size_t pos = line_buffer.find('\n'); + if (pos == std::string::npos) +return None; + std::string line = StringRef(line_buffer.c_str(), pos).rtrim("\n\r"); + line_buffer = line_buffer.substr(pos + 1); + return line; +} + +// If the final line of the file ends without a end-of-line, return +// it as a line anyway. +static Optional SplitLineEOF(std::string _buffer) { + if (llvm::all_of(line_buffer, isspace)) +return None; + std::string line = std::move(line_buffer); + line_buffer.clear(); + return line; +} + bool IOHandlerEditline::GetLine(std::string , bool ) { #ifndef LLDB_DISABLE_LIBEDIT if (m_editline_up) { bool b = m_editline_up->GetLine(line, interrupted); -if (m_data_recorder) +if (b && m_data_recorder) m_data_recorder->Record(line, true); return b; - } else { + } #endif -line.clear(); -FILE *in = GetInputFILE(); -if (in) { - if (GetIsInteractive()) { -const char *prompt = nullptr; + line.clear(); -if (m_multi_line && m_curr_line_idx > 0) - prompt = GetContinuationPrompt(); + if (GetIsInteractive()) { +const char *prompt = nullptr; -if (prompt == nullptr) - prompt = GetPrompt(); +if (m_multi_line && m_curr_line_idx > 0) + prompt = GetContinuationPrompt(); -if (prompt && prompt[0]) { - if (m_output_sp) { -m_output_sp->Printf("%s", prompt); -m_output_sp->Flush(); - } -} +if (prompt == nullptr) + prompt = GetPrompt(); + +if (prompt && prompt[0]) { + if (m_output_sp) { +m_output_sp->Printf("%s", prompt); +m_output_sp->Flush(); + } +} + } + + Optional got_line = SplitLine(m_line_buffer); + + if (!got_line && !m_input_sp) { +// No more input file, we are done... +SetIsDone(true); +return false; + } + + FILE *in = GetInputFILE(); + char buffer[256]; + + if (!got_line && !in && m_input_sp) { +// there is no FILE*, fall back on just reading bytes from the stream. +while (!got_line) { + size_t bytes_read = sizeof(buffer); + Status error = m_input_sp->Read((void *)buffer, bytes_read); + if (error.Success() && !bytes_read) { +got_line = SplitLineEOF(m_line_buffer); +break; } - char buffer[256]; - bool done = false; - bool got_line = false; - m_editing = true; - while (!done) { + if (error.Fail()) +break; + m_line_buffer += StringRef(buffer, bytes_read); + got_line = SplitLine(m_line_buffer); +} + } + + if (!got_line && in) { +m_editing = true; +while (!got_line) { + char *r = fgets(buffer, sizeof(buffer), in); #ifdef _WIN32 -// ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED -// according to the docs on MSDN. However, this has evidently been a -// known bug since Windows 8. Therefore, we can't detect if a signal -// interrupted in the fgets. So pressing ctrl-c causes the repl to end -// and the process to exit. A temporary workaround is just to attempt to -// fgets twice until this bug is fixed. -if (fgets(buffer, sizeof(buffer), in) == nullptr && -fgets(buffer, sizeof(buffer), in) == nullptr) { - // this is the equivalent of EINTR for Windows - if (GetLastError() == ERROR_OPERATION_ABORTED) -continue; -#else - if (fgets(buffer, sizeof(buffer), in) == nullptr) { + // ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED + // according to the docs on MSDN. However, this has evidently been a + // known bug since Windows 8. Therefore, we can't detect if a signal + // interrupted in the fgets. So pressing ctrl-c causes the repl to end + // and the process to exit. A temporary workaround is just to attempt to + // fgets twice
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
lawrence_danna updated this revision to Diff 224630. lawrence_danna added a comment. move using declarations Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 Files: lldb/include/lldb/Core/IOHandler.h lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py lldb/source/Core/IOHandler.cpp Index: lldb/source/Core/IOHandler.cpp === --- lldb/source/Core/IOHandler.cpp +++ lldb/source/Core/IOHandler.cpp @@ -70,6 +70,10 @@ using namespace lldb; using namespace lldb_private; +using llvm::None; +using llvm::Optional; +using llvm::StringRef; + IOHandler::IOHandler(Debugger , IOHandler::Type type) : IOHandler(debugger, type, @@ -306,94 +310,119 @@ m_delegate.IOHandlerDeactivated(*this); } +// Split out a line from the buffer, if there is a full one to get. +static Optional SplitLine(std::string _buffer) { + size_t pos = line_buffer.find('\n'); + if (pos == std::string::npos) +return None; + std::string line = StringRef(line_buffer.c_str(), pos).rtrim("\n\r"); + line_buffer = line_buffer.substr(pos + 1); + return line; +} + +// If the final line of the file ends without a end-of-line, return +// it as a line anyway. +static Optional SplitLineEOF(std::string _buffer) { + if (llvm::all_of(line_buffer, isspace)) +return None; + std::string line = std::move(line_buffer); + line_buffer.clear(); + return line; +} + bool IOHandlerEditline::GetLine(std::string , bool ) { #ifndef LLDB_DISABLE_LIBEDIT if (m_editline_up) { bool b = m_editline_up->GetLine(line, interrupted); -if (m_data_recorder) +if (b && m_data_recorder) m_data_recorder->Record(line, true); return b; - } else { + } #endif -line.clear(); -FILE *in = GetInputFILE(); -if (in) { - if (GetIsInteractive()) { -const char *prompt = nullptr; + line.clear(); -if (m_multi_line && m_curr_line_idx > 0) - prompt = GetContinuationPrompt(); + if (GetIsInteractive()) { +const char *prompt = nullptr; -if (prompt == nullptr) - prompt = GetPrompt(); +if (m_multi_line && m_curr_line_idx > 0) + prompt = GetContinuationPrompt(); -if (prompt && prompt[0]) { - if (m_output_sp) { -m_output_sp->Printf("%s", prompt); -m_output_sp->Flush(); - } -} +if (prompt == nullptr) + prompt = GetPrompt(); + +if (prompt && prompt[0]) { + if (m_output_sp) { +m_output_sp->Printf("%s", prompt); +m_output_sp->Flush(); + } +} + } + + Optional got_line = SplitLine(m_line_buffer); + + if (!got_line && !m_input_sp) { +// No more input file, we are done... +SetIsDone(true); +return false; + } + + FILE *in = GetInputFILE(); + char buffer[256]; + + if (!got_line && !in && m_input_sp) { +// there is no FILE*, fall back on just reading bytes from the stream. +while (!got_line) { + size_t bytes_read = sizeof(buffer); + Status error = m_input_sp->Read((void *)buffer, bytes_read); + if (error.Success() && !bytes_read) { +got_line = SplitLineEOF(m_line_buffer); +break; } - char buffer[256]; - bool done = false; - bool got_line = false; - m_editing = true; - while (!done) { + if (error.Fail()) +break; + m_line_buffer += StringRef(buffer, bytes_read); + got_line = SplitLine(m_line_buffer); +} + } + + if (!got_line && in) { +m_editing = true; +while (!got_line) { + char *r = fgets(buffer, sizeof(buffer), in); #ifdef _WIN32 -// ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED -// according to the docs on MSDN. However, this has evidently been a -// known bug since Windows 8. Therefore, we can't detect if a signal -// interrupted in the fgets. So pressing ctrl-c causes the repl to end -// and the process to exit. A temporary workaround is just to attempt to -// fgets twice until this bug is fixed. -if (fgets(buffer, sizeof(buffer), in) == nullptr && -fgets(buffer, sizeof(buffer), in) == nullptr) { - // this is the equivalent of EINTR for Windows - if (GetLastError() == ERROR_OPERATION_ABORTED) -continue; -#else - if (fgets(buffer, sizeof(buffer), in) == nullptr) { + // ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED + // according to the docs on MSDN. However, this has evidently been a + // known bug since Windows 8. Therefore, we can't detect if a signal + // interrupted in the fgets. So pressing ctrl-c causes the repl to end + // and the process to exit. A temporary workaround is just to attempt to + // fgets twice until this bug is fixed. + if (r == nullptr) +r = fgets(buffer, sizeof(buffer),
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
labath accepted this revision. labath added inline comments. This revision is now accepted and ready to land. Comment at: lldb/source/Core/IOHandler.cpp:308-310 +using llvm::None; +using llvm::Optional; +using llvm::StringRef; Please move these to the beginning of the file, next to all the "using namespace" stuff. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
lawrence_danna added a comment. fixed Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
lawrence_danna updated this revision to Diff 224119. lawrence_danna marked 4 inline comments as done. lawrence_danna added a comment. review fixes Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 Files: lldb/include/lldb/Core/IOHandler.h lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py lldb/source/Core/IOHandler.cpp Index: lldb/source/Core/IOHandler.cpp === --- lldb/source/Core/IOHandler.cpp +++ lldb/source/Core/IOHandler.cpp @@ -305,94 +305,123 @@ m_delegate.IOHandlerDeactivated(*this); } +using llvm::None; +using llvm::Optional; +using llvm::StringRef; + +// Split out a line from the buffer, if there is a full one to get. +static Optional SplitLine(std::string _buffer) { + size_t pos = line_buffer.find('\n'); + if (pos == std::string::npos) +return None; + std::string line = StringRef(line_buffer.c_str(), pos).rtrim("\n\r"); + line_buffer = line_buffer.substr(pos + 1); + return line; +} + +// If the final line of the file ends without a end-of-line, return +// it as a line anyway. +static Optional SplitLineEOF(std::string _buffer) { + if (llvm::all_of(line_buffer, isspace)) +return None; + std::string line = std::move(line_buffer); + line_buffer.clear(); + return line; +} + bool IOHandlerEditline::GetLine(std::string , bool ) { #ifndef LLDB_DISABLE_LIBEDIT if (m_editline_up) { bool b = m_editline_up->GetLine(line, interrupted); -if (m_data_recorder) +if (b && m_data_recorder) m_data_recorder->Record(line, true); return b; - } else { + } #endif -line.clear(); -FILE *in = GetInputFILE(); -if (in) { - if (GetIsInteractive()) { -const char *prompt = nullptr; + line.clear(); -if (m_multi_line && m_curr_line_idx > 0) - prompt = GetContinuationPrompt(); + if (GetIsInteractive()) { +const char *prompt = nullptr; -if (prompt == nullptr) - prompt = GetPrompt(); +if (m_multi_line && m_curr_line_idx > 0) + prompt = GetContinuationPrompt(); -if (prompt && prompt[0]) { - if (m_output_sp) { -m_output_sp->Printf("%s", prompt); -m_output_sp->Flush(); - } -} +if (prompt == nullptr) + prompt = GetPrompt(); + +if (prompt && prompt[0]) { + if (m_output_sp) { +m_output_sp->Printf("%s", prompt); +m_output_sp->Flush(); + } +} + } + + Optional got_line = SplitLine(m_line_buffer); + + if (!got_line && !m_input_sp) { +// No more input file, we are done... +SetIsDone(true); +return false; + } + + FILE *in = GetInputFILE(); + char buffer[256]; + + if (!got_line && !in && m_input_sp) { +// there is no FILE*, fall back on just reading bytes from the stream. +while (!got_line) { + size_t bytes_read = sizeof(buffer); + Status error = m_input_sp->Read((void *)buffer, bytes_read); + if (error.Success() && !bytes_read) { +got_line = SplitLineEOF(m_line_buffer); +break; } - char buffer[256]; - bool done = false; - bool got_line = false; - m_editing = true; - while (!done) { + if (error.Fail()) +break; + m_line_buffer += StringRef(buffer, bytes_read); + got_line = SplitLine(m_line_buffer); +} + } + + if (!got_line && in) { +m_editing = true; +while (!got_line) { + char *r = fgets(buffer, sizeof(buffer), in); #ifdef _WIN32 -// ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED -// according to the docs on MSDN. However, this has evidently been a -// known bug since Windows 8. Therefore, we can't detect if a signal -// interrupted in the fgets. So pressing ctrl-c causes the repl to end -// and the process to exit. A temporary workaround is just to attempt to -// fgets twice until this bug is fixed. -if (fgets(buffer, sizeof(buffer), in) == nullptr && -fgets(buffer, sizeof(buffer), in) == nullptr) { - // this is the equivalent of EINTR for Windows - if (GetLastError() == ERROR_OPERATION_ABORTED) -continue; -#else - if (fgets(buffer, sizeof(buffer), in) == nullptr) { + // ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED + // according to the docs on MSDN. However, this has evidently been a + // known bug since Windows 8. Therefore, we can't detect if a signal + // interrupted in the fgets. So pressing ctrl-c causes the repl to end + // and the process to exit. A temporary workaround is just to attempt to + // fgets twice until this bug is fixed. + if (r == nullptr) +r = fgets(buffer, sizeof(buffer), in); + // this is the equivalent of EINTR for Windows + if (r == nullptr && GetLastError() ==
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
labath added inline comments. Comment at: lldb/source/Core/IOHandler.cpp:317-321 + size_t end = pos + 1; + while (end > 0 && + (line_buffer[end - 1] == '\n' || line_buffer[end - 1] == '\r')) +end--; + std::string line = line_buffer.substr(0, end); `line = StringRef(line_buffer.begin(), pos).rtrim("\n\r")` ? Comment at: lldb/source/Core/IOHandler.cpp:326-341 +// Append newchars to the buffer and split out a line. +static Optional AppendAndSplitLine(std::string _buffer, +StringRef newchars) { + size_t pos = newchars.find('\n'); + if (pos == StringRef::npos) { +line_buffer.append(newchars); +return None; This looks like too much optimization. Why not just append the new stuff and then call `SplitLine` ? Comment at: lldb/source/Core/IOHandler.cpp:346-347 +static Optional SplitLineEOF(std::string _buffer) { + if (line_buffer.empty()) +return None; + if (std::all_of(line_buffer.begin(), line_buffer.end(), isspace)) Technically, this check is subsumed by the next one. Comment at: lldb/source/Core/IOHandler.cpp:348 +return None; + if (std::all_of(line_buffer.begin(), line_buffer.end(), isspace)) +return None; `llvm::all_of(line_buffer, ::isspace)` Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
lawrence_danna updated this revision to Diff 223983. lawrence_danna added a comment. rebased Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 Files: lldb/include/lldb/Core/IOHandler.h lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py lldb/source/Core/IOHandler.cpp Index: lldb/source/Core/IOHandler.cpp === --- lldb/source/Core/IOHandler.cpp +++ lldb/source/Core/IOHandler.cpp @@ -305,94 +305,145 @@ m_delegate.IOHandlerDeactivated(*this); } +using llvm::None; +using llvm::Optional; +using llvm::StringRef; + +// Split out a line from the buffer, if there is a full one to get. +static Optional SplitLine(std::string _buffer) { + size_t pos = line_buffer.find('\n'); + if (pos == std::string::npos) +return None; + size_t end = pos + 1; + while (end > 0 && + (line_buffer[end - 1] == '\n' || line_buffer[end - 1] == '\r')) +end--; + std::string line = line_buffer.substr(0, end); + line_buffer = line_buffer.substr(pos + 1); + return line; +} + +// Append newchars to the buffer and split out a line. +static Optional AppendAndSplitLine(std::string _buffer, +StringRef newchars) { + size_t pos = newchars.find('\n'); + if (pos == StringRef::npos) { +line_buffer.append(newchars); +return None; + } + size_t end = pos + 1; + while (end > 0 && (newchars[end - 1] == '\n' || newchars[end - 1] == '\r')) +end--; + std::string line = std::move(line_buffer); + line.append(newchars.substr(0, end)); + line_buffer = newchars.substr(pos + 1); + return line; +} + +// If the final line of the file ends without a end-of-line, return +// it as a line anyway. +static Optional SplitLineEOF(std::string _buffer) { + if (line_buffer.empty()) +return None; + if (std::all_of(line_buffer.begin(), line_buffer.end(), isspace)) +return None; + std::string line = std::move(line_buffer); + line_buffer.clear(); + return line; +} + bool IOHandlerEditline::GetLine(std::string , bool ) { #ifndef LLDB_DISABLE_LIBEDIT if (m_editline_up) { bool b = m_editline_up->GetLine(line, interrupted); -if (m_data_recorder) +if (b && m_data_recorder) m_data_recorder->Record(line, true); return b; - } else { + } #endif -line.clear(); -FILE *in = GetInputFILE(); -if (in) { - if (GetIsInteractive()) { -const char *prompt = nullptr; + line.clear(); -if (m_multi_line && m_curr_line_idx > 0) - prompt = GetContinuationPrompt(); + if (GetIsInteractive()) { +const char *prompt = nullptr; -if (prompt == nullptr) - prompt = GetPrompt(); +if (m_multi_line && m_curr_line_idx > 0) + prompt = GetContinuationPrompt(); -if (prompt && prompt[0]) { - if (m_output_sp) { -m_output_sp->Printf("%s", prompt); -m_output_sp->Flush(); - } -} +if (prompt == nullptr) + prompt = GetPrompt(); + +if (prompt && prompt[0]) { + if (m_output_sp) { +m_output_sp->Printf("%s", prompt); +m_output_sp->Flush(); + } +} + } + + Optional got_line = SplitLine(m_line_buffer); + + if (!got_line && !m_input_sp) { +// No more input file, we are done... +SetIsDone(true); +return false; + } + + FILE *in = GetInputFILE(); + char buffer[256]; + + if (!got_line && !in && m_input_sp) { +// there is no FILE*, fall back on just reading bytes from the stream. +while (!got_line) { + size_t bytes_read = sizeof(buffer); + Status error = m_input_sp->Read((void *)buffer, bytes_read); + if (error.Success() && !bytes_read) { +got_line = SplitLineEOF(m_line_buffer); +break; } - char buffer[256]; - bool done = false; - bool got_line = false; - m_editing = true; - while (!done) { + if (error.Fail()) +break; + got_line = + AppendAndSplitLine(m_line_buffer, StringRef(buffer, bytes_read)); +} + } + + if (!got_line && in) { +m_editing = true; +while (!got_line) { + char *r = fgets(buffer, sizeof(buffer), in); #ifdef _WIN32 -// ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED -// according to the docs on MSDN. However, this has evidently been a -// known bug since Windows 8. Therefore, we can't detect if a signal -// interrupted in the fgets. So pressing ctrl-c causes the repl to end -// and the process to exit. A temporary workaround is just to attempt to -// fgets twice until this bug is fixed. -if (fgets(buffer, sizeof(buffer), in) == nullptr && -fgets(buffer, sizeof(buffer), in) == nullptr) { - // this is the equivalent of EINTR for Windows - if (GetLastError() == ERROR_OPERATION_ABORTED) -
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
lawrence_danna updated this revision to Diff 223958. lawrence_danna added a comment. factor out string splitting stuff Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 Files: lldb/include/lldb/Core/IOHandler.h lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py lldb/source/Core/IOHandler.cpp Index: lldb/source/Core/IOHandler.cpp === --- lldb/source/Core/IOHandler.cpp +++ lldb/source/Core/IOHandler.cpp @@ -305,94 +305,145 @@ m_delegate.IOHandlerDeactivated(*this); } +using llvm::None; +using llvm::Optional; +using llvm::StringRef; + +// Split out a line from the buffer, if there is a full one to get. +static Optional SplitLine(std::string _buffer) { + size_t pos = line_buffer.find('\n'); + if (pos == std::string::npos) +return None; + size_t end = pos + 1; + while (end > 0 && + (line_buffer[end - 1] == '\n' || line_buffer[end - 1] == '\r')) +end--; + std::string line = line_buffer.substr(0, end); + line_buffer = line_buffer.substr(pos + 1); + return line; +} + +// Append newchars to the buffer and split out a line. +static Optional AppendAndSplitLine(std::string _buffer, +StringRef newchars) { + size_t pos = newchars.find('\n'); + if (pos == StringRef::npos) { +line_buffer.append(newchars); +return None; + } + size_t end = pos + 1; + while (end > 0 && (newchars[end - 1] == '\n' || newchars[end - 1] == '\r')) +end--; + std::string line = std::move(line_buffer); + line.append(newchars.substr(0, end)); + line_buffer = newchars.substr(pos + 1); + return line; +} + +// If the final line of the file ends without a end-of-line, return +// it as a line anyway. +static Optional SplitLineEOF(std::string _buffer) { + if (line_buffer.empty()) +return None; + if (std::all_of(line_buffer.begin(), line_buffer.end(), isspace)) +return None; + std::string line = std::move(line_buffer); + line_buffer.clear(); + return line; +} + bool IOHandlerEditline::GetLine(std::string , bool ) { #ifndef LLDB_DISABLE_LIBEDIT if (m_editline_up) { bool b = m_editline_up->GetLine(line, interrupted); -if (m_data_recorder) +if (b && m_data_recorder) m_data_recorder->Record(line, true); return b; - } else { + } #endif -line.clear(); -FILE *in = GetInputFILE(); -if (in) { - if (GetIsInteractive()) { -const char *prompt = nullptr; + line.clear(); -if (m_multi_line && m_curr_line_idx > 0) - prompt = GetContinuationPrompt(); + if (GetIsInteractive()) { +const char *prompt = nullptr; -if (prompt == nullptr) - prompt = GetPrompt(); +if (m_multi_line && m_curr_line_idx > 0) + prompt = GetContinuationPrompt(); -if (prompt && prompt[0]) { - if (m_output_sp) { -m_output_sp->Printf("%s", prompt); -m_output_sp->Flush(); - } -} +if (prompt == nullptr) + prompt = GetPrompt(); + +if (prompt && prompt[0]) { + if (m_output_sp) { +m_output_sp->Printf("%s", prompt); +m_output_sp->Flush(); + } +} + } + + Optional got_line = SplitLine(m_line_buffer); + + if (!got_line && !m_input_sp) { +// No more input file, we are done... +SetIsDone(true); +return false; + } + + FILE *in = GetInputFILE(); + char buffer[256]; + + if (!got_line && !in && m_input_sp) { +// there is no FILE*, fall back on just reading bytes from the stream. +while (!got_line) { + size_t bytes_read = sizeof(buffer); + Status error = m_input_sp->Read((void *)buffer, bytes_read); + if (error.Success() && !bytes_read) { +got_line = SplitLineEOF(m_line_buffer); +break; } - char buffer[256]; - bool done = false; - bool got_line = false; - m_editing = true; - while (!done) { + if (error.Fail()) +break; + got_line = + AppendAndSplitLine(m_line_buffer, StringRef(buffer, bytes_read)); +} + } + + if (!got_line && in) { +m_editing = true; +while (!got_line) { + char *r = fgets(buffer, sizeof(buffer), in); #ifdef _WIN32 -// ReadFile on Windows is supposed to set ERROR_OPERATION_ABORTED -// according to the docs on MSDN. However, this has evidently been a -// known bug since Windows 8. Therefore, we can't detect if a signal -// interrupted in the fgets. So pressing ctrl-c causes the repl to end -// and the process to exit. A temporary workaround is just to attempt to -// fgets twice until this bug is fixed. -if (fgets(buffer, sizeof(buffer), in) == nullptr && -fgets(buffer, sizeof(buffer), in) == nullptr) { - // this is the equivalent of EINTR for Windows - if (GetLastError() ==
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
labath added a comment. Even if we ignore the windows parts, there's still a lot of duplication here. The bits that extract a "complete" line from the buffer look like they could be factored into a separate function (`Optional GetCompleteLineFromCache(...)` ?). It would not hurt to split the parts that read from a FILE and the parts reading from the lldb_private::File into separate functions too... Other than that, the functionality seems fine to me... Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D68622/new/ https://reviews.llvm.org/D68622 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D68622: IOHandler: fall back on File::Read if a FILE* isn't available.
lawrence_danna created this revision. lawrence_danna added reviewers: JDevlieghere, jasonmolenda, labath, lanza. Herald added a project: LLDB. IOHandler needs to read lines of input from a lldb::File. The way it currently does this using, FILE*, which is something we want to avoid now. I'd prefer to just replace the FILE* code with calls to File::Read, but it contains an awkward and delicate workaround specific to ctrl-C handling on windows, and it's not clear if or how that workaround would translate to lldb::File. So in this patch, we use use the FILE* if it's available, and only fall back on File::Read if that's the only option. I think this is a reasonable approach here for two reasons. First is that interactive terminal support is the one area where FILE* can't be avoided. We need them for libedit and curses anyway, and using them here as well is consistent with that pattern. The second reason is that the comments express a hope that the underlying windows bug that's being worked around will be fixed one day, so hopefully when that happens, that whole path can be deleted. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D68622 Files: lldb/include/lldb/Core/IOHandler.h lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py lldb/source/Core/IOHandler.cpp Index: lldb/source/Core/IOHandler.cpp === --- lldb/source/Core/IOHandler.cpp +++ lldb/source/Core/IOHandler.cpp @@ -316,27 +316,71 @@ #endif line.clear(); +if (GetIsInteractive()) { + const char *prompt = nullptr; + + if (m_multi_line && m_curr_line_idx > 0) +prompt = GetContinuationPrompt(); + + if (prompt == nullptr) +prompt = GetPrompt(); + + if (prompt && prompt[0]) { +if (m_output_sp) { + m_output_sp->Printf("%s", prompt); + m_output_sp->Flush(); +} + } +} + FILE *in = GetInputFILE(); -if (in) { - if (GetIsInteractive()) { -const char *prompt = nullptr; +char buffer[256]; +bool done = false; +bool got_line = false; -if (m_multi_line && m_curr_line_idx > 0) - prompt = GetContinuationPrompt(); +if (!in && m_input_sp) { + // there is no FILE*, fall back on just reading bytes from the stream. -if (prompt == nullptr) - prompt = GetPrompt(); + size_t pos = m_line_buffer.find('\n'); + if (pos != std::string::npos) { +size_t end = pos; +while (end > 0 && + (m_line_buffer[end] == '\n' || m_line_buffer[end] == '\r')) + end--; +line = m_line_buffer.substr(0, end + 1); +m_line_buffer = m_line_buffer.substr(pos + 1); +done = true; +got_line = true; + } -if (prompt && prompt[0]) { - if (m_output_sp) { -m_output_sp->Printf("%s", prompt); -m_output_sp->Flush(); + while (!done) { +size_t bytes_read = sizeof(buffer); +m_input_sp->Read((void *)buffer, bytes_read); +if (bytes_read) { + auto bytes = llvm::StringRef(buffer, bytes_read); + size_t pos = bytes.find('\n'); + if (pos != llvm::StringRef::npos) { +size_t end = pos; +while (end > 0 && (bytes[end] == '\n' || bytes[end] == '\r')) + end--; +line = m_line_buffer; +line.append(bytes.substr(0, end + 1)); +m_line_buffer = bytes.substr(pos + 1); +done = true; +got_line = true; + } else { +m_line_buffer.append(bytes); } +} else { + // No more input file, we are done... + SetIsDone(true); + done = true; } } - char buffer[256]; - bool done = false; - bool got_line = false; + return got_line; +} + +if (in) { m_editing = true; while (!done) { #ifdef _WIN32 Index: lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py === --- lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py +++ lldb/packages/Python/lldbsuite/test/python_api/file_handle/TestFileHandle.py @@ -400,9 +400,9 @@ @add_test_categories(['pyapi']) -@expectedFailure # FIXME IOHandler still using FILE* +@skipIf(py_version=['<', (3,)]) def test_string_inout(self): -inf = io.StringIO("help help\n") +inf = io.StringIO("help help\np/x ~0\n") outf = io.StringIO() status = self.debugger.SetOutputFile(lldb.SBFile(outf)) self.assertTrue(status.Success()) @@ -413,10 +413,11 @@ self.debugger.GetOutputFile().Flush() output = outf.getvalue() self.assertIn('Show a list of all debugger commands', output) +self.assertIn('0xfff', output) @add_test_categories(['pyapi']) -