111
|
1 /* Find the correct compiler.
|
131
|
2 Copyright (C) 2014-2018 Free Software Foundation, Inc.
|
111
|
3
|
|
4 This file is part of GCC.
|
|
5
|
|
6 GCC is free software; you can redistribute it and/or modify it under
|
|
7 the terms of the GNU General Public License as published by the Free
|
|
8 Software Foundation; either version 3, or (at your option) any later
|
|
9 version.
|
|
10
|
|
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with GCC; see the file COPYING3. If not see
|
|
18 <http://www.gnu.org/licenses/>. */
|
|
19
|
|
20 #include <config.h>
|
|
21 #include <string>
|
|
22 #include <dirent.h>
|
|
23 #include <stdlib.h>
|
|
24
|
|
25 #include "libiberty.h"
|
|
26 #include "xregex.h"
|
|
27 #include "findcomp.hh"
|
|
28 #include "system.h"
|
|
29
|
|
30 class scanner
|
|
31 {
|
|
32 public:
|
|
33
|
|
34 scanner (const std::string &dir)
|
|
35 {
|
|
36 m_dir = opendir (dir.c_str ());
|
|
37 }
|
|
38
|
|
39 ~scanner ()
|
|
40 {
|
|
41 if (m_dir != NULL)
|
|
42 closedir (m_dir);
|
|
43 }
|
|
44
|
|
45 const char *next ()
|
|
46 {
|
|
47 if (m_dir == NULL)
|
|
48 return NULL;
|
|
49
|
|
50 struct dirent *entry = readdir (m_dir);
|
|
51 if (entry == NULL)
|
|
52 return NULL;
|
|
53
|
|
54 return entry->d_name;
|
|
55 }
|
|
56
|
|
57 private:
|
|
58
|
|
59 DIR *m_dir;
|
|
60 };
|
|
61
|
|
62 static bool
|
|
63 search_dir (const regex_t ®exp, const std::string &dir, std::string *result)
|
|
64 {
|
|
65 scanner scan (dir);
|
|
66 const char *filename;
|
|
67
|
|
68 while ((filename = scan.next ()) != NULL)
|
|
69 {
|
|
70 if (regexec (®exp, filename, 0, NULL, 0) == 0)
|
|
71 {
|
|
72 *result = dir + DIR_SEPARATOR + filename;
|
|
73 return true;
|
|
74 }
|
|
75 }
|
|
76
|
|
77 return false;
|
|
78 }
|
|
79
|
|
80 class tokenizer
|
|
81 {
|
|
82 public:
|
|
83
|
|
84 tokenizer (const char *str)
|
|
85 : m_str (str),
|
|
86 m_pos (0)
|
|
87 {
|
|
88 }
|
|
89
|
|
90 bool done () const
|
|
91 {
|
|
92 return m_pos == std::string::npos;
|
|
93 }
|
|
94
|
|
95 std::string next ()
|
|
96 {
|
|
97 std::string::size_type last_pos = m_pos;
|
|
98 std::string::size_type colon = m_str.find(':', last_pos);
|
|
99
|
|
100 std::string result;
|
|
101 if (colon == std::string::npos)
|
|
102 {
|
|
103 m_pos = colon;
|
|
104 result = m_str.substr(last_pos, colon);
|
|
105 }
|
|
106 else
|
|
107 {
|
|
108 m_pos = colon + 1;
|
|
109 result = m_str.substr(last_pos, colon - last_pos);
|
|
110 }
|
|
111 if (result == "")
|
|
112 result = ".";
|
|
113
|
|
114 return result;
|
|
115 }
|
|
116
|
|
117 private:
|
|
118
|
|
119 std::string m_str;
|
|
120 std::string::size_type m_pos;
|
|
121 };
|
|
122
|
|
123 bool
|
|
124 find_compiler (const regex_t ®exp, std::string *result)
|
|
125 {
|
|
126 const char *cpath = getenv ("PATH");
|
|
127
|
|
128 if (cpath == NULL)
|
|
129 return false;
|
|
130
|
|
131 tokenizer dirs (cpath);
|
|
132 while (!dirs.done ())
|
|
133 {
|
|
134 std::string dir = dirs.next ();
|
|
135 if (search_dir (regexp, dir, result))
|
|
136 return true;
|
|
137 }
|
|
138
|
|
139 return false;
|
|
140 }
|