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 "mcld/Config/Config.h"
     17 
     18 #include <llvm/Support/raw_ostream.h>
     19 
     20 #include <iosfwd>
     21 #include <functional>
     22 #include <string>
     23 #include <locale>
     24 
     25 namespace mcld {
     26 namespace sys {
     27 namespace fs {
     28 
     29 #if defined(MCLD_ON_WIN32)
     30 const char preferred_separator = '/';
     31 const char separator = '/';
     32 #else
     33 const char preferred_separator = '/';
     34 const char separator = '/';
     35 #endif
     36 
     37 const char colon = ':';
     38 const char dot = '.';
     39 
     40 /** \class Path
     41  *  \brief Path provides an abstraction for the path to a file or directory in
     42  *   the operating system's filesystem.
     43  */
     44 class Path {
     45  public:
     46   typedef char ValueType;
     47   typedef std::string StringType;
     48 
     49  public:
     50   Path();
     51   explicit Path(const ValueType* s);
     52   explicit 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   Path& append(const StringType& pPath);
     67 
     68   //  -----  observers  ----- //
     69   bool empty() const;
     70 
     71   bool isFromRoot() const;
     72   bool isFromPWD() const;
     73 
     74   const StringType& native() const { return m_PathName; }
     75   StringType& native() { return m_PathName; }
     76 
     77   const ValueType* c_str() const { 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>& operator<<(
    110     std::basic_ostream<Char, Traits>& pOS,
    111     const Path& pPath) {
    112   return pOS << pPath.native();
    113 }
    114 
    115 template <class Char, class Traits>
    116 inline std::basic_istream<Char, Traits>& operator>>(
    117     std::basic_istream<Char, Traits>& pOS,
    118     Path& pPath) {
    119   return pOS >> pPath.native();
    120 }
    121 
    122 inline llvm::raw_ostream& operator<<(llvm::raw_ostream& pOS,
    123                                      const Path& pPath) {
    124   return pOS << pPath.native();
    125 }
    126 
    127 //===----------------------------------------------------------------------===//
    128 // class path member template implementation
    129 //===----------------------------------------------------------------------===//
    130 template <class InputIterator>
    131 Path& Path::assign(InputIterator begin, InputIterator end) {
    132   m_PathName.clear();
    133   if (begin != end)
    134     m_PathName.append<InputIterator>(begin, end);
    135   return *this;
    136 }
    137 
    138 template <class InputIterator>
    139 Path& Path::append(InputIterator begin, InputIterator end) {
    140   if (begin == end)
    141     return *this;
    142   StringType::size_type sep_pos(m_append_separator_if_needed());
    143   m_PathName.append<InputIterator>(begin, end);
    144   if (sep_pos)
    145     m_erase_redundant_separator(sep_pos);
    146   return *this;
    147 }
    148 
    149 }  // namespace fs
    150 }  // namespace sys
    151 }  // namespace mcld
    152 
    153 //===----------------------------------------------------------------------===//
    154 // STL compatible functions
    155 //===----------------------------------------------------------------------===//
    156 namespace std {
    157 
    158 template <>
    159 struct less<mcld::sys::fs::Path>
    160     : public binary_function<mcld::sys::fs::Path, mcld::sys::fs::Path, bool> {
    161   bool operator()(const mcld::sys::fs::Path& pX,
    162                   const mcld::sys::fs::Path& pY) const {
    163     if (pX.generic_string().size() < pY.generic_string().size())
    164       return true;
    165     return (pX.generic_string() < pY.generic_string());
    166   }
    167 };
    168 
    169 }  // namespace std
    170 
    171 #endif  // MCLD_SUPPORT_PATH_H_
    172