entered into RCS
[make.git] / vpath.c
blobb619eb286e5e80989594793df663686e30a605d8
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)
7 any later version.
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. */
18 #include "make.h"
19 #include "file.h"
20 #include "variable.h"
23 /* Structure used to represent a selective VPATH searchpath. */
25 struct vpath
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. */
49 void
50 build_vpath_lists ()
52 register struct vpath *new = 0;
53 register struct vpath *old, *nexto;
54 register char *p;
56 /* Reverse the chain. */
57 for (old = vpaths; old != 0; old = nexto)
59 nexto = old->next;
60 old->next = new;
61 new = old;
64 vpaths = new;
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;
80 if (*p != '\0')
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. */
87 vpaths = 0;
89 /* Parse P. */
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;
95 vpaths = save_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
105 variable.
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. */
117 void
118 construct_vpath_list (pattern, dirpath)
119 char *pattern, *dirpath;
121 register unsigned int elem;
122 register char *p;
123 register char **vpath;
124 register unsigned int maxvpath;
125 unsigned int maxelem;
126 char *percent;
128 if (pattern != 0)
130 pattern = savestring (pattern, strlen (pattern));
131 percent = find_percent (pattern);
134 if (dirpath == 0)
136 /* Remove matching listings. */
137 register struct vpath *path, *lastpath;
139 lastpath = 0;
140 path = vpaths;
141 while (path != 0)
143 struct vpath *next = path->next;
145 if (pattern == 0
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. */
151 if (lastpath == 0)
152 vpaths = path->next;
153 else
154 lastpath->next = next;
156 /* Free its unused storage. */
157 free (path->pattern);
158 free ((char *) path->searchpath);
159 free ((char *) path);
161 else
162 lastpath = path;
164 path = next;
167 if (pattern != 0)
168 free (pattern);
169 return;
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. */
176 maxelem = 2;
177 p = dirpath;
178 while (*p != '\0')
179 if (*p++ == ':' || isblank (*p))
180 ++maxelem;
182 vpath = (char **) xmalloc (maxelem * sizeof (char *));
183 maxvpath = 0;
185 /* Skip over any initial colons and blanks. */
186 p = dirpath;
187 while (*p == ':' || isblank (*p))
188 ++p;
190 elem = 0;
191 while (*p != '\0')
193 char *v;
194 unsigned int len;
196 /* Find the end of this entry. */
197 v = p;
198 while (*p != '\0' && *p != ':' && !isblank (*p))
199 ++p;
201 len = p - v;
202 /* Make sure there's no trailing slash,
203 but still allow "/" as a directory. */
204 if (len > 1 && p[-1] == '/')
205 --len;
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);
217 free (v);
218 if (len > maxvpath)
219 maxvpath = len;
221 else
222 /* The directory does not exist. Omit from the list. */
223 free (v);
226 /* Skip over colons and blanks between entries. */
227 while (*p == ':' || isblank (*p))
228 ++p;
231 if (elem > 0)
233 struct vpath *path;
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. */
242 vpath[elem] = 0;
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;
248 path->next = vpaths;
249 vpaths = path;
251 /* Set up the members. */
252 path->pattern = pattern;
253 path->percent = percent;
254 path->patlen = strlen (pattern);
256 else
258 /* There were no entries, so free whatever space we allocated. */
259 free ((char *) vpath);
260 if (pattern != 0)
261 free (pattern);
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)
273 char **file;
274 time_t *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))
282 return 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))
287 return 1;
289 if (general_vpath != 0
290 && selective_vpath_search (general_vpath, file, mtime_ptr))
291 return 1;
293 return 0;
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. */
303 static int
304 selective_vpath_search (path, file, mtime_ptr)
305 struct vpath *path;
306 char **file;
307 time_t *mtime_ptr;
309 int not_target;
310 char *name, *n;
311 char *filename;
312 register char **vpath = path->searchpath;
313 unsigned int maxvpath = path->maxlen;
314 register unsigned int i;
315 unsigned int flen, vlen, name_dplen;
316 int exists = 0;
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;
335 if (name_dplen > 0)
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;
349 n = name;
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);
354 n += vlen;
356 /* Add the directory prefix already in *FILE. */
357 if (name_dplen > 0)
359 *n++ = '/';
360 bcopy (*file, n, name_dplen);
361 n += name_dplen;
364 /* Now add the name-within-directory at the end of NAME. */
365 if (n != name && n[-1] != '/')
367 *n = '/';
368 bcopy (filename, n + 1, flen + 1);
370 else
371 bcopy (filename, n, flen + 1);
373 /* Check if the file is mentioned in a makefile. If *FILE is not
374 a target, that is enough for us to decide this file exists.
375 If *FILE is a target, then the file must be mentioned in the
376 makefile also as a target to be chosen.
378 The restriction that *FILE must not be a target for a
379 makefile-mentioned file to be chosen was added by an
380 inadequately commented change in July 1990; I am not sure off
381 hand what problem it fixes.
383 In December 1993 I loosened of this restriction to allow a file
384 to be chosen if it is mentioned as a target in a makefile. This
385 seem logical. */
387 struct file *f = lookup_file (name);
388 if (f != 0)
389 exists = not_target || f->is_target;
392 if (!exists)
394 /* That file wasn't mentioned in the makefile.
395 See if it actually exists. */
397 /* Clobber a null into the name at the last slash.
398 Now NAME is the name of the directory to look in. */
399 *n = '\0';
401 /* We know the directory is in the hash table now because either
402 construct_vpath_list or the code just above put it there.
403 Does the file we seek exist in it? */
404 exists_in_cache = exists = dir_file_exists_p (name, filename);
407 if (exists)
409 /* The file is in the directory cache.
410 Now check that it actually exists in the filesystem.
411 The cache may be out of date. When vpath thinks a file
412 exists, but stat fails for it, confusion results in the
413 higher levels. */
415 struct stat st;
417 /* Put the slash back in NAME. */
418 *n = '/';
420 if (!exists_in_cache /* Makefile-mentioned file need not exist. */
421 || stat (name, &st) == 0) /* Does it really exist? */
423 /* We have found a file.
424 Store the name we found into *FILE for the caller. */
426 *file = savestring (name, (n + 1 - name) + flen);
428 if (mtime_ptr != 0)
429 /* Store the modtime into *MTIME_PTR for the caller.
430 If we have had no need to stat the file here,
431 we record a zero modtime to indicate this. */
432 *mtime_ptr = exists_in_cache ? st.st_mtime : (time_t) 0;
434 return 1;
439 return 0;
442 /* Print the data base of VPATH search paths. */
444 void
445 print_vpath_data_base ()
447 register unsigned int nvpaths;
448 register struct vpath *v;
450 puts ("\n# VPATH Search Paths\n");
452 nvpaths = 0;
453 for (v = vpaths; v != 0; v = v->next)
455 register unsigned int i;
457 ++nvpaths;
459 printf ("vpath %s ", v->pattern);
461 for (i = 0; v->searchpath[i] != 0; ++i)
462 printf ("%s%c", v->searchpath[i],
463 v->searchpath[i + 1] == 0 ? '\n' : ':');
466 if (vpaths == 0)
467 puts ("# No `vpath' search paths.");
468 else
469 printf ("\n# %u `vpath' search paths.\n", nvpaths);
471 if (general_vpath == 0)
472 puts ("\n# No general (`VPATH' variable) search path.");
473 else
475 register char **path = general_vpath->searchpath;
476 register unsigned int i;
478 fputs ("\n# General (`VPATH' variable) search path:\n# ", stdout);
480 for (i = 0; path[i] != 0; ++i)
481 printf ("%s%c", path[i], path[i + 1] == 0 ? '\n' : ':');