172 lines
4.8 KiB
172 lines
4.8 KiB
//===- Path.h -------------------------------------------------------------===//
|
|
//
|
|
// The MCLinker Project
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
// This file declares the mcld::sys::fs::Path. It follows TR2/boost
|
|
// filesystem (v3), but modified to remove exception handling and the
|
|
// path class.
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef MCLD_SUPPORT_PATH_H_
|
|
#define MCLD_SUPPORT_PATH_H_
|
|
|
|
#include "mcld/Config/Config.h"
|
|
|
|
#include <llvm/Support/raw_ostream.h>
|
|
|
|
#include <iosfwd>
|
|
#include <functional>
|
|
#include <string>
|
|
#include <locale>
|
|
|
|
namespace mcld {
|
|
namespace sys {
|
|
namespace fs {
|
|
|
|
#if defined(MCLD_ON_WIN32)
|
|
const char preferred_separator = '/';
|
|
const char separator = '/';
|
|
#else
|
|
const char preferred_separator = '/';
|
|
const char separator = '/';
|
|
#endif
|
|
|
|
const char colon = ':';
|
|
const char dot = '.';
|
|
|
|
/** \class Path
|
|
* \brief Path provides an abstraction for the path to a file or directory in
|
|
* the operating system's filesystem.
|
|
*/
|
|
class Path {
|
|
public:
|
|
typedef char ValueType;
|
|
typedef std::string StringType;
|
|
|
|
public:
|
|
Path();
|
|
explicit Path(const ValueType* s);
|
|
explicit Path(const StringType& s);
|
|
Path(const Path& pCopy);
|
|
virtual ~Path();
|
|
|
|
// ----- assignments ----- //
|
|
template <class InputIterator>
|
|
Path& assign(InputIterator begin, InputIterator end);
|
|
Path& assign(const StringType& s);
|
|
Path& assign(const ValueType* s, unsigned int length);
|
|
|
|
// ----- appends ----- //
|
|
template <class InputIterator>
|
|
Path& append(InputIterator begin, InputIterator end);
|
|
Path& append(const Path& pPath);
|
|
Path& append(const StringType& pPath);
|
|
|
|
// ----- observers ----- //
|
|
bool empty() const;
|
|
|
|
bool isFromRoot() const;
|
|
bool isFromPWD() const;
|
|
|
|
const StringType& native() const { return m_PathName; }
|
|
StringType& native() { return m_PathName; }
|
|
|
|
const ValueType* c_str() const { return m_PathName.c_str(); }
|
|
|
|
// ----- decomposition ----- //
|
|
Path parent_path() const;
|
|
Path filename() const;
|
|
Path stem() const;
|
|
Path extension() const;
|
|
|
|
// ----- generic form observers ----- //
|
|
StringType generic_string() const;
|
|
bool canonicalize();
|
|
|
|
public:
|
|
StringType::size_type m_append_separator_if_needed();
|
|
void m_erase_redundant_separator(StringType::size_type sep_pos);
|
|
|
|
protected:
|
|
StringType m_PathName;
|
|
};
|
|
|
|
bool operator==(const Path& pLHS, const Path& pRHS);
|
|
bool operator!=(const Path& pLHS, const Path& pRHS);
|
|
Path operator+(const Path& pLHS, const Path& pRHS);
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Non-member Functions
|
|
//===----------------------------------------------------------------------===//
|
|
bool exists(const Path& pPath);
|
|
|
|
bool is_directory(const Path& pPath);
|
|
|
|
template <class Char, class Traits>
|
|
inline std::basic_ostream<Char, Traits>& operator<<(
|
|
std::basic_ostream<Char, Traits>& pOS,
|
|
const Path& pPath) {
|
|
return pOS << pPath.native();
|
|
}
|
|
|
|
template <class Char, class Traits>
|
|
inline std::basic_istream<Char, Traits>& operator>>(
|
|
std::basic_istream<Char, Traits>& pOS,
|
|
Path& pPath) {
|
|
return pOS >> pPath.native();
|
|
}
|
|
|
|
inline llvm::raw_ostream& operator<<(llvm::raw_ostream& pOS,
|
|
const Path& pPath) {
|
|
return pOS << pPath.native();
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// class path member template implementation
|
|
//===----------------------------------------------------------------------===//
|
|
template <class InputIterator>
|
|
Path& Path::assign(InputIterator begin, InputIterator end) {
|
|
m_PathName.clear();
|
|
if (begin != end)
|
|
m_PathName.append<InputIterator>(begin, end);
|
|
return *this;
|
|
}
|
|
|
|
template <class InputIterator>
|
|
Path& Path::append(InputIterator begin, InputIterator end) {
|
|
if (begin == end)
|
|
return *this;
|
|
StringType::size_type sep_pos(m_append_separator_if_needed());
|
|
m_PathName.append<InputIterator>(begin, end);
|
|
if (sep_pos)
|
|
m_erase_redundant_separator(sep_pos);
|
|
return *this;
|
|
}
|
|
|
|
} // namespace fs
|
|
} // namespace sys
|
|
} // namespace mcld
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// STL compatible functions
|
|
//===----------------------------------------------------------------------===//
|
|
namespace std {
|
|
|
|
template <>
|
|
struct less<mcld::sys::fs::Path>
|
|
: public binary_function<mcld::sys::fs::Path, mcld::sys::fs::Path, bool> {
|
|
bool operator()(const mcld::sys::fs::Path& pX,
|
|
const mcld::sys::fs::Path& pY) const {
|
|
if (pX.generic_string().size() < pY.generic_string().size())
|
|
return true;
|
|
return (pX.generic_string() < pY.generic_string());
|
|
}
|
|
};
|
|
|
|
} // namespace std
|
|
|
|
#endif // MCLD_SUPPORT_PATH_H_
|