Changeset 51 in kBuild for trunk/src/kmk/suff.c
- Timestamp:
- Apr 7, 2003 1:30:32 AM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/suff.c
r46 r51 1 1 /* 2 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * 3 * The Regents of the University of California. All rights reserved. 4 4 * Copyright (c) 1989 by Berkeley Softworks 5 5 * All rights reserved. … … 18 18 * 3. All advertising materials mentioning features or use of this software 19 19 * must display the following acknowledgement: 20 * 21 * 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 22 * 4. Neither the name of the University nor the names of its contributors 23 23 * may be used to endorse or promote products derived from this software … … 39 39 #ifndef lint 40 40 #if 0 41 static char sccsid[] = "@(#)suff.c 41 static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94"; 42 42 #else 43 43 static const char rcsid[] = 44 44 "$FreeBSD: src/usr.bin/make/suff.c,v 1.12.2.1 2001/03/09 01:13:24 tmm Exp $"; 45 45 #endif 46 #define KLIBFILEDEF rcsid 46 47 #endif /* not lint */ 47 48 48 49 /*- 49 50 * suff.c -- 50 * 51 * 51 * Functions to maintain suffix lists and find implicit dependents 52 * using suffix transformation rules 52 53 * 53 54 * Interface: 54 * Suff_Init Initialize all things to do with suffixes. 55 * 56 * Suff_End Cleanup the module 57 * 58 * Suff_DoPaths This function is used to make life easier 59 * when searching for a file according to its 60 * suffix. It takes the global search path, 61 * as defined using the .PATH: target, and appends 62 * its directories to the path of each of the 63 * defined suffixes, as specified using 64 * .PATH<suffix>: targets. In addition, all 65 * directories given for suffixes labeled as 66 * include files or libraries, using the .INCLUDES 67 * or .LIBS targets, are played with using 68 * Dir_MakeFlags to create the .INCLUDES and 69 * .LIBS global variables. 70 * 71 * Suff_ClearSuffixes Clear out all the suffixes and defined 72 * transformations. 73 * 74 * Suff_IsTransform Return TRUE if the passed string is the lhs 75 * of a transformation rule. 76 * 77 * Suff_AddSuffix Add the passed string as another known suffix. 78 * 79 * Suff_GetPath Return the search path for the given suffix. 80 * 81 * Suff_AddInclude Mark the given suffix as denoting an include 82 * file. 83 * 84 * Suff_AddLib Mark the given suffix as denoting a library. 85 * 86 * Suff_AddTransform Add another transformation to the suffix 87 * graph. Returns GNode suitable for framing, I 88 * mean, tacking commands, attributes, etc. on. 89 * 90 * Suff_SetNull Define the suffix to consider the suffix of 91 * any file that doesn't have a known one. 92 * 93 * Suff_FindDeps Find implicit sources for and the location of 94 * a target based on its suffix. Returns the 95 * bottom-most node added to the graph or NILGNODE 96 * if the target had no implicit sources. 97 */ 98 99 #include <stdio.h> 100 #include "make.h" 101 #include "hash.h" 102 #include "dir.h" 103 104 static Lst sufflist; /* Lst of suffixes */ 105 static Lst suffClean; /* Lst of suffixes to be cleaned */ 106 static Lst srclist; /* Lst of sources */ 107 static Lst transforms; /* Lst of transformation rules */ 108 109 static int sNum = 0; /* Counter for assigning suffix numbers */ 55 * Suff_Init Initialize all things to do with suffixes. 56 * 57 * Suff_End Cleanup the module 58 * 59 * Suff_DoPaths This function is used to make life easier 60 * when searching for a file according to its 61 * suffix. It takes the global search path, 62 * as defined using the .PATH: target, and appends 63 * its directories to the path of each of the 64 * defined suffixes, as specified using 65 * .PATH<suffix>: targets. In addition, all 66 * directories given for suffixes labeled as 67 * include files or libraries, using the .INCLUDES 68 * or .LIBS targets, are played with using 69 * Dir_MakeFlags to create the .INCLUDES and 70 * .LIBS global variables. 71 * 72 * Suff_ClearSuffixes Clear out all the suffixes and defined 73 * transformations. 74 * 75 * Suff_IsTransform Return TRUE if the passed string is the lhs 76 * of a transformation rule. 77 * 78 * Suff_AddSuffix Add the passed string as another known suffix. 79 * 80 * Suff_GetPath Return the search path for the given suffix. 81 * 82 * Suff_AddInclude Mark the given suffix as denoting an include 83 * file. 84 * 85 * Suff_AddLib Mark the given suffix as denoting a library. 86 * 87 * Suff_AddTransform Add another transformation to the suffix 88 * graph. Returns GNode suitable for framing, I 89 * mean, tacking commands, attributes, etc. on. 90 * 91 * Suff_SetNull Define the suffix to consider the suffix of 92 * any file that doesn't have a known one. 93 * 94 * Suff_FindDeps Find implicit sources for and the location of 95 * a target based on its suffix. Returns the 96 * bottom-most node added to the graph or NILGNODE 97 * if the target had no implicit sources. 98 */ 99 100 #include <stdio.h> 101 #include <strings.h> 102 #include "make.h" 103 #include "hash.h" 104 #include "dir.h" 105 106 static Lst sufflist; /* Lst of suffixes */ 107 static Lst suffClean; /* Lst of suffixes to be cleaned */ 108 static Lst srclist; /* Lst of sources */ 109 static Lst transforms; /* Lst of transformation rules */ 110 111 static int sNum = 0; /* Counter for assigning suffix numbers */ 110 112 111 113 /* … … 113 115 */ 114 116 typedef struct _Suff { 115 char *name; 116 int nameLen;/* Length of the suffix */117 short flags;/* Type of suffix */118 #define SUFF_INCLUDE 0x01/* One which is #include'd */117 char *name; /* The suffix itself */ 118 int nameLen; /* Length of the suffix */ 119 short flags; /* Type of suffix */ 120 #define SUFF_INCLUDE 0x01 /* One which is #include'd */ 119 121 #ifdef USE_ARCHIVES 120 #define SUFF_LIBRARY 0x02/* One which contains a library */122 #define SUFF_LIBRARY 0x02 /* One which contains a library */ 121 123 #endif 122 #define SUFF_NULL 0x04/* The empty suffix */123 Lst searchPath;/* The path along which files of this suffix124 125 int sNum; 126 int refCount;/* Reference count of list membership */127 Lst parents; 128 Lst children; 129 Lst ref;/* List of lists this suffix is referenced */124 #define SUFF_NULL 0x04 /* The empty suffix */ 125 Lst searchPath; /* The path along which files of this suffix 126 * may be found */ 127 int sNum; /* The suffix number */ 128 int refCount; /* Reference count of list membership */ 129 Lst parents; /* Suffixes we have a transformation to */ 130 Lst children; /* Suffixes we have a transformation from */ 131 Lst ref; /* List of lists this suffix is referenced */ 130 132 } Suff; 131 133 … … 134 136 */ 135 137 typedef struct _Src { 136 char *file; 137 char *pref;/* Prefix from which file was formed */138 Suff *suff; 139 struct _Src *parent; 140 GNode *node; 141 int children;/* Count of existing children (so we don't efree142 138 char *file; /* The file to look for */ 139 char *pref; /* Prefix from which file was formed */ 140 Suff *suff; /* The suffix on the file */ 141 struct _Src *parent; /* The Src for which this is a source */ 142 GNode *node; /* The node describing the file */ 143 int children; /* Count of existing children (so we don't efree 144 * this thing too early or never nuke it) */ 143 145 #ifdef DEBUG_SRC 144 Lst cp;/* Debug; children list */146 Lst cp; /* Debug; children list */ 145 147 #endif 146 148 } Src; … … 155 157 } LstSrc; 156 158 157 static Suff *suffNull;/* The NULL suffix for this run */158 static Suff *emptySuff;/* The empty suffix required for POSIX159 159 static Suff *suffNull; /* The NULL suffix for this run */ 160 static Suff *emptySuff; /* The empty suffix required for POSIX 161 * single-suffix transformation rules */ 160 162 161 163 … … 187 189 static int SuffPrintTrans __P((ClientData, ClientData)); 188 190 189 191 /*************** Lst Predicates ****************/ 190 192 /*- 191 193 *----------------------------------------------------------------------- 192 194 * SuffStrIsPrefix -- 193 * 194 * 195 * Results: 196 * 197 * 198 * Side Effects: 199 * 195 * See if pref is a prefix of str. 196 * 197 * Results: 198 * NULL if it ain't, pointer to character in str after prefix if so 199 * 200 * Side Effects: 201 * None 200 202 *----------------------------------------------------------------------- 201 203 */ 202 204 static char * 203 205 SuffStrIsPrefix (pref, str) 204 register char *pref; 205 register char *str; 206 register char *pref; /* possible prefix */ 207 register char *str; /* string to check */ 206 208 { 207 209 while (*str && *pref == *str) { 208 209 210 pref++; 211 str++; 210 212 } 211 213 … … 216 218 *----------------------------------------------------------------------- 217 219 * SuffSuffIsSuffix -- 218 * 219 * 220 * 221 * Results: 222 * 223 * 224 * 225 * Side Effects: 226 * 220 * See if suff is a suffix of str. Str should point to THE END of the 221 * string to check. (THE END == the null byte) 222 * 223 * Results: 224 * NULL if it ain't, pointer to character in str before suffix if 225 * it is. 226 * 227 * Side Effects: 228 * None 227 229 *----------------------------------------------------------------------- 228 230 */ 229 231 static char * 230 232 SuffSuffIsSuffix (s, str) 231 register Suff *s; 232 char *str; 233 { 234 register char *p1; 235 register char *p2; 233 register Suff *s; /* possible suffix */ 234 char *str; /* string to examine */ 235 { 236 register char *p1; /* Pointer into suffix name */ 237 register char *p2; /* Pointer into string being examined */ 236 238 237 239 p1 = s->name + s->nameLen; … … 239 241 240 242 while (p1 >= s->name && *p1 == *p2) { 241 242 243 p1--; 244 p2--; 243 245 } 244 246 … … 249 251 *----------------------------------------------------------------------- 250 252 * SuffSuffIsSuffixP -- 251 * 252 * 253 * 254 * Results: 255 * 256 * 257 * Side Effects: 258 * 253 * Predicate form of SuffSuffIsSuffix. Passed as the callback function 254 * to Lst_Find. 255 * 256 * Results: 257 * 0 if the suffix is the one desired, non-zero if not. 258 * 259 * Side Effects: 260 * None. 259 261 * 260 262 *----------------------------------------------------------------------- … … 271 273 *----------------------------------------------------------------------- 272 274 * SuffSuffHasNameP -- 273 * 274 * 275 * 276 * Results: 277 * 278 * 279 * Side Effects: 280 * 275 * Callback procedure for finding a suffix based on its name. Used by 276 * Suff_GetPath. 277 * 278 * Results: 279 * 0 if the suffix is of the given name. non-zero otherwise. 280 * 281 * Side Effects: 282 * None 281 283 *----------------------------------------------------------------------- 282 284 */ 283 285 static int 284 286 SuffSuffHasNameP (s, sname) 285 ClientData s; 286 ClientData sname; 287 ClientData s; /* Suffix to check */ 288 ClientData sname; /* Desired name */ 287 289 { 288 290 return (strcmp ((char *) sname, ((Suff *) s)->name)); … … 292 294 *----------------------------------------------------------------------- 293 295 * SuffSuffIsPrefix -- 294 * 295 * 296 * 297 * 298 * 299 * Results: 300 * 301 * 302 * Side Effects: 303 * 296 * See if the suffix described by s is a prefix of the string. Care 297 * must be taken when using this to search for transformations and 298 * what-not, since there could well be two suffixes, one of which 299 * is a prefix of the other... 300 * 301 * Results: 302 * 0 if s is a prefix of str. non-zero otherwise 303 * 304 * Side Effects: 305 * None 304 306 *----------------------------------------------------------------------- 305 307 */ 306 308 static int 307 309 SuffSuffIsPrefix (s, str) 308 ClientData s; 309 ClientData str; 310 ClientData s; /* suffix to compare */ 311 ClientData str; /* string to examine */ 310 312 { 311 313 return (SuffStrIsPrefix (((Suff *) s)->name, (char *) str) == NULL ? 1 : 0); … … 315 317 *----------------------------------------------------------------------- 316 318 * SuffGNHasNameP -- 317 * 318 * 319 * Results: 320 * 321 * 322 * Side Effects: 323 * 319 * See if the graph node has the desired name 320 * 321 * Results: 322 * 0 if it does. non-zero if it doesn't 323 * 324 * Side Effects: 325 * None 324 326 *----------------------------------------------------------------------- 325 327 */ 326 328 static int 327 329 SuffGNHasNameP (gn, name) 328 ClientData gn; 329 ClientData name; 330 ClientData gn; /* current node we're looking at */ 331 ClientData name; /* name we're looking for */ 330 332 { 331 333 return (strcmp ((char *) name, ((GNode *) gn)->name)); 332 334 } 333 335 334 336 /*********** Maintenance Functions ************/ 335 337 336 338 /*- 337 339 *----------------------------------------------------------------------- 338 340 * SuffFree -- 339 * 340 * 341 * Results: 342 * 343 * 344 * Side Effects: 345 * 341 * Free up all memory associated with the given suffix structure. 342 * 343 * Results: 344 * none 345 * 346 * Side Effects: 347 * the suffix entry is detroyed 346 348 *----------------------------------------------------------------------- 347 349 */ … … 353 355 354 356 if (s == suffNull) 355 357 suffNull = NULL; 356 358 357 359 if (s == emptySuff) 358 360 emptySuff = NULL; 359 361 360 362 Lst_Destroy (s->ref, NOFREE); … … 370 372 *----------------------------------------------------------------------- 371 373 * SuffRemove -- 372 * 373 * 374 * Results: 375 * 376 * 377 * Side Effects: 378 * 374 * Remove the suffix into the list 375 * 376 * Results: 377 * None 378 * 379 * Side Effects: 380 * The reference count for the suffix is decremented 379 381 *----------------------------------------------------------------------- 380 382 */ … … 386 388 LstNode ln = Lst_Member(l, (ClientData)s); 387 389 if (ln != NILLNODE) { 388 389 390 Lst_Remove(l, ln); 391 s->refCount--; 390 392 } 391 393 } … … 395 397 *----------------------------------------------------------------------- 396 398 * SuffInsert -- 397 * 398 * 399 * 400 * Results: 401 * 402 * 403 * Side Effects: 404 * 399 * Insert the suffix into the list keeping the list ordered by suffix 400 * numbers. 401 * 402 * Results: 403 * None 404 * 405 * Side Effects: 406 * The reference count of the suffix is incremented 405 407 *----------------------------------------------------------------------- 406 408 */ 407 409 static void 408 410 SuffInsert (l, s) 409 Lst l; 410 Suff *s; 411 { 412 LstNode ln;/* current element in l we're examining */413 Suff *s2 = NULL; 411 Lst l; /* the list where in s should be inserted */ 412 Suff *s; /* the suffix to insert */ 413 { 414 LstNode ln; /* current element in l we're examining */ 415 Suff *s2 = NULL; /* the suffix descriptor in this element */ 414 416 415 417 if (Lst_Open (l) == FAILURE) { 416 418 return; 417 419 } 418 420 while ((ln = Lst_Next (l)) != NILLNODE) { 419 420 421 422 421 s2 = (Suff *) Lst_Datum (ln); 422 if (s2->sNum >= s->sNum) { 423 break; 424 } 423 425 } 424 426 425 427 Lst_Close (l); 426 428 if (DEBUG(SUFF)) { 427 429 printf("inserting %s(%d)...", s->name, s->sNum); 428 430 } 429 431 if (ln == NILLNODE) { 430 431 432 433 434 435 432 if (DEBUG(SUFF)) { 433 printf("at end of list\n"); 434 } 435 (void)Lst_AtEnd (l, (ClientData)s); 436 s->refCount++; 437 (void)Lst_AtEnd(s->ref, (ClientData) l); 436 438 } else if (s2->sNum != s->sNum) { 437 438 439 440 441 442 439 if (DEBUG(SUFF)) { 440 printf("before %s(%d)\n", s2->name, s2->sNum); 441 } 442 (void)Lst_Insert (l, ln, (ClientData)s); 443 s->refCount++; 444 (void)Lst_AtEnd(s->ref, (ClientData) l); 443 445 } else if (DEBUG(SUFF)) { 444 446 printf("already there\n"); 445 447 } 446 448 } … … 449 451 *----------------------------------------------------------------------- 450 452 * Suff_ClearSuffixes -- 451 * 452 * 453 * 454 * 455 * 456 * 457 * 458 * Results: 459 * 460 * 461 * Side Effects: 462 * 453 * This is gross. Nuke the list of suffixes but keep all transformation 454 * rules around. The transformation graph is destroyed in this process, 455 * but we leave the list of rules so when a new graph is formed the rules 456 * will remain. 457 * This function is called from the parse module when a 458 * .SUFFIXES:\n line is encountered. 459 * 460 * Results: 461 * none 462 * 463 * Side Effects: 464 * the sufflist and its graph nodes are destroyed 463 465 *----------------------------------------------------------------------- 464 466 */ … … 483 485 *----------------------------------------------------------------------- 484 486 * SuffParseTransform -- 485 * 486 * 487 * Results: 488 * 489 * 490 * Side Effects: 491 * 487 * Parse a transformation string to find its two component suffixes. 488 * 489 * Results: 490 * TRUE if the string is a valid transformation and FALSE otherwise. 491 * 492 * Side Effects: 493 * The passed pointers are overwritten. 492 494 * 493 495 *----------------------------------------------------------------------- … … 495 497 static Boolean 496 498 SuffParseTransform(str, srcPtr, targPtr) 497 char *str;/* String being parsed */498 Suff **srcPtr;/* Place to store source of trans. */499 Suff **targPtr;/* Place to store target of trans. */500 { 501 register LstNode srcLn;/* element in suffix list of trans source*/502 register Suff *src;/* Source of transformation */503 register LstNode targLn; 504 register char *str2;/* Extra pointer (maybe target suffix) */505 LstNode 506 507 Suff 508 499 char *str; /* String being parsed */ 500 Suff **srcPtr; /* Place to store source of trans. */ 501 Suff **targPtr; /* Place to store target of trans. */ 502 { 503 register LstNode srcLn; /* element in suffix list of trans source*/ 504 register Suff *src; /* Source of transformation */ 505 register LstNode targLn; /* element in suffix list of trans target*/ 506 register char *str2; /* Extra pointer (maybe target suffix) */ 507 LstNode singleLn; /* element in suffix list of any suffix 508 * that exactly matches str */ 509 Suff *single = NULL;/* Source of possible transformation to 510 * null suffix */ 509 511 510 512 srcLn = NILLNODE; … … 518 520 */ 519 521 for (;;) { 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 522 if (srcLn == NILLNODE) { 523 srcLn = Lst_Find(sufflist, (ClientData)str, SuffSuffIsPrefix); 524 } else { 525 srcLn = Lst_FindFrom (sufflist, Lst_Succ(srcLn), (ClientData)str, 526 SuffSuffIsPrefix); 527 } 528 if (srcLn == NILLNODE) { 529 /* 530 * Ran out of source suffixes -- no such rule 531 */ 532 if (singleLn != NILLNODE) { 533 /* 534 * Not so fast Mr. Smith! There was a suffix that encompassed 535 * the entire string, so we assume it was a transformation 536 * to the null suffix (thank you POSIX). We still prefer to 537 * find a double rule over a singleton, hence we leave this 538 * check until the end. 539 * 540 * XXX: Use emptySuff over suffNull? 541 */ 542 *srcPtr = single; 543 *targPtr = suffNull; 544 return(TRUE); 545 } 546 return (FALSE); 547 } 548 src = (Suff *) Lst_Datum (srcLn); 549 str2 = str + src->nameLen; 550 if (*str2 == '\0') { 551 single = src; 552 singleLn = srcLn; 553 } else { 554 targLn = Lst_Find(sufflist, (ClientData)str2, SuffSuffHasNameP); 555 if (targLn != NILLNODE) { 556 *srcPtr = src; 557 *targPtr = (Suff *)Lst_Datum(targLn); 558 return (TRUE); 559 } 560 } 559 561 } 560 562 } … … 563 565 *----------------------------------------------------------------------- 564 566 * Suff_IsTransform -- 565 * 566 * 567 * 568 * Results: 569 * 570 * 571 * 572 * Side Effects: 573 * 567 * Return TRUE if the given string is a transformation rule 568 * 569 * 570 * Results: 571 * TRUE if the string is a concatenation of two known suffixes. 572 * FALSE otherwise 573 * 574 * Side Effects: 575 * None 574 576 *----------------------------------------------------------------------- 575 577 */ 576 578 Boolean 577 579 Suff_IsTransform (str) 578 char *str; 579 { 580 Suff 580 char *str; /* string to check */ 581 { 582 Suff *src, *targ; 581 583 582 584 return (SuffParseTransform(str, &src, &targ)); … … 586 588 *----------------------------------------------------------------------- 587 589 * Suff_AddTransform -- 588 * 589 * 590 * 591 * Results: 592 * 593 * 594 * Side Effects: 595 * 596 * 590 * Add the transformation rule described by the line to the 591 * list of rules and place the transformation itself in the graph 592 * 593 * Results: 594 * The node created for the transformation in the transforms list 595 * 596 * Side Effects: 597 * The node is placed on the end of the transforms Lst and links are 598 * made between the two suffixes mentioned in the target name 597 599 *----------------------------------------------------------------------- 598 600 */ 599 601 GNode * 600 602 Suff_AddTransform (line) 601 char *line; 602 { 603 GNode *gn; 604 Suff *s, 605 *t; 606 LstNode ln;/* Node for existing transformation */603 char *line; /* name of transformation to add */ 604 { 605 GNode *gn; /* GNode of transformation rule */ 606 Suff *s, /* source suffix */ 607 *t; /* target suffix */ 608 LstNode ln; /* Node for existing transformation */ 607 609 608 610 ln = Lst_Find (transforms, (ClientData)line, SuffGNHasNameP); 609 611 if (ln == NILLNODE) { 610 611 612 613 614 615 612 /* 613 * Make a new graph node for the transformation. It will be filled in 614 * by the Parse module. 615 */ 616 gn = Targ_NewGN (line); 617 (void)Lst_AtEnd (transforms, (ClientData)gn); 616 618 } else { 617 618 619 620 621 622 623 624 625 626 627 619 /* 620 * New specification for transformation rule. Just nuke the old list 621 * of commands so they can be filled in again... We don't actually 622 * efree the commands themselves, because a given command can be 623 * attached to several different transformations. 624 */ 625 gn = (GNode *) Lst_Datum (ln); 626 Lst_Destroy (gn->commands, NOFREE); 627 Lst_Destroy (gn->children, NOFREE); 628 gn->commands = Lst_Init (FALSE); 629 gn->children = Lst_Init (FALSE); 628 630 } 629 631 … … 636 638 */ 637 639 if (DEBUG(SUFF)) { 638 639 640 printf("defining transformation from `%s' to `%s'\n", 641 s->name, t->name); 640 642 } 641 643 SuffInsert (t->children, s); … … 648 650 *----------------------------------------------------------------------- 649 651 * Suff_EndTransform -- 650 * 651 * 652 * 653 * 654 * 655 * Results: 656 * 657 * 658 * Side Effects: 659 * 660 * 652 * Handle the finish of a transformation definition, removing the 653 * transformation from the graph if it has neither commands nor 654 * sources. This is a callback procedure for the Parse module via 655 * Lst_ForEach 656 * 657 * Results: 658 * === 0 659 * 660 * Side Effects: 661 * If the node has no commands or children, the children and parents 662 * lists of the affected suffices are altered. 661 663 * 662 664 *----------------------------------------------------------------------- … … 664 666 int 665 667 Suff_EndTransform(gnp, dummy) 666 ClientData gnp; 667 ClientData dummy; 668 ClientData gnp; /* Node for transformation */ 669 ClientData dummy; /* Node for transformation */ 668 670 { 669 671 GNode *gn = (GNode *) gnp; 670 672 671 673 if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) && 672 674 Lst_IsEmpty(gn->children)) 673 675 { 674 Suff*s, *t;675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 676 Suff *s, *t; 677 678 (void)SuffParseTransform(gn->name, &s, &t); 679 680 if (DEBUG(SUFF)) { 681 printf("deleting transformation from `%s' to `%s'\n", 682 s->name, t->name); 683 } 684 685 /* 686 * Remove the source from the target's children list. We check for a 687 * nil return to handle a beanhead saying something like 688 * .c.o .c.o: 689 * 690 * We'll be called twice when the next target is seen, but .c and .o 691 * are only linked once... 692 */ 693 SuffRemove(t->children, s); 694 695 /* 696 * Remove the target from the source's parents list 697 */ 698 SuffRemove(s->parents, t); 697 699 } else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { 698 700 printf("transformation %s complete\n", gn->name); 699 701 } 700 702 … … 705 707 *----------------------------------------------------------------------- 706 708 * SuffRebuildGraph -- 707 * 708 * 709 * 710 * 711 * 712 * 713 * 714 * Results: 715 * 716 * 717 * Side Effects: 718 * 719 * 709 * Called from Suff_AddSuffix via Lst_ForEach to search through the 710 * list of existing transformation rules and rebuild the transformation 711 * graph when it has been destroyed by Suff_ClearSuffixes. If the 712 * given rule is a transformation involving this suffix and another, 713 * existing suffix, the proper relationship is established between 714 * the two. 715 * 716 * Results: 717 * Always 0. 718 * 719 * Side Effects: 720 * The appropriate links will be made between this suffix and 721 * others if transformation rules exist for it. 720 722 * 721 723 *----------------------------------------------------------------------- … … 724 726 SuffRebuildGraph(transformp, sp) 725 727 ClientData transformp; /* Transformation to test */ 726 ClientData sp; 727 { 728 GNode 729 Suff 730 char 731 LstNode 732 Suff 728 ClientData sp; /* Suffix to rebuild */ 729 { 730 GNode *transform = (GNode *) transformp; 731 Suff *s = (Suff *) sp; 732 char *cp; 733 LstNode ln; 734 Suff *s2 = NULL; 733 735 734 736 /* … … 737 739 cp = SuffStrIsPrefix(s->name, transform->name); 738 740 if (cp != (char *)NULL) { 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 741 if (cp[0] == '\0') /* null rule */ 742 s2 = suffNull; 743 else { 744 ln = Lst_Find(sufflist, (ClientData)cp, SuffSuffHasNameP); 745 if (ln != NILLNODE) 746 s2 = (Suff *)Lst_Datum(ln); 747 } 748 if (s2 != NULL) { 749 /* 750 * Found target. Link in and return, since it can't be anything 751 * else. 752 */ 753 SuffInsert(s2->children, s); 754 SuffInsert(s->parents, s2); 755 return(0); 756 } 755 757 } 756 758 … … 760 762 cp = SuffSuffIsSuffix(s, transform->name + strlen(transform->name)); 761 763 if (cp != (char *)NULL) { 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 764 /* 765 * Null-terminate the source suffix in order to find it. 766 */ 767 cp[1] = '\0'; 768 ln = Lst_Find(sufflist, (ClientData)transform->name, SuffSuffHasNameP); 769 /* 770 * Replace the start of the target suffix 771 */ 772 cp[1] = s->name[0]; 773 if (ln != NILLNODE) { 774 /* 775 * Found it -- establish the proper relationship 776 */ 777 s2 = (Suff *)Lst_Datum(ln); 778 SuffInsert(s->children, s2); 779 SuffInsert(s2->parents, s); 780 } 779 781 } 780 782 return(0); … … 784 786 *----------------------------------------------------------------------- 785 787 * Suff_AddSuffix -- 786 * 787 * 788 * 789 * Results: 790 * 791 * 792 * Side Effects: 793 * 794 * 788 * Add the suffix in string to the end of the list of known suffixes. 789 * Should we restructure the suffix graph? Make doesn't... 790 * 791 * Results: 792 * None 793 * 794 * Side Effects: 795 * A GNode is created for the suffix and a Suff structure is created and 796 * added to the suffixes list unless the suffix was already known. 795 797 *----------------------------------------------------------------------- 796 798 */ 797 799 void 798 800 Suff_AddSuffix (str) 799 char *str; 800 { 801 Suff *s; 802 LstNode 801 char *str; /* the name of the suffix to add */ 802 { 803 Suff *s; /* new suffix descriptor */ 804 LstNode ln; 803 805 804 806 ln = Lst_Find (sufflist, (ClientData)str, SuffSuffHasNameP); 805 807 if (ln == NILLNODE) { 806 807 808 s->name =estrdup (str);809 s->nameLen =strlen (s->name);810 811 s->children =Lst_Init (FALSE);812 s->parents =Lst_Init (FALSE);813 s->ref =Lst_Init (FALSE);814 s->sNum =sNum++;815 s->flags =0;816 s->refCount =0;817 818 819 820 821 822 823 808 s = (Suff *) emalloc (sizeof (Suff)); 809 810 s->name = estrdup (str); 811 s->nameLen = strlen (s->name); 812 s->searchPath = Lst_Init (FALSE); 813 s->children = Lst_Init (FALSE); 814 s->parents = Lst_Init (FALSE); 815 s->ref = Lst_Init (FALSE); 816 s->sNum = sNum++; 817 s->flags = 0; 818 s->refCount = 0; 819 820 (void)Lst_AtEnd (sufflist, (ClientData)s); 821 /* 822 * Look for any existing transformations from or to this suffix. 823 * XXX: Only do this after a Suff_ClearSuffixes? 824 */ 825 Lst_ForEach (transforms, SuffRebuildGraph, (ClientData)s); 824 826 } 825 827 } … … 828 830 *----------------------------------------------------------------------- 829 831 * Suff_GetPath -- 830 * 831 * 832 * Results: 833 * 834 * 835 * 836 * Side Effects: 837 * 832 * Return the search path for the given suffix, if it's defined. 833 * 834 * Results: 835 * The searchPath for the desired suffix or NILLST if the suffix isn't 836 * defined. 837 * 838 * Side Effects: 839 * None 838 840 *----------------------------------------------------------------------- 839 841 */ 840 842 Lst 841 843 Suff_GetPath (sname) 842 char 843 { 844 LstNode 845 Suff 844 char *sname; 845 { 846 LstNode ln; 847 Suff *s; 846 848 847 849 ln = Lst_Find (sufflist, (ClientData)sname, SuffSuffHasNameP); 848 850 if (ln == NILLNODE) { 849 851 return (NILLST); 850 852 } else { 851 852 853 s = (Suff *) Lst_Datum (ln); 854 return (s->searchPath); 853 855 } 854 856 } … … 857 859 *----------------------------------------------------------------------- 858 860 * Suff_DoPaths -- 859 * 860 * 861 * 862 * Results: 863 * 864 * 865 * Side Effects: 866 * 867 * 868 * 869 * 870 * 871 * 861 * Extend the search paths for all suffixes to include the default 862 * search path. 863 * 864 * Results: 865 * None. 866 * 867 * Side Effects: 868 * The searchPath field of all the suffixes is extended by the 869 * directories in dirSearchPath. If paths were specified for the 870 * ".h" suffix, the directories are stuffed into a global variable 871 * called ".INCLUDES" with each directory preceeded by a -I. The same 872 * is done for the ".a" suffix, except the variable is called 873 * ".LIBS" and the flag is -L. 872 874 *----------------------------------------------------------------------- 873 875 */ … … 875 877 Suff_DoPaths() 876 878 { 877 register Suff 878 register LstNode 879 char 880 Lst 881 Lst inLibs;/* Cumulative .LIBS path */879 register Suff *s; 880 register LstNode ln; 881 char *ptr; 882 Lst inIncludes; /* Cumulative .INCLUDES path */ 883 Lst inLibs; /* Cumulative .LIBS path */ 882 884 883 885 if (Lst_Open (sufflist) == FAILURE) { 884 886 return; 885 887 } 886 888 … … 889 891 890 892 while ((ln = Lst_Next (sufflist)) != NILLNODE) { 891 892 893 s = (Suff *) Lst_Datum (ln); 894 if (!Lst_IsEmpty (s->searchPath)) { 893 895 #ifdef INCLUDES 894 895 896 896 if (s->flags & SUFF_INCLUDE) { 897 Dir_Concat(inIncludes, s->searchPath); 898 } 897 899 #endif /* INCLUDES */ 898 900 #ifdef USE_ARCHIVES 899 901 #ifdef LIBRARIES 900 901 902 902 if (s->flags & SUFF_LIBRARY) { 903 Dir_Concat(inLibs, s->searchPath); 904 } 903 905 #endif /* LIBRARIES */ 904 906 #endif 905 906 907 908 909 907 Dir_Concat(s->searchPath, dirSearchPath); 908 } else { 909 Lst_Destroy (s->searchPath, Dir_Destroy); 910 s->searchPath = Lst_Duplicate(dirSearchPath, Dir_CopyDir); 911 } 910 912 } 911 913 … … 924 926 *----------------------------------------------------------------------- 925 927 * Suff_AddInclude -- 926 * 927 * 928 * 929 * 930 * Results: 931 * 932 * 933 * Side Effects: 934 * 928 * Add the given suffix as a type of file which gets included. 929 * Called from the parse module when a .INCLUDES line is parsed. 930 * The suffix must have already been defined. 931 * 932 * Results: 933 * None. 934 * 935 * Side Effects: 936 * The SUFF_INCLUDE bit is set in the suffix's flags field 935 937 * 936 938 *----------------------------------------------------------------------- … … 938 940 void 939 941 Suff_AddInclude (sname) 940 char 941 { 942 LstNode 943 Suff 942 char *sname; /* Name of suffix to mark */ 943 { 944 LstNode ln; 945 Suff *s; 944 946 945 947 ln = Lst_Find (sufflist, (ClientData)sname, SuffSuffHasNameP); 946 948 if (ln != NILLNODE) { 947 948 949 s = (Suff *) Lst_Datum (ln); 950 s->flags |= SUFF_INCLUDE; 949 951 } 950 952 } … … 954 956 *----------------------------------------------------------------------- 955 957 * Suff_AddLib -- 956 * 957 * 958 * 959 * 960 * 961 * Results: 962 * 963 * 964 * Side Effects: 965 * 958 * Add the given suffix as a type of file which is a library. 959 * Called from the parse module when parsing a .LIBS line. The 960 * suffix must have been defined via .SUFFIXES before this is 961 * called. 962 * 963 * Results: 964 * None. 965 * 966 * Side Effects: 967 * The SUFF_LIBRARY bit is set in the suffix's flags field 966 968 * 967 969 *----------------------------------------------------------------------- … … 969 971 void 970 972 Suff_AddLib (sname) 971 char 972 { 973 LstNode 974 Suff 973 char *sname; /* Name of suffix to mark */ 974 { 975 LstNode ln; 976 Suff *s; 975 977 976 978 ln = Lst_Find (sufflist, (ClientData)sname, SuffSuffHasNameP); 977 979 if (ln != NILLNODE) { 978 979 980 s = (Suff *) Lst_Datum (ln); 981 s->flags |= SUFF_LIBRARY; 980 982 } 981 983 } 982 984 #endif /* USE_ARCHIVES */ 983 985 984 986 /********** Implicit Source Search Functions *********/ 985 987 986 988 /*- 987 989 *----------------------------------------------------------------------- 988 990 * SuffAddSrc -- 989 * 990 * 991 * 992 * 993 * Results: 994 * 995 * 996 * Side Effects: 997 * 991 * Add a suffix as a Src structure to the given list with its parent 992 * being the given Src structure. If the suffix is the null suffix, 993 * the prefix is used unaltered as the file name in the Src structure. 994 * 995 * Results: 996 * always returns 0 997 * 998 * Side Effects: 999 * A Src structure is created and tacked onto the end of the list 998 1000 *----------------------------------------------------------------------- 999 1001 */ 1000 1002 static int 1001 1003 SuffAddSrc (sp, lsp) 1002 ClientData sp;/* suffix for which to create a Src structure */1003 ClientData lsp; 1004 { 1005 Suff 1004 ClientData sp; /* suffix for which to create a Src structure */ 1005 ClientData lsp; /* list and parent for the new Src */ 1006 { 1007 Suff *s = (Suff *) sp; 1006 1008 LstSrc *ls = (LstSrc *) lsp; 1007 Src *s2; 1008 Src *targ;/* Target structure */1009 Src *s2; /* new Src structure */ 1010 Src *targ; /* Target structure */ 1009 1011 1010 1012 targ = ls->s; 1011 1013 1012 1014 if ((s->flags & SUFF_NULL) && (*s->name != '\0')) { 1013 1014 1015 1016 1017 1018 1019 s2->file =estrdup(targ->pref);1020 s2->pref =targ->pref;1021 s2->parent =targ;1022 s2->node =NILGNODE;1023 s2->suff =s;1024 1025 s2->children =0;1026 1027 1015 /* 1016 * If the suffix has been marked as the NULL suffix, also create a Src 1017 * structure for a file with no suffix attached. Two birds, and all 1018 * that... 1019 */ 1020 s2 = (Src *) emalloc (sizeof (Src)); 1021 s2->file = estrdup(targ->pref); 1022 s2->pref = targ->pref; 1023 s2->parent = targ; 1024 s2->node = NILGNODE; 1025 s2->suff = s; 1026 s->refCount++; 1027 s2->children = 0; 1028 targ->children += 1; 1029 (void)Lst_AtEnd (ls->l, (ClientData)s2); 1028 1030 #ifdef DEBUG_SRC 1029 1030 1031 1032 1033 1031 s2->cp = Lst_Init(FALSE); 1032 Lst_AtEnd(targ->cp, (ClientData) s2); 1033 printf("1 add %x %x to %x:", targ, s2, ls->l); 1034 Lst_ForEach(ls->l, PrintAddr, (ClientData) 0); 1035 printf("\n"); 1034 1036 #endif 1035 1037 } 1036 1038 s2 = (Src *) emalloc (sizeof (Src)); 1037 s2->file = 1038 s2->pref = 1039 s2->file = str_concat (targ->pref, s->name, 0); 1040 s2->pref = targ->pref; 1039 1041 s2->parent = targ; 1040 s2->node = 1041 s2->suff = 1042 s2->node = NILGNODE; 1043 s2->suff = s; 1042 1044 s->refCount++; 1043 1045 s2->children = 0; … … 1058 1060 *----------------------------------------------------------------------- 1059 1061 * SuffAddLevel -- 1060 * 1061 * 1062 * Results: 1063 * 1064 * 1065 * Side Effects: 1066 * 1062 * Add all the children of targ as Src structures to the given list 1063 * 1064 * Results: 1065 * None 1066 * 1067 * Side Effects: 1068 * Lots of structures are created and added to the list 1067 1069 *----------------------------------------------------------------------- 1068 1070 */ 1069 1071 static void 1070 1072 SuffAddLevel (l, targ) 1071 Lst l; 1072 Src *targ; 1073 Lst l; /* list to which to add the new level */ 1074 Src *targ; /* Src structure to use as the parent */ 1073 1075 { 1074 1076 LstSrc ls; … … 1083 1085 *---------------------------------------------------------------------- 1084 1086 * SuffRemoveSrc -- 1085 * 1086 * 1087 * Results: 1088 * 1089 * 1090 * Side Effects: 1091 * 1087 * Free all src structures in list that don't have a reference count 1088 * 1089 * Results: 1090 * Ture if an src was removed 1091 * 1092 * Side Effects: 1093 * The memory is efree'd. 1092 1094 *---------------------------------------------------------------------- 1093 1095 */ … … 1101 1103 1102 1104 if (Lst_Open (l) == FAILURE) { 1103 1105 return 0; 1104 1106 } 1105 1107 #ifdef DEBUG_SRC … … 1111 1113 1112 1114 while ((ln = Lst_Next (l)) != NILLNODE) { 1113 1114 1115 1116 1117 1118 1115 s = (Src *) Lst_Datum (ln); 1116 if (s->children == 0) { 1117 efree ((Address)s->file); 1118 if (!s->parent) 1119 efree((Address)s->pref); 1120 else { 1119 1121 #ifdef DEBUG_SRC 1120 1121 1122 1122 LstNode ln = Lst_Member(s->parent->cp, (ClientData)s); 1123 if (ln != NILLNODE) 1124 Lst_Remove(s->parent->cp, ln); 1123 1125 #endif 1124 1125 1126 --s->parent->children; 1127 } 1126 1128 #ifdef DEBUG_SRC 1127 1128 1129 printf("efree: [l=%x] p=%x %d\n", l, s, s->children); 1130 Lst_Destroy(s->cp, NOFREE); 1129 1131 #endif 1130 1131 1132 1133 1134 1135 1132 Lst_Remove(l, ln); 1133 efree ((Address)s); 1134 t |= 1; 1135 Lst_Close(l); 1136 return TRUE; 1137 } 1136 1138 #ifdef DEBUG_SRC 1137 1138 1139 1140 1141 1139 else { 1140 printf("keep: [l=%x] p=%x %d: ", l, s, s->children); 1141 Lst_ForEach(s->cp, PrintAddr, (ClientData) 0); 1142 printf("\n"); 1143 } 1142 1144 #endif 1143 1145 } … … 1151 1153 *----------------------------------------------------------------------- 1152 1154 * SuffFindThem -- 1153 * 1154 * 1155 * Results: 1156 * 1157 * 1158 * Side Effects: 1159 * 1155 * Find the first existing file/target in the list srcs 1156 * 1157 * Results: 1158 * The lowest structure in the chain of transformations 1159 * 1160 * Side Effects: 1161 * None 1160 1162 *----------------------------------------------------------------------- 1161 1163 */ 1162 1164 static Src * 1163 1165 SuffFindThem (srcs, slst) 1164 Lst srcs; 1165 Lst 1166 { 1167 Src *s; 1168 Src *rs;/* returned Src */1169 char 1166 Lst srcs; /* list of Src structures to search through */ 1167 Lst slst; 1168 { 1169 Src *s; /* current Src */ 1170 Src *rs; /* returned Src */ 1171 char *ptr; 1170 1172 1171 1173 rs = (Src *) NULL; 1172 1174 1173 1175 while (!Lst_IsEmpty (srcs)) { 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1176 s = (Src *) Lst_DeQueue (srcs); 1177 1178 if (DEBUG(SUFF)) { 1179 printf ("\ttrying %s...", s->file); 1180 } 1181 1182 /* 1183 * A file is considered to exist if either a node exists in the 1184 * graph for it or the file actually exists. 1185 */ 1186 if (Targ_FindNode(s->file, TARG_NOCREATE) != NILGNODE) { 1185 1187 #ifdef DEBUG_SRC 1186 1188 printf("remove %x from %x\n", s, srcs); 1187 1189 #endif 1188 1189 1190 1191 1192 1193 1190 rs = s; 1191 break; 1192 } 1193 1194 if ((ptr = Dir_FindFile (s->file, s->suff->searchPath)) != NULL) { 1195 rs = s; 1194 1196 #ifdef DEBUG_SRC 1195 1197 printf("remove %x from %x\n", s, srcs); 1196 1198 #endif 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1199 efree(ptr); 1200 break; 1201 } 1202 1203 if (DEBUG(SUFF)) { 1204 printf ("not there\n"); 1205 } 1206 1207 SuffAddLevel (srcs, s); 1208 Lst_AtEnd(slst, (ClientData) s); 1207 1209 } 1208 1210 1209 1211 if (DEBUG(SUFF) && rs) { 1210 1212 printf ("got it\n"); 1211 1213 } 1212 1214 return (rs); … … 1216 1218 *----------------------------------------------------------------------- 1217 1219 * SuffFindCmds -- 1218 * 1219 * 1220 * 1221 * 1222 * Results: 1223 * 1224 * 1225 * Side Effects: 1226 * 1220 * See if any of the children of the target in the Src structure is 1221 * one from which the target can be transformed. If there is one, 1222 * a Src structure is put together for it and returned. 1223 * 1224 * Results: 1225 * The Src structure of the "winning" child, or NIL if no such beast. 1226 * 1227 * Side Effects: 1228 * A Src structure may be allocated. 1227 1229 * 1228 1230 *----------------------------------------------------------------------- … … 1230 1232 static Src * 1231 1233 SuffFindCmds (targ, slst) 1232 Src *targ;/* Src structure to play with */1233 Lst 1234 { 1235 LstNode ln;/* General-purpose list node */1236 register GNode *t,/* Target GNode */1237 *s;/* Source GNode */1238 int 1239 Suff *suff;/* Suffix on matching beastie */1240 Src *ret;/* Return value */1241 char 1234 Src *targ; /* Src structure to play with */ 1235 Lst slst; 1236 { 1237 LstNode ln; /* General-purpose list node */ 1238 register GNode *t, /* Target GNode */ 1239 *s; /* Source GNode */ 1240 int prefLen;/* The length of the defined prefix */ 1241 Suff *suff; /* Suffix on matching beastie */ 1242 Src *ret; /* Return value */ 1243 char *cp; 1242 1244 1243 1245 t = targ->node; … … 1246 1248 1247 1249 while ((ln = Lst_Next (t->children)) != NILLNODE) { 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1250 s = (GNode *)Lst_Datum (ln); 1251 1252 cp = strrchr (s->name, '/'); 1253 if (cp == (char *)NULL) { 1254 cp = s->name; 1255 } else { 1256 cp++; 1257 } 1258 if (strncmp (cp, targ->pref, prefLen) == 0) { 1259 /* 1260 * The node matches the prefix ok, see if it has a known 1261 * suffix. 1262 */ 1263 ln = Lst_Find (sufflist, (ClientData)&cp[prefLen], 1264 SuffSuffHasNameP); 1265 if (ln != NILLNODE) { 1266 /* 1267 * It even has a known suffix, see if there's a transformation 1268 * defined between the node's suffix and the target's suffix. 1269 * 1270 * XXX: Handle multi-stage transformations here, too. 1271 */ 1272 suff = (Suff *)Lst_Datum (ln); 1273 1274 if (Lst_Member (suff->parents, 1275 (ClientData)targ->suff) != NILLNODE) 1276 { 1277 /* 1278 * Hot Damn! Create a new Src structure to describe 1279 * this transformation (making sure to duplicate the 1280 * source node's name so Suff_FindDeps can efree it 1281 * again (ick)), and return the new structure. 1282 */ 1283 ret = (Src *)emalloc (sizeof (Src)); 1284 ret->file = estrdup(s->name); 1285 ret->pref = targ->pref; 1286 ret->suff = suff; 1287 suff->refCount++; 1288 ret->parent = targ; 1289 ret->node = s; 1290 ret->children = 0; 1291 targ->children += 1; 1290 1292 #ifdef DEBUG_SRC 1291 1292 1293 1293 ret->cp = Lst_Init(FALSE); 1294 printf("3 add %x %x\n", targ, ret); 1295 Lst_AtEnd(targ->cp, (ClientData) ret); 1294 1296 #endif 1295 1296 1297 1298 1299 1300 1301 1302 1297 Lst_AtEnd(slst, (ClientData) ret); 1298 if (DEBUG(SUFF)) { 1299 printf ("\tusing existing source %s\n", s->name); 1300 } 1301 return (ret); 1302 } 1303 } 1304 } 1303 1305 } 1304 1306 Lst_Close (t->children); … … 1309 1311 *----------------------------------------------------------------------- 1310 1312 * SuffExpandChildren -- 1311 * 1312 * 1313 * 1314 * Results: 1315 * 1316 * 1317 * Side Effects: 1318 * 1319 * 1320 * 1313 * Expand the names of any children of a given node that contain 1314 * variable invocations or file wildcards into actual targets. 1315 * 1316 * Results: 1317 * === 0 (continue) 1318 * 1319 * Side Effects: 1320 * The expanded node is removed from the parent's list of children, 1321 * and the parent's unmade counter is decremented, but other nodes 1322 * may be added. 1321 1323 * 1322 1324 *----------------------------------------------------------------------- … … 1324 1326 static int 1325 1327 SuffExpandChildren(cgnp, pgnp) 1326 ClientData cgnp; 1327 ClientData pgnp; 1328 { 1329 GNode 1330 GNode 1331 GNode *gn;/* New source 8) */1332 LstNode 1333 LstNode ln;/* List element for old source */1334 char *cp;/* Expanded value */1328 ClientData cgnp; /* Child to examine */ 1329 ClientData pgnp; /* Parent node being processed */ 1330 { 1331 GNode *cgn = (GNode *) cgnp; 1332 GNode *pgn = (GNode *) pgnp; 1333 GNode *gn; /* New source 8) */ 1334 LstNode prevLN; /* Node after which new source should be put */ 1335 LstNode ln; /* List element for old source */ 1336 char *cp; /* Expanded value */ 1335 1337 1336 1338 /* … … 1347 1349 */ 1348 1350 if (strchr(cgn->name, '$') != (char *)NULL) { 1349 1350 1351 1352 1353 1354 1355 Lstmembers = Lst_Init(FALSE);1351 if (DEBUG(SUFF)) { 1352 printf("Expanding \"%s\"...", cgn->name); 1353 } 1354 cp = Var_Subst(NULL, cgn->name, pgn, TRUE); 1355 1356 if (cp != (char *)NULL) { 1357 Lst members = Lst_Init(FALSE); 1356 1358 1357 1359 #ifdef USE_ARCHIVES 1358 1359 1360 1361 1362 1363 1364 char*sacrifice = cp;1365 1366 1367 1360 if (cgn->type & OP_ARCHV) { 1361 /* 1362 * Node was an archive(member) target, so we want to call 1363 * on the Arch module to find the nodes for us, expanding 1364 * variables in the parent's context. 1365 */ 1366 char *sacrifice = cp; 1367 1368 (void)Arch_ParseArchive(&sacrifice, members, pgn); 1369 } else 1368 1370 #endif 1369 1371 { 1370 1371 1372 1373 1374 1375 1376 1377 char*start;1378 char*initcp = cp; /* For freeing... */1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 char*junk;1405 intlen;1406 BooleandoFree;1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1372 /* 1373 * Break the result into a vector of strings whose nodes 1374 * we can find, then add those nodes to the members list. 1375 * Unfortunately, we can't use brk_string b/c it 1376 * doesn't understand about variable specifications with 1377 * spaces in them... 1378 */ 1379 char *start; 1380 char *initcp = cp; /* For freeing... */ 1381 1382 for (start = cp; *start == ' ' || *start == '\t'; start++) 1383 continue; 1384 for (cp = start; *cp != '\0'; cp++) { 1385 if (*cp == ' ' || *cp == '\t') { 1386 /* 1387 * White-space -- terminate element, find the node, 1388 * add it, skip any further spaces. 1389 */ 1390 *cp++ = '\0'; 1391 gn = Targ_FindNode(start, TARG_CREATE); 1392 (void)Lst_AtEnd(members, (ClientData)gn); 1393 while (*cp == ' ' || *cp == '\t') { 1394 cp++; 1395 } 1396 /* 1397 * Adjust cp for increment at start of loop, but 1398 * set start to first non-space. 1399 */ 1400 start = cp--; 1401 } else if (*cp == '$') { 1402 /* 1403 * Start of a variable spec -- contact variable module 1404 * to find the end so we can skip over it. 1405 */ 1406 char *junk; 1407 int len; 1408 Boolean doFree; 1409 1410 junk = Var_Parse(cp, pgn, TRUE, &len, &doFree); 1411 if (junk != var_Error) { 1412 cp += len - 1; 1413 } 1414 1415 if (doFree) { 1416 efree(junk); 1417 } 1418 } else if (*cp == '\\' && *cp != '\0') { 1419 /* 1420 * Escaped something -- skip over it 1421 */ 1422 cp++; 1423 } 1424 } 1425 1426 if (cp != start) { 1427 /* 1428 * Stuff left over -- add it to the list too 1429 */ 1430 gn = Targ_FindNode(start, TARG_CREATE); 1431 (void)Lst_AtEnd(members, (ClientData)gn); 1432 } 1433 /* 1434 * Point cp back at the beginning again so the variable value 1435 * can be freed. 1436 */ 1437 cp = initcp; 1438 } 1439 /* 1440 * Add all elements of the members list to the parent node. 1441 */ 1442 while(!Lst_IsEmpty(members)) { 1443 gn = (GNode *)Lst_DeQueue(members); 1444 1445 if (DEBUG(SUFF)) { 1446 printf("%s...", gn->name); 1447 } 1448 if (Lst_Member(pgn->children, (ClientData)gn) == NILLNODE) { 1449 (void)Lst_Append(pgn->children, prevLN, (ClientData)gn); 1450 prevLN = Lst_Succ(prevLN); 1451 (void)Lst_AtEnd(gn->parents, (ClientData)pgn); 1452 pgn->unmade++; 1453 } 1454 } 1455 Lst_Destroy(members, NOFREE); 1456 /* 1457 * Free the result 1458 */ 1459 efree((char *)cp); 1460 } 1461 /* 1462 * Now the source is expanded, remove it from the list of children to 1463 * keep it from being processed. 1464 */ 1465 ln = Lst_Member(pgn->children, (ClientData)cgn); 1466 pgn->unmade--; 1467 Lst_Remove(pgn->children, ln); 1468 if (DEBUG(SUFF)) { 1469 printf("\n"); 1470 } 1469 1471 } else if (Dir_HasWildcards(cgn->name)) { 1470 Lst exp;/* List of expansions */1471 Lst path;/* Search path along which to expand */1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1472 Lst exp; /* List of expansions */ 1473 Lst path; /* Search path along which to expand */ 1474 1475 /* 1476 * Find a path along which to expand the word. 1477 * 1478 * If the word has a known suffix, use that path. 1479 * If it has no known suffix and we're allowed to use the null 1480 * suffix, use its path. 1481 * Else use the default system search path. 1482 */ 1483 cp = cgn->name + strlen(cgn->name); 1484 ln = Lst_Find(sufflist, (ClientData)cp, SuffSuffIsSuffixP); 1485 1486 if (DEBUG(SUFF)) { 1487 printf("Wildcard expanding \"%s\"...", cgn->name); 1488 } 1489 1490 if (ln != NILLNODE) { 1491 Suff *s = (Suff *)Lst_Datum(ln); 1492 1493 if (DEBUG(SUFF)) { 1494 printf("suffix is \"%s\"...", s->name); 1495 } 1496 path = s->searchPath; 1497 } else { 1498 /* 1499 * Use default search path 1500 */ 1501 path = dirSearchPath; 1502 } 1503 1504 /* 1505 * Expand the word along the chosen path 1506 */ 1507 exp = Lst_Init(FALSE); 1508 Dir_Expand(cgn->name, path, exp); 1509 1510 while (!Lst_IsEmpty(exp)) { 1511 /* 1512 * Fetch next expansion off the list and find its GNode 1513 */ 1514 cp = (char *)Lst_DeQueue(exp); 1515 1516 if (DEBUG(SUFF)) { 1517 printf("%s...", cp); 1518 } 1519 gn = Targ_FindNode(cp, TARG_CREATE); 1520 1521 /* 1522 * If gn isn't already a child of the parent, make it so and 1523 * up the parent's count of unmade children. 1524 */ 1525 if (Lst_Member(pgn->children, (ClientData)gn) == NILLNODE) { 1526 (void)Lst_Append(pgn->children, prevLN, (ClientData)gn); 1527 prevLN = Lst_Succ(prevLN); 1528 (void)Lst_AtEnd(gn->parents, (ClientData)pgn); 1529 pgn->unmade++; 1530 } 1531 } 1532 1533 /* 1534 * Nuke what's left of the list 1535 */ 1536 Lst_Destroy(exp, NOFREE); 1537 1538 /* 1539 * Now the source is expanded, remove it from the list of children to 1540 * keep it from being processed. 1541 */ 1542 ln = Lst_Member(pgn->children, (ClientData)cgn); 1543 pgn->unmade--; 1544 Lst_Remove(pgn->children, ln); 1545 if (DEBUG(SUFF)) { 1546 printf("\n"); 1547 } 1546 1548 } 1547 1549 … … 1552 1554 *----------------------------------------------------------------------- 1553 1555 * SuffApplyTransform -- 1554 * 1555 * 1556 * 1557 * Results: 1558 * 1559 * 1560 * Side Effects: 1561 * 1562 * 1563 * 1564 * 1565 * 1556 * Apply a transformation rule, given the source and target nodes 1557 * and suffixes. 1558 * 1559 * Results: 1560 * TRUE if successful, FALSE if not. 1561 * 1562 * Side Effects: 1563 * The source and target are linked and the commands from the 1564 * transformation are added to the target node's commands list. 1565 * All attributes but OP_DEPMASK and OP_TRANSFORM are applied 1566 * to the target. The target also inherits all the sources for 1567 * the transformation rule. 1566 1568 * 1567 1569 *----------------------------------------------------------------------- … … 1569 1571 static Boolean 1570 1572 SuffApplyTransform(tGn, sGn, t, s) 1571 GNode *tGn;/* Target node */1572 GNode *sGn;/* Source node */1573 Suff *t;/* Target suffix */1574 Suff *s;/* Source suffix */1575 { 1576 LstNode ln;/* General node */1577 char *tname;/* Name of transformation rule */1578 GNode *gn;/* Node for same */1573 GNode *tGn; /* Target node */ 1574 GNode *sGn; /* Source node */ 1575 Suff *t; /* Target suffix */ 1576 Suff *s; /* Source suffix */ 1577 { 1578 LstNode ln; /* General node */ 1579 char *tname; /* Name of transformation rule */ 1580 GNode *gn; /* Node for same */ 1579 1581 1580 1582 if (Lst_Member(tGn->children, (ClientData)sGn) == NILLNODE) { 1581 1582 1583 1584 1585 1586 1587 1583 /* 1584 * Not already linked, so form the proper links between the 1585 * target and source. 1586 */ 1587 (void)Lst_AtEnd(tGn->children, (ClientData)sGn); 1588 (void)Lst_AtEnd(sGn->parents, (ClientData)tGn); 1589 tGn->unmade += 1; 1588 1590 } 1589 1591 1590 1592 if ((sGn->type & OP_OPMASK) == OP_DOUBLEDEP) { 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1593 /* 1594 * When a :: node is used as the implied source of a node, we have 1595 * to link all its cohorts in as sources as well. Only the initial 1596 * sGn gets the target in its iParents list, however, as that 1597 * will be sufficient to get the .IMPSRC variable set for tGn 1598 */ 1599 for (ln=Lst_First(sGn->cohorts); ln != NILLNODE; ln=Lst_Succ(ln)) { 1600 gn = (GNode *)Lst_Datum(ln); 1601 1602 if (Lst_Member(tGn->children, (ClientData)gn) == NILLNODE) { 1603 /* 1604 * Not already linked, so form the proper links between the 1605 * target and source. 1606 */ 1607 (void)Lst_AtEnd(tGn->children, (ClientData)gn); 1608 (void)Lst_AtEnd(gn->parents, (ClientData)tGn); 1609 tGn->unmade += 1; 1610 } 1611 } 1610 1612 } 1611 1613 /* … … 1617 1619 1618 1620 if (ln == NILLNODE) { 1619 1620 1621 1622 1623 1624 1621 /* 1622 * Not really such a transformation rule (can happen when we're 1623 * called to link an OP_MEMBER and OP_ARCHV node), so return 1624 * FALSE. 1625 */ 1626 return(FALSE); 1625 1627 } 1626 1628 … … 1628 1630 1629 1631 if (DEBUG(SUFF)) { 1630 1632 printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); 1631 1633 } 1632 1634 … … 1646 1648 ln = Lst_Succ(ln); 1647 1649 if (ln != NILLNODE) { 1648 1649 1650 Lst_ForEachFrom(tGn->children, ln, 1651 SuffExpandChildren, (ClientData)tGn); 1650 1652 } 1651 1653 … … 1664 1666 *----------------------------------------------------------------------- 1665 1667 * SuffFindArchiveDeps -- 1666 * 1667 * 1668 * Results: 1669 * 1670 * 1671 * Side Effects: 1672 * 1668 * Locate dependencies for an OP_ARCHV node. 1669 * 1670 * Results: 1671 * None 1672 * 1673 * Side Effects: 1674 * Same as Suff_FindDeps 1673 1675 * 1674 1676 *----------------------------------------------------------------------- … … 1676 1678 static void 1677 1679 SuffFindArchiveDeps(gn, slst) 1678 GNode *gn;/* Node for which to locate dependencies */1679 Lst 1680 { 1681 char 1682 char 1683 GNode *mem;/* Node for member */1684 static char 1685 TARGET,/* Must be first */1686 PREFIX,/* Must be second */1680 GNode *gn; /* Node for which to locate dependencies */ 1681 Lst slst; 1682 { 1683 char *eoarch; /* End of archive portion */ 1684 char *eoname; /* End of member portion */ 1685 GNode *mem; /* Node for member */ 1686 static char *copy[] = { /* Variables to be copied from the member node */ 1687 TARGET, /* Must be first */ 1688 PREFIX, /* Must be second */ 1687 1689 }; 1688 int i;/* Index into copy and vals */1689 Suff *ms;/* Suffix descriptor for member */1690 char *name;/* Start of member's name */1690 int i; /* Index into copy and vals */ 1691 Suff *ms; /* Suffix descriptor for member */ 1692 char *name; /* Start of member's name */ 1691 1693 1692 1694 /* … … 1697 1699 eoname = strchr (eoarch, ')'); 1698 1700 1699 *eoname = '\0'; 1700 *eoarch = '\0'; 1701 *eoname = '\0'; /* Nuke parentheses during suffix search */ 1702 *eoarch = '\0'; /* So a suffix can be found */ 1701 1703 1702 1704 name = eoarch + 1; … … 1716 1718 */ 1717 1719 if (Lst_Member(gn->children, (ClientData)mem) == NILLNODE) { 1718 1719 1720 1720 (void)Lst_AtEnd(gn->children, (ClientData)mem); 1721 (void)Lst_AtEnd(mem->parents, (ClientData)gn); 1722 gn->unmade += 1; 1721 1723 } 1722 1724 … … 1725 1727 */ 1726 1728 for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) { 1727 1728 1729 1729 char *p1; 1730 Var_Set(copy[i], Var_Value(copy[i], mem, &p1), gn); 1731 efree(p1); 1730 1732 1731 1733 } … … 1733 1735 ms = mem->suffix; 1734 1736 if (ms == NULL) { 1735 1736 1737 1738 1739 1740 1741 1737 /* 1738 * Didn't know what it was -- use .NULL suffix if not in make mode 1739 */ 1740 if (DEBUG(SUFF)) { 1741 printf("using null suffix\n"); 1742 } 1743 ms = suffNull; 1742 1744 } 1743 1745 … … 1750 1752 1751 1753 if (ms != NULL) { 1752 1753 1754 1755 1756 1757 1758 LstNodeln;1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1754 /* 1755 * Member has a known suffix, so look for a transformation rule from 1756 * it to a possible suffix of the archive. Rather than searching 1757 * through the entire list, we just look at suffixes to which the 1758 * member's suffix may be transformed... 1759 */ 1760 LstNode ln; 1761 1762 /* 1763 * Use first matching suffix... 1764 */ 1765 ln = Lst_Find(ms->parents, eoarch, SuffSuffIsSuffixP); 1766 1767 if (ln != NILLNODE) { 1768 /* 1769 * Got one -- apply it 1770 */ 1771 if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && 1772 DEBUG(SUFF)) 1773 { 1774 printf("\tNo transformation from %s -> %s\n", 1775 ms->name, ((Suff *)Lst_Datum(ln))->name); 1776 } 1777 } 1776 1778 } 1777 1779 … … 1788 1790 */ 1789 1791 if (OP_NOP(gn->type)) { 1790 1792 gn->type |= OP_DEPENDS; 1791 1793 } 1792 1794 … … 1802 1804 *----------------------------------------------------------------------- 1803 1805 * SuffFindNormalDeps -- 1804 * 1805 * 1806 * Results: 1807 * 1808 * 1809 * Side Effects: 1810 * 1806 * Locate implicit dependencies for regular targets. 1807 * 1808 * Results: 1809 * None. 1810 * 1811 * Side Effects: 1812 * Same as Suff_FindDeps... 1811 1813 * 1812 1814 *----------------------------------------------------------------------- … … 1814 1816 static void 1815 1817 SuffFindNormalDeps(gn, slst) 1816 GNode *gn;/* Node for which to find sources */1817 Lst 1818 { 1819 char 1820 char 1821 LstNode ln;/* Next suffix node to check */1822 Lst srcs;/* List of sources at which to look */1823 Lst targs;/* List of targets to which things can be1824 1825 1826 Src 1827 Src *src;/* General Src pointer */1828 char *pref;/* Prefix to use */1829 Src *targ;/* General Src target pointer */1818 GNode *gn; /* Node for which to find sources */ 1819 Lst slst; 1820 { 1821 char *eoname; /* End of name */ 1822 char *sopref; /* Start of prefix */ 1823 LstNode ln; /* Next suffix node to check */ 1824 Lst srcs; /* List of sources at which to look */ 1825 Lst targs; /* List of targets to which things can be 1826 * transformed. They all have the same file, 1827 * but different suff and pref fields */ 1828 Src *bottom; /* Start of found transformation path */ 1829 Src *src; /* General Src pointer */ 1830 char *pref; /* Prefix to use */ 1831 Src *targ; /* General Src target pointer */ 1830 1832 1831 1833 … … 1861 1863 1862 1864 while (ln != NILLNODE) { 1863 1864 1865 1866 1867 1868 1869 int prefLen;/* Length of the prefix */1870 Src*targ;1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1865 /* 1866 * Look for next possible suffix... 1867 */ 1868 ln = Lst_FindFrom(sufflist, ln, eoname, SuffSuffIsSuffixP); 1869 1870 if (ln != NILLNODE) { 1871 int prefLen; /* Length of the prefix */ 1872 Src *targ; 1873 1874 /* 1875 * Allocate a Src structure to which things can be transformed 1876 */ 1877 targ = (Src *)emalloc(sizeof (Src)); 1878 targ->file = estrdup(gn->name); 1879 targ->suff = (Suff *)Lst_Datum(ln); 1880 targ->suff->refCount++; 1881 targ->node = gn; 1882 targ->parent = (Src *)NULL; 1883 targ->children = 0; 1882 1884 #ifdef DEBUG_SRC 1883 1885 targ->cp = Lst_Init(FALSE); 1884 1886 #endif 1885 1887 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1888 /* 1889 * Allocate room for the prefix, whose end is found by subtracting 1890 * the length of the suffix from the end of the name. 1891 */ 1892 prefLen = (eoname - targ->suff->nameLen) - sopref; 1893 targ->pref = emalloc(prefLen + 1); 1894 memcpy(targ->pref, sopref, prefLen); 1895 targ->pref[prefLen] = '\0'; 1896 1897 /* 1898 * Add nodes from which the target can be made 1899 */ 1900 SuffAddLevel(srcs, targ); 1901 1902 /* 1903 * Record the target so we can nuke it 1904 */ 1905 (void)Lst_AtEnd(targs, (ClientData)targ); 1906 1907 /* 1908 * Search from this suffix's successor... 1909 */ 1910 ln = Lst_Succ(ln); 1911 } 1910 1912 } 1911 1913 … … 1914 1916 */ 1915 1917 if (Lst_IsEmpty(targs) && suffNull != NULL) { 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1918 if (DEBUG(SUFF)) { 1919 printf("\tNo known suffix on %s. Using .NULL suffix\n", gn->name); 1920 } 1921 1922 targ = (Src *)emalloc(sizeof (Src)); 1923 targ->file = estrdup(gn->name); 1924 targ->suff = suffNull; 1925 targ->suff->refCount++; 1926 targ->node = gn; 1927 targ->parent = (Src *)NULL; 1928 targ->children = 0; 1929 targ->pref = estrdup(sopref); 1928 1930 #ifdef DEBUG_SRC 1929 1931 targ->cp = Lst_Init(FALSE); 1930 1932 #endif 1931 1933 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1934 /* 1935 * Only use the default suffix rules if we don't have commands 1936 * or dependencies defined for this gnode 1937 */ 1938 if (Lst_IsEmpty(gn->commands) && Lst_IsEmpty(gn->children)) 1939 SuffAddLevel(srcs, targ); 1940 else { 1941 if (DEBUG(SUFF)) 1942 printf("not "); 1943 } 1944 1945 if (DEBUG(SUFF)) 1946 printf("adding suffix rules\n"); 1947 1948 (void)Lst_AtEnd(targs, (ClientData)targ); 1947 1949 } 1948 1950 … … 1954 1956 1955 1957 if (bottom == (Src *)NULL) { 1956 1957 1958 1959 1960 1961 1962 1963 1964 1958 /* 1959 * No known transformations -- use the first suffix found for setting 1960 * the local variables. 1961 */ 1962 if (!Lst_IsEmpty(targs)) { 1963 targ = (Src *)Lst_Datum(Lst_First(targs)); 1964 } else { 1965 targ = (Src *)NULL; 1966 } 1965 1967 } else { 1966 1967 1968 1969 1970 1971 1968 /* 1969 * Work up the transformation path to find the suffix of the 1970 * target to which the transformation was made. 1971 */ 1972 for (targ = bottom; targ->parent != NULL; targ = targ->parent) 1973 continue; 1972 1974 } 1973 1975 … … 1990 1992 1991 1993 if (targ == NULL) { 1992 1993 1994 1994 if (DEBUG(SUFF)) { 1995 printf("\tNo valid suffix on %s\n", gn->name); 1996 } 1995 1997 1996 1998 sfnd_abort: 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 intsavep = strlen(gn->path) - targ->suff->nameLen;2018 charsavec;2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 1999 /* 2000 * Deal with finding the thing on the default search path if the 2001 * node is only a source (not on the lhs of a dependency operator 2002 * or [XXX] it has neither children or commands). 2003 */ 2004 if (OP_NOP(gn->type) || 2005 (Lst_IsEmpty(gn->children) && Lst_IsEmpty(gn->commands))) 2006 { 2007 gn->path = Dir_FindFile(gn->name, 2008 (targ == NULL ? dirSearchPath : 2009 targ->suff->searchPath)); 2010 if (gn->path != NULL) { 2011 char *ptr; 2012 Var_Set(TARGET, gn->path, gn); 2013 2014 if (targ != NULL) { 2015 /* 2016 * Suffix known for the thing -- trim the suffix off 2017 * the path to form the proper .PREFIX variable. 2018 */ 2019 int savep = strlen(gn->path) - targ->suff->nameLen; 2020 char savec; 2021 2022 if (gn->suffix) 2023 gn->suffix->refCount--; 2024 gn->suffix = targ->suff; 2025 gn->suffix->refCount++; 2026 2027 savec = gn->path[savep]; 2028 gn->path[savep] = '\0'; 2029 2030 if ((ptr = strrchr(gn->path, '/')) != NULL) 2031 ptr++; 2032 else 2033 ptr = gn->path; 2034 2035 Var_Set(PREFIX, ptr, gn); 2036 2037 gn->path[savep] = savec; 2038 } else { 2039 /* 2040 * The .PREFIX gets the full path if the target has 2041 * no known suffix. 2042 */ 2043 if (gn->suffix) 2044 gn->suffix->refCount--; 2045 gn->suffix = NULL; 2046 2047 if ((ptr = strrchr(gn->path, '/')) != NULL) 2048 ptr++; 2049 else 2050 ptr = gn->path; 2051 2052 Var_Set(PREFIX, ptr, gn); 2053 } 2054 } 2055 } else { 2056 /* 2057 * Not appropriate to search for the thing -- set the 2058 * path to be the name so Dir_MTime won't go grovelling for 2059 * it. 2060 */ 2061 if (gn->suffix) 2062 gn->suffix->refCount--; 2063 gn->suffix = (targ == NULL) ? NULL : targ->suff; 2064 if (gn->suffix) 2065 gn->suffix->refCount++; 2066 efree(gn->path); 2067 gn->path = estrdup(gn->name); 2068 } 2069 2070 goto sfnd_return; 2069 2071 } 2070 2072 … … 2075 2077 */ 2076 2078 if (targ->suff->flags & SUFF_LIBRARY) { 2077 2079 gn->type |= OP_LIB; 2078 2080 } 2079 2081 #endif … … 2083 2085 */ 2084 2086 if (!Lst_IsEmpty(gn->children)) { 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2087 src = SuffFindCmds(targ, slst); 2088 2089 if (src != (Src *)NULL) { 2090 /* 2091 * Free up all the Src structures in the transformation path 2092 * up to, but not including, the parent node. 2093 */ 2094 while (bottom && bottom->parent != NULL) { 2095 if (Lst_Member(slst, (ClientData) bottom) == NILLNODE) { 2096 Lst_AtEnd(slst, (ClientData) bottom); 2097 } 2098 bottom = bottom->parent; 2099 } 2100 bottom = src; 2101 } 2100 2102 } 2101 2103 2102 2104 if (bottom == NULL) { 2103 2104 2105 2106 2105 /* 2106 * No idea from where it can come -- return now. 2107 */ 2108 goto sfnd_abort; 2107 2109 } 2108 2110 … … 2120 2122 */ 2121 2123 if (bottom->node == NILGNODE) { 2122 2124 bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); 2123 2125 } 2124 2126 2125 2127 for (src = bottom; src->parent != (Src *)NULL; src = src->parent) { 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2128 targ = src->parent; 2129 2130 if (src->node->suffix) 2131 src->node->suffix->refCount--; 2132 src->node->suffix = src->suff; 2133 src->node->suffix->refCount++; 2134 2135 if (targ->node == NILGNODE) { 2136 targ->node = Targ_FindNode(targ->file, TARG_CREATE); 2137 } 2138 2139 SuffApplyTransform(targ->node, src->node, 2140 targ->suff, src->suff); 2141 2142 if (targ->node != gn) { 2143 /* 2144 * Finish off the dependency-search process for any nodes 2145 * between bottom and gn (no point in questing around the 2146 * filesystem for their implicit source when it's already 2147 * known). Note that the node can't have any sources that 2148 * need expanding, since SuffFindThem will stop on an existing 2149 * node, so all we need to do is set the standard and System V 2150 * variables. 2151 */ 2152 targ->node->type |= OP_DEPS_FOUND; 2153 2154 Var_Set(PREFIX, targ->pref, targ->node); 2155 2156 Var_Set(TARGET, targ->node->name, targ->node); 2157 } 2156 2158 } 2157 2159 2158 2160 if (gn->suffix) 2159 2161 gn->suffix->refCount--; 2160 2162 gn->suffix = src->suff; 2161 2163 gn->suffix->refCount++; … … 2173 2175 sfnd_return: 2174 2176 if (bottom) 2175 2176 2177 if (Lst_Member(slst, (ClientData) bottom) == NILLNODE) 2178 Lst_AtEnd(slst, (ClientData) bottom); 2177 2179 2178 2180 while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs)) 2179 2181 continue; 2180 2182 2181 2183 Lst_Concat(slst, srcs, LST_CONCLINK); … … 2187 2189 *----------------------------------------------------------------------- 2188 2190 * Suff_FindDeps -- 2189 * 2190 * 2191 * 2192 * Results: 2193 * 2194 * 2195 * Side Effects: 2196 * 2197 * 2198 * 2199 * 2191 * Find implicit sources for the target described by the graph node 2192 * gn 2193 * 2194 * Results: 2195 * Nothing. 2196 * 2197 * Side Effects: 2198 * Nodes are added to the graph below the passed-in node. The nodes 2199 * are marked to have their IMPSRC variable filled in. The 2200 * PREFIX variable is set for the given node and all its 2201 * implied children. 2200 2202 * 2201 2203 * Notes: 2202 * 2203 * 2204 * 2205 * 2206 * 2207 * 2208 * 2209 * 2204 * The path found by this target is the shortest path in the 2205 * transformation graph, which may pass through non-existent targets, 2206 * to an existing target. The search continues on all paths from the 2207 * root suffix until a file is found. I.e. if there's a path 2208 * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but 2209 * the .c and .l files don't, the search will branch out in 2210 * all directions from .o and again from all the nodes on the 2211 * next level until the .l,v node is encountered. 2210 2212 * 2211 2213 *----------------------------------------------------------------------- … … 2219 2221 SuffFindDeps(gn, srclist); 2220 2222 while (SuffRemoveSrc(srclist)) 2221 2223 continue; 2222 2224 } 2223 2225 … … 2225 2227 static void 2226 2228 SuffFindDeps (gn, slst) 2227 GNode *gn; 2228 Lst 2229 GNode *gn; /* node we're dealing with */ 2230 Lst slst; 2229 2231 { 2230 2232 if (gn->type & OP_DEPS_FOUND) { 2231 2232 2233 2234 2233 /* 2234 * If dependencies already found, no need to do it again... 2235 */ 2236 return; 2235 2237 } else { 2236 2238 gn->type |= OP_DEPS_FOUND; 2237 2239 } 2238 2240 2239 2241 if (DEBUG(SUFF)) { 2240 2242 printf ("SuffFindDeps (%s)\n", gn->name); 2241 2243 } 2242 2244 2243 2245 #ifdef USE_ARCHIVES 2244 2246 if (gn->type & OP_ARCHV) { 2245 2247 SuffFindArchiveDeps(gn, slst); 2246 2248 } else if (gn->type & OP_LIB) { 2247 2248 2249 2250 2251 2252 2253 2254 2255 LstNodeln;2256 Suff*s;2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2249 /* 2250 * If the node is a library, it is the arch module's job to find it 2251 * and set the TARGET variable accordingly. We merely provide the 2252 * search path, assuming all libraries end in ".a" (if the suffix 2253 * hasn't been defined, there's nothing we can do for it, so we just 2254 * set the TARGET variable to the node's name in order to give it a 2255 * value). 2256 */ 2257 LstNode ln; 2258 Suff *s; 2259 2260 ln = Lst_Find (sufflist, (ClientData)LIBSUFF, SuffSuffHasNameP); 2261 if (gn->suffix) 2262 gn->suffix->refCount--; 2263 if (ln != NILLNODE) { 2264 gn->suffix = s = (Suff *) Lst_Datum (ln); 2265 gn->suffix->refCount++; 2266 Arch_FindLib (gn, s->searchPath); 2267 } else { 2268 gn->suffix = NULL; 2269 Var_Set (TARGET, gn->name, gn); 2270 } 2271 /* 2272 * Because a library (-lfoo) target doesn't follow the standard 2273 * filesystem conventions, we don't set the regular variables for 2274 * the thing. .PREFIX is simply made empty... 2275 */ 2276 Var_Set(PREFIX, "", gn); 2275 2277 } else 2276 2278 #endif /* USE_ARCHIVES */ 2277 2279 SuffFindNormalDeps(gn, slst); 2278 2280 } 2279 2281 … … 2281 2283 *----------------------------------------------------------------------- 2282 2284 * Suff_SetNull -- 2283 * 2284 * 2285 * Results: 2286 * 2287 * 2288 * Side Effects: 2289 * 2285 * Define which suffix is the null suffix. 2286 * 2287 * Results: 2288 * None. 2289 * 2290 * Side Effects: 2291 * 'suffNull' is altered. 2290 2292 * 2291 2293 * Notes: 2292 * 2293 * 2294 * Need to handle the changing of the null suffix gracefully so the 2295 * old transformation rules don't just go away. 2294 2296 * 2295 2297 *----------------------------------------------------------------------- … … 2297 2299 void 2298 2300 Suff_SetNull(name) 2299 char *name; 2301 char *name; /* Name of null suffix */ 2300 2302 { 2301 2303 Suff *s; … … 2304 2306 ln = Lst_Find(sufflist, (ClientData)name, SuffSuffHasNameP); 2305 2307 if (ln != NILLNODE) { 2306 2307 2308 2309 2310 2311 2312 2313 2314 2308 s = (Suff *)Lst_Datum(ln); 2309 if (suffNull != (Suff *)NULL) { 2310 suffNull->flags &= ~SUFF_NULL; 2311 } 2312 s->flags |= SUFF_NULL; 2313 /* 2314 * XXX: Here's where the transformation mangling would take place 2315 */ 2316 suffNull = s; 2315 2317 } else { 2316 2317 2318 Parse_Error (PARSE_WARNING, "Desired null suffix %s not defined.", 2319 name); 2318 2320 } 2319 2321 } … … 2322 2324 *----------------------------------------------------------------------- 2323 2325 * Suff_Init -- 2324 * 2325 * 2326 * Results: 2327 * 2328 * 2329 * Side Effects: 2330 * 2326 * Initialize suffixes module 2327 * 2328 * Results: 2329 * None 2330 * 2331 * Side Effects: 2332 * Many 2331 2333 *----------------------------------------------------------------------- 2332 2334 */ … … 2347 2349 emptySuff = suffNull = (Suff *) emalloc (sizeof (Suff)); 2348 2350 2349 suffNull->name = 2351 suffNull->name = estrdup (""); 2350 2352 suffNull->nameLen = 0; 2351 2353 suffNull->searchPath = Lst_Init (FALSE); 2352 2354 Dir_Concat(suffNull->searchPath, dirSearchPath); 2353 2355 suffNull->children = Lst_Init (FALSE); 2354 suffNull->parents = 2355 suffNull->ref = 2356 suffNull->sNum = 2357 suffNull->flags = 2356 suffNull->parents = Lst_Init (FALSE); 2357 suffNull->ref = Lst_Init (FALSE); 2358 suffNull->sNum = sNum++; 2359 suffNull->flags = SUFF_NULL; 2358 2360 suffNull->refCount = 1; 2359 2361 … … 2364 2366 *---------------------------------------------------------------------- 2365 2367 * Suff_End -- 2366 * 2367 * 2368 * Results: 2369 * 2370 * 2371 * Side Effects: 2372 * 2368 * Cleanup the this module 2369 * 2370 * Results: 2371 * None 2372 * 2373 * Side Effects: 2374 * The memory is efree'd. 2373 2375 *---------------------------------------------------------------------- 2374 2376 */ … … 2380 2382 Lst_Destroy(suffClean, SuffFree); 2381 2383 if (suffNull) 2382 2384 SuffFree(suffNull); 2383 2385 Lst_Destroy(srclist, NOFREE); 2384 2386 Lst_Destroy(transforms, NOFREE); … … 2402 2404 { 2403 2405 Suff *s = (Suff *) sp; 2404 int 2405 int 2406 int flags; 2407 int flag; 2406 2408 2407 2409 printf ("# `%s' [%d] ", s->name, s->refCount); … … 2409 2411 flags = s->flags; 2410 2412 if (flags) { 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2413 fputs (" (", stdout); 2414 while (flags) { 2415 flag = 1 << (ffs(flags) - 1); 2416 flags &= ~flag; 2417 switch (flag) { 2418 case SUFF_NULL: 2419 printf ("NULL"); 2420 break; 2421 case SUFF_INCLUDE: 2422 printf ("INCLUDE"); 2423 break; 2422 2424 #ifdef USE_ARCHIVES 2423 2424 2425 2425 case SUFF_LIBRARY: 2426 printf ("LIBRARY"); 2427 break; 2426 2428 #endif 2427 2428 2429 2429 } 2430 fputc(flags ? '|' : ')', stdout); 2431 } 2430 2432 } 2431 2433 fputc ('\n', stdout);
Note:
See TracChangeset
for help on using the changeset viewer.