[Lldb-commits] [lldb] r215123 - Fix FileSpec to be able to understand Windows paths.
Zachary Turner
zturner at google.com
Thu Aug 7 10:33:08 PDT 2014
Author: zturner
Date: Thu Aug 7 12:33:07 2014
New Revision: 215123
URL: http://llvm.org/viewvc/llvm-project?rev=215123&view=rev
Log:
Fix FileSpec to be able to understand Windows paths.
This patch adds the notion of a "path syntax" to FileSpec. There
are two syntaxes (Posix and Windows) and one "meta syntax",
Host Native, which uses the current platform to figure out the
appropriate syntax for host paths.
This allows paths from one platform to be represented and
manipulated on another platform even if they have different path
syntaxes.
Modified:
lldb/trunk/include/lldb/Host/FileSpec.h
lldb/trunk/include/lldb/Host/Host.h
lldb/trunk/source/Host/common/FileSpec.cpp
lldb/trunk/source/Host/common/Host.cpp
Modified: lldb/trunk/include/lldb/Host/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSpec.h?rev=215123&r1=215122&r2=215123&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/FileSpec.h (original)
+++ lldb/trunk/include/lldb/Host/FileSpec.h Thu Aug 7 12:33:07 2014
@@ -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)
};
//----------------------------------------------------------------------
Modified: lldb/trunk/include/lldb/Host/Host.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=215123&r1=215122&r2=215123&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/Host.h (original)
+++ lldb/trunk/include/lldb/Host/Host.h Thu Aug 7 12:33:07 2014
@@ -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.
Modified: lldb/trunk/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=215123&r1=215122&r2=215123&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/FileSpec.cpp (original)
+++ lldb/trunk/source/Host/common/FileSpec.cpp Thu Aug 7 12:33:07 2014
@@ -229,7 +229,8 @@ FileSpec::Resolve (const char *src_path,
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,
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,
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
Modified: lldb/trunk/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Host.cpp?rev=215123&r1=215122&r2=215123&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/Host.cpp (original)
+++ lldb/trunk/source/Host/common/Host.cpp Thu Aug 7 12:33:07 2014
@@ -839,6 +839,16 @@ Host::SetShortThreadName (lldb::pid_t pi
#endif
+FileSpec::PathSyntax
+Host::GetHostPathSyntax()
+{
+#if defined(_WIN32)
+ return FileSpec::ePathSyntaxWindows;
+#else
+ return FileSpec::ePathSyntaxPosix;
+#endif
+}
+
FileSpec
Host::GetUserProfileFileSpec ()
{
More information about the lldb-commits
mailing list