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