Home | History | Annotate | Download | only in Support
      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 
     73   const StringType& native() const { return m_PathName; }
     74   StringType&       native()       { return m_PathName; }
     75 
     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>
    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>
    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