summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2014-08-07 17:33:07 +0000
committerZachary Turner <zturner@google.com>2014-08-07 17:33:07 +0000
commitdf62f20c75d0984aac06b8b998988eb91262e43c (patch)
tree9ae54a149637a5998f3b030aabd71cb95e7406f5 /lldb/source
parent17ae2fca4ca0bf8396af7cec68b376efcfe0e63e (diff)
downloadbcm5719-llvm-df62f20c75d0984aac06b8b998988eb91262e43c.tar.gz
bcm5719-llvm-df62f20c75d0984aac06b8b998988eb91262e43c.zip
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. llvm-svn: 215123
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Host/common/FileSpec.cpp109
-rw-r--r--lldb/source/Host/common/Host.cpp10
2 files changed, 74 insertions, 45 deletions
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 ()
{
OpenPOWER on IntegriCloud