• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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