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 25 namespace mcld { 26 namespace sys { 27 namespace fs { 28 29 #if defined(MCLD_ON_WIN32) 30 const char preferred_separator = '/'; 31 const char separator = '/'; 32 #else 33 const char preferred_separator = '/'; 34 const char separator = '/'; 35 #endif 36 37 const char colon = ':'; 38 const 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 */ 44 class 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 97 bool operator==(const Path& pLHS, const Path& pRHS); 98 bool operator!=(const Path& pLHS, const Path& pRHS); 99 Path operator+(const Path& pLHS, const Path& pRHS); 100 101 //===----------------------------------------------------------------------===// 102 // Non-member Functions 103 //===----------------------------------------------------------------------===// 104 bool exists(const Path& pPath); 105 106 bool is_directory(const Path& pPath); 107 108 template <class Char, class Traits> 109 inline std::basic_ostream<Char, Traits>& operator<<( 110 std::basic_ostream<Char, Traits>& pOS, 111 const Path& pPath) { 112 return pOS << pPath.native(); 113 } 114 115 template <class Char, class Traits> 116 inline std::basic_istream<Char, Traits>& operator>>( 117 std::basic_istream<Char, Traits>& pOS, 118 Path& pPath) { 119 return pOS >> pPath.native(); 120 } 121 122 inline 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 //===----------------------------------------------------------------------===// 130 template <class InputIterator> 131 Path& 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 138 template <class InputIterator> 139 Path& 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 //===----------------------------------------------------------------------===// 156 namespace std { 157 158 template <> 159 struct 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