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
14 namespace mcld {
15
16 //===----------------------------------------------------------------------===//
17 // Non-member functions
18 //===----------------------------------------------------------------------===//
SpecToFilename(const std::string & pSpec,std::string & pFile)19 static inline void SpecToFilename(const std::string& pSpec,
20 std::string& pFile) {
21 pFile = "lib";
22 pFile += pSpec;
23 }
24
25 //===----------------------------------------------------------------------===//
26 // SearchDirs
27 //===----------------------------------------------------------------------===//
SearchDirs()28 SearchDirs::SearchDirs() {
29 // a magic number 8, no why.
30 // please prove it or change it
31 m_DirList.reserve(8);
32 }
33
SearchDirs(const sys::fs::Path & pSysRoot)34 SearchDirs::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
~SearchDirs()40 SearchDirs::~SearchDirs() {
41 iterator dir, dirEnd = end();
42 for (dir = begin(); dir != dirEnd; ++dir) {
43 delete (*dir);
44 }
45 }
46
insert(const std::string & pPath)47 bool 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
insert(const char * pPath)62 bool SearchDirs::insert(const char* pPath) {
63 return insert(std::string(pPath));
64 }
65
insert(const sys::fs::Path & pPath)66 bool SearchDirs::insert(const sys::fs::Path& pPath) {
67 return insert(pPath.native());
68 }
69
find(const std::string & pNamespec,mcld::Input::Type pType)70 mcld::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
find(const std::string & pNamespec,mcld::Input::Type pType) const135 const 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