• 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_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