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