1/* Implementation of pattern-matching file search paths for GNU Make.
2Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
31998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
4Foundation, Inc.
5This file is part of GNU Make.
6
7GNU Make is free software; you can redistribute it and/or modify it under the
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 2, or (at your option) any later version.
10
11GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License along with
16GNU Make; see the file COPYING.  If not, write to the Free Software
17Foundation, 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
29struct 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
41static struct vpath *vpaths;
42
43/* Structure for the general VPATH given in the variable.  */
44
45static struct vpath *general_vpath;
46
47/* Structure for GPATH given in the variable.  */
48
49static struct vpath *gpaths;
50
51static 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
57void
58build_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
158void
159construct_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
317int
318gpath_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
336int
337vpath_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
371static int
372selective_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
565void
566print_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