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