• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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"
25 namespace mcld {
26 namespace sys  {
27 namespace fs   {
28 
29 #ifdef LLVM_ON_WIN32
30 const wchar_t       separator = L'\\';
31 const wchar_t       preferred_separator = L'\\';
32 #else
33 const char          separator = '/';
34 const 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  */
44 class Path
45 {
46 public:
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 
54 public:
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 
native()78   const StringType &native() const
79   { return m_PathName; }
80 
native()81   StringType &native()
82   { return m_PathName; }
83 
c_str()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 
97 public:
98   StringType::size_type m_append_separator_if_needed();
99   void m_erase_redundant_separator(StringType::size_type sep_pos);
100 
101 protected:
102   StringType m_PathName;
103 };
104 
105 bool operator==(const Path& pLHS,const Path& pRHS);
106 bool 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 
117 bool is_separator(char value);
118 
119 bool exists(const Path &pPath);
120 
121 bool is_directory(const Path &pPath);
122 
123 
124 std::ostream &operator<<(std::ostream& pOS, const Path& pPath);
125 
126 std::istream &operator>>(std::istream& pOS, Path& pPath);
127 
128 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Path &pPath);
129 
130 
131 //--------------------------------------------------------------------------------------//
132 //                     class path member template implementation                        //
133 //--------------------------------------------------------------------------------------//
134 template <class InputIterator>
assign(InputIterator begin,InputIterator end)135 Path& 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 
143 template <class InputIterator>
append(InputIterator begin,InputIterator end)144 Path& 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 //-------------------------------------------------------------------------//
162 namespace std {
163 
164 template<>
165 struct 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