1 /* Implementation of pattern-matching file search paths for GNU Make.
2 Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
3 This file is part of GNU Make.
5 GNU Make is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 GNU Make is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNU Make; see the file COPYING. If not, write to
17 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 /* Structure used to represent a selective VPATH searchpath. */
28 struct vpath
*next
; /* Pointer to next struct in the linked list. */
29 char *pattern
; /* The pattern to match. */
30 char *percent
; /* Pointer into `pattern' where the `%' is. */
31 unsigned int patlen
;/* Length of the pattern. */
32 char **searchpath
; /* Null-terminated list of directories. */
33 unsigned int maxlen
;/* Maximum length of any entry in the list. */
36 /* Linked-list of all selective VPATHs. */
38 static struct vpath
*vpaths
;
40 /* Structure for the general VPATH given in the variable. */
42 static struct vpath
*general_vpath
;
44 static int selective_vpath_search ();
46 /* Reverse the chain of selective VPATH lists so they
47 will be searched in the order given in the makefiles
48 and construct the list from the VPATH variable. */
53 register struct vpath
*new = 0;
54 register struct vpath
*old
, *nexto
;
57 /* Reverse the chain. */
58 for (old
= vpaths
; old
!= 0; old
= nexto
)
67 /* If there is a VPATH variable with a nonnull value, construct the
68 general VPATH list from it. We use variable_expand rather than just
69 calling lookup_variable so that it will be recursively expanded. */
72 /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
73 int save
= warn_undefined_variables_flag
;
74 warn_undefined_variables_flag
= 0;
76 p
= variable_expand ("$(strip $(VPATH))");
78 warn_undefined_variables_flag
= save
;
83 /* Save the list of vpaths. */
84 struct vpath
*save_vpaths
= vpaths
;
86 /* Empty `vpaths' so the new one will have no next, and `vpaths'
87 will still be nil if P contains no existing directories. */
91 construct_vpath_list ("%", p
);
93 /* Store the created path as the general path,
94 and restore the old list of vpaths. */
95 general_vpath
= vpaths
;
100 /* Construct the VPATH listing for the pattern and searchpath given.
102 This function is called to generate selective VPATH lists and also for
103 the general VPATH list (which is in fact just a selective VPATH that
104 is applied to everything). The returned pointer is either put in the
105 linked list of all selective VPATH lists or in the GENERAL_VPATH
108 If SEARCHPATH is nil, remove all previous listings with the same
109 pattern. If PATTERN is nil, remove all VPATH listings.
110 Existing and readable directories that are not "." given in the
111 searchpath separated by colons are loaded into the directory hash
112 table if they are not there already and put in the VPATH searchpath
113 for the given pattern with trailing slashes stripped off if present
114 (and if the directory is not the root, "/").
115 The length of the longest entry in the list is put in the structure as well.
116 The new entry will be at the head of the VPATHS chain. */
119 construct_vpath_list (pattern
, dirpath
)
120 char *pattern
, *dirpath
;
122 register unsigned int elem
;
124 register char **vpath
;
125 register unsigned int maxvpath
;
126 unsigned int maxelem
;
131 pattern
= savestring (pattern
, strlen (pattern
));
132 percent
= find_percent (pattern
);
137 /* Remove matching listings. */
138 register struct vpath
*path
, *lastpath
;
144 struct vpath
*next
= path
->next
;
147 || (((percent
== 0 && path
->percent
== 0)
148 || (percent
- pattern
== path
->percent
- path
->pattern
))
149 && streq (pattern
, path
->pattern
)))
151 /* Remove it from the linked list. */
155 lastpath
->next
= next
;
157 /* Free its unused storage. */
158 free (path
->pattern
);
159 free ((char *) path
->searchpath
);
160 free ((char *) path
);
173 /* Figure out the maximum number of VPATH entries and
174 put it in MAXELEM. We start with 2, one before the
175 first colon and one nil, the list terminator and
176 increment our estimated number for each colon or blank we find. */
180 if (*p
++ == PATH_SEPARATOR_CHAR
|| isblank (*p
))
183 vpath
= (char **) xmalloc (maxelem
* sizeof (char *));
186 /* Skip over any initial colons and blanks. */
188 while (*p
== PATH_SEPARATOR_CHAR
|| isblank (*p
))
197 /* Find the end of this entry. */
199 while (*p
!= '\0' && *p
!= PATH_SEPARATOR_CHAR
&& !isblank (*p
))
203 /* Make sure there's no trailing slash,
204 but still allow "/" as a directory. */
205 if (len
> 1 && p
[-1] == '/')
208 if (len
> 1 || *v
!= '.')
210 v
= savestring (v
, len
);
212 /* Verify that the directory actually exists. */
214 if (dir_file_exists_p (v
, ""))
216 /* It does. Put it in the list. */
217 vpath
[elem
++] = dir_name (v
);
223 /* The directory does not exist. Omit from the list. */
227 /* Skip over colons and blanks between entries. */
228 while (*p
== PATH_SEPARATOR_CHAR
|| isblank (*p
))
235 /* ELEM is now incremented one element past the last
236 entry, to where the nil-pointer terminator goes.
237 Usually this is maxelem - 1. If not, shrink down. */
238 if (elem
< (maxelem
- 1))
239 vpath
= (char **) xrealloc ((char *) vpath
,
240 (elem
+ 1) * sizeof (char *));
242 /* Put the nil-pointer terminator on the end of the VPATH list. */
245 /* Construct the vpath structure and put it into the linked list. */
246 path
= (struct vpath
*) xmalloc (sizeof (struct vpath
));
247 path
->searchpath
= vpath
;
248 path
->maxlen
= maxvpath
;
252 /* Set up the members. */
253 path
->pattern
= pattern
;
254 path
->percent
= percent
;
255 path
->patlen
= strlen (pattern
);
259 /* There were no entries, so free whatever space we allocated. */
260 free ((char *) vpath
);
266 /* Search the VPATH list whose pattern matches *FILE for a directory
267 where the name pointed to by FILE exists. If it is found, we set *FILE to
268 the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
269 not NULL) to its modtime (or zero if no stat call was done), and return 1.
270 Otherwise we return 0. */
273 vpath_search (file
, mtime_ptr
)
277 register struct vpath
*v
;
279 /* If there are no VPATH entries or FILENAME starts at the root,
280 there is nothing we can do. */
282 if (**file
== '/' || (vpaths
== 0 && general_vpath
== 0))
285 for (v
= vpaths
; v
!= 0; v
= v
->next
)
286 if (pattern_matches (v
->pattern
, v
->percent
, *file
))
287 if (selective_vpath_search (v
, file
, mtime_ptr
))
290 if (general_vpath
!= 0
291 && selective_vpath_search (general_vpath
, file
, mtime_ptr
))
298 /* Search the given VPATH list for a directory where the name pointed
299 to by FILE exists. If it is found, we set *FILE to the newly malloc'd
300 name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
301 its modtime (or zero if no stat call was done), and we return 1.
302 Otherwise we return 0. */
305 selective_vpath_search (path
, file
, mtime_ptr
)
313 register char **vpath
= path
->searchpath
;
314 unsigned int maxvpath
= path
->maxlen
;
315 register unsigned int i
;
316 unsigned int flen
, vlen
, name_dplen
;
319 /* Find out if *FILE is a target.
320 If and only if it is NOT a target, we will accept prospective
321 files that don't exist but are mentioned in a makefile. */
323 struct file
*f
= lookup_file (*file
);
324 not_target
= f
== 0 || !f
->is_target
;
327 flen
= strlen (*file
);
329 /* Split *FILE into a directory prefix and a name-within-directory.
330 NAME_DPLEN gets the length of the prefix; FILENAME gets the
331 pointer to the name-within-directory and FLEN is its length. */
333 n
= rindex (*file
, '/');
334 name_dplen
= n
!= 0 ? n
- *file
: 0;
335 filename
= name_dplen
> 0 ? n
+ 1 : *file
;
337 flen
-= name_dplen
+ 1;
339 /* Allocate enough space for the biggest VPATH entry,
340 a slash, the directory prefix that came with *FILE,
341 another slash (although this one may not always be
342 necessary), the filename, and a null terminator. */
343 name
= (char *) alloca (maxvpath
+ 1 + name_dplen
+ 1 + flen
+ 1);
345 /* Try each VPATH entry. */
346 for (i
= 0; vpath
[i
] != 0; ++i
)
348 int exists_in_cache
= 0;
352 /* Put the next VPATH entry into NAME at N and increment N past it. */
353 vlen
= strlen (vpath
[i
]);
354 bcopy (vpath
[i
], n
, vlen
);
357 /* Add the directory prefix already in *FILE. */
361 bcopy (*file
, n
, name_dplen
);
365 /* Now add the name-within-directory at the end of NAME. */
366 if (n
!= name
&& n
[-1] != '/')
369 bcopy (filename
, n
+ 1, flen
+ 1);
372 bcopy (filename
, n
, flen
+ 1);
374 /* Check if the file is mentioned in a makefile. If *FILE is not
375 a target, that is enough for us to decide this file exists.
376 If *FILE is a target, then the file must be mentioned in the
377 makefile also as a target to be chosen.
379 The restriction that *FILE must not be a target for a
380 makefile-mentioned file to be chosen was added by an
381 inadequately commented change in July 1990; I am not sure off
382 hand what problem it fixes.
384 In December 1993 I loosened of this restriction to allow a file
385 to be chosen if it is mentioned as a target in a makefile. This
388 struct file
*f
= lookup_file (name
);
390 exists
= not_target
|| f
->is_target
;
395 /* That file wasn't mentioned in the makefile.
396 See if it actually exists. */
398 /* Clobber a null into the name at the last slash.
399 Now NAME is the name of the directory to look in. */
402 /* We know the directory is in the hash table now because either
403 construct_vpath_list or the code just above put it there.
404 Does the file we seek exist in it? */
405 exists_in_cache
= exists
= dir_file_exists_p (name
, filename
);
410 /* The file is in the directory cache.
411 Now check that it actually exists in the filesystem.
412 The cache may be out of date. When vpath thinks a file
413 exists, but stat fails for it, confusion results in the
418 /* Put the slash back in NAME. */
421 if (!exists_in_cache
/* Makefile-mentioned file need not exist. */
422 || safe_stat (name
, &st
) == 0) /* Does it really exist? */
424 /* We have found a file.
425 Store the name we found into *FILE for the caller. */
427 *file
= savestring (name
, (n
+ 1 - name
) + flen
);
430 /* Store the modtime into *MTIME_PTR for the caller.
431 If we have had no need to stat the file here,
432 we record a zero modtime to indicate this. */
433 *mtime_ptr
= exists_in_cache
? st
.st_mtime
: (time_t) 0;
443 /* Print the data base of VPATH search paths. */
446 print_vpath_data_base ()
448 register unsigned int nvpaths
;
449 register struct vpath
*v
;
451 puts ("\n# VPATH Search Paths\n");
454 for (v
= vpaths
; v
!= 0; v
= v
->next
)
456 register unsigned int i
;
460 printf ("vpath %s ", v
->pattern
);
462 for (i
= 0; v
->searchpath
[i
] != 0; ++i
)
463 printf ("%s%c", v
->searchpath
[i
],
464 v
->searchpath
[i
+ 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR
);
468 puts ("# No `vpath' search paths.");
470 printf ("\n# %u `vpath' search paths.\n", nvpaths
);
472 if (general_vpath
== 0)
473 puts ("\n# No general (`VPATH' variable) search path.");
476 register char **path
= general_vpath
->searchpath
;
477 register unsigned int i
;
479 fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout
);
481 for (i
= 0; path
[i
] != 0; ++i
)
482 printf ("%s%c", path
[i
],
483 path
[i
+ 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR
);