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