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*
     77 SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType)
     78 {
     79   assert(Input::DynObj  == pType ||
     80          Input::Archive == pType ||
     81          Input::Script  == pType);
     82 
     83   std::string file;
     84   switch(pType) {
     85   case Input::Script:
     86     file.assign(pNamespec);
     87     break;
     88   case Input::DynObj:
     89   case Input::Archive :
     90     SpecToFilename(pNamespec, file);
     91     break;
     92   default:
     93     break;
     94   } // end of switch
     95 
     96   // for all MCLDDirectorys
     97   DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end();
     98   for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) {
     99     // for all entries in MCLDDirectory
    100     MCLDDirectory::iterator entry = (*mcld_dir)->begin();
    101     MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
    102 
    103     switch(pType) {
    104     case Input::Script: {
    105       while (entry != enEnd) {
    106         if (file == entry.path()->filename())
    107           return entry.path();
    108         ++entry;
    109       }
    110       break;
    111     }
    112     case Input::DynObj: {
    113       while (entry != enEnd) {
    114         if (file == entry.path()->stem().native() ) {
    115           if (mcld::sys::fs::detail::shared_library_extension ==
    116                 entry.path()->extension().native()) {
    117             return entry.path();
    118           }
    119         }
    120         ++entry;
    121       }
    122     }
    123     /** Fall through **/
    124     case Input::Archive : {
    125       entry = (*mcld_dir)->begin();
    126       enEnd = (*mcld_dir)->end();
    127       while (entry != enEnd) {
    128         if (file == entry.path()->stem().native() &&
    129             mcld::sys::fs::detail::static_library_extension ==
    130               entry.path()->extension().native()) {
    131           return entry.path();
    132         }
    133         ++entry;
    134       }
    135     }
    136     default:
    137       break;
    138     } // end of switch
    139   } // end of for
    140   return NULL;
    141 }
    142 
    143 const mcld::sys::fs::Path*
    144 SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType) const
    145 {
    146   assert(Input::DynObj  == pType ||
    147          Input::Archive == pType ||
    148          Input::Script  == pType);
    149 
    150   std::string file;
    151   switch(pType) {
    152   case Input::Script:
    153     file.assign(pNamespec);
    154     break;
    155   case Input::DynObj:
    156   case Input::Archive :
    157     SpecToFilename(pNamespec, file);
    158     break;
    159   default:
    160     break;
    161   } // end of switch
    162 
    163   // for all MCLDDirectorys
    164   DirList::const_iterator mcld_dir, mcld_dir_end = m_DirList.end();
    165   for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) {
    166     // for all entries in MCLDDirectory
    167     MCLDDirectory::iterator entry = (*mcld_dir)->begin();
    168     MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
    169 
    170     switch(pType) {
    171     case Input::Script: {
    172       while (entry != enEnd) {
    173         if (file == entry.path()->filename())
    174           return entry.path();
    175         ++entry;
    176       }
    177       break;
    178     }
    179     case Input::DynObj: {
    180       while (entry != enEnd) {
    181         if (file == entry.path()->stem().native() ) {
    182           if (mcld::sys::fs::detail::shared_library_extension ==
    183                 entry.path()->extension().native()) {
    184             return entry.path();
    185           }
    186         }
    187         ++entry;
    188       }
    189     }
    190     /** Fall through **/
    191     case Input::Archive : {
    192       entry = (*mcld_dir)->begin();
    193       enEnd = (*mcld_dir)->end();
    194       while ( entry!=enEnd ) {
    195         if (file == entry.path()->stem().native() &&
    196             mcld::sys::fs::detail::static_library_extension ==
    197               entry.path()->extension().native()) {
    198           return entry.path();
    199         }
    200         ++entry;
    201       }
    202     }
    203     default:
    204       break;
    205     } // end of switch
    206   } // end of for
    207   return NULL;
    208 }
    209