3.74.6
[make.git] / vpath.c
blobbf13bc3aa98c86df4d9f41cdc0cd365a0086d0a2
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)
8 any later version.
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. */
19 #include "make.h"
20 #include "filedef.h"
21 #include "variable.h"
22 #ifdef WIN32
23 #include "pathstuff.h"
24 #endif
27 /* Structure used to represent a selective VPATH searchpath. */
29 struct vpath
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. */
53 void
54 build_vpath_lists ()
56 register struct vpath *new = 0;
57 register struct vpath *old, *nexto;
58 register char *p;
60 /* Reverse the chain. */
61 for (old = vpaths; old != 0; old = nexto)
63 nexto = old->next;
64 old->next = new;
65 new = old;
68 vpaths = new;
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;
84 if (*p != '\0')
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. */
91 vpaths = 0;
93 /* Parse P. */
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;
99 vpaths = save_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
109 variable.
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. */
121 void
122 construct_vpath_list (pattern, dirpath)
123 char *pattern, *dirpath;
125 register unsigned int elem;
126 register char *p;
127 register char **vpath;
128 register unsigned int maxvpath;
129 unsigned int maxelem;
130 char *percent;
132 if (pattern != 0)
134 pattern = savestring (pattern, strlen (pattern));
135 percent = find_percent (pattern);
138 if (dirpath == 0)
140 /* Remove matching listings. */
141 register struct vpath *path, *lastpath;
143 lastpath = 0;
144 path = vpaths;
145 while (path != 0)
147 struct vpath *next = path->next;
149 if (pattern == 0
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. */
155 if (lastpath == 0)
156 vpaths = path->next;
157 else
158 lastpath->next = next;
160 /* Free its unused storage. */
161 free (path->pattern);
162 free ((char *) path->searchpath);
163 free ((char *) path);
165 else
166 lastpath = path;
168 path = next;
171 if (pattern != 0)
172 free (pattern);
173 return;
176 #ifdef WIN32
177 convert_vpath_to_win32(dirpath, ';');
178 #endif
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. */
184 maxelem = 2;
185 p = dirpath;
186 while (*p != '\0')
187 if (*p++ == PATH_SEPARATOR_CHAR || isblank (*p))
188 ++maxelem;
190 vpath = (char **) xmalloc (maxelem * sizeof (char *));
191 maxvpath = 0;
193 /* Skip over any initial colons and blanks. */
194 p = dirpath;
195 while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
196 ++p;
198 elem = 0;
199 while (*p != '\0')
201 char *v;
202 unsigned int len;
204 /* Find the end of this entry. */
205 v = p;
206 while (*p != '\0' && *p != PATH_SEPARATOR_CHAR && !isblank (*p))
207 ++p;
209 len = p - v;
210 /* Make sure there's no trailing slash,
211 but still allow "/" as a directory. */
212 if (len > 1 && p[-1] == '/')
213 --len;
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);
225 free (v);
226 if (len > maxvpath)
227 maxvpath = len;
229 else
230 /* The directory does not exist. Omit from the list. */
231 free (v);
234 /* Skip over colons and blanks between entries. */
235 while (*p == PATH_SEPARATOR_CHAR || isblank (*p))
236 ++p;
239 if (elem > 0)
241 struct vpath *path;
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. */
250 vpath[elem] = 0;
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;
256 path->next = vpaths;
257 vpaths = path;
259 /* Set up the members. */
260 path->pattern = pattern;
261 path->percent = percent;
262 path->patlen = strlen (pattern);
264 else
266 /* There were no entries, so free whatever space we allocated. */
267 free ((char *) vpath);
268 if (pattern != 0)
269 free (pattern);
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)
281 char **file;
282 time_t *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. */
289 if (**file == '/'
290 #ifdef WIN32
291 || **file == '\\'
292 || (*file)[1] == ':'
293 #endif
294 || (vpaths == 0 && general_vpath == 0))
295 return 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))
300 return 1;
302 if (general_vpath != 0
303 && selective_vpath_search (general_vpath, file, mtime_ptr))
304 return 1;
306 return 0;
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. */
316 static int
317 selective_vpath_search (path, file, mtime_ptr)
318 struct vpath *path;
319 char **file;
320 time_t *mtime_ptr;
322 int not_target;
323 char *name, *n;
324 char *filename;
325 register char **vpath = path->searchpath;
326 unsigned int maxvpath = path->maxlen;
327 register unsigned int i;
328 unsigned int flen, vlen, name_dplen;
329 int exists = 0;
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, '/');
346 #ifdef WIN32
347 if (!n)
348 n = rindex(*file,, '\\');
349 #endif
350 name_dplen = n != 0 ? n - *file : 0;
351 filename = name_dplen > 0 ? n + 1 : *file;
352 if (name_dplen > 0)
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;
366 n = name;
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);
371 n += vlen;
373 /* Add the directory prefix already in *FILE. */
374 if (name_dplen > 0)
376 *n++ = '/';
377 bcopy (*file, n, name_dplen);
378 n += name_dplen;
381 /* Now add the name-within-directory at the end of NAME. */
382 if (n != name && n[-1] != '/')
384 *n = '/';
385 bcopy (filename, n + 1, flen + 1);
387 else
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
402 seem logical. */
404 struct file *f = lookup_file (name);
405 if (f != 0)
406 exists = not_target || f->is_target;
409 if (!exists)
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. */
416 *n = '\0';
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);
424 if (exists)
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
430 higher levels. */
432 struct stat st;
434 /* Put the slash back in NAME. */
435 *n = '/';
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);
445 if (mtime_ptr != 0)
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;
451 free (name);
452 return 1;
454 else
455 exists = 0;
459 free (name);
460 return 0;
463 /* Print the data base of VPATH search paths. */
465 void
466 print_vpath_data_base ()
468 register unsigned int nvpaths;
469 register struct vpath *v;
471 puts ("\n# VPATH Search Paths\n");
473 nvpaths = 0;
474 for (v = vpaths; v != 0; v = v->next)
476 register unsigned int i;
478 ++nvpaths;
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);
487 if (vpaths == 0)
488 puts ("# No `vpath' search paths.");
489 else
490 printf ("\n# %u `vpath' search paths.\n", nvpaths);
492 if (general_vpath == 0)
493 puts ("\n# No general (`VPATH' variable) search path.");
494 else
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);