Branch data Line data Source code
1 : : /* Utility functions for finding files relative to GCC binaries.
2 : : Copyright (C) 1992-2024 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 : 91893 : find_file_set_debug (bool debug_state)
29 : : {
30 : 91893 : debug = debug_state;
31 : 91893 : }
32 : :
33 : : char *
34 : 918930 : find_a_file (struct path_prefix *pprefix, const char *name, int mode)
35 : : {
36 : 918930 : char *temp;
37 : 918930 : struct prefix_list *pl;
38 : 918930 : int len = pprefix->max_len + strlen (name) + 1;
39 : :
40 : 918930 : 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 : 918930 : temp = XNEWVEC (char, len);
48 : :
49 : : /* Determine the filename to execute (special case for absolute paths). */
50 : :
51 : 918930 : if (IS_ABSOLUTE_PATH (name))
52 : : {
53 : 91893 : if (access (name, mode) == 0)
54 : : {
55 : 91893 : strcpy (temp, name);
56 : :
57 : 91893 : if (debug)
58 : 0 : fprintf (stderr, " - found: absolute path\n");
59 : :
60 : 91893 : 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 : 2746729 : for (pl = pprefix->plist; pl; pl = pl->next)
78 : : {
79 : 2195371 : struct stat st;
80 : :
81 : 2195371 : strcpy (temp, pl->prefix);
82 : 2195371 : strcat (temp, name);
83 : :
84 : 2195371 : if (stat (temp, &st) >= 0
85 : 275679 : && ! S_ISDIR (st.st_mode)
86 : 2471050 : && access (temp, mode) == 0)
87 : 275679 : 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 : 551358 : if (debug && pprefix->plist == NULL)
102 : 0 : fprintf (stderr, " - failed: no entries in prefix list\n");
103 : :
104 : 551358 : free (temp);
105 : 551358 : 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 : 640799 : do_add_prefix (struct path_prefix *pprefix, const char *prefix, bool first)
113 : : {
114 : 640799 : struct prefix_list *pl, **prev;
115 : 640799 : int len;
116 : :
117 : 640799 : if (pprefix->plist && !first)
118 : : {
119 : 1075317 : for (pl = pprefix->plist; pl->next; pl = pl->next)
120 : : ;
121 : 457013 : prev = &pl->next;
122 : : }
123 : : else
124 : 183786 : prev = &pprefix->plist;
125 : :
126 : : /* Keep track of the longest prefix. */
127 : :
128 : 640799 : len = strlen (prefix);
129 : 640799 : if (len > pprefix->max_len)
130 : 251299 : pprefix->max_len = len;
131 : :
132 : 640799 : pl = XNEW (struct prefix_list);
133 : 640799 : pl->prefix = xstrdup (prefix);
134 : :
135 : 640799 : if (*prev)
136 : 0 : pl->next = *prev;
137 : : else
138 : 640799 : pl->next = (struct prefix_list *) 0;
139 : 640799 : *prev = pl;
140 : 640799 : }
141 : :
142 : : /* Add an entry for PREFIX at the end of prefix list PREFIX. */
143 : :
144 : : void
145 : 640799 : add_prefix (struct path_prefix *pprefix, const char *prefix)
146 : : {
147 : 640799 : do_add_prefix (pprefix, prefix, false);
148 : 640799 : }
149 : :
150 : : /* Add an entry for PREFIX at the begin of prefix list PREFIX. */
151 : :
152 : : void
153 : 0 : add_prefix_begin (struct path_prefix *pprefix, const char *prefix)
154 : : {
155 : 0 : do_add_prefix (pprefix, prefix, true);
156 : 0 : }
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 : 183786 : prefix_from_env (const char *env, struct path_prefix *pprefix)
163 : : {
164 : 183786 : const char *p;
165 : 183786 : p = getenv (env);
166 : :
167 : 183786 : if (p)
168 : 183786 : prefix_from_string (p, pprefix);
169 : 183786 : }
170 : :
171 : : void
172 : 183786 : prefix_from_string (const char *p, struct path_prefix *pprefix)
173 : : {
174 : 183786 : const char *startp, *endp;
175 : 183786 : char *nstore = XNEWVEC (char, strlen (p) + 3);
176 : :
177 : 183786 : if (debug)
178 : 0 : fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
179 : :
180 : : startp = endp = p;
181 : 17667895 : while (1)
182 : : {
183 : 17667895 : if (*endp == PATH_SEPARATOR || *endp == 0)
184 : : {
185 : 640799 : strncpy (nstore, startp, endp-startp);
186 : 640799 : if (endp == startp)
187 : : {
188 : 0 : strcpy (nstore, "./");
189 : : }
190 : 640799 : else if (! IS_DIR_SEPARATOR (endp[-1]))
191 : : {
192 : 459718 : nstore[endp-startp] = DIR_SEPARATOR;
193 : 459718 : nstore[endp-startp+1] = 0;
194 : : }
195 : : else
196 : 181081 : nstore[endp-startp] = 0;
197 : :
198 : 640799 : if (debug)
199 : 0 : fprintf (stderr, " - add prefix: %s\n", nstore);
200 : :
201 : 640799 : add_prefix (pprefix, nstore);
202 : 640799 : if (*endp == 0)
203 : : break;
204 : 457013 : endp = startp = endp + 1;
205 : : }
206 : : else
207 : 17027096 : endp++;
208 : : }
209 : 183786 : free (nstore);
210 : 183786 : }
|