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