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 <llvm/Support/ErrorHandling.h>
     10 #include <llvm/ADT/Twine.h>
     11 
     12 #include "mcld/MC/SearchDirs.h"
     13 #include "mcld/Support/FileSystem.h"
     14 #include "mcld/MC/MCLDDirectory.h"
     15 
     16 using namespace mcld;
     17 
     18 //==========================
     19 // Non-member functions
     20 static void SpecToFilename(const std::string& pSpec, std::string& pFile)
     21 {
     22   pFile = "lib";
     23   pFile += pSpec;
     24 }
     25 
     26 //==========================
     27 // SearchDirs
     28 SearchDirs::SearchDirs()
     29 {
     30   // a magic number 8, no why.
     31   // please prove it or change it
     32   m_DirList.reserve(8);
     33 }
     34 
     35 SearchDirs::~SearchDirs()
     36 {
     37   iterator dir, dirEnd = end();
     38   for (dir = begin(); dir!=dirEnd; ++dir) {
     39     delete (*dir);
     40   }
     41 }
     42 
     43 void SearchDirs::add(const MCLDDirectory& pDirectory)
     44 {
     45   m_DirList.push_back(new MCLDDirectory(pDirectory));
     46 }
     47 
     48 mcld::sys::fs::Path* SearchDirs::find(const std::string& pNamespec, mcld::Input::Type pType)
     49 {
     50   std::string file;
     51   SpecToFilename(pNamespec, file);
     52   // for all MCLDDirectorys
     53   DirList::iterator mcld_dir, mcld_dir_end = m_DirList.end();
     54   for (mcld_dir=m_DirList.begin(); mcld_dir!=mcld_dir_end; ++mcld_dir) {
     55     // for all entries in MCLDDirectory
     56     MCLDDirectory::iterator entry = (*mcld_dir)->begin();
     57     MCLDDirectory::iterator enEnd = (*mcld_dir)->end();
     58 
     59     switch(pType) {
     60       case Input::DynObj: {
     61         while (entry!=enEnd) {
     62           if (file == entry.path()->stem().native() ) {
     63             if(mcld::sys::fs::detail::shared_library_extension == entry.path()->extension().native()) {
     64               return entry.path();
     65             }
     66           }
     67 
     68           ++entry;
     69         }
     70       }
     71 
     72       case Input::Archive : {
     73         entry = (*mcld_dir)->begin();
     74         enEnd = (*mcld_dir)->end();
     75         while ( entry!=enEnd ) {
     76           if (file == entry.path()->stem().native() &&
     77             mcld::sys::fs::detail::static_library_extension == entry.path()->extension().native()) {
     78             return entry.path();
     79           }
     80           ++entry;
     81        }
     82      }
     83      default: {
     84        llvm::report_fatal_error(llvm::Twine("SearchDir can not recoginize namespec: `") +
     85                                 pNamespec +
     86                                 llvm::Twine("'."));
     87      }
     88     }
     89   }
     90   return 0;
     91 }
     92 
     93