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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Path.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Config/Config.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileSystem.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/ADT/StringRef.h>
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1667e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <istream>
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <locale>
1867e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao#include <ostream>
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <string.h>
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace sys {
2337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace fs {
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===//
26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// Helper
27f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===--------------------------------------------------------------------===//
28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace {
29f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#if defined(MCLD_ON_WIN32)
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool is_separator(char value) {
31f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return (value == separator || value == preferred_separator);
32f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
33f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
34f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesconst Path::StringType separator_str("/");
35f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
36f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#else
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool is_separator(char value) {
38f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return (value == separator);
39f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines}
40f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
41f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesconst Path::StringType separator_str("/");
42f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
43f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // anonymous namespace
45f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
46f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===--------------------------------------------------------------------===//
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Path
48f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===--------------------------------------------------------------------===//
4937b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::Path() : m_PathName() {
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5237b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::Path(const Path::ValueType* s) : m_PathName(s) {
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5537b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::Path(const Path::StringType& s) : m_PathName(s) {
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5837b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::Path(const Path& pCopy) : m_PathName(pCopy.m_PathName) {
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6137b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::~Path() {
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Path::isFromRoot() const {
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (m_PathName.empty())
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (separator == m_PathName[0]);
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Path::isFromPWD() const {
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_PathName.size() < 2)
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    return false;
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return ('.' == m_PathName[0] && separator == m_PathName[1]);
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7637b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath& Path::assign(const Path::StringType& s) {
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_PathName.assign(s);
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8137b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath& Path::assign(const Path::ValueType* s, unsigned int length) {
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (s == 0 || length == 0)
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    assert(0 && "assign a null or empty string to Path");
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_PathName.assign(s, length);
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines// a,/b a/,b a/,b/ a,b is a/b
8937b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath& Path::append(const Path& pPath) {
9037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  // first path is a/,second path is /b
9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_PathName[m_PathName.length() - 1] == separator &&
9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pPath.native()[0] == separator) {
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    llvm::StringRef path(pPath.native());
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    m_PathName.append(path.begin() + 1, path.end());
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else if (this->native()[this->native().size() - 1] != separator &&
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines             pPath.native()[0] != separator) {
9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    // first path is a,second path is b
98f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_PathName.append(separator_str);
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.append(pPath.native());
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    // a/,b or a,/b just append
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    m_PathName.append(pPath.native());
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return *this;
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines// a,/b a/,b a/,b/ a,b is a/b
10837b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath& Path::append(const StringType& pPath) {
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  Path path(pPath);
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  this->append(path);
11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return *this;
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines}
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
11437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Path::empty() const {
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_PathName.empty();
1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11837b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::StringType Path::generic_string() const {
119f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  StringType result = m_PathName;
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  detail::canonicalize(result);
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool Path::canonicalize() {
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return detail::canonicalize(m_PathName);
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
12837b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath::StringType::size_type Path::m_append_separator_if_needed() {
129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#if defined(MCLD_ON_WIN32)
130f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // On Windows platform, path can not append separator.
131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  return 0;
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
133f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines
134f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  StringType::value_type last_char = m_PathName[m_PathName.size() - 1];
13537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (!m_PathName.empty() && !is_separator(last_char)) {
136f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    StringType::size_type tmp(m_PathName.size());
137f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    m_PathName += separator_str;
138f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    return tmp;
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return 0;
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid Path::m_erase_redundant_separator(Path::StringType::size_type pSepPos) {
14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t begin = pSepPos;
145f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // skip '/' or '\\'
14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  while (separator == m_PathName[pSepPos]) {
147f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#if defined(MCLD_ON_WIN32)
148f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines    pSepPos += 2;
149f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#else
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    ++pSepPos;
151f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#endif
152f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  }
1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (begin != pSepPos)
15537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    m_PathName.erase(begin + 1, pSepPos - begin - 1);
1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15837b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath Path::parent_path() const {
159cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  size_t end_pos = m_PathName.find_last_of(separator);
160cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  if (end_pos != StringType::npos)
161cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao    return Path(m_PathName.substr(0, end_pos));
162cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao  return Path();
163cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao}
164cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
16537b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath Path::filename() const {
16622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  size_t pos = m_PathName.find_last_of(separator);
16722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (pos != StringType::npos) {
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++pos;
16922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return Path(m_PathName.substr(pos));
17022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
17122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return Path(*this);
17222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
17437b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath Path::stem() const {
17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t begin_pos = m_PathName.find_last_of(separator) + 1;
17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  size_t end_pos = m_PathName.find_last_of(dot);
1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Path result_path(m_PathName.substr(begin_pos, end_pos - begin_pos));
1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result_path;
1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
18137b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath Path::extension() const {
182f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  size_t pos = m_PathName.find_last_of('.');
183f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  if (pos == StringType::npos)
184f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines    return Path();
185f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines  return Path(m_PathName.substr(pos));
1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===--------------------------------------------------------------------===//
1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// non-member functions
19067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao//===--------------------------------------------------------------------===//
19137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool operator==(const Path& pLHS, const Path& pRHS) {
19237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return (pLHS.generic_string() == pRHS.generic_string());
1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
19537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool operator!=(const Path& pLHS, const Path& pRHS) {
19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return !(pLHS == pRHS);
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
19937b74a387bb3993387029859c2d9d051c41c724eStephen HinesPath operator+(const Path& pLHS, const Path& pRHS) {
20067e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  mcld::sys::fs::Path result = pLHS;
20167e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  result.append(pRHS);
20267e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao  return result;
20367e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao}
20467e37f1be98c926645219cfb47fab9e90d8c725cShih-wei Liao
20537b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace fs
20637b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace sys
20737b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
208