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