1 /* $OpenBSD: suff.c,v 1.79 2010/07/19 19:46:44 espie 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 SuffExpandVarChildren(LstNode after, GNode *cgn, GNode *pgn) 1065 { 1066 GNode *gn; /* New source 8) */ 1067 char *cp; /* Expanded value */ 1068 LIST members; 1069 1070 1071 if (DEBUG(SUFF)) 1072 printf("Expanding \"%s\"...", cgn->name); 1073 1074 cp = Var_Subst(cgn->name, &pgn->context, true); 1075 if (cp == NULL) { 1076 printf("Problem substituting in %s", cgn->name); 1077 printf("\n"); 1078 return; 1079 } 1080 1081 Lst_Init(&members); 1082 1083 if (cgn->type & OP_ARCHV) { 1084 /* 1085 * Node was an archive(member) target, so we want to call 1086 * on the Arch module to find the nodes for us, expanding 1087 * variables in the parent's context. 1088 */ 1089 const char *sacrifice = (const char *)cp; 1090 1091 (void)Arch_ParseArchive(&sacrifice, &members, &pgn->context); 1092 } else { 1093 /* Break the result into a vector of strings whose nodes 1094 * we can find, then add those nodes to the members list. 1095 * Unfortunately, we can't use brk_string because it 1096 * doesn't understand about variable specifications with 1097 * spaces in them... */ 1098 const char *start, *cp2; 1099 1100 for (start = cp; *start == ' ' || *start == '\t'; start++) 1101 continue; 1102 for (cp2 = start; *cp2 != '\0';) { 1103 if (isspace(*cp2)) { 1104 /* White-space -- terminate element, find the 1105 * node, add it, skip any further spaces. */ 1106 gn = Targ_FindNodei(start, cp2, TARG_CREATE); 1107 cp2++; 1108 Lst_AtEnd(&members, gn); 1109 while (isspace(*cp2)) 1110 cp2++; 1111 /* Adjust cp2 for increment at start of loop, 1112 * but set start to first non-space. */ 1113 start = cp2; 1114 } else if (*cp2 == '$') 1115 /* Start of a variable spec -- contact variable 1116 * module to find the end so we can skip over 1117 * it. */ 1118 Var_ParseSkip(&cp2, &pgn->context); 1119 else if (*cp2 == '\\' && cp2[1] != '\0') 1120 /* Escaped something -- skip over it. */ 1121 cp2+=2; 1122 else 1123 cp2++; 1124 } 1125 1126 if (cp2 != start) { 1127 /* Stuff left over -- add it to the list too. */ 1128 gn = Targ_FindNodei(start, cp2, TARG_CREATE); 1129 Lst_AtEnd(&members, gn); 1130 } 1131 } 1132 /* Add all elements of the members list to the parent node. */ 1133 while ((gn = (GNode *)Lst_DeQueue(&members)) != NULL) { 1134 if (DEBUG(SUFF)) 1135 printf("%s...", gn->name); 1136 if (Lst_Member(&pgn->children, gn) == NULL) { 1137 Lst_Append(&pgn->children, after, gn); 1138 after = Lst_Adv(after); 1139 Lst_AtEnd(&gn->parents, pgn); 1140 if (!has_been_built(gn)) 1141 pgn->unmade++; 1142 } 1143 } 1144 /* Free the result. */ 1145 free(cp); 1146 if (DEBUG(SUFF)) 1147 printf("\n"); 1148 } 1149 1150 static void 1151 SuffExpandWildChildren(LstNode after, GNode *cgn, GNode *pgn) 1152 { 1153 Suff *s; 1154 char *cp; /* Expanded value */ 1155 1156 LIST exp; /* List of expansions */ 1157 Lst path; /* Search path along which to expand */ 1158 1159 if (DEBUG(SUFF)) 1160 printf("Wildcard expanding \"%s\"...", cgn->name); 1161 1162 /* Find a path along which to expand the word. 1163 * 1164 * If the word has a known suffix, use that path. 1165 * If it has no known suffix and we're allowed to use the null 1166 * suffix, use its path. 1167 * Else use the default system search path. */ 1168 s = find_best_suffix(cgn->name, cgn->name + strlen(cgn->name)); 1169 1170 if (s != NULL) { 1171 if (DEBUG(SUFF)) 1172 printf("suffix is \"%s\"...", s->name); 1173 path = &s->searchPath; 1174 } else 1175 /* Use default search path. */ 1176 path = defaultPath; 1177 1178 /* Expand the word along the chosen path. */ 1179 Lst_Init(&exp); 1180 Dir_Expand(cgn->name, path, &exp); 1181 1182 /* Fetch next expansion off the list and find its GNode. */ 1183 while ((cp = (char *)Lst_DeQueue(&exp)) != NULL) { 1184 GNode *gn; /* New source 8) */ 1185 if (DEBUG(SUFF)) 1186 printf("%s...", cp); 1187 gn = Targ_FindNode(cp, TARG_CREATE); 1188 1189 /* If gn isn't already a child of the parent, make it so and 1190 * up the parent's count of unmade children. */ 1191 if (Lst_Member(&pgn->children, gn) == NULL) { 1192 Lst_Append(&pgn->children, after, gn); 1193 after = Lst_Adv(after); 1194 Lst_AtEnd(&gn->parents, pgn); 1195 if (!has_been_built(gn)) 1196 pgn->unmade++; 1197 } 1198 } 1199 1200 if (DEBUG(SUFF)) 1201 printf("\n"); 1202 } 1203 1204 /*- 1205 *----------------------------------------------------------------------- 1206 * SuffExpandChildren -- 1207 * Expand the names of any children of a given node that contain 1208 * variable invocations or file wildcards into actual targets. 1209 * 1210 * Side Effects: 1211 * The expanded node is removed from the parent's list of children, 1212 * and the parent's unmade counter is decremented, but other nodes 1213 * may be added. 1214 *----------------------------------------------------------------------- 1215 */ 1216 static void 1217 SuffExpandChildren(LstNode ln, /* LstNode of child, so we can replace it */ 1218 GNode *pgn) 1219 { 1220 GNode *cgn = (GNode *)Lst_Datum(ln); 1221 1222 /* First do variable expansion -- this takes precedence over wildcard 1223 * expansion. If the result contains wildcards, they'll be gotten to 1224 * later since the resulting words are tacked on to the end of the 1225 * children list. */ 1226 if (strchr(cgn->name, '$') != NULL) 1227 SuffExpandVarChildren(ln, cgn, pgn); 1228 else if (Dir_HasWildcards(cgn->name)) 1229 SuffExpandWildChildren(ln, cgn, pgn); 1230 else 1231 /* Third case: nothing to expand. */ 1232 return; 1233 1234 /* Since the source was expanded, remove it from the list of children to 1235 * keep it from being processed. */ 1236 pgn->unmade--; 1237 Lst_Remove(&pgn->children, ln); 1238 } 1239 1240 void 1241 expand_children_from(GNode *parent, LstNode from) 1242 { 1243 LstNode np, ln; 1244 1245 for (ln = from; ln != NULL; ln = np) { 1246 np = Lst_Adv(ln); 1247 SuffExpandChildren(ln, parent); 1248 } 1249 } 1250 1251 /*- 1252 *----------------------------------------------------------------------- 1253 * SuffApplyTransform -- 1254 * Apply a transformation rule, given the source and target nodes 1255 * and suffixes. 1256 * 1257 * Results: 1258 * true if successful, false if not. 1259 * 1260 * Side Effects: 1261 * The source and target are linked and the commands from the 1262 * transformation are added to the target node's commands list. 1263 * All attributes but OP_DEPMASK and OP_TRANSFORM are applied 1264 * to the target. The target also inherits all the sources for 1265 * the transformation rule. 1266 *----------------------------------------------------------------------- 1267 */ 1268 static bool 1269 SuffApplyTransform( 1270 GNode *tGn, /* Target node */ 1271 GNode *sGn, /* Source node */ 1272 Suff *t, /* Target suffix */ 1273 Suff *s) /* Source suffix */ 1274 { 1275 LstNode ln; /* General node */ 1276 char *tname; /* Name of transformation rule */ 1277 GNode *gn; /* Node for same */ 1278 1279 if (Lst_AddNew(&tGn->children, sGn)) { 1280 /* Not already linked, so form the proper links between the 1281 * target and source. */ 1282 Lst_AtEnd(&sGn->parents, tGn); 1283 if (!has_been_built(sGn)) 1284 tGn->unmade++; 1285 } 1286 1287 if ((sGn->type & OP_OPMASK) == OP_DOUBLEDEP) { 1288 /* When a :: node is used as the implied source of a node, we 1289 * have to link all its cohorts in as sources as well. There's 1290 * only one implied src, as that will be sufficient to get 1291 * the .IMPSRC variable set for tGn. */ 1292 for (ln=Lst_First(&sGn->cohorts); ln != NULL; ln=Lst_Adv(ln)) { 1293 gn = (GNode *)Lst_Datum(ln); 1294 1295 if (Lst_AddNew(&tGn->children, gn)) { 1296 /* Not already linked, so form the proper links 1297 * between the target and source. */ 1298 Lst_AtEnd(&gn->parents, tGn); 1299 if (!has_been_built(gn)) 1300 tGn->unmade++; 1301 } 1302 } 1303 } 1304 /* Locate the transformation rule itself. */ 1305 tname = Str_concat(s->name, t->name, 0); 1306 gn = find_transform(tname); 1307 free(tname); 1308 1309 if (gn == NULL) 1310 /* 1311 * Not really such a transformation rule (can happen when we're 1312 * called to link an OP_MEMBER and OP_ARCHV node), so return 1313 * false. 1314 */ 1315 return false; 1316 1317 if (DEBUG(SUFF)) 1318 printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, 1319 tGn->name); 1320 1321 /* Record last child for expansion purposes. */ 1322 ln = Lst_Last(&tGn->children); 1323 1324 /* Pass the buck to Make_HandleUse to apply the rule. */ 1325 Make_HandleUse(gn, tGn); 1326 1327 /* Deal with wildcards and variables in any acquired sources. */ 1328 expand_children_from(tGn, Lst_Succ(ln)); 1329 1330 /* Keep track of another parent to which this beast is transformed so 1331 * the .IMPSRC variable can be set correctly for the parent. */ 1332 tGn->impliedsrc = sGn; 1333 1334 return true; 1335 } 1336 1337 static Suff * 1338 find_suffix_as_suffix(Lst l, const char *b, const char *e) 1339 { 1340 LstNode ln; 1341 Suff *s; 1342 1343 for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) { 1344 s = (Suff *)Lst_Datum(ln); 1345 if (suffix_is_suffix(s, b, e)) 1346 return s; 1347 } 1348 return NULL; 1349 } 1350 1351 /*- 1352 *----------------------------------------------------------------------- 1353 * SuffFindArchiveDeps -- 1354 * Locate dependencies for an OP_ARCHV node. 1355 * 1356 * Side Effects: 1357 * Same as Suff_FindDeps 1358 *----------------------------------------------------------------------- 1359 */ 1360 static void 1361 SuffFindArchiveDeps( 1362 GNode *gn, /* Node for which to locate dependencies */ 1363 Lst slst) 1364 { 1365 char *eoarch; /* End of archive portion */ 1366 char *eoname; /* End of member portion */ 1367 GNode *mem; /* Node for member */ 1368 Suff *ms; /* Suffix descriptor for member */ 1369 char *name; /* Start of member's name */ 1370 1371 /* The node is an archive(member) pair. so we must find a suffix 1372 * for both of them. */ 1373 eoarch = strchr(gn->name, '('); 1374 if (eoarch == NULL) 1375 return; 1376 1377 name = eoarch + 1; 1378 1379 eoname = strchr(name, ')'); 1380 if (eoname == NULL) 1381 return; 1382 1383 /* To simplify things, call Suff_FindDeps recursively on the member now, 1384 * so we can simply compare the member's .PREFIX and .TARGET variables 1385 * to locate its suffix. This allows us to figure out the suffix to 1386 * use for the archive without having to do a quadratic search over the 1387 * suffix list, backtracking for each one... */ 1388 mem = Targ_FindNodei(name, eoname, TARG_CREATE); 1389 SuffFindDeps(mem, slst); 1390 1391 /* Create the link between the two nodes right off. */ 1392 if (Lst_AddNew(&gn->children, mem)) { 1393 Lst_AtEnd(&mem->parents, gn); 1394 if (!has_been_built(mem)) 1395 gn->unmade++; 1396 } 1397 1398 /* Copy variables from member node to this one. */ 1399 Var(TARGET_INDEX, gn) = Var(TARGET_INDEX, mem); 1400 Var(PREFIX_INDEX, gn) = Var(PREFIX_INDEX, mem); 1401 1402 ms = mem->suffix; 1403 if (ms == NULL) { 1404 /* Didn't know what it was -- use .NULL suffix if not in make 1405 * mode. */ 1406 if (DEBUG(SUFF)) 1407 printf("using null suffix\n"); 1408 ms = suffNull; 1409 } 1410 1411 1412 /* Set the other two local variables required for this target. */ 1413 Var(MEMBER_INDEX, gn) = mem->name; 1414 Var(ARCHIVE_INDEX, gn) = gn->name; 1415 1416 if (ms != NULL) { 1417 /* 1418 * Member has a known suffix, so look for a transformation rule 1419 * from it to a possible suffix of the archive. Rather than 1420 * searching through the entire list, we just look at suffixes 1421 * to which the member's suffix may be transformed... 1422 */ 1423 1424 Suff *suff; 1425 1426 suff = find_suffix_as_suffix(&ms->parents, gn->name, eoarch); 1427 1428 if (suff != NULL) { 1429 /* Got one -- apply it. */ 1430 if (!SuffApplyTransform(gn, mem, suff, ms) && 1431 DEBUG(SUFF)) 1432 printf("\tNo transformation from %s -> %s\n", 1433 ms->name, suff->name); 1434 } 1435 } 1436 1437 /* Pretend gn appeared to the left of a dependency operator so 1438 * the user needn't provide a transformation from the member to the 1439 * archive. */ 1440 if (OP_NOP(gn->type)) 1441 gn->type |= OP_DEPENDS; 1442 1443 /* Flag the member as such so we remember to look in the archive for 1444 * its modification time. */ 1445 mem->type |= OP_MEMBER; 1446 } 1447 1448 static void 1449 record_possible_suffix(Suff *s, GNode *gn, char *eoname, Lst srcs, Lst targs) 1450 { 1451 int prefLen; 1452 Src *targ; 1453 char *sopref = gn->name; 1454 1455 targ = emalloc(sizeof(Src)); 1456 targ->file = estrdup(gn->name); 1457 targ->suff = s; 1458 targ->node = gn; 1459 targ->parent = NULL; 1460 targ->children = 0; 1461 #ifdef DEBUG_SRC 1462 Lst_Init(&targ->cp); 1463 #endif 1464 1465 /* Allocate room for the prefix, whose end is found by 1466 * subtracting the length of the suffix from the end of 1467 * the name. */ 1468 prefLen = (eoname - targ->suff->nameLen) - sopref; 1469 targ->pref = emalloc(prefLen + 1); 1470 memcpy(targ->pref, sopref, prefLen); 1471 targ->pref[prefLen] = '\0'; 1472 1473 /* Add nodes from which the target can be made. */ 1474 SuffAddLevel(srcs, targ); 1475 1476 /* Record the target so we can nuke it. */ 1477 Lst_AtEnd(targs, targ); 1478 } 1479 1480 static void 1481 record_possible_suffixes(GNode *gn, Lst srcs, Lst targs) 1482 { 1483 char *s = gn->name; 1484 char *e = s + strlen(s); 1485 const char *p; 1486 uint32_t hv; 1487 unsigned int slot; 1488 Suff *suff; 1489 1490 if (e == s) 1491 return; 1492 1493 p = e; 1494 hv = *--p; 1495 1496 while (p != s) { 1497 slot = ohash_lookup_interval(&suffixes, p, e, hv); 1498 suff = ohash_find(&suffixes, slot); 1499 if (suff != NULL && (suff->flags & SUFF_ACTIVE)) 1500 record_possible_suffix(suff, gn, e, srcs, targs); 1501 if (e - p >= (ptrdiff_t)maxLen) 1502 break; 1503 reverse_hash_add_char(&hv, --p); 1504 } 1505 } 1506 1507 /*- 1508 *----------------------------------------------------------------------- 1509 * SuffFindNormalDeps -- 1510 * Locate implicit dependencies for regular targets. 1511 * 1512 * Side Effects: 1513 * Same as Suff_FindDeps... 1514 *----------------------------------------------------------------------- 1515 */ 1516 static void 1517 SuffFindNormalDeps( 1518 GNode *gn, /* Node for which to find sources */ 1519 Lst slst) 1520 { 1521 LIST srcs; /* List of sources at which to look */ 1522 LIST targs; /* List of targets to which things can be 1523 * transformed. They all have the same file, 1524 * but different suff and pref fields */ 1525 Src *bottom; /* Start of found transformation path */ 1526 Src *src; /* General Src pointer */ 1527 char *pref; /* Prefix to use */ 1528 Src *targ; /* General Src target pointer */ 1529 1530 1531 Lst_Init(&srcs); 1532 Lst_Init(&targs); 1533 1534 /* We're caught in a catch-22 here. On the one hand, we want to use any 1535 * transformation implied by the target's sources, but we can't examine 1536 * the sources until we've expanded any variables/wildcards they may 1537 * hold, and we can't do that until we've set up the target's local 1538 * variables and we can't do that until we know what the proper suffix 1539 * for the target is (in case there are two suffixes one of which is a 1540 * suffix of the other) and we can't know that until we've found its 1541 * implied source, which we may not want to use if there's an existing 1542 * source that implies a different transformation. 1543 * 1544 * In an attempt to get around this, which may not work all the time, 1545 * but should work most of the time, we look for implied sources first, 1546 * checking transformations to all possible suffixes of the target, use 1547 * what we find to set the target's local variables, expand the 1548 * children, then look for any overriding transformations they imply. 1549 * Should we find one, we discard the one we found before. */ 1550 1551 1552 record_possible_suffixes(gn, &srcs, &targs); 1553 /* Handle target of unknown suffix... */ 1554 if (Lst_IsEmpty(&srcs)) { 1555 if (DEBUG(SUFF)) 1556 printf("\tNo known suffix on %s. Using .NULL suffix\n", 1557 gn->name); 1558 1559 targ = emalloc(sizeof(Src)); 1560 targ->file = estrdup(gn->name); 1561 targ->suff = suffNull; 1562 targ->node = gn; 1563 targ->parent = NULL; 1564 targ->children = 0; 1565 targ->pref = estrdup(gn->name); 1566 #ifdef DEBUG_SRC 1567 Lst_Init(&targ->cp); 1568 #endif 1569 1570 /* Only use the default suffix rules if we don't have commands 1571 * or dependencies defined for this gnode. */ 1572 if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children)) 1573 SuffAddLevel(&srcs, targ); 1574 else { 1575 if (DEBUG(SUFF)) 1576 printf("not "); 1577 } 1578 1579 if (DEBUG(SUFF)) 1580 printf("adding suffix rules\n"); 1581 1582 Lst_AtEnd(&targs, targ); 1583 } 1584 1585 /* Using the list of possible sources built up from the target 1586 * suffix(es), try and find an existing file/target that matches. */ 1587 bottom = SuffFindThem(&srcs, slst); 1588 1589 if (bottom == NULL) { 1590 /* No known transformations -- use the first suffix found for 1591 * setting the local variables. */ 1592 if (!Lst_IsEmpty(&targs)) 1593 targ = (Src *)Lst_Datum(Lst_First(&targs)); 1594 else 1595 targ = NULL; 1596 } else { 1597 /* Work up the transformation path to find the suffix of the 1598 * target to which the transformation was made. */ 1599 for (targ = bottom; targ->parent != NULL; targ = targ->parent) 1600 continue; 1601 } 1602 1603 /* The .TARGET variable we always set to be the name at this point, 1604 * since it's only set to the path if the thing is only a source and 1605 * if it's only a source, it doesn't matter what we put here as far 1606 * as expanding sources is concerned, since it has none... */ 1607 Var(TARGET_INDEX, gn) = gn->name; 1608 1609 pref = targ != NULL ? estrdup(targ->pref) : gn->name; 1610 Var(PREFIX_INDEX, gn) = pref; 1611 1612 /* Now we've got the important local variables set, expand any sources 1613 * that still contain variables or wildcards in their names. */ 1614 expand_all_children(gn); 1615 1616 if (targ == NULL) { 1617 if (DEBUG(SUFF)) 1618 printf("\tNo valid suffix on %s\n", gn->name); 1619 1620 sfnd_abort: 1621 /* Deal with finding the thing on the default search path if the 1622 * node is only a source (not on the lhs of a dependency operator 1623 * or [XXX] it has neither children or commands). */ 1624 if (OP_NOP(gn->type) || 1625 (Lst_IsEmpty(&gn->children) && 1626 Lst_IsEmpty(&gn->commands))) { 1627 gn->path = Dir_FindFile(gn->name, 1628 (targ == NULL ? defaultPath : 1629 &targ->suff->searchPath)); 1630 if (gn->path != NULL) { 1631 char *ptr; 1632 Var(TARGET_INDEX, gn) = estrdup(gn->path); 1633 1634 if (targ != NULL) { 1635 /* Suffix known for the thing -- trim 1636 * the suffix off the path to form the 1637 * proper .PREFIX variable. */ 1638 int savep = strlen(gn->path) - 1639 targ->suff->nameLen; 1640 char savec; 1641 1642 gn->suffix = targ->suff; 1643 1644 savec = gn->path[savep]; 1645 gn->path[savep] = '\0'; 1646 1647 if ((ptr = strrchr(gn->path, '/')) != 1648 NULL) 1649 ptr++; 1650 else 1651 ptr = gn->path; 1652 1653 Var(PREFIX_INDEX, gn) = estrdup(ptr); 1654 1655 gn->path[savep] = savec; 1656 } else { 1657 /* The .PREFIX gets the full path if the 1658 * target has no known suffix. */ 1659 gn->suffix = NULL; 1660 1661 if ((ptr = strrchr(gn->path, '/')) != 1662 NULL) 1663 ptr++; 1664 else 1665 ptr = gn->path; 1666 1667 Var(PREFIX_INDEX, gn) = estrdup(ptr); 1668 } 1669 } 1670 } else { 1671 /* Not appropriate to search for the thing -- set the 1672 * path to be the name so Dir_MTime won't go grovelling 1673 * for it. */ 1674 gn->suffix = targ == NULL ? NULL : targ->suff; 1675 efree(gn->path); 1676 gn->path = estrdup(gn->name); 1677 } 1678 1679 goto sfnd_return; 1680 } 1681 1682 /* If the suffix indicates that the target is a library, mark that in 1683 * the node's type field. */ 1684 if (targ->suff->flags & SUFF_LIBRARY) { 1685 gn->type |= OP_LIB; 1686 } 1687 1688 /* Check for overriding transformation rule implied by sources. */ 1689 if (!Lst_IsEmpty(&gn->children)) { 1690 src = SuffFindCmds(targ, slst); 1691 1692 if (src != NULL) { 1693 /* Free up all the Src structures in the transformation 1694 * path up to, but not including, the parent node. */ 1695 while (bottom && bottom->parent != NULL) { 1696 (void)Lst_AddNew(slst, bottom); 1697 bottom = bottom->parent; 1698 } 1699 bottom = src; 1700 } 1701 } 1702 1703 if (bottom == NULL) { 1704 /* No idea from where it can come -- return now. */ 1705 goto sfnd_abort; 1706 } 1707 1708 /* We now have a list of Src structures headed by 'bottom' and linked 1709 * via their 'parent' pointers. What we do next is create links between 1710 * source and target nodes (which may or may not have been created) and 1711 * set the necessary local variables in each target. The commands for 1712 * each target are set from the commands of the transformation rule 1713 * used to get from the src suffix to the targ suffix. Note that this 1714 * causes the commands list of the original node, gn, to be replaced by 1715 * the commands of the final transformation rule. Also, the unmade 1716 * field of gn is incremented. Etc. */ 1717 if (bottom->node == NULL) { 1718 bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); 1719 } 1720 1721 for (src = bottom; src->parent != NULL; src = src->parent) { 1722 targ = src->parent; 1723 1724 src->node->suffix = src->suff; 1725 1726 if (targ->node == NULL) { 1727 targ->node = Targ_FindNode(targ->file, TARG_CREATE); 1728 } 1729 1730 SuffApplyTransform(targ->node, src->node, 1731 targ->suff, src->suff); 1732 1733 if (targ->node != gn) { 1734 /* Finish off the dependency-search process for any 1735 * nodes between bottom and gn (no point in questing 1736 * around the filesystem for their implicit source when 1737 * it's already known). Note that the node can't have 1738 * any sources that need expanding, since SuffFindThem 1739 * will stop on an existing node, so all we need to do 1740 * is set the standard and System V variables. */ 1741 targ->node->type |= OP_DEPS_FOUND; 1742 1743 Var(PREFIX_INDEX, targ->node) = estrdup(targ->pref); 1744 1745 Var(TARGET_INDEX, targ->node) = targ->node->name; 1746 } 1747 } 1748 1749 gn->suffix = src->suff; 1750 1751 /* So Dir_MTime doesn't go questing for it... */ 1752 efree(gn->path); 1753 gn->path = estrdup(gn->name); 1754 1755 /* Nuke the transformation path and the Src structures left over in the 1756 * two lists. */ 1757 sfnd_return: 1758 if (bottom) 1759 (void)Lst_AddNew(slst, bottom); 1760 1761 while (SuffRemoveSrc(&srcs) || SuffRemoveSrc(&targs)) 1762 continue; 1763 1764 Lst_ConcatDestroy(slst, &srcs); 1765 Lst_ConcatDestroy(slst, &targs); 1766 } 1767 1768 1769 /*- 1770 *----------------------------------------------------------------------- 1771 * Suff_FindDeps -- 1772 * Find implicit sources for the target described by the graph node 1773 * gn 1774 * 1775 * Side Effects: 1776 * Nodes are added to the graph below the passed-in node. The nodes 1777 * are marked to have their IMPSRC variable filled in. The 1778 * PREFIX variable is set for the given node and all its 1779 * implied children. 1780 * 1781 * Notes: 1782 * The path found by this target is the shortest path in the 1783 * transformation graph, which may pass through non-existent targets, 1784 * to an existing target. The search continues on all paths from the 1785 * root suffix until a file is found. I.e. if there's a path 1786 * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but 1787 * the .c and .l files don't, the search will branch out in 1788 * all directions from .o and again from all the nodes on the 1789 * next level until the .l,v node is encountered. 1790 *----------------------------------------------------------------------- 1791 */ 1792 1793 void 1794 Suff_FindDeps(GNode *gn) 1795 { 1796 1797 SuffFindDeps(gn, &srclist); 1798 while (SuffRemoveSrc(&srclist)) 1799 continue; 1800 } 1801 1802 1803 static void 1804 SuffFindDeps(GNode *gn, Lst slst) 1805 { 1806 if (gn->type & OP_DEPS_FOUND) { 1807 /* 1808 * If dependencies already found, no need to do it again... 1809 */ 1810 return; 1811 } else { 1812 gn->type |= OP_DEPS_FOUND; 1813 } 1814 1815 if (DEBUG(SUFF)) 1816 printf("SuffFindDeps (%s)\n", gn->name); 1817 1818 if (gn->type & OP_ARCHV) { 1819 SuffFindArchiveDeps(gn, slst); 1820 } else if (gn->type & OP_LIB) { 1821 /* 1822 * If the node is a library, it is the arch module's job to 1823 * find it and set the TARGET variable accordingly. We merely 1824 * provide the search path, assuming all libraries end in ".a" 1825 * (if the suffix hasn't been defined, there's nothing we can 1826 * do for it, so we just set the TARGET variable to the node's 1827 * name in order to give it a value). 1828 */ 1829 Suff *s; 1830 1831 s = find_suff(LIBSUFF); 1832 if (s != NULL) { 1833 gn->suffix = s; 1834 Arch_FindLib(gn, &s->searchPath); 1835 } else { 1836 gn->suffix = NULL; 1837 Var(TARGET_INDEX, gn) = gn->name; 1838 } 1839 /* 1840 * Because a library (-lfoo) target doesn't follow the standard 1841 * filesystem conventions, we don't set the regular variables 1842 * for the thing. .PREFIX is simply made empty... 1843 */ 1844 Var(PREFIX_INDEX, gn) = ""; 1845 } else 1846 SuffFindNormalDeps(gn, slst); 1847 } 1848 1849 /*- 1850 * Notes: 1851 */ 1852 void 1853 Suff_SetNulli(const char *name, const char *end) 1854 { 1855 Suff *s; 1856 1857 s= find_suffi(name, end); 1858 if (s != NULL) { 1859 /* pass the pumpkin */ 1860 suffNull->flags &= ~SUFF_NULL; 1861 s->flags |= SUFF_NULL; 1862 /* 1863 * XXX: Here's where the transformation mangling would take 1864 * place 1865 * we would need to handle the changing of the null suffix 1866 * gracefully so the old transformation rules don't just go 1867 * away. 1868 */ 1869 suffNull = s; 1870 } else { 1871 Parse_Error(PARSE_WARNING, 1872 "Desired null suffix %s not defined.", name); 1873 } 1874 } 1875 1876 /*- 1877 *----------------------------------------------------------------------- 1878 * Suff_Init -- 1879 * Initialize suffixes module 1880 * 1881 * Side Effects: 1882 * Many 1883 *----------------------------------------------------------------------- 1884 */ 1885 void 1886 Suff_Init(void) 1887 { 1888 Static_Lst_Init(&srclist); 1889 ohash_init(&transforms, 4, &gnode_info); 1890 1891 /* 1892 * Create null suffix for single-suffix rules (POSIX). The thing doesn't 1893 * actually go on the suffix list or everyone will think that's its 1894 * suffix. 1895 */ 1896 emptySuff = new_suffix(""); 1897 emptySuff->flags |= SUFF_NULL; 1898 make_suffix_known(emptySuff); 1899 Dir_Concat(&emptySuff->searchPath, defaultPath); 1900 ohash_init(&suffixes, 4, &suff_info); 1901 order = 0; 1902 clear_suffixes(); 1903 special_path_hack(); 1904 1905 } 1906 1907 1908 /*- 1909 *---------------------------------------------------------------------- 1910 * Suff_End -- 1911 * Cleanup the this module 1912 * 1913 * Side Effects: 1914 * The memory is free'd. 1915 *---------------------------------------------------------------------- 1916 */ 1917 1918 #ifdef CLEANUP 1919 void 1920 Suff_End(void) 1921 { 1922 free_hash(&suffixes); 1923 if (emptySuff) 1924 SuffFree(emptySuff); 1925 Lst_Destroy(&srclist, NOFREE); 1926 ohash_delete(&transforms); 1927 } 1928 #endif 1929 1930 1931 /********************* DEBUGGING FUNCTIONS **********************/ 1932 1933 static void 1934 SuffPrintName(void *s) 1935 { 1936 printf("%s ", ((Suff *)s)->name); 1937 } 1938 1939 static void 1940 SuffPrintSuff(void *sp) 1941 { 1942 Suff *s = (Suff *)sp; 1943 int flags; 1944 int flag; 1945 1946 printf("# `%s' ", s->name); 1947 1948 flags = s->flags; 1949 if (flags) { 1950 fputs(" (", stdout); 1951 while (flags) { 1952 flag = 1 << (ffs(flags) - 1); 1953 flags &= ~flag; 1954 switch (flag) { 1955 case SUFF_NULL: 1956 printf("NULL"); 1957 break; 1958 case SUFF_INCLUDE: 1959 printf("INCLUDE"); 1960 break; 1961 case SUFF_LIBRARY: 1962 printf("LIBRARY"); 1963 break; 1964 } 1965 fputc(flags ? '|' : ')', stdout); 1966 } 1967 } 1968 fputc('\n', stdout); 1969 printf("#\tTo: "); 1970 Lst_Every(&s->parents, SuffPrintName); 1971 fputc('\n', stdout); 1972 printf("#\tFrom: "); 1973 Lst_Every(&s->children, SuffPrintName); 1974 fputc('\n', stdout); 1975 printf("#\tSearch Path: "); 1976 Dir_PrintPath(&s->searchPath); 1977 fputc('\n', stdout); 1978 } 1979 1980 static void 1981 SuffPrintTrans(GNode *t) 1982 { 1983 printf("%-16s: ", t->name); 1984 Targ_PrintType(t->type); 1985 fputc('\n', stdout); 1986 Lst_Every(&t->commands, Targ_PrintCmd); 1987 fputc('\n', stdout); 1988 } 1989 1990 void 1991 Suff_PrintAll(void) 1992 { 1993 Suff *s; 1994 GNode *gn; 1995 unsigned int i; 1996 1997 printf("#*** Suffixes:\n"); 1998 1999 for (s = ohash_first(&suffixes, &i); s != NULL; 2000 s = ohash_next(&suffixes, &i)) 2001 SuffPrintSuff(s); 2002 2003 printf("#*** Transformations:\n"); 2004 for (gn = ohash_first(&transforms, &i); gn != NULL; 2005 gn = ohash_next(&transforms, &i)) 2006 SuffPrintTrans(gn); 2007 } 2008 2009 #ifdef DEBUG_SRC 2010 static void 2011 PrintAddr(void *a) 2012 { 2013 printf("%lx ", (unsigned long)a); 2014 } 2015 #endif 2016