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 
Reset()14 void SearchPathList::Reset() {
15   list_.Resize(0);
16   env_list_.Resize(0);
17   full_path_.Resize(0);
18 }
19 
ResetFromEnv(const char * var_name)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 
AddPaths(const char * list,const char * list_end)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 
FindFile(const char * file_name)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