• 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 
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