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