Home | History | Annotate | Download | only in MC
      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 //===----------------------------------------------------------------------===//
     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 //===----------------------------------------------------------------------===//
     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 
     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 
     41 SearchDirs::~SearchDirs()
     42 {
     43   iterator dir, dirEnd = end();
     44   for (dir = begin(); dir!=dirEnd; ++dir) {
     45     delete (*dir);
     46   }
     47 }
     48 
     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 
     66 bool SearchDirs::insert(const char* pPath)
     67 {
     68   return insert(std::string(pPath));
     69 }
     70 
     71 bool SearchDirs::insert(const sys::fs::Path& pPath)
     72 {
     73   return insert(pPath.native());
     74 }
     75 
     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*
    120 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