1 /* $OpenBSD: suff.c,v 1.80 2012/04/21 04:35:32 guenther Exp $ */ 2 /* $NetBSD: suff.c,v 1.13 1996/11/06 17:59:25 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1988, 1989, 1990, 1993 6 * The Regents of the University of California. All rights reserved. 7 * Copyright (c) 1989 by Berkeley Softworks 8 * All rights reserved. 9 * 10 * This code is derived from software contributed to Berkeley by 11 * Adam de Boor. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 /*- 39 * suff.c -- 40 * Functions to maintain suffix lists and find implicit dependents 41 * using suffix transformation rules 42 * 43 * Interface: 44 * Suff_Init Initialize all things to do with suffixes. 45 * 46 * Suff_End Cleanup the module 47 * 48 * Suff_ClearSuffixes Clear out all the suffixes and defined 49 * transformations. 50 * 51 * Suff_AddSuffix Add the passed string as another known suffix. 52 * 53 * Suff_GetPath Return the search path for the given suffix. 54 * 55 * Suff_AddInclude Mark the given suffix as denoting an include 56 * file. 57 * 58 * Suff_AddLib Mark the given suffix as denoting a library. 59 * 60 * Suff_ParseAsTransform Line might be a suffix line, check it. 61 * If it's not, return NULL. Otherwise, add 62 * another transformation to the suffix graph. 63 * Returns GNode suitable for framing, I mean, 64 * tacking commands, attributes, etc. on. 65 * 66 * Suff_SetNull Define the suffix to consider the suffix of 67 * any file that doesn't have a known one. 68 * 69 * Suff_FindDeps Find implicit sources for and the location of 70 * a target based on its suffix. Returns the 71 * bottom-most node added to the graph or NULL 72 * if the target had no implicit sources. 73 */ 74 75 #include <ctype.h> 76 #include <stdio.h> 77 #include <stdlib.h> 78 #include <stdint.h> 79 #include <stddef.h> 80 #include <string.h> 81 #include <signal.h> 82 #include <ohash.h> 83 #include "config.h" 84 #include "defines.h" 85 #include "dir.h" 86 #include "direxpand.h" 87 #include "engine.h" 88 #include "arch.h" 89 #include "suff.h" 90 #include "var.h" 91 #include "targ.h" 92 #include "error.h" 93 #include "str.h" 94 #include "lst.h" 95 #include "memory.h" 96 #include "gnode.h" 97 #include "make.h" 98 #include "stats.h" 99 100 /* XXX the suffixes hash is stored using a specific hash function, suitable 101 * for looking up suffixes in reverse. 102 */ 103 static struct ohash suffixes; 104 105 /* We remember the longest suffix, so we don't need to look beyond that. */ 106 size_t maxLen; 107 static LIST srclist; 108 109 /* Transforms (.c.o) are stored in another hash, independently from suffixes. 110 * When make sees a target, it checks whether it's currently parsable as a 111 * transform (according to the active suffixes). If yes, it's stored as a 112 * new transform. 113 * 114 * XXX 115 * But transforms DO NOT have a canonical decomposition as a set of suffixes, 116 * and will be used as necessary later, when looking up implicit rules for 117 * actual targets. 118 * 119 * For instance, a transform .a.b.c can be parsed as .a -> .b.c if suffixes 120 * .a and .b.c are active, and then LATER, reused as .a.b -> .c if suffixes 121 * .a.b and .c are active. 122 */ 123 static struct ohash transforms; 124 125 /* conflicts between suffixes are solved by suffix declaration order. */ 126 static int order = 0; 127 128 /* 129 * Structure describing an individual suffix. 130 */ 131 typedef struct Suff_ { 132 size_t nameLen; /* optimisation: strlen(name) */ 133 short flags; 134 #define SUFF_INCLUDE 0x01 /* suffix marked with .INCLUDES keyword */ 135 #define SUFF_LIBRARY 0x02 /* suffix marked with .LIBS keyword */ 136 #define SUFF_NULL 0x04 /* The empty suffix (normally '', */ 137 /* but see .EMPTY keyword) */ 138 #define SUFF_ACTIVE 0x08 /* We never destroy suffixes and rules, */ 139 /* we just deactivate them. */ 140 #define SUFF_PATH 0x10 /* False suffix: actually, the path keyword */ 141 LIST searchPath; /* The path along which files of this suffix 142 * may be found */ 143 int order; /* order of declaration for conflict 144 * resolution. */ 145 LIST parents; /* List of Suff we have a transformation to */ 146 LIST children; /* List of Suff we have a transformation from */ 147 char name[1]; 148 } Suff; 149 150 static struct ohash_info suff_info = { 151 offsetof(struct Suff_, name), NULL, 152 hash_alloc, hash_free, element_alloc 153 }; 154 155 /* 156 * Structure used in the search for implied sources. 157 */ 158 typedef struct Src_ { 159 char *file; /* The file to look for */ 160 char *pref; /* Prefix from which file was formed */ 161 Suff *suff; /* The suffix on the file */ 162 struct Src_ *parent; /* The Src for which this is a source */ 163 GNode *node; /* The node describing the file */ 164 int children; /* Count of existing children (so we don't free 165 * this thing too early or never nuke it) */ 166 #ifdef DEBUG_SRC 167 LIST cp; /* Debug; children list */ 168 #endif 169 } Src; 170 171 /* 172 * A structure for passing more than one argument to the Lst-library-invoked 173 * function... 174 */ 175 typedef struct { 176 Lst l; 177 Src *s; 178 } LstSrc; 179 180 static Suff *suffNull; /* The NULL suffix for this run */ 181 static Suff *emptySuff; /* The empty suffix required for POSIX 182 * single-suffix transformation rules */ 183 184 185 static void build_path_variable(struct ohash *, int, const char *, const char *); 186 static void add_property(const char *, const char *, int); 187 #define parse_transform(s, p, q) parse_transformi(s, s + strlen(s), p, q) 188 static bool parse_transformi(const char *, const char *, Suff **, Suff **); 189 #define new_suffix(s) new_suffixi(s, NULL) 190 static Suff *new_suffixi(const char *, const char *); 191 static void reverse_hash_add_char(uint32_t *, const char *); 192 static uint32_t reverse_hashi(const char *, const char **); 193 static unsigned int reverse_slot(struct ohash *, const char *, const char **); 194 static void clear_suffixes(void); 195 static void record_possible_suffix(Suff *, GNode *, char *, Lst, Lst); 196 static void record_possible_suffixes(GNode *, Lst, Lst); 197 static Suff *find_suffix_as_suffix(Lst, const char *, const char *); 198 static Suff *add_suffixi(const char *, const char *); 199 200 #ifdef CLEANUP 201 static void SuffFree(void *); 202 #endif 203 static void SuffInsert(Lst, Suff *); 204 static void SuffAddSrc(void *, void *); 205 static int SuffRemoveSrc(Lst); 206 static void SuffAddLevel(Lst, Src *); 207 static Src *SuffFindThem(Lst, Lst); 208 static Src *SuffFindCmds(Src *, Lst); 209 static void SuffExpandChildren(LstNode, GNode *); 210 static void SuffExpandVarChildren(LstNode, GNode *, GNode *); 211 static void SuffExpandWildChildren(LstNode, GNode *, GNode *); 212 static bool SuffApplyTransform(GNode *, GNode *, Suff *, Suff *); 213 static void SuffFindDeps(GNode *, Lst); 214 static void SuffFindArchiveDeps(GNode *, Lst); 215 static void SuffFindNormalDeps(GNode *, Lst); 216 static void SuffPrintName(void *); 217 static void SuffPrintSuff(void *); 218 static void SuffPrintTrans(GNode *); 219 220 #define find_suff(name) find_suffi(name, NULL) 221 static Suff *find_suffi(const char *, const char *); 222 static Suff *find_best_suffix(const char *, const char *); 223 static GNode *find_transform(const char *); 224 static GNode *find_or_create_transformi(const char *, const char *); 225 static void setup_paths(void); 226 static void build_suffixes_graph(void); 227 static void special_path_hack(void); 228 229 #ifdef DEBUG_SRC 230 static void PrintAddr(void *); 231 #endif 232 233 /* hash functions for the suffixes hash */ 234 /* add one char to the hash */ 235 static void 236 reverse_hash_add_char(uint32_t *pk, const char *s) 237 { 238 *pk = ((*pk << 2) | (*pk >> 30)) ^ *s; 239 } 240 241 /* build a full hash from end to start */ 242 static uint32_t 243 reverse_hashi(const char *s, const char **e) 244 { 245 const char *p; 246 uint32_t k; 247 248 if (*e == NULL) 249 *e = s + strlen(s); 250 p = *e; 251 if (p == s) 252 k = 0; 253 else 254 k = *--p; 255 while (p != s) { 256 reverse_hash_add_char(&k, --p); 257 } 258 return k; 259 } 260 261 static unsigned int 262 reverse_slot(struct ohash *h, const char *s, const char **e) 263 { 264 uint32_t hv; 265 266 hv = reverse_hashi(s, e); 267 return ohash_lookup_interval(h, s, *e, hv); 268 } 269 270 271 static char * 272 suffix_is_suffix(Suff *s, const char *str, const char *estr) 273 { 274 const char *p1; /* Pointer into suffix name */ 275 const char *p2; /* Pointer into string being examined */ 276 277 if (estr - str < (ptrdiff_t) s->nameLen) 278 return NULL; 279 p1 = s->name + s->nameLen; 280 p2 = estr; 281 282 while (p1 != s->name) { 283 p1--; 284 p2--; 285 if (*p1 != *p2) 286 return NULL; 287 } 288 289 return (char *)p2; 290 } 291 292 static Suff * 293 find_suffi(const char *name, const char *ename) 294 { 295 unsigned int slot; 296 #ifdef STATS_SUFF 297 STAT_SUFF_LOOKUP_NAME++; 298 #endif 299 slot = reverse_slot(&suffixes, name, &ename); 300 return ohash_find(&suffixes, slot); 301 } 302 303 static GNode * 304 find_transform(const char *name) 305 { 306 unsigned int slot; 307 308 #ifdef STATS_SUFF 309 STAT_TRANSFORM_LOOKUP_NAME++; 310 #endif 311 slot = ohash_qlookup(&transforms, name); 312 313 return ohash_find(&transforms, slot); 314 } 315 316 static GNode * 317 find_or_create_transformi(const char *name, const char *end) 318 { 319 GNode *r; 320 unsigned int slot; 321 322 #ifdef STATS_SUFF 323 STAT_TRANSFORM_LOOKUP_NAME++; 324 #endif 325 slot = ohash_qlookupi(&transforms, name, &end); 326 327 r = ohash_find(&transforms, slot); 328 329 if (r == NULL) { 330 r = Targ_NewGNi(name, end); 331 ohash_insert(&transforms, slot, r); 332 } 333 return r; 334 } 335 336 #ifdef CLEANUP 337 /*- 338 *----------------------------------------------------------------------- 339 * SuffFree -- 340 * Free up all memory associated with the given suffix structure. 341 * 342 * Side Effects: 343 * the suffix entry is detroyed 344 *----------------------------------------------------------------------- 345 */ 346 static void 347 SuffFree(void *sp) 348 { 349 Suff *s = (Suff *)sp; 350 351 if (s == emptySuff) 352 emptySuff = NULL; 353 354 Lst_Destroy(&s->children, NOFREE); 355 Lst_Destroy(&s->parents, NOFREE); 356 Lst_Destroy(&s->searchPath, Dir_Destroy); 357 358 free(s->name); 359 free(s); 360 } 361 #endif 362 363 364 /*- 365 *----------------------------------------------------------------------- 366 * SuffInsert -- 367 * Insert the suffix into the list keeping the list ordered by suffix 368 * numbers. 369 * 370 * Side Effects: 371 * The reference count of the suffix is incremented 372 *----------------------------------------------------------------------- 373 */ 374 static void 375 SuffInsert(Lst l, Suff *s) 376 { 377 LstNode ln; /* current element in l we're examining */ 378 Suff *s2 = NULL; /* the suffix descriptor in this element */ 379 380 for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) { 381 s2 = (Suff *)Lst_Datum(ln); 382 if (s2->order >= s->order) 383 break; 384 } 385 386 if (DEBUG(SUFF)) 387 printf("inserting %s(%d)...", s->name, s->order); 388 if (ln == NULL) { 389 if (DEBUG(SUFF)) 390 printf("at end of list\n"); 391 Lst_AtEnd(l, s); 392 } else if (s2->order != s->order) { 393 if (DEBUG(SUFF)) 394 printf("before %s(%d)\n", s2->name, s2->order); 395 Lst_Insert(l, ln, s); 396 } else if (DEBUG(SUFF)) { 397 printf("already there\n"); 398 } 399 } 400 401 /*- 402 *----------------------------------------------------------------------- 403 * Suff_ClearSuffixes -- 404 * Nuke the list of suffixes but keep all transformation 405 * rules around. 406 * 407 * Side Effects: 408 * Current suffixes are reset 409 *----------------------------------------------------------------------- 410 */ 411 static void 412 clear_suffixes(void) 413 { 414 unsigned int i; 415 Suff *s; 416 417 for (s = ohash_first(&suffixes, &i); s != NULL; 418 s = ohash_next(&suffixes, &i)) 419 s->flags &= ~SUFF_ACTIVE; 420 421 order = 0; 422 maxLen = 0; 423 suffNull = emptySuff; 424 } 425 426 void 427 Suff_ClearSuffixes(void) 428 { 429 clear_suffixes(); 430 } 431 432 433 /* okay = parse_transform(str, &src, &targ); 434 * try parsing a string as a transformation rule, returns true if 435 * successful. Fills &src, &targ with the constituent suffixes. 436 * Special hack: source suffixes must exist OR be the special SUFF_PATH 437 * pseudo suffix (.PATH) 438 */ 439 static bool 440 parse_transformi(const char *str, const char *e, Suff **srcPtr, Suff **targPtr) 441 { 442 Suff *src, *target, *best_src, *best_target; 443 const char *p; 444 445 size_t len; 446 uint32_t hv; 447 unsigned int slot; 448 449 /* empty string -> no suffix */ 450 if (e == str) 451 return false; 452 453 len = e - str; 454 455 if (len > 2 * maxLen) 456 return false; 457 458 p = e; 459 best_src = best_target = NULL; 460 461 hv = *--p; 462 while (p != str) { 463 slot = ohash_lookup_interval(&suffixes, p, e, hv); 464 /* no double suffix in there */ 465 if (p - str <= (ptrdiff_t)maxLen) { 466 target = ohash_find(&suffixes, slot); 467 if (target != NULL && (target->flags & SUFF_ACTIVE)) { 468 src = find_suffi(str, p); 469 if (src != NULL && 470 (src->flags & (SUFF_ACTIVE | SUFF_PATH))) { 471 /* XXX even if we find a set of suffixes, we 472 * have to keep going to find the best one, 473 * namely, the one whose src appears first in 474 * .SUFFIXES 475 */ 476 if (best_src == NULL || 477 src->order < best_src->order) { 478 best_src = src; 479 best_target = target; 480 } 481 } 482 } 483 } 484 /* can't be a suffix anyways */ 485 if (e - p >= (ptrdiff_t)maxLen) 486 break; 487 reverse_hash_add_char(&hv, --p); 488 } 489 490 if (p == str && best_src == NULL) { 491 /* no double suffix transformation, resort to single suffix if 492 * we find one. */ 493 slot = ohash_lookup_interval(&suffixes, p, e, hv); 494 src = ohash_find(&suffixes, slot); 495 if (src != NULL && (src->flags & (SUFF_ACTIVE | SUFF_PATH))) { 496 best_src = src; 497 best_target = suffNull; 498 } 499 } 500 if (best_src != NULL) { 501 *srcPtr = best_src; 502 *targPtr = best_target; 503 return true; 504 } else { 505 return false; 506 } 507 } 508 509 static void 510 special_path_hack(void) 511 { 512 Suff *path = add_suffixi(".PATH", NULL); 513 path->flags |= SUFF_PATH; 514 } 515 516 static Suff * 517 find_best_suffix(const char *s, const char *e) 518 { 519 const char *p; 520 uint32_t hv; 521 unsigned int slot; 522 Suff *best = NULL; 523 Suff *suff; 524 525 if (e == s) 526 return NULL; 527 p = e; 528 hv = *--p; 529 while (p != s) { 530 slot = ohash_lookup_interval(&suffixes, p, e, hv); 531 suff = ohash_find(&suffixes, slot); 532 if (suff != NULL) 533 if (best == NULL || suff->order < best->order) 534 best = suff; 535 if (e - p >= (ptrdiff_t)maxLen) 536 break; 537 reverse_hash_add_char(&hv, --p); 538 } 539 return best; 540 } 541 542 /*- 543 *----------------------------------------------------------------------- 544 * Suff_ParseAsTransform -- 545 * Try parsing a target line as a transformation rule, depending on 546 * existing suffixes. 547 * 548 * Possibly create anew transform, or reset an existing one. 549 *----------------------------------------------------------------------- 550 */ 551 GNode * 552 Suff_ParseAsTransform(const char *line, const char *end) 553 { 554 GNode *gn; /* GNode of transformation rule */ 555 Suff *s; /* source suffix */ 556 Suff *t; /* target suffix */ 557 558 if (!parse_transformi(line, end, &s, &t)) 559 return NULL; 560 561 gn = find_or_create_transformi(line, end); 562 /* In case the transform already exists, nuke old commands and children. 563 * Note we can't free them, since there might be stuff that references 564 * them elsewhere 565 */ 566 if (!Lst_IsEmpty(&gn->commands)) { 567 Lst_Destroy(&gn->commands, NOFREE); 568 Lst_Init(&gn->commands); 569 } 570 if (!Lst_IsEmpty(&gn->children)) { 571 Lst_Destroy(&gn->children, NOFREE); 572 Lst_Init(&gn->children); 573 } 574 575 gn->type = OP_TRANSFORM; 576 if (s->flags & SUFF_PATH) { 577 gn->special = SPECIAL_PATH | SPECIAL_TARGET; 578 gn->suffix = t; 579 } 580 581 if (DEBUG(SUFF)) 582 printf("defining transformation from `%s' to `%s'\n", 583 s->name, t->name); 584 return gn; 585 } 586 587 static void 588 make_suffix_known(Suff *s) 589 { 590 if ((s->flags & SUFF_ACTIVE) == 0) { 591 s->order = order++; 592 s->flags |= SUFF_ACTIVE; 593 if (s->nameLen > maxLen) 594 maxLen = s->nameLen; 595 } 596 } 597 598 static Suff * 599 new_suffixi(const char *str, const char *eptr) 600 { 601 Suff *s; 602 603 s = ohash_create_entry(&suff_info, str, &eptr); 604 s->nameLen = eptr - str; 605 Lst_Init(&s->searchPath); 606 Lst_Init(&s->children); 607 Lst_Init(&s->parents); 608 s->flags = 0; 609 return s; 610 } 611 612 /*- 613 *----------------------------------------------------------------------- 614 * Suff_AddSuffix -- 615 * Add the suffix in string to the end of the list of known suffixes. 616 * Should we restructure the suffix graph? Make doesn't... 617 * 618 * Side Effects: 619 * A GNode is created for the suffix and a Suff structure is created and 620 * added to the known suffixes, unless it was already known. 621 *----------------------------------------------------------------------- 622 */ 623 void 624 Suff_AddSuffixi(const char *str, const char *end) 625 { 626 (void)add_suffixi(str, end); 627 } 628 629 static Suff * 630 add_suffixi(const char *str, const char *end) 631 { 632 Suff *s; /* new suffix descriptor */ 633 634 unsigned int slot; 635 636 slot = reverse_slot(&suffixes, str, &end); 637 s = ohash_find(&suffixes, slot); 638 if (s == NULL) { 639 s = new_suffixi(str, end); 640 ohash_insert(&suffixes, slot, s); 641 } 642 make_suffix_known(s); 643 return s; 644 } 645 646 Lst 647 find_suffix_path(GNode *gn) 648 { 649 if (gn->suffix != NULL && gn->suffix != emptySuff) 650 return &(gn->suffix->searchPath); 651 else 652 return defaultPath; 653 } 654 655 /* find out the tagged suffixes, build a temporary path, and construct 656 * a variable based on that. 657 */ 658 static void 659 build_path_variable(struct ohash *h, int opt, const char *name, 660 const char *flag) 661 { 662 char *value; 663 LIST path; 664 Suff *s; 665 unsigned int i; 666 667 Lst_Init(&path); 668 for (s = ohash_first(h, &i); s != NULL; s = ohash_next(h, &i)) { 669 if (Lst_IsEmpty(&s->searchPath)) 670 continue; 671 if (s->flags & opt) 672 Dir_Concat(&path, &s->searchPath); 673 } 674 675 value = Dir_MakeFlags(flag, &path); 676 Var_Set(name, value); 677 free(value); 678 Lst_Destroy(&path, Dir_Destroy); 679 } 680 681 static void 682 add_property(const char *sname, const char *end, int opt) 683 { 684 Suff *s; 685 686 s = find_suffi(sname, end); 687 if (s != NULL) { 688 s->flags |= opt; 689 } 690 } 691 692 void 693 Suff_AddIncludei(const char *sname, const char *end) 694 { 695 add_property(sname, end, SUFF_INCLUDE); 696 } 697 698 void 699 Suff_AddLibi(const char *sname, const char *end) 700 { 701 add_property(sname, end, SUFF_LIBRARY); 702 } 703 704 static void 705 build_suffixes_graph(void) 706 { 707 Suff *s, *s2; 708 GNode *gn; 709 unsigned int i; 710 711 for (gn = ohash_first(&transforms, &i); gn != NULL; 712 gn = ohash_next(&transforms, &i)) { 713 if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children)) 714 continue; 715 if ((gn->special & SPECIAL_MASK) == SPECIAL_PATH) 716 continue; 717 if (parse_transform(gn->name, &s, &s2)) { 718 SuffInsert(&s2->children, s); 719 SuffInsert(&s->parents, s2); 720 } 721 } 722 } 723 724 /*- 725 *----------------------------------------------------------------------- 726 * setup_paths 727 * Extend the search paths for all suffixes to include the default 728 * search path. 729 * 730 * Side Effects: 731 * The searchPath field of all the suffixes is extended by the 732 * directories in defaultPath. If paths were specified for the 733 * ".h" suffix, the directories are stuffed into a global variable 734 * called ".INCLUDES" with each directory preceded by a -I. The same 735 * is done for the ".a" suffix, except the variable is called 736 * ".LIBS" and the flag is -L. 737 *----------------------------------------------------------------------- 738 */ 739 static void 740 setup_paths(void) 741 { 742 unsigned int i; 743 Suff *s; 744 745 for (s = ohash_first(&suffixes, &i); s != NULL; 746 s = ohash_next(&suffixes, &i)) { 747 if (!Lst_IsEmpty(&s->searchPath)) 748 Dir_Concat(&s->searchPath, defaultPath); 749 else 750 Lst_Clone(&s->searchPath, defaultPath, Dir_CopyDir); 751 } 752 753 build_path_variable(&suffixes, SUFF_INCLUDE, ".INCLUDES", "-I"); 754 build_path_variable(&suffixes, SUFF_LIBRARY, ".LIBS", "-L"); 755 } 756 757 void 758 process_suffixes_after_makefile_is_read(void) 759 { 760 /* once the Makefile is finish reading, we can set up the default PATH 761 * stuff, and build the final suffixes graph 762 */ 763 setup_paths(); 764 /* and we link all transforms to active suffixes at this point. */ 765 build_suffixes_graph(); 766 } 767 /********** Implicit Source Search Functions *********/ 768 769 /*- 770 *----------------------------------------------------------------------- 771 * SuffAddSrc -- 772 * Add a suffix as a Src structure to the given list with its parent 773 * being the given Src structure. If the suffix is the null suffix, 774 * the prefix is used unaltered as the file name in the Src structure. 775 * 776 * Side Effects: 777 * A Src structure is created and tacked onto the end of the list 778 *----------------------------------------------------------------------- 779 */ 780 static void 781 SuffAddSrc( 782 void *sp, /* suffix for which to create a Src structure */ 783 void *lsp) /* list and parent for the new Src */ 784 { 785 Suff *s = (Suff *)sp; 786 LstSrc *ls = (LstSrc *)lsp; 787 Src *s2; /* new Src structure */ 788 Src *targ; /* Target structure */ 789 790 targ = ls->s; 791 792 if ((s->flags & SUFF_NULL) && *s->name != '\0') { 793 /* 794 * If the suffix has been marked as the NULL suffix, also 795 * create a Src structure for a file with no suffix attached. 796 * Two birds, and all that... 797 */ 798 s2 = emalloc(sizeof(Src)); 799 s2->file = estrdup(targ->pref); 800 s2->pref = targ->pref; 801 s2->parent = targ; 802 s2->node = NULL; 803 s2->suff = s; 804 s2->children = 0; 805 targ->children++; 806 Lst_AtEnd(ls->l, s2); 807 #ifdef DEBUG_SRC 808 Lst_Init(&s2->cp); 809 Lst_AtEnd(&targ->cp, s2); 810 printf("1 add %x %x to %x:", targ, s2, ls->l); 811 Lst_Every(ls->l, PrintAddr); 812 printf("\n"); 813 #endif 814 } 815 s2 = emalloc(sizeof(Src)); 816 s2->file = Str_concat(targ->pref, s->name, 0); 817 s2->pref = targ->pref; 818 s2->parent = targ; 819 s2->node = NULL; 820 s2->suff = s; 821 s2->children = 0; 822 targ->children++; 823 Lst_AtEnd(ls->l, s2); 824 #ifdef DEBUG_SRC 825 Lst_Init(&s2->cp); 826 Lst_AtEnd(&targ->cp, s2); 827 printf("2 add %x %x to %x:", targ, s2, ls->l); 828 Lst_Every(ls->l, PrintAddr); 829 printf("\n"); 830 #endif 831 832 } 833 834 /*- 835 *----------------------------------------------------------------------- 836 * SuffAddLevel -- 837 * Add all the children of targ as Src structures to the given list 838 * 839 * Side Effects: 840 * Lots of structures are created and added to the list 841 *----------------------------------------------------------------------- 842 */ 843 static void 844 SuffAddLevel( 845 Lst l, /* list to which to add the new level */ 846 Src *targ) /* Src structure to use as the parent */ 847 { 848 LstSrc ls; 849 850 ls.s = targ; 851 ls.l = l; 852 853 Lst_ForEach(&targ->suff->children, SuffAddSrc, &ls); 854 } 855 856 /*- 857 *---------------------------------------------------------------------- 858 * SuffRemoveSrc -- 859 * Free all src structures in list that don't have a reference count 860 * 861 * Results: 862 * Ture if an src was removed 863 * 864 * Side Effects: 865 * The memory is free'd. 866 *---------------------------------------------------------------------- 867 */ 868 static int 869 SuffRemoveSrc(Lst l) 870 { 871 LstNode ln; 872 Src *s; 873 int t = 0; 874 875 #ifdef DEBUG_SRC 876 printf("cleaning %lx: ", (unsigned long)l); 877 Lst_Every(l, PrintAddr); 878 printf("\n"); 879 #endif 880 881 882 for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) { 883 s = (Src *)Lst_Datum(ln); 884 if (s->children == 0) { 885 free(s->file); 886 if (!s->parent) 887 free(s->pref); 888 else { 889 #ifdef DEBUG_SRC 890 LstNode ln2 = Lst_Member(&s->parent->cp, s); 891 if (ln2 != NULL) 892 Lst_Remove(&s->parent->cp, ln2); 893 #endif 894 --s->parent->children; 895 } 896 #ifdef DEBUG_SRC 897 printf("free: [l=%x] p=%x %d\n", l, s, s->children); 898 Lst_Destroy(&s->cp, NOFREE); 899 #endif 900 Lst_Remove(l, ln); 901 free(s); 902 t |= 1; 903 return true; 904 } 905 #ifdef DEBUG_SRC 906 else { 907 printf("keep: [l=%x] p=%x %d: ", l, s, s->children); 908 Lst_Every(&s->cp, PrintAddr); 909 printf("\n"); 910 } 911 #endif 912 } 913 914 return t; 915 } 916 917 /*- 918 *----------------------------------------------------------------------- 919 * SuffFindThem -- 920 * Find the first existing file/target in the list srcs 921 * 922 * Results: 923 * The lowest structure in the chain of transformations 924 *----------------------------------------------------------------------- 925 */ 926 static Src * 927 SuffFindThem( 928 Lst srcs, /* list of Src structures to search through */ 929 Lst slst) 930 { 931 Src *s; /* current Src */ 932 Src *rs; /* returned Src */ 933 char *ptr; 934 935 rs = NULL; 936 937 while ((s = (Src *)Lst_DeQueue(srcs)) != NULL) { 938 if (DEBUG(SUFF)) 939 printf("\ttrying %s...", s->file); 940 941 /* 942 * A file is considered to exist if either a node exists in the 943 * graph for it or the file actually exists. 944 */ 945 if (Targ_FindNode(s->file, TARG_NOCREATE) != NULL) { 946 #ifdef DEBUG_SRC 947 printf("remove %x from %x\n", s, srcs); 948 #endif 949 rs = s; 950 break; 951 } 952 953 if ((ptr = Dir_FindFile(s->file, &s->suff->searchPath)) 954 != NULL) { 955 rs = s; 956 #ifdef DEBUG_SRC 957 printf("remove %x from %x\n", s, srcs); 958 #endif 959 free(ptr); 960 break; 961 } 962 963 if (DEBUG(SUFF)) 964 printf("not there\n"); 965 966 SuffAddLevel(srcs, s); 967 Lst_AtEnd(slst, s); 968 } 969 970 if (DEBUG(SUFF) && rs) 971 printf("got it\n"); 972 return rs; 973 } 974 975 /*- 976 *----------------------------------------------------------------------- 977 * SuffFindCmds -- 978 * See if any of the children of the target in the Src structure is 979 * one from which the target can be transformed. If there is one, 980 * a Src structure is put together for it and returned. 981 * 982 * Results: 983 * The Src structure of the "winning" child, or NULL if no such beast. 984 * 985 * Side Effects: 986 * A Src structure may be allocated. 987 *----------------------------------------------------------------------- 988 */ 989 static Src * 990 SuffFindCmds( 991 Src *targ, /* Src structure to play with */ 992 Lst slst) 993 { 994 LstNode ln; /* General-purpose list node */ 995 GNode *t; /* Target GNode */ 996 GNode *s; /* Source GNode */ 997 int prefLen; /* The length of the defined prefix */ 998 Suff *suff; /* Suffix on matching beastie */ 999 Src *ret; /* Return value */ 1000 const char *cp; 1001 1002 t = targ->node; 1003 prefLen = strlen(targ->pref); 1004 1005 for (ln = Lst_First(&t->children); ln != NULL; ln = Lst_Adv(ln)) { 1006 s = (GNode *)Lst_Datum(ln); 1007 1008 cp = strrchr(s->name, '/'); 1009 if (cp == NULL) { 1010 cp = s->name; 1011 } else { 1012 cp++; 1013 } 1014 if (strncmp(cp, targ->pref, prefLen) == 0) { 1015 /* The node matches the prefix ok, see if it has a known 1016 * suffix. */ 1017 suff = find_suff(&cp[prefLen]); 1018 if (suff != NULL) { 1019 /* 1020 * It even has a known suffix, see if there's a 1021 * transformation defined between the node's 1022 * suffix and the target's suffix. 1023 * 1024 * XXX: Handle multi-stage transformations 1025 * here, too. 1026 */ 1027 if (Lst_Member(&suff->parents, targ->suff) 1028 != NULL) { 1029 /* 1030 * Hot Damn! Create a new Src structure 1031 * to describe this transformation 1032 * (making sure to duplicate the source 1033 * node's name so Suff_FindDeps can 1034 * free it again (ick)), and return the 1035 * new structure. 1036 */ 1037 ret = emalloc(sizeof(Src)); 1038 ret->file = estrdup(s->name); 1039 ret->pref = targ->pref; 1040 ret->suff = suff; 1041 ret->parent = targ; 1042 ret->node = s; 1043 ret->children = 0; 1044 targ->children++; 1045 #ifdef DEBUG_SRC 1046 Lst_Init(&ret->cp); 1047 printf("3 add %x %x\n", targ, ret); 1048 Lst_AtEnd(&targ->cp, ret); 1049 #endif 1050 Lst_AtEnd(slst, ret); 1051 if (DEBUG(SUFF)) 1052 printf( 1053 "\tusing existing source %s\n", 1054 s->name); 1055 return ret; 1056 } 1057 } 1058 } 1059 } 1060 return NULL; 1061 } 1062 1063 static void 1064 SuffLinkParent(GNode *cgn, GNode *pgn) 1065 { 1066 Lst_AtEnd(&cgn->parents, pgn); 1067 if (!has_been_built(cgn)) 1068 pgn->unmade++; 1069 else if ( ! (cgn->type & (OP_EXEC|OP_USE))) { 1070 if (cgn->built_status == MADE) 1071 pgn->childMade = true; 1072 (void)Make_TimeStamp(pgn, cgn); 1073 } 1074 } 1075 1076 static void 1077 SuffExpandVarChildren(LstNode after, GNode *cgn, GNode *pgn) 1078 { 1079 GNode *gn; /* New source 8) */ 1080 char *cp; /* Expanded value */ 1081 LIST members; 1082 1083 1084 if (DEBUG(SUFF)) 1085 printf("Expanding \"%s\"...", cgn->name); 1086 1087 cp = Var_Subst(cgn->name, &pgn->context, true); 1088 if (cp == NULL) { 1089 printf("Problem substituting in %s", cgn->name); 1090 printf("\n"); 1091 return; 1092 } 1093 1094 Lst_Init(&members); 1095 1096 if (cgn->type & OP_ARCHV) { 1097 /* 1098 * Node was an archive(member) target, so we want to call 1099 * on the Arch module to find the nodes for us, expanding 1100 * variables in the parent's context. 1101 */ 1102 const char *sacrifice = (const char *)cp; 1103 1104 (void)Arch_ParseArchive(&sacrifice, &members, &pgn->context); 1105 } else { 1106 /* Break the result into a vector of strings whose nodes 1107 * we can find, then add those nodes to the members list. 1108 * Unfortunately, we can't use brk_string because it 1109 * doesn't understand about variable specifications with 1110 * spaces in them... */ 1111 const char *start, *cp2; 1112 1113 for (start = cp; *start == ' ' || *start == '\t'; start++) 1114 continue; 1115 for (cp2 = start; *cp2 != '\0';) { 1116 if (isspace(*cp2)) { 1117 /* White-space -- terminate element, find the 1118 * node, add it, skip any further spaces. */ 1119 gn = Targ_FindNodei(start, cp2, TARG_CREATE); 1120 cp2++; 1121 Lst_AtEnd(&members, gn); 1122 while (isspace(*cp2)) 1123 cp2++; 1124 /* Adjust cp2 for increment at start of loop, 1125 * but set start to first non-space. */ 1126 start = cp2; 1127 } else if (*cp2 == '$') 1128 /* Start of a variable spec -- contact variable 1129 * module to find the end so we can skip over 1130 * it. */ 1131 Var_ParseSkip(&cp2, &pgn->context); 1132 else if (*cp2 == '\\' && cp2[1] != '\0') 1133 /* Escaped something -- skip over it. */ 1134 cp2+=2; 1135 else 1136 cp2++; 1137 } 1138 1139 if (cp2 != start) { 1140 /* Stuff left over -- add it to the list too. */ 1141 gn = Targ_FindNodei(start, cp2, TARG_CREATE); 1142 Lst_AtEnd(&members, gn); 1143 } 1144 } 1145 /* Add all elements of the members list to the parent node. */ 1146 while ((gn = (GNode *)Lst_DeQueue(&members)) != NULL) { 1147 if (DEBUG(SUFF)) 1148 printf("%s...", gn->name); 1149 if (Lst_Member(&pgn->children, gn) == NULL) { 1150 Lst_Append(&pgn->children, after, gn); 1151 after = Lst_Adv(after); 1152 SuffLinkParent(gn, pgn); 1153 } 1154 } 1155 /* Free the result. */ 1156 free(cp); 1157 if (DEBUG(SUFF)) 1158 printf("\n"); 1159 } 1160 1161 static void 1162 SuffExpandWildChildren(LstNode after, GNode *cgn, GNode *pgn) 1163 { 1164 Suff *s; 1165 char *cp; /* Expanded value */ 1166 1167 LIST exp; /* List of expansions */ 1168 Lst path; /* Search path along which to expand */ 1169 1170 if (DEBUG(SUFF)) 1171 printf("Wildcard expanding \"%s\"...", cgn->name); 1172 1173 /* Find a path along which to expand the word. 1174 * 1175 * If the word has a known suffix, use that path. 1176 * If it has no known suffix and we're allowed to use the null 1177 * suffix, use its path. 1178 * Else use the default system search path. */ 1179 s = find_best_suffix(cgn->name, cgn->name + strlen(cgn->name)); 1180 1181 if (s != NULL) { 1182 if (DEBUG(SUFF)) 1183 printf("suffix is \"%s\"...", s->name); 1184 path = &s->searchPath; 1185 } else 1186 /* Use default search path. */ 1187 path = defaultPath; 1188 1189 /* Expand the word along the chosen path. */ 1190 Lst_Init(&exp); 1191 Dir_Expand(cgn->name, path, &exp); 1192 1193 /* Fetch next expansion off the list and find its GNode. */ 1194 while ((cp = (char *)Lst_DeQueue(&exp)) != NULL) { 1195 GNode *gn; /* New source 8) */ 1196 if (DEBUG(SUFF)) 1197 printf("%s...", cp); 1198 gn = Targ_FindNode(cp, TARG_CREATE); 1199 1200 /* If gn isn't already a child of the parent, make it so and 1201 * up the parent's count of unmade children. */ 1202 if (Lst_Member(&pgn->children, gn) == NULL) { 1203 Lst_Append(&pgn->children, after, gn); 1204 after = Lst_Adv(after); 1205 SuffLinkParent(gn, pgn); 1206 } 1207 } 1208 1209 if (DEBUG(SUFF)) 1210 printf("\n"); 1211 } 1212 1213 /*- 1214 *----------------------------------------------------------------------- 1215 * SuffExpandChildren -- 1216 * Expand the names of any children of a given node that contain 1217 * variable invocations or file wildcards into actual targets. 1218 * 1219 * Side Effects: 1220 * The expanded node is removed from the parent's list of children, 1221 * and the parent's unmade counter is decremented, but other nodes 1222 * may be added. 1223 *----------------------------------------------------------------------- 1224 */ 1225 static void 1226 SuffExpandChildren(LstNode ln, /* LstNode of child, so we can replace it */ 1227 GNode *pgn) 1228 { 1229 GNode *cgn = (GNode *)Lst_Datum(ln); 1230 1231 /* First do variable expansion -- this takes precedence over wildcard 1232 * expansion. If the result contains wildcards, they'll be gotten to 1233 * later since the resulting words are tacked on to the end of the 1234 * children list. */ 1235 if (strchr(cgn->name, '$') != NULL) 1236 SuffExpandVarChildren(ln, cgn, pgn); 1237 else if (Dir_HasWildcards(cgn->name)) 1238 SuffExpandWildChildren(ln, cgn, pgn); 1239 else 1240 /* Third case: nothing to expand. */ 1241 return; 1242 1243 /* Since the source was expanded, remove it from the list of children to 1244 * keep it from being processed. */ 1245 pgn->unmade--; 1246 Lst_Remove(&pgn->children, ln); 1247 } 1248 1249 void 1250 expand_children_from(GNode *parent, LstNode from) 1251 { 1252 LstNode np, ln; 1253 1254 for (ln = from; ln != NULL; ln = np) { 1255 np = Lst_Adv(ln); 1256 SuffExpandChildren(ln, parent); 1257 } 1258 } 1259 1260 /*- 1261 *----------------------------------------------------------------------- 1262 * SuffApplyTransform -- 1263 * Apply a transformation rule, given the source and target nodes 1264 * and suffixes. 1265 * 1266 * Results: 1267 * true if successful, false if not. 1268 * 1269 * Side Effects: 1270 * The source and target are linked and the commands from the 1271 * transformation are added to the target node's commands list. 1272 * All attributes but OP_DEPMASK and OP_TRANSFORM are applied 1273 * to the target. The target also inherits all the sources for 1274 * the transformation rule. 1275 *----------------------------------------------------------------------- 1276 */ 1277 static bool 1278 SuffApplyTransform( 1279 GNode *tGn, /* Target node */ 1280 GNode *sGn, /* Source node */ 1281 Suff *t, /* Target suffix */ 1282 Suff *s) /* Source suffix */ 1283 { 1284 LstNode ln; /* General node */ 1285 char *tname; /* Name of transformation rule */ 1286 GNode *gn; /* Node for same */ 1287 1288 if (Lst_AddNew(&tGn->children, sGn)) { 1289 /* Not already linked, so form the proper links between the 1290 * target and source. */ 1291 SuffLinkParent(sGn, tGn); 1292 } 1293 1294 if ((sGn->type & OP_OPMASK) == OP_DOUBLEDEP) { 1295 /* When a :: node is used as the implied source of a node, we 1296 * have to link all its cohorts in as sources as well. There's 1297 * only one implied src, as that will be sufficient to get 1298 * the .IMPSRC variable set for tGn. */ 1299 for (ln=Lst_First(&sGn->cohorts); ln != NULL; ln=Lst_Adv(ln)) { 1300 gn = (GNode *)Lst_Datum(ln); 1301 1302 if (Lst_AddNew(&tGn->children, gn)) { 1303 /* Not already linked, so form the proper links 1304 * between the target and source. */ 1305 SuffLinkParent(gn, tGn); 1306 } 1307 } 1308 } 1309 /* Locate the transformation rule itself. */ 1310 tname = Str_concat(s->name, t->name, 0); 1311 gn = find_transform(tname); 1312 free(tname); 1313 1314 if (gn == NULL) 1315 /* 1316 * Not really such a transformation rule (can happen when we're 1317 * called to link an OP_MEMBER and OP_ARCHV node), so return 1318 * false. 1319 */ 1320 return false; 1321 1322 if (DEBUG(SUFF)) 1323 printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, 1324 tGn->name); 1325 1326 /* Record last child for expansion purposes. */ 1327 ln = Lst_Last(&tGn->children); 1328 1329 /* Pass the buck to Make_HandleUse to apply the rule. */ 1330 Make_HandleUse(gn, tGn); 1331 1332 /* Deal with wildcards and variables in any acquired sources. */ 1333 expand_children_from(tGn, Lst_Succ(ln)); 1334 1335 /* Keep track of another parent to which this beast is transformed so 1336 * the .IMPSRC variable can be set correctly for the parent. */ 1337 tGn->impliedsrc = sGn; 1338 1339 return true; 1340 } 1341 1342 static Suff * 1343 find_suffix_as_suffix(Lst l, const char *b, const char *e) 1344 { 1345 LstNode ln; 1346 Suff *s; 1347 1348 for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) { 1349 s = (Suff *)Lst_Datum(ln); 1350 if (suffix_is_suffix(s, b, e)) 1351 return s; 1352 } 1353 return NULL; 1354 } 1355 1356 /*- 1357 *----------------------------------------------------------------------- 1358 * SuffFindArchiveDeps -- 1359 * Locate dependencies for an OP_ARCHV node. 1360 * 1361 * Side Effects: 1362 * Same as Suff_FindDeps 1363 *----------------------------------------------------------------------- 1364 */ 1365 static void 1366 SuffFindArchiveDeps( 1367 GNode *gn, /* Node for which to locate dependencies */ 1368 Lst slst) 1369 { 1370 char *eoarch; /* End of archive portion */ 1371 char *eoname; /* End of member portion */ 1372 GNode *mem; /* Node for member */ 1373 Suff *ms; /* Suffix descriptor for member */ 1374 char *name; /* Start of member's name */ 1375 1376 /* The node is an archive(member) pair. so we must find a suffix 1377 * for both of them. */ 1378 eoarch = strchr(gn->name, '('); 1379 if (eoarch == NULL) 1380 return; 1381 1382 name = eoarch + 1; 1383 1384 eoname = strchr(name, ')'); 1385 if (eoname == NULL) 1386 return; 1387 1388 /* To simplify things, call Suff_FindDeps recursively on the member now, 1389 * so we can simply compare the member's .PREFIX and .TARGET variables 1390 * to locate its suffix. This allows us to figure out the suffix to 1391 * use for the archive without having to do a quadratic search over the 1392 * suffix list, backtracking for each one... */ 1393 mem = Targ_FindNodei(name, eoname, TARG_CREATE); 1394 SuffFindDeps(mem, slst); 1395 1396 /* Create the link between the two nodes right off. */ 1397 if (Lst_AddNew(&gn->children, mem)) 1398 SuffLinkParent(mem, gn); 1399 1400 /* Copy variables from member node to this one. */ 1401 Var(TARGET_INDEX, gn) = Var(TARGET_INDEX, mem); 1402 Var(PREFIX_INDEX, gn) = Var(PREFIX_INDEX, mem); 1403 1404 ms = mem->suffix; 1405 if (ms == NULL) { 1406 /* Didn't know what it was -- use .NULL suffix if not in make 1407 * mode. */ 1408 if (DEBUG(SUFF)) 1409 printf("using null suffix\n"); 1410 ms = suffNull; 1411 } 1412 1413 1414 /* Set the other two local variables required for this target. */ 1415 Var(MEMBER_INDEX, gn) = mem->name; 1416 Var(ARCHIVE_INDEX, gn) = gn->name; 1417 1418 if (ms != NULL) { 1419 /* 1420 * Member has a known suffix, so look for a transformation rule 1421 * from it to a possible suffix of the archive. Rather than 1422 * searching through the entire list, we just look at suffixes 1423 * to which the member's suffix may be transformed... 1424 */ 1425 1426 Suff *suff; 1427 1428 suff = find_suffix_as_suffix(&ms->parents, gn->name, eoarch); 1429 1430 if (suff != NULL) { 1431 /* Got one -- apply it. */ 1432 if (!SuffApplyTransform(gn, mem, suff, ms) && 1433 DEBUG(SUFF)) 1434 printf("\tNo transformation from %s -> %s\n", 1435 ms->name, suff->name); 1436 } 1437 } 1438 1439 /* Pretend gn appeared to the left of a dependency operator so 1440 * the user needn't provide a transformation from the member to the 1441 * archive. */ 1442 if (OP_NOP(gn->type)) 1443 gn->type |= OP_DEPENDS; 1444 1445 /* Flag the member as such so we remember to look in the archive for 1446 * its modification time. */ 1447 mem->type |= OP_MEMBER; 1448 } 1449 1450 static void 1451 record_possible_suffix(Suff *s, GNode *gn, char *eoname, Lst srcs, Lst targs) 1452 { 1453 int prefLen; 1454 Src *targ; 1455 char *sopref = gn->name; 1456 1457 targ = emalloc(sizeof(Src)); 1458 targ->file = estrdup(gn->name); 1459 targ->suff = s; 1460 targ->node = gn; 1461 targ->parent = NULL; 1462 targ->children = 0; 1463 #ifdef DEBUG_SRC 1464 Lst_Init(&targ->cp); 1465 #endif 1466 1467 /* Allocate room for the prefix, whose end is found by 1468 * subtracting the length of the suffix from the end of 1469 * the name. */ 1470 prefLen = (eoname - targ->suff->nameLen) - sopref; 1471 targ->pref = emalloc(prefLen + 1); 1472 memcpy(targ->pref, sopref, prefLen); 1473 targ->pref[prefLen] = '\0'; 1474 1475 /* Add nodes from which the target can be made. */ 1476 SuffAddLevel(srcs, targ); 1477 1478 /* Record the target so we can nuke it. */ 1479 Lst_AtEnd(targs, targ); 1480 } 1481 1482 static void 1483 record_possible_suffixes(GNode *gn, Lst srcs, Lst targs) 1484 { 1485 char *s = gn->name; 1486 char *e = s + strlen(s); 1487 const char *p; 1488 uint32_t hv; 1489 unsigned int slot; 1490 Suff *suff; 1491 1492 if (e == s) 1493 return; 1494 1495 p = e; 1496 hv = *--p; 1497 1498 while (p != s) { 1499 slot = ohash_lookup_interval(&suffixes, p, e, hv); 1500 suff = ohash_find(&suffixes, slot); 1501 if (suff != NULL && (suff->flags & SUFF_ACTIVE)) 1502 record_possible_suffix(suff, gn, e, srcs, targs); 1503 if (e - p >= (ptrdiff_t)maxLen) 1504 break; 1505 reverse_hash_add_char(&hv, --p); 1506 } 1507 } 1508 1509 /*- 1510 *----------------------------------------------------------------------- 1511 * SuffFindNormalDeps -- 1512 * Locate implicit dependencies for regular targets. 1513 * 1514 * Side Effects: 1515 * Same as Suff_FindDeps... 1516 *----------------------------------------------------------------------- 1517 */ 1518 static void 1519 SuffFindNormalDeps( 1520 GNode *gn, /* Node for which to find sources */ 1521 Lst slst) 1522 { 1523 LIST srcs; /* List of sources at which to look */ 1524 LIST targs; /* List of targets to which things can be 1525 * transformed. They all have the same file, 1526 * but different suff and pref fields */ 1527 Src *bottom; /* Start of found transformation path */ 1528 Src *src; /* General Src pointer */ 1529 char *pref; /* Prefix to use */ 1530 Src *targ; /* General Src target pointer */ 1531 1532 1533 Lst_Init(&srcs); 1534 Lst_Init(&targs); 1535 1536 /* We're caught in a catch-22 here. On the one hand, we want to use any 1537 * transformation implied by the target's sources, but we can't examine 1538 * the sources until we've expanded any variables/wildcards they may 1539 * hold, and we can't do that until we've set up the target's local 1540 * variables and we can't do that until we know what the proper suffix 1541 * for the target is (in case there are two suffixes one of which is a 1542 * suffix of the other) and we can't know that until we've found its 1543 * implied source, which we may not want to use if there's an existing 1544 * source that implies a different transformation. 1545 * 1546 * In an attempt to get around this, which may not work all the time, 1547 * but should work most of the time, we look for implied sources first, 1548 * checking transformations to all possible suffixes of the target, use 1549 * what we find to set the target's local variables, expand the 1550 * children, then look for any overriding transformations they imply. 1551 * Should we find one, we discard the one we found before. */ 1552 1553 1554 record_possible_suffixes(gn, &srcs, &targs); 1555 /* Handle target of unknown suffix... */ 1556 if (Lst_IsEmpty(&srcs)) { 1557 if (DEBUG(SUFF)) 1558 printf("\tNo known suffix on %s. Using .NULL suffix\n", 1559 gn->name); 1560 1561 targ = emalloc(sizeof(Src)); 1562 targ->file = estrdup(gn->name); 1563 targ->suff = suffNull; 1564 targ->node = gn; 1565 targ->parent = NULL; 1566 targ->children = 0; 1567 targ->pref = estrdup(gn->name); 1568 #ifdef DEBUG_SRC 1569 Lst_Init(&targ->cp); 1570 #endif 1571 1572 /* Only use the default suffix rules if we don't have commands 1573 * or dependencies defined for this gnode. */ 1574 if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children)) 1575 SuffAddLevel(&srcs, targ); 1576 else { 1577 if (DEBUG(SUFF)) 1578 printf("not "); 1579 } 1580 1581 if (DEBUG(SUFF)) 1582 printf("adding suffix rules\n"); 1583 1584 Lst_AtEnd(&targs, targ); 1585 } 1586 1587 /* Using the list of possible sources built up from the target 1588 * suffix(es), try and find an existing file/target that matches. */ 1589 bottom = SuffFindThem(&srcs, slst); 1590 1591 if (bottom == NULL) { 1592 /* No known transformations -- use the first suffix found for 1593 * setting the local variables. */ 1594 if (!Lst_IsEmpty(&targs)) 1595 targ = (Src *)Lst_Datum(Lst_First(&targs)); 1596 else 1597 targ = NULL; 1598 } else { 1599 /* Work up the transformation path to find the suffix of the 1600 * target to which the transformation was made. */ 1601 for (targ = bottom; targ->parent != NULL; targ = targ->parent) 1602 continue; 1603 } 1604 1605 /* The .TARGET variable we always set to be the name at this point, 1606 * since it's only set to the path if the thing is only a source and 1607 * if it's only a source, it doesn't matter what we put here as far 1608 * as expanding sources is concerned, since it has none... */ 1609 Var(TARGET_INDEX, gn) = gn->name; 1610 1611 pref = targ != NULL ? estrdup(targ->pref) : gn->name; 1612 Var(PREFIX_INDEX, gn) = pref; 1613 1614 /* Now we've got the important local variables set, expand any sources 1615 * that still contain variables or wildcards in their names. */ 1616 expand_all_children(gn); 1617 1618 if (targ == NULL) { 1619 if (DEBUG(SUFF)) 1620 printf("\tNo valid suffix on %s\n", gn->name); 1621 1622 sfnd_abort: 1623 /* Deal with finding the thing on the default search path if the 1624 * node is only a source (not on the lhs of a dependency operator 1625 * or [XXX] it has neither children or commands). */ 1626 if (OP_NOP(gn->type) || 1627 (Lst_IsEmpty(&gn->children) && 1628 Lst_IsEmpty(&gn->commands))) { 1629 gn->path = Dir_FindFile(gn->name, 1630 (targ == NULL ? defaultPath : 1631 &targ->suff->searchPath)); 1632 if (gn->path != NULL) { 1633 char *ptr; 1634 Var(TARGET_INDEX, gn) = estrdup(gn->path); 1635 1636 if (targ != NULL) { 1637 /* Suffix known for the thing -- trim 1638 * the suffix off the path to form the 1639 * proper .PREFIX variable. */ 1640 int savep = strlen(gn->path) - 1641 targ->suff->nameLen; 1642 char savec; 1643 1644 gn->suffix = targ->suff; 1645 1646 savec = gn->path[savep]; 1647 gn->path[savep] = '\0'; 1648 1649 if ((ptr = strrchr(gn->path, '/')) != 1650 NULL) 1651 ptr++; 1652 else 1653 ptr = gn->path; 1654 1655 Var(PREFIX_INDEX, gn) = estrdup(ptr); 1656 1657 gn->path[savep] = savec; 1658 } else { 1659 /* The .PREFIX gets the full path if the 1660 * target has no known suffix. */ 1661 gn->suffix = NULL; 1662 1663 if ((ptr = strrchr(gn->path, '/')) != 1664 NULL) 1665 ptr++; 1666 else 1667 ptr = gn->path; 1668 1669 Var(PREFIX_INDEX, gn) = estrdup(ptr); 1670 } 1671 } 1672 } else { 1673 /* Not appropriate to search for the thing -- set the 1674 * path to be the name so Dir_MTime won't go grovelling 1675 * for it. */ 1676 gn->suffix = targ == NULL ? NULL : targ->suff; 1677 efree(gn->path); 1678 gn->path = estrdup(gn->name); 1679 } 1680 1681 goto sfnd_return; 1682 } 1683 1684 /* If the suffix indicates that the target is a library, mark that in 1685 * the node's type field. */ 1686 if (targ->suff->flags & SUFF_LIBRARY) { 1687 gn->type |= OP_LIB; 1688 } 1689 1690 /* Check for overriding transformation rule implied by sources. */ 1691 if (!Lst_IsEmpty(&gn->children)) { 1692 src = SuffFindCmds(targ, slst); 1693 1694 if (src != NULL) { 1695 /* Free up all the Src structures in the transformation 1696 * path up to, but not including, the parent node. */ 1697 while (bottom && bottom->parent != NULL) { 1698 (void)Lst_AddNew(slst, bottom); 1699 bottom = bottom->parent; 1700 } 1701 bottom = src; 1702 } 1703 } 1704 1705 if (bottom == NULL) { 1706 /* No idea from where it can come -- return now. */ 1707 goto sfnd_abort; 1708 } 1709 1710 /* We now have a list of Src structures headed by 'bottom' and linked 1711 * via their 'parent' pointers. What we do next is create links between 1712 * source and target nodes (which may or may not have been created) and 1713 * set the necessary local variables in each target. The commands for 1714 * each target are set from the commands of the transformation rule 1715 * used to get from the src suffix to the targ suffix. Note that this 1716 * causes the commands list of the original node, gn, to be replaced by 1717 * the commands of the final transformation rule. Also, the unmade 1718 * field of gn is incremented. Etc. */ 1719 if (bottom->node == NULL) { 1720 bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); 1721 } 1722 1723 for (src = bottom; src->parent != NULL; src = src->parent) { 1724 targ = src->parent; 1725 1726 src->node->suffix = src->suff; 1727 1728 if (targ->node == NULL) { 1729 targ->node = Targ_FindNode(targ->file, TARG_CREATE); 1730 } 1731 1732 SuffApplyTransform(targ->node, src->node, 1733 targ->suff, src->suff); 1734 1735 if (targ->node != gn) { 1736 /* Finish off the dependency-search process for any 1737 * nodes between bottom and gn (no point in questing 1738 * around the filesystem for their implicit source when 1739 * it's already known). Note that the node can't have 1740 * any sources that need expanding, since SuffFindThem 1741 * will stop on an existing node, so all we need to do 1742 * is set the standard and System V variables. */ 1743 targ->node->type |= OP_DEPS_FOUND; 1744 1745 Var(PREFIX_INDEX, targ->node) = estrdup(targ->pref); 1746 1747 Var(TARGET_INDEX, targ->node) = targ->node->name; 1748 } 1749 } 1750 1751 gn->suffix = src->suff; 1752 1753 /* So Dir_MTime doesn't go questing for it... */ 1754 efree(gn->path); 1755 gn->path = estrdup(gn->name); 1756 1757 /* Nuke the transformation path and the Src structures left over in the 1758 * two lists. */ 1759 sfnd_return: 1760 if (bottom) 1761 (void)Lst_AddNew(slst, bottom); 1762 1763 while (SuffRemoveSrc(&srcs) || SuffRemoveSrc(&targs)) 1764 continue; 1765 1766 Lst_ConcatDestroy(slst, &srcs); 1767 Lst_ConcatDestroy(slst, &targs); 1768 } 1769 1770 1771 /*- 1772 *----------------------------------------------------------------------- 1773 * Suff_FindDeps -- 1774 * Find implicit sources for the target described by the graph node 1775 * gn 1776 * 1777 * Side Effects: 1778 * Nodes are added to the graph below the passed-in node. The nodes 1779 * are marked to have their IMPSRC variable filled in. The 1780 * PREFIX variable is set for the given node and all its 1781 * implied children. 1782 * 1783 * Notes: 1784 * The path found by this target is the shortest path in the 1785 * transformation graph, which may pass through non-existent targets, 1786 * to an existing target. The search continues on all paths from the 1787 * root suffix until a file is found. I.e. if there's a path 1788 * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but 1789 * the .c and .l files don't, the search will branch out in 1790 * all directions from .o and again from all the nodes on the 1791 * next level until the .l,v node is encountered. 1792 *----------------------------------------------------------------------- 1793 */ 1794 1795 void 1796 Suff_FindDeps(GNode *gn) 1797 { 1798 1799 SuffFindDeps(gn, &srclist); 1800 while (SuffRemoveSrc(&srclist)) 1801 continue; 1802 } 1803 1804 1805 static void 1806 SuffFindDeps(GNode *gn, Lst slst) 1807 { 1808 if (gn->type & OP_DEPS_FOUND) { 1809 /* 1810 * If dependencies already found, no need to do it again... 1811 */ 1812 return; 1813 } else { 1814 gn->type |= OP_DEPS_FOUND; 1815 } 1816 1817 if (DEBUG(SUFF)) 1818 printf("SuffFindDeps (%s)\n", gn->name); 1819 1820 if (gn->type & OP_ARCHV) { 1821 SuffFindArchiveDeps(gn, slst); 1822 } else if (gn->type & OP_LIB) { 1823 /* 1824 * If the node is a library, it is the arch module's job to 1825 * find it and set the TARGET variable accordingly. We merely 1826 * provide the search path, assuming all libraries end in ".a" 1827 * (if the suffix hasn't been defined, there's nothing we can 1828 * do for it, so we just set the TARGET variable to the node's 1829 * name in order to give it a value). 1830 */ 1831 Suff *s; 1832 1833 s = find_suff(LIBSUFF); 1834 if (s != NULL) { 1835 gn->suffix = s; 1836 Arch_FindLib(gn, &s->searchPath); 1837 } else { 1838 gn->suffix = NULL; 1839 Var(TARGET_INDEX, gn) = gn->name; 1840 } 1841 /* 1842 * Because a library (-lfoo) target doesn't follow the standard 1843 * filesystem conventions, we don't set the regular variables 1844 * for the thing. .PREFIX is simply made empty... 1845 */ 1846 Var(PREFIX_INDEX, gn) = ""; 1847 } else 1848 SuffFindNormalDeps(gn, slst); 1849 } 1850 1851 /*- 1852 * Notes: 1853 */ 1854 void 1855 Suff_SetNulli(const char *name, const char *end) 1856 { 1857 Suff *s; 1858 1859 s= find_suffi(name, end); 1860 if (s != NULL) { 1861 /* pass the pumpkin */ 1862 suffNull->flags &= ~SUFF_NULL; 1863 s->flags |= SUFF_NULL; 1864 /* 1865 * XXX: Here's where the transformation mangling would take 1866 * place 1867 * we would need to handle the changing of the null suffix 1868 * gracefully so the old transformation rules don't just go 1869 * away. 1870 */ 1871 suffNull = s; 1872 } else { 1873 Parse_Error(PARSE_WARNING, 1874 "Desired null suffix %s not defined.", name); 1875 } 1876 } 1877 1878 /*- 1879 *----------------------------------------------------------------------- 1880 * Suff_Init -- 1881 * Initialize suffixes module 1882 * 1883 * Side Effects: 1884 * Many 1885 *----------------------------------------------------------------------- 1886 */ 1887 void 1888 Suff_Init(void) 1889 { 1890 Static_Lst_Init(&srclist); 1891 ohash_init(&transforms, 4, &gnode_info); 1892 1893 /* 1894 * Create null suffix for single-suffix rules (POSIX). The thing doesn't 1895 * actually go on the suffix list or everyone will think that's its 1896 * suffix. 1897 */ 1898 emptySuff = new_suffix(""); 1899 emptySuff->flags |= SUFF_NULL; 1900 make_suffix_known(emptySuff); 1901 Dir_Concat(&emptySuff->searchPath, defaultPath); 1902 ohash_init(&suffixes, 4, &suff_info); 1903 order = 0; 1904 clear_suffixes(); 1905 special_path_hack(); 1906 1907 } 1908 1909 1910 /*- 1911 *---------------------------------------------------------------------- 1912 * Suff_End -- 1913 * Cleanup the this module 1914 * 1915 * Side Effects: 1916 * The memory is free'd. 1917 *---------------------------------------------------------------------- 1918 */ 1919 1920 #ifdef CLEANUP 1921 void 1922 Suff_End(void) 1923 { 1924 free_hash(&suffixes); 1925 if (emptySuff) 1926 SuffFree(emptySuff); 1927 Lst_Destroy(&srclist, NOFREE); 1928 ohash_delete(&transforms); 1929 } 1930 #endif 1931 1932 1933 /********************* DEBUGGING FUNCTIONS **********************/ 1934 1935 static void 1936 SuffPrintName(void *s) 1937 { 1938 printf("%s ", ((Suff *)s)->name); 1939 } 1940 1941 static void 1942 SuffPrintSuff(void *sp) 1943 { 1944 Suff *s = (Suff *)sp; 1945 int flags; 1946 int flag; 1947 1948 printf("# `%s' ", s->name); 1949 1950 flags = s->flags; 1951 if (flags) { 1952 fputs(" (", stdout); 1953 while (flags) { 1954 flag = 1 << (ffs(flags) - 1); 1955 flags &= ~flag; 1956 switch (flag) { 1957 case SUFF_NULL: 1958 printf("NULL"); 1959 break; 1960 case SUFF_INCLUDE: 1961 printf("INCLUDE"); 1962 break; 1963 case SUFF_LIBRARY: 1964 printf("LIBRARY"); 1965 break; 1966 } 1967 fputc(flags ? '|' : ')', stdout); 1968 } 1969 } 1970 fputc('\n', stdout); 1971 printf("#\tTo: "); 1972 Lst_Every(&s->parents, SuffPrintName); 1973 fputc('\n', stdout); 1974 printf("#\tFrom: "); 1975 Lst_Every(&s->children, SuffPrintName); 1976 fputc('\n', stdout); 1977 printf("#\tSearch Path: "); 1978 Dir_PrintPath(&s->searchPath); 1979 fputc('\n', stdout); 1980 } 1981 1982 static void 1983 SuffPrintTrans(GNode *t) 1984 { 1985 printf("%-16s: ", t->name); 1986 Targ_PrintType(t->type); 1987 fputc('\n', stdout); 1988 Lst_Every(&t->commands, Targ_PrintCmd); 1989 fputc('\n', stdout); 1990 } 1991 1992 void 1993 Suff_PrintAll(void) 1994 { 1995 Suff *s; 1996 GNode *gn; 1997 unsigned int i; 1998 1999 printf("#*** Suffixes:\n"); 2000 2001 for (s = ohash_first(&suffixes, &i); s != NULL; 2002 s = ohash_next(&suffixes, &i)) 2003 SuffPrintSuff(s); 2004 2005 printf("#*** Transformations:\n"); 2006 for (gn = ohash_first(&transforms, &i); gn != NULL; 2007 gn = ohash_next(&transforms, &i)) 2008 SuffPrintTrans(gn); 2009 } 2010 2011 #ifdef DEBUG_SRC 2012 static void 2013 PrintAddr(void *a) 2014 { 2015 printf("%lx ", (unsigned long)a); 2016 } 2017 #endif 2018