1 /* Implementation of pattern-matching file search paths for GNU Make.
2 Copyright (C) 1988, 89, 91, 92, 93, 94, 95, 96 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. */
23 #include "pathstuff.h"
27 /* Structure used to represent a selective VPATH searchpath. */
31 struct vpath
*next
; /* Pointer to next struct in the linked list. */
32 char *pattern
; /* The pattern to match. */
33 char *percent
; /* Pointer into `pattern' where the `%' is. */
34 unsigned int patlen
;/* Length of the pattern. */
35 char **searchpath
; /* Null-terminated list of directories. */
36 unsigned int maxlen
;/* Maximum length of any entry in the list. */
39 /* Linked-list of all selective VPATHs. */
41 static struct vpath
*vpaths
;
43 /* Structure for the general VPATH given in the variable. */
45 static struct vpath
*general_vpath
;
47 static int selective_vpath_search
PARAMS ((struct vpath
*path
, char **file
, time_t *mtime_ptr
));
49 /* Reverse the chain of selective VPATH lists so they
50 will be searched in the order given in the makefiles
51 and construct the list from the VPATH variable. */
56 register struct vpath
*new = 0;
57 register struct vpath
*old
, *nexto
;
60 /* Reverse the chain. */
61 for (old
= vpaths
; old
!= 0; old
= nexto
)
70 /* If there is a VPATH variable with a nonnull value, construct the
71 general VPATH list from it. We use variable_expand rather than just
72 calling lookup_variable so that it will be recursively expanded. */
75 /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
76 int save
= warn_undefined_variables_flag
;
77 warn_undefined_variables_flag
= 0;
79 p
= variable_expand ("$(strip $(VPATH))");
81 warn_undefined_variables_flag
= save
;
86 /* Save the list of vpaths. */
87 struct vpath
*save_vpaths
= vpaths
;
89 /* Empty `vpaths' so the new one will have no next, and `vpaths'
90 will still be nil if P contains no existing directories. */
94 construct_vpath_list ("%", p
);
96 /* Store the created path as the general path,
97 and restore the old list of vpaths. */
98 general_vpath
= vpaths
;
103 /* Construct the VPATH listing for the pattern and searchpath given.
105 This function is called to generate selective VPATH lists and also for
106 the general VPATH list (which is in fact just a selective VPATH that
107 is applied to everything). The returned pointer is either put in the
108 linked list of all selective VPATH lists or in the GENERAL_VPATH
111 If SEARCHPATH is nil, remove all previous listings with the same
112 pattern. If PATTERN is nil, remove all VPATH listings.
113 Existing and readable directories that are not "." given in the
114 searchpath separated by colons are loaded into the directory hash
115 table if they are not there already and put in the VPATH searchpath
116 for the given pattern with trailing slashes stripped off if present
117 (and if the directory is not the root, "/").
118 The length of the longest entry in the list is put in the structure as well.
119 The new entry will be at the head of the VPATHS chain. */
122 construct_vpath_list (pattern
, dirpath
)
123 char *pattern
, *dirpath
;
125 register unsigned int elem
;
127 register char **vpath
;
128 register unsigned int maxvpath
;
129 unsigned int maxelem
;
134 pattern
= savestring (pattern
, strlen (pattern
));
135 percent
= find_percent (pattern
);
140 /* Remove matching listings. */
141 register struct vpath
*path
, *lastpath
;
147 struct vpath
*next
= path
->next
;
150 || (((percent
== 0 && path
->percent
== 0)
151 || (percent
- pattern
== path
->percent
- path
->pattern
))
152 && streq (pattern
, path
->pattern
)))
154 /* Remove it from the linked list. */
158 lastpath
->next
= next
;
160 /* Free its unused storage. */
161 free (path
->pattern
);
162 free ((char *) path
->searchpath
);
163 free ((char *) path
);
177 convert_vpath_to_win32(dirpath
, ';');
180 /* Figure out the maximum number of VPATH entries and
181 put it in MAXELEM. We start with 2, one before the
182 first colon and one nil, the list terminator and
183 increment our estimated number for each colon or blank we find. */
187 if (*p
++ == PATH_SEPARATOR_CHAR
|| isblank (*p
))
190 vpath
= (char **) xmalloc (maxelem
* sizeof (char *));
193 /* Skip over any initial colons and blanks. */
195 while (*p
== PATH_SEPARATOR_CHAR
|| isblank (*p
))
204 /* Find the end of this entry. */
206 while (*p
!= '\0' && *p
!= PATH_SEPARATOR_CHAR
&& !isblank (*p
))
210 /* Make sure there's no trailing slash,
211 but still allow "/" as a directory. */
212 if (len
> 1 && p
[-1] == '/')
215 if (len
> 1 || *v
!= '.')
217 v
= savestring (v
, len
);
219 /* Verify that the directory actually exists. */
221 if (dir_file_exists_p (v
, ""))
223 /* It does. Put it in the list. */
224 vpath
[elem
++] = dir_name (v
);
230 /* The directory does not exist. Omit from the list. */
234 /* Skip over colons and blanks between entries. */
235 while (*p
== PATH_SEPARATOR_CHAR
|| isblank (*p
))
242 /* ELEM is now incremented one element past the last
243 entry, to where the nil-pointer terminator goes.
244 Usually this is maxelem - 1. If not, shrink down. */
245 if (elem
< (maxelem
- 1))
246 vpath
= (char **) xrealloc ((char *) vpath
,
247 (elem
+ 1) * sizeof (char *));
249 /* Put the nil-pointer terminator on the end of the VPATH list. */
252 /* Construct the vpath structure and put it into the linked list. */
253 path
= (struct vpath
*) xmalloc (sizeof (struct vpath
));
254 path
->searchpath
= vpath
;
255 path
->maxlen
= maxvpath
;
259 /* Set up the members. */
260 path
->pattern
= pattern
;
261 path
->percent
= percent
;
262 path
->patlen
= strlen (pattern
);
266 /* There were no entries, so free whatever space we allocated. */
267 free ((char *) vpath
);
273 /* Search the VPATH list whose pattern matches *FILE for a directory
274 where the name pointed to by FILE exists. If it is found, we set *FILE to
275 the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
276 not NULL) to its modtime (or zero if no stat call was done), and return 1.
277 Otherwise we return 0. */
280 vpath_search (file
, mtime_ptr
)
284 register struct vpath
*v
;
286 /* If there are no VPATH entries or FILENAME starts at the root,
287 there is nothing we can do. */
294 || (vpaths
== 0 && general_vpath
== 0))
297 for (v
= vpaths
; v
!= 0; v
= v
->next
)
298 if (pattern_matches (v
->pattern
, v
->percent
, *file
))
299 if (selective_vpath_search (v
, file
, mtime_ptr
))
302 if (general_vpath
!= 0
303 && selective_vpath_search (general_vpath
, file
, mtime_ptr
))
310 /* Search the given VPATH list for a directory where the name pointed
311 to by FILE exists. If it is found, we set *FILE to the newly malloc'd
312 name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
313 its modtime (or zero if no stat call was done), and we return 1.
314 Otherwise we return 0. */
317 selective_vpath_search (path
, file
, mtime_ptr
)
325 register char **vpath
= path
->searchpath
;
326 unsigned int maxvpath
= path
->maxlen
;
327 register unsigned int i
;
328 unsigned int flen
, vlen
, name_dplen
;
331 /* Find out if *FILE is a target.
332 If and only if it is NOT a target, we will accept prospective
333 files that don't exist but are mentioned in a makefile. */
335 struct file
*f
= lookup_file (*file
);
336 not_target
= f
== 0 || !f
->is_target
;
339 flen
= strlen (*file
);
341 /* Split *FILE into a directory prefix and a name-within-directory.
342 NAME_DPLEN gets the length of the prefix; FILENAME gets the
343 pointer to the name-within-directory and FLEN is its length. */
345 n
= rindex (*file
, '/');
348 n
= rindex(*file
,, '\\');
350 name_dplen
= n
!= 0 ? n
- *file
: 0;
351 filename
= name_dplen
> 0 ? n
+ 1 : *file
;
353 flen
-= name_dplen
+ 1;
355 /* Allocate enough space for the biggest VPATH entry,
356 a slash, the directory prefix that came with *FILE,
357 another slash (although this one may not always be
358 necessary), the filename, and a null terminator. */
359 name
= (char *) xmalloc (maxvpath
+ 1 + name_dplen
+ 1 + flen
+ 1);
361 /* Try each VPATH entry. */
362 for (i
= 0; vpath
[i
] != 0; ++i
)
364 int exists_in_cache
= 0;
368 /* Put the next VPATH entry into NAME at N and increment N past it. */
369 vlen
= strlen (vpath
[i
]);
370 bcopy (vpath
[i
], n
, vlen
);
373 /* Add the directory prefix already in *FILE. */
377 bcopy (*file
, n
, name_dplen
);
381 /* Now add the name-within-directory at the end of NAME. */
382 if (n
!= name
&& n
[-1] != '/')
385 bcopy (filename
, n
+ 1, flen
+ 1);
388 bcopy (filename
, n
, flen
+ 1);
390 /* Check if the file is mentioned in a makefile. If *FILE is not
391 a target, that is enough for us to decide this file exists.
392 If *FILE is a target, then the file must be mentioned in the
393 makefile also as a target to be chosen.
395 The restriction that *FILE must not be a target for a
396 makefile-mentioned file to be chosen was added by an
397 inadequately commented change in July 1990; I am not sure off
398 hand what problem it fixes.
400 In December 1993 I loosened of this restriction to allow a file
401 to be chosen if it is mentioned as a target in a makefile. This
404 struct file
*f
= lookup_file (name
);
406 exists
= not_target
|| f
->is_target
;
411 /* That file wasn't mentioned in the makefile.
412 See if it actually exists. */
414 /* Clobber a null into the name at the last slash.
415 Now NAME is the name of the directory to look in. */
418 /* We know the directory is in the hash table now because either
419 construct_vpath_list or the code just above put it there.
420 Does the file we seek exist in it? */
421 exists_in_cache
= exists
= dir_file_exists_p (name
, filename
);
426 /* The file is in the directory cache.
427 Now check that it actually exists in the filesystem.
428 The cache may be out of date. When vpath thinks a file
429 exists, but stat fails for it, confusion results in the
434 /* Put the slash back in NAME. */
437 if (!exists_in_cache
/* Makefile-mentioned file need not exist. */
438 || stat (name
, &st
) == 0) /* Does it really exist? */
440 /* We have found a file.
441 Store the name we found into *FILE for the caller. */
443 *file
= savestring (name
, (n
+ 1 - name
) + flen
);
446 /* Store the modtime into *MTIME_PTR for the caller.
447 If we have had no need to stat the file here,
448 we record a zero modtime to indicate this. */
449 *mtime_ptr
= exists_in_cache
? st
.st_mtime
: (time_t) 0;
463 /* Print the data base of VPATH search paths. */
466 print_vpath_data_base ()
468 register unsigned int nvpaths
;
469 register struct vpath
*v
;
471 puts ("\n# VPATH Search Paths\n");
474 for (v
= vpaths
; v
!= 0; v
= v
->next
)
476 register unsigned int i
;
480 printf ("vpath %s ", v
->pattern
);
482 for (i
= 0; v
->searchpath
[i
] != 0; ++i
)
483 printf ("%s%c", v
->searchpath
[i
],
484 v
->searchpath
[i
+ 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR
);
488 puts ("# No `vpath' search paths.");
490 printf ("\n# %u `vpath' search paths.\n", nvpaths
);
492 if (general_vpath
== 0)
493 puts ("\n# No general (`VPATH' variable) search path.");
496 register char **path
= general_vpath
->searchpath
;
497 register unsigned int i
;
499 fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout
);
501 for (i
= 0; path
[i
] != 0; ++i
)
502 printf ("%s%c", path
[i
],
503 path
[i
+ 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR
);