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