1 /* $NetBSD: suff.c,v 1.96 2020/08/11 18:44:52 rillig Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * Copyright (c) 1989 by Berkeley Softworks 37 * All rights reserved. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * Adam de Boor. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the University of 53 * California, Berkeley and its contributors. 54 * 4. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 */ 70 71 #ifndef MAKE_NATIVE 72 static char rcsid[] = "$NetBSD: suff.c,v 1.96 2020/08/11 18:44:52 rillig Exp $"; 73 #else 74 #include <sys/cdefs.h> 75 #ifndef lint 76 #if 0 77 static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94"; 78 #else 79 __RCSID("$NetBSD: suff.c,v 1.96 2020/08/11 18:44:52 rillig Exp $"); 80 #endif 81 #endif /* not lint */ 82 #endif 83 84 /*- 85 * suff.c -- 86 * Functions to maintain suffix lists and find implicit dependents 87 * using suffix transformation rules 88 * 89 * Interface: 90 * Suff_Init Initialize all things to do with suffixes. 91 * 92 * Suff_End Cleanup the module 93 * 94 * Suff_DoPaths This function is used to make life easier 95 * when searching for a file according to its 96 * suffix. It takes the global search path, 97 * as defined using the .PATH: target, and appends 98 * its directories to the path of each of the 99 * defined suffixes, as specified using 100 * .PATH<suffix>: targets. In addition, all 101 * directories given for suffixes labeled as 102 * include files or libraries, using the .INCLUDES 103 * or .LIBS targets, are played with using 104 * Dir_MakeFlags to create the .INCLUDES and 105 * .LIBS global variables. 106 * 107 * Suff_ClearSuffixes Clear out all the suffixes and defined 108 * transformations. 109 * 110 * Suff_IsTransform Return TRUE if the passed string is the lhs 111 * of a transformation rule. 112 * 113 * Suff_AddSuffix Add the passed string as another known suffix. 114 * 115 * Suff_GetPath Return the search path for the given suffix. 116 * 117 * Suff_AddInclude Mark the given suffix as denoting an include 118 * file. 119 * 120 * Suff_AddLib Mark the given suffix as denoting a library. 121 * 122 * Suff_AddTransform Add another transformation to the suffix 123 * graph. Returns GNode suitable for framing, I 124 * mean, tacking commands, attributes, etc. on. 125 * 126 * Suff_SetNull Define the suffix to consider the suffix of 127 * any file that doesn't have a known one. 128 * 129 * Suff_FindDeps Find implicit sources for and the location of 130 * a target based on its suffix. Returns the 131 * bottom-most node added to the graph or NULL 132 * if the target had no implicit sources. 133 * 134 * Suff_FindPath Return the appropriate path to search in 135 * order to find the node. 136 */ 137 138 #include <assert.h> 139 #include <stdio.h> 140 #include "make.h" 141 #include "hash.h" 142 #include "dir.h" 143 144 static Lst sufflist; /* Lst of suffixes */ 145 #ifdef CLEANUP 146 static Lst suffClean; /* Lst of suffixes to be cleaned */ 147 #endif 148 static Lst srclist; /* Lst of sources */ 149 static Lst transforms; /* Lst of transformation rules */ 150 151 static int sNum = 0; /* Counter for assigning suffix numbers */ 152 153 typedef enum { 154 SUFF_INCLUDE = 0x01, /* One which is #include'd */ 155 SUFF_LIBRARY = 0x02, /* One which contains a library */ 156 SUFF_NULL = 0x04 /* The empty suffix */ 157 } SuffFlags; 158 159 /* 160 * Structure describing an individual suffix. 161 */ 162 typedef struct Suff { 163 char *name; /* The suffix itself */ 164 int nameLen; /* Length of the suffix */ 165 SuffFlags flags; /* Type of suffix */ 166 Lst searchPath; /* The path along which files of this suffix 167 * may be found */ 168 int sNum; /* The suffix number */ 169 int refCount; /* Reference count of list membership */ 170 Lst parents; /* Suffixes we have a transformation to */ 171 Lst children; /* Suffixes we have a transformation from */ 172 Lst ref; /* List of lists this suffix is referenced */ 173 } Suff; 174 175 /* 176 * for SuffSuffIsSuffix 177 */ 178 typedef struct { 179 char *ename; /* The end of the name */ 180 int len; /* Length of the name */ 181 } SuffixCmpData; 182 183 /* 184 * Structure used in the search for implied sources. 185 */ 186 typedef struct _Src { 187 char *file; /* The file to look for */ 188 char *pref; /* Prefix from which file was formed */ 189 Suff *suff; /* The suffix on the file */ 190 struct _Src *parent; /* The Src for which this is a source */ 191 GNode *node; /* The node describing the file */ 192 int children; /* Count of existing children (so we don't free 193 * this thing too early or never nuke it) */ 194 #ifdef DEBUG_SRC 195 Lst cp; /* Debug; children list */ 196 #endif 197 } Src; 198 199 /* 200 * A structure for passing more than one argument to the Lst-library-invoked 201 * function... 202 */ 203 typedef struct { 204 Lst l; 205 Src *s; 206 } LstSrc; 207 208 typedef struct { 209 GNode **gn; 210 Suff *s; 211 Boolean r; 212 } GNodeSuff; 213 214 static Suff *suffNull; /* The NULL suffix for this run */ 215 static Suff *emptySuff; /* The empty suffix required for POSIX 216 * single-suffix transformation rules */ 217 218 219 static const char *SuffStrIsPrefix(const char *, const char *); 220 static char *SuffSuffIsSuffix(const Suff *, const SuffixCmpData *); 221 static int SuffSuffIsSuffixP(const void *, const void *); 222 static int SuffSuffHasNameP(const void *, const void *); 223 static int SuffSuffIsPrefix(const void *, const void *); 224 static int SuffGNHasNameP(const void *, const void *); 225 static void SuffUnRef(void *, void *); 226 static void SuffFree(void *); 227 static void SuffInsert(Lst, Suff *); 228 static void SuffRemove(Lst, Suff *); 229 static Boolean SuffParseTransform(char *, Suff **, Suff **); 230 static int SuffRebuildGraph(void *, void *); 231 static int SuffScanTargets(void *, void *); 232 static int SuffAddSrc(void *, void *); 233 static int SuffRemoveSrc(Lst); 234 static void SuffAddLevel(Lst, Src *); 235 static Src *SuffFindThem(Lst, Lst); 236 static Src *SuffFindCmds(Src *, Lst); 237 static void SuffExpandChildren(LstNode, GNode *); 238 static void SuffExpandWildcards(LstNode, GNode *); 239 static Boolean SuffApplyTransform(GNode *, GNode *, Suff *, Suff *); 240 static void SuffFindDeps(GNode *, Lst); 241 static void SuffFindArchiveDeps(GNode *, Lst); 242 static void SuffFindNormalDeps(GNode *, Lst); 243 static int SuffPrintName(void *, void *); 244 static int SuffPrintSuff(void *, void *); 245 static int SuffPrintTrans(void *, void *); 246 247 /*************** Lst Predicates ****************/ 248 /*- 249 *----------------------------------------------------------------------- 250 * SuffStrIsPrefix -- 251 * See if pref is a prefix of str. 252 * 253 * Input: 254 * pref possible prefix 255 * str string to check 256 * 257 * Results: 258 * NULL if it ain't, pointer to character in str after prefix if so 259 * 260 * Side Effects: 261 * None 262 *----------------------------------------------------------------------- 263 */ 264 static const char * 265 SuffStrIsPrefix(const char *pref, const char *str) 266 { 267 while (*str && *pref == *str) { 268 pref++; 269 str++; 270 } 271 272 return *pref ? NULL : str; 273 } 274 275 /*- 276 *----------------------------------------------------------------------- 277 * SuffSuffIsSuffix -- 278 * See if suff is a suffix of str. sd->ename should point to THE END 279 * of the string to check. (THE END == the null byte) 280 * 281 * Input: 282 * s possible suffix 283 * sd string to examine 284 * 285 * Results: 286 * NULL if it ain't, pointer to character in str before suffix if 287 * it is. 288 * 289 * Side Effects: 290 * None 291 *----------------------------------------------------------------------- 292 */ 293 static char * 294 SuffSuffIsSuffix(const Suff *s, const SuffixCmpData *sd) 295 { 296 char *p1; /* Pointer into suffix name */ 297 char *p2; /* Pointer into string being examined */ 298 299 if (sd->len < s->nameLen) 300 return NULL; /* this string is shorter than the suffix */ 301 302 p1 = s->name + s->nameLen; 303 p2 = sd->ename; 304 305 while (p1 >= s->name && *p1 == *p2) { 306 p1--; 307 p2--; 308 } 309 310 return p1 == s->name - 1 ? p2 : NULL; 311 } 312 313 /*- 314 *----------------------------------------------------------------------- 315 * SuffSuffIsSuffixP -- 316 * Predicate form of SuffSuffIsSuffix. Passed as the callback function 317 * to Lst_Find. 318 * 319 * Results: 320 * 0 if the suffix is the one desired, non-zero if not. 321 * 322 * Side Effects: 323 * None. 324 * 325 *----------------------------------------------------------------------- 326 */ 327 static int 328 SuffSuffIsSuffixP(const void *s, const void *sd) 329 { 330 return !SuffSuffIsSuffix(s, sd); 331 } 332 333 /*- 334 *----------------------------------------------------------------------- 335 * SuffSuffHasNameP -- 336 * Callback procedure for finding a suffix based on its name. Used by 337 * Suff_GetPath. 338 * 339 * Input: 340 * s Suffix to check 341 * sd Desired name 342 * 343 * Results: 344 * 0 if the suffix is of the given name. non-zero otherwise. 345 * 346 * Side Effects: 347 * None 348 *----------------------------------------------------------------------- 349 */ 350 static int 351 SuffSuffHasNameP(const void *s, const void *sname) 352 { 353 return strcmp(sname, ((const Suff *)s)->name); 354 } 355 356 /*- 357 *----------------------------------------------------------------------- 358 * SuffSuffIsPrefix -- 359 * See if the suffix described by s is a prefix of the string. Care 360 * must be taken when using this to search for transformations and 361 * what-not, since there could well be two suffixes, one of which 362 * is a prefix of the other... 363 * 364 * Input: 365 * s suffix to compare 366 * str string to examine 367 * 368 * Results: 369 * 0 if s is a prefix of str. non-zero otherwise 370 * 371 * Side Effects: 372 * None 373 *----------------------------------------------------------------------- 374 */ 375 static int 376 SuffSuffIsPrefix(const void *s, const void *str) 377 { 378 return SuffStrIsPrefix(((const Suff *)s)->name, str) == NULL; 379 } 380 381 /*- 382 *----------------------------------------------------------------------- 383 * SuffGNHasNameP -- 384 * See if the graph node has the desired name 385 * 386 * Input: 387 * gn current node we're looking at 388 * name name we're looking for 389 * 390 * Results: 391 * 0 if it does. non-zero if it doesn't 392 * 393 * Side Effects: 394 * None 395 *----------------------------------------------------------------------- 396 */ 397 static int 398 SuffGNHasNameP(const void *gn, const void *name) 399 { 400 return strcmp(name, ((const GNode *)gn)->name); 401 } 402 403 /*********** Maintenance Functions ************/ 404 405 static void 406 SuffUnRef(void *lp, void *sp) 407 { 408 Lst l = (Lst) lp; 409 410 LstNode ln = Lst_Member(l, sp); 411 if (ln != NULL) { 412 Lst_Remove(l, ln); 413 ((Suff *)sp)->refCount--; 414 } 415 } 416 417 /*- 418 *----------------------------------------------------------------------- 419 * SuffFree -- 420 * Free up all memory associated with the given suffix structure. 421 * 422 * Results: 423 * none 424 * 425 * Side Effects: 426 * the suffix entry is detroyed 427 *----------------------------------------------------------------------- 428 */ 429 static void 430 SuffFree(void *sp) 431 { 432 Suff *s = (Suff *)sp; 433 434 if (s == suffNull) 435 suffNull = NULL; 436 437 if (s == emptySuff) 438 emptySuff = NULL; 439 440 #ifdef notdef 441 /* We don't delete suffixes in order, so we cannot use this */ 442 if (s->refCount) 443 Punt("Internal error deleting suffix `%s' with refcount = %d", s->name, 444 s->refCount); 445 #endif 446 447 Lst_Destroy(s->ref, NULL); 448 Lst_Destroy(s->children, NULL); 449 Lst_Destroy(s->parents, NULL); 450 Lst_Destroy(s->searchPath, Dir_Destroy); 451 452 free(s->name); 453 free(s); 454 } 455 456 /*- 457 *----------------------------------------------------------------------- 458 * SuffRemove -- 459 * Remove the suffix into the list 460 * 461 * Results: 462 * None 463 * 464 * Side Effects: 465 * The reference count for the suffix is decremented and the 466 * suffix is possibly freed 467 *----------------------------------------------------------------------- 468 */ 469 static void 470 SuffRemove(Lst l, Suff *s) 471 { 472 SuffUnRef(l, s); 473 if (s->refCount == 0) { 474 SuffUnRef(sufflist, s); 475 SuffFree(s); 476 } 477 } 478 479 /*- 480 *----------------------------------------------------------------------- 481 * SuffInsert -- 482 * Insert the suffix into the list keeping the list ordered by suffix 483 * numbers. 484 * 485 * Input: 486 * l the list where in s should be inserted 487 * s the suffix to insert 488 * 489 * Results: 490 * None 491 * 492 * Side Effects: 493 * The reference count of the suffix is incremented 494 *----------------------------------------------------------------------- 495 */ 496 static void 497 SuffInsert(Lst l, Suff *s) 498 { 499 LstNode ln; /* current element in l we're examining */ 500 Suff *s2 = NULL; /* the suffix descriptor in this element */ 501 502 if (Lst_Open(l) == FAILURE) { 503 return; 504 } 505 while ((ln = Lst_Next(l)) != NULL) { 506 s2 = (Suff *)Lst_Datum(ln); 507 if (s2->sNum >= s->sNum) { 508 break; 509 } 510 } 511 512 Lst_Close(l); 513 if (DEBUG(SUFF)) { 514 fprintf(debug_file, "inserting %s(%d)...", s->name, s->sNum); 515 } 516 if (ln == NULL) { 517 if (DEBUG(SUFF)) { 518 fprintf(debug_file, "at end of list\n"); 519 } 520 (void)Lst_AtEnd(l, s); 521 s->refCount++; 522 (void)Lst_AtEnd(s->ref, l); 523 } else if (s2->sNum != s->sNum) { 524 if (DEBUG(SUFF)) { 525 fprintf(debug_file, "before %s(%d)\n", s2->name, s2->sNum); 526 } 527 (void)Lst_InsertBefore(l, ln, s); 528 s->refCount++; 529 (void)Lst_AtEnd(s->ref, l); 530 } else if (DEBUG(SUFF)) { 531 fprintf(debug_file, "already there\n"); 532 } 533 } 534 535 /*- 536 *----------------------------------------------------------------------- 537 * Suff_ClearSuffixes -- 538 * This is gross. Nuke the list of suffixes but keep all transformation 539 * rules around. The transformation graph is destroyed in this process, 540 * but we leave the list of rules so when a new graph is formed the rules 541 * will remain. 542 * This function is called from the parse module when a 543 * .SUFFIXES:\n line is encountered. 544 * 545 * Results: 546 * none 547 * 548 * Side Effects: 549 * the sufflist and its graph nodes are destroyed 550 *----------------------------------------------------------------------- 551 */ 552 void 553 Suff_ClearSuffixes(void) 554 { 555 #ifdef CLEANUP 556 Lst_Concat(suffClean, sufflist, LST_CONCLINK); 557 #endif 558 sufflist = Lst_Init(FALSE); 559 sNum = 0; 560 if (suffNull) 561 SuffFree(suffNull); 562 emptySuff = suffNull = bmake_malloc(sizeof(Suff)); 563 564 suffNull->name = bmake_strdup(""); 565 suffNull->nameLen = 0; 566 suffNull->searchPath = Lst_Init(FALSE); 567 Dir_Concat(suffNull->searchPath, dirSearchPath); 568 suffNull->children = Lst_Init(FALSE); 569 suffNull->parents = Lst_Init(FALSE); 570 suffNull->ref = Lst_Init(FALSE); 571 suffNull->sNum = sNum++; 572 suffNull->flags = SUFF_NULL; 573 suffNull->refCount = 1; 574 } 575 576 /*- 577 *----------------------------------------------------------------------- 578 * SuffParseTransform -- 579 * Parse a transformation string to find its two component suffixes. 580 * 581 * Input: 582 * str String being parsed 583 * srcPtr Place to store source of trans. 584 * targPtr Place to store target of trans. 585 * 586 * Results: 587 * TRUE if the string is a valid transformation and FALSE otherwise. 588 * 589 * Side Effects: 590 * The passed pointers are overwritten. 591 * 592 *----------------------------------------------------------------------- 593 */ 594 static Boolean 595 SuffParseTransform(char *str, Suff **srcPtr, Suff **targPtr) 596 { 597 LstNode srcLn; /* element in suffix list of trans source*/ 598 Suff *src; /* Source of transformation */ 599 LstNode targLn; /* element in suffix list of trans target*/ 600 char *str2; /* Extra pointer (maybe target suffix) */ 601 LstNode singleLn; /* element in suffix list of any suffix 602 * that exactly matches str */ 603 Suff *single = NULL;/* Source of possible transformation to 604 * null suffix */ 605 606 srcLn = NULL; 607 singleLn = NULL; 608 609 /* 610 * Loop looking first for a suffix that matches the start of the 611 * string and then for one that exactly matches the rest of it. If 612 * we can find two that meet these criteria, we've successfully 613 * parsed the string. 614 */ 615 for (;;) { 616 if (srcLn == NULL) { 617 srcLn = Lst_Find(sufflist, str, SuffSuffIsPrefix); 618 } else { 619 srcLn = Lst_FindFrom(sufflist, Lst_Succ(srcLn), str, 620 SuffSuffIsPrefix); 621 } 622 if (srcLn == NULL) { 623 /* 624 * Ran out of source suffixes -- no such rule 625 */ 626 if (singleLn != NULL) { 627 /* 628 * Not so fast Mr. Smith! There was a suffix that encompassed 629 * the entire string, so we assume it was a transformation 630 * to the null suffix (thank you POSIX). We still prefer to 631 * find a double rule over a singleton, hence we leave this 632 * check until the end. 633 * 634 * XXX: Use emptySuff over suffNull? 635 */ 636 *srcPtr = single; 637 *targPtr = suffNull; 638 return TRUE; 639 } 640 return FALSE; 641 } 642 src = (Suff *)Lst_Datum(srcLn); 643 str2 = str + src->nameLen; 644 if (*str2 == '\0') { 645 single = src; 646 singleLn = srcLn; 647 } else { 648 targLn = Lst_Find(sufflist, str2, SuffSuffHasNameP); 649 if (targLn != NULL) { 650 *srcPtr = src; 651 *targPtr = (Suff *)Lst_Datum(targLn); 652 return TRUE; 653 } 654 } 655 } 656 } 657 658 /*- 659 *----------------------------------------------------------------------- 660 * Suff_IsTransform -- 661 * Return TRUE if the given string is a transformation rule 662 * 663 * 664 * Input: 665 * str string to check 666 * 667 * Results: 668 * TRUE if the string is a concatenation of two known suffixes. 669 * FALSE otherwise 670 * 671 * Side Effects: 672 * None 673 *----------------------------------------------------------------------- 674 */ 675 Boolean 676 Suff_IsTransform(char *str) 677 { 678 Suff *src, *targ; 679 680 return SuffParseTransform(str, &src, &targ); 681 } 682 683 /*- 684 *----------------------------------------------------------------------- 685 * Suff_AddTransform -- 686 * Add the transformation rule described by the line to the 687 * list of rules and place the transformation itself in the graph 688 * 689 * Input: 690 * line name of transformation to add 691 * 692 * Results: 693 * The node created for the transformation in the transforms list 694 * 695 * Side Effects: 696 * The node is placed on the end of the transforms Lst and links are 697 * made between the two suffixes mentioned in the target name 698 *----------------------------------------------------------------------- 699 */ 700 GNode * 701 Suff_AddTransform(char *line) 702 { 703 GNode *gn; /* GNode of transformation rule */ 704 Suff *s, /* source suffix */ 705 *t; /* target suffix */ 706 LstNode ln; /* Node for existing transformation */ 707 708 ln = Lst_Find(transforms, line, SuffGNHasNameP); 709 if (ln == NULL) { 710 /* 711 * Make a new graph node for the transformation. It will be filled in 712 * by the Parse module. 713 */ 714 gn = Targ_NewGN(line); 715 (void)Lst_AtEnd(transforms, gn); 716 } else { 717 /* 718 * New specification for transformation rule. Just nuke the old list 719 * of commands so they can be filled in again... We don't actually 720 * free the commands themselves, because a given command can be 721 * attached to several different transformations. 722 */ 723 gn = (GNode *)Lst_Datum(ln); 724 Lst_Destroy(gn->commands, NULL); 725 Lst_Destroy(gn->children, NULL); 726 gn->commands = Lst_Init(FALSE); 727 gn->children = Lst_Init(FALSE); 728 } 729 730 gn->type = OP_TRANSFORM; 731 732 (void)SuffParseTransform(line, &s, &t); 733 734 /* 735 * link the two together in the proper relationship and order 736 */ 737 if (DEBUG(SUFF)) { 738 fprintf(debug_file, "defining transformation from `%s' to `%s'\n", 739 s->name, t->name); 740 } 741 SuffInsert(t->children, s); 742 SuffInsert(s->parents, t); 743 744 return gn; 745 } 746 747 /*- 748 *----------------------------------------------------------------------- 749 * Suff_EndTransform -- 750 * Handle the finish of a transformation definition, removing the 751 * transformation from the graph if it has neither commands nor 752 * sources. This is a callback procedure for the Parse module via 753 * Lst_ForEach 754 * 755 * Input: 756 * gnp Node for transformation 757 * dummy Node for transformation 758 * 759 * Results: 760 * === 0 761 * 762 * Side Effects: 763 * If the node has no commands or children, the children and parents 764 * lists of the affected suffixes are altered. 765 * 766 *----------------------------------------------------------------------- 767 */ 768 int 769 Suff_EndTransform(void *gnp, void *dummy MAKE_ATTR_UNUSED) 770 { 771 GNode *gn = (GNode *)gnp; 772 773 if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) 774 gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts)); 775 if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) && 776 Lst_IsEmpty(gn->children)) 777 { 778 Suff *s, *t; 779 780 /* 781 * SuffParseTransform() may fail for special rules which are not 782 * actual transformation rules. (e.g. .DEFAULT) 783 */ 784 if (SuffParseTransform(gn->name, &s, &t)) { 785 Lst p; 786 787 if (DEBUG(SUFF)) { 788 fprintf(debug_file, "deleting transformation from `%s' to `%s'\n", 789 s->name, t->name); 790 } 791 792 /* 793 * Store s->parents because s could be deleted in SuffRemove 794 */ 795 p = s->parents; 796 797 /* 798 * Remove the source from the target's children list. We check for a 799 * nil return to handle a beanhead saying something like 800 * .c.o .c.o: 801 * 802 * We'll be called twice when the next target is seen, but .c and .o 803 * are only linked once... 804 */ 805 SuffRemove(t->children, s); 806 807 /* 808 * Remove the target from the source's parents list 809 */ 810 SuffRemove(p, t); 811 } 812 } else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { 813 fprintf(debug_file, "transformation %s complete\n", gn->name); 814 } 815 816 return 0; 817 } 818 819 /*- 820 *----------------------------------------------------------------------- 821 * SuffRebuildGraph -- 822 * Called from Suff_AddSuffix via Lst_ForEach to search through the 823 * list of existing transformation rules and rebuild the transformation 824 * graph when it has been destroyed by Suff_ClearSuffixes. If the 825 * given rule is a transformation involving this suffix and another, 826 * existing suffix, the proper relationship is established between 827 * the two. 828 * 829 * Input: 830 * transformp Transformation to test 831 * sp Suffix to rebuild 832 * 833 * Results: 834 * Always 0. 835 * 836 * Side Effects: 837 * The appropriate links will be made between this suffix and 838 * others if transformation rules exist for it. 839 * 840 *----------------------------------------------------------------------- 841 */ 842 static int 843 SuffRebuildGraph(void *transformp, void *sp) 844 { 845 GNode *transform = (GNode *)transformp; 846 Suff *s = (Suff *)sp; 847 char *cp; 848 LstNode ln; 849 Suff *s2; 850 SuffixCmpData sd; 851 852 /* 853 * First see if it is a transformation from this suffix. 854 */ 855 cp = UNCONST(SuffStrIsPrefix(s->name, transform->name)); 856 if (cp != NULL) { 857 ln = Lst_Find(sufflist, cp, SuffSuffHasNameP); 858 if (ln != NULL) { 859 /* 860 * Found target. Link in and return, since it can't be anything 861 * else. 862 */ 863 s2 = (Suff *)Lst_Datum(ln); 864 SuffInsert(s2->children, s); 865 SuffInsert(s->parents, s2); 866 return 0; 867 } 868 } 869 870 /* 871 * Not from, maybe to? 872 */ 873 sd.len = strlen(transform->name); 874 sd.ename = transform->name + sd.len; 875 cp = SuffSuffIsSuffix(s, &sd); 876 if (cp != NULL) { 877 /* 878 * Null-terminate the source suffix in order to find it. 879 */ 880 cp[1] = '\0'; 881 ln = Lst_Find(sufflist, transform->name, SuffSuffHasNameP); 882 /* 883 * Replace the start of the target suffix 884 */ 885 cp[1] = s->name[0]; 886 if (ln != NULL) { 887 /* 888 * Found it -- establish the proper relationship 889 */ 890 s2 = (Suff *)Lst_Datum(ln); 891 SuffInsert(s->children, s2); 892 SuffInsert(s2->parents, s); 893 } 894 } 895 return 0; 896 } 897 898 /*- 899 *----------------------------------------------------------------------- 900 * SuffScanTargets -- 901 * Called from Suff_AddSuffix via Lst_ForEach to search through the 902 * list of existing targets and find if any of the existing targets 903 * can be turned into a transformation rule. 904 * 905 * Results: 906 * 1 if a new main target has been selected, 0 otherwise. 907 * 908 * Side Effects: 909 * If such a target is found and the target is the current main 910 * target, the main target is set to NULL and the next target 911 * examined (if that exists) becomes the main target. 912 * 913 *----------------------------------------------------------------------- 914 */ 915 static int 916 SuffScanTargets(void *targetp, void *gsp) 917 { 918 GNode *target = (GNode *)targetp; 919 GNodeSuff *gs = (GNodeSuff *)gsp; 920 Suff *s, *t; 921 char *ptr; 922 923 if (*gs->gn == NULL && gs->r && (target->type & OP_NOTARGET) == 0) { 924 *gs->gn = target; 925 Targ_SetMain(target); 926 return 1; 927 } 928 929 if ((unsigned int)target->type == OP_TRANSFORM) 930 return 0; 931 932 if ((ptr = strstr(target->name, gs->s->name)) == NULL || 933 ptr == target->name) 934 return 0; 935 936 if (SuffParseTransform(target->name, &s, &t)) { 937 if (*gs->gn == target) { 938 gs->r = TRUE; 939 *gs->gn = NULL; 940 Targ_SetMain(NULL); 941 } 942 Lst_Destroy(target->children, NULL); 943 target->children = Lst_Init(FALSE); 944 target->type = OP_TRANSFORM; 945 /* 946 * link the two together in the proper relationship and order 947 */ 948 if (DEBUG(SUFF)) { 949 fprintf(debug_file, "defining transformation from `%s' to `%s'\n", 950 s->name, t->name); 951 } 952 SuffInsert(t->children, s); 953 SuffInsert(s->parents, t); 954 } 955 return 0; 956 } 957 958 /*- 959 *----------------------------------------------------------------------- 960 * Suff_AddSuffix -- 961 * Add the suffix in string to the end of the list of known suffixes. 962 * Should we restructure the suffix graph? Make doesn't... 963 * 964 * Input: 965 * str the name of the suffix to add 966 * 967 * Results: 968 * None 969 * 970 * Side Effects: 971 * A GNode is created for the suffix and a Suff structure is created and 972 * added to the suffixes list unless the suffix was already known. 973 * The mainNode passed can be modified if a target mutated into a 974 * transform and that target happened to be the main target. 975 *----------------------------------------------------------------------- 976 */ 977 void 978 Suff_AddSuffix(char *str, GNode **gn) 979 { 980 Suff *s; /* new suffix descriptor */ 981 LstNode ln; 982 GNodeSuff gs; 983 984 ln = Lst_Find(sufflist, str, SuffSuffHasNameP); 985 if (ln == NULL) { 986 s = bmake_malloc(sizeof(Suff)); 987 988 s->name = bmake_strdup(str); 989 s->nameLen = strlen(s->name); 990 s->searchPath = Lst_Init(FALSE); 991 s->children = Lst_Init(FALSE); 992 s->parents = Lst_Init(FALSE); 993 s->ref = Lst_Init(FALSE); 994 s->sNum = sNum++; 995 s->flags = 0; 996 s->refCount = 1; 997 998 (void)Lst_AtEnd(sufflist, s); 999 /* 1000 * We also look at our existing targets list to see if adding 1001 * this suffix will make one of our current targets mutate into 1002 * a suffix rule. This is ugly, but other makes treat all targets 1003 * that start with a . as suffix rules. 1004 */ 1005 gs.gn = gn; 1006 gs.s = s; 1007 gs.r = FALSE; 1008 Lst_ForEach(Targ_List(), SuffScanTargets, &gs); 1009 /* 1010 * Look for any existing transformations from or to this suffix. 1011 * XXX: Only do this after a Suff_ClearSuffixes? 1012 */ 1013 Lst_ForEach(transforms, SuffRebuildGraph, s); 1014 } 1015 } 1016 1017 /*- 1018 *----------------------------------------------------------------------- 1019 * Suff_GetPath -- 1020 * Return the search path for the given suffix, if it's defined. 1021 * 1022 * Results: 1023 * The searchPath for the desired suffix or NULL if the suffix isn't 1024 * defined. 1025 * 1026 * Side Effects: 1027 * None 1028 *----------------------------------------------------------------------- 1029 */ 1030 Lst 1031 Suff_GetPath(char *sname) 1032 { 1033 LstNode ln; 1034 Suff *s; 1035 1036 ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); 1037 if (ln == NULL) { 1038 return NULL; 1039 } else { 1040 s = (Suff *)Lst_Datum(ln); 1041 return s->searchPath; 1042 } 1043 } 1044 1045 /*- 1046 *----------------------------------------------------------------------- 1047 * Suff_DoPaths -- 1048 * Extend the search paths for all suffixes to include the default 1049 * search path. 1050 * 1051 * Results: 1052 * None. 1053 * 1054 * Side Effects: 1055 * The searchPath field of all the suffixes is extended by the 1056 * directories in dirSearchPath. If paths were specified for the 1057 * ".h" suffix, the directories are stuffed into a global variable 1058 * called ".INCLUDES" with each directory preceded by a -I. The same 1059 * is done for the ".a" suffix, except the variable is called 1060 * ".LIBS" and the flag is -L. 1061 *----------------------------------------------------------------------- 1062 */ 1063 void 1064 Suff_DoPaths(void) 1065 { 1066 Suff *s; 1067 LstNode ln; 1068 char *ptr; 1069 Lst inIncludes; /* Cumulative .INCLUDES path */ 1070 Lst inLibs; /* Cumulative .LIBS path */ 1071 1072 if (Lst_Open(sufflist) == FAILURE) { 1073 return; 1074 } 1075 1076 inIncludes = Lst_Init(FALSE); 1077 inLibs = Lst_Init(FALSE); 1078 1079 while ((ln = Lst_Next(sufflist)) != NULL) { 1080 s = (Suff *)Lst_Datum(ln); 1081 if (!Lst_IsEmpty (s->searchPath)) { 1082 #ifdef INCLUDES 1083 if (s->flags & SUFF_INCLUDE) { 1084 Dir_Concat(inIncludes, s->searchPath); 1085 } 1086 #endif /* INCLUDES */ 1087 #ifdef LIBRARIES 1088 if (s->flags & SUFF_LIBRARY) { 1089 Dir_Concat(inLibs, s->searchPath); 1090 } 1091 #endif /* LIBRARIES */ 1092 Dir_Concat(s->searchPath, dirSearchPath); 1093 } else { 1094 Lst_Destroy(s->searchPath, Dir_Destroy); 1095 s->searchPath = Lst_Duplicate(dirSearchPath, Dir_CopyDir); 1096 } 1097 } 1098 1099 Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL); 1100 free(ptr); 1101 Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL); 1102 free(ptr); 1103 1104 Lst_Destroy(inIncludes, Dir_Destroy); 1105 Lst_Destroy(inLibs, Dir_Destroy); 1106 1107 Lst_Close(sufflist); 1108 } 1109 1110 /*- 1111 *----------------------------------------------------------------------- 1112 * Suff_AddInclude -- 1113 * Add the given suffix as a type of file which gets included. 1114 * Called from the parse module when a .INCLUDES line is parsed. 1115 * The suffix must have already been defined. 1116 * 1117 * Input: 1118 * sname Name of the suffix to mark 1119 * 1120 * Results: 1121 * None. 1122 * 1123 * Side Effects: 1124 * The SUFF_INCLUDE bit is set in the suffix's flags field 1125 * 1126 *----------------------------------------------------------------------- 1127 */ 1128 void 1129 Suff_AddInclude(char *sname) 1130 { 1131 LstNode ln; 1132 Suff *s; 1133 1134 ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); 1135 if (ln != NULL) { 1136 s = (Suff *)Lst_Datum(ln); 1137 s->flags |= SUFF_INCLUDE; 1138 } 1139 } 1140 1141 /*- 1142 *----------------------------------------------------------------------- 1143 * Suff_AddLib -- 1144 * Add the given suffix as a type of file which is a library. 1145 * Called from the parse module when parsing a .LIBS line. The 1146 * suffix must have been defined via .SUFFIXES before this is 1147 * called. 1148 * 1149 * Input: 1150 * sname Name of the suffix to mark 1151 * 1152 * Results: 1153 * None. 1154 * 1155 * Side Effects: 1156 * The SUFF_LIBRARY bit is set in the suffix's flags field 1157 * 1158 *----------------------------------------------------------------------- 1159 */ 1160 void 1161 Suff_AddLib(char *sname) 1162 { 1163 LstNode ln; 1164 Suff *s; 1165 1166 ln = Lst_Find(sufflist, sname, SuffSuffHasNameP); 1167 if (ln != NULL) { 1168 s = (Suff *)Lst_Datum(ln); 1169 s->flags |= SUFF_LIBRARY; 1170 } 1171 } 1172 1173 /********** Implicit Source Search Functions *********/ 1174 1175 /*- 1176 *----------------------------------------------------------------------- 1177 * SuffAddSrc -- 1178 * Add a suffix as a Src structure to the given list with its parent 1179 * being the given Src structure. If the suffix is the null suffix, 1180 * the prefix is used unaltered as the file name in the Src structure. 1181 * 1182 * Input: 1183 * sp suffix for which to create a Src structure 1184 * lsp list and parent for the new Src 1185 * 1186 * Results: 1187 * always returns 0 1188 * 1189 * Side Effects: 1190 * A Src structure is created and tacked onto the end of the list 1191 *----------------------------------------------------------------------- 1192 */ 1193 static int 1194 SuffAddSrc(void *sp, void *lsp) 1195 { 1196 Suff *s = (Suff *)sp; 1197 LstSrc *ls = (LstSrc *)lsp; 1198 Src *s2; /* new Src structure */ 1199 Src *targ; /* Target structure */ 1200 1201 targ = ls->s; 1202 1203 if ((s->flags & SUFF_NULL) && (*s->name != '\0')) { 1204 /* 1205 * If the suffix has been marked as the NULL suffix, also create a Src 1206 * structure for a file with no suffix attached. Two birds, and all 1207 * that... 1208 */ 1209 s2 = bmake_malloc(sizeof(Src)); 1210 s2->file = bmake_strdup(targ->pref); 1211 s2->pref = targ->pref; 1212 s2->parent = targ; 1213 s2->node = NULL; 1214 s2->suff = s; 1215 s->refCount++; 1216 s2->children = 0; 1217 targ->children += 1; 1218 (void)Lst_AtEnd(ls->l, s2); 1219 #ifdef DEBUG_SRC 1220 s2->cp = Lst_Init(FALSE); 1221 Lst_AtEnd(targ->cp, s2); 1222 fprintf(debug_file, "1 add %p %p to %p:", targ, s2, ls->l); 1223 Lst_ForEach(ls->l, PrintAddr, NULL); 1224 fprintf(debug_file, "\n"); 1225 #endif 1226 } 1227 s2 = bmake_malloc(sizeof(Src)); 1228 s2->file = str_concat2(targ->pref, s->name); 1229 s2->pref = targ->pref; 1230 s2->parent = targ; 1231 s2->node = NULL; 1232 s2->suff = s; 1233 s->refCount++; 1234 s2->children = 0; 1235 targ->children += 1; 1236 (void)Lst_AtEnd(ls->l, s2); 1237 #ifdef DEBUG_SRC 1238 s2->cp = Lst_Init(FALSE); 1239 Lst_AtEnd(targ->cp, s2); 1240 fprintf(debug_file, "2 add %p %p to %p:", targ, s2, ls->l); 1241 Lst_ForEach(ls->l, PrintAddr, NULL); 1242 fprintf(debug_file, "\n"); 1243 #endif 1244 1245 return 0; 1246 } 1247 1248 /*- 1249 *----------------------------------------------------------------------- 1250 * SuffAddLevel -- 1251 * Add all the children of targ as Src structures to the given list 1252 * 1253 * Input: 1254 * l list to which to add the new level 1255 * targ Src structure to use as the parent 1256 * 1257 * Results: 1258 * None 1259 * 1260 * Side Effects: 1261 * Lots of structures are created and added to the list 1262 *----------------------------------------------------------------------- 1263 */ 1264 static void 1265 SuffAddLevel(Lst l, Src *targ) 1266 { 1267 LstSrc ls; 1268 1269 ls.s = targ; 1270 ls.l = l; 1271 1272 Lst_ForEach(targ->suff->children, SuffAddSrc, &ls); 1273 } 1274 1275 /*- 1276 *---------------------------------------------------------------------- 1277 * SuffRemoveSrc -- 1278 * Free all src structures in list that don't have a reference count 1279 * 1280 * Results: 1281 * Ture if an src was removed 1282 * 1283 * Side Effects: 1284 * The memory is free'd. 1285 *---------------------------------------------------------------------- 1286 */ 1287 static int 1288 SuffRemoveSrc(Lst l) 1289 { 1290 LstNode ln; 1291 Src *s; 1292 int t = 0; 1293 1294 if (Lst_Open(l) == FAILURE) { 1295 return 0; 1296 } 1297 #ifdef DEBUG_SRC 1298 fprintf(debug_file, "cleaning %lx: ", (unsigned long) l); 1299 Lst_ForEach(l, PrintAddr, NULL); 1300 fprintf(debug_file, "\n"); 1301 #endif 1302 1303 1304 while ((ln = Lst_Next(l)) != NULL) { 1305 s = (Src *)Lst_Datum(ln); 1306 if (s->children == 0) { 1307 free(s->file); 1308 if (!s->parent) 1309 free(s->pref); 1310 else { 1311 #ifdef DEBUG_SRC 1312 LstNode ln2 = Lst_Member(s->parent->cp, s); 1313 if (ln2 != NULL) 1314 Lst_Remove(s->parent->cp, ln2); 1315 #endif 1316 --s->parent->children; 1317 } 1318 #ifdef DEBUG_SRC 1319 fprintf(debug_file, "free: [l=%p] p=%p %d\n", l, s, s->children); 1320 Lst_Destroy(s->cp, NULL); 1321 #endif 1322 Lst_Remove(l, ln); 1323 free(s); 1324 t |= 1; 1325 Lst_Close(l); 1326 return TRUE; 1327 } 1328 #ifdef DEBUG_SRC 1329 else { 1330 fprintf(debug_file, "keep: [l=%p] p=%p %d: ", l, s, s->children); 1331 Lst_ForEach(s->cp, PrintAddr, NULL); 1332 fprintf(debug_file, "\n"); 1333 } 1334 #endif 1335 } 1336 1337 Lst_Close(l); 1338 1339 return t; 1340 } 1341 1342 /*- 1343 *----------------------------------------------------------------------- 1344 * SuffFindThem -- 1345 * Find the first existing file/target in the list srcs 1346 * 1347 * Input: 1348 * srcs list of Src structures to search through 1349 * 1350 * Results: 1351 * The lowest structure in the chain of transformations 1352 * 1353 * Side Effects: 1354 * None 1355 *----------------------------------------------------------------------- 1356 */ 1357 static Src * 1358 SuffFindThem(Lst srcs, Lst slst) 1359 { 1360 Src *s; /* current Src */ 1361 Src *rs; /* returned Src */ 1362 char *ptr; 1363 1364 rs = NULL; 1365 1366 while (!Lst_IsEmpty (srcs)) { 1367 s = (Src *)Lst_DeQueue(srcs); 1368 1369 if (DEBUG(SUFF)) { 1370 fprintf(debug_file, "\ttrying %s...", s->file); 1371 } 1372 1373 /* 1374 * A file is considered to exist if either a node exists in the 1375 * graph for it or the file actually exists. 1376 */ 1377 if (Targ_FindNode(s->file, TARG_NOCREATE) != NULL) { 1378 #ifdef DEBUG_SRC 1379 fprintf(debug_file, "remove %p from %p\n", s, srcs); 1380 #endif 1381 rs = s; 1382 break; 1383 } 1384 1385 if ((ptr = Dir_FindFile(s->file, s->suff->searchPath)) != NULL) { 1386 rs = s; 1387 #ifdef DEBUG_SRC 1388 fprintf(debug_file, "remove %p from %p\n", s, srcs); 1389 #endif 1390 free(ptr); 1391 break; 1392 } 1393 1394 if (DEBUG(SUFF)) { 1395 fprintf(debug_file, "not there\n"); 1396 } 1397 1398 SuffAddLevel(srcs, s); 1399 Lst_AtEnd(slst, s); 1400 } 1401 1402 if (DEBUG(SUFF) && rs) { 1403 fprintf(debug_file, "got it\n"); 1404 } 1405 return rs; 1406 } 1407 1408 /*- 1409 *----------------------------------------------------------------------- 1410 * SuffFindCmds -- 1411 * See if any of the children of the target in the Src structure is 1412 * one from which the target can be transformed. If there is one, 1413 * a Src structure is put together for it and returned. 1414 * 1415 * Input: 1416 * targ Src structure to play with 1417 * 1418 * Results: 1419 * The Src structure of the "winning" child, or NULL if no such beast. 1420 * 1421 * Side Effects: 1422 * A Src structure may be allocated. 1423 * 1424 *----------------------------------------------------------------------- 1425 */ 1426 static Src * 1427 SuffFindCmds(Src *targ, Lst slst) 1428 { 1429 LstNode ln; /* General-purpose list node */ 1430 GNode *t, /* Target GNode */ 1431 *s; /* Source GNode */ 1432 int prefLen;/* The length of the defined prefix */ 1433 Suff *suff; /* Suffix on matching beastie */ 1434 Src *ret; /* Return value */ 1435 char *cp; 1436 1437 t = targ->node; 1438 (void)Lst_Open(t->children); 1439 prefLen = strlen(targ->pref); 1440 1441 for (;;) { 1442 ln = Lst_Next(t->children); 1443 if (ln == NULL) { 1444 Lst_Close(t->children); 1445 return NULL; 1446 } 1447 s = (GNode *)Lst_Datum(ln); 1448 1449 if (s->type & OP_OPTIONAL && Lst_IsEmpty(t->commands)) { 1450 /* 1451 * We haven't looked to see if .OPTIONAL files exist yet, so 1452 * don't use one as the implicit source. 1453 * This allows us to use .OPTIONAL in .depend files so make won't 1454 * complain "don't know how to make xxx.h' when a dependent file 1455 * has been moved/deleted. 1456 */ 1457 continue; 1458 } 1459 1460 cp = strrchr(s->name, '/'); 1461 if (cp == NULL) { 1462 cp = s->name; 1463 } else { 1464 cp++; 1465 } 1466 if (strncmp(cp, targ->pref, prefLen) != 0) 1467 continue; 1468 /* 1469 * The node matches the prefix ok, see if it has a known 1470 * suffix. 1471 */ 1472 ln = Lst_Find(sufflist, &cp[prefLen], SuffSuffHasNameP); 1473 if (ln == NULL) 1474 continue; 1475 /* 1476 * It even has a known suffix, see if there's a transformation 1477 * defined between the node's suffix and the target's suffix. 1478 * 1479 * XXX: Handle multi-stage transformations here, too. 1480 */ 1481 suff = (Suff *)Lst_Datum(ln); 1482 1483 if (Lst_Member(suff->parents, targ->suff) != NULL) 1484 break; 1485 } 1486 1487 /* 1488 * Hot Damn! Create a new Src structure to describe 1489 * this transformation (making sure to duplicate the 1490 * source node's name so Suff_FindDeps can free it 1491 * again (ick)), and return the new structure. 1492 */ 1493 ret = bmake_malloc(sizeof(Src)); 1494 ret->file = bmake_strdup(s->name); 1495 ret->pref = targ->pref; 1496 ret->suff = suff; 1497 suff->refCount++; 1498 ret->parent = targ; 1499 ret->node = s; 1500 ret->children = 0; 1501 targ->children += 1; 1502 #ifdef DEBUG_SRC 1503 ret->cp = Lst_Init(FALSE); 1504 fprintf(debug_file, "3 add %p %p\n", targ, ret); 1505 Lst_AtEnd(targ->cp, ret); 1506 #endif 1507 Lst_AtEnd(slst, ret); 1508 if (DEBUG(SUFF)) { 1509 fprintf(debug_file, "\tusing existing source %s\n", s->name); 1510 } 1511 return ret; 1512 } 1513 1514 /*- 1515 *----------------------------------------------------------------------- 1516 * SuffExpandChildren -- 1517 * Expand the names of any children of a given node that contain 1518 * variable invocations or file wildcards into actual targets. 1519 * 1520 * Input: 1521 * cln Child to examine 1522 * pgn Parent node being processed 1523 * 1524 * Results: 1525 * === 0 (continue) 1526 * 1527 * Side Effects: 1528 * The expanded node is removed from the parent's list of children, 1529 * and the parent's unmade counter is decremented, but other nodes 1530 * may be added. 1531 * 1532 *----------------------------------------------------------------------- 1533 */ 1534 static void 1535 SuffExpandChildren(LstNode cln, GNode *pgn) 1536 { 1537 GNode *cgn = (GNode *)Lst_Datum(cln); 1538 GNode *gn; /* New source 8) */ 1539 char *cp; /* Expanded value */ 1540 1541 if (!Lst_IsEmpty(cgn->order_pred) || !Lst_IsEmpty(cgn->order_succ)) 1542 /* It is all too hard to process the result of .ORDER */ 1543 return; 1544 1545 if (cgn->type & OP_WAIT) 1546 /* Ignore these (& OP_PHONY ?) */ 1547 return; 1548 1549 /* 1550 * First do variable expansion -- this takes precedence over 1551 * wildcard expansion. If the result contains wildcards, they'll be gotten 1552 * to later since the resulting words are tacked on to the end of 1553 * the children list. 1554 */ 1555 if (strchr(cgn->name, '$') == NULL) { 1556 SuffExpandWildcards(cln, pgn); 1557 return; 1558 } 1559 1560 if (DEBUG(SUFF)) { 1561 fprintf(debug_file, "Expanding \"%s\"...", cgn->name); 1562 } 1563 cp = Var_Subst(cgn->name, pgn, VARE_UNDEFERR|VARE_WANTRES); 1564 1565 if (cp != NULL) { 1566 Lst members = Lst_Init(FALSE); 1567 1568 if (cgn->type & OP_ARCHV) { 1569 /* 1570 * Node was an archive(member) target, so we want to call 1571 * on the Arch module to find the nodes for us, expanding 1572 * variables in the parent's context. 1573 */ 1574 char *sacrifice = cp; 1575 1576 (void)Arch_ParseArchive(&sacrifice, members, pgn); 1577 } else { 1578 /* 1579 * Break the result into a vector of strings whose nodes 1580 * we can find, then add those nodes to the members list. 1581 * Unfortunately, we can't use brk_string b/c it 1582 * doesn't understand about variable specifications with 1583 * spaces in them... 1584 */ 1585 char *start; 1586 char *initcp = cp; /* For freeing... */ 1587 1588 for (start = cp; *start == ' ' || *start == '\t'; start++) 1589 continue; 1590 for (cp = start; *cp != '\0'; cp++) { 1591 if (*cp == ' ' || *cp == '\t') { 1592 /* 1593 * White-space -- terminate element, find the node, 1594 * add it, skip any further spaces. 1595 */ 1596 *cp++ = '\0'; 1597 gn = Targ_FindNode(start, TARG_CREATE); 1598 (void)Lst_AtEnd(members, gn); 1599 while (*cp == ' ' || *cp == '\t') { 1600 cp++; 1601 } 1602 /* 1603 * Adjust cp for increment at start of loop, but 1604 * set start to first non-space. 1605 */ 1606 start = cp--; 1607 } else if (*cp == '$') { 1608 /* 1609 * Start of a variable spec -- contact variable module 1610 * to find the end so we can skip over it. 1611 */ 1612 const char *junk; 1613 int len; 1614 void *freeIt; 1615 1616 junk = Var_Parse(cp, pgn, VARE_UNDEFERR|VARE_WANTRES, 1617 &len, &freeIt); 1618 if (junk != var_Error) { 1619 cp += len - 1; 1620 } 1621 1622 free(freeIt); 1623 } else if (*cp == '\\' && cp[1] != '\0') { 1624 /* 1625 * Escaped something -- skip over it 1626 */ 1627 cp++; 1628 } 1629 } 1630 1631 if (cp != start) { 1632 /* 1633 * Stuff left over -- add it to the list too 1634 */ 1635 gn = Targ_FindNode(start, TARG_CREATE); 1636 (void)Lst_AtEnd(members, gn); 1637 } 1638 /* 1639 * Point cp back at the beginning again so the variable value 1640 * can be freed. 1641 */ 1642 cp = initcp; 1643 } 1644 1645 /* 1646 * Add all elements of the members list to the parent node. 1647 */ 1648 while(!Lst_IsEmpty(members)) { 1649 gn = (GNode *)Lst_DeQueue(members); 1650 1651 if (DEBUG(SUFF)) { 1652 fprintf(debug_file, "%s...", gn->name); 1653 } 1654 /* Add gn to the parents child list before the original child */ 1655 (void)Lst_InsertBefore(pgn->children, cln, gn); 1656 (void)Lst_AtEnd(gn->parents, pgn); 1657 pgn->unmade++; 1658 /* Expand wildcards on new node */ 1659 SuffExpandWildcards(Lst_Prev(cln), pgn); 1660 } 1661 Lst_Destroy(members, NULL); 1662 1663 /* 1664 * Free the result 1665 */ 1666 free(cp); 1667 } 1668 if (DEBUG(SUFF)) { 1669 fprintf(debug_file, "\n"); 1670 } 1671 1672 /* 1673 * Now the source is expanded, remove it from the list of children to 1674 * keep it from being processed. 1675 */ 1676 pgn->unmade--; 1677 Lst_Remove(pgn->children, cln); 1678 Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn)); 1679 } 1680 1681 static void 1682 SuffExpandWildcards(LstNode cln, GNode *pgn) 1683 { 1684 GNode *cgn = (GNode *)Lst_Datum(cln); 1685 GNode *gn; /* New source 8) */ 1686 char *cp; /* Expanded value */ 1687 Lst explist; /* List of expansions */ 1688 1689 if (!Dir_HasWildcards(cgn->name)) 1690 return; 1691 1692 /* 1693 * Expand the word along the chosen path 1694 */ 1695 explist = Lst_Init(FALSE); 1696 Dir_Expand(cgn->name, Suff_FindPath(cgn), explist); 1697 1698 while (!Lst_IsEmpty(explist)) { 1699 /* 1700 * Fetch next expansion off the list and find its GNode 1701 */ 1702 cp = (char *)Lst_DeQueue(explist); 1703 1704 if (DEBUG(SUFF)) { 1705 fprintf(debug_file, "%s...", cp); 1706 } 1707 gn = Targ_FindNode(cp, TARG_CREATE); 1708 1709 /* Add gn to the parents child list before the original child */ 1710 (void)Lst_InsertBefore(pgn->children, cln, gn); 1711 (void)Lst_AtEnd(gn->parents, pgn); 1712 pgn->unmade++; 1713 } 1714 1715 /* 1716 * Nuke what's left of the list 1717 */ 1718 Lst_Destroy(explist, NULL); 1719 1720 if (DEBUG(SUFF)) { 1721 fprintf(debug_file, "\n"); 1722 } 1723 1724 /* 1725 * Now the source is expanded, remove it from the list of children to 1726 * keep it from being processed. 1727 */ 1728 pgn->unmade--; 1729 Lst_Remove(pgn->children, cln); 1730 Lst_Remove(cgn->parents, Lst_Member(cgn->parents, pgn)); 1731 } 1732 1733 /*- 1734 *----------------------------------------------------------------------- 1735 * Suff_FindPath -- 1736 * Find a path along which to expand the node. 1737 * 1738 * If the word has a known suffix, use that path. 1739 * If it has no known suffix, use the default system search path. 1740 * 1741 * Input: 1742 * gn Node being examined 1743 * 1744 * Results: 1745 * The appropriate path to search for the GNode. 1746 * 1747 * Side Effects: 1748 * XXX: We could set the suffix here so that we don't have to scan 1749 * again. 1750 * 1751 *----------------------------------------------------------------------- 1752 */ 1753 Lst 1754 Suff_FindPath(GNode* gn) 1755 { 1756 Suff *suff = gn->suffix; 1757 1758 if (suff == NULL) { 1759 SuffixCmpData sd; /* Search string data */ 1760 LstNode ln; 1761 sd.len = strlen(gn->name); 1762 sd.ename = gn->name + sd.len; 1763 ln = Lst_Find(sufflist, &sd, SuffSuffIsSuffixP); 1764 1765 if (DEBUG(SUFF)) { 1766 fprintf(debug_file, "Wildcard expanding \"%s\"...", gn->name); 1767 } 1768 if (ln != NULL) 1769 suff = (Suff *)Lst_Datum(ln); 1770 /* XXX: Here we can save the suffix so we don't have to do this again */ 1771 } 1772 1773 if (suff != NULL) { 1774 if (DEBUG(SUFF)) { 1775 fprintf(debug_file, "suffix is \"%s\"...", suff->name); 1776 } 1777 return suff->searchPath; 1778 } else { 1779 /* 1780 * Use default search path 1781 */ 1782 return dirSearchPath; 1783 } 1784 } 1785 1786 /*- 1787 *----------------------------------------------------------------------- 1788 * SuffApplyTransform -- 1789 * Apply a transformation rule, given the source and target nodes 1790 * and suffixes. 1791 * 1792 * Input: 1793 * tGn Target node 1794 * sGn Source node 1795 * t Target suffix 1796 * s Source suffix 1797 * 1798 * Results: 1799 * TRUE if successful, FALSE if not. 1800 * 1801 * Side Effects: 1802 * The source and target are linked and the commands from the 1803 * transformation are added to the target node's commands list. 1804 * All attributes but OP_DEPMASK and OP_TRANSFORM are applied 1805 * to the target. The target also inherits all the sources for 1806 * the transformation rule. 1807 * 1808 *----------------------------------------------------------------------- 1809 */ 1810 static Boolean 1811 SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s) 1812 { 1813 LstNode ln, nln; /* General node */ 1814 char *tname; /* Name of transformation rule */ 1815 GNode *gn; /* Node for same */ 1816 1817 /* 1818 * Form the proper links between the target and source. 1819 */ 1820 (void)Lst_AtEnd(tGn->children, sGn); 1821 (void)Lst_AtEnd(sGn->parents, tGn); 1822 tGn->unmade += 1; 1823 1824 /* 1825 * Locate the transformation rule itself 1826 */ 1827 tname = str_concat2(s->name, t->name); 1828 ln = Lst_Find(transforms, tname, SuffGNHasNameP); 1829 free(tname); 1830 1831 if (ln == NULL) { 1832 /* 1833 * Not really such a transformation rule (can happen when we're 1834 * called to link an OP_MEMBER and OP_ARCHV node), so return 1835 * FALSE. 1836 */ 1837 return FALSE; 1838 } 1839 1840 gn = (GNode *)Lst_Datum(ln); 1841 1842 if (DEBUG(SUFF)) { 1843 fprintf(debug_file, "\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); 1844 } 1845 1846 /* 1847 * Record last child for expansion purposes 1848 */ 1849 ln = Lst_Last(tGn->children); 1850 1851 /* 1852 * Pass the buck to Make_HandleUse to apply the rule 1853 */ 1854 (void)Make_HandleUse(gn, tGn); 1855 1856 /* 1857 * Deal with wildcards and variables in any acquired sources 1858 */ 1859 for (ln = Lst_Succ(ln); ln != NULL; ln = nln) { 1860 nln = Lst_Succ(ln); 1861 SuffExpandChildren(ln, tGn); 1862 } 1863 1864 /* 1865 * Keep track of another parent to which this beast is transformed so 1866 * the .IMPSRC variable can be set correctly for the parent. 1867 */ 1868 (void)Lst_AtEnd(sGn->iParents, tGn); 1869 1870 return TRUE; 1871 } 1872 1873 1874 /*- 1875 *----------------------------------------------------------------------- 1876 * SuffFindArchiveDeps -- 1877 * Locate dependencies for an OP_ARCHV node. 1878 * 1879 * Input: 1880 * gn Node for which to locate dependencies 1881 * 1882 * Results: 1883 * None 1884 * 1885 * Side Effects: 1886 * Same as Suff_FindDeps 1887 * 1888 *----------------------------------------------------------------------- 1889 */ 1890 static void 1891 SuffFindArchiveDeps(GNode *gn, Lst slst) 1892 { 1893 char *eoarch; /* End of archive portion */ 1894 char *eoname; /* End of member portion */ 1895 GNode *mem; /* Node for member */ 1896 static const char *copy[] = { 1897 /* Variables to be copied from the member node */ 1898 TARGET, /* Must be first */ 1899 PREFIX, /* Must be second */ 1900 }; 1901 LstNode ln, nln; /* Next suffix node to check */ 1902 int i; /* Index into copy and vals */ 1903 Suff *ms; /* Suffix descriptor for member */ 1904 char *name; /* Start of member's name */ 1905 1906 /* 1907 * The node is an archive(member) pair. so we must find a 1908 * suffix for both of them. 1909 */ 1910 eoarch = strchr(gn->name, '('); 1911 eoname = strchr(eoarch, ')'); 1912 1913 /* 1914 * Caller guarantees the format `libname(member)', via 1915 * Arch_ParseArchive. 1916 */ 1917 assert(eoarch != NULL); 1918 assert(eoname != NULL); 1919 1920 *eoname = '\0'; /* Nuke parentheses during suffix search */ 1921 *eoarch = '\0'; /* So a suffix can be found */ 1922 1923 name = eoarch + 1; 1924 1925 /* 1926 * To simplify things, call Suff_FindDeps recursively on the member now, 1927 * so we can simply compare the member's .PREFIX and .TARGET variables 1928 * to locate its suffix. This allows us to figure out the suffix to 1929 * use for the archive without having to do a quadratic search over the 1930 * suffix list, backtracking for each one... 1931 */ 1932 mem = Targ_FindNode(name, TARG_CREATE); 1933 SuffFindDeps(mem, slst); 1934 1935 /* 1936 * Create the link between the two nodes right off 1937 */ 1938 (void)Lst_AtEnd(gn->children, mem); 1939 (void)Lst_AtEnd(mem->parents, gn); 1940 gn->unmade += 1; 1941 1942 /* 1943 * Copy in the variables from the member node to this one. 1944 */ 1945 for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) { 1946 char *p1; 1947 Var_Set(copy[i], Var_Value(copy[i], mem, &p1), gn); 1948 bmake_free(p1); 1949 1950 } 1951 1952 ms = mem->suffix; 1953 if (ms == NULL) { 1954 /* 1955 * Didn't know what it was -- use .NULL suffix if not in make mode 1956 */ 1957 if (DEBUG(SUFF)) { 1958 fprintf(debug_file, "using null suffix\n"); 1959 } 1960 ms = suffNull; 1961 } 1962 1963 1964 /* 1965 * Set the other two local variables required for this target. 1966 */ 1967 Var_Set(MEMBER, name, gn); 1968 Var_Set(ARCHIVE, gn->name, gn); 1969 1970 /* 1971 * Set $@ for compatibility with other makes 1972 */ 1973 Var_Set(TARGET, gn->name, gn); 1974 1975 /* 1976 * Now we've got the important local variables set, expand any sources 1977 * that still contain variables or wildcards in their names. 1978 */ 1979 for (ln = Lst_First(gn->children); ln != NULL; ln = nln) { 1980 nln = Lst_Succ(ln); 1981 SuffExpandChildren(ln, gn); 1982 } 1983 1984 if (ms != NULL) { 1985 /* 1986 * Member has a known suffix, so look for a transformation rule from 1987 * it to a possible suffix of the archive. Rather than searching 1988 * through the entire list, we just look at suffixes to which the 1989 * member's suffix may be transformed... 1990 */ 1991 SuffixCmpData sd; /* Search string data */ 1992 1993 /* 1994 * Use first matching suffix... 1995 */ 1996 sd.len = eoarch - gn->name; 1997 sd.ename = eoarch; 1998 ln = Lst_Find(ms->parents, &sd, SuffSuffIsSuffixP); 1999 2000 if (ln != NULL) { 2001 /* 2002 * Got one -- apply it 2003 */ 2004 if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && 2005 DEBUG(SUFF)) 2006 { 2007 fprintf(debug_file, "\tNo transformation from %s -> %s\n", 2008 ms->name, ((Suff *)Lst_Datum(ln))->name); 2009 } 2010 } 2011 } 2012 2013 /* 2014 * Replace the opening and closing parens now we've no need of the separate 2015 * pieces. 2016 */ 2017 *eoarch = '('; *eoname = ')'; 2018 2019 /* 2020 * Pretend gn appeared to the left of a dependency operator so 2021 * the user needn't provide a transformation from the member to the 2022 * archive. 2023 */ 2024 if (OP_NOP(gn->type)) { 2025 gn->type |= OP_DEPENDS; 2026 } 2027 2028 /* 2029 * Flag the member as such so we remember to look in the archive for 2030 * its modification time. The OP_JOIN | OP_MADE is needed because this 2031 * target should never get made. 2032 */ 2033 mem->type |= OP_MEMBER | OP_JOIN | OP_MADE; 2034 } 2035 2036 /*- 2037 *----------------------------------------------------------------------- 2038 * SuffFindNormalDeps -- 2039 * Locate implicit dependencies for regular targets. 2040 * 2041 * Input: 2042 * gn Node for which to find sources 2043 * 2044 * Results: 2045 * None. 2046 * 2047 * Side Effects: 2048 * Same as Suff_FindDeps... 2049 * 2050 *----------------------------------------------------------------------- 2051 */ 2052 static void 2053 SuffFindNormalDeps(GNode *gn, Lst slst) 2054 { 2055 char *eoname; /* End of name */ 2056 char *sopref; /* Start of prefix */ 2057 LstNode ln, nln; /* Next suffix node to check */ 2058 Lst srcs; /* List of sources at which to look */ 2059 Lst targs; /* List of targets to which things can be 2060 * transformed. They all have the same file, 2061 * but different suff and pref fields */ 2062 Src *bottom; /* Start of found transformation path */ 2063 Src *src; /* General Src pointer */ 2064 char *pref; /* Prefix to use */ 2065 Src *targ; /* General Src target pointer */ 2066 SuffixCmpData sd; /* Search string data */ 2067 2068 2069 sd.len = strlen(gn->name); 2070 sd.ename = eoname = gn->name + sd.len; 2071 2072 sopref = gn->name; 2073 2074 /* 2075 * Begin at the beginning... 2076 */ 2077 ln = Lst_First(sufflist); 2078 srcs = Lst_Init(FALSE); 2079 targs = Lst_Init(FALSE); 2080 2081 /* 2082 * We're caught in a catch-22 here. On the one hand, we want to use any 2083 * transformation implied by the target's sources, but we can't examine 2084 * the sources until we've expanded any variables/wildcards they may hold, 2085 * and we can't do that until we've set up the target's local variables 2086 * and we can't do that until we know what the proper suffix for the 2087 * target is (in case there are two suffixes one of which is a suffix of 2088 * the other) and we can't know that until we've found its implied 2089 * source, which we may not want to use if there's an existing source 2090 * that implies a different transformation. 2091 * 2092 * In an attempt to get around this, which may not work all the time, 2093 * but should work most of the time, we look for implied sources first, 2094 * checking transformations to all possible suffixes of the target, 2095 * use what we find to set the target's local variables, expand the 2096 * children, then look for any overriding transformations they imply. 2097 * Should we find one, we discard the one we found before. 2098 */ 2099 bottom = NULL; 2100 targ = NULL; 2101 2102 if (!(gn->type & OP_PHONY)) { 2103 2104 while (ln != NULL) { 2105 /* 2106 * Look for next possible suffix... 2107 */ 2108 ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP); 2109 2110 if (ln != NULL) { 2111 int prefLen; /* Length of the prefix */ 2112 2113 /* 2114 * Allocate a Src structure to which things can be transformed 2115 */ 2116 targ = bmake_malloc(sizeof(Src)); 2117 targ->file = bmake_strdup(gn->name); 2118 targ->suff = (Suff *)Lst_Datum(ln); 2119 targ->suff->refCount++; 2120 targ->node = gn; 2121 targ->parent = NULL; 2122 targ->children = 0; 2123 #ifdef DEBUG_SRC 2124 targ->cp = Lst_Init(FALSE); 2125 #endif 2126 2127 /* 2128 * Allocate room for the prefix, whose end is found by 2129 * subtracting the length of the suffix from 2130 * the end of the name. 2131 */ 2132 prefLen = (eoname - targ->suff->nameLen) - sopref; 2133 targ->pref = bmake_malloc(prefLen + 1); 2134 memcpy(targ->pref, sopref, prefLen); 2135 targ->pref[prefLen] = '\0'; 2136 2137 /* 2138 * Add nodes from which the target can be made 2139 */ 2140 SuffAddLevel(srcs, targ); 2141 2142 /* 2143 * Record the target so we can nuke it 2144 */ 2145 (void)Lst_AtEnd(targs, targ); 2146 2147 /* 2148 * Search from this suffix's successor... 2149 */ 2150 ln = Lst_Succ(ln); 2151 } 2152 } 2153 2154 /* 2155 * Handle target of unknown suffix... 2156 */ 2157 if (Lst_IsEmpty(targs) && suffNull != NULL) { 2158 if (DEBUG(SUFF)) { 2159 fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name); 2160 } 2161 2162 targ = bmake_malloc(sizeof(Src)); 2163 targ->file = bmake_strdup(gn->name); 2164 targ->suff = suffNull; 2165 targ->suff->refCount++; 2166 targ->node = gn; 2167 targ->parent = NULL; 2168 targ->children = 0; 2169 targ->pref = bmake_strdup(sopref); 2170 #ifdef DEBUG_SRC 2171 targ->cp = Lst_Init(FALSE); 2172 #endif 2173 2174 /* 2175 * Only use the default suffix rules if we don't have commands 2176 * defined for this gnode; traditional make programs used to 2177 * not define suffix rules if the gnode had children but we 2178 * don't do this anymore. 2179 */ 2180 if (Lst_IsEmpty(gn->commands)) 2181 SuffAddLevel(srcs, targ); 2182 else { 2183 if (DEBUG(SUFF)) 2184 fprintf(debug_file, "not "); 2185 } 2186 2187 if (DEBUG(SUFF)) 2188 fprintf(debug_file, "adding suffix rules\n"); 2189 2190 (void)Lst_AtEnd(targs, targ); 2191 } 2192 2193 /* 2194 * Using the list of possible sources built up from the target 2195 * suffix(es), try and find an existing file/target that matches. 2196 */ 2197 bottom = SuffFindThem(srcs, slst); 2198 2199 if (bottom == NULL) { 2200 /* 2201 * No known transformations -- use the first suffix found 2202 * for setting the local variables. 2203 */ 2204 if (!Lst_IsEmpty(targs)) { 2205 targ = (Src *)Lst_Datum(Lst_First(targs)); 2206 } else { 2207 targ = NULL; 2208 } 2209 } else { 2210 /* 2211 * Work up the transformation path to find the suffix of the 2212 * target to which the transformation was made. 2213 */ 2214 for (targ = bottom; targ->parent != NULL; targ = targ->parent) 2215 continue; 2216 } 2217 } 2218 2219 Var_Set(TARGET, gn->path ? gn->path : gn->name, gn); 2220 2221 pref = (targ != NULL) ? targ->pref : gn->name; 2222 Var_Set(PREFIX, pref, gn); 2223 2224 /* 2225 * Now we've got the important local variables set, expand any sources 2226 * that still contain variables or wildcards in their names. 2227 */ 2228 for (ln = Lst_First(gn->children); ln != NULL; ln = nln) { 2229 nln = Lst_Succ(ln); 2230 SuffExpandChildren(ln, gn); 2231 } 2232 2233 if (targ == NULL) { 2234 if (DEBUG(SUFF)) { 2235 fprintf(debug_file, "\tNo valid suffix on %s\n", gn->name); 2236 } 2237 2238 sfnd_abort: 2239 /* 2240 * Deal with finding the thing on the default search path. We 2241 * always do that, not only if the node is only a source (not 2242 * on the lhs of a dependency operator or [XXX] it has neither 2243 * children or commands) as the old pmake did. 2244 */ 2245 if ((gn->type & (OP_PHONY|OP_NOPATH)) == 0) { 2246 free(gn->path); 2247 gn->path = Dir_FindFile(gn->name, 2248 (targ == NULL ? dirSearchPath : 2249 targ->suff->searchPath)); 2250 if (gn->path != NULL) { 2251 char *ptr; 2252 Var_Set(TARGET, gn->path, gn); 2253 2254 if (targ != NULL) { 2255 /* 2256 * Suffix known for the thing -- trim the suffix off 2257 * the path to form the proper .PREFIX variable. 2258 */ 2259 int savep = strlen(gn->path) - targ->suff->nameLen; 2260 char savec; 2261 2262 if (gn->suffix) 2263 gn->suffix->refCount--; 2264 gn->suffix = targ->suff; 2265 gn->suffix->refCount++; 2266 2267 savec = gn->path[savep]; 2268 gn->path[savep] = '\0'; 2269 2270 if ((ptr = strrchr(gn->path, '/')) != NULL) 2271 ptr++; 2272 else 2273 ptr = gn->path; 2274 2275 Var_Set(PREFIX, ptr, gn); 2276 2277 gn->path[savep] = savec; 2278 } else { 2279 /* 2280 * The .PREFIX gets the full path if the target has 2281 * no known suffix. 2282 */ 2283 if (gn->suffix) 2284 gn->suffix->refCount--; 2285 gn->suffix = NULL; 2286 2287 if ((ptr = strrchr(gn->path, '/')) != NULL) 2288 ptr++; 2289 else 2290 ptr = gn->path; 2291 2292 Var_Set(PREFIX, ptr, gn); 2293 } 2294 } 2295 } 2296 2297 goto sfnd_return; 2298 } 2299 2300 /* 2301 * If the suffix indicates that the target is a library, mark that in 2302 * the node's type field. 2303 */ 2304 if (targ->suff->flags & SUFF_LIBRARY) { 2305 gn->type |= OP_LIB; 2306 } 2307 2308 /* 2309 * Check for overriding transformation rule implied by sources 2310 */ 2311 if (!Lst_IsEmpty(gn->children)) { 2312 src = SuffFindCmds(targ, slst); 2313 2314 if (src != NULL) { 2315 /* 2316 * Free up all the Src structures in the transformation path 2317 * up to, but not including, the parent node. 2318 */ 2319 while (bottom && bottom->parent != NULL) { 2320 if (Lst_Member(slst, bottom) == NULL) { 2321 Lst_AtEnd(slst, bottom); 2322 } 2323 bottom = bottom->parent; 2324 } 2325 bottom = src; 2326 } 2327 } 2328 2329 if (bottom == NULL) { 2330 /* 2331 * No idea from where it can come -- return now. 2332 */ 2333 goto sfnd_abort; 2334 } 2335 2336 /* 2337 * We now have a list of Src structures headed by 'bottom' and linked via 2338 * their 'parent' pointers. What we do next is create links between 2339 * source and target nodes (which may or may not have been created) 2340 * and set the necessary local variables in each target. The 2341 * commands for each target are set from the commands of the 2342 * transformation rule used to get from the src suffix to the targ 2343 * suffix. Note that this causes the commands list of the original 2344 * node, gn, to be replaced by the commands of the final 2345 * transformation rule. Also, the unmade field of gn is incremented. 2346 * Etc. 2347 */ 2348 if (bottom->node == NULL) { 2349 bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); 2350 } 2351 2352 for (src = bottom; src->parent != NULL; src = src->parent) { 2353 targ = src->parent; 2354 2355 if (src->node->suffix) 2356 src->node->suffix->refCount--; 2357 src->node->suffix = src->suff; 2358 src->node->suffix->refCount++; 2359 2360 if (targ->node == NULL) { 2361 targ->node = Targ_FindNode(targ->file, TARG_CREATE); 2362 } 2363 2364 SuffApplyTransform(targ->node, src->node, 2365 targ->suff, src->suff); 2366 2367 if (targ->node != gn) { 2368 /* 2369 * Finish off the dependency-search process for any nodes 2370 * between bottom and gn (no point in questing around the 2371 * filesystem for their implicit source when it's already 2372 * known). Note that the node can't have any sources that 2373 * need expanding, since SuffFindThem will stop on an existing 2374 * node, so all we need to do is set the standard and System V 2375 * variables. 2376 */ 2377 targ->node->type |= OP_DEPS_FOUND; 2378 2379 Var_Set(PREFIX, targ->pref, targ->node); 2380 2381 Var_Set(TARGET, targ->node->name, targ->node); 2382 } 2383 } 2384 2385 if (gn->suffix) 2386 gn->suffix->refCount--; 2387 gn->suffix = src->suff; 2388 gn->suffix->refCount++; 2389 2390 /* 2391 * Nuke the transformation path and the Src structures left over in the 2392 * two lists. 2393 */ 2394 sfnd_return: 2395 if (bottom) 2396 if (Lst_Member(slst, bottom) == NULL) 2397 Lst_AtEnd(slst, bottom); 2398 2399 while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs)) 2400 continue; 2401 2402 Lst_Concat(slst, srcs, LST_CONCLINK); 2403 Lst_Concat(slst, targs, LST_CONCLINK); 2404 } 2405 2406 2407 /*- 2408 *----------------------------------------------------------------------- 2409 * Suff_FindDeps -- 2410 * Find implicit sources for the target described by the graph node 2411 * gn 2412 * 2413 * Results: 2414 * Nothing. 2415 * 2416 * Side Effects: 2417 * Nodes are added to the graph below the passed-in node. The nodes 2418 * are marked to have their IMPSRC variable filled in. The 2419 * PREFIX variable is set for the given node and all its 2420 * implied children. 2421 * 2422 * Notes: 2423 * The path found by this target is the shortest path in the 2424 * transformation graph, which may pass through non-existent targets, 2425 * to an existing target. The search continues on all paths from the 2426 * root suffix until a file is found. I.e. if there's a path 2427 * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but 2428 * the .c and .l files don't, the search will branch out in 2429 * all directions from .o and again from all the nodes on the 2430 * next level until the .l,v node is encountered. 2431 * 2432 *----------------------------------------------------------------------- 2433 */ 2434 2435 void 2436 Suff_FindDeps(GNode *gn) 2437 { 2438 2439 SuffFindDeps(gn, srclist); 2440 while (SuffRemoveSrc(srclist)) 2441 continue; 2442 } 2443 2444 2445 /* 2446 * Input: 2447 * gn node we're dealing with 2448 * 2449 */ 2450 static void 2451 SuffFindDeps(GNode *gn, Lst slst) 2452 { 2453 if (gn->type & OP_DEPS_FOUND) { 2454 /* 2455 * If dependencies already found, no need to do it again... 2456 */ 2457 return; 2458 } else { 2459 gn->type |= OP_DEPS_FOUND; 2460 } 2461 /* 2462 * Make sure we have these set, may get revised below. 2463 */ 2464 Var_Set(TARGET, gn->path ? gn->path : gn->name, gn); 2465 Var_Set(PREFIX, gn->name, gn); 2466 2467 if (DEBUG(SUFF)) { 2468 fprintf(debug_file, "SuffFindDeps (%s)\n", gn->name); 2469 } 2470 2471 if (gn->type & OP_ARCHV) { 2472 SuffFindArchiveDeps(gn, slst); 2473 } else if (gn->type & OP_LIB) { 2474 /* 2475 * If the node is a library, it is the arch module's job to find it 2476 * and set the TARGET variable accordingly. We merely provide the 2477 * search path, assuming all libraries end in ".a" (if the suffix 2478 * hasn't been defined, there's nothing we can do for it, so we just 2479 * set the TARGET variable to the node's name in order to give it a 2480 * value). 2481 */ 2482 LstNode ln; 2483 Suff *s; 2484 2485 ln = Lst_Find(sufflist, LIBSUFF, SuffSuffHasNameP); 2486 if (gn->suffix) 2487 gn->suffix->refCount--; 2488 if (ln != NULL) { 2489 gn->suffix = s = (Suff *)Lst_Datum(ln); 2490 gn->suffix->refCount++; 2491 Arch_FindLib(gn, s->searchPath); 2492 } else { 2493 gn->suffix = NULL; 2494 Var_Set(TARGET, gn->name, gn); 2495 } 2496 /* 2497 * Because a library (-lfoo) target doesn't follow the standard 2498 * filesystem conventions, we don't set the regular variables for 2499 * the thing. .PREFIX is simply made empty... 2500 */ 2501 Var_Set(PREFIX, "", gn); 2502 } else { 2503 SuffFindNormalDeps(gn, slst); 2504 } 2505 } 2506 2507 /*- 2508 *----------------------------------------------------------------------- 2509 * Suff_SetNull -- 2510 * Define which suffix is the null suffix. 2511 * 2512 * Input: 2513 * name Name of null suffix 2514 * 2515 * Results: 2516 * None. 2517 * 2518 * Side Effects: 2519 * 'suffNull' is altered. 2520 * 2521 * Notes: 2522 * Need to handle the changing of the null suffix gracefully so the 2523 * old transformation rules don't just go away. 2524 * 2525 *----------------------------------------------------------------------- 2526 */ 2527 void 2528 Suff_SetNull(char *name) 2529 { 2530 Suff *s; 2531 LstNode ln; 2532 2533 ln = Lst_Find(sufflist, name, SuffSuffHasNameP); 2534 if (ln != NULL) { 2535 s = (Suff *)Lst_Datum(ln); 2536 if (suffNull != NULL) { 2537 suffNull->flags &= ~SUFF_NULL; 2538 } 2539 s->flags |= SUFF_NULL; 2540 /* 2541 * XXX: Here's where the transformation mangling would take place 2542 */ 2543 suffNull = s; 2544 } else { 2545 Parse_Error(PARSE_WARNING, "Desired null suffix %s not defined.", 2546 name); 2547 } 2548 } 2549 2550 /*- 2551 *----------------------------------------------------------------------- 2552 * Suff_Init -- 2553 * Initialize suffixes module 2554 * 2555 * Results: 2556 * None 2557 * 2558 * Side Effects: 2559 * Many 2560 *----------------------------------------------------------------------- 2561 */ 2562 void 2563 Suff_Init(void) 2564 { 2565 #ifdef CLEANUP 2566 suffClean = Lst_Init(FALSE); 2567 #endif 2568 srclist = Lst_Init(FALSE); 2569 transforms = Lst_Init(FALSE); 2570 2571 /* 2572 * Create null suffix for single-suffix rules (POSIX). The thing doesn't 2573 * actually go on the suffix list or everyone will think that's its 2574 * suffix. 2575 */ 2576 Suff_ClearSuffixes(); 2577 } 2578 2579 2580 /*- 2581 *---------------------------------------------------------------------- 2582 * Suff_End -- 2583 * Cleanup the this module 2584 * 2585 * Results: 2586 * None 2587 * 2588 * Side Effects: 2589 * The memory is free'd. 2590 *---------------------------------------------------------------------- 2591 */ 2592 2593 void 2594 Suff_End(void) 2595 { 2596 #ifdef CLEANUP 2597 Lst_Destroy(sufflist, SuffFree); 2598 Lst_Destroy(suffClean, SuffFree); 2599 if (suffNull) 2600 SuffFree(suffNull); 2601 Lst_Destroy(srclist, NULL); 2602 Lst_Destroy(transforms, NULL); 2603 #endif 2604 } 2605 2606 2607 /********************* DEBUGGING FUNCTIONS **********************/ 2608 2609 static int SuffPrintName(void *s, void *dummy MAKE_ATTR_UNUSED) 2610 { 2611 2612 fprintf(debug_file, "%s ", ((Suff *)s)->name); 2613 return 0; 2614 } 2615 2616 static int 2617 SuffPrintSuff(void *sp, void *dummy MAKE_ATTR_UNUSED) 2618 { 2619 Suff *s = (Suff *)sp; 2620 int flags; 2621 int flag; 2622 2623 fprintf(debug_file, "# `%s' [%d] ", s->name, s->refCount); 2624 2625 flags = s->flags; 2626 if (flags) { 2627 fputs(" (", debug_file); 2628 while (flags) { 2629 flag = 1 << (ffs(flags) - 1); 2630 flags &= ~flag; 2631 switch (flag) { 2632 case SUFF_NULL: 2633 fprintf(debug_file, "NULL"); 2634 break; 2635 case SUFF_INCLUDE: 2636 fprintf(debug_file, "INCLUDE"); 2637 break; 2638 case SUFF_LIBRARY: 2639 fprintf(debug_file, "LIBRARY"); 2640 break; 2641 } 2642 fputc(flags ? '|' : ')', debug_file); 2643 } 2644 } 2645 fputc('\n', debug_file); 2646 fprintf(debug_file, "#\tTo: "); 2647 Lst_ForEach(s->parents, SuffPrintName, NULL); 2648 fputc('\n', debug_file); 2649 fprintf(debug_file, "#\tFrom: "); 2650 Lst_ForEach(s->children, SuffPrintName, NULL); 2651 fputc('\n', debug_file); 2652 fprintf(debug_file, "#\tSearch Path: "); 2653 Dir_PrintPath(s->searchPath); 2654 fputc('\n', debug_file); 2655 return 0; 2656 } 2657 2658 static int 2659 SuffPrintTrans(void *tp, void *dummy MAKE_ATTR_UNUSED) 2660 { 2661 GNode *t = (GNode *)tp; 2662 2663 fprintf(debug_file, "%-16s: ", t->name); 2664 Targ_PrintType(t->type); 2665 fputc('\n', debug_file); 2666 Lst_ForEach(t->commands, Targ_PrintCmd, NULL); 2667 fputc('\n', debug_file); 2668 return 0; 2669 } 2670 2671 void 2672 Suff_PrintAll(void) 2673 { 2674 fprintf(debug_file, "#*** Suffixes:\n"); 2675 Lst_ForEach(sufflist, SuffPrintSuff, NULL); 2676 2677 fprintf(debug_file, "#*** Transformations:\n"); 2678 Lst_ForEach(transforms, SuffPrintTrans, NULL); 2679 } 2680