summaryrefslogtreecommitdiff
path: root/lib/MC/SearchDirs.cpp
blob: 940553ea79a9abda4e43e9cea9887774c8e24498 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//===- SearchDirs.cpp -----------------------------------------------------===//
//
//                     The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/MC/SearchDirs.h>
#include <mcld/MC/MCLDDirectory.h>
#include <mcld/Support/FileSystem.h>

using namespace mcld;

//===----------------------------------------------------------------------===//
// Non-member functions
//===----------------------------------------------------------------------===//
static inline void SpecToFilename(const std::string& pSpec, std::string& pFile)
{
  pFile = "lib";
  pFile += pSpec;
}

//===----------------------------------------------------------------------===//
// SearchDirs
//===----------------------------------------------------------------------===//
SearchDirs::SearchDirs()
{
  // a magic number 8, no why.
  // please prove it or change it
  m_DirList.reserve(8);
}

SearchDirs::SearchDirs(const sys::fs::Path& pSysRoot)
  : m_SysRoot(pSysRoot) {
  // a magic number 8, no why.
  // please prove it or change it
  m_DirList.reserve(8);
}

SearchDirs::~SearchDirs()
{
  iterator dir, dirEnd = end();
  for (dir = begin(); dir!=dirEnd; ++dir) {
    delete (*dir);
  }
}

bool SearchDirs::insert(const std::string& pPath)
{
  MCLDDirectory* dir = new MCLDDirectory(pPath);
  if (dir->isInSysroot())
    dir->setSysroot(m_SysRoot);

  if (exists(dir->path()) && is_directory(dir->path())) {
    m_DirList.push_back(dir);
    return true;
  }
  else {
    delete dir;
    return false;
  }
  return true;
}

bool SearchDirs::insert(const char* pPath)
{
  return insert(std::string(pPath));
}

bool SearchDirs::insert(const sys::fs::Path& pPath)
{
  return insert(pPath.native());
}

mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType)
{
  assert(Input::DynObj == pType || Input::Archive == pType);

  std::string file;
  SpecToFilename(pNamespec, file);
  // for all MCLDDirectorys
  DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end();
  for (mcld_dir=m_DirList.begin(); mcld_dir!=mcld_dir_end; ++mcld_dir) {
    // for all entries in MCLDDirectory
    MCLDDirectory::iterator entry = (*mcld_dir)->begin();
    MCLDDirectory::iterator enEnd = (*mcld_dir)->end();

    switch(pType) {
      case Input::DynObj: {
        while (entry!=enEnd) {
          if (file == entry.path()->stem().native() ) {
            if(mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) {
              return entry.path();
            }
          }
          ++entry;
        }
      }
      /** Fall through **/
      case Input::Archive : {
        entry = (*mcld_dir)->begin();
        enEnd = (*mcld_dir)->end();
        while ( entry!=enEnd ) {
          if (file == entry.path()->stem().native() &&
            mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) {
            return entry.path();
          }
          ++entry;
        }
      }
      default:
        break;
    } // end of switch
  } // end of while
  return NULL;
}

const mcld::sys::fs::Path*
SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType) const
{
  assert(Input::DynObj == pType || Input::Archive == pType);

  std::string file;
  SpecToFilename(pNamespec, file);
  // for all MCLDDirectorys
  DirList::const_iterator mcld_dir, mcld_dir_end = m_DirList.end();
  for (mcld_dir=m_DirList.begin(); mcld_dir!=mcld_dir_end; ++mcld_dir) {
    // for all entries in MCLDDirectory
    MCLDDirectory::iterator entry = (*mcld_dir)->begin();
    MCLDDirectory::iterator enEnd = (*mcld_dir)->end();

    switch(pType) {
      case Input::DynObj: {
        while (entry!=enEnd) {
          if (file == entry.path()->stem().native() ) {
            if(mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) {
              return entry.path();
            }
          }
          ++entry;
        }
      }
      /** Fall through **/
      case Input::Archive : {
        entry = (*mcld_dir)->begin();
        enEnd = (*mcld_dir)->end();
        while ( entry!=enEnd ) {
          if (file == entry.path()->stem().native() &&
            mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) {
            return entry.path();
          }
          ++entry;
        }
      }
      default:
        break;
    } // end of switch
  } // end of while
  return NULL;
}