Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "crazy_linker_search_path_list.h"
      6 
      7 #include <string.h>
      8 
      9 #include "crazy_linker_debug.h"
     10 #include "crazy_linker_system.h"
     11 
     12 namespace crazy {
     13 
     14 void SearchPathList::Reset() {
     15   list_.Resize(0);
     16   env_list_.Resize(0);
     17   full_path_.Resize(0);
     18 }
     19 
     20 void SearchPathList::ResetFromEnv(const char* var_name) {
     21   Reset();
     22   const char* env = GetEnv(var_name);
     23   if (env && *env)
     24     env_list_ = env;
     25 }
     26 
     27 void SearchPathList::AddPaths(const char* list, const char* list_end) {
     28   // Append a column to the current list, if necessary
     29   if (list_.size() > 0 && list_[list_.size() - 1] != ':')
     30     list_ += ':';
     31   list_.Append(list, list_end - list);
     32 }
     33 
     34 const char* SearchPathList::FindFile(const char* file_name) {
     35   // Sanity checks.
     36   if (!file_name || !*file_name)
     37     return NULL;
     38 
     39   LOG("%s: Looking for %s\n", __FUNCTION__, file_name);
     40 
     41   // Build full list by appending the env_list_ after the regular one.
     42   String full_list = list_;
     43   if (env_list_.size() > 0) {
     44     if (full_list.size() > 0 && full_list[full_list.size() - 1] != ':')
     45       full_list += ':';
     46     full_list += env_list_;
     47   }
     48 
     49   // Iterate over all items in the list.
     50   const char* p = full_list.c_str();
     51   const char* end = p + full_list.size();
     52 
     53   while (p < end) {
     54     // compute current list item, and next item start at the same time.
     55     const char* item = p;
     56     const char* item_end =
     57         reinterpret_cast<const char*>(memchr(p, ':', end - p));
     58     if (item_end)
     59       p = item_end + 1;
     60     else {
     61       item_end = end;
     62       p = end;
     63     }
     64 
     65     full_path_.Assign(item, item_end - item);
     66 
     67     // Add trailing directory separator if needed.
     68     if (full_path_.size() > 0 && full_path_[full_path_.size() - 1] != '/')
     69       full_path_ += '/';
     70 
     71     full_path_ += file_name;
     72 
     73     if (PathIsFile(full_path_.c_str())) {
     74       LOG("    FOUND %s\n", full_path_.c_str());
     75       return full_path_.c_str();
     76     } else
     77       LOG("    skip  %s\n", full_path_.c_str());
     78   }
     79 
     80   return NULL;
     81 }
     82 
     83 }  // namespace crazy
     84