SearchDirs.cpp revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
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
13using namespace mcld;
14
15//===----------------------------------------------------------------------===//
16// Non-member functions
17//===----------------------------------------------------------------------===//
18static inline void SpecToFilename(const std::string& pSpec, std::string& pFile)
19{
20  pFile = "lib";
21  pFile += pSpec;
22}
23
24//===----------------------------------------------------------------------===//
25// SearchDirs
26//===----------------------------------------------------------------------===//
27SearchDirs::SearchDirs()
28{
29  // a magic number 8, no why.
30  // please prove it or change it
31  m_DirList.reserve(8);
32}
33
34SearchDirs::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
41SearchDirs::~SearchDirs()
42{
43  iterator dir, dirEnd = end();
44  for (dir = begin(); dir!=dirEnd; ++dir) {
45    delete (*dir);
46  }
47}
48
49bool 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
66bool SearchDirs::insert(const char* pPath)
67{
68  return insert(std::string(pPath));
69}
70
71bool SearchDirs::insert(const sys::fs::Path& pPath)
72{
73  return insert(pPath.native());
74}
75
76mcld::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
119const mcld::sys::fs::Path*
120SearchDirs::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