Path.h revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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:: namespace. It follows TR2/boost 10// filesystem (v3), but modified to remove exception handling and the 11// path class. 12//===----------------------------------------------------------------------===// 13#ifndef MCLD_PATH_H 14#define MCLD_PATH_H 15#ifdef ENABLE_UNITTEST 16#include <gtest.h> 17#endif 18 19#include <llvm/Support/raw_ostream.h> 20#include <mcld/Config/Config.h> 21 22#include <iosfwd> 23#include <functional> 24#include <string> 25 26namespace mcld { 27namespace sys { 28namespace fs { 29 30#if defined(MCLD_ON_WIN32) 31const wchar_t separator = L'\\'; 32const wchar_t preferred_separator = L'\\'; 33#else 34const char separator = '/'; 35const char preferred_separator = '/'; 36#endif 37 38/** \class Path 39 * \brief Path provides an abstraction for the path to a file or directory in 40 * the operating system's filesystem. 41 * 42 * FIXME: current Path library only support UTF-8 chararcter set. 43 * 44 */ 45class Path 46{ 47public: 48#if defined(MCLD_ON_WIN32) 49 typedef wchar_t ValueType; 50#else 51 typedef char ValueType; 52#endif 53 typedef std::basic_string<ValueType> StringType; 54 55public: 56 Path(); 57 Path(const ValueType* s); 58 Path(const StringType &s); 59 Path(const Path& pCopy); 60 virtual ~Path(); 61 62 // ----- assignments ----- // 63 template <class InputIterator> 64 Path& assign(InputIterator begin, InputIterator end); 65 Path& assign(const StringType &s); 66 Path& assign(const ValueType* s, unsigned int length); 67 68 // ----- appends ----- // 69 template <class InputIterator> 70 Path& append(InputIterator begin, InputIterator end); 71 Path& append(const Path& pPath); 72 73 // ----- observers ----- // 74 bool empty() const; 75 76 bool isFromRoot() const; 77 bool isFromPWD() const; 78 79 const StringType &native() const 80 { return m_PathName; } 81 82 StringType &native() 83 { return m_PathName; } 84 85 const ValueType* c_str() const 86 { return m_PathName.c_str(); } 87 88 std::string string() const; 89 90 // ----- decomposition ----- // 91 Path parent_path() const; 92 Path filename() const; 93 Path stem() const; 94 Path extension() const; 95 96 // ----- generic form observers ----- // 97 StringType generic_string() const; 98 bool canonicalize(); 99 100public: 101 StringType::size_type m_append_separator_if_needed(); 102 void m_erase_redundant_separator(StringType::size_type sep_pos); 103 104protected: 105 StringType m_PathName; 106}; 107 108bool operator==(const Path& pLHS,const Path& pRHS); 109bool operator!=(const Path& pLHS,const Path& pRHS); 110Path operator+(const Path& pLHS, const Path& pRHS); 111 112//--------------------------------------------------------------------------// 113// non-member functions // 114//--------------------------------------------------------------------------// 115 116/// is_separator - is the given character a separator of a path. 117// @param value a character 118// @result true if \a value is a path separator character on the host OS 119//bool status_known(FileStatus f) { return f.type() != StatusError; } 120 121bool is_separator(char value); 122 123bool exists(const Path &pPath); 124 125bool is_directory(const Path &pPath); 126 127 128std::ostream &operator<<(std::ostream& pOS, const Path& pPath); 129 130std::istream &operator>>(std::istream& pOS, Path& pPath); 131 132llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Path &pPath); 133 134 135//--------------------------------------------------------------------------------------// 136// class path member template implementation // 137//--------------------------------------------------------------------------------------// 138template <class InputIterator> 139Path& Path::assign(InputIterator begin, InputIterator end) 140{ 141 m_PathName.clear(); 142 if (begin != end) 143 m_PathName.append<InputIterator>(begin, end); 144 return *this; 145} 146 147template <class InputIterator> 148Path& Path::append(InputIterator begin, InputIterator end) 149{ 150 if (begin == end) 151 return *this; 152 StringType::size_type sep_pos(m_append_separator_if_needed()); 153 m_PathName.append<InputIterator>(begin, end); 154 if (sep_pos) 155 m_erase_redundant_separator(sep_pos); 156 return *this; 157} 158 159} // namespace of fs 160} // namespace of sys 161} // namespace of mcld 162 163//-------------------------------------------------------------------------// 164// STL compatible functions // 165//-------------------------------------------------------------------------// 166namespace std { 167 168template<> 169struct less<mcld::sys::fs::Path> : public binary_function<mcld::sys::fs::Path, 170 mcld::sys::fs::Path, 171 bool> 172{ 173 bool operator() (const mcld::sys::fs::Path& pX,const mcld::sys::fs::Path& pY) const { 174 if (pX.generic_string().size() < pY.generic_string().size()) 175 return true; 176 return (pX.generic_string() < pY.generic_string()); 177 } 178}; 179 180} // namespace of std 181 182#endif 183 184