Path.cpp revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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