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