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