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 <llvm/Support/raw_ostream.h> 17 #include <mcld/Config/Config.h> 18 19 #include <iosfwd> 20 #include <functional> 21 #include <string> 22 #include <locale> 23 24 namespace mcld { 25 namespace sys { 26 namespace fs { 27 28 #if defined(MCLD_ON_WIN32) 29 const char preferred_separator = '/'; 30 const char separator = '/'; 31 #else 32 const char preferred_separator = '/'; 33 const char separator = '/'; 34 #endif 35 36 const char colon = ':'; 37 const char dot = '.'; 38 39 /** \class Path 40 * \brief Path provides an abstraction for the path to a file or directory in 41 * the operating system's filesystem. 42 */ 43 class Path 44 { 45 public: 46 typedef char ValueType; 47 typedef std::string StringType; 48 49 public: 50 Path(); 51 Path(const ValueType* s); 52 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 67 // ----- observers ----- // 68 bool empty() const; 69 70 bool isFromRoot() const; 71 bool isFromPWD() const; 72 73 const StringType& native() const { return m_PathName; } 74 StringType& native() { return m_PathName; } 75 76 const ValueType* c_str() const 77 { 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>& 110 operator<<(std::basic_ostream<Char, Traits>& pOS, const Path& pPath) 111 { 112 return pOS << pPath.native(); 113 } 114 115 template <class Char, class Traits> 116 inline std::basic_istream<Char, Traits>& 117 operator>>(std::basic_istream<Char, Traits>& pOS, Path& pPath) 118 { 119 return pOS >> pPath.native(); 120 } 121 122 inline llvm::raw_ostream& 123 operator<<(llvm::raw_ostream& pOS, const Path& pPath) 124 { 125 return pOS << pPath.native(); 126 } 127 128 //===----------------------------------------------------------------------===// 129 // class path member template implementation 130 //===----------------------------------------------------------------------===// 131 template <class InputIterator> 132 Path& Path::assign(InputIterator begin, InputIterator end) 133 { 134 m_PathName.clear(); 135 if (begin != end) 136 m_PathName.append<InputIterator>(begin, end); 137 return *this; 138 } 139 140 template <class InputIterator> 141 Path& Path::append(InputIterator begin, InputIterator end) 142 { 143 if (begin == end) 144 return *this; 145 StringType::size_type sep_pos(m_append_separator_if_needed()); 146 m_PathName.append<InputIterator>(begin, end); 147 if (sep_pos) 148 m_erase_redundant_separator(sep_pos); 149 return *this; 150 } 151 152 } // namespace of fs 153 } // namespace of sys 154 } // namespace of mcld 155 156 //===----------------------------------------------------------------------===// 157 // STL compatible functions 158 //===----------------------------------------------------------------------===// 159 namespace std { 160 161 template<> 162 struct less<mcld::sys::fs::Path> : public binary_function<mcld::sys::fs::Path, 163 mcld::sys::fs::Path, 164 bool> 165 { 166 bool operator() (const mcld::sys::fs::Path& pX,const mcld::sys::fs::Path& pY) const { 167 if (pX.generic_string().size() < pY.generic_string().size()) 168 return true; 169 return (pX.generic_string() < pY.generic_string()); 170 } 171 }; 172 173 } // namespace of std 174 175 #endif 176 177