1 /* Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
2 This file is part of GNU Make.
4 GNU Make is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 GNU Make is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GNU Make; see the file COPYING. If not, write to
16 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
23 /* Structure used to represent a selective VPATH searchpath. */
27 struct vpath
*next
; /* Pointer to next struct in the linked list. */
28 char *pattern
; /* The pattern to match. */
29 char *percent
; /* Pointer into `pattern' where the `%' is. */
30 unsigned int patlen
;/* Length of the pattern. */
31 char **searchpath
; /* Null-terminated list of directories. */
32 unsigned int maxlen
;/* Maximum length of any entry in the list. */
35 /* Linked-list of all selective VPATHs. */
37 static struct vpath
*vpaths
;
39 /* Structure for the general VPATH given in the variable. */
41 static struct vpath
*general_vpath
;
43 static int selective_vpath_search ();
45 /* Reverse the chain of selective VPATH lists so they
46 will be searched in the order given in the makefiles
47 and construct the list from the VPATH variable. */
52 register struct vpath
*new = 0;
53 register struct vpath
*old
, *nexto
;
56 /* Reverse the chain. */
57 for (old
= vpaths
; old
!= 0; old
= nexto
)
66 /* If there is a VPATH variable with a nonnull value, construct the
67 general VPATH list from it. We use variable_expand rather than just
68 calling lookup_variable so that it will be recursively expanded. */
71 /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */
72 int save
= warn_undefined_variables_flag
;
73 warn_undefined_variables_flag
= 0;
75 p
= variable_expand ("$(strip $(VPATH))");
77 warn_undefined_variables_flag
= save
;
82 /* Save the list of vpaths. */
83 struct vpath
*save_vpaths
= vpaths
;
85 /* Empty `vpaths' so the new one will have no next, and `vpaths'
86 will still be nil if P contains no existing directories. */
90 construct_vpath_list ("%", p
);
92 /* Store the created path as the general path,
93 and restore the old list of vpaths. */
94 general_vpath
= vpaths
;
99 /* Construct the VPATH listing for the pattern and searchpath given.
101 This function is called to generate selective VPATH lists and also for
102 the general VPATH list (which is in fact just a selective VPATH that
103 is applied to everything). The returned pointer is either put in the
104 linked list of all selective VPATH lists or in the GENERAL_VPATH
107 If SEARCHPATH is nil, remove all previous listings with the same
108 pattern. If PATTERN is nil, remove all VPATH listings.
109 Existing and readable directories that are not "." given in the
110 searchpath separated by colons are loaded into the directory hash
111 table if they are not there already and put in the VPATH searchpath
112 for the given pattern with trailing slashes stripped off if present
113 (and if the directory is not the root, "/").
114 The length of the longest entry in the list is put in the structure as well.
115 The new entry will be at the head of the VPATHS chain. */
118 construct_vpath_list (pattern
, dirpath
)
119 char *pattern
, *dirpath
;
121 register unsigned int elem
;
123 register char **vpath
;
124 register unsigned int maxvpath
;
125 unsigned int maxelem
;
130 pattern
= savestring (pattern
, strlen (pattern
));
131 percent
= find_percent (pattern
);
136 /* Remove matching listings. */
137 register struct vpath
*path
, *lastpath
;
143 struct vpath
*next
= path
->next
;
146 || (((percent
== 0 && path
->percent
== 0)
147 || (percent
- pattern
== path
->percent
- path
->pattern
))
148 && streq (pattern
, path
->pattern
)))
150 /* Remove it from the linked list. */
154 lastpath
->next
= next
;
156 /* Free its unused storage. */
157 free (path
->pattern
);
158 free ((char *) path
->searchpath
);
159 free ((char *) path
);
172 /* Figure out the maximum number of VPATH entries and
173 put it in MAXELEM. We start with 2, one before the
174 first colon and one nil, the list terminator and
175 increment our estimated number for each colon or blank we find. */
179 if (*p
++ == ':' || isblank (*p
))
182 vpath
= (char **) xmalloc (maxelem
* sizeof (char *));
185 /* Skip over any initial colons and blanks. */
187 while (*p
== ':' || isblank (*p
))
196 /* Find the end of this entry. */
198 while (*p
!= '\0' && *p
!= ':' && !isblank (*p
))
202 /* Make sure there's no trailing slash,
203 but still allow "/" as a directory. */
204 if (len
> 1 && p
[-1] == '/')
207 if (len
> 1 || *v
!= '.')
209 v
= savestring (v
, len
);
211 /* Verify that the directory actually exists. */
213 if (dir_file_exists_p (v
, ""))
215 /* It does. Put it in the list. */
216 vpath
[elem
++] = dir_name (v
);
222 /* The directory does not exist. Omit from the list. */
226 /* Skip over colons and blanks between entries. */
227 while (*p
== ':' || isblank (*p
))
234 /* ELEM is now incremented one element past the last
235 entry, to where the nil-pointer terminator goes.
236 Usually this is maxelem - 1. If not, shrink down. */
237 if (elem
< (maxelem
- 1))
238 vpath
= (char **) xrealloc ((char *) vpath
,
239 (elem
+ 1) * sizeof (char *));
241 /* Put the nil-pointer terminator on the end of the VPATH list. */
244 /* Construct the vpath structure and put it into the linked list. */
245 path
= (struct vpath
*) xmalloc (sizeof (struct vpath
));
246 path
->searchpath
= vpath
;
247 path
->maxlen
= maxvpath
;
251 /* Set up the members. */
252 path
->pattern
= pattern
;
253 path
->percent
= percent
;
254 path
->patlen
= strlen (pattern
);
258 /* There were no entries, so free whatever space we allocated. */
259 free ((char *) vpath
);
265 /* Search the VPATH list whose pattern matches *FILE for a directory
266 where the name pointed to by FILE exists. If it is found, we set *FILE to
267 the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
268 not NULL) to its modtime (or zero if no stat call was done), and return 1.
269 Otherwise we return 0. */
272 vpath_search (file
, mtime_ptr
)
276 register struct vpath
*v
;
278 /* If there are no VPATH entries or FILENAME starts at the root,
279 there is nothing we can do. */
281 if (**file
== '/' || (vpaths
== 0 && general_vpath
== 0))
284 for (v
= vpaths
; v
!= 0; v
= v
->next
)
285 if (pattern_matches (v
->pattern
, v
->percent
, *file
))
286 if (selective_vpath_search (v
, file
, mtime_ptr
))
289 if (general_vpath
!= 0
290 && selective_vpath_search (general_vpath
, file
, mtime_ptr
))
297 /* Search the given VPATH list for a directory where the name pointed
298 to by FILE exists. If it is found, we set *FILE to the newly malloc'd
299 name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
300 its modtime (or zero if no stat call was done), and we return 1.
301 Otherwise we return 0. */
304 selective_vpath_search (path
, file
, mtime_ptr
)
312 register char **vpath
= path
->searchpath
;
313 unsigned int maxvpath
= path
->maxlen
;
314 register unsigned int i
;
315 unsigned int flen
, vlen
, name_dplen
;
318 /* Find out if *FILE is a target.
319 If and only if it is NOT a target, we will accept prospective
320 files that don't exist but are mentioned in a makefile. */
322 struct file
*f
= lookup_file (*file
);
323 not_target
= f
== 0 || !f
->is_target
;
326 flen
= strlen (*file
);
328 /* Split *FILE into a directory prefix and a name-within-directory.
329 NAME_DPLEN gets the length of the prefix; FILENAME gets the
330 pointer to the name-within-directory and FLEN is its length. */
332 n
= rindex (*file
, '/');
333 name_dplen
= n
!= 0 ? n
- *file
: 0;
334 filename
= name_dplen
> 0 ? n
+ 1 : *file
;
336 flen
-= name_dplen
+ 1;
338 /* Allocate enough space for the biggest VPATH entry,
339 a slash, the directory prefix that came with *FILE,
340 another slash (although this one may not always be
341 necessary), the filename, and a null terminator. */
342 name
= (char *) alloca (maxvpath
+ 1 + name_dplen
+ 1 + flen
+ 1);
344 /* Try each VPATH entry. */
345 for (i
= 0; vpath
[i
] != 0; ++i
)
347 int exists_in_cache
= 0;
351 /* Put the next VPATH entry into NAME at N and increment N past it. */
352 vlen
= strlen (vpath
[i
]);
353 bcopy (vpath
[i
], n
, vlen
);
356 /* Add the directory prefix already in *FILE. */
360 bcopy (*file
, n
, name_dplen
);
364 /* Now add the name-within-directory at the end of NAME. */
365 if (n
!= name
&& n
[-1] != '/')
368 bcopy (filename
, n
+ 1, flen
+ 1);
371 bcopy (filename
, n
, flen
+ 1);
374 /* Since *FILE is not a target, if the file is
375 mentioned in a makefile, we consider it existent. */
376 exists
= lookup_file (name
) != 0;
380 /* That file wasn't mentioned in the makefile.
381 See if it actually exists. */
383 /* Clobber a null into the name at the last slash.
384 Now NAME is the name of the directory to look in. */
387 /* We know the directory is in the hash table now because either
388 construct_vpath_list or the code just above put it there.
389 Does the file we seek exist in it? */
390 exists_in_cache
= exists
= dir_file_exists_p (name
, filename
);
395 /* The file is in the directory cache.
396 Now check that it actually exists in the filesystem.
397 The cache may be out of date. When vpath thinks a file
398 exists, but stat fails for it, confusion results in the
403 /* Put the slash back in NAME. */
406 if (!exists_in_cache
/* Makefile-mentioned file need not exist. */
407 || stat (name
, &st
) == 0) /* Does it really exist? */
409 /* We have found a file.
410 Store the name we found into *FILE for the caller. */
412 *file
= savestring (name
, (n
+ 1 - name
) + flen
);
415 /* Store the modtime into *MTIME_PTR for the caller.
416 If we have had no need to stat the file here,
417 we record a zero modtime to indicate this. */
418 *mtime_ptr
= exists_in_cache
? st
.st_mtime
: (time_t) 0;
428 /* Print the data base of VPATH search paths. */
431 print_vpath_data_base ()
433 register unsigned int nvpaths
;
434 register struct vpath
*v
;
436 puts ("\n# VPATH Search Paths\n");
439 for (v
= vpaths
; v
!= 0; v
= v
->next
)
441 register unsigned int i
;
445 printf ("vpath %s ", v
->pattern
);
447 for (i
= 0; v
->searchpath
[i
] != 0; ++i
)
448 printf ("%s%c", v
->searchpath
[i
],
449 v
->searchpath
[i
+ 1] == 0 ? '\n' : ':');
453 puts ("# No `vpath' search paths.");
455 printf ("\n# %u `vpath' search paths.\n", nvpaths
);
457 if (general_vpath
== 0)
458 puts ("\n# No general (`VPATH' variable) search path.");
461 register char **path
= general_vpath
->searchpath
;
462 register unsigned int i
;
464 fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout
);
466 for (i
= 0; path
[i
] != 0; ++i
)
467 printf ("%s%c", path
[i
], path
[i
+ 1] == 0 ? '\n' : ':');