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
find(const std::string & pNamespec,mcld::Input::Type pType)76 mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType)
77 {
78 assert(Input::DynObj == pType || Input::Archive == pType);
79
80 std::string file;
81 SpecToFilename(pNamespec, file);
82 // for all MCLDDirectorys
83 DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end();
84 for (mcld_dir=m_DirList.begin(); mcld_dir!=mcld_dir_end; ++mcld_dir) {
85 // for all entries in MCLDDirectory
86 MCLDDirectory::iterator entry = (*mcld_dir)->begin();
87 MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
88
89 switch(pType) {
90 case Input::DynObj: {
91 while (entry!=enEnd) {
92 if (file == entry.path()->stem().native() ) {
93 if(mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) {
94 return entry.path();
95 }
96 }
97 ++entry;
98 }
99 }
100 /** Fall through **/
101 case Input::Archive : {
102 entry = (*mcld_dir)->begin();
103 enEnd = (*mcld_dir)->end();
104 while ( entry!=enEnd ) {
105 if (file == entry.path()->stem().native() &&
106 mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) {
107 return entry.path();
108 }
109 ++entry;
110 }
111 }
112 default:
113 break;
114 } // end of switch
115 } // end of while
116 return NULL;
117 }
118
119 const mcld::sys::fs::Path*
find(const std::string & pNamespec,mcld::Input::Type pType) const120 SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType) const
121 {
122 assert(Input::DynObj == pType || Input::Archive == pType);
123
124 std::string file;
125 SpecToFilename(pNamespec, file);
126 // for all MCLDDirectorys
127 DirList::const_iterator mcld_dir, mcld_dir_end = m_DirList.end();
128 for (mcld_dir=m_DirList.begin(); mcld_dir!=mcld_dir_end; ++mcld_dir) {
129 // for all entries in MCLDDirectory
130 MCLDDirectory::iterator entry = (*mcld_dir)->begin();
131 MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
132
133 switch(pType) {
134 case Input::DynObj: {
135 while (entry!=enEnd) {
136 if (file == entry.path()->stem().native() ) {
137 if(mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) {
138 return entry.path();
139 }
140 }
141 ++entry;
142 }
143 }
144 /** Fall through **/
145 case Input::Archive : {
146 entry = (*mcld_dir)->begin();
147 enEnd = (*mcld_dir)->end();
148 while ( entry!=enEnd ) {
149 if (file == entry.path()->stem().native() &&
150 mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) {
151 return entry.path();
152 }
153 ++entry;
154 }
155 }
156 default:
157 break;
158 } // end of switch
159 } // end of while
160 return NULL;
161 }
162