1//===- Path.h -------------------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// This file declares the mcld::sys::fs::Path. It follows TR2/boost 10// filesystem (v3), but modified to remove exception handling and the 11// path class. 12//===----------------------------------------------------------------------===// 13#ifndef MCLD_SUPPORT_PATH_H_ 14#define MCLD_SUPPORT_PATH_H_ 15 16#include "mcld/Config/Config.h" 17 18#include <llvm/Support/raw_ostream.h> 19 20#include <iosfwd> 21#include <functional> 22#include <string> 23#include <locale> 24 25namespace mcld { 26namespace sys { 27namespace fs { 28 29#if defined(MCLD_ON_WIN32) 30const char preferred_separator = '/'; 31const char separator = '/'; 32#else 33const char preferred_separator = '/'; 34const char separator = '/'; 35#endif 36 37const char colon = ':'; 38const char dot = '.'; 39 40/** \class Path 41 * \brief Path provides an abstraction for the path to a file or directory in 42 * the operating system's filesystem. 43 */ 44class Path { 45 public: 46 typedef char ValueType; 47 typedef std::string StringType; 48 49 public: 50 Path(); 51 explicit Path(const ValueType* s); 52 explicit Path(const StringType& s); 53 Path(const Path& pCopy); 54 virtual ~Path(); 55 56 // ----- assignments ----- // 57 template <class InputIterator> 58 Path& assign(InputIterator begin, InputIterator end); 59 Path& assign(const StringType& s); 60 Path& assign(const ValueType* s, unsigned int length); 61 62 // ----- appends ----- // 63 template <class InputIterator> 64 Path& append(InputIterator begin, InputIterator end); 65 Path& append(const Path& pPath); 66 Path& append(const StringType& pPath); 67 68 // ----- observers ----- // 69 bool empty() const; 70 71 bool isFromRoot() const; 72 bool isFromPWD() const; 73 74 const StringType& native() const { return m_PathName; } 75 StringType& native() { return m_PathName; } 76 77 const ValueType* c_str() const { return m_PathName.c_str(); } 78 79 // ----- decomposition ----- // 80 Path parent_path() const; 81 Path filename() const; 82 Path stem() const; 83 Path extension() const; 84 85 // ----- generic form observers ----- // 86 StringType generic_string() const; 87 bool canonicalize(); 88 89 public: 90 StringType::size_type m_append_separator_if_needed(); 91 void m_erase_redundant_separator(StringType::size_type sep_pos); 92 93 protected: 94 StringType m_PathName; 95}; 96 97bool operator==(const Path& pLHS, const Path& pRHS); 98bool operator!=(const Path& pLHS, const Path& pRHS); 99Path operator+(const Path& pLHS, const Path& pRHS); 100 101//===----------------------------------------------------------------------===// 102// Non-member Functions 103//===----------------------------------------------------------------------===// 104bool exists(const Path& pPath); 105 106bool is_directory(const Path& pPath); 107 108template <class Char, class Traits> 109inline std::basic_ostream<Char, Traits>& operator<<( 110 std::basic_ostream<Char, Traits>& pOS, 111 const Path& pPath) { 112 return pOS << pPath.native(); 113} 114 115template <class Char, class Traits> 116inline std::basic_istream<Char, Traits>& operator>>( 117 std::basic_istream<Char, Traits>& pOS, 118 Path& pPath) { 119 return pOS >> pPath.native(); 120} 121 122inline llvm::raw_ostream& operator<<(llvm::raw_ostream& pOS, 123 const Path& pPath) { 124 return pOS << pPath.native(); 125} 126 127//===----------------------------------------------------------------------===// 128// class path member template implementation 129//===----------------------------------------------------------------------===// 130template <class InputIterator> 131Path& Path::assign(InputIterator begin, InputIterator end) { 132 m_PathName.clear(); 133 if (begin != end) 134 m_PathName.append<InputIterator>(begin, end); 135 return *this; 136} 137 138template <class InputIterator> 139Path& Path::append(InputIterator begin, InputIterator end) { 140 if (begin == end) 141 return *this; 142 StringType::size_type sep_pos(m_append_separator_if_needed()); 143 m_PathName.append<InputIterator>(begin, end); 144 if (sep_pos) 145 m_erase_redundant_separator(sep_pos); 146 return *this; 147} 148 149} // namespace fs 150} // namespace sys 151} // namespace mcld 152 153//===----------------------------------------------------------------------===// 154// STL compatible functions 155//===----------------------------------------------------------------------===// 156namespace std { 157 158template <> 159struct less<mcld::sys::fs::Path> 160 : public binary_function<mcld::sys::fs::Path, mcld::sys::fs::Path, bool> { 161 bool operator()(const mcld::sys::fs::Path& pX, 162 const mcld::sys::fs::Path& pY) const { 163 if (pX.generic_string().size() < pY.generic_string().size()) 164 return true; 165 return (pX.generic_string() < pY.generic_string()); 166 } 167}; 168 169} // namespace std 170 171#endif // MCLD_SUPPORT_PATH_H_ 172