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