diff options
Diffstat (limited to 'lldb/source/Host/common')
| -rw-r--r-- | lldb/source/Host/common/Editline.cpp | 30 | ||||
| -rw-r--r-- | lldb/source/Host/common/File.cpp | 34 | ||||
| -rw-r--r-- | lldb/source/Host/common/HostInfoBase.cpp | 38 |
3 files changed, 84 insertions, 18 deletions
diff --git a/lldb/source/Host/common/Editline.cpp b/lldb/source/Host/common/Editline.cpp index 5ed30fbb231d..1b1922e71076 100644 --- a/lldb/source/Host/common/Editline.cpp +++ b/lldb/source/Host/common/Editline.cpp @@ -10,10 +10,8 @@ #include <iomanip> #include <optional> -#include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Editline.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Host/StreamFile.h" #include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/CompletionRequest.h" @@ -100,11 +98,6 @@ bool IsOnlySpaces(const EditLineStringType &content) { return true; } -static size_t ColumnWidth(llvm::StringRef str) { - std::string stripped = ansi::StripAnsiTerminalCodes(str); - return llvm::sys::locale::columnWidth(stripped); -} - static int GetOperation(HistoryOperation op) { // The naming used by editline for the history operations is counter // intuitive to how it's used in LLDB's editline implementation. @@ -219,20 +212,19 @@ private: const char *GetHistoryFilePath() { // Compute the history path lazily. if (m_path.empty() && m_history && !m_prefix.empty()) { - llvm::SmallString<128> lldb_history_file; - FileSystem::Instance().GetHomeDirectory(lldb_history_file); - llvm::sys::path::append(lldb_history_file, ".lldb"); + FileSpec lldb_dir = HostInfo::GetUserLLDBDir(); // 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 (!llvm::sys::fs::create_directory(lldb_dir.GetPath())) { #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()); + FileSpec lldb_history_file = + lldb_dir.CopyByAppendingPathComponent(filename); + m_path = lldb_history_file.GetPath(); } } @@ -332,8 +324,8 @@ std::string Editline::PromptForIndex(int line_index) { if (m_set_continuation_prompt.length() > 0) { continuation_prompt = m_set_continuation_prompt; // Ensure that both prompts are the same length through space padding - const size_t prompt_width = ColumnWidth(prompt); - const size_t cont_prompt_width = ColumnWidth(continuation_prompt); + const size_t prompt_width = ansi::ColumnWidth(prompt); + const size_t cont_prompt_width = ansi::ColumnWidth(continuation_prompt); const size_t padded_prompt_width = std::max(prompt_width, cont_prompt_width); if (prompt_width < padded_prompt_width) @@ -358,7 +350,9 @@ void Editline::SetCurrentLine(int line_index) { m_current_prompt = PromptForIndex(line_index); } -size_t Editline::GetPromptWidth() { return ColumnWidth(PromptForIndex(0)); } +size_t Editline::GetPromptWidth() { + return ansi::ColumnWidth(PromptForIndex(0)); +} bool Editline::IsEmacs() { const char *editor; @@ -448,7 +442,7 @@ void Editline::DisplayInput(int firstIndex) { 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() + ColumnWidth(prompt)); + int line_length = (int)(content.length() + ansi::ColumnWidth(prompt)); return (line_length / m_terminal_width) + 1; } diff --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp index 23b6dc9fe850..8fd1ca069dc0 100644 --- a/lldb/source/Host/common/File.cpp +++ b/lldb/source/Host/common/File.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Process.h" +#include "llvm/Support/raw_ostream.h" using namespace lldb; using namespace lldb_private; @@ -247,6 +248,32 @@ uint32_t File::GetPermissions(Status &error) const { return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); } +NativeFile::NativeFile() = default; + +NativeFile::NativeFile(FILE *fh, bool transfer_ownership) + : m_stream(fh), m_own_stream(transfer_ownership) { +#ifdef _WIN32 + // In order to properly display non ASCII characters in Windows, we need to + // use Windows APIs to print to the console. This is only required if the + // stream outputs to a console. + int fd = _fileno(fh); + is_windows_console = + ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR; +#endif +} + +NativeFile::NativeFile(int fd, OpenOptions options, bool transfer_ownership) + : m_descriptor(fd), m_own_descriptor(transfer_ownership), + m_options(options) { +#ifdef _WIN32 + // In order to properly display non ASCII characters in Windows, we need to + // use Windows APIs to print to the console. This is only required if the + // file outputs to a console. + is_windows_console = + ::GetFileType((HANDLE)::_get_osfhandle(fd)) == FILE_TYPE_CHAR; +#endif +} + bool NativeFile::IsValid() const { std::scoped_lock<std::mutex, std::mutex> lock(m_descriptor_mutex, m_stream_mutex); return DescriptorIsValidUnlocked() || StreamIsValidUnlocked(); @@ -629,6 +656,13 @@ Status NativeFile::Write(const void *buf, size_t &num_bytes) { } if (ValueGuard stream_guard = StreamIsValid()) { +#ifdef _WIN32 + if (is_windows_console) { + llvm::raw_fd_ostream(_fileno(m_stream), false) + .write((char *)buf, num_bytes); + return error; + } +#endif bytes_written = ::fwrite(buf, 1, num_bytes, m_stream); if (bytes_written == 0) { diff --git a/lldb/source/Host/common/HostInfoBase.cpp b/lldb/source/Host/common/HostInfoBase.cpp index 89dfe4a9e9ba..a02ac77df66a 100644 --- a/lldb/source/Host/common/HostInfoBase.cpp +++ b/lldb/source/Host/common/HostInfoBase.cpp @@ -61,6 +61,10 @@ struct HostInfoBaseFields { FileSpec m_lldb_clang_resource_dir; llvm::once_flag m_lldb_system_plugin_dir_once; FileSpec m_lldb_system_plugin_dir; + llvm::once_flag m_lldb_user_home_dir_once; + FileSpec m_lldb_user_home_dir; + llvm::once_flag m_lldb_user_lldb_dir_once; + FileSpec m_lldb_user_lldb_dir; llvm::once_flag m_lldb_user_plugin_dir_once; FileSpec m_lldb_user_plugin_dir; llvm::once_flag m_lldb_process_tmp_dir_once; @@ -161,6 +165,26 @@ FileSpec HostInfoBase::GetSystemPluginDir() { return g_fields->m_lldb_system_plugin_dir; } +FileSpec HostInfoBase::GetUserHomeDir() { + llvm::call_once(g_fields->m_lldb_user_home_dir_once, []() { + if (!HostInfo::ComputeUserHomeDirectory(g_fields->m_lldb_user_home_dir)) + g_fields->m_lldb_user_home_dir = FileSpec(); + LLDB_LOG(GetLog(LLDBLog::Host), "user home dir -> `{0}`", + g_fields->m_lldb_user_home_dir); + }); + return g_fields->m_lldb_user_home_dir; +} + +FileSpec HostInfoBase::GetUserLLDBDir() { + llvm::call_once(g_fields->m_lldb_user_lldb_dir_once, []() { + if (!HostInfo::ComputeUserLLDBHomeDirectory(g_fields->m_lldb_user_lldb_dir)) + g_fields->m_lldb_user_lldb_dir = FileSpec(); + LLDB_LOG(GetLog(LLDBLog::Host), "user lldb home dir -> `{0}`", + g_fields->m_lldb_user_lldb_dir); + }); + return g_fields->m_lldb_user_lldb_dir; +} + FileSpec HostInfoBase::GetUserPluginDir() { llvm::call_once(g_fields->m_lldb_user_plugin_dir_once, []() { if (!HostInfo::ComputeUserPluginsDirectory( @@ -316,6 +340,20 @@ bool HostInfoBase::ComputeSystemPluginsDirectory(FileSpec &file_spec) { return false; } +bool HostInfoBase::ComputeUserHomeDirectory(FileSpec &file_spec) { + FileSpec temp_file("~"); + FileSystem::Instance().Resolve(temp_file); + file_spec.SetDirectory(temp_file.GetPathAsConstString()); + return true; +} + +bool HostInfoBase::ComputeUserLLDBHomeDirectory(FileSpec &file_spec) { + FileSpec home_dir_spec = GetUserHomeDir(); + home_dir_spec.AppendPathComponent(".lldb"); + file_spec.SetDirectory(home_dir_spec.GetPathAsConstString()); + return true; +} + bool HostInfoBase::ComputeUserPluginsDirectory(FileSpec &file_spec) { // TODO(zturner): Figure out how to compute the user plugins directory for // all platforms. |
