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