Make FileSpec::Dump use FileSpec::GetPath(), not the other way around.

Summary:
Fix FileSpec::Dump() to output denormalized path.

See D9942 for previous discussions.

Reviewers: zturner

Reviewed By: zturner

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D10077

llvm-svn: 238440
This commit is contained in:
Chaoren Lin 2015-05-28 17:02:45 +00:00
parent 3adf9b8d80
commit 1c614fedf9
2 changed files with 63 additions and 53 deletions

View File

@ -259,13 +259,9 @@ public:
///
/// @param[in] s
/// The stream to which to dump the object description.
///
/// @param[in] trailing_slash
/// If true and the file is a non root directory, then a trailing slash
/// will be added.
//------------------------------------------------------------------
void
Dump(Stream *s, bool trailing_slash = true) const;
Dump(Stream *s) const;
//------------------------------------------------------------------
/// Existence test.
@ -635,10 +631,6 @@ public:
lldb::DataBufferSP
ReadFileContentsAsCString(Error *error_ptr = NULL);
static void Normalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax = ePathSyntaxHostNative);
static void DeNormalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax = ePathSyntaxHostNative);
//------------------------------------------------------------------
/// Run through the input string, replaying the effect of any ".." and produce
/// the resultant path. The input path is not required to be in the host file system

View File

@ -47,7 +47,45 @@
using namespace lldb;
using namespace lldb_private;
static bool
namespace {
bool
PathSyntaxIsPosix(FileSpec::PathSyntax syntax)
{
return (syntax == FileSpec::ePathSyntaxPosix ||
(syntax == FileSpec::ePathSyntaxHostNative &&
FileSystem::GetNativePathSyntax() == FileSpec::ePathSyntaxPosix));
}
char
GetPathSeparator(FileSpec::PathSyntax syntax)
{
return PathSyntaxIsPosix(syntax) ? '/' : '\\';
}
void
Normalize(llvm::SmallVectorImpl<char> &path, FileSpec::PathSyntax syntax)
{
if (PathSyntaxIsPosix(syntax)) return;
std::replace(path.begin(), path.end(), '\\', '/');
// Windows path can have \\ slashes which can be changed by replace
// call above to //. Here we remove the duplicate.
auto iter = std::unique ( path.begin(), path.end(),
[]( char &c1, char &c2 ){
return (c1 == '/' && c2 == '/');});
path.erase(iter, path.end());
}
void
Denormalize(llvm::SmallVectorImpl<char> &path, FileSpec::PathSyntax syntax)
{
if (PathSyntaxIsPosix(syntax)) return;
std::replace(path.begin(), path.end(), '/', '\\');
}
bool
GetFileStats (const FileSpec *file_spec, struct stat *stats_ptr)
{
char resolved_path[PATH_MAX];
@ -56,6 +94,8 @@ GetFileStats (const FileSpec *file_spec, struct stat *stats_ptr)
return false;
}
}
// Resolves the username part of a path of the form ~user/other/directories, and
// writes the result into dst_path. This will also resolve "~" to the current user.
// If you want to complete "~" to the list of users, pass it to ResolvePartialUsername.
@ -252,30 +292,6 @@ FileSpec::operator= (const FileSpec& rhs)
return *this;
}
void FileSpec::Normalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax)
{
if (syntax == ePathSyntaxPosix ||
(syntax == ePathSyntaxHostNative && FileSystem::GetNativePathSyntax() == ePathSyntaxPosix))
return;
std::replace(path.begin(), path.end(), '\\', '/');
// Windows path can have \\ slashes which can be changed by replace
// call above to //. Here we remove the duplicate.
auto iter = std::unique ( path.begin(), path.end(),
[]( char &c1, char &c2 ){
return (c1 == '/' && c2 == '/');});
path.erase(iter, path.end());
}
void FileSpec::DeNormalize(llvm::SmallVectorImpl<char> &path, PathSyntax syntax)
{
if (syntax == ePathSyntaxPosix ||
(syntax == ePathSyntaxHostNative && FileSystem::GetNativePathSyntax() == ePathSyntaxPosix))
return;
std::replace(path.begin(), path.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
@ -609,15 +625,15 @@ FileSpec::RemoveBackupDots (const ConstString &input_const_str, ConstString &res
// directory delimiter, and the filename.
//------------------------------------------------------------------
void
FileSpec::Dump(Stream *s, bool trailing_slash) const
FileSpec::Dump(Stream *s) const
{
if (s)
{
m_directory.Dump(s);
if ((m_filename || trailing_slash) && m_directory &&
!m_directory.GetStringRef().endswith("/"))
s->PutChar('/');
m_filename.Dump(s);
std::string path{GetPath(true)};
s->PutCString(path.c_str());
char path_separator = GetPathSeparator(m_syntax);
if (!m_filename && !path.empty() && path.back() != path_separator)
s->PutChar(path_separator);
}
}
@ -816,12 +832,14 @@ FileSpec::GetPath(bool denormalize) const
void
FileSpec::GetPath(llvm::SmallVectorImpl<char> &path, bool denormalize) const
{
StreamString stream;
Dump(&stream, false);
path.append(stream.GetString().begin(), stream.GetString().end());
path.append(m_directory.GetStringRef().begin(), m_directory.GetStringRef().end());
if (m_directory)
path.insert(path.end(), '/');
path.append(m_filename.GetStringRef().begin(), m_filename.GetStringRef().end());
Normalize(path, m_syntax);
if (path.size() > 1 && path.back() == '/') path.pop_back();
if (denormalize && !path.empty())
DeNormalize(path, m_syntax);
Denormalize(path, m_syntax);
}
ConstString
@ -1383,15 +1401,7 @@ FileSpec::IsRelativeToCurrentWorkingDirectory () const
if (directory.size() > 0)
{
if (m_syntax == ePathSyntaxWindows)
{
if (directory.size() >= 2 && directory[1] == ':')
return false;
if (directory[0] == '/')
return false;
return true;
}
else
if (PathSyntaxIsPosix(m_syntax))
{
// If the path doesn't start with '/' or '~', return true
switch (directory[0])
@ -1403,6 +1413,14 @@ FileSpec::IsRelativeToCurrentWorkingDirectory () const
return true;
}
}
else
{
if (directory.size() >= 2 && directory[1] == ':')
return false;
if (directory[0] == '/')
return false;
return true;
}
}
else if (m_filename)
{