xref: /dflybsd-src/contrib/gcc-8.0/gcc/file-find.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Utility functions for finding files relative to GCC binaries.
2*38fd1498Szrj    Copyright (C) 1992-2018 Free Software Foundation, Inc.
3*38fd1498Szrj 
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj 
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
7*38fd1498Szrj the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj version.
10*38fd1498Szrj 
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*38fd1498Szrj for more details.
15*38fd1498Szrj 
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
19*38fd1498Szrj 
20*38fd1498Szrj #include "config.h"
21*38fd1498Szrj #include "system.h"
22*38fd1498Szrj #include "filenames.h"
23*38fd1498Szrj #include "file-find.h"
24*38fd1498Szrj 
25*38fd1498Szrj static bool debug = false;
26*38fd1498Szrj 
27*38fd1498Szrj void
find_file_set_debug(bool debug_state)28*38fd1498Szrj find_file_set_debug (bool debug_state)
29*38fd1498Szrj {
30*38fd1498Szrj   debug = debug_state;
31*38fd1498Szrj }
32*38fd1498Szrj 
33*38fd1498Szrj char *
find_a_file(struct path_prefix * pprefix,const char * name,int mode)34*38fd1498Szrj find_a_file (struct path_prefix *pprefix, const char *name, int mode)
35*38fd1498Szrj {
36*38fd1498Szrj   char *temp;
37*38fd1498Szrj   struct prefix_list *pl;
38*38fd1498Szrj   int len = pprefix->max_len + strlen (name) + 1;
39*38fd1498Szrj 
40*38fd1498Szrj   if (debug)
41*38fd1498Szrj     fprintf (stderr, "Looking for '%s'\n", name);
42*38fd1498Szrj 
43*38fd1498Szrj #ifdef HOST_EXECUTABLE_SUFFIX
44*38fd1498Szrj   len += strlen (HOST_EXECUTABLE_SUFFIX);
45*38fd1498Szrj #endif
46*38fd1498Szrj 
47*38fd1498Szrj   temp = XNEWVEC (char, len);
48*38fd1498Szrj 
49*38fd1498Szrj   /* Determine the filename to execute (special case for absolute paths).  */
50*38fd1498Szrj 
51*38fd1498Szrj   if (IS_ABSOLUTE_PATH (name))
52*38fd1498Szrj     {
53*38fd1498Szrj       if (access (name, mode) == 0)
54*38fd1498Szrj 	{
55*38fd1498Szrj 	  strcpy (temp, name);
56*38fd1498Szrj 
57*38fd1498Szrj 	  if (debug)
58*38fd1498Szrj 	    fprintf (stderr, "  - found: absolute path\n");
59*38fd1498Szrj 
60*38fd1498Szrj 	  return temp;
61*38fd1498Szrj 	}
62*38fd1498Szrj 
63*38fd1498Szrj #ifdef HOST_EXECUTABLE_SUFFIX
64*38fd1498Szrj 	/* Some systems have a suffix for executable files.
65*38fd1498Szrj 	   So try appending that.  */
66*38fd1498Szrj       strcpy (temp, name);
67*38fd1498Szrj 	strcat (temp, HOST_EXECUTABLE_SUFFIX);
68*38fd1498Szrj 
69*38fd1498Szrj 	if (access (temp, mode) == 0)
70*38fd1498Szrj 	  return temp;
71*38fd1498Szrj #endif
72*38fd1498Szrj 
73*38fd1498Szrj       if (debug)
74*38fd1498Szrj 	fprintf (stderr, "  - failed to locate using absolute path\n");
75*38fd1498Szrj     }
76*38fd1498Szrj   else
77*38fd1498Szrj     for (pl = pprefix->plist; pl; pl = pl->next)
78*38fd1498Szrj       {
79*38fd1498Szrj 	struct stat st;
80*38fd1498Szrj 
81*38fd1498Szrj 	strcpy (temp, pl->prefix);
82*38fd1498Szrj 	strcat (temp, name);
83*38fd1498Szrj 
84*38fd1498Szrj 	if (stat (temp, &st) >= 0
85*38fd1498Szrj 	    && ! S_ISDIR (st.st_mode)
86*38fd1498Szrj 	    && access (temp, mode) == 0)
87*38fd1498Szrj 	  return temp;
88*38fd1498Szrj 
89*38fd1498Szrj #ifdef HOST_EXECUTABLE_SUFFIX
90*38fd1498Szrj 	/* Some systems have a suffix for executable files.
91*38fd1498Szrj 	   So try appending that.  */
92*38fd1498Szrj 	strcat (temp, HOST_EXECUTABLE_SUFFIX);
93*38fd1498Szrj 
94*38fd1498Szrj 	if (stat (temp, &st) >= 0
95*38fd1498Szrj 	    && ! S_ISDIR (st.st_mode)
96*38fd1498Szrj 	    && access (temp, mode) == 0)
97*38fd1498Szrj 	  return temp;
98*38fd1498Szrj #endif
99*38fd1498Szrj       }
100*38fd1498Szrj 
101*38fd1498Szrj   if (debug && pprefix->plist == NULL)
102*38fd1498Szrj     fprintf (stderr, "  - failed: no entries in prefix list\n");
103*38fd1498Szrj 
104*38fd1498Szrj   free (temp);
105*38fd1498Szrj   return 0;
106*38fd1498Szrj }
107*38fd1498Szrj 
108*38fd1498Szrj /* Add an entry for PREFIX to prefix list PREFIX.
109*38fd1498Szrj    Add at beginning if FIRST is true.  */
110*38fd1498Szrj 
111*38fd1498Szrj void
do_add_prefix(struct path_prefix * pprefix,const char * prefix,bool first)112*38fd1498Szrj do_add_prefix (struct path_prefix *pprefix, const char *prefix, bool first)
113*38fd1498Szrj {
114*38fd1498Szrj   struct prefix_list *pl, **prev;
115*38fd1498Szrj   int len;
116*38fd1498Szrj 
117*38fd1498Szrj   if (pprefix->plist && !first)
118*38fd1498Szrj     {
119*38fd1498Szrj       for (pl = pprefix->plist; pl->next; pl = pl->next)
120*38fd1498Szrj 	;
121*38fd1498Szrj       prev = &pl->next;
122*38fd1498Szrj     }
123*38fd1498Szrj   else
124*38fd1498Szrj     prev = &pprefix->plist;
125*38fd1498Szrj 
126*38fd1498Szrj   /* Keep track of the longest prefix.  */
127*38fd1498Szrj 
128*38fd1498Szrj   len = strlen (prefix);
129*38fd1498Szrj   if (len > pprefix->max_len)
130*38fd1498Szrj     pprefix->max_len = len;
131*38fd1498Szrj 
132*38fd1498Szrj   pl = XNEW (struct prefix_list);
133*38fd1498Szrj   pl->prefix = xstrdup (prefix);
134*38fd1498Szrj 
135*38fd1498Szrj   if (*prev)
136*38fd1498Szrj     pl->next = *prev;
137*38fd1498Szrj   else
138*38fd1498Szrj     pl->next = (struct prefix_list *) 0;
139*38fd1498Szrj   *prev = pl;
140*38fd1498Szrj }
141*38fd1498Szrj 
142*38fd1498Szrj /* Add an entry for PREFIX at the end of prefix list PREFIX.  */
143*38fd1498Szrj 
144*38fd1498Szrj void
add_prefix(struct path_prefix * pprefix,const char * prefix)145*38fd1498Szrj add_prefix (struct path_prefix *pprefix, const char *prefix)
146*38fd1498Szrj {
147*38fd1498Szrj   do_add_prefix (pprefix, prefix, false);
148*38fd1498Szrj }
149*38fd1498Szrj 
150*38fd1498Szrj /* Add an entry for PREFIX at the begin of prefix list PREFIX.  */
151*38fd1498Szrj 
152*38fd1498Szrj void
add_prefix_begin(struct path_prefix * pprefix,const char * prefix)153*38fd1498Szrj add_prefix_begin (struct path_prefix *pprefix, const char *prefix)
154*38fd1498Szrj {
155*38fd1498Szrj   do_add_prefix (pprefix, prefix, true);
156*38fd1498Szrj }
157*38fd1498Szrj 
158*38fd1498Szrj /* Take the value of the environment variable ENV, break it into a path, and
159*38fd1498Szrj    add of the entries to PPREFIX.  */
160*38fd1498Szrj 
161*38fd1498Szrj void
prefix_from_env(const char * env,struct path_prefix * pprefix)162*38fd1498Szrj prefix_from_env (const char *env, struct path_prefix *pprefix)
163*38fd1498Szrj {
164*38fd1498Szrj   const char *p;
165*38fd1498Szrj   p = getenv (env);
166*38fd1498Szrj 
167*38fd1498Szrj   if (p)
168*38fd1498Szrj     prefix_from_string (p, pprefix);
169*38fd1498Szrj }
170*38fd1498Szrj 
171*38fd1498Szrj void
prefix_from_string(const char * p,struct path_prefix * pprefix)172*38fd1498Szrj prefix_from_string (const char *p, struct path_prefix *pprefix)
173*38fd1498Szrj {
174*38fd1498Szrj   const char *startp, *endp;
175*38fd1498Szrj   char *nstore = XNEWVEC (char, strlen (p) + 3);
176*38fd1498Szrj 
177*38fd1498Szrj   if (debug)
178*38fd1498Szrj     fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
179*38fd1498Szrj 
180*38fd1498Szrj   startp = endp = p;
181*38fd1498Szrj   while (1)
182*38fd1498Szrj     {
183*38fd1498Szrj       if (*endp == PATH_SEPARATOR || *endp == 0)
184*38fd1498Szrj 	{
185*38fd1498Szrj 	  strncpy (nstore, startp, endp-startp);
186*38fd1498Szrj 	  if (endp == startp)
187*38fd1498Szrj 	    {
188*38fd1498Szrj 	      strcpy (nstore, "./");
189*38fd1498Szrj 	    }
190*38fd1498Szrj 	  else if (! IS_DIR_SEPARATOR (endp[-1]))
191*38fd1498Szrj 	    {
192*38fd1498Szrj 	      nstore[endp-startp] = DIR_SEPARATOR;
193*38fd1498Szrj 	      nstore[endp-startp+1] = 0;
194*38fd1498Szrj 	    }
195*38fd1498Szrj 	  else
196*38fd1498Szrj 	    nstore[endp-startp] = 0;
197*38fd1498Szrj 
198*38fd1498Szrj 	  if (debug)
199*38fd1498Szrj 	    fprintf (stderr, "  - add prefix: %s\n", nstore);
200*38fd1498Szrj 
201*38fd1498Szrj 	  add_prefix (pprefix, nstore);
202*38fd1498Szrj 	  if (*endp == 0)
203*38fd1498Szrj 	    break;
204*38fd1498Szrj 	  endp = startp = endp + 1;
205*38fd1498Szrj 	}
206*38fd1498Szrj       else
207*38fd1498Szrj 	endp++;
208*38fd1498Szrj     }
209*38fd1498Szrj   free (nstore);
210*38fd1498Szrj }
211