///
/// @see FileSpec::SetFile (const char *path, bool resolve)
//------------------------------------------------------------------
- // TODO: Convert this constructor to use a StringRef.
- explicit FileSpec(const char *path, bool resolve_path,
+ explicit FileSpec(llvm::StringRef path, bool resolve_path,
PathSyntax syntax = ePathSyntaxHostNative);
- explicit FileSpec(const char *path, bool resolve_path, ArchSpec arch);
-
- explicit FileSpec(const std::string &path, bool resolve_path,
- PathSyntax syntax = ePathSyntaxHostNative);
-
- explicit FileSpec(const std::string &path, bool resolve_path, ArchSpec arch);
+ explicit FileSpec(llvm::StringRef path, bool resolve_path, ArchSpec arch);
//------------------------------------------------------------------
/// Copy constructor
/// If \b true, then we will try to resolve links the path using
/// the static FileSpec::Resolve.
//------------------------------------------------------------------
- void SetFile(const char *path, bool resolve_path,
- PathSyntax syntax = ePathSyntaxHostNative);
-
- void SetFile(const char *path, bool resolve_path, ArchSpec arch);
-
- void SetFile(const std::string &path, bool resolve_path,
+ void SetFile(llvm::StringRef path, bool resolve_path,
PathSyntax syntax = ePathSyntaxHostNative);
- void SetFile(const std::string &path, bool resolve_path, ArchSpec arch);
+ void SetFile(llvm::StringRef path, bool resolve_path, ArchSpec arch);
bool IsResolved() const { return m_is_resolved; }
//------------------------------------------------------------------
static void Resolve(llvm::SmallVectorImpl<char> &path);
- FileSpec CopyByAppendingPathComponent(const char *new_path) const;
-
+ FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const;
FileSpec CopyByRemovingLastPathComponent() const;
- void PrependPathComponent(const char *new_path);
-
- void PrependPathComponent(const std::string &new_path);
-
+ void PrependPathComponent(llvm::StringRef component);
void PrependPathComponent(const FileSpec &new_path);
- void AppendPathComponent(const char *new_path);
-
- void AppendPathComponent(const std::string &new_path);
-
+ void AppendPathComponent(llvm::StringRef component);
void AppendPathComponent(const FileSpec &new_path);
void RemoveLastPathComponent();
//------------------------------------------------------------------
static void ResolveUsername(llvm::SmallVectorImpl<char> &path);
- static size_t ResolvePartialUsername(const char *partial_name,
+ static size_t ResolvePartialUsername(llvm::StringRef partial_name,
StringList &matches);
enum EnumerateDirectoryResult {
void *baton, FileType file_type, const FileSpec &spec);
static EnumerateDirectoryResult
- EnumerateDirectory(const char *dir_path, bool find_directories,
+ EnumerateDirectory(llvm::StringRef dir_path, bool find_directories,
bool find_files, bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton);
DirectoryCallback;
static EnumerateDirectoryResult
- ForEachItemInDirectory(const char *dir_path,
+ ForEachItemInDirectory(llvm::StringRef dir_path,
DirectoryCallback const &callback);
protected:
#include "lldb/Host/Host.h"
#include "lldb/Utility/CleanUp.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
return PathSyntaxIsPosix(syntax) ? "/" : "\\/";
}
-char GetPrefferedPathSeparator(FileSpec::PathSyntax syntax) {
+char GetPreferredPathSeparator(FileSpec::PathSyntax syntax) {
return GetPathSeparators(syntax)[0];
}
#endif
}
-size_t FileSpec::ResolvePartialUsername(const char *partial_name,
+size_t FileSpec::ResolvePartialUsername(llvm::StringRef partial_name,
StringList &matches) {
#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
size_t extant_entries = matches.GetSize();
setpwent();
struct passwd *user_entry;
- const char *name_start = partial_name + 1;
+ partial_name = partial_name.drop_front();
std::set<std::string> name_list;
while ((user_entry = getpwent()) != NULL) {
- if (strstr(user_entry->pw_name, name_start) == user_entry->pw_name) {
+ if (llvm::StringRef(user_entry->pw_name).startswith(partial_name)) {
std::string tmp_buf("~");
tmp_buf.append(user_entry->pw_name);
tmp_buf.push_back('/');
name_list.insert(tmp_buf);
}
}
- std::set<std::string>::iterator pos, end = name_list.end();
- for (pos = name_list.begin(); pos != end; pos++) {
- matches.AppendString((*pos).c_str());
+
+ for (auto &name : name_list) {
+ matches.AppendString(name);
}
return matches.GetSize() - extant_entries;
#else
// Default constructor that can take an optional full path to a
// file on disk.
//------------------------------------------------------------------
-FileSpec::FileSpec(const char *pathname, bool resolve_path, PathSyntax syntax)
+FileSpec::FileSpec(llvm::StringRef path, bool resolve_path, PathSyntax syntax)
: m_directory(), m_filename(), m_is_resolved(false), m_syntax(syntax) {
- if (pathname && pathname[0])
- SetFile(pathname, resolve_path, syntax);
+ SetFile(path, resolve_path, syntax);
}
-FileSpec::FileSpec(const char *pathname, bool resolve_path, ArchSpec arch)
- : FileSpec{pathname, resolve_path, arch.GetTriple().isOSWindows()
- ? ePathSyntaxWindows
- : ePathSyntaxPosix} {}
-
-FileSpec::FileSpec(const std::string &path, bool resolve_path,
- PathSyntax syntax)
- : FileSpec{path.c_str(), resolve_path, syntax} {}
-
-FileSpec::FileSpec(const std::string &path, bool resolve_path, ArchSpec arch)
- : FileSpec{path.c_str(), resolve_path, arch} {}
+FileSpec::FileSpec(llvm::StringRef path, bool resolve_path, ArchSpec arch)
+ : FileSpec{path, resolve_path, arch.GetTriple().isOSWindows()
+ ? ePathSyntaxWindows
+ : ePathSyntaxPosix} {}
//------------------------------------------------------------------
// Copy constructor
// 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, PathSyntax syntax) {
+void FileSpec::SetFile(llvm::StringRef pathname, bool resolve,
+ PathSyntax syntax) {
+ // CLEANUP: Use StringRef for string handling. This function is kind of a
+ // mess and the unclear semantics of RootDirStart and ParentPathEnd make
+ // it very difficult to understand this function. There's no reason this
+ // function should be particularly complicated or difficult to understand.
m_filename.Clear();
m_directory.Clear();
m_is_resolved = false;
? FileSystem::GetNativePathSyntax()
: syntax;
- if (pathname == NULL || pathname[0] == '\0')
+ if (pathname.empty())
return;
llvm::SmallString<64> resolved(pathname);
: resolve_path_ref.substr(filename_begin));
}
-void FileSpec::SetFile(const char *pathname, bool resolve, ArchSpec arch) {
- return SetFile(pathname, resolve, arch.GetTriple().isOSWindows()
- ? ePathSyntaxWindows
- : ePathSyntaxPosix);
-}
-
-void FileSpec::SetFile(const std::string &pathname, bool resolve,
- PathSyntax syntax) {
- return SetFile(pathname.c_str(), resolve, syntax);
-}
-
-void FileSpec::SetFile(const std::string &pathname, bool resolve,
- ArchSpec arch) {
- return SetFile(pathname.c_str(), resolve, arch);
+void FileSpec::SetFile(llvm::StringRef path, bool resolve, ArchSpec arch) {
+ return SetFile(path, resolve, arch.GetTriple().isOSWindows()
+ ? ePathSyntaxWindows
+ : ePathSyntaxPosix);
}
//----------------------------------------------------------------------
if (s) {
std::string path{GetPath(true)};
s->PutCString(path.c_str());
- char path_separator = GetPrefferedPathSeparator(m_syntax);
+ char path_separator = GetPreferredPathSeparator(m_syntax);
if (!m_filename && !path.empty() && path.back() != path_separator)
s->PutChar(path_separator);
}
}
bool FileSpec::ResolveExecutableLocation() {
+ // CLEANUP: Use StringRef for string handling.
if (!m_directory) {
const char *file_cstr = m_filename.GetCString();
if (file_cstr) {
m_directory.GetStringRef().end());
if (m_directory && m_filename &&
!IsPathSeparator(m_directory.GetStringRef().back(), m_syntax))
- path.insert(path.end(), GetPrefferedPathSeparator(m_syntax));
+ path.insert(path.end(), GetPreferredPathSeparator(m_syntax));
path.append(m_filename.GetStringRef().begin(),
m_filename.GetStringRef().end());
Normalize(path, m_syntax);
}
FileSpec::EnumerateDirectoryResult
-FileSpec::ForEachItemInDirectory(const char *dir_path,
+FileSpec::ForEachItemInDirectory(llvm::StringRef dir_path,
DirectoryCallback const &callback) {
- if (dir_path && dir_path[0]) {
+ if (dir_path.empty())
+ return eEnumerateDirectoryResultNext;
+
#ifdef _WIN32
std::string szDir(dir_path);
szDir += "\\*";
continue;
}
- std::vector<char> child_path(PATH_MAX);
- const int child_path_len =
- ::snprintf(child_path.data(), child_path.size(), "%s\\%s", dir_path,
- fileName.c_str());
- if (child_path_len < (int)(child_path.size() - 1)) {
- // Don't resolve the file type or path
- FileSpec child_path_spec(child_path.data(), false);
-
- EnumerateDirectoryResult result = callback(file_type, child_path_spec);
-
- switch (result) {
- case eEnumerateDirectoryResultNext:
- // Enumerate next entry in the current directory. We just
- // exit this switch and will continue enumerating the
- // current directory as we currently are...
- break;
+ std::string child_path = llvm::join_items("\\", dir_path, fileName);
+ // Don't resolve the file type or path
+ FileSpec child_path_spec(child_path.data(), false);
- case eEnumerateDirectoryResultEnter: // Recurse into the current entry
- // if it is a directory or symlink,
- // or next if not
- if (FileSpec::ForEachItemInDirectory(child_path.data(), callback) ==
- eEnumerateDirectoryResultQuit) {
- // The subdirectory returned Quit, which means to
- // stop all directory enumerations at all levels.
- return eEnumerateDirectoryResultQuit;
- }
- break;
+ EnumerateDirectoryResult result = callback(file_type, child_path_spec);
- case eEnumerateDirectoryResultExit: // Exit from the current directory
- // at the current level.
- // Exit from this directory level and tell parent to
- // keep enumerating.
- return eEnumerateDirectoryResultNext;
+ switch (result) {
+ case eEnumerateDirectoryResultNext:
+ // Enumerate next entry in the current directory. We just
+ // exit this switch and will continue enumerating the
+ // current directory as we currently are...
+ break;
- case eEnumerateDirectoryResultQuit: // Stop directory enumerations at
- // any level
+ case eEnumerateDirectoryResultEnter: // Recurse into the current entry
+ // if it is a directory or symlink,
+ // or next if not
+ if (FileSpec::ForEachItemInDirectory(child_path.data(), callback) ==
+ eEnumerateDirectoryResultQuit) {
+ // The subdirectory returned Quit, which means to
+ // stop all directory enumerations at all levels.
return eEnumerateDirectoryResultQuit;
}
+ break;
+
+ case eEnumerateDirectoryResultExit: // Exit from the current directory
+ // at the current level.
+ // Exit from this directory level and tell parent to
+ // keep enumerating.
+ return eEnumerateDirectoryResultNext;
+
+ case eEnumerateDirectoryResultQuit: // Stop directory enumerations at
+ // any level
+ return eEnumerateDirectoryResultQuit;
}
} while (FindNextFileW(hFind, &ffd) != 0);
FindClose(hFind);
#else
- lldb_utility::CleanUp<DIR *, int> dir_path_dir(opendir(dir_path), NULL,
- closedir);
- if (dir_path_dir.is_valid()) {
- char dir_path_last_char = dir_path[strlen(dir_path) - 1];
+ std::string dir_string(dir_path);
+ lldb_utility::CleanUp<DIR *, int> dir_path_dir(opendir(dir_string.c_str()),
+ NULL, closedir);
+ if (dir_path_dir.is_valid()) {
+ char dir_path_last_char = dir_path.back();
- long path_max = fpathconf(dirfd(dir_path_dir.get()), _PC_NAME_MAX);
+ long path_max = fpathconf(dirfd(dir_path_dir.get()), _PC_NAME_MAX);
#if defined(__APPLE_) && defined(__DARWIN_MAXPATHLEN)
if (path_max < __DARWIN_MAXPATHLEN)
path_max = __DARWIN_MAXPATHLEN;
#endif
}
- char child_path[PATH_MAX];
-
+ std::string child_path;
// Don't make paths with "/foo//bar", that just confuses everybody.
- int child_path_len;
if (dir_path_last_char == '/')
- child_path_len = ::snprintf(child_path, sizeof(child_path), "%s%s",
- dir_path, dp->d_name);
+ child_path = llvm::join_items("", dir_path, dp->d_name);
else
- child_path_len = ::snprintf(child_path, sizeof(child_path), "%s/%s",
- dir_path, dp->d_name);
+ child_path = llvm::join_items('/', dir_path, dp->d_name);
- if (child_path_len < (int)(sizeof(child_path) - 1)) {
// Don't resolve the file type or path
FileSpec child_path_spec(child_path, false);
free(buf);
return eEnumerateDirectoryResultQuit;
}
- }
}
if (buf) {
free(buf);
}
}
#endif
- }
// By default when exiting a directory, we tell the parent enumeration
// to continue enumerating.
return eEnumerateDirectoryResultNext;
}
FileSpec::EnumerateDirectoryResult
-FileSpec::EnumerateDirectory(const char *dir_path, bool find_directories,
+FileSpec::EnumerateDirectory(llvm::StringRef dir_path, bool find_directories,
bool find_files, bool find_other,
EnumerateDirectoryCallbackType callback,
void *callback_baton) {
});
}
-FileSpec FileSpec::CopyByAppendingPathComponent(const char *new_path) const {
+FileSpec
+FileSpec::CopyByAppendingPathComponent(llvm::StringRef component) const {
FileSpec ret = *this;
- ret.AppendPathComponent(new_path);
+ ret.AppendPathComponent(component);
return ret;
}
FileSpec FileSpec::CopyByRemovingLastPathComponent() const {
+ // CLEANUP: Use StringRef for string handling.
const bool resolve = false;
if (m_filename.IsEmpty() && m_directory.IsEmpty())
return FileSpec("", resolve);
}
ConstString FileSpec::GetLastPathComponent() const {
+ // CLEANUP: Use StringRef for string handling.
if (m_filename)
return m_filename;
if (m_directory) {
return ConstString();
}
-void FileSpec::PrependPathComponent(const char *new_path) {
- if (!new_path)
+void FileSpec::PrependPathComponent(llvm::StringRef component) {
+ if (component.empty())
return;
+
const bool resolve = false;
if (m_filename.IsEmpty() && m_directory.IsEmpty()) {
- SetFile(new_path, resolve);
+ SetFile(component, resolve);
return;
}
- StreamString stream;
+
+ char sep = GetPreferredPathSeparator(m_syntax);
+ std::string result;
if (m_filename.IsEmpty())
- stream.Printf("%s/%s", new_path, m_directory.GetCString());
+ result = llvm::join_items(sep, component, m_directory.GetStringRef());
else if (m_directory.IsEmpty())
- stream.Printf("%s/%s", new_path, m_filename.GetCString());
+ result = llvm::join_items(sep, component, m_filename.GetStringRef());
else
- stream.Printf("%s/%s/%s", new_path, m_directory.GetCString(),
- m_filename.GetCString());
- SetFile(stream.GetData(), resolve);
-}
+ result = llvm::join_items(sep, component, m_directory.GetStringRef(),
+ m_filename.GetStringRef());
-void FileSpec::PrependPathComponent(const std::string &new_path) {
- return PrependPathComponent(new_path.c_str());
+ SetFile(result, resolve);
}
void FileSpec::PrependPathComponent(const FileSpec &new_path) {
return PrependPathComponent(new_path.GetPath(false));
}
-void FileSpec::AppendPathComponent(const char *new_path) {
- if (!new_path)
+void FileSpec::AppendPathComponent(llvm::StringRef component) {
+ if (component.empty())
return;
- StreamString stream;
+ std::string result;
if (!m_directory.IsEmpty()) {
- stream.PutCString(m_directory.GetCString());
+ result += m_directory.GetStringRef();
if (!IsPathSeparator(m_directory.GetStringRef().back(), m_syntax))
- stream.PutChar(GetPrefferedPathSeparator(m_syntax));
+ result += GetPreferredPathSeparator(m_syntax);
}
if (!m_filename.IsEmpty()) {
- stream.PutCString(m_filename.GetCString());
+ result += m_filename.GetStringRef();
if (!IsPathSeparator(m_filename.GetStringRef().back(), m_syntax))
- stream.PutChar(GetPrefferedPathSeparator(m_syntax));
+ result += GetPreferredPathSeparator(m_syntax);
}
- while (IsPathSeparator(new_path[0], m_syntax))
- new_path++;
+ component = component.drop_while(
+ [this](char c) { return IsPathSeparator(c, m_syntax); });
- stream.PutCString(new_path);
+ result += component;
- const bool resolve = false;
- SetFile(stream.GetData(), resolve, m_syntax);
-}
-
-void FileSpec::AppendPathComponent(const std::string &new_path) {
- return AppendPathComponent(new_path.c_str());
+ SetFile(result, false, m_syntax);
}
void FileSpec::AppendPathComponent(const FileSpec &new_path) {
}
void FileSpec::RemoveLastPathComponent() {
+ // CLEANUP: Use StringRef for string handling.
+
const bool resolve = false;
if (m_filename.IsEmpty() && m_directory.IsEmpty()) {
SetFile("", resolve);