diff options
-rw-r--r-- | lldb/include/lldb/Host/FileSpec.h | 23 | ||||
-rw-r--r-- | lldb/include/lldb/Host/Host.h | 9 | ||||
-rw-r--r-- | lldb/source/Host/common/FileSpec.cpp | 109 | ||||
-rw-r--r-- | lldb/source/Host/common/Host.cpp | 10 |
4 files changed, 102 insertions, 49 deletions
diff --git a/lldb/include/lldb/Host/FileSpec.h b/lldb/include/lldb/Host/FileSpec.h index 70465f32600..6dfb9d4e134 100644 --- a/lldb/include/lldb/Host/FileSpec.h +++ b/lldb/include/lldb/Host/FileSpec.h @@ -51,6 +51,13 @@ public: eFileTypeOther } FileType; + enum PathSyntax + { + ePathSyntaxPosix, + ePathSyntaxWindows, + ePathSyntaxHostNative + }; + FileSpec(); //------------------------------------------------------------------ @@ -69,7 +76,7 @@ public: /// /// @see FileSpec::SetFile (const char *path, bool resolve) //------------------------------------------------------------------ - explicit FileSpec (const char *path, bool resolve_path); + explicit FileSpec (const char *path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative); //------------------------------------------------------------------ /// Copy constructor @@ -291,6 +298,9 @@ public: uint64_t GetByteSize() const; + PathSyntax + GetPathSyntax() const; + //------------------------------------------------------------------ /// Directory string get accessor. /// @@ -375,7 +385,7 @@ public: /// still NULL terminated). //------------------------------------------------------------------ size_t - GetPath (char *path, size_t max_path_length) const; + GetPath (char *path, size_t max_path_length, bool denormalize = true) const; //------------------------------------------------------------------ /// Extract the full path to the file. @@ -387,7 +397,7 @@ public: /// concatenated. //------------------------------------------------------------------ std::string - GetPath () const; + GetPath (bool denormalize = true) const; //------------------------------------------------------------------ /// Extract the extension of the file. @@ -559,6 +569,10 @@ public: //------------------------------------------------------------------ lldb::DataBufferSP ReadFileContentsAsCString(Error *error_ptr = NULL); + + static void Normalize(llvm::StringRef path, llvm::SmallVectorImpl<char> &result, PathSyntax syntax); + static void DeNormalize(llvm::StringRef path, llvm::SmallVectorImpl<char> &result, PathSyntax syntax); + //------------------------------------------------------------------ /// Change the file specified with a new path. /// @@ -574,7 +588,7 @@ public: /// the static FileSpec::Resolve. //------------------------------------------------------------------ void - SetFile (const char *path, bool resolve_path); + SetFile (const char *path, bool resolve_path, PathSyntax syntax = ePathSyntaxHostNative); bool IsResolved () const @@ -709,6 +723,7 @@ protected: ConstString m_directory; ///< The uniqued directory path ConstString m_filename; ///< The uniqued filename path mutable bool m_is_resolved; ///< True if this path has been resolved. + PathSyntax m_syntax; ///< The syntax that this path uses (e.g. Windows / Posix) }; //---------------------------------------------------------------------- diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h index aa934d9fe7f..c937a60cdfb 100644 --- a/lldb/include/lldb/Host/Host.h +++ b/lldb/include/lldb/Host/Host.h @@ -362,6 +362,15 @@ public: SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name, size_t len); //------------------------------------------------------------------ + /// Gets the host environment's native path syntax (Windows / Posix). + /// + /// @return + /// \b One of {FileSpec::ePathSyntaxWindows, FileSpec::ePathSyntaxPosix} + //------------------------------------------------------------------ + static FileSpec::PathSyntax + GetHostPathSyntax(); + + //------------------------------------------------------------------ /// Gets the FileSpec of the user profile directory. On Posix-platforms /// this is ~, and on windows this is generally something like /// C:\Users\Alice. diff --git a/lldb/source/Host/common/FileSpec.cpp b/lldb/source/Host/common/FileSpec.cpp index 44eb3af118f..845a3183001 100644 --- a/lldb/source/Host/common/FileSpec.cpp +++ b/lldb/source/Host/common/FileSpec.cpp @@ -229,7 +229,8 @@ FileSpec::Resolve (const char *src_path, char *dst_path, size_t dst_len) FileSpec::FileSpec() : m_directory(), - m_filename() + m_filename(), + m_syntax(Host::GetHostPathSyntax()) { } @@ -237,13 +238,13 @@ FileSpec::FileSpec() : // Default constructor that can take an optional full path to a // file on disk. //------------------------------------------------------------------ -FileSpec::FileSpec(const char *pathname, bool resolve_path) : +FileSpec::FileSpec(const char *pathname, bool resolve_path, PathSyntax syntax) : m_directory(), m_filename(), m_is_resolved(false) { if (pathname && pathname[0]) - SetFile(pathname, resolve_path); + SetFile(pathname, resolve_path, syntax); } //------------------------------------------------------------------ @@ -252,7 +253,8 @@ FileSpec::FileSpec(const char *pathname, bool resolve_path) : FileSpec::FileSpec(const FileSpec& rhs) : m_directory (rhs.m_directory), m_filename (rhs.m_filename), - m_is_resolved (rhs.m_is_resolved) + m_is_resolved (rhs.m_is_resolved), + m_syntax (rhs.m_syntax) { } @@ -285,46 +287,71 @@ FileSpec::operator= (const FileSpec& rhs) m_directory = rhs.m_directory; m_filename = rhs.m_filename; m_is_resolved = rhs.m_is_resolved; + m_syntax = rhs.m_syntax; } return *this; } +void FileSpec::Normalize(llvm::StringRef path, llvm::SmallVectorImpl<char> &result, PathSyntax syntax) +{ + result.clear(); + result.append(path.begin(), path.end()); + if (syntax == ePathSyntaxPosix || (syntax == ePathSyntaxHostNative && Host::GetHostPathSyntax() == ePathSyntaxPosix)) + return; + + std::replace(result.begin(), result.end(), '\\', '/'); +} + +void FileSpec::DeNormalize(llvm::StringRef path, llvm::SmallVectorImpl<char> &result, PathSyntax syntax) +{ + result.clear(); + result.append(path.begin(), path.end()); + if (syntax == ePathSyntaxPosix || (syntax == ePathSyntaxHostNative && Host::GetHostPathSyntax() == ePathSyntaxPosix)) + return; + + std::replace(result.begin(), result.end(), '/', '\\'); +} + //------------------------------------------------------------------ // Update the contents of this object with a new path. The path will // be split up into a directory and filename and stored as uniqued // string values for quick comparison and efficient memory usage. //------------------------------------------------------------------ void -FileSpec::SetFile (const char *pathname, bool resolve) +FileSpec::SetFile (const char *pathname, bool resolve, PathSyntax syntax) { m_filename.Clear(); m_directory.Clear(); m_is_resolved = false; + m_syntax = (syntax == ePathSyntaxHostNative) ? Host::GetHostPathSyntax() : syntax; + if (pathname == NULL || pathname[0] == '\0') return; - char resolved_path[PATH_MAX]; + llvm::SmallString<64> normalized; + Normalize(pathname, normalized, syntax); + + std::vector<char> resolved_path(PATH_MAX); bool path_fit = true; if (resolve) { - path_fit = (FileSpec::Resolve (pathname, resolved_path, sizeof(resolved_path)) < sizeof(resolved_path) - 1); + path_fit = (FileSpec::Resolve (normalized.c_str(), &resolved_path[0], resolved_path.size()) < resolved_path.size() - 1); m_is_resolved = path_fit; } else { // Copy the path because "basename" and "dirname" want to muck with the // path buffer - if (::strlen (pathname) > sizeof(resolved_path) - 1) + if (normalized.size() > resolved_path.size() - 1) path_fit = false; else - ::strcpy (resolved_path, pathname); + ::strcpy (&resolved_path[0], normalized.c_str()); } - if (path_fit) { - llvm::StringRef resolve_path_ref(resolved_path); + llvm::StringRef resolve_path_ref(&resolved_path[0]); llvm::StringRef filename_ref = llvm::sys::path::filename(resolve_path_ref); if (!filename_ref.empty()) { @@ -334,7 +361,7 @@ FileSpec::SetFile (const char *pathname, bool resolve) m_directory.SetString(directory_ref); } else - m_directory.SetCString(resolved_path); + m_directory.SetCString(&resolved_path[0]); } } @@ -580,7 +607,7 @@ FileSpec::ResolvePath () return true; // We have already resolved this path char path_buf[PATH_MAX]; - if (!GetPath (path_buf, PATH_MAX)) + if (!GetPath (path_buf, PATH_MAX, false)) return false; // SetFile(...) will set m_is_resolved correctly if it can resolve the path SetFile (path_buf, true); @@ -596,6 +623,12 @@ FileSpec::GetByteSize() const return 0; } +FileSpec::PathSyntax +FileSpec::GetPathSyntax() const +{ + return m_syntax; +} + FileSpec::FileType FileSpec::GetFileType () const { @@ -681,45 +714,31 @@ FileSpec::GetFilename() const // values. //------------------------------------------------------------------ size_t -FileSpec::GetPath(char *path, size_t path_max_len) const +FileSpec::GetPath(char *path, size_t path_max_len, bool denormalize) const { - if (path_max_len) - { - const char *dirname = m_directory.GetCString(); - const char *filename = m_filename.GetCString(); - if (dirname) - { - if (filename) - return ::snprintf (path, path_max_len, "%s/%s", dirname, filename); - else - return ::snprintf (path, path_max_len, "%s", dirname); - } - else if (filename) - { - return ::snprintf (path, path_max_len, "%s", filename); - } - } - if (path) - path[0] = '\0'; - return 0; + std::string result = GetPath(denormalize); + + size_t result_length = std::min(path_max_len-1, result.length()); + ::strncpy(path, result.c_str(), result_length + 1); + return result_length; } std::string -FileSpec::GetPath (void) const +FileSpec::GetPath (bool denormalize) const { - static ConstString g_slash_only ("/"); - std::string path; - const char *dirname = m_directory.GetCString(); - const char *filename = m_filename.GetCString(); - if (dirname) + llvm::SmallString<64> result; + if (m_directory) + result.append(m_directory.GetCString()); + if (m_filename) + llvm::sys::path::append(result, m_filename.GetCString()); + if (denormalize && !result.empty()) { - path.append (dirname); - if (filename && m_directory != g_slash_only) - path.append ("/"); + llvm::SmallString<64> denormalized; + DeNormalize(result.c_str(), denormalized, m_syntax); + result = denormalized; } - if (filename) - path.append (filename); - return path; + + return std::string(result.begin(), result.end()); } ConstString diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index df1c78726b6..a19608365ec 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -839,6 +839,16 @@ Host::SetShortThreadName (lldb::pid_t pid, lldb::tid_t tid, #endif +FileSpec::PathSyntax +Host::GetHostPathSyntax() +{ +#if defined(_WIN32) + return FileSpec::ePathSyntaxWindows; +#else + return FileSpec::ePathSyntaxPosix; +#endif +} + FileSpec Host::GetUserProfileFileSpec () { |