15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- Path.cpp -----------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "mcld/Support/FileSystem.h"
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "mcld/Support/Path.h"
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/StringRef.h>
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <locale>
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string.h>
1567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <istream>
1667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <ostream>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld::sys::fs;
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===//
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Path
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::Path()
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_PathName() {
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::Path(const Path::ValueType* s )
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_PathName(s) {
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::Path(const Path::StringType &s )
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_PathName(s) {
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::Path(const Path& pCopy)
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : m_PathName(pCopy.m_PathName) {
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::~Path()
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Path::isFromRoot() const
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (m_PathName.empty())
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (separator == m_PathName[0]);
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Path::isFromPWD() const
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (2 > m_PathName.size())
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return ('.' == m_PathName[0] && separator == m_PathName[1]);
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath& Path::assign(const Path::StringType &s)
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_PathName.assign(s);
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath& Path::assign(const Path::ValueType* s, unsigned int length)
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == s || 0 == length)
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "assign a null or empty string to Path");
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_PathName.assign(s, length);
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//a,/b a/,b a/,b/ a,b is a/b
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath& Path::append(const Path& pPath)
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //first path is a/,second path is /b
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(m_PathName[m_PathName.length()-1] == separator &&
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao     pPath.native()[0] == separator) {
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned int old_size = m_PathName.size()-1;
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned int new_size = old_size + pPath.native().size();
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.resize(new_size);
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    strcpy(const_cast<char*>(m_PathName.data()+old_size), pPath.native().data());
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //first path is a,second path is b
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else if(this->string()[this->native().size()-1] != separator &&
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          pPath.string()[0] != separator) {
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.append("/");
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.append(pPath.native());
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // a/,b or a,/b just append
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.append(pPath.native());
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Path::empty() const
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_PathName.empty();
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostd::string Path::string() const
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_PathName;
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::StringType Path::generic_string() const
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::string result = m_PathName;
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  detail::canonicalize(result);
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Path::canonicalize()
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return detail::canonicalize(m_PathName);
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::StringType::size_type Path::m_append_separator_if_needed()
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (!m_PathName.empty() &&
121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#if defined(MCLD_ON_WIN32)
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      *(m_PathName.end()-1) != colon &&
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      !is_separator(*(m_PathName.end()-1))) {
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        StringType::size_type tmp(m_PathName.size());
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        m_PathName += preferred_separator;
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao        return tmp;
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Path::m_erase_redundant_separator(Path::StringType::size_type pSepPos)
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t begin=pSepPos;
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // skip '/'
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  while(separator == m_PathName[pSepPos])
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++pSepPos;
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(begin!=pSepPos)
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.erase(begin+1,pSepPos-begin-1);
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
143cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoPath Path::parent_path() const
144cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
145cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  size_t end_pos = m_PathName.find_last_of(separator);
146cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (end_pos != StringType::npos)
147cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return Path(m_PathName.substr(0, end_pos));
148cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return Path();
149cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
150cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath Path::stem() const
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t begin_pos = m_PathName.find_last_of(separator)+1;
15467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  size_t end_pos   = m_PathName.find_last_of(".");
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Path result_path(m_PathName.substr(begin_pos, end_pos - begin_pos));
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result_path;
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath Path::extension() const
1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t begin_pos = m_PathName.find_last_of('.');
1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Path result_path(m_PathName.substr(begin_pos));
1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result_path;
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===//
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// non-member functions
16867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===--------------------------------------------------------------------===//
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool mcld::sys::fs::operator==(const Path& pLHS,const Path& pRHS)
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (pLHS.generic_string()==pRHS.generic_string());
1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool mcld::sys::fs::operator!=(const Path& pLHS,const Path& pRHS)
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return !(pLHS==pRHS);
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei LiaoPath mcld::sys::fs::operator+(const Path& pLHS, const Path& pRHS)
18067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
18167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::sys::fs::Path result = pLHS;
18267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  result.append(pRHS);
18367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  return result;
18467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
18567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool mcld::sys::fs::is_separator(char value)
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (value == separator
189affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#if defined(MCLD_ON_WIN32)
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          || value == preferred_separator
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          );
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool mcld::sys::fs::exists(const Path &pPath)
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  FileStatus pFileStatus;
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  detail::status(pPath, pFileStatus);
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return exists(pFileStatus);
2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool mcld::sys::fs::is_directory(const Path &pPath)
2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  FileStatus pFileStatus;
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  detail::status(pPath, pFileStatus);
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return is_directory(pFileStatus);
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostd::ostream &mcld::sys::fs::operator<<(std::ostream& pOS,
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        const Path& pPath)
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pOS << pPath.native();
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostd::istream &mcld::sys::fs::operator>>(std::istream& pOS,
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                        Path& pPath)
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pOS >> pPath.native();
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaollvm::raw_ostream &mcld::sys::fs::operator<<(llvm::raw_ostream &pOS,
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                                             const Path &pPath)
2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return pOS << pPath.native();
2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
22667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
227