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