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