1//===- SearchDirs.cpp -----------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#include <mcld/MC/SearchDirs.h> 10#include <mcld/MC/MCLDDirectory.h> 11#include <mcld/Support/FileSystem.h> 12 13using namespace mcld; 14 15//===----------------------------------------------------------------------===// 16// Non-member functions 17//===----------------------------------------------------------------------===// 18static inline void SpecToFilename(const std::string& pSpec, std::string& pFile) 19{ 20 pFile = "lib"; 21 pFile += pSpec; 22} 23 24//===----------------------------------------------------------------------===// 25// SearchDirs 26//===----------------------------------------------------------------------===// 27SearchDirs::SearchDirs() 28{ 29 // a magic number 8, no why. 30 // please prove it or change it 31 m_DirList.reserve(8); 32} 33 34SearchDirs::SearchDirs(const sys::fs::Path& pSysRoot) 35 : m_SysRoot(pSysRoot) { 36 // a magic number 8, no why. 37 // please prove it or change it 38 m_DirList.reserve(8); 39} 40 41SearchDirs::~SearchDirs() 42{ 43 iterator dir, dirEnd = end(); 44 for (dir = begin(); dir!=dirEnd; ++dir) { 45 delete (*dir); 46 } 47} 48 49bool SearchDirs::insert(const std::string& pPath) 50{ 51 MCLDDirectory* dir = new MCLDDirectory(pPath); 52 if (dir->isInSysroot()) 53 dir->setSysroot(m_SysRoot); 54 55 if (exists(dir->path()) && is_directory(dir->path())) { 56 m_DirList.push_back(dir); 57 return true; 58 } 59 else { 60 delete dir; 61 return false; 62 } 63 return true; 64} 65 66bool SearchDirs::insert(const char* pPath) 67{ 68 return insert(std::string(pPath)); 69} 70 71bool SearchDirs::insert(const sys::fs::Path& pPath) 72{ 73 return insert(pPath.native()); 74} 75 76mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType) 77{ 78 assert(Input::DynObj == pType || Input::Archive == pType); 79 80 std::string file; 81 SpecToFilename(pNamespec, file); 82 // for all MCLDDirectorys 83 DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end(); 84 for (mcld_dir=m_DirList.begin(); mcld_dir!=mcld_dir_end; ++mcld_dir) { 85 // for all entries in MCLDDirectory 86 MCLDDirectory::iterator entry = (*mcld_dir)->begin(); 87 MCLDDirectory::iterator enEnd = (*mcld_dir)->end(); 88 89 switch(pType) { 90 case Input::DynObj: { 91 while (entry!=enEnd) { 92 if (file == entry.path()->stem().native() ) { 93 if(mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) { 94 return entry.path(); 95 } 96 } 97 ++entry; 98 } 99 } 100 /** Fall through **/ 101 case Input::Archive : { 102 entry = (*mcld_dir)->begin(); 103 enEnd = (*mcld_dir)->end(); 104 while ( entry!=enEnd ) { 105 if (file == entry.path()->stem().native() && 106 mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) { 107 return entry.path(); 108 } 109 ++entry; 110 } 111 } 112 default: 113 break; 114 } // end of switch 115 } // end of while 116 return NULL; 117} 118 119const mcld::sys::fs::Path* 120SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType) const 121{ 122 assert(Input::DynObj == pType || Input::Archive == pType); 123 124 std::string file; 125 SpecToFilename(pNamespec, file); 126 // for all MCLDDirectorys 127 DirList::const_iterator mcld_dir, mcld_dir_end = m_DirList.end(); 128 for (mcld_dir=m_DirList.begin(); mcld_dir!=mcld_dir_end; ++mcld_dir) { 129 // for all entries in MCLDDirectory 130 MCLDDirectory::iterator entry = (*mcld_dir)->begin(); 131 MCLDDirectory::iterator enEnd = (*mcld_dir)->end(); 132 133 switch(pType) { 134 case Input::DynObj: { 135 while (entry!=enEnd) { 136 if (file == entry.path()->stem().native() ) { 137 if(mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) { 138 return entry.path(); 139 } 140 } 141 ++entry; 142 } 143 } 144 /** Fall through **/ 145 case Input::Archive : { 146 entry = (*mcld_dir)->begin(); 147 enEnd = (*mcld_dir)->end(); 148 while ( entry!=enEnd ) { 149 if (file == entry.path()->stem().native() && 150 mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) { 151 return entry.path(); 152 } 153 ++entry; 154 } 155 } 156 default: 157 break; 158 } // end of switch 159 } // end of while 160 return NULL; 161} 162