Formerly default.c.~31~
[make.git] / vpath.c
blob230bb6ab8146e760ac130c4b08938765791fddf7
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 if (not_target)
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;
378 if (!exists)
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. */
385 *n = '\0';
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);
393 if (exists)
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
399 higher levels. */
401 struct stat st;
403 /* Put the slash back in NAME. */
404 *n = '/';
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);
414 if (mtime_ptr != 0)
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;
420 return 1;
425 return 0;
428 /* Print the data base of VPATH search paths. */
430 void
431 print_vpath_data_base ()
433 register unsigned int nvpaths;
434 register struct vpath *v;
436 puts ("\n# VPATH Search Paths\n");
438 nvpaths = 0;
439 for (v = vpaths; v != 0; v = v->next)
441 register unsigned int i;
443 ++nvpaths;
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' : ':');
452 if (vpaths == 0)
453 puts ("# No `vpath' search paths.");
454 else
455 printf ("\n# %u `vpath' search paths.\n", nvpaths);
457 if (general_vpath == 0)
458 puts ("\n# No general (`VPATH' variable) search path.");
459 else
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' : ':');