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 //===----------------------------------------------------------------------===//
SpecToFilename(const std::string & pSpec,std::string & pFile)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 //===----------------------------------------------------------------------===//
SearchDirs()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
SearchDirs(const sys::fs::Path & pSysRoot)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
~SearchDirs()41 SearchDirs::~SearchDirs()
42 {
43 iterator dir, dirEnd = end();
44 for (dir = begin(); dir!=dirEnd; ++dir) {
45 delete (*dir);
46 }
47 }
48
insert(const std::string & pPath)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
insert(const char * pPath)66 bool SearchDirs::insert(const char* pPath)
67 {
68 return insert(std::string(pPath));
69 }
70
insert(const sys::fs::Path & pPath)71 bool SearchDirs::insert(const sys::fs::Path& pPath)
72 {
73 return insert(pPath.native());
74 }
75
76 mcld::sys::fs::Path*
find(const std::string & pNamespec,mcld::Input::Type pType)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*
find(const std::string & pNamespec,mcld::Input::Type pType) const144 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