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