//===- SearchDirs.cpp -----------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "mcld/MC/SearchDirs.h" #include "mcld/MC/MCLDDirectory.h" #include "mcld/Support/FileSystem.h" namespace mcld { //===----------------------------------------------------------------------===// // Non-member functions //===----------------------------------------------------------------------===// static inline void SpecToFilename(const std::string& pSpec, std::string& pFile) { pFile = "lib"; pFile += pSpec; } //===----------------------------------------------------------------------===// // SearchDirs //===----------------------------------------------------------------------===// SearchDirs::SearchDirs() { // a magic number 8, no why. // please prove it or change it m_DirList.reserve(8); } SearchDirs::SearchDirs(const sys::fs::Path& pSysRoot) : m_SysRoot(pSysRoot) { // a magic number 8, no why. // please prove it or change it m_DirList.reserve(8); } SearchDirs::~SearchDirs() { iterator dir, dirEnd = end(); for (dir = begin(); dir != dirEnd; ++dir) { delete (*dir); } } bool SearchDirs::insert(const std::string& pPath) { MCLDDirectory* dir = new MCLDDirectory(pPath); if (dir->isInSysroot()) dir->setSysroot(m_SysRoot); if (exists(dir->path()) && is_directory(dir->path())) { m_DirList.push_back(dir); return true; } else { delete dir; return false; } return true; } bool SearchDirs::insert(const char* pPath) { return insert(std::string(pPath)); } bool SearchDirs::insert(const sys::fs::Path& pPath) { return insert(pPath.native()); } mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType) { assert(Input::DynObj == pType || Input::Archive == pType || Input::Script == pType); std::string file; switch (pType) { case Input::Script: file.assign(pNamespec); break; case Input::DynObj: case Input::Archive: SpecToFilename(pNamespec, file); break; default: break; } // end of switch // for all MCLDDirectorys DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end(); for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) { // for all entries in MCLDDirectory MCLDDirectory::iterator entry = (*mcld_dir)->begin(); MCLDDirectory::iterator enEnd = (*mcld_dir)->end(); switch (pType) { case Input::Script: { while (entry != enEnd) { if (file == entry.path()->filename().native()) return entry.path(); ++entry; } break; } case Input::DynObj: { while (entry != enEnd) { if (file == entry.path()->stem().native()) { if (mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) { return entry.path(); } } ++entry; } } /** Fall through **/ case Input::Archive: { entry = (*mcld_dir)->begin(); enEnd = (*mcld_dir)->end(); while (entry != enEnd) { if (file == entry.path()->stem().native() && mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) { return entry.path(); } ++entry; } } default: break; } // end of switch } // end of for return NULL; } const mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType) const { assert(Input::DynObj == pType || Input::Archive == pType || Input::Script == pType); std::string file; switch (pType) { case Input::Script: file.assign(pNamespec); break; case Input::DynObj: case Input::Archive: SpecToFilename(pNamespec, file); break; default: break; } // end of switch // for all MCLDDirectorys DirList::const_iterator mcld_dir, mcld_dir_end = m_DirList.end(); for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) { // for all entries in MCLDDirectory MCLDDirectory::iterator entry = (*mcld_dir)->begin(); MCLDDirectory::iterator enEnd = (*mcld_dir)->end(); switch (pType) { case Input::Script: { while (entry != enEnd) { if (file == entry.path()->filename().native()) return entry.path(); ++entry; } break; } case Input::DynObj: { while (entry != enEnd) { if (file == entry.path()->stem().native()) { if (mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) { return entry.path(); } } ++entry; } } /** Fall through **/ case Input::Archive: { entry = (*mcld_dir)->begin(); enEnd = (*mcld_dir)->end(); while (entry != enEnd) { if (file == entry.path()->stem().native() && mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) { return entry.path(); } ++entry; } } default: break; } // end of switch } // end of for return NULL; } } // namespace mcld