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