Changeset 51 in kBuild for trunk/src/kmk/targ.c
- Timestamp:
- Apr 7, 2003 1:30:32 AM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/targ.c
r47 r51 1 1 /* 2 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * 3 * The Regents of the University of California. All rights reserved. 4 4 * Copyright (c) 1989 by Berkeley Softworks 5 5 * All rights reserved. … … 18 18 * 3. All advertising materials mentioning features or use of this software 19 19 * must display the following acknowledgement: 20 * 21 * 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 22 * 4. Neither the name of the University nor the names of its contributors 23 23 * may be used to endorse or promote products derived from this software … … 39 39 #ifndef lint 40 40 #if 0 41 static char sccsid[] = "@(#)targ.c 41 static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; 42 42 #else 43 43 static const char rcsid[] = 44 44 "$FreeBSD: src/usr.bin/make/targ.c,v 1.10 1999/09/11 13:08:02 hoek Exp $"; 45 45 #endif 46 #define KLIBFILEDEF rcsid 46 47 #endif /* not lint */ 47 48 48 49 /*- 49 50 * targ.c -- 50 * 51 * Functions for maintaining the Lst allTargets. Target nodes are 51 52 * kept in two structures: a Lst, maintained by the list library, and a 52 53 * hash table, maintained by the hash library. 53 54 * 54 55 * Interface: 55 * Targ_InitInitialization procedure.56 * 57 * Targ_EndCleanup the module58 * 59 * Targ_NewGNCreate a new GNode for the passed target60 * 61 * 62 * 63 * 64 * Targ_FindNodeFind the node for a given target, creating65 * 66 * 67 * 68 * Targ_FindListGiven a list of names, find nodes for all69 * 70 * 71 * 72 * 73 * 74 * Targ_IgnoreReturn TRUE if errors should be ignored when75 * 76 * 77 * Targ_SilentReturn TRUE if we should be silent when78 * 79 * 80 * Targ_PreciousReturn TRUE if the target is precious and81 * 56 * Targ_Init Initialization procedure. 57 * 58 * Targ_End Cleanup the module 59 * 60 * Targ_NewGN Create a new GNode for the passed target 61 * (string). The node is *not* placed in the 62 * hash table, though all its fields are 63 * initialized. 64 * 65 * Targ_FindNode Find the node for a given target, creating 66 * and storing it if it doesn't exist and the 67 * flags are right (TARG_CREATE) 68 * 69 * Targ_FindList Given a list of names, find nodes for all 70 * of them. If a name doesn't exist and the 71 * TARG_NOCREATE flag was given, an error message 72 * is printed. Else, if a name doesn't exist, 73 * its node is created. 74 * 75 * Targ_Ignore Return TRUE if errors should be ignored when 76 * creating the given target. 77 * 78 * Targ_Silent Return TRUE if we should be silent when 79 * creating the given target. 80 * 81 * Targ_Precious Return TRUE if the target is precious and 82 * should not be removed if we are interrupted. 82 83 * 83 84 * Debugging: 84 * Targ_PrintGraph Print out the entire graphm all variables 85 * and statistics for the directory cache. Should 86 * print something for suffixes, too, but... 87 */ 88 89 #include <stdio.h> 90 #include <time.h> 91 #include "make.h" 92 #include "hash.h" 93 #include "dir.h" 94 95 static Lst allTargets; /* the list of all targets found so far */ 96 static Lst allGNs; /* List of all the GNodes */ 97 static Hash_Table targets; /* a hash table of same */ 98 99 #define HTSIZE 191 /* initial size of hash table */ 85 * Targ_PrintGraph Print out the entire graphm all variables 86 * and statistics for the directory cache. Should 87 * print something for suffixes, too, but... 88 */ 89 90 #include <stdio.h> 91 #include <time.h> 92 #include <strings.h> 93 #include "make.h" 94 #include "hash.h" 95 #include "dir.h" 96 97 static Lst allTargets; /* the list of all targets found so far */ 98 static Lst allGNs; /* List of all the GNodes */ 99 static Hash_Table targets; /* a hash table of same */ 100 101 #define HTSIZE 191 /* initial size of hash table */ 100 102 101 103 static int TargPrintOnlySrc __P((ClientData, ClientData)); … … 107 109 *----------------------------------------------------------------------- 108 110 * Targ_Init -- 109 * 110 * 111 * Results: 112 * 113 * 114 * Side Effects: 115 * 111 * Initialize this module 112 * 113 * Results: 114 * None 115 * 116 * Side Effects: 117 * The allTargets list and the targets hash table are initialized 116 118 *----------------------------------------------------------------------- 117 119 */ … … 126 128 *----------------------------------------------------------------------- 127 129 * Targ_End -- 128 * 129 * 130 * Results: 131 * 132 * 133 * Side Effects: 134 * 130 * Finalize this module 131 * 132 * Results: 133 * None 134 * 135 * Side Effects: 136 * All lists and gnodes are cleared 135 137 *----------------------------------------------------------------------- 136 138 */ … … 140 142 Lst_Destroy(allTargets, NOFREE); 141 143 if (allGNs) 142 144 Lst_Destroy(allGNs, TargFreeGN); 143 145 Hash_DeleteTable(&targets); 144 146 } … … 147 149 *----------------------------------------------------------------------- 148 150 * Targ_NewGN -- 149 * 150 * 151 * Results: 152 * 153 * 154 * 155 * Side Effects: 156 * 151 * Create and initialize a new graph node 152 * 153 * Results: 154 * An initialized graph node with the name field filled with a copy 155 * of the passed name 156 * 157 * Side Effects: 158 * The gnode is added to the list of all gnodes. 157 159 *----------------------------------------------------------------------- 158 160 */ 159 161 GNode * 160 162 Targ_NewGN (name) 161 char *name; 163 char *name; /* the name to stick in the new node */ 162 164 { 163 165 register GNode *gn; … … 168 170 #ifdef USE_ARCHIVES 169 171 if (name[0] == '-' && name[1] == 'l') { 170 172 gn->type = OP_LIB; 171 173 } else { 172 174 gn->type = 0; 173 175 } 174 176 #else 175 177 gn->type = 0; 176 178 #endif 177 gn->unmade = 178 gn->make = 179 gn->made = 180 gn->childMade = 181 gn->order = 179 gn->unmade = 0; 180 gn->make = FALSE; 181 gn->made = UNMADE; 182 gn->childMade = FALSE; 183 gn->order = 0; 182 184 gn->mtime = gn->cmtime = 0; 183 gn->iParents = 184 gn->cohorts = 185 gn->parents = 186 gn->children = 187 gn->successors = 188 gn->preds = 189 gn->context = 190 gn->commands = 191 gn->suffix = 185 gn->iParents = Lst_Init (FALSE); 186 gn->cohorts = Lst_Init (FALSE); 187 gn->parents = Lst_Init (FALSE); 188 gn->children = Lst_Init (FALSE); 189 gn->successors = Lst_Init (FALSE); 190 gn->preds = Lst_Init (FALSE); 191 gn->context = Lst_Init (FALSE); 192 gn->commands = Lst_Init (FALSE); 193 gn->suffix = NULL; 192 194 193 195 if (allGNs == NULL) 194 196 allGNs = Lst_Init(FALSE); 195 197 Lst_AtEnd(allGNs, (ClientData) gn); 196 198 … … 201 203 *----------------------------------------------------------------------- 202 204 * TargFreeGN -- 203 * 204 * 205 * Results: 206 * 207 * 208 * Side Effects: 209 * 205 * Destroy a GNode 206 * 207 * Results: 208 * None. 209 * 210 * Side Effects: 211 * None. 210 212 *----------------------------------------------------------------------- 211 213 */ … … 235 237 *----------------------------------------------------------------------- 236 238 * Targ_FindNode -- 237 * 238 * 239 * Results: 240 * 241 * 242 * 243 * 244 * Side Effects: 245 * 239 * Find a node in the list using the given name for matching 240 * 241 * Results: 242 * The node in the list if it was. If it wasn't, return NILGNODE of 243 * flags was TARG_NOCREATE or the newly created and initialized node 244 * if it was TARG_CREATE 245 * 246 * Side Effects: 247 * Sometimes a node is created and added to the list 246 248 *----------------------------------------------------------------------- 247 249 */ 248 250 GNode * 249 251 Targ_FindNode (name, flags) 250 char *name; 251 int flags; 252 253 { 254 GNode *gn; 255 Hash_Entry *he;/* New or used hash entry for node */256 Boolean 257 252 char *name; /* the name to find */ 253 int flags; /* flags governing events when target not 254 * found */ 255 { 256 GNode *gn; /* node in that element */ 257 Hash_Entry *he; /* New or used hash entry for node */ 258 Boolean isNew; /* Set TRUE if Hash_CreateEntry had to create */ 259 /* an entry for the node */ 258 260 259 261 260 262 if (flags & TARG_CREATE) { 261 262 263 264 265 266 263 he = Hash_CreateEntry (&targets, name, &isNew); 264 if (isNew) { 265 gn = Targ_NewGN (name); 266 Hash_SetValue (he, gn); 267 (void) Lst_AtEnd (allTargets, (ClientData)gn); 268 } 267 269 } else { 268 270 he = Hash_FindEntry (&targets, name); 269 271 } 270 272 271 273 if (he == (Hash_Entry *) NULL) { 272 274 return (NILGNODE); 273 275 } else { 274 276 return ((GNode *) Hash_GetValue (he)); 275 277 } 276 278 } … … 279 281 *----------------------------------------------------------------------- 280 282 * Targ_FindList -- 281 * 282 * 283 * Results: 284 * 285 * 286 * 287 * Side Effects: 288 * 289 * 290 * 283 * Make a complete list of GNodes from the given list of names 284 * 285 * Results: 286 * A complete list of graph nodes corresponding to all instances of all 287 * the names in names. 288 * 289 * Side Effects: 290 * If flags is TARG_CREATE, nodes will be created for all names in 291 * names which do not yet have graph nodes. If flags is TARG_NOCREATE, 292 * an error message will be printed for each name which can't be found. 291 293 * ----------------------------------------------------------------------- 292 294 */ 293 295 Lst 294 296 Targ_FindList (names, flags) 295 Lst names;/* list of names to find */296 int flags; 297 298 { 299 Lst nodes; 300 register LstNode ln; 301 register GNode *gn; 302 char 297 Lst names; /* list of names to find */ 298 int flags; /* flags used if no node is found for a given 299 * name */ 300 { 301 Lst nodes; /* result list */ 302 register LstNode ln; /* name list element */ 303 register GNode *gn; /* node in tLn */ 304 char *name; 303 305 304 306 nodes = Lst_Init (FALSE); 305 307 306 308 if (Lst_Open (names) == FAILURE) { 307 309 return (nodes); 308 310 } 309 311 while ((ln = Lst_Next (names)) != NILLNODE) { 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 312 name = (char *)Lst_Datum(ln); 313 gn = Targ_FindNode (name, flags); 314 if (gn != NILGNODE) { 315 /* 316 * Note: Lst_AtEnd must come before the Lst_Concat so the nodes 317 * are added to the list in the order in which they were 318 * encountered in the makefile. 319 */ 320 (void) Lst_AtEnd (nodes, (ClientData)gn); 321 if (gn->type & OP_DOUBLEDEP) { 322 (void)Lst_Concat (nodes, gn->cohorts, LST_CONCNEW); 323 } 324 } else if (flags == TARG_NOCREATE) { 325 Error ("\"%s\" -- target unknown.", name); 326 } 325 327 } 326 328 Lst_Close (names); … … 331 333 *----------------------------------------------------------------------- 332 334 * Targ_Ignore -- 333 * 334 * 335 * Results: 336 * 337 * 338 * Side Effects: 339 * 335 * Return true if should ignore errors when creating gn 336 * 337 * Results: 338 * TRUE if should ignore errors 339 * 340 * Side Effects: 341 * None 340 342 *----------------------------------------------------------------------- 341 343 */ 342 344 Boolean 343 345 Targ_Ignore (gn) 344 GNode *gn; 346 GNode *gn; /* node to check for */ 345 347 { 346 348 if (ignoreErrors || gn->type & OP_IGNORE) { 347 349 return (TRUE); 348 350 } else { 349 351 return (FALSE); 350 352 } 351 353 } … … 354 356 *----------------------------------------------------------------------- 355 357 * Targ_Silent -- 356 * 357 * 358 * Results: 359 * 360 * 361 * Side Effects: 362 * 358 * Return true if be silent when creating gn 359 * 360 * Results: 361 * TRUE if should be silent 362 * 363 * Side Effects: 364 * None 363 365 *----------------------------------------------------------------------- 364 366 */ 365 367 Boolean 366 368 Targ_Silent (gn) 367 GNode *gn; 369 GNode *gn; /* node to check for */ 368 370 { 369 371 if (beSilent || gn->type & OP_SILENT) { 370 372 return (TRUE); 371 373 } else { 372 374 return (FALSE); 373 375 } 374 376 } … … 377 379 *----------------------------------------------------------------------- 378 380 * Targ_Precious -- 379 * 380 * 381 * Results: 382 * 383 * 384 * Side Effects: 385 * 381 * See if the given target is precious 382 * 383 * Results: 384 * TRUE if it is precious. FALSE otherwise 385 * 386 * Side Effects: 387 * None 386 388 *----------------------------------------------------------------------- 387 389 */ 388 390 Boolean 389 391 Targ_Precious (gn) 390 GNode *gn; 392 GNode *gn; /* the node to check */ 391 393 { 392 394 if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) { 393 395 return (TRUE); 394 396 } else { 395 397 return (FALSE); 396 398 } 397 399 } … … 399 401 /******************* DEBUG INFO PRINTING ****************/ 400 402 401 static GNode *mainTarg;/* the main target, as set by Targ_SetMain */403 static GNode *mainTarg; /* the main target, as set by Targ_SetMain */ 402 404 /*- 403 405 *----------------------------------------------------------------------- 404 406 * Targ_SetMain -- 405 * 406 * 407 * 408 * Results: 409 * 410 * 411 * Side Effects: 412 * 407 * Set our idea of the main target we'll be creating. Used for 408 * debugging output. 409 * 410 * Results: 411 * None. 412 * 413 * Side Effects: 414 * "mainTarg" is set to the main target's node. 413 415 *----------------------------------------------------------------------- 414 416 */ 415 417 void 416 418 Targ_SetMain (gn) 417 GNode *gn; 419 GNode *gn; /* The main target we'll create */ 418 420 { 419 421 mainTarg = gn; … … 423 425 TargPrintName (gnp, ppath) 424 426 ClientData gnp; 425 ClientData 427 ClientData ppath; 426 428 { 427 429 GNode *gn = (GNode *) gnp; … … 429 431 #ifdef notdef 430 432 if (ppath) { 431 432 433 434 435 436 433 if (gn->path) { 434 printf ("[%s] ", gn->path); 435 } 436 if (gn == mainTarg) { 437 printf ("(MAIN NAME) "); 438 } 437 439 } 438 440 #endif /* notdef */ … … 453 455 *----------------------------------------------------------------------- 454 456 * Targ_FmtTime -- 455 * 456 * 457 * Results: 458 * 459 * 460 * Side Effects: 461 * 462 * 457 * Format a modification time in some reasonable way and return it. 458 * 459 * Results: 460 * The time reformatted. 461 * 462 * Side Effects: 463 * The time is placed in a static area, so it is overwritten 464 * with each call. 463 465 * 464 466 *----------------------------------------------------------------------- … … 468 470 time_t time; 469 471 { 470 struct tm 471 static char 472 struct tm *parts; 473 static char buf[128]; 472 474 473 475 parts = localtime(&time); … … 487 489 *----------------------------------------------------------------------- 488 490 * Targ_PrintType -- 489 * 490 * 491 * Print out a type field giving only those attributes the user can 492 * set. 491 493 * 492 494 * Results: … … 502 504 register int tbit; 503 505 504 #if def __STDC__505 #define PRINTBIT(attr) 506 #if defined(__STDC__) || defined(__IBMC__) 507 #define PRINTBIT(attr) case CONCAT(OP_,attr): printf("." #attr " "); break 506 508 #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf("." #attr " "); break 507 509 #else 508 #define PRINTBIT(attr) 509 #define PRINTDBIT(attr) 510 #define PRINTBIT(attr) case CONCAT(OP_,attr): printf(".attr "); break 511 #define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf(".attr "); break 510 512 #endif /* __STDC__ */ 511 513 … … 513 515 514 516 while (type) { 515 516 517 518 519 520 521 522 523 524 525 526 527 528 517 tbit = 1 << (ffs(type) - 1); 518 type &= ~tbit; 519 520 switch(tbit) { 521 PRINTBIT(OPTIONAL); 522 PRINTBIT(USE); 523 PRINTBIT(EXEC); 524 PRINTBIT(IGNORE); 525 PRINTBIT(PRECIOUS); 526 PRINTBIT(SILENT); 527 PRINTBIT(MAKE); 528 PRINTBIT(JOIN); 529 PRINTBIT(INVISIBLE); 530 PRINTBIT(NOTMAIN); 529 531 #ifdef USE_ARCHIVES 530 532 PRINTDBIT(LIB); 531 533 /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */ 532 533 534 case OP_MEMBER: if (DEBUG(TARG)) printf(".MEMBER "); break; 535 PRINTDBIT(ARCHV); 534 536 #endif 535 537 } 536 538 } 537 539 } … … 540 542 *----------------------------------------------------------------------- 541 543 * TargPrintNode -- 542 * 544 * print the contents of a node 543 545 *----------------------------------------------------------------------- 544 546 */ … … 546 548 TargPrintNode (gnp, passp) 547 549 ClientData gnp; 548 ClientData 550 ClientData passp; 549 551 { 550 552 GNode *gn = (GNode *) gnp; 551 int 553 int pass = *(int *) passp; 552 554 if (!OP_NOP(gn->type)) { 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 555 printf("#\n"); 556 if (gn == mainTarg) { 557 printf("# *** MAIN TARGET ***\n"); 558 } 559 if (pass == 2) { 560 if (gn->unmade) { 561 printf("# %d unmade children\n", gn->unmade); 562 } else { 563 printf("# No unmade children\n"); 564 } 565 if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) { 566 if (gn->mtime != 0) { 567 printf("# last modified %s: %s\n", 568 Targ_FmtTime(gn->mtime), 569 (gn->made == UNMADE ? "unmade" : 570 (gn->made == MADE ? "made" : 571 (gn->made == UPTODATE ? "up-to-date" : 572 "error when made")))); 573 } else if (gn->made != UNMADE) { 574 printf("# non-existent (maybe): %s\n", 575 (gn->made == MADE ? "made" : 576 (gn->made == UPTODATE ? "up-to-date" : 577 (gn->made == ERROR ? "error when made" : 578 "aborted")))); 579 } else { 580 printf("# unmade\n"); 581 } 582 } 583 if (!Lst_IsEmpty (gn->iParents)) { 584 printf("# implicit parents: "); 585 Lst_ForEach (gn->iParents, TargPrintName, (ClientData)0); 586 fputc ('\n', stdout); 587 } 588 } 589 if (!Lst_IsEmpty (gn->parents)) { 590 printf("# parents: "); 591 Lst_ForEach (gn->parents, TargPrintName, (ClientData)0); 592 fputc ('\n', stdout); 593 } 594 595 printf("%-16s", gn->name); 596 switch (gn->type & OP_OPMASK) { 597 case OP_DEPENDS: 598 printf(": "); break; 599 case OP_FORCE: 600 printf("! "); break; 601 case OP_DOUBLEDEP: 602 printf(":: "); break; 603 } 604 Targ_PrintType (gn->type); 605 Lst_ForEach (gn->children, TargPrintName, (ClientData)0); 606 fputc ('\n', stdout); 607 Lst_ForEach (gn->commands, Targ_PrintCmd, (ClientData)0); 608 printf("\n\n"); 609 if (gn->type & OP_DOUBLEDEP) { 610 Lst_ForEach (gn->cohorts, TargPrintNode, (ClientData)&pass); 611 } 610 612 } 611 613 return (0); … … 615 617 *----------------------------------------------------------------------- 616 618 * TargPrintOnlySrc -- 617 * 618 * 619 * Results: 620 * 621 * 622 * Side Effects: 623 * 619 * Print only those targets that are just a source. 620 * 621 * Results: 622 * 0. 623 * 624 * Side Effects: 625 * The name of each file is printed preceeded by #\t 624 626 * 625 627 *----------------------------------------------------------------------- … … 627 629 static int 628 630 TargPrintOnlySrc(gnp, dummy) 629 ClientData 630 ClientData 631 { 632 GNode 631 ClientData gnp; 632 ClientData dummy; 633 { 634 GNode *gn = (GNode *) gnp; 633 635 if (OP_NOP(gn->type)) 634 636 printf("#\t%s [%s]\n", gn->name, gn->path ? gn->path : gn->name); 635 637 636 638 return (dummy ? 0 : 0); … … 640 642 *----------------------------------------------------------------------- 641 643 * Targ_PrintGraph -- 642 * 643 * 644 * Results: 645 * 646 * 647 * Side Effects: 648 * 644 * print the entire graph. heh heh 645 * 646 * Results: 647 * none 648 * 649 * Side Effects: 650 * lots o' output 649 651 *----------------------------------------------------------------------- 650 652 */ 651 653 void 652 654 Targ_PrintGraph (pass) 653 int pass;/* Which pass this is. 1 => no processing654 655 int pass; /* Which pass this is. 1 => no processing 656 * 2 => processing done */ 655 657 { 656 658 printf("#*** Input graph:\n");
Note:
See TracChangeset
for help on using the changeset viewer.