| //===- 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 |