15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- SearchDirs.cpp -----------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/SearchDirs.h"
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/MCLDDirectory.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileSystem.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// Non-member functions
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstatic inline void SpecToFilename(const std::string& pSpec,
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                  std::string& pFile) {
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pFile = "lib";
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  pFile += pSpec;
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
25affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// SearchDirs
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2837b74a387bb3993387029859c2d9d051c41c724eStephen HinesSearchDirs::SearchDirs() {
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // a magic number 8, no why.
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // please prove it or change it
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_DirList.reserve(8);
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3437b74a387bb3993387029859c2d9d051c41c724eStephen HinesSearchDirs::SearchDirs(const sys::fs::Path& pSysRoot) : m_SysRoot(pSysRoot) {
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // a magic number 8, no why.
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // please prove it or change it
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  m_DirList.reserve(8);
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4037b74a387bb3993387029859c2d9d051c41c724eStephen HinesSearchDirs::~SearchDirs() {
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  iterator dir, dirEnd = end();
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  for (dir = begin(); dir != dirEnd; ++dir) {
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete (*dir);
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool SearchDirs::insert(const std::string& pPath) {
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  MCLDDirectory* dir = new MCLDDirectory(pPath);
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (dir->isInSysroot())
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    dir->setSysroot(m_SysRoot);
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (exists(dir->path()) && is_directory(dir->path())) {
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    m_DirList.push_back(dir);
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return true;
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else {
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    delete dir;
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return false;
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return true;
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines}
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool SearchDirs::insert(const char* pPath) {
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  return insert(std::string(pPath));
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool SearchDirs::insert(const sys::fs::Path& pPath) {
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return insert(pPath.native());
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesmcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec,
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                      mcld::Input::Type pType) {
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(Input::DynObj == pType || Input::Archive == pType ||
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines         Input::Script == pType);
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  std::string file;
7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  switch (pType) {
7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case Input::Script:
7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      file.assign(pNamespec);
7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case Input::DynObj:
8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case Input::Archive:
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      SpecToFilename(pNamespec, file);
8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    default:
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // end of switch
8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // for all MCLDDirectorys
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end();
9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) {
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    // for all entries in MCLDDirectory
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    MCLDDirectory::iterator entry = (*mcld_dir)->begin();
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    switch (pType) {
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case Input::Script: {
9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        while (entry != enEnd) {
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines          if (file == entry.path()->filename().native())
9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines            return entry.path();
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ++entry;
10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }
10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      }
10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case Input::DynObj: {
10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines        while (entry != enEnd) {
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          if (file == entry.path()->stem().native()) {
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines            if (mcld::sys::fs::detail::shared_library_extension ==
10887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                entry.path()->extension().native()) {
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines              return entry.path();
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines            }
1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao          }
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ++entry;
113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
11487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      /** Fall through **/
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case Input::Archive: {
11737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        entry = (*mcld_dir)->begin();
11837b74a387bb3993387029859c2d9d051c41c724eStephen Hines        enEnd = (*mcld_dir)->end();
11937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        while (entry != enEnd) {
12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          if (file == entry.path()->stem().native() &&
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines              mcld::sys::fs::detail::static_library_extension ==
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines                  entry.path()->extension().native()) {
12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines            return entry.path();
12437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          }
12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ++entry;
12687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      default:
12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }  // end of switch
13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }    // end of for
132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return NULL;
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec,
13637b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                            mcld::Input::Type pType) const {
13737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(Input::DynObj == pType || Input::Archive == pType ||
13837b74a387bb3993387029859c2d9d051c41c724eStephen Hines         Input::Script == pType);
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  std::string file;
14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  switch (pType) {
14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case Input::Script:
14337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      file.assign(pNamespec);
14437b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case Input::DynObj:
14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    case Input::Archive:
14737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      SpecToFilename(pNamespec, file);
14837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
14937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    default:
15037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      break;
15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }  // end of switch
15287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // for all MCLDDirectorys
15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  DirList::const_iterator mcld_dir, mcld_dir_end = m_DirList.end();
15587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) {
15622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // for all entries in MCLDDirectory
15722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    MCLDDirectory::iterator entry = (*mcld_dir)->begin();
15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
15922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
16037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    switch (pType) {
16137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case Input::Script: {
16237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        while (entry != enEnd) {
16337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          if (file == entry.path()->filename().native())
16437b74a387bb3993387029859c2d9d051c41c724eStephen Hines            return entry.path();
16537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ++entry;
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hines        }
16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
16822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case Input::DynObj: {
17037b74a387bb3993387029859c2d9d051c41c724eStephen Hines        while (entry != enEnd) {
17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          if (file == entry.path()->stem().native()) {
17237b74a387bb3993387029859c2d9d051c41c724eStephen Hines            if (mcld::sys::fs::detail::shared_library_extension ==
17387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                entry.path()->extension().native()) {
17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines              return entry.path();
17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines            }
17622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          }
17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ++entry;
17822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
17987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      }
18037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      /** Fall through **/
18137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      case Input::Archive: {
18237b74a387bb3993387029859c2d9d051c41c724eStephen Hines        entry = (*mcld_dir)->begin();
18337b74a387bb3993387029859c2d9d051c41c724eStephen Hines        enEnd = (*mcld_dir)->end();
18437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        while (entry != enEnd) {
18537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          if (file == entry.path()->stem().native() &&
18637b74a387bb3993387029859c2d9d051c41c724eStephen Hines              mcld::sys::fs::detail::static_library_extension ==
18737b74a387bb3993387029859c2d9d051c41c724eStephen Hines                  entry.path()->extension().native()) {
18837b74a387bb3993387029859c2d9d051c41c724eStephen Hines            return entry.path();
18937b74a387bb3993387029859c2d9d051c41c724eStephen Hines          }
19037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ++entry;
19187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines        }
19222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
19337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      default:
19437b74a387bb3993387029859c2d9d051c41c724eStephen Hines        break;
19537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    }  // end of switch
19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }    // end of for
19722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return NULL;
19822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
19937b74a387bb3993387029859c2d9d051c41c724eStephen Hines
20037b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
201