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