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