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
5 This file is part of GNU Make.
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.
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.
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. */
23 #include "pathstuff.h"
27 /* Structure used to represent a selective VPATH searchpath. */
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. */
39 /* Linked-list of all selective VPATHs. */
41 static struct vpath
*vpaths
;
43 /* Structure for the general VPATH given in the variable. */
45 static struct vpath
*general_vpath
;
47 /* Structure for GPATH given in the variable. */
49 static struct vpath
*gpaths
;
51 static int selective_vpath_search
PARAMS ((struct vpath
*path
, char **file
, FILE_TIMESTAMP
*mtime_ptr
));
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. */
60 register struct vpath
*new = 0;
61 register struct vpath
*old
, *nexto
;
64 /* Reverse the chain. */
65 for (old
= vpaths
; old
!= 0; old
= nexto
)
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. */
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;
83 p
= variable_expand ("$(strip $(VPATH))");
85 warn_undefined_variables_flag
= save
;
90 /* Save the list of vpaths. */
91 struct vpath
*save_vpaths
= vpaths
;
93 /* Empty `vpaths' so the new one will have no next, and `vpaths'
94 will still be nil if P contains no existing directories. */
98 construct_vpath_list ("%", p
);
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
;
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. */
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;
115 p
= variable_expand ("$(strip $(GPATH))");
117 warn_undefined_variables_flag
= save
;
122 /* Save the list of vpaths. */
123 struct vpath
*save_vpaths
= vpaths
;
125 /* Empty `vpaths' so the new one will have no next, and `vpaths'
126 will still be nil if P contains no existing directories. */
130 construct_vpath_list ("%", p
);
132 /* Store the created path as the GPATH,
133 and restore the old list of vpaths. */
135 vpaths
= save_vpaths
;
139 /* Construct the VPATH listing for the pattern and searchpath given.
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
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
159 construct_vpath_list (char *pattern
, char *dirpath
)
161 register unsigned int elem
;
163 register char **vpath
;
164 register unsigned int maxvpath
;
165 unsigned int maxelem
;
166 char *percent
= NULL
;
170 pattern
= xstrdup (pattern
);
171 percent
= find_percent (pattern
);
176 /* Remove matching listings. */
177 register struct vpath
*path
, *lastpath
;
183 struct vpath
*next
= path
->next
;
186 || (((percent
== 0 && path
->percent
== 0)
187 || (percent
- pattern
== path
->percent
- path
->pattern
))
188 && streq (pattern
, path
->pattern
)))
190 /* Remove it from the linked list. */
194 lastpath
->next
= next
;
196 /* Free its unused storage. */
197 free (path
->pattern
);
198 free ((char *) path
->searchpath
);
199 free ((char *) path
);
213 convert_vpath_to_windows32(dirpath
, ';');
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. */
223 if (*p
++ == PATH_SEPARATOR_CHAR
|| isblank ((unsigned char)*p
))
226 vpath
= (char **) xmalloc (maxelem
* sizeof (char *));
229 /* Skip over any initial separators and blanks. */
231 while (*p
== PATH_SEPARATOR_CHAR
|| isblank ((unsigned char)*p
))
240 /* Find the end of this entry. */
242 while (*p
!= '\0' && *p
!= PATH_SEPARATOR_CHAR
243 && !isblank ((unsigned char)*p
))
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] != ':'))
253 if (len
> 1 && p
[-1] == '/')
256 if (len
> 1 || *v
!= '.')
258 v
= savestring (v
, len
);
260 /* Verify that the directory actually exists. */
262 if (dir_file_exists_p (v
, ""))
264 /* It does. Put it in the list. */
265 vpath
[elem
++] = dir_name (v
);
271 /* The directory does not exist. Omit from the list. */
275 /* Skip over separators and blanks between entries. */
276 while (*p
== PATH_SEPARATOR_CHAR
|| isblank ((unsigned char)*p
))
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 *));
290 /* Put the nil-pointer terminator on the end of the VPATH list. */
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
;
300 /* Set up the members. */
301 path
->pattern
= pattern
;
302 path
->percent
= percent
;
303 path
->patlen
= strlen (pattern
);
307 /* There were no entries, so free whatever space we allocated. */
308 free ((char *) vpath
);
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. */
318 gpath_search (char *file
, unsigned int len
)
322 if (gpaths
&& (len
<= gpaths
->maxlen
))
323 for (gp
= gpaths
->searchpath
; *gp
!= NULL
; ++gp
)
324 if (strneq (*gp
, file
, len
) && (*gp
)[len
] == '\0')
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. */
337 vpath_search (char **file
, FILE_TIMESTAMP
*mtime_ptr
)
339 register struct vpath
*v
;
341 /* If there are no VPATH entries or FILENAME starts at the root,
342 there is nothing we can do. */
345 #ifdef HAVE_DOS_PATHS
349 || (vpaths
== 0 && general_vpath
== 0))
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
))
357 if (general_vpath
!= 0
358 && selective_vpath_search (general_vpath
, file
, mtime_ptr
))
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. */
372 selective_vpath_search (struct vpath
*path
, char **file
,
373 FILE_TIMESTAMP
*mtime_ptr
)
378 register char **vpath
= path
->searchpath
;
379 unsigned int maxvpath
= path
->maxlen
;
380 register unsigned int i
;
381 unsigned int flen
, vlen
, name_dplen
;
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. */
388 struct file
*f
= lookup_file (*file
);
389 not_target
= f
== 0 || !f
->is_target
;
392 flen
= strlen (*file
);
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. */
398 n
= strrchr (*file
, '/');
399 #ifdef HAVE_DOS_PATHS
400 /* We need the rightmost slash or backslash. */
402 char *bslash
= strrchr(*file
, '\\');
403 if (!n
|| bslash
> n
)
407 name_dplen
= n
!= 0 ? n
- *file
: 0;
408 filename
= name_dplen
> 0 ? n
+ 1 : *file
;
410 flen
-= name_dplen
+ 1;
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);
418 /* Try each VPATH entry. */
419 for (i
= 0; vpath
[i
] != 0; ++i
)
421 int exists_in_cache
= 0;
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
);
430 /* Add the directory prefix already in *FILE. */
436 bcopy (*file
, n
, name_dplen
);
440 #ifdef HAVE_DOS_PATHS
441 /* Cause the next if to treat backslash and slash alike. */
442 if (n
!= name
&& n
[-1] == '\\' )
445 /* Now add the name-within-directory at the end of NAME. */
447 if (n
!= name
&& n
[-1] != '/')
450 bcopy (filename
, n
+ 1, flen
+ 1);
454 bcopy (filename
, n
, flen
+ 1);
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.
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.
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
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
478 struct file
*f
= lookup_file (name
);
481 exists
= not_target
|| f
->is_target
;
482 if (exists
&& mtime_ptr
483 && (f
->last_mtime
== OLD_MTIME
|| f
->last_mtime
== NEW_MTIME
))
485 *mtime_ptr
= f
->last_mtime
;
493 /* That file wasn't mentioned in the makefile.
494 See if it actually exists. */
497 exists_in_cache
= exists
= dir_file_exists_p (vpath
[i
], filename
);
499 /* Clobber a null into the name at the last slash.
500 Now NAME is the name of the directory to look in. */
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
);
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
521 /* Put the slash back in NAME. */
525 if (exists_in_cache
) /* Makefile-mentioned file need not exist. */
529 EINTRLOOP (e
, stat (name
, &st
)); /* Does it really exist? */
536 /* Store the modtime into *MTIME_PTR for the caller. */
539 *mtime_ptr
= FILE_TIMESTAMP_STAT_MODTIME (name
, st
);
544 /* We have found a file.
545 Store the name we found into *FILE for the caller. */
547 *file
= savestring (name
, (n
+ 1 - name
) + flen
);
549 /* If we get here and mtime_ptr hasn't been set, record
550 UNKNOWN_MTIME to indicate this. */
552 *mtime_ptr
= UNKNOWN_MTIME
;
563 /* Print the data base of VPATH search paths. */
566 print_vpath_data_base (void)
568 register unsigned int nvpaths
;
569 register struct vpath
*v
;
571 puts (_("\n# VPATH Search Paths\n"));
574 for (v
= vpaths
; v
!= 0; v
= v
->next
)
576 register unsigned int i
;
580 printf ("vpath %s ", v
->pattern
);
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
);
588 puts (_("# No `vpath' search paths."));
590 printf (_("\n# %u `vpath' search paths.\n"), nvpaths
);
592 if (general_vpath
== 0)
593 puts (_("\n# No general (`VPATH' variable) search path."));
596 register char **path
= general_vpath
->searchpath
;
597 register unsigned int i
;
599 fputs (_("\n# General (`VPATH' variable) search path:\n# "), stdout
);
601 for (i
= 0; path
[i
] != 0; ++i
)
602 printf ("%s%c", path
[i
],
603 path
[i
+ 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR
);