Path.h revision cedee4b38f4786845183be7f5916dd520a170ae0
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 stem() const; 93 Path extension() const; 94 95 // ----- generic form observers ----- // 96 StringType generic_string() const; 97 bool canonicalize(); 98 99public: 100 StringType::size_type m_append_separator_if_needed(); 101 void m_erase_redundant_separator(StringType::size_type sep_pos); 102 103protected: 104 StringType m_PathName; 105}; 106 107bool operator==(const Path& pLHS,const Path& pRHS); 108bool operator!=(const Path& pLHS,const Path& pRHS); 109Path operator+(const Path& pLHS, const Path& pRHS); 110 111//--------------------------------------------------------------------------// 112// non-member functions // 113//--------------------------------------------------------------------------// 114 115/// is_separator - is the given character a separator of a path. 116// @param value a character 117// @result true if \a value is a path separator character on the host OS 118//bool status_known(FileStatus f) { return f.type() != StatusError; } 119 120bool is_separator(char value); 121 122bool exists(const Path &pPath); 123 124bool is_directory(const Path &pPath); 125 126 127std::ostream &operator<<(std::ostream& pOS, const Path& pPath); 128 129std::istream &operator>>(std::istream& pOS, Path& pPath); 130 131llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Path &pPath); 132 133 134//--------------------------------------------------------------------------------------// 135// class path member template implementation // 136//--------------------------------------------------------------------------------------// 137template <class InputIterator> 138Path& Path::assign(InputIterator begin, InputIterator end) 139{ 140 m_PathName.clear(); 141 if (begin != end) 142 m_PathName.append<InputIterator>(begin, end); 143 return *this; 144} 145 146template <class InputIterator> 147Path& Path::append(InputIterator begin, InputIterator end) 148{ 149 if (begin == end) 150 return *this; 151 StringType::size_type sep_pos(m_append_separator_if_needed()); 152 m_PathName.append<InputIterator>(begin, end); 153 if (sep_pos) 154 m_erase_redundant_separator(sep_pos); 155 return *this; 156} 157 158} // namespace of fs 159} // namespace of sys 160} // namespace of mcld 161 162//-------------------------------------------------------------------------// 163// STL compatible functions // 164//-------------------------------------------------------------------------// 165namespace std { 166 167template<> 168struct less<mcld::sys::fs::Path> : public binary_function<mcld::sys::fs::Path, 169 mcld::sys::fs::Path, 170 bool> 171{ 172 bool operator() (const mcld::sys::fs::Path& pX,const mcld::sys::fs::Path& pY) const { 173 if (pX.generic_string().size() < pY.generic_string().size()) 174 return true; 175 return (pX.generic_string() < pY.generic_string()); 176 } 177}; 178 179} // namespace of std 180 181#endif 182 183