aboutsummaryrefslogtreecommitdiff
path: root/source/Utility/FileSpec.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 20:51:52 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 20:51:52 +0000
commit5f29bb8a675e8f96452b632e7129113f7dec850e (patch)
tree3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Utility/FileSpec.cpp
parent88c643b6fec27eec436c8d138fee6346e92337d6 (diff)
Notes
Diffstat (limited to 'source/Utility/FileSpec.cpp')
-rw-r--r--source/Utility/FileSpec.cpp92
1 files changed, 27 insertions, 65 deletions
diff --git a/source/Utility/FileSpec.cpp b/source/Utility/FileSpec.cpp
index 954968b7a8af..35d22404b948 100644
--- a/source/Utility/FileSpec.cpp
+++ b/source/Utility/FileSpec.cpp
@@ -1,9 +1,8 @@
//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -68,9 +67,7 @@ void Denormalize(llvm::SmallVectorImpl<char> &path, FileSpec::Style style) {
FileSpec::FileSpec() : m_style(GetNativeStyle()) {}
-//------------------------------------------------------------------
// Default constructor that can take an optional full path to a file on disk.
-//------------------------------------------------------------------
FileSpec::FileSpec(llvm::StringRef path, Style style) : m_style(style) {
SetFile(path, style);
}
@@ -78,47 +75,33 @@ FileSpec::FileSpec(llvm::StringRef path, Style style) : m_style(style) {
FileSpec::FileSpec(llvm::StringRef path, const llvm::Triple &Triple)
: FileSpec{path, Triple.isOSWindows() ? Style::windows : Style::posix} {}
-//------------------------------------------------------------------
-// Copy constructor
-//------------------------------------------------------------------
-FileSpec::FileSpec(const FileSpec &rhs)
- : m_directory(rhs.m_directory), m_filename(rhs.m_filename),
- m_is_resolved(rhs.m_is_resolved), m_style(rhs.m_style) {}
-
-//------------------------------------------------------------------
// Copy constructor
-//------------------------------------------------------------------
FileSpec::FileSpec(const FileSpec *rhs) : m_directory(), m_filename() {
if (rhs)
*this = *rhs;
}
-//------------------------------------------------------------------
// Virtual destructor in case anyone inherits from this class.
-//------------------------------------------------------------------
FileSpec::~FileSpec() {}
namespace {
-//------------------------------------------------------------------
/// Safely get a character at the specified index.
///
-/// @param[in] path
+/// \param[in] path
/// A full, partial, or relative path to a file.
///
-/// @param[in] i
+/// \param[in] i
/// An index into path which may or may not be valid.
///
-/// @return
+/// \return
/// The character at index \a i if the index is valid, or 0 if
/// the index is not valid.
-//------------------------------------------------------------------
inline char safeCharAtIndex(const llvm::StringRef &path, size_t i) {
if (i < path.size())
return path[i];
return 0;
}
-//------------------------------------------------------------------
/// Check if a path needs to be normalized.
///
/// Check if a path needs to be normalized. We currently consider a
@@ -131,12 +114,11 @@ inline char safeCharAtIndex(const llvm::StringRef &path, size_t i) {
/// need normalization since we aren't trying to resolve the path,
/// we are just trying to remove redundant things from the path.
///
-/// @param[in] path
+/// \param[in] path
/// A full, partial, or relative path to a file.
///
-/// @return
+/// \return
/// Returns \b true if the path needs to be normalized.
-//------------------------------------------------------------------
bool needsNormalization(const llvm::StringRef &path) {
if (path.empty())
return false;
@@ -192,9 +174,7 @@ bool needsNormalization(const llvm::StringRef &path) {
}
-//------------------------------------------------------------------
// Assignment operator.
-//------------------------------------------------------------------
const FileSpec &FileSpec::operator=(const FileSpec &rhs) {
if (this != &rhs) {
m_directory = rhs.m_directory;
@@ -207,11 +187,9 @@ const FileSpec &FileSpec::operator=(const FileSpec &rhs) {
void FileSpec::SetFile(llvm::StringRef pathname) { SetFile(pathname, m_style); }
-//------------------------------------------------------------------
// 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(llvm::StringRef pathname, Style style) {
m_filename.Clear();
m_directory.Clear();
@@ -254,22 +232,18 @@ void FileSpec::SetFile(llvm::StringRef path, const llvm::Triple &Triple) {
return SetFile(path, Triple.isOSWindows() ? Style::windows : Style::posix);
}
-//----------------------------------------------------------------------
// Convert to pointer operator. This allows code to check any FileSpec objects
// to see if they contain anything valid using code such as:
//
// if (file_spec)
// {}
-//----------------------------------------------------------------------
FileSpec::operator bool() const { return m_filename || m_directory; }
-//----------------------------------------------------------------------
// Logical NOT operator. This allows code to check any FileSpec objects to see
// if they are invalid using code such as:
//
// if (!file_spec)
// {}
-//----------------------------------------------------------------------
bool FileSpec::operator!() const { return !m_directory && !m_filename; }
bool FileSpec::DirectoryEquals(const FileSpec &rhs) const {
@@ -282,43 +256,32 @@ bool FileSpec::FileEquals(const FileSpec &rhs) const {
return ConstString::Equals(m_filename, rhs.m_filename, case_sensitive);
}
-//------------------------------------------------------------------
// Equal to operator
-//------------------------------------------------------------------
bool FileSpec::operator==(const FileSpec &rhs) const {
return FileEquals(rhs) && DirectoryEquals(rhs);
}
-//------------------------------------------------------------------
// Not equal to operator
-//------------------------------------------------------------------
bool FileSpec::operator!=(const FileSpec &rhs) const { return !(*this == rhs); }
-//------------------------------------------------------------------
// Less than operator
-//------------------------------------------------------------------
bool FileSpec::operator<(const FileSpec &rhs) const {
return FileSpec::Compare(*this, rhs, true) < 0;
}
-//------------------------------------------------------------------
// Dump a FileSpec object to a stream
-//------------------------------------------------------------------
Stream &lldb_private::operator<<(Stream &s, const FileSpec &f) {
f.Dump(&s);
return s;
}
-//------------------------------------------------------------------
// Clear this object by releasing both the directory and filename string values
// and making them both the empty string.
-//------------------------------------------------------------------
void FileSpec::Clear() {
m_directory.Clear();
m_filename.Clear();
}
-//------------------------------------------------------------------
// Compare two FileSpec objects. If "full" is true, then both the directory and
// the filename must match. If "full" is false, then the directory names for
// "a" and "b" are only compared if they are both non-empty. This allows a
@@ -327,7 +290,6 @@ void FileSpec::Clear() {
//
// Return -1 if the "a" is less than "b", 0 if "a" is equal to "b" and "1" if
// "a" is greater than "b".
-//------------------------------------------------------------------
int FileSpec::Compare(const FileSpec &a, const FileSpec &b, bool full) {
int result = 0;
@@ -366,11 +328,20 @@ bool FileSpec::Equal(const FileSpec &a, const FileSpec &b, bool full) {
return a == b;
}
-//------------------------------------------------------------------
+llvm::Optional<FileSpec::Style> FileSpec::GuessPathStyle(llvm::StringRef absolute_path) {
+ if (absolute_path.startswith("/"))
+ return Style::posix;
+ if (absolute_path.startswith(R"(\\)"))
+ return Style::windows;
+ if (absolute_path.size() > 3 && llvm::isAlpha(absolute_path[0]) &&
+ absolute_path.substr(1, 2) == R"(:\)")
+ return Style::windows;
+ return llvm::None;
+}
+
// Dump the object to the supplied stream. If the object contains a valid
// directory name, it will be displayed followed by a directory delimiter, and
// the filename.
-//------------------------------------------------------------------
void FileSpec::Dump(Stream *s) const {
if (s) {
std::string path{GetPath(true)};
@@ -383,30 +354,20 @@ void FileSpec::Dump(Stream *s) const {
FileSpec::Style FileSpec::GetPathStyle() const { return m_style; }
-//------------------------------------------------------------------
// Directory string get accessor.
-//------------------------------------------------------------------
ConstString &FileSpec::GetDirectory() { return m_directory; }
-//------------------------------------------------------------------
// Directory string const get accessor.
-//------------------------------------------------------------------
-const ConstString &FileSpec::GetDirectory() const { return m_directory; }
+ConstString FileSpec::GetDirectory() const { return m_directory; }
-//------------------------------------------------------------------
// Filename string get accessor.
-//------------------------------------------------------------------
ConstString &FileSpec::GetFilename() { return m_filename; }
-//------------------------------------------------------------------
// Filename string const get accessor.
-//------------------------------------------------------------------
-const ConstString &FileSpec::GetFilename() const { return m_filename; }
+ConstString FileSpec::GetFilename() const { return m_filename; }
-//------------------------------------------------------------------
// Extract the directory and path into a fixed buffer. This is needed as the
// directory and path are stored in separate string values.
-//------------------------------------------------------------------
size_t FileSpec::GetPath(char *path, size_t path_max_len,
bool denormalize) const {
if (!path)
@@ -452,10 +413,8 @@ ConstString FileSpec::GetFileNameStrippingExtension() const {
return ConstString(llvm::sys::path::stem(m_filename.GetStringRef(), m_style));
}
-//------------------------------------------------------------------
// Return the size in bytes that this object takes in memory. This returns the
// size in bytes of this object, not any shared string values it may refer to.
-//------------------------------------------------------------------
size_t FileSpec::MemorySize() const {
return m_filename.MemorySize() + m_directory.MemorySize();
}
@@ -516,15 +475,13 @@ bool FileSpec::RemoveLastPathComponent() {
}
return false;
}
-//------------------------------------------------------------------
/// Returns true if the filespec represents an implementation source
/// file (files with a ".c", ".cpp", ".m", ".mm" (many more)
/// extension).
///
-/// @return
+/// \return
/// \b true if the filespec represents an implementation source
/// file, \b false otherwise.
-//------------------------------------------------------------------
bool FileSpec::IsSourceImplementationFile() const {
ConstString extension(GetFileNameExtension());
if (!extension)
@@ -557,6 +514,11 @@ bool FileSpec::IsAbsolute() const {
return llvm::sys::path::is_absolute(current_path, m_style);
}
+void FileSpec::MakeAbsolute(const FileSpec &dir) {
+ if (IsRelative())
+ PrependPathComponent(dir);
+}
+
void llvm::format_provider<FileSpec>::format(const FileSpec &F,
raw_ostream &Stream,
StringRef Style) {