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