Line data Source code
1 : /* Utility functions for finding files relative to GCC binaries.
2 : Copyright (C) 1992-2026 Free Software Foundation, Inc.
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 "system.h"
22 : #include "filenames.h"
23 : #include "file-find.h"
24 :
25 : static bool debug = false;
26 :
27 : void
28 94004 : find_file_set_debug (bool debug_state)
29 : {
30 94004 : debug = debug_state;
31 94004 : }
32 :
33 : char *
34 940043 : find_a_file (struct path_prefix *pprefix, const char *name, int mode)
35 : {
36 940043 : char *temp;
37 940043 : struct prefix_list *pl;
38 940043 : int len = pprefix->max_len + strlen (name) + 1;
39 :
40 940043 : if (debug)
41 0 : fprintf (stderr, "Looking for '%s'\n", name);
42 :
43 : #ifdef HOST_EXECUTABLE_SUFFIX
44 : len += strlen (HOST_EXECUTABLE_SUFFIX);
45 : #endif
46 :
47 940043 : temp = XNEWVEC (char, len);
48 :
49 : /* Determine the filename to execute (special case for absolute paths). */
50 :
51 940043 : if (IS_ABSOLUTE_PATH (name))
52 : {
53 94004 : if (access (name, mode) == 0)
54 : {
55 94004 : strcpy (temp, name);
56 :
57 94004 : if (debug)
58 0 : fprintf (stderr, " - found: absolute path\n");
59 :
60 94004 : return temp;
61 : }
62 :
63 : #ifdef HOST_EXECUTABLE_SUFFIX
64 : /* Some systems have a suffix for executable files.
65 : So try appending that. */
66 : strcpy (temp, name);
67 : strcat (temp, HOST_EXECUTABLE_SUFFIX);
68 :
69 : if (access (temp, mode) == 0)
70 : return temp;
71 : #endif
72 :
73 0 : if (debug)
74 0 : fprintf (stderr, " - failed to locate using absolute path\n");
75 : }
76 : else
77 2808693 : for (pl = pprefix->plist; pl; pl = pl->next)
78 : {
79 2244668 : struct stat st;
80 :
81 2244668 : strcpy (temp, pl->prefix);
82 2244668 : strcat (temp, name);
83 :
84 2244668 : if (stat (temp, &st) >= 0
85 282014 : && ! S_ISDIR (st.st_mode)
86 2526682 : && access (temp, mode) == 0)
87 282014 : return temp;
88 :
89 : #ifdef HOST_EXECUTABLE_SUFFIX
90 : /* Some systems have a suffix for executable files.
91 : So try appending that. */
92 : strcat (temp, HOST_EXECUTABLE_SUFFIX);
93 :
94 : if (stat (temp, &st) >= 0
95 : && ! S_ISDIR (st.st_mode)
96 : && access (temp, mode) == 0)
97 : return temp;
98 : #endif
99 : }
100 :
101 564025 : if (debug && pprefix->plist == NULL)
102 0 : fprintf (stderr, " - failed: no entries in prefix list\n");
103 :
104 564025 : free (temp);
105 564025 : return 0;
106 : }
107 :
108 : /* Add an entry for PREFIX to prefix list PREFIX.
109 : Add at beginning if FIRST is true. */
110 :
111 : void
112 655241 : do_add_prefix (struct path_prefix *pprefix, const char *prefix, bool first)
113 : {
114 655241 : struct prefix_list *pl, **prev;
115 655241 : int len;
116 :
117 655241 : if (pprefix->plist && !first)
118 : {
119 1100101 : for (pl = pprefix->plist; pl->next; pl = pl->next)
120 : ;
121 467229 : prev = &pl->next;
122 : }
123 : else
124 188012 : prev = &pprefix->plist;
125 :
126 : /* Keep track of the longest prefix. */
127 :
128 655241 : len = strlen (prefix);
129 655241 : if (len > pprefix->max_len)
130 257640 : pprefix->max_len = len;
131 :
132 655241 : pl = XNEW (struct prefix_list);
133 655241 : pl->prefix = xstrdup (prefix);
134 :
135 655241 : if (*prev)
136 2 : pl->next = *prev;
137 : else
138 655239 : pl->next = (struct prefix_list *) 0;
139 655241 : *prev = pl;
140 655241 : }
141 :
142 : /* Add an entry for PREFIX at the end of prefix list PREFIX. */
143 :
144 : void
145 655239 : add_prefix (struct path_prefix *pprefix, const char *prefix)
146 : {
147 655239 : do_add_prefix (pprefix, prefix, false);
148 655239 : }
149 :
150 : /* Add an entry for PREFIX at the begin of prefix list PREFIX. */
151 :
152 : void
153 2 : add_prefix_begin (struct path_prefix *pprefix, const char *prefix)
154 : {
155 2 : do_add_prefix (pprefix, prefix, true);
156 2 : }
157 :
158 : /* Take the value of the environment variable ENV, break it into a path, and
159 : add of the entries to PPREFIX. */
160 :
161 : void
162 188009 : prefix_from_env (const char *env, struct path_prefix *pprefix)
163 : {
164 188009 : const char *p;
165 188009 : p = getenv (env);
166 :
167 188009 : if (p)
168 188009 : prefix_from_string (p, pprefix);
169 188009 : }
170 :
171 : void
172 188011 : prefix_from_string (const char *p, struct path_prefix *pprefix)
173 : {
174 188011 : const char *startp, *endp;
175 188011 : char *nstore = XNEWVEC (char, strlen (p) + 3);
176 :
177 188011 : if (debug)
178 0 : fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
179 :
180 : startp = endp = p;
181 18049800 : while (1)
182 : {
183 18049800 : if (*endp == PATH_SEPARATOR || *endp == 0)
184 : {
185 655239 : strncpy (nstore, startp, endp-startp);
186 655239 : if (endp == startp)
187 : {
188 0 : strcpy (nstore, "./");
189 : }
190 655239 : else if (! IS_DIR_SEPARATOR (endp[-1]))
191 : {
192 470279 : nstore[endp-startp] = DIR_SEPARATOR;
193 470279 : nstore[endp-startp+1] = 0;
194 : }
195 : else
196 184960 : nstore[endp-startp] = 0;
197 :
198 655239 : if (debug)
199 0 : fprintf (stderr, " - add prefix: %s\n", nstore);
200 :
201 655239 : add_prefix (pprefix, nstore);
202 655239 : if (*endp == 0)
203 : break;
204 467228 : endp = startp = endp + 1;
205 : }
206 : else
207 17394561 : endp++;
208 : }
209 188011 : free (nstore);
210 188011 : }
|