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//===----------------------------------------------------------------------===//
9f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Config/Config.h>
10f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/FileSystem.h>
11f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/Path.h>
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/StringRef.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <locale>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string.h>
1667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <istream>
1767e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <ostream>
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld::sys::fs;
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===//
23f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// Helper
24f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===--------------------------------------------------------------------===//
25f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace {
26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#if defined(MCLD_ON_WIN32)
27f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool is_separator(char value)
28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
29f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return (value == separator || value == preferred_separator);
30f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
31f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
32f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesconst Path::StringType separator_str("/");
33f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
34f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#else
35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesbool is_separator(char value)
36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines{
37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return (value == separator);
38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
39f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
40f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesconst Path::StringType separator_str("/");
41f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
42f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif
43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines} // anonymous namespace
44f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===--------------------------------------------------------------------===//
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Path
48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===--------------------------------------------------------------------===//
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::Path()
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_PathName() {
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::Path(const Path::ValueType* s )
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_PathName(s) {
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::Path(const Path::StringType &s )
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : m_PathName(s) {
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::Path(const Path& pCopy)
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao : m_PathName(pCopy.m_PathName) {
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::~Path()
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Path::isFromRoot() const
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (m_PathName.empty())
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (separator == m_PathName[0]);
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Path::isFromPWD() const
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (2 > m_PathName.size())
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return ('.' == m_PathName[0] && separator == m_PathName[1]);
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath& Path::assign(const Path::StringType &s)
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_PathName.assign(s);
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath& Path::assign(const Path::ValueType* s, unsigned int length)
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (0 == s || 0 == length)
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "assign a null or empty string to Path");
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_PathName.assign(s, length);
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//a,/b a/,b a/,b/ a,b is a/b
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath& Path::append(const Path& pPath)
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //first path is a/,second path is /b
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(m_PathName[m_PathName.length()-1] == separator &&
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao     pPath.native()[0] == separator) {
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned int old_size = m_PathName.size()-1;
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    unsigned int new_size = old_size + pPath.native().size();
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.resize(new_size);
107f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    strcpy(const_cast<ValueType*>(m_PathName.data()+old_size), pPath.native().data());
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  //first path is a,second path is b
110f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  else if(this->native()[this->native().size()-1] != separator &&
111f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines          pPath.native()[0] != separator) {
112f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_PathName.append(separator_str);
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.append(pPath.native());
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // a/,b or a,/b just append
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  else {
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.append(pPath.native());
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Path::empty() const
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_PathName.empty();
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::StringType Path::generic_string() const
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  StringType result = m_PathName;
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  detail::canonicalize(result);
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool Path::canonicalize()
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return detail::canonicalize(m_PathName);
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath::StringType::size_type Path::m_append_separator_if_needed()
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#if defined(MCLD_ON_WIN32)
142f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // On Windows platform, path can not append separator.
143f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return 0;
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
146f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  StringType::value_type last_char = m_PathName[m_PathName.size() - 1];
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  if (!m_PathName.empty() &&
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines      !is_separator(last_char)) {
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    StringType::size_type tmp(m_PathName.size());
150f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_PathName += separator_str;
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return tmp;
1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid Path::m_erase_redundant_separator(Path::StringType::size_type pSepPos)
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t begin=pSepPos;
159f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // skip '/' or '\\'
160f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  while(separator == m_PathName[pSepPos]) {
161f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#if defined(MCLD_ON_WIN32)
162f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pSepPos += 2;
163f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#else
1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++pSepPos;
165f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif
166f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if(begin!=pSepPos)
1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.erase(begin+1,pSepPos-begin-1);
1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
172cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei LiaoPath Path::parent_path() const
173cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao{
174cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  size_t end_pos = m_PathName.find_last_of(separator);
175cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (end_pos != StringType::npos)
176cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return Path(m_PathName.substr(0, end_pos));
177cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return Path();
178cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
179cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
18022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoPath Path::filename() const
18122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t pos = m_PathName.find_last_of(separator);
18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pos != StringType::npos) {
18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++pos;
18522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return Path(m_PathName.substr(pos));
18622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
18722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return Path(*this);
18822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
18922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath Path::stem() const
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  size_t begin_pos = m_PathName.find_last_of(separator)+1;
193f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  size_t end_pos   = m_PathName.find_last_of(dot);
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Path result_path(m_PathName.substr(begin_pos, end_pos - begin_pos));
1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result_path;
1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoPath Path::extension() const
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
200f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  size_t pos = m_PathName.find_last_of('.');
201f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (pos == StringType::npos)
202f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    return Path();
203f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return Path(m_PathName.substr(pos));
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===//
2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// non-member functions
20867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===--------------------------------------------------------------------===//
2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool mcld::sys::fs::operator==(const Path& pLHS,const Path& pRHS)
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (pLHS.generic_string()==pRHS.generic_string());
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool mcld::sys::fs::operator!=(const Path& pLHS,const Path& pRHS)
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return !(pLHS==pRHS);
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
21967e37f1be98c926645219cfb47fab9e90d8c725cShih-wei LiaoPath mcld::sys::fs::operator+(const Path& pLHS, const Path& pRHS)
22067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao{
22167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::sys::fs::Path result = pLHS;
22267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  result.append(pRHS);
22367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  return result;
22467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
22567e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
226