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