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 11#include "mcld/MC/MCLDDirectory.h" 12#include "mcld/Support/FileSystem.h" 13 14namespace mcld { 15 16//===----------------------------------------------------------------------===// 17// Non-member functions 18//===----------------------------------------------------------------------===// 19static inline void SpecToFilename(const std::string& pSpec, 20 std::string& pFile) { 21 pFile = "lib"; 22 pFile += pSpec; 23} 24 25//===----------------------------------------------------------------------===// 26// SearchDirs 27//===----------------------------------------------------------------------===// 28SearchDirs::SearchDirs() { 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) : m_SysRoot(pSysRoot) { 35 // a magic number 8, no why. 36 // please prove it or change it 37 m_DirList.reserve(8); 38} 39 40SearchDirs::~SearchDirs() { 41 iterator dir, dirEnd = end(); 42 for (dir = begin(); dir != dirEnd; ++dir) { 43 delete (*dir); 44 } 45} 46 47bool SearchDirs::insert(const std::string& pPath) { 48 MCLDDirectory* dir = new MCLDDirectory(pPath); 49 if (dir->isInSysroot()) 50 dir->setSysroot(m_SysRoot); 51 52 if (exists(dir->path()) && is_directory(dir->path())) { 53 m_DirList.push_back(dir); 54 return true; 55 } else { 56 delete dir; 57 return false; 58 } 59 return true; 60} 61 62bool SearchDirs::insert(const char* pPath) { 63 return insert(std::string(pPath)); 64} 65 66bool SearchDirs::insert(const sys::fs::Path& pPath) { 67 return insert(pPath.native()); 68} 69 70mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, 71 mcld::Input::Type pType) { 72 assert(Input::DynObj == pType || Input::Archive == pType || 73 Input::Script == pType); 74 75 std::string file; 76 switch (pType) { 77 case Input::Script: 78 file.assign(pNamespec); 79 break; 80 case Input::DynObj: 81 case Input::Archive: 82 SpecToFilename(pNamespec, file); 83 break; 84 default: 85 break; 86 } // end of switch 87 88 // for all MCLDDirectorys 89 DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end(); 90 for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) { 91 // for all entries in MCLDDirectory 92 MCLDDirectory::iterator entry = (*mcld_dir)->begin(); 93 MCLDDirectory::iterator enEnd = (*mcld_dir)->end(); 94 95 switch (pType) { 96 case Input::Script: { 97 while (entry != enEnd) { 98 if (file == entry.path()->filename().native()) 99 return entry.path(); 100 ++entry; 101 } 102 break; 103 } 104 case Input::DynObj: { 105 while (entry != enEnd) { 106 if (file == entry.path()->stem().native()) { 107 if (mcld::sys::fs::detail::shared_library_extension == 108 entry.path()->extension().native()) { 109 return entry.path(); 110 } 111 } 112 ++entry; 113 } 114 } 115 /** Fall through **/ 116 case Input::Archive: { 117 entry = (*mcld_dir)->begin(); 118 enEnd = (*mcld_dir)->end(); 119 while (entry != enEnd) { 120 if (file == entry.path()->stem().native() && 121 mcld::sys::fs::detail::static_library_extension == 122 entry.path()->extension().native()) { 123 return entry.path(); 124 } 125 ++entry; 126 } 127 } 128 default: 129 break; 130 } // end of switch 131 } // end of for 132 return NULL; 133} 134 135const mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, 136 mcld::Input::Type pType) const { 137 assert(Input::DynObj == pType || Input::Archive == pType || 138 Input::Script == pType); 139 140 std::string file; 141 switch (pType) { 142 case Input::Script: 143 file.assign(pNamespec); 144 break; 145 case Input::DynObj: 146 case Input::Archive: 147 SpecToFilename(pNamespec, file); 148 break; 149 default: 150 break; 151 } // end of switch 152 153 // for all MCLDDirectorys 154 DirList::const_iterator mcld_dir, mcld_dir_end = m_DirList.end(); 155 for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) { 156 // for all entries in MCLDDirectory 157 MCLDDirectory::iterator entry = (*mcld_dir)->begin(); 158 MCLDDirectory::iterator enEnd = (*mcld_dir)->end(); 159 160 switch (pType) { 161 case Input::Script: { 162 while (entry != enEnd) { 163 if (file == entry.path()->filename().native()) 164 return entry.path(); 165 ++entry; 166 } 167 break; 168 } 169 case Input::DynObj: { 170 while (entry != enEnd) { 171 if (file == entry.path()->stem().native()) { 172 if (mcld::sys::fs::detail::shared_library_extension == 173 entry.path()->extension().native()) { 174 return entry.path(); 175 } 176 } 177 ++entry; 178 } 179 } 180 /** Fall through **/ 181 case Input::Archive: { 182 entry = (*mcld_dir)->begin(); 183 enEnd = (*mcld_dir)->end(); 184 while (entry != enEnd) { 185 if (file == entry.path()->stem().native() && 186 mcld::sys::fs::detail::static_library_extension == 187 entry.path()->extension().native()) { 188 return entry.path(); 189 } 190 ++entry; 191 } 192 } 193 default: 194 break; 195 } // end of switch 196 } // end of for 197 return NULL; 198} 199 200} // namespace mcld 201