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 
     11 #include "mcld/MC/MCLDDirectory.h"
     12 #include "mcld/Support/FileSystem.h"
     13 
     14 namespace mcld {
     15 
     16 //===----------------------------------------------------------------------===//
     17 // Non-member functions
     18 //===----------------------------------------------------------------------===//
     19 static inline void SpecToFilename(const std::string& pSpec,
     20                                   std::string& pFile) {
     21   pFile = "lib";
     22   pFile += pSpec;
     23 }
     24 
     25 //===----------------------------------------------------------------------===//
     26 // SearchDirs
     27 //===----------------------------------------------------------------------===//
     28 SearchDirs::SearchDirs() {
     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) : m_SysRoot(pSysRoot) {
     35   // a magic number 8, no why.
     36   // please prove it or change it
     37   m_DirList.reserve(8);
     38 }
     39 
     40 SearchDirs::~SearchDirs() {
     41   iterator dir, dirEnd = end();
     42   for (dir = begin(); dir != dirEnd; ++dir) {
     43     delete (*dir);
     44   }
     45 }
     46 
     47 bool SearchDirs::insert(const std::string& pPath) {
     48   MCLDDirectory* dir = new MCLDDirectory(pPath);
     49   if (dir->isInSysroot())
     50     dir->setSysroot(m_SysRoot);
     51 
     52   if (exists(dir->path()) && is_directory(dir->path())) {
     53     m_DirList.push_back(dir);
     54     return true;
     55   } else {
     56     delete dir;
     57     return false;
     58   }
     59   return true;
     60 }
     61 
     62 bool SearchDirs::insert(const char* pPath) {
     63   return insert(std::string(pPath));
     64 }
     65 
     66 bool SearchDirs::insert(const sys::fs::Path& pPath) {
     67   return insert(pPath.native());
     68 }
     69 
     70 mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec,
     71                                       mcld::Input::Type pType) {
     72   assert(Input::DynObj == pType || Input::Archive == pType ||
     73          Input::Script == pType);
     74 
     75   std::string file;
     76   switch (pType) {
     77     case Input::Script:
     78       file.assign(pNamespec);
     79       break;
     80     case Input::DynObj:
     81     case Input::Archive:
     82       SpecToFilename(pNamespec, file);
     83       break;
     84     default:
     85       break;
     86   }  // end of switch
     87 
     88   // for all MCLDDirectorys
     89   DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end();
     90   for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) {
     91     // for all entries in MCLDDirectory
     92     MCLDDirectory::iterator entry = (*mcld_dir)->begin();
     93     MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
     94 
     95     switch (pType) {
     96       case Input::Script: {
     97         while (entry != enEnd) {
     98           if (file == entry.path()->filename().native())
     99             return entry.path();
    100           ++entry;
    101         }
    102         break;
    103       }
    104       case Input::DynObj: {
    105         while (entry != enEnd) {
    106           if (file == entry.path()->stem().native()) {
    107             if (mcld::sys::fs::detail::shared_library_extension ==
    108                 entry.path()->extension().native()) {
    109               return entry.path();
    110             }
    111           }
    112           ++entry;
    113         }
    114       }
    115       /** Fall through **/
    116       case Input::Archive: {
    117         entry = (*mcld_dir)->begin();
    118         enEnd = (*mcld_dir)->end();
    119         while (entry != enEnd) {
    120           if (file == entry.path()->stem().native() &&
    121               mcld::sys::fs::detail::static_library_extension ==
    122                   entry.path()->extension().native()) {
    123             return entry.path();
    124           }
    125           ++entry;
    126         }
    127       }
    128       default:
    129         break;
    130     }  // end of switch
    131   }    // end of for
    132   return NULL;
    133 }
    134 
    135 const mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec,
    136                                             mcld::Input::Type pType) const {
    137   assert(Input::DynObj == pType || Input::Archive == pType ||
    138          Input::Script == pType);
    139 
    140   std::string file;
    141   switch (pType) {
    142     case Input::Script:
    143       file.assign(pNamespec);
    144       break;
    145     case Input::DynObj:
    146     case Input::Archive:
    147       SpecToFilename(pNamespec, file);
    148       break;
    149     default:
    150       break;
    151   }  // end of switch
    152 
    153   // for all MCLDDirectorys
    154   DirList::const_iterator mcld_dir, mcld_dir_end = m_DirList.end();
    155   for (mcld_dir = m_DirList.begin(); mcld_dir != mcld_dir_end; ++mcld_dir) {
    156     // for all entries in MCLDDirectory
    157     MCLDDirectory::iterator entry = (*mcld_dir)->begin();
    158     MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
    159 
    160     switch (pType) {
    161       case Input::Script: {
    162         while (entry != enEnd) {
    163           if (file == entry.path()->filename().native())
    164             return entry.path();
    165           ++entry;
    166         }
    167         break;
    168       }
    169       case Input::DynObj: {
    170         while (entry != enEnd) {
    171           if (file == entry.path()->stem().native()) {
    172             if (mcld::sys::fs::detail::shared_library_extension ==
    173                 entry.path()->extension().native()) {
    174               return entry.path();
    175             }
    176           }
    177           ++entry;
    178         }
    179       }
    180       /** Fall through **/
    181       case Input::Archive: {
    182         entry = (*mcld_dir)->begin();
    183         enEnd = (*mcld_dir)->end();
    184         while (entry != enEnd) {
    185           if (file == entry.path()->stem().native() &&
    186               mcld::sys::fs::detail::static_library_extension ==
    187                   entry.path()->extension().native()) {
    188             return entry.path();
    189           }
    190           ++entry;
    191         }
    192       }
    193       default:
    194         break;
    195     }  // end of switch
    196   }    // end of for
    197   return NULL;
    198 }
    199 
    200 }  // namespace mcld
    201