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