• 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::Path. 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 #include <locale>
26 
27 namespace mcld {
28 namespace sys  {
29 namespace fs   {
30 
31 #if defined(MCLD_ON_WIN32)
32 const char preferred_separator = '/';
33 const char separator = '/';
34 #else
35 const char preferred_separator = '/';
36 const char separator = '/';
37 #endif
38 
39 const char colon = ':';
40 const char dot = '.';
41 
42 /** \class Path
43  *  \brief Path provides an abstraction for the path to a file or directory in
44  *   the operating system's filesystem.
45  */
46 class Path
47 {
48 public:
49   typedef char                               ValueType;
50   typedef std::string                        StringType;
51 
52 public:
53   Path();
54   Path(const ValueType* s);
55   Path(const StringType &s);
56   Path(const Path& pCopy);
57   virtual ~Path();
58 
59   // -----  assignments  ----- //
60   template <class InputIterator>
61   Path& assign(InputIterator begin, InputIterator end);
62   Path& assign(const StringType &s);
63   Path& assign(const ValueType* s, unsigned int length);
64 
65   //  -----  appends  ----- //
66   template <class InputIterator>
67   Path& append(InputIterator begin, InputIterator end);
68   Path& append(const Path& pPath);
69 
70   //  -----  observers  ----- //
71   bool empty() const;
72 
73   bool isFromRoot() const;
74   bool isFromPWD() const;
75 
native()76   const StringType& native() const { return m_PathName; }
native()77   StringType&       native()       { return m_PathName; }
78 
c_str()79   const ValueType* c_str() const
80   { return m_PathName.c_str(); }
81 
82   // -----  decomposition  ----- //
83   Path parent_path() const;
84   Path filename() const;
85   Path stem() const;
86   Path extension() const;
87 
88   // -----  generic form observers  ----- //
89   StringType generic_string() const;
90   bool canonicalize();
91 
92 public:
93   StringType::size_type m_append_separator_if_needed();
94   void m_erase_redundant_separator(StringType::size_type sep_pos);
95 
96 protected:
97   StringType m_PathName;
98 };
99 
100 bool operator==(const Path& pLHS,const Path& pRHS);
101 bool operator!=(const Path& pLHS,const Path& pRHS);
102 Path operator+(const Path& pLHS, const Path& pRHS);
103 
104 //===----------------------------------------------------------------------===//
105 // Non-member Functions
106 //===----------------------------------------------------------------------===//
107 bool exists(const Path &pPath);
108 
109 bool is_directory(const Path &pPath);
110 
111 template <class Char, class Traits>
112 inline std::basic_ostream<Char, Traits>&
113 operator<<(std::basic_ostream<Char, Traits>& pOS, const Path& pPath)
114 {
115   return pOS << pPath.native();
116 }
117 
118 template <class Char, class Traits>
119 inline std::basic_istream<Char, Traits>&
120 operator>>(std::basic_istream<Char, Traits>& pOS, Path& pPath)
121 {
122   return pOS >> pPath.native();
123 }
124 
125 inline llvm::raw_ostream&
126 operator<<(llvm::raw_ostream& pOS, const Path& pPath)
127 {
128   return pOS << pPath.native();
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