diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 |
commit | 5f29bb8a675e8f96452b632e7129113f7dec850e (patch) | |
tree | 3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Utility/FileSpec.cpp | |
parent | 88c643b6fec27eec436c8d138fee6346e92337d6 (diff) |
Notes
Diffstat (limited to 'source/Utility/FileSpec.cpp')
-rw-r--r-- | source/Utility/FileSpec.cpp | 92 |
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) { |