Changeset 3140 for trunk/src/kmk/vpath.c
- Timestamp:
- Mar 14, 2018, 10:28:10 PM (7 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk
-
Property svn:mergeinfo
set to
/vendor/gnumake/current merged eligible
-
Property svn:mergeinfo
set to
-
trunk/src/kmk/vpath.c
r2592 r3140 1 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, 2007, 2008, 2009, 4 2010 Free Software Foundation, Inc. 2 Copyright (C) 1988-2016 Free Software Foundation, Inc. 5 3 This file is part of GNU Make. 6 4 … … 17 15 this program. If not, see <http://www.gnu.org/licenses/>. */ 18 16 19 #include "make .h"17 #include "makeint.h" 20 18 #include "filedef.h" 21 19 #include "variable.h" … … 29 27 struct vpath 30 28 { 31 struct vpath *next; 29 struct vpath *next; /* Pointer to next struct in the linked list. */ 32 30 const char *pattern;/* The pattern to match. */ 33 const char *percent;/* Pointer into `pattern' where the `%' is. */31 const char *percent;/* Pointer into 'pattern' where the '%' is. */ 34 32 unsigned int patlen;/* Length of the pattern. */ 35 33 const char **searchpath; /* Null-terminated list of directories. */ … … 56 54 57 55 void 58 build_vpath_lists ( )56 build_vpath_lists (void) 59 57 { 60 58 register struct vpath *new = 0; … … 98 96 char gp[] = "%"; 99 97 100 /* Empty `vpaths' so the new one will have no next, and `vpaths'101 98 /* Empty 'vpaths' so the new one will have no next, and 'vpaths' 99 will still be nil if P contains no existing directories. */ 102 100 vpaths = 0; 103 101 … … 106 104 107 105 /* Store the created path as the general path, 108 106 and restore the old list of vpaths. */ 109 107 general_vpath = vpaths; 110 108 vpaths = save_vpaths; … … 135 133 char gp[] = "%"; 136 134 137 /* Empty `vpaths' so the new one will have no next, and `vpaths'138 135 /* Empty 'vpaths' so the new one will have no next, and 'vpaths' 136 will still be nil if P contains no existing directories. */ 139 137 vpaths = 0; 140 138 … … 143 141 144 142 /* Store the created path as the GPATH, 145 143 and restore the old list of vpaths. */ 146 144 gpaths = vpaths; 147 145 vpaths = save_vpaths; … … 161 159 pattern. If PATTERN is nil, remove all VPATH listings. Existing 162 160 and readable directories that are not "." given in the DIRPATH 163 separated by the path element separator (defined in make .h) are161 separated by the path element separator (defined in makeint.h) are 164 162 loaded into the directory hash table if they are not there already 165 163 and put in the VPATH searchpath for the given pattern with trailing … … 190 188 path = vpaths; 191 189 while (path != 0) 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 190 { 191 struct vpath *next = path->next; 192 193 if (pattern == 0 194 || (((percent == 0 && path->percent == 0) 195 || (percent - pattern == path->percent - path->pattern)) 196 && streq (pattern, path->pattern))) 197 { 198 /* Remove it from the linked list. */ 199 if (lastpath == 0) 200 vpaths = path->next; 201 else 202 lastpath->next = next; 203 204 /* Free its unused storage. */ 207 205 /* MSVC erroneously warns without a cast here. */ 208 209 210 211 212 213 214 215 206 free ((void *)path->searchpath); 207 free (path); 208 } 209 else 210 lastpath = path; 211 212 path = next; 213 } 216 214 217 215 return; … … 219 217 220 218 #ifdef WINDOWS32 221 convert_vpath_to_windows32 (dirpath, ';');219 convert_vpath_to_windows32 (dirpath, ';'); 222 220 #endif 223 221 224 222 /* Skip over any initial separators and blanks. */ 225 while ( *dirpath == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*dirpath))223 while (STOP_SET (*dirpath, MAP_BLANK|MAP_PATHSEP)) 226 224 ++dirpath; 227 225 … … 233 231 p = dirpath; 234 232 while (*p != '\0') 235 if ( *p++ == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))233 if (STOP_SET (*p++, MAP_BLANK|MAP_PATHSEP)) 236 234 ++maxelem; 237 235 … … 250 248 while (*p != '\0' 251 249 #if defined(HAVE_DOS_PATHS) && (PATH_SEPARATOR_CHAR == ':') 252 253 254 255 256 257 250 /* Platforms whose PATH_SEPARATOR_CHAR is ':' and which 251 also define HAVE_DOS_PATHS would like us to recognize 252 colons after the drive letter in the likes of 253 "D:/foo/bar:C:/xyzzy". */ 254 && (*p != PATH_SEPARATOR_CHAR 255 || (p == v + 1 && (p[1] == '/' || p[1] == '\\'))) 258 256 #else 259 260 #endif 261 && !isblank ((unsigned char)*p))262 257 && *p != PATH_SEPARATOR_CHAR 258 #endif 259 && !ISBLANK (*p)) 260 ++p; 263 261 264 262 len = p - v; 265 263 /* Make sure there's no trailing slash, 266 264 but still allow "/" as a directory. */ 267 265 #if defined(__MSDOS__) || defined(__EMX__) || defined(HAVE_DOS_PATHS) 268 266 /* We need also to leave alone a trailing slash in "d:/". */ … … 270 268 #endif 271 269 if (len > 1 && p[-1] == '/') 272 270 --len; 273 271 274 272 /* Put the directory on the vpath list. */ 275 273 if (len > 1 || *v != '.') 276 274 { 277 275 vpath[elem++] = dir_name (strcache_add_len (v, len)); 278 276 if (len > maxvpath) 279 277 maxvpath = len; 280 278 } 281 279 282 280 /* Skip over separators and blanks between entries. */ 283 while ( *p == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p))284 281 while (STOP_SET (*p, MAP_BLANK|MAP_PATHSEP)) 282 ++p; 285 283 } 286 284 … … 289 287 struct vpath *path; 290 288 /* ELEM is now incremented one element past the last 291 292 289 entry, to where the nil-pointer terminator goes. 290 Usually this is maxelem - 1. If not, shrink down. */ 293 291 if (elem < (maxelem - 1)) 294 vpath = (const char **)xrealloc (vpath, (elem+1) * sizeof (const char *)); 292 vpath = xrealloc ((void *)vpath, (elem+1) * sizeof (const char *)); /* bird: Weird cast for msc. */ 295 293 296 294 /* Put the nil-pointer terminator on the end of the VPATH list. */ … … 322 320 gpath_search (const char *file, unsigned int len) 323 321 { 324 const char **gp;325 326 322 if (gpaths && (len <= gpaths->maxlen)) 327 for (gp = gpaths->searchpath; *gp != NULL; ++gp) 328 if (strneq (*gp, file, len) && (*gp)[len] == '\0') 329 return 1; 323 { 324 const char **gp; 325 for (gp = gpaths->searchpath; *gp != NULL; ++gp) 326 if (strneq (*gp, file, len) && (*gp)[len] == '\0') 327 return 1; 328 } 330 329 331 330 return 0; … … 351 350 unsigned int maxvpath = path->maxlen; 352 351 unsigned int i; 353 unsigned int flen, vlen,name_dplen;352 unsigned int flen, name_dplen; 354 353 int exists = 0; 355 354 … … 372 371 /* We need the rightmost slash or backslash. */ 373 372 { 374 const char *bslash = strrchr (file, '\\');373 const char *bslash = strrchr (file, '\\'); 375 374 if (!n || bslash > n) 376 375 n = bslash; … … 391 390 { 392 391 int exists_in_cache = 0; 393 char *p; 394 395 p = name; 392 char *p = name; 393 unsigned int vlen = strlen (vpath[i]); 396 394 397 395 /* Put the next VPATH entry into NAME at P and increment P past it. */ 398 vlen = strlen (vpath[i]);399 396 memcpy (p, vpath[i], vlen); 400 397 p += vlen; … … 402 399 /* Add the directory prefix already in *FILE. */ 403 400 if (name_dplen > 0) 404 401 { 405 402 #ifndef VMS 406 *p++ = '/'; 407 #endif 408 memcpy (p, file, name_dplen); 409 p += name_dplen; 410 } 403 *p++ = '/'; 404 #else 405 /* VMS: if this is not in VMS format, treat as Unix format */ 406 if ((*p != ':') && (*p != ']') && (*p != '>')) 407 *p++ = '/'; 408 #endif 409 memcpy (p, file, name_dplen); 410 p += name_dplen; 411 } 411 412 412 413 #ifdef HAVE_DOS_PATHS 413 414 /* Cause the next if to treat backslash and slash alike. */ 414 415 if (p != name && p[-1] == '\\' ) 415 416 p[-1] = '/'; 416 417 #endif 417 418 /* Now add the name-within-directory at the end of NAME. */ 418 419 #ifndef VMS 419 420 if (p != name && p[-1] != '/') 420 421 422 423 421 { 422 *p = '/'; 423 memcpy (p + 1, filename, flen + 1); 424 } 424 425 else 425 #endif 426 memcpy (p, filename, flen + 1); 426 #else 427 /* VMS use a slash if no directory terminator present */ 428 if (p != name && p[-1] != '/' && p[-1] != ':' && 429 p[-1] != '>' && p[-1] != ']') 430 { 431 *p = '/'; 432 memcpy (p + 1, filename, flen + 1); 433 } 434 else 435 #endif 436 memcpy (p, filename, flen + 1); 427 437 428 438 /* Check if the file is mentioned in a makefile. If *FILE is not 429 430 431 432 433 434 435 436 437 438 439 440 439 a target, that is enough for us to decide this file exists. 440 If *FILE is a target, then the file must be mentioned in the 441 makefile also as a target to be chosen. 442 443 The restriction that *FILE must not be a target for a 444 makefile-mentioned file to be chosen was added by an 445 inadequately commented change in July 1990; I am not sure off 446 hand what problem it fixes. 447 448 In December 1993 I loosened this restriction to allow a file 449 to be chosen if it is mentioned as a target in a makefile. This 450 seem logical. 441 451 442 452 Special handling for -W / -o: make sure we preserve the special … … 448 458 */ 449 459 { 450 451 460 struct file *f = lookup_file (name); 461 if (f != 0) 452 462 { 453 463 exists = not_target || f->is_target; … … 462 472 463 473 if (!exists) 464 465 466 474 { 475 /* That file wasn't mentioned in the makefile. 476 See if it actually exists. */ 467 477 468 478 #ifdef VMS 469 exists_in_cache = exists = dir_file_exists_p (vpath[i], filename); 479 /* For VMS syntax just use the original vpath */ 480 if (*p != '/') 481 exists_in_cache = exists = dir_file_exists_p (vpath[i], filename); 482 else 483 #endif 484 { 485 /* Clobber a null into the name at the last slash. 486 Now NAME is the name of the directory to look in. */ 487 *p = '\0'; 488 /* We know the directory is in the hash table now because either 489 construct_vpath_list or the code just above put it there. 490 Does the file we seek exist in it? */ 491 exists_in_cache = exists = dir_file_exists_p (name, filename); 492 } 493 } 494 495 if (exists) 496 { 497 /* The file is in the directory cache. 498 Now check that it actually exists in the filesystem. 499 The cache may be out of date. When vpath thinks a file 500 exists, but stat fails for it, confusion results in the 501 higher levels. */ 502 503 struct stat st; 504 505 #ifndef VMS 506 /* Put the slash back in NAME. */ 507 *p = '/'; 470 508 #else 471 /* Clobber a null into the name at the last slash. 472 Now NAME is the name of the directory to look in. */ 473 *p = '\0'; 474 475 /* We know the directory is in the hash table now because either 476 construct_vpath_list or the code just above put it there. 477 Does the file we seek exist in it? */ 478 exists_in_cache = exists = dir_file_exists_p (name, filename); 479 #endif 480 } 481 482 if (exists) 483 { 484 /* The file is in the directory cache. 485 Now check that it actually exists in the filesystem. 486 The cache may be out of date. When vpath thinks a file 487 exists, but stat fails for it, confusion results in the 488 higher levels. */ 489 490 struct stat st; 491 492 #ifndef VMS 493 /* Put the slash back in NAME. */ 494 *p = '/'; 495 #endif 496 497 if (exists_in_cache) /* Makefile-mentioned file need not exist. */ 498 { 509 /* If the slash was removed, put it back */ 510 if (*p == 0) 511 *p = '/'; 512 #endif 513 514 if (exists_in_cache) /* Makefile-mentioned file need not exist. */ 515 { 499 516 int e; 500 517 … … 526 543 527 544 return strcache_add_len (name, (p + 1 - name) + flen); 528 545 } 529 546 } 530 547 … … 611 628 612 629 for (i = 0; v->searchpath[i] != 0; ++i) 613 614 630 printf ("%s%c", v->searchpath[i], 631 v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR); 615 632 } 616 633 617 634 if (vpaths == 0) 618 puts (_("# No `vpath' search paths."));635 puts (_("# No 'vpath' search paths.")); 619 636 else 620 printf (_("\n# %u `vpath' search paths.\n"), nvpaths);637 printf (_("\n# %u 'vpath' search paths.\n"), nvpaths); 621 638 622 639 if (general_vpath == 0) 623 puts (_("\n# No general ( `VPATH' variable) search path."));640 puts (_("\n# No general ('VPATH' variable) search path.")); 624 641 else 625 642 { … … 627 644 unsigned int i; 628 645 629 fputs (_("\n# General ( `VPATH' variable) search path:\n# "), stdout);646 fputs (_("\n# General ('VPATH' variable) search path:\n# "), stdout); 630 647 631 648 for (i = 0; path[i] != 0; ++i) 632 633 649 printf ("%s%c", path[i], 650 path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR); 634 651 } 635 652 }
Note:
See TracChangeset
for help on using the changeset viewer.