1*69606e3fSchristos /* Implementation of pattern-matching file search paths for GNU Make.
2*69606e3fSchristos Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3*69606e3fSchristos 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
4*69606e3fSchristos Foundation, Inc.
5*69606e3fSchristos This file is part of GNU Make.
6*69606e3fSchristos
7*69606e3fSchristos GNU Make is free software; you can redistribute it and/or modify it under the
8*69606e3fSchristos terms of the GNU General Public License as published by the Free Software
9*69606e3fSchristos Foundation; either version 2, or (at your option) any later version.
10*69606e3fSchristos
11*69606e3fSchristos GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
12*69606e3fSchristos WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13*69606e3fSchristos A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14*69606e3fSchristos
15*69606e3fSchristos You should have received a copy of the GNU General Public License along with
16*69606e3fSchristos GNU Make; see the file COPYING. If not, write to the Free Software
17*69606e3fSchristos Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
18*69606e3fSchristos
19*69606e3fSchristos #include "make.h"
20*69606e3fSchristos #include "filedef.h"
21*69606e3fSchristos #include "variable.h"
22*69606e3fSchristos #ifdef WINDOWS32
23*69606e3fSchristos #include "pathstuff.h"
24*69606e3fSchristos #endif
25*69606e3fSchristos
26*69606e3fSchristos
27*69606e3fSchristos /* Structure used to represent a selective VPATH searchpath. */
28*69606e3fSchristos
29*69606e3fSchristos struct vpath
30*69606e3fSchristos {
31*69606e3fSchristos struct vpath *next; /* Pointer to next struct in the linked list. */
32*69606e3fSchristos char *pattern; /* The pattern to match. */
33*69606e3fSchristos char *percent; /* Pointer into `pattern' where the `%' is. */
34*69606e3fSchristos unsigned int patlen;/* Length of the pattern. */
35*69606e3fSchristos char **searchpath; /* Null-terminated list of directories. */
36*69606e3fSchristos unsigned int maxlen;/* Maximum length of any entry in the list. */
37*69606e3fSchristos };
38*69606e3fSchristos
39*69606e3fSchristos /* Linked-list of all selective VPATHs. */
40*69606e3fSchristos
41*69606e3fSchristos static struct vpath *vpaths;
42*69606e3fSchristos
43*69606e3fSchristos /* Structure for the general VPATH given in the variable. */
44*69606e3fSchristos
45*69606e3fSchristos static struct vpath *general_vpath;
46*69606e3fSchristos
47*69606e3fSchristos /* Structure for GPATH given in the variable. */
48*69606e3fSchristos
49*69606e3fSchristos static struct vpath *gpaths;
50*69606e3fSchristos
51*69606e3fSchristos static int selective_vpath_search PARAMS ((struct vpath *path, char **file, FILE_TIMESTAMP *mtime_ptr));
52*69606e3fSchristos
53*69606e3fSchristos /* Reverse the chain of selective VPATH lists so they
54*69606e3fSchristos will be searched in the order given in the makefiles
55*69606e3fSchristos and construct the list from the VPATH variable. */
56*69606e3fSchristos
57*69606e3fSchristos void
build_vpath_lists()58*69606e3fSchristos build_vpath_lists ()
59*69606e3fSchristos {
60*69606e3fSchristos register struct vpath *new = 0;
61*69606e3fSchristos register struct vpath *old, *nexto;
62*69606e3fSchristos register char *p;
63*69606e3fSchristos
64*69606e3fSchristos /* Reverse the chain. */
65*69606e3fSchristos for (old = vpaths; old != 0; old = nexto)
66*69606e3fSchristos {
67*69606e3fSchristos nexto = old->next;
68*69606e3fSchristos old->next = new;
69*69606e3fSchristos new = old;
70*69606e3fSchristos }
71*69606e3fSchristos
72*69606e3fSchristos vpaths = new;
73*69606e3fSchristos
74*69606e3fSchristos /* If there is a VPATH variable with a nonnull value, construct the
75*69606e3fSchristos general VPATH list from it. We use variable_expand rather than just
76*69606e3fSchristos calling lookup_variable so that it will be recursively expanded. */
77*69606e3fSchristos
78*69606e3fSchristos {
79*69606e3fSchristos /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
80*69606e3fSchristos int save = warn_undefined_variables_flag;
81*69606e3fSchristos warn_undefined_variables_flag = 0;
82*69606e3fSchristos
83*69606e3fSchristos p = variable_expand ("$(strip $(VPATH))");
84*69606e3fSchristos
85*69606e3fSchristos warn_undefined_variables_flag = save;
86*69606e3fSchristos }
87*69606e3fSchristos
88*69606e3fSchristos if (*p != '\0')
89*69606e3fSchristos {
90*69606e3fSchristos /* Save the list of vpaths. */
91*69606e3fSchristos struct vpath *save_vpaths = vpaths;
92*69606e3fSchristos
93*69606e3fSchristos /* Empty `vpaths' so the new one will have no next, and `vpaths'
94*69606e3fSchristos will still be nil if P contains no existing directories. */
95*69606e3fSchristos vpaths = 0;
96*69606e3fSchristos
97*69606e3fSchristos /* Parse P. */
98*69606e3fSchristos construct_vpath_list ("%", p);
99*69606e3fSchristos
100*69606e3fSchristos /* Store the created path as the general path,
101*69606e3fSchristos and restore the old list of vpaths. */
102*69606e3fSchristos general_vpath = vpaths;
103*69606e3fSchristos vpaths = save_vpaths;
104*69606e3fSchristos }
105*69606e3fSchristos
106*69606e3fSchristos /* If there is a GPATH variable with a nonnull value, construct the
107*69606e3fSchristos GPATH list from it. We use variable_expand rather than just
108*69606e3fSchristos calling lookup_variable so that it will be recursively expanded. */
109*69606e3fSchristos
110*69606e3fSchristos {
111*69606e3fSchristos /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
112*69606e3fSchristos int save = warn_undefined_variables_flag;
113*69606e3fSchristos warn_undefined_variables_flag = 0;
114*69606e3fSchristos
115*69606e3fSchristos p = variable_expand ("$(strip $(GPATH))");
116*69606e3fSchristos
117*69606e3fSchristos warn_undefined_variables_flag = save;
118*69606e3fSchristos }
119*69606e3fSchristos
120*69606e3fSchristos if (*p != '\0')
121*69606e3fSchristos {
122*69606e3fSchristos /* Save the list of vpaths. */
123*69606e3fSchristos struct vpath *save_vpaths = vpaths;
124*69606e3fSchristos
125*69606e3fSchristos /* Empty `vpaths' so the new one will have no next, and `vpaths'
126*69606e3fSchristos will still be nil if P contains no existing directories. */
127*69606e3fSchristos vpaths = 0;
128*69606e3fSchristos
129*69606e3fSchristos /* Parse P. */
130*69606e3fSchristos construct_vpath_list ("%", p);
131*69606e3fSchristos
132*69606e3fSchristos /* Store the created path as the GPATH,
133*69606e3fSchristos and restore the old list of vpaths. */
134*69606e3fSchristos gpaths = vpaths;
135*69606e3fSchristos vpaths = save_vpaths;
136*69606e3fSchristos }
137*69606e3fSchristos }
138*69606e3fSchristos
139*69606e3fSchristos /* Construct the VPATH listing for the pattern and searchpath given.
140*69606e3fSchristos
141*69606e3fSchristos This function is called to generate selective VPATH lists and also for
142*69606e3fSchristos the general VPATH list (which is in fact just a selective VPATH that
143*69606e3fSchristos is applied to everything). The returned pointer is either put in the
144*69606e3fSchristos linked list of all selective VPATH lists or in the GENERAL_VPATH
145*69606e3fSchristos variable.
146*69606e3fSchristos
147*69606e3fSchristos If SEARCHPATH is nil, remove all previous listings with the same
148*69606e3fSchristos pattern. If PATTERN is nil, remove all VPATH listings. Existing
149*69606e3fSchristos and readable directories that are not "." given in the searchpath
150*69606e3fSchristos separated by the path element separator (defined in make.h) are
151*69606e3fSchristos loaded into the directory hash table if they are not there already
152*69606e3fSchristos and put in the VPATH searchpath for the given pattern with trailing
153*69606e3fSchristos slashes stripped off if present (and if the directory is not the
154*69606e3fSchristos root, "/"). The length of the longest entry in the list is put in
155*69606e3fSchristos the structure as well. The new entry will be at the head of the
156*69606e3fSchristos VPATHS chain. */
157*69606e3fSchristos
158*69606e3fSchristos void
construct_vpath_list(char * pattern,char * dirpath)159*69606e3fSchristos construct_vpath_list (char *pattern, char *dirpath)
160*69606e3fSchristos {
161*69606e3fSchristos register unsigned int elem;
162*69606e3fSchristos register char *p;
163*69606e3fSchristos register char **vpath;
164*69606e3fSchristos register unsigned int maxvpath;
165*69606e3fSchristos unsigned int maxelem;
166*69606e3fSchristos char *percent = NULL;
167*69606e3fSchristos
168*69606e3fSchristos if (pattern != 0)
169*69606e3fSchristos {
170*69606e3fSchristos pattern = xstrdup (pattern);
171*69606e3fSchristos percent = find_percent (pattern);
172*69606e3fSchristos }
173*69606e3fSchristos
174*69606e3fSchristos if (dirpath == 0)
175*69606e3fSchristos {
176*69606e3fSchristos /* Remove matching listings. */
177*69606e3fSchristos register struct vpath *path, *lastpath;
178*69606e3fSchristos
179*69606e3fSchristos lastpath = 0;
180*69606e3fSchristos path = vpaths;
181*69606e3fSchristos while (path != 0)
182*69606e3fSchristos {
183*69606e3fSchristos struct vpath *next = path->next;
184*69606e3fSchristos
185*69606e3fSchristos if (pattern == 0
186*69606e3fSchristos || (((percent == 0 && path->percent == 0)
187*69606e3fSchristos || (percent - pattern == path->percent - path->pattern))
188*69606e3fSchristos && streq (pattern, path->pattern)))
189*69606e3fSchristos {
190*69606e3fSchristos /* Remove it from the linked list. */
191*69606e3fSchristos if (lastpath == 0)
192*69606e3fSchristos vpaths = path->next;
193*69606e3fSchristos else
194*69606e3fSchristos lastpath->next = next;
195*69606e3fSchristos
196*69606e3fSchristos /* Free its unused storage. */
197*69606e3fSchristos free (path->pattern);
198*69606e3fSchristos free ((char *) path->searchpath);
199*69606e3fSchristos free ((char *) path);
200*69606e3fSchristos }
201*69606e3fSchristos else
202*69606e3fSchristos lastpath = path;
203*69606e3fSchristos
204*69606e3fSchristos path = next;
205*69606e3fSchristos }
206*69606e3fSchristos
207*69606e3fSchristos if (pattern != 0)
208*69606e3fSchristos free (pattern);
209*69606e3fSchristos return;
210*69606e3fSchristos }
211*69606e3fSchristos
212*69606e3fSchristos #ifdef WINDOWS32
213*69606e3fSchristos convert_vpath_to_windows32(dirpath, ';');
214*69606e3fSchristos #endif
215*69606e3fSchristos
216*69606e3fSchristos /* Figure out the maximum number of VPATH entries and put it in
217*69606e3fSchristos MAXELEM. We start with 2, one before the first separator and one
218*69606e3fSchristos nil (the list terminator) and increment our estimated number for
219*69606e3fSchristos each separator or blank we find. */
220*69606e3fSchristos maxelem = 2;
221*69606e3fSchristos p = dirpath;
222*69606e3fSchristos while (*p != '\0')
223*69606e3fSchristos if (*p++ == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))
224*69606e3fSchristos ++maxelem;
225*69606e3fSchristos
226*69606e3fSchristos vpath = (char **) xmalloc (maxelem * sizeof (char *));
227*69606e3fSchristos maxvpath = 0;
228*69606e3fSchristos
229*69606e3fSchristos /* Skip over any initial separators and blanks. */
230*69606e3fSchristos p = dirpath;
231*69606e3fSchristos while (*p == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))
232*69606e3fSchristos ++p;
233*69606e3fSchristos
234*69606e3fSchristos elem = 0;
235*69606e3fSchristos while (*p != '\0')
236*69606e3fSchristos {
237*69606e3fSchristos char *v;
238*69606e3fSchristos unsigned int len;
239*69606e3fSchristos
240*69606e3fSchristos /* Find the end of this entry. */
241*69606e3fSchristos v = p;
242*69606e3fSchristos while (*p != '\0' && *p != PATH_SEPARATOR_CHAR
243*69606e3fSchristos && !isblank ((unsigned char)*p))
244*69606e3fSchristos ++p;
245*69606e3fSchristos
246*69606e3fSchristos len = p - v;
247*69606e3fSchristos /* Make sure there's no trailing slash,
248*69606e3fSchristos but still allow "/" as a directory. */
249*69606e3fSchristos #if defined(__MSDOS__) || defined(__EMX__)
250*69606e3fSchristos /* We need also to leave alone a trailing slash in "d:/". */
251*69606e3fSchristos if (len > 3 || (len > 1 && v[1] != ':'))
252*69606e3fSchristos #endif
253*69606e3fSchristos if (len > 1 && p[-1] == '/')
254*69606e3fSchristos --len;
255*69606e3fSchristos
256*69606e3fSchristos if (len > 1 || *v != '.')
257*69606e3fSchristos {
258*69606e3fSchristos v = savestring (v, len);
259*69606e3fSchristos
260*69606e3fSchristos /* Verify that the directory actually exists. */
261*69606e3fSchristos
262*69606e3fSchristos if (dir_file_exists_p (v, ""))
263*69606e3fSchristos {
264*69606e3fSchristos /* It does. Put it in the list. */
265*69606e3fSchristos vpath[elem++] = dir_name (v);
266*69606e3fSchristos free (v);
267*69606e3fSchristos if (len > maxvpath)
268*69606e3fSchristos maxvpath = len;
269*69606e3fSchristos }
270*69606e3fSchristos else
271*69606e3fSchristos /* The directory does not exist. Omit from the list. */
272*69606e3fSchristos free (v);
273*69606e3fSchristos }
274*69606e3fSchristos
275*69606e3fSchristos /* Skip over separators and blanks between entries. */
276*69606e3fSchristos while (*p == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))
277*69606e3fSchristos ++p;
278*69606e3fSchristos }
279*69606e3fSchristos
280*69606e3fSchristos if (elem > 0)
281*69606e3fSchristos {
282*69606e3fSchristos struct vpath *path;
283*69606e3fSchristos /* ELEM is now incremented one element past the last
284*69606e3fSchristos entry, to where the nil-pointer terminator goes.
285*69606e3fSchristos Usually this is maxelem - 1. If not, shrink down. */
286*69606e3fSchristos if (elem < (maxelem - 1))
287*69606e3fSchristos vpath = (char **) xrealloc ((char *) vpath,
288*69606e3fSchristos (elem + 1) * sizeof (char *));
289*69606e3fSchristos
290*69606e3fSchristos /* Put the nil-pointer terminator on the end of the VPATH list. */
291*69606e3fSchristos vpath[elem] = 0;
292*69606e3fSchristos
293*69606e3fSchristos /* Construct the vpath structure and put it into the linked list. */
294*69606e3fSchristos path = (struct vpath *) xmalloc (sizeof (struct vpath));
295*69606e3fSchristos path->searchpath = vpath;
296*69606e3fSchristos path->maxlen = maxvpath;
297*69606e3fSchristos path->next = vpaths;
298*69606e3fSchristos vpaths = path;
299*69606e3fSchristos
300*69606e3fSchristos /* Set up the members. */
301*69606e3fSchristos path->pattern = pattern;
302*69606e3fSchristos path->percent = percent;
303*69606e3fSchristos path->patlen = strlen (pattern);
304*69606e3fSchristos }
305*69606e3fSchristos else
306*69606e3fSchristos {
307*69606e3fSchristos /* There were no entries, so free whatever space we allocated. */
308*69606e3fSchristos free ((char *) vpath);
309*69606e3fSchristos if (pattern != 0)
310*69606e3fSchristos free (pattern);
311*69606e3fSchristos }
312*69606e3fSchristos }
313*69606e3fSchristos
314*69606e3fSchristos /* Search the GPATH list for a pathname string that matches the one passed
315*69606e3fSchristos in. If it is found, return 1. Otherwise we return 0. */
316*69606e3fSchristos
317*69606e3fSchristos int
gpath_search(char * file,unsigned int len)318*69606e3fSchristos gpath_search (char *file, unsigned int len)
319*69606e3fSchristos {
320*69606e3fSchristos char **gp;
321*69606e3fSchristos
322*69606e3fSchristos if (gpaths && (len <= gpaths->maxlen))
323*69606e3fSchristos for (gp = gpaths->searchpath; *gp != NULL; ++gp)
324*69606e3fSchristos if (strneq (*gp, file, len) && (*gp)[len] == '\0')
325*69606e3fSchristos return 1;
326*69606e3fSchristos
327*69606e3fSchristos return 0;
328*69606e3fSchristos }
329*69606e3fSchristos
330*69606e3fSchristos /* Search the VPATH list whose pattern matches *FILE for a directory
331*69606e3fSchristos where the name pointed to by FILE exists. If it is found, we set *FILE to
332*69606e3fSchristos the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
333*69606e3fSchristos not NULL) to its modtime (or zero if no stat call was done), and return 1.
334*69606e3fSchristos Otherwise we return 0. */
335*69606e3fSchristos
336*69606e3fSchristos int
vpath_search(char ** file,FILE_TIMESTAMP * mtime_ptr)337*69606e3fSchristos vpath_search (char **file, FILE_TIMESTAMP *mtime_ptr)
338*69606e3fSchristos {
339*69606e3fSchristos register struct vpath *v;
340*69606e3fSchristos
341*69606e3fSchristos /* If there are no VPATH entries or FILENAME starts at the root,
342*69606e3fSchristos there is nothing we can do. */
343*69606e3fSchristos
344*69606e3fSchristos if (**file == '/'
345*69606e3fSchristos #ifdef HAVE_DOS_PATHS
346*69606e3fSchristos || **file == '\\'
347*69606e3fSchristos || (*file)[1] == ':'
348*69606e3fSchristos #endif
349*69606e3fSchristos || (vpaths == 0 && general_vpath == 0))
350*69606e3fSchristos return 0;
351*69606e3fSchristos
352*69606e3fSchristos for (v = vpaths; v != 0; v = v->next)
353*69606e3fSchristos if (pattern_matches (v->pattern, v->percent, *file))
354*69606e3fSchristos if (selective_vpath_search (v, file, mtime_ptr))
355*69606e3fSchristos return 1;
356*69606e3fSchristos
357*69606e3fSchristos if (general_vpath != 0
358*69606e3fSchristos && selective_vpath_search (general_vpath, file, mtime_ptr))
359*69606e3fSchristos return 1;
360*69606e3fSchristos
361*69606e3fSchristos return 0;
362*69606e3fSchristos }
363*69606e3fSchristos
364*69606e3fSchristos
365*69606e3fSchristos /* Search the given VPATH list for a directory where the name pointed
366*69606e3fSchristos to by FILE exists. If it is found, we set *FILE to the newly malloc'd
367*69606e3fSchristos name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
368*69606e3fSchristos its modtime (or zero if no stat call was done), and we return 1.
369*69606e3fSchristos Otherwise we return 0. */
370*69606e3fSchristos
371*69606e3fSchristos static int
selective_vpath_search(struct vpath * path,char ** file,FILE_TIMESTAMP * mtime_ptr)372*69606e3fSchristos selective_vpath_search (struct vpath *path, char **file,
373*69606e3fSchristos FILE_TIMESTAMP *mtime_ptr)
374*69606e3fSchristos {
375*69606e3fSchristos int not_target;
376*69606e3fSchristos char *name, *n;
377*69606e3fSchristos char *filename;
378*69606e3fSchristos register char **vpath = path->searchpath;
379*69606e3fSchristos unsigned int maxvpath = path->maxlen;
380*69606e3fSchristos register unsigned int i;
381*69606e3fSchristos unsigned int flen, vlen, name_dplen;
382*69606e3fSchristos int exists = 0;
383*69606e3fSchristos
384*69606e3fSchristos /* Find out if *FILE is a target.
385*69606e3fSchristos If and only if it is NOT a target, we will accept prospective
386*69606e3fSchristos files that don't exist but are mentioned in a makefile. */
387*69606e3fSchristos {
388*69606e3fSchristos struct file *f = lookup_file (*file);
389*69606e3fSchristos not_target = f == 0 || !f->is_target;
390*69606e3fSchristos }
391*69606e3fSchristos
392*69606e3fSchristos flen = strlen (*file);
393*69606e3fSchristos
394*69606e3fSchristos /* Split *FILE into a directory prefix and a name-within-directory.
395*69606e3fSchristos NAME_DPLEN gets the length of the prefix; FILENAME gets the
396*69606e3fSchristos pointer to the name-within-directory and FLEN is its length. */
397*69606e3fSchristos
398*69606e3fSchristos n = strrchr (*file, '/');
399*69606e3fSchristos #ifdef HAVE_DOS_PATHS
400*69606e3fSchristos /* We need the rightmost slash or backslash. */
401*69606e3fSchristos {
402*69606e3fSchristos char *bslash = strrchr(*file, '\\');
403*69606e3fSchristos if (!n || bslash > n)
404*69606e3fSchristos n = bslash;
405*69606e3fSchristos }
406*69606e3fSchristos #endif
407*69606e3fSchristos name_dplen = n != 0 ? n - *file : 0;
408*69606e3fSchristos filename = name_dplen > 0 ? n + 1 : *file;
409*69606e3fSchristos if (name_dplen > 0)
410*69606e3fSchristos flen -= name_dplen + 1;
411*69606e3fSchristos
412*69606e3fSchristos /* Allocate enough space for the biggest VPATH entry,
413*69606e3fSchristos a slash, the directory prefix that came with *FILE,
414*69606e3fSchristos another slash (although this one may not always be
415*69606e3fSchristos necessary), the filename, and a null terminator. */
416*69606e3fSchristos name = (char *) xmalloc (maxvpath + 1 + name_dplen + 1 + flen + 1);
417*69606e3fSchristos
418*69606e3fSchristos /* Try each VPATH entry. */
419*69606e3fSchristos for (i = 0; vpath[i] != 0; ++i)
420*69606e3fSchristos {
421*69606e3fSchristos int exists_in_cache = 0;
422*69606e3fSchristos
423*69606e3fSchristos n = name;
424*69606e3fSchristos
425*69606e3fSchristos /* Put the next VPATH entry into NAME at N and increment N past it. */
426*69606e3fSchristos vlen = strlen (vpath[i]);
427*69606e3fSchristos bcopy (vpath[i], n, vlen);
428*69606e3fSchristos n += vlen;
429*69606e3fSchristos
430*69606e3fSchristos /* Add the directory prefix already in *FILE. */
431*69606e3fSchristos if (name_dplen > 0)
432*69606e3fSchristos {
433*69606e3fSchristos #ifndef VMS
434*69606e3fSchristos *n++ = '/';
435*69606e3fSchristos #endif
436*69606e3fSchristos bcopy (*file, n, name_dplen);
437*69606e3fSchristos n += name_dplen;
438*69606e3fSchristos }
439*69606e3fSchristos
440*69606e3fSchristos #ifdef HAVE_DOS_PATHS
441*69606e3fSchristos /* Cause the next if to treat backslash and slash alike. */
442*69606e3fSchristos if (n != name && n[-1] == '\\' )
443*69606e3fSchristos n[-1] = '/';
444*69606e3fSchristos #endif
445*69606e3fSchristos /* Now add the name-within-directory at the end of NAME. */
446*69606e3fSchristos #ifndef VMS
447*69606e3fSchristos if (n != name && n[-1] != '/')
448*69606e3fSchristos {
449*69606e3fSchristos *n = '/';
450*69606e3fSchristos bcopy (filename, n + 1, flen + 1);
451*69606e3fSchristos }
452*69606e3fSchristos else
453*69606e3fSchristos #endif
454*69606e3fSchristos bcopy (filename, n, flen + 1);
455*69606e3fSchristos
456*69606e3fSchristos /* Check if the file is mentioned in a makefile. If *FILE is not
457*69606e3fSchristos a target, that is enough for us to decide this file exists.
458*69606e3fSchristos If *FILE is a target, then the file must be mentioned in the
459*69606e3fSchristos makefile also as a target to be chosen.
460*69606e3fSchristos
461*69606e3fSchristos The restriction that *FILE must not be a target for a
462*69606e3fSchristos makefile-mentioned file to be chosen was added by an
463*69606e3fSchristos inadequately commented change in July 1990; I am not sure off
464*69606e3fSchristos hand what problem it fixes.
465*69606e3fSchristos
466*69606e3fSchristos In December 1993 I loosened this restriction to allow a file
467*69606e3fSchristos to be chosen if it is mentioned as a target in a makefile. This
468*69606e3fSchristos seem logical.
469*69606e3fSchristos
470*69606e3fSchristos Special handling for -W / -o: make sure we preserve the special
471*69606e3fSchristos values here. Actually this whole thing is a little bogus: I think
472*69606e3fSchristos we should ditch the name/hname thing and look into the renamed
473*69606e3fSchristos capability that already exists for files: that is, have a new struct
474*69606e3fSchristos file* entry for the VPATH-found file, and set the renamed field if
475*69606e3fSchristos we use it.
476*69606e3fSchristos */
477*69606e3fSchristos {
478*69606e3fSchristos struct file *f = lookup_file (name);
479*69606e3fSchristos if (f != 0)
480*69606e3fSchristos {
481*69606e3fSchristos exists = not_target || f->is_target;
482*69606e3fSchristos if (exists && mtime_ptr
483*69606e3fSchristos && (f->last_mtime == OLD_MTIME || f->last_mtime == NEW_MTIME))
484*69606e3fSchristos {
485*69606e3fSchristos *mtime_ptr = f->last_mtime;
486*69606e3fSchristos mtime_ptr = 0;
487*69606e3fSchristos }
488*69606e3fSchristos }
489*69606e3fSchristos }
490*69606e3fSchristos
491*69606e3fSchristos if (!exists)
492*69606e3fSchristos {
493*69606e3fSchristos /* That file wasn't mentioned in the makefile.
494*69606e3fSchristos See if it actually exists. */
495*69606e3fSchristos
496*69606e3fSchristos #ifdef VMS
497*69606e3fSchristos exists_in_cache = exists = dir_file_exists_p (vpath[i], filename);
498*69606e3fSchristos #else
499*69606e3fSchristos /* Clobber a null into the name at the last slash.
500*69606e3fSchristos Now NAME is the name of the directory to look in. */
501*69606e3fSchristos *n = '\0';
502*69606e3fSchristos
503*69606e3fSchristos /* We know the directory is in the hash table now because either
504*69606e3fSchristos construct_vpath_list or the code just above put it there.
505*69606e3fSchristos Does the file we seek exist in it? */
506*69606e3fSchristos exists_in_cache = exists = dir_file_exists_p (name, filename);
507*69606e3fSchristos #endif
508*69606e3fSchristos }
509*69606e3fSchristos
510*69606e3fSchristos if (exists)
511*69606e3fSchristos {
512*69606e3fSchristos /* The file is in the directory cache.
513*69606e3fSchristos Now check that it actually exists in the filesystem.
514*69606e3fSchristos The cache may be out of date. When vpath thinks a file
515*69606e3fSchristos exists, but stat fails for it, confusion results in the
516*69606e3fSchristos higher levels. */
517*69606e3fSchristos
518*69606e3fSchristos struct stat st;
519*69606e3fSchristos
520*69606e3fSchristos #ifndef VMS
521*69606e3fSchristos /* Put the slash back in NAME. */
522*69606e3fSchristos *n = '/';
523*69606e3fSchristos #endif
524*69606e3fSchristos
525*69606e3fSchristos if (exists_in_cache) /* Makefile-mentioned file need not exist. */
526*69606e3fSchristos {
527*69606e3fSchristos int e;
528*69606e3fSchristos
529*69606e3fSchristos EINTRLOOP (e, stat (name, &st)); /* Does it really exist? */
530*69606e3fSchristos if (e != 0)
531*69606e3fSchristos {
532*69606e3fSchristos exists = 0;
533*69606e3fSchristos continue;
534*69606e3fSchristos }
535*69606e3fSchristos
536*69606e3fSchristos /* Store the modtime into *MTIME_PTR for the caller. */
537*69606e3fSchristos if (mtime_ptr != 0)
538*69606e3fSchristos {
539*69606e3fSchristos *mtime_ptr = FILE_TIMESTAMP_STAT_MODTIME (name, st);
540*69606e3fSchristos mtime_ptr = 0;
541*69606e3fSchristos }
542*69606e3fSchristos }
543*69606e3fSchristos
544*69606e3fSchristos /* We have found a file.
545*69606e3fSchristos Store the name we found into *FILE for the caller. */
546*69606e3fSchristos
547*69606e3fSchristos *file = savestring (name, (n + 1 - name) + flen);
548*69606e3fSchristos
549*69606e3fSchristos /* If we get here and mtime_ptr hasn't been set, record
550*69606e3fSchristos UNKNOWN_MTIME to indicate this. */
551*69606e3fSchristos if (mtime_ptr != 0)
552*69606e3fSchristos *mtime_ptr = UNKNOWN_MTIME;
553*69606e3fSchristos
554*69606e3fSchristos free (name);
555*69606e3fSchristos return 1;
556*69606e3fSchristos }
557*69606e3fSchristos }
558*69606e3fSchristos
559*69606e3fSchristos free (name);
560*69606e3fSchristos return 0;
561*69606e3fSchristos }
562*69606e3fSchristos
563*69606e3fSchristos /* Print the data base of VPATH search paths. */
564*69606e3fSchristos
565*69606e3fSchristos void
print_vpath_data_base(void)566*69606e3fSchristos print_vpath_data_base (void)
567*69606e3fSchristos {
568*69606e3fSchristos register unsigned int nvpaths;
569*69606e3fSchristos register struct vpath *v;
570*69606e3fSchristos
571*69606e3fSchristos puts (_("\n# VPATH Search Paths\n"));
572*69606e3fSchristos
573*69606e3fSchristos nvpaths = 0;
574*69606e3fSchristos for (v = vpaths; v != 0; v = v->next)
575*69606e3fSchristos {
576*69606e3fSchristos register unsigned int i;
577*69606e3fSchristos
578*69606e3fSchristos ++nvpaths;
579*69606e3fSchristos
580*69606e3fSchristos printf ("vpath %s ", v->pattern);
581*69606e3fSchristos
582*69606e3fSchristos for (i = 0; v->searchpath[i] != 0; ++i)
583*69606e3fSchristos printf ("%s%c", v->searchpath[i],
584*69606e3fSchristos v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
585*69606e3fSchristos }
586*69606e3fSchristos
587*69606e3fSchristos if (vpaths == 0)
588*69606e3fSchristos puts (_("# No `vpath' search paths."));
589*69606e3fSchristos else
590*69606e3fSchristos printf (_("\n# %u `vpath' search paths.\n"), nvpaths);
591*69606e3fSchristos
592*69606e3fSchristos if (general_vpath == 0)
593*69606e3fSchristos puts (_("\n# No general (`VPATH' variable) search path."));
594*69606e3fSchristos else
595*69606e3fSchristos {
596*69606e3fSchristos register char **path = general_vpath->searchpath;
597*69606e3fSchristos register unsigned int i;
598*69606e3fSchristos
599*69606e3fSchristos fputs (_("\n# General (`VPATH' variable) search path:\n# "), stdout);
600*69606e3fSchristos
601*69606e3fSchristos for (i = 0; path[i] != 0; ++i)
602*69606e3fSchristos printf ("%s%c", path[i],
603*69606e3fSchristos path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
604*69606e3fSchristos }
605*69606e3fSchristos }
606