• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Implementation of pattern-matching file search paths for GNU Make.
2 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
4 Foundation, Inc.
5 This file is part of GNU Make.
6 
7 GNU Make is free software; you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation; either version 2, or (at your option) any later version.
10 
11 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along with
16 GNU Make; see the file COPYING.  If not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */
18 
19 #include "make.h"
20 #include "filedef.h"
21 #include "variable.h"
22 #ifdef WINDOWS32
23 #include "pathstuff.h"
24 #endif
25 
26 
27 /* Structure used to represent a selective VPATH searchpath.  */
28 
29 struct vpath
30   {
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.  */
37   };
38 
39 /* Linked-list of all selective VPATHs.  */
40 
41 static struct vpath *vpaths;
42 
43 /* Structure for the general VPATH given in the variable.  */
44 
45 static struct vpath *general_vpath;
46 
47 /* Structure for GPATH given in the variable.  */
48 
49 static struct vpath *gpaths;
50 
51 static int selective_vpath_search PARAMS ((struct vpath *path, char **file, FILE_TIMESTAMP *mtime_ptr));
52 
53 /* Reverse the chain of selective VPATH lists so they
54    will be searched in the order given in the makefiles
55    and construct the list from the VPATH variable.  */
56 
57 void
build_vpath_lists()58 build_vpath_lists ()
59 {
60   register struct vpath *new = 0;
61   register struct vpath *old, *nexto;
62   register char *p;
63 
64   /* Reverse the chain.  */
65   for (old = vpaths; old != 0; old = nexto)
66     {
67       nexto = old->next;
68       old->next = new;
69       new = old;
70     }
71 
72   vpaths = new;
73 
74   /* If there is a VPATH variable with a nonnull value, construct the
75      general VPATH list from it.  We use variable_expand rather than just
76      calling lookup_variable so that it will be recursively expanded.  */
77 
78   {
79     /* Turn off --warn-undefined-variables while we expand SHELL and IFS.  */
80     int save = warn_undefined_variables_flag;
81     warn_undefined_variables_flag = 0;
82 
83     p = variable_expand ("$(strip $(VPATH))");
84 
85     warn_undefined_variables_flag = save;
86   }
87 
88   if (*p != '\0')
89     {
90       /* Save the list of vpaths.  */
91       struct vpath *save_vpaths = vpaths;
92 
93       /* Empty `vpaths' so the new one will have no next, and `vpaths'
94 	 will still be nil if P contains no existing directories.  */
95       vpaths = 0;
96 
97       /* Parse P.  */
98       construct_vpath_list ("%", p);
99 
100       /* Store the created path as the general path,
101 	 and restore the old list of vpaths.  */
102       general_vpath = vpaths;
103       vpaths = save_vpaths;
104     }
105 
106   /* If there is a GPATH variable with a nonnull value, construct the
107      GPATH list from it.  We use variable_expand rather than just
108      calling lookup_variable so that it will be recursively expanded.  */
109 
110   {
111     /* Turn off --warn-undefined-variables while we expand SHELL and IFS.  */
112     int save = warn_undefined_variables_flag;
113     warn_undefined_variables_flag = 0;
114 
115     p = variable_expand ("$(strip $(GPATH))");
116 
117     warn_undefined_variables_flag = save;
118   }
119 
120   if (*p != '\0')
121     {
122       /* Save the list of vpaths.  */
123       struct vpath *save_vpaths = vpaths;
124 
125       /* Empty `vpaths' so the new one will have no next, and `vpaths'
126 	 will still be nil if P contains no existing directories.  */
127       vpaths = 0;
128 
129       /* Parse P.  */
130       construct_vpath_list ("%", p);
131 
132       /* Store the created path as the GPATH,
133 	 and restore the old list of vpaths.  */
134       gpaths = vpaths;
135       vpaths = save_vpaths;
136     }
137 }
138 
139 /* Construct the VPATH listing for the pattern and searchpath given.
140 
141    This function is called to generate selective VPATH lists and also for
142    the general VPATH list (which is in fact just a selective VPATH that
143    is applied to everything).  The returned pointer is either put in the
144    linked list of all selective VPATH lists or in the GENERAL_VPATH
145    variable.
146 
147    If SEARCHPATH is nil, remove all previous listings with the same
148    pattern.  If PATTERN is nil, remove all VPATH listings.  Existing
149    and readable directories that are not "." given in the searchpath
150    separated by the path element separator (defined in make.h) are
151    loaded into the directory hash table if they are not there already
152    and put in the VPATH searchpath for the given pattern with trailing
153    slashes stripped off if present (and if the directory is not the
154    root, "/").  The length of the longest entry in the list is put in
155    the structure as well.  The new entry will be at the head of the
156    VPATHS chain.  */
157 
158 void
construct_vpath_list(char * pattern,char * dirpath)159 construct_vpath_list (char *pattern, char *dirpath)
160 {
161   register unsigned int elem;
162   register char *p;
163   register char **vpath;
164   register unsigned int maxvpath;
165   unsigned int maxelem;
166   char *percent = NULL;
167 
168   if (pattern != 0)
169     {
170       pattern = xstrdup (pattern);
171       percent = find_percent (pattern);
172     }
173 
174   if (dirpath == 0)
175     {
176       /* Remove matching listings.  */
177       register struct vpath *path, *lastpath;
178 
179       lastpath = 0;
180       path = vpaths;
181       while (path != 0)
182 	{
183 	  struct vpath *next = path->next;
184 
185 	  if (pattern == 0
186 	      || (((percent == 0 && path->percent == 0)
187 		   || (percent - pattern == path->percent - path->pattern))
188 		  && streq (pattern, path->pattern)))
189 	    {
190 	      /* Remove it from the linked list.  */
191 	      if (lastpath == 0)
192 		vpaths = path->next;
193 	      else
194 		lastpath->next = next;
195 
196 	      /* Free its unused storage.  */
197 	      free (path->pattern);
198 	      free ((char *) path->searchpath);
199 	      free ((char *) path);
200 	    }
201 	  else
202 	    lastpath = path;
203 
204 	  path = next;
205 	}
206 
207       if (pattern != 0)
208 	free (pattern);
209       return;
210     }
211 
212 #ifdef WINDOWS32
213     convert_vpath_to_windows32(dirpath, ';');
214 #endif
215 
216   /* Figure out the maximum number of VPATH entries and put it in
217      MAXELEM.  We start with 2, one before the first separator and one
218      nil (the list terminator) and increment our estimated number for
219      each separator or blank we find.  */
220   maxelem = 2;
221   p = dirpath;
222   while (*p != '\0')
223     if (*p++ == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))
224       ++maxelem;
225 
226   vpath = (char **) xmalloc (maxelem * sizeof (char *));
227   maxvpath = 0;
228 
229   /* Skip over any initial separators and blanks.  */
230   p = dirpath;
231   while (*p == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))
232     ++p;
233 
234   elem = 0;
235   while (*p != '\0')
236     {
237       char *v;
238       unsigned int len;
239 
240       /* Find the end of this entry.  */
241       v = p;
242       while (*p != '\0' && *p != PATH_SEPARATOR_CHAR
243 	     && !isblank ((unsigned char)*p))
244 	++p;
245 
246       len = p - v;
247       /* Make sure there's no trailing slash,
248 	 but still allow "/" as a directory.  */
249 #if defined(__MSDOS__) || defined(__EMX__)
250       /* We need also to leave alone a trailing slash in "d:/".  */
251       if (len > 3 || (len > 1 && v[1] != ':'))
252 #endif
253       if (len > 1 && p[-1] == '/')
254 	--len;
255 
256       if (len > 1 || *v != '.')
257 	{
258 	  v = savestring (v, len);
259 
260 	  /* Verify that the directory actually exists.  */
261 
262 	  if (dir_file_exists_p (v, ""))
263 	    {
264 	      /* It does.  Put it in the list.  */
265 	      vpath[elem++] = dir_name (v);
266 	      free (v);
267 	      if (len > maxvpath)
268 		maxvpath = len;
269 	    }
270 	  else
271 	    /* The directory does not exist.  Omit from the list.  */
272 	    free (v);
273 	}
274 
275       /* Skip over separators and blanks between entries.  */
276       while (*p == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))
277 	++p;
278     }
279 
280   if (elem > 0)
281     {
282       struct vpath *path;
283       /* ELEM is now incremented one element past the last
284 	 entry, to where the nil-pointer terminator goes.
285 	 Usually this is maxelem - 1.  If not, shrink down.  */
286       if (elem < (maxelem - 1))
287 	vpath = (char **) xrealloc ((char *) vpath,
288 				    (elem + 1) * sizeof (char *));
289 
290       /* Put the nil-pointer terminator on the end of the VPATH list.  */
291       vpath[elem] = 0;
292 
293       /* Construct the vpath structure and put it into the linked list.  */
294       path = (struct vpath *) xmalloc (sizeof (struct vpath));
295       path->searchpath = vpath;
296       path->maxlen = maxvpath;
297       path->next = vpaths;
298       vpaths = path;
299 
300       /* Set up the members.  */
301       path->pattern = pattern;
302       path->percent = percent;
303       path->patlen = strlen (pattern);
304     }
305   else
306     {
307       /* There were no entries, so free whatever space we allocated.  */
308       free ((char *) vpath);
309       if (pattern != 0)
310 	free (pattern);
311     }
312 }
313 
314 /* Search the GPATH list for a pathname string that matches the one passed
315    in.  If it is found, return 1.  Otherwise we return 0.  */
316 
317 int
gpath_search(char * file,unsigned int len)318 gpath_search (char *file, unsigned int len)
319 {
320   char **gp;
321 
322   if (gpaths && (len <= gpaths->maxlen))
323     for (gp = gpaths->searchpath; *gp != NULL; ++gp)
324       if (strneq (*gp, file, len) && (*gp)[len] == '\0')
325         return 1;
326 
327   return 0;
328 }
329 
330 /* Search the VPATH list whose pattern matches *FILE for a directory
331    where the name pointed to by FILE exists.  If it is found, we set *FILE to
332    the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is
333    not NULL) to its modtime (or zero if no stat call was done), and return 1.
334    Otherwise we return 0.  */
335 
336 int
vpath_search(char ** file,FILE_TIMESTAMP * mtime_ptr)337 vpath_search (char **file, FILE_TIMESTAMP *mtime_ptr)
338 {
339   register struct vpath *v;
340 
341   /* If there are no VPATH entries or FILENAME starts at the root,
342      there is nothing we can do.  */
343 
344   if (**file == '/'
345 #ifdef HAVE_DOS_PATHS
346       || **file == '\\'
347       || (*file)[1] == ':'
348 #endif
349       || (vpaths == 0 && general_vpath == 0))
350     return 0;
351 
352   for (v = vpaths; v != 0; v = v->next)
353     if (pattern_matches (v->pattern, v->percent, *file))
354       if (selective_vpath_search (v, file, mtime_ptr))
355 	return 1;
356 
357   if (general_vpath != 0
358       && selective_vpath_search (general_vpath, file, mtime_ptr))
359     return 1;
360 
361   return 0;
362 }
363 
364 
365 /* Search the given VPATH list for a directory where the name pointed
366    to by FILE exists.  If it is found, we set *FILE to the newly malloc'd
367    name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to
368    its modtime (or zero if no stat call was done), and we return 1.
369    Otherwise we return 0.  */
370 
371 static int
selective_vpath_search(struct vpath * path,char ** file,FILE_TIMESTAMP * mtime_ptr)372 selective_vpath_search (struct vpath *path, char **file,
373                         FILE_TIMESTAMP *mtime_ptr)
374 {
375   int not_target;
376   char *name, *n;
377   char *filename;
378   register char **vpath = path->searchpath;
379   unsigned int maxvpath = path->maxlen;
380   register unsigned int i;
381   unsigned int flen, vlen, name_dplen;
382   int exists = 0;
383 
384   /* Find out if *FILE is a target.
385      If and only if it is NOT a target, we will accept prospective
386      files that don't exist but are mentioned in a makefile.  */
387   {
388     struct file *f = lookup_file (*file);
389     not_target = f == 0 || !f->is_target;
390   }
391 
392   flen = strlen (*file);
393 
394   /* Split *FILE into a directory prefix and a name-within-directory.
395      NAME_DPLEN gets the length of the prefix; FILENAME gets the
396      pointer to the name-within-directory and FLEN is its length.  */
397 
398   n = strrchr (*file, '/');
399 #ifdef HAVE_DOS_PATHS
400   /* We need the rightmost slash or backslash.  */
401   {
402     char *bslash = strrchr(*file, '\\');
403     if (!n || bslash > n)
404       n = bslash;
405   }
406 #endif
407   name_dplen = n != 0 ? n - *file : 0;
408   filename = name_dplen > 0 ? n + 1 : *file;
409   if (name_dplen > 0)
410     flen -= name_dplen + 1;
411 
412   /* Allocate enough space for the biggest VPATH entry,
413      a slash, the directory prefix that came with *FILE,
414      another slash (although this one may not always be
415      necessary), the filename, and a null terminator.  */
416   name = (char *) xmalloc (maxvpath + 1 + name_dplen + 1 + flen + 1);
417 
418   /* Try each VPATH entry.  */
419   for (i = 0; vpath[i] != 0; ++i)
420     {
421       int exists_in_cache = 0;
422 
423       n = name;
424 
425       /* Put the next VPATH entry into NAME at N and increment N past it.  */
426       vlen = strlen (vpath[i]);
427       bcopy (vpath[i], n, vlen);
428       n += vlen;
429 
430       /* Add the directory prefix already in *FILE.  */
431       if (name_dplen > 0)
432 	{
433 #ifndef VMS
434 	  *n++ = '/';
435 #endif
436 	  bcopy (*file, n, name_dplen);
437 	  n += name_dplen;
438 	}
439 
440 #ifdef HAVE_DOS_PATHS
441       /* Cause the next if to treat backslash and slash alike.  */
442       if (n != name && n[-1] == '\\' )
443 	n[-1] = '/';
444 #endif
445       /* Now add the name-within-directory at the end of NAME.  */
446 #ifndef VMS
447       if (n != name && n[-1] != '/')
448 	{
449 	  *n = '/';
450 	  bcopy (filename, n + 1, flen + 1);
451 	}
452       else
453 #endif
454 	bcopy (filename, n, flen + 1);
455 
456       /* Check if the file is mentioned in a makefile.  If *FILE is not
457 	 a target, that is enough for us to decide this file exists.
458 	 If *FILE is a target, then the file must be mentioned in the
459 	 makefile also as a target to be chosen.
460 
461 	 The restriction that *FILE must not be a target for a
462 	 makefile-mentioned file to be chosen was added by an
463 	 inadequately commented change in July 1990; I am not sure off
464 	 hand what problem it fixes.
465 
466 	 In December 1993 I loosened this restriction to allow a file
467 	 to be chosen if it is mentioned as a target in a makefile.  This
468 	 seem logical.
469 
470          Special handling for -W / -o: make sure we preserve the special
471          values here.  Actually this whole thing is a little bogus: I think
472          we should ditch the name/hname thing and look into the renamed
473          capability that already exists for files: that is, have a new struct
474          file* entry for the VPATH-found file, and set the renamed field if
475          we use it.
476       */
477       {
478 	struct file *f = lookup_file (name);
479 	if (f != 0)
480           {
481             exists = not_target || f->is_target;
482             if (exists && mtime_ptr
483                 && (f->last_mtime == OLD_MTIME || f->last_mtime == NEW_MTIME))
484               {
485                 *mtime_ptr = f->last_mtime;
486                 mtime_ptr = 0;
487               }
488           }
489       }
490 
491       if (!exists)
492 	{
493 	  /* That file wasn't mentioned in the makefile.
494 	     See if it actually exists.  */
495 
496 #ifdef VMS
497 	  exists_in_cache = exists = dir_file_exists_p (vpath[i], filename);
498 #else
499 	  /* Clobber a null into the name at the last slash.
500 	     Now NAME is the name of the directory to look in.  */
501 	  *n = '\0';
502 
503 	  /* We know the directory is in the hash table now because either
504 	     construct_vpath_list or the code just above put it there.
505 	     Does the file we seek exist in it?  */
506 	  exists_in_cache = exists = dir_file_exists_p (name, filename);
507 #endif
508 	}
509 
510       if (exists)
511 	{
512 	  /* The file is in the directory cache.
513 	     Now check that it actually exists in the filesystem.
514 	     The cache may be out of date.  When vpath thinks a file
515 	     exists, but stat fails for it, confusion results in the
516 	     higher levels.  */
517 
518 	  struct stat st;
519 
520 #ifndef VMS
521 	  /* Put the slash back in NAME.  */
522 	  *n = '/';
523 #endif
524 
525 	  if (exists_in_cache)	/* Makefile-mentioned file need not exist.  */
526 	    {
527               int e;
528 
529               EINTRLOOP (e, stat (name, &st)); /* Does it really exist?  */
530               if (e != 0)
531                 {
532                   exists = 0;
533                   continue;
534                 }
535 
536               /* Store the modtime into *MTIME_PTR for the caller.  */
537               if (mtime_ptr != 0)
538                 {
539                   *mtime_ptr = FILE_TIMESTAMP_STAT_MODTIME (name, st);
540                   mtime_ptr = 0;
541                 }
542             }
543 
544           /* We have found a file.
545              Store the name we found into *FILE for the caller.  */
546 
547           *file = savestring (name, (n + 1 - name) + flen);
548 
549           /* If we get here and mtime_ptr hasn't been set, record
550              UNKNOWN_MTIME to indicate this.  */
551           if (mtime_ptr != 0)
552             *mtime_ptr = UNKNOWN_MTIME;
553 
554           free (name);
555           return 1;
556 	}
557     }
558 
559   free (name);
560   return 0;
561 }
562 
563 /* Print the data base of VPATH search paths.  */
564 
565 void
print_vpath_data_base(void)566 print_vpath_data_base (void)
567 {
568   register unsigned int nvpaths;
569   register struct vpath *v;
570 
571   puts (_("\n# VPATH Search Paths\n"));
572 
573   nvpaths = 0;
574   for (v = vpaths; v != 0; v = v->next)
575     {
576       register unsigned int i;
577 
578       ++nvpaths;
579 
580       printf ("vpath %s ", v->pattern);
581 
582       for (i = 0; v->searchpath[i] != 0; ++i)
583 	printf ("%s%c", v->searchpath[i],
584 		v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
585     }
586 
587   if (vpaths == 0)
588     puts (_("# No `vpath' search paths."));
589   else
590     printf (_("\n# %u `vpath' search paths.\n"), nvpaths);
591 
592   if (general_vpath == 0)
593     puts (_("\n# No general (`VPATH' variable) search path."));
594   else
595     {
596       register char **path = general_vpath->searchpath;
597       register unsigned int i;
598 
599       fputs (_("\n# General (`VPATH' variable) search path:\n# "), stdout);
600 
601       for (i = 0; path[i] != 0; ++i)
602 	printf ("%s%c", path[i],
603 		path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR);
604     }
605 }
606