version 1.45, 2007/09/17 09:28:36 |
version 1.46, 2007/09/17 12:42:09 |
|
|
#include "extern.h" |
#include "extern.h" |
#include "timestamp.h" |
#include "timestamp.h" |
#include "lst.h" |
#include "lst.h" |
|
#include "node_int.h" |
|
#include "nodehashconsts.h" |
#ifdef CLEANUP |
#ifdef CLEANUP |
#include <stdlib.h> |
#include <stdlib.h> |
#endif |
#endif |
|
|
static struct ohash targets; /* a hash table of same */ |
static struct ohash targets; /* a hash table of same */ |
static struct ohash_info gnode_info = { |
struct ohash_info gnode_info = { |
offsetof(GNode, name), |
offsetof(GNode, name), NULL, hash_alloc, hash_free, element_alloc |
NULL, hash_alloc, hash_free, element_alloc |
|
}; |
}; |
|
|
static void TargPrintOnlySrc(GNode *); |
static void TargPrintOnlySrc(GNode *); |
|
|
static void TargFreeGN(void *); |
static void TargFreeGN(void *); |
#endif |
#endif |
|
|
/*- |
GNode *begin_node, *end_node, *interrupt_node, *DEFAULT; |
*----------------------------------------------------------------------- |
|
* Targ_Init -- |
|
* Initialize this module |
|
* |
|
* Side Effects: |
|
* The targets hash table is initialized |
|
*----------------------------------------------------------------------- |
|
*/ |
|
void |
void |
Targ_Init(void) |
Targ_Init(void) |
{ |
{ |
|
|
#ifdef CLEANUP |
#ifdef CLEANUP |
Lst_Init(&allTargets); |
Lst_Init(&allTargets); |
#endif |
#endif |
|
begin_node = Targ_FindConstantNode(NODE_BEGIN, TARG_CREATE); |
|
begin_node->type |= OP_DUMMY | OP_NOTMAIN | OP_NODEFAULT; |
|
end_node = Targ_FindConstantNode(NODE_END, TARG_CREATE); |
|
end_node->type |= OP_DUMMY | OP_NOTMAIN | OP_NODEFAULT; |
|
interrupt_node = Targ_FindConstantNode(NODE_INTERRUPT, TARG_CREATE); |
|
interrupt_node->type |= OP_DUMMY | OP_NOTMAIN | OP_NODEFAULT; |
|
DEFAULT = Targ_FindConstantNode(NODE_DEFAULT, TARG_CREATE); |
|
DEFAULT->type |= OP_DUMMY | OP_NOTMAIN| OP_TRANSFORM | OP_NODEFAULT; |
|
|
} |
} |
|
|
/*- |
|
*----------------------------------------------------------------------- |
|
* Targ_End -- |
|
* Finalize this module |
|
* |
|
* Side Effects: |
|
* All lists and gnodes are cleared |
|
*----------------------------------------------------------------------- |
|
*/ |
|
#ifdef CLEANUP |
#ifdef CLEANUP |
void |
void |
Targ_End(void) |
Targ_End(void) |
|
|
} |
} |
#endif |
#endif |
|
|
/*- |
|
*----------------------------------------------------------------------- |
|
* Targ_NewGNi -- |
|
* Create and initialize a new graph node |
|
* |
|
* Results: |
|
* An initialized graph node with the name field filled with a copy |
|
* of the passed name |
|
* |
|
* Side effect: |
|
* add targets to list of all targets if CLEANUP |
|
*----------------------------------------------------------------------- |
|
*/ |
|
GNode * |
GNode * |
Targ_NewGNi(const char *name, /* the name to stick in the new node */ |
Targ_NewGNi(const char *name, const char *ename) |
const char *ename) |
|
{ |
{ |
GNode *gn; |
GNode *gn; |
|
|
gn = ohash_create_entry(&gnode_info, name, &ename); |
gn = ohash_create_entry(&gnode_info, name, &ename); |
gn->path = NULL; |
gn->path = NULL; |
if (name[0] == '-' && name[1] == 'l') { |
if (name[0] == '-' && name[1] == 'l') |
gn->type = OP_LIB; |
gn->type = OP_LIB; |
} else { |
else |
gn->type = 0; |
gn->type = 0; |
} |
|
gn->unmade = 0; |
gn->special = SPECIAL_NONE; |
gn->make = false; |
gn->unmade = 0; |
gn->made = UNMADE; |
gn->make = false; |
|
gn->made = UNMADE; |
gn->childMade = false; |
gn->childMade = false; |
gn->order = 0; |
gn->order = 0; |
ts_set_out_of_date(gn->mtime); |
ts_set_out_of_date(gn->mtime); |
ts_set_out_of_date(gn->cmtime); |
ts_set_out_of_date(gn->cmtime); |
Lst_Init(&gn->iParents); |
Lst_Init(&gn->iParents); |
|
|
} |
} |
|
|
#ifdef CLEANUP |
#ifdef CLEANUP |
/*- |
|
*----------------------------------------------------------------------- |
|
* TargFreeGN -- |
|
* Destroy a GNode |
|
*----------------------------------------------------------------------- |
|
*/ |
|
static void |
static void |
TargFreeGN(void *gnp) |
TargFreeGN(void *gnp) |
{ |
{ |
|
|
} |
} |
#endif |
#endif |
|
|
|
GNode * |
|
Targ_FindNodei(const char *name, const char *ename, int flags) |
|
{ |
|
uint32_t hv; |
|
|
/*- |
hv = ohash_interval(name, &ename); |
*----------------------------------------------------------------------- |
return Targ_FindNodeih(name, ename, hv, flags); |
* Targ_FindNodei -- |
} |
* Find a node in the list using the given name for matching |
|
* |
|
* Results: |
|
* The node in the list if it was. If it wasn't, return NULL if |
|
* flags was TARG_NOCREATE or the newly created and initialized node |
|
* if flags was TARG_CREATE |
|
* |
|
* Side Effects: |
|
* Sometimes a node is created and added to the list |
|
*----------------------------------------------------------------------- |
|
*/ |
|
GNode * |
GNode * |
Targ_FindNodei(const char *name, const char *ename, |
Targ_FindNodeih(const char *name, const char *ename, uint32_t hv, int flags) |
int flags) /* flags governing events when target not |
|
* found */ |
|
{ |
{ |
GNode *gn; /* node in that element */ |
GNode *gn; |
unsigned int slot; |
unsigned int slot; |
|
|
slot = ohash_qlookupi(&targets, name, &ename); |
slot = ohash_lookup_interval(&targets, name, ename, hv); |
|
|
gn = ohash_find(&targets, slot); |
gn = ohash_find(&targets, slot); |
|
|
|
|
return gn; |
return gn; |
} |
} |
|
|
/*- |
|
*----------------------------------------------------------------------- |
|
* Targ_FindList -- |
|
* Make a complete list of GNodes from the given list of names |
|
* |
|
* Side Effects: |
|
* Nodes will be created for all names in names which do not yet have graph |
|
* nodes. |
|
* |
|
* A complete list of graph nodes corresponding to all instances of all |
|
* the names in names is added to nodes. |
|
* ----------------------------------------------------------------------- |
|
*/ |
|
void |
void |
Targ_FindList(Lst nodes, /* result list */ |
Targ_FindList(Lst nodes, Lst names) |
Lst names) /* list of names to find */ |
|
{ |
{ |
LstNode ln; /* name list element */ |
LstNode ln; |
GNode *gn; /* node in tLn */ |
GNode *gn; |
char *name; |
char *name; |
|
|
for (ln = Lst_First(names); ln != NULL; ln = Lst_Adv(ln)) { |
for (ln = Lst_First(names); ln != NULL; ln = Lst_Adv(ln)) { |
|
|
return false; |
return false; |
} |
} |
|
|
/******************* DEBUG INFO PRINTING ****************/ |
|
|
|
static GNode *mainTarg; /* the main target, as set by Targ_SetMain */ |
|
/*- |
|
*----------------------------------------------------------------------- |
|
* Targ_SetMain -- |
|
* Set our idea of the main target we'll be creating. Used for |
|
* debugging output. |
|
* |
|
* Side Effects: |
|
* "mainTarg" is set to the main target's node. |
|
*----------------------------------------------------------------------- |
|
*/ |
|
void |
|
Targ_SetMain(GNode *gn) |
|
{ |
|
mainTarg = gn; |
|
} |
|
|
|
static void |
static void |
TargPrintName(void *gnp) |
TargPrintName(void *gnp) |
{ |
{ |
|
|
printf("\t%s\n", (char *)cmd); |
printf("\t%s\n", (char *)cmd); |
} |
} |
|
|
/*- |
|
*----------------------------------------------------------------------- |
|
* Targ_PrintType -- |
|
* Print out a type field giving only those attributes the user can |
|
* set. |
|
*----------------------------------------------------------------------- |
|
*/ |
|
void |
void |
Targ_PrintType(int type) |
Targ_PrintType(int type) |
{ |
{ |
int tbit; |
int tbit; |
|
|
#define PRINTBIT(attr) case CONCAT(OP_,attr): \ |
#define PRINTBIT(attr) case CONCAT(OP_,attr): printf("." #attr " "); break |
printf("." #attr " "); \ |
#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf("." #attr " "); break |
break |
|
#define PRINTDBIT(attr) case CONCAT(OP_,attr): \ |
|
if (DEBUG(TARG)) \ |
|
printf("." #attr " "); \ |
|
break |
|
|
|
type &= ~OP_OPMASK; |
type &= ~OP_OPMASK; |
|
|
|
|
break; |
break; |
PRINTDBIT(ARCHV); |
PRINTDBIT(ARCHV); |
} |
} |
} |
} |
} |
} |
|
|
static void |
static void |
|
|
if (OP_NOP(gn->type)) |
if (OP_NOP(gn->type)) |
return; |
return; |
printf("#\n"); |
printf("#\n"); |
if (gn == mainTarg) { |
|
printf("# *** MAIN TARGET ***\n"); |
|
} |
|
if (pass == 2) { |
if (pass == 2) { |
if (gn->unmade) { |
printf("# %d unmade children\n", gn->unmade); |
printf("# %d unmade children\n", gn->unmade); |
|
} else { |
|
printf("# No unmade children\n"); |
|
} |
|
if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) { |
if (! (gn->type & (OP_JOIN|OP_USE|OP_EXEC))) { |
if (!is_out_of_date(gn->mtime)) { |
if (!is_out_of_date(gn->mtime)) { |
printf("# last modified %s: %s\n", |
printf("# last modified %s: %s\n", |
time_to_string(gn->mtime), |
time_to_string(gn->mtime), |
(gn->made == UNMADE ? "unmade" : |
(gn->made == UNMADE ? "unmade" : |
(gn->made == MADE ? "made" : |
(gn->made == MADE ? "made" : |
(gn->made == UPTODATE ? "up-to-date" : |
(gn->made == UPTODATE ? "up-to-date" : |
"error when made")))); |
"error when made")))); |
} else if (gn->made != UNMADE) { |
} else if (gn->made != UNMADE) { |
printf("# non-existent (maybe): %s\n", |
printf("# non-existent (maybe): %s\n", |
(gn->made == MADE ? "made" : |
(gn->made == MADE ? "made" : |
(gn->made == UPTODATE ? "up-to-date" : |
(gn->made == UPTODATE ? "up-to-date" : |
(gn->made == ERROR ? "error when made" : |
(gn->made == ERROR ? "error when made" : |
"aborted")))); |
"aborted")))); |
} else { |
} else { |
printf("# unmade\n"); |
printf("# unmade\n"); |
} |
} |
|
|
printf("#\n# Files that are only sources:\n"); |
printf("#\n# Files that are only sources:\n"); |
for (gn = ohash_first(&targets, &i); gn != NULL; |
for (gn = ohash_first(&targets, &i); gn != NULL; |
gn = ohash_next(&targets, &i)) |
gn = ohash_next(&targets, &i)) |
TargPrintOnlySrc(gn); |
TargPrintOnlySrc(gn); |
Var_Dump(); |
Var_Dump(); |
printf("\n"); |
printf("\n"); |
|
#ifdef DEBUG_DIRECTORY_CACHE |
|
Dir_PrintDirectories(); |
|
printf("\n"); |
|
#endif |
Suff_PrintAll(); |
Suff_PrintAll(); |
} |
} |