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 93805 : find_file_set_debug (bool debug_state)
29 : {
30 93805 : debug = debug_state;
31 93805 : }
32 :
33 : char *
34 938053 : find_a_file (struct path_prefix *pprefix, const char *name, int mode)
35 : {
36 938053 : char *temp;
37 938053 : struct prefix_list *pl;
38 938053 : int len = pprefix->max_len + strlen (name) + 1;
39 :
40 938053 : 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 938053 : temp = XNEWVEC (char, len);
48 :
49 : /* Determine the filename to execute (special case for absolute paths). */
50 :
51 938053 : if (IS_ABSOLUTE_PATH (name))
52 : {
53 93805 : if (access (name, mode) == 0)
54 : {
55 93805 : strcpy (temp, name);
56 :
57 93805 : if (debug)
58 0 : fprintf (stderr, " - found: absolute path\n");
59 :
60 93805 : 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 2798583 : for (pl = pprefix->plist; pl; pl = pl->next)
78 : {
79 2235752 : struct stat st;
80 :
81 2235752 : strcpy (temp, pl->prefix);
82 2235752 : strcat (temp, name);
83 :
84 2235752 : if (stat (temp, &st) >= 0
85 281417 : && ! S_ISDIR (st.st_mode)
86 2517169 : && access (temp, mode) == 0)
87 281417 : 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 562831 : if (debug && pprefix->plist == NULL)
102 0 : fprintf (stderr, " - failed: no entries in prefix list\n");
103 :
104 562831 : free (temp);
105 562831 : 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 652813 : do_add_prefix (struct path_prefix *pprefix, const char *prefix, bool first)
113 : {
114 652813 : struct prefix_list *pl, **prev;
115 652813 : int len;
116 :
117 652813 : if (pprefix->plist && !first)
118 : {
119 1095427 : for (pl = pprefix->plist; pl->next; pl = pl->next)
120 : ;
121 465199 : prev = &pl->next;
122 : }
123 : else
124 187614 : prev = &pprefix->plist;
125 :
126 : /* Keep track of the longest prefix. */
127 :
128 652813 : len = strlen (prefix);
129 652813 : if (len > pprefix->max_len)
130 256514 : pprefix->max_len = len;
131 :
132 652813 : pl = XNEW (struct prefix_list);
133 652813 : pl->prefix = xstrdup (prefix);
134 :
135 652813 : if (*prev)
136 2 : pl->next = *prev;
137 : else
138 652811 : pl->next = (struct prefix_list *) 0;
139 652813 : *prev = pl;
140 652813 : }
141 :
142 : /* Add an entry for PREFIX at the end of prefix list PREFIX. */
143 :
144 : void
145 652811 : add_prefix (struct path_prefix *pprefix, const char *prefix)
146 : {
147 652811 : do_add_prefix (pprefix, prefix, false);
148 652811 : }
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 187611 : prefix_from_env (const char *env, struct path_prefix *pprefix)
163 : {
164 187611 : const char *p;
165 187611 : p = getenv (env);
166 :
167 187611 : if (p)
168 187611 : prefix_from_string (p, pprefix);
169 187611 : }
170 :
171 : void
172 187613 : prefix_from_string (const char *p, struct path_prefix *pprefix)
173 : {
174 187613 : const char *startp, *endp;
175 187613 : char *nstore = XNEWVEC (char, strlen (p) + 3);
176 :
177 187613 : if (debug)
178 0 : fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
179 :
180 : startp = endp = p;
181 17924610 : while (1)
182 : {
183 17924610 : if (*endp == PATH_SEPARATOR || *endp == 0)
184 : {
185 652811 : strncpy (nstore, startp, endp-startp);
186 652811 : if (endp == startp)
187 : {
188 0 : strcpy (nstore, "./");
189 : }
190 652811 : else if (! IS_DIR_SEPARATOR (endp[-1]))
191 : {
192 469284 : nstore[endp-startp] = DIR_SEPARATOR;
193 469284 : nstore[endp-startp+1] = 0;
194 : }
195 : else
196 183527 : nstore[endp-startp] = 0;
197 :
198 652811 : if (debug)
199 0 : fprintf (stderr, " - add prefix: %s\n", nstore);
200 :
201 652811 : add_prefix (pprefix, nstore);
202 652811 : if (*endp == 0)
203 : break;
204 465198 : endp = startp = endp + 1;
205 : }
206 : else
207 17271799 : endp++;
208 : }
209 187613 : free (nstore);
210 187613 : }
|