version 1.24, 2000/11/24 14:36:34 |
version 1.25, 2001/05/03 13:41:08 |
|
|
|
/* $OpenPackages$ */ |
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
/* $NetBSD: make.c,v 1.10 1996/11/06 17:59:15 christos Exp $ */ |
/* $NetBSD: make.c,v 1.10 1996/11/06 17:59:15 christos Exp $ */ |
|
|
|
|
* their suitability for creation |
* their suitability for creation |
* |
* |
* Interface: |
* Interface: |
* Make_Run Initialize things for the module and recreate |
* Make_Run Initialize things for the module and recreate |
* whatever needs recreating. Returns TRUE if |
* whatever needs recreating. Returns TRUE if |
* work was (or would have been) done and FALSE |
* work was (or would have been) done and FALSE |
* otherwise. |
* otherwise. |
* |
* |
* Make_Update Update all parents of a given child. Performs |
* Make_Update Update all parents of a given child. Performs |
* various bookkeeping chores like the updating |
* various bookkeeping chores like the updating |
* of the cmtime field of the parent, filling |
* of the cmtime field of the parent, filling |
* of the IMPSRC context variable, etc. It will |
* of the IMPSRC context variable, etc. It will |
* place the parent on the toBeMade queue if it |
* place the parent on the toBeMade queue if it |
* should be. |
* should be. |
* |
* |
* Make_TimeStamp Function to set the parent's cmtime field |
* Make_TimeStamp Function to set the parent's cmtime field |
* based on a child's modification time. |
* based on a child's modification time. |
* |
* |
* Make_DoAllVar Set up the various local variables for a |
* Make_DoAllVar Set up the various local variables for a |
* target, including the .ALLSRC variable, making |
* target, including the .ALLSRC variable, making |
* sure that any variable that needs to exist |
* sure that any variable that needs to exist |
* at the very least has the empty value. |
* at the very least has the empty value. |
* |
* |
* Make_OODate Determine if a target is out-of-date. |
* Make_OODate Determine if a target is out-of-date. |
* |
* |
* Make_HandleUse See if a child is a .USE node for a parent |
* Make_HandleUse See if a child is a .USE node for a parent |
* and perform the .USE actions if so. |
* and perform the .USE actions if so. |
|
|
#endif |
#endif |
#endif /* not lint */ |
#endif /* not lint */ |
|
|
static LIST toBeMade; /* The current fringe of the graph. These |
|
|
static LIST toBeMade; /* The current fringe of the graph. These |
* are nodes which await examination by |
* are nodes which await examination by |
* MakeOODate. It is added to by |
* MakeOODate. It is added to by |
* Make_Update and subtracted from by |
* Make_Update and subtracted from by |
* MakeStartJobs */ |
* MakeStartJobs */ |
static int numNodes; /* Number of nodes to be processed. If this |
static int numNodes; /* Number of nodes to be processed. If this |
* is non-zero when Job_Empty() returns |
* is non-zero when Job_Empty() returns |
* TRUE, there's a cycle in the graph */ |
* TRUE, there's a cycle in the graph */ |
|
|
static void MakeAddChild __P((void *, void *)); |
static void MakeAddChild(void *, void *); |
static void MakeAddAllSrc __P((void *, void *)); |
static void MakeAddAllSrc(void *, void *); |
static void MakeTimeStamp __P((void *, void *)); |
static void MakeTimeStamp(void *, void *); |
static void MakeHandleUse __P((void *, void *)); |
static void MakeHandleUse(void *, void *); |
static Boolean MakeStartJobs __P((void)); |
static Boolean MakeStartJobs(void); |
static void MakePrintStatus __P((void *, void *)); |
static void MakePrintStatus(void *, void *); |
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* Make_TimeStamp -- |
* Make_TimeStamp -- |
* Set the cmtime field of a parent node based on the mtime stamp in its |
* Set the cmtime field of a parent node based on the mtime stamp in its |
* child. Called from MakeOODate via Lst_ForEach. |
* child. |
* |
* |
* Side Effects: |
* Side Effects: |
* The cmtime of the parent node will be changed if the mtime |
* The cmtime of the parent node will be changed if the mtime |
|
|
*/ |
*/ |
void |
void |
Make_TimeStamp(pgn, cgn) |
Make_TimeStamp(pgn, cgn) |
GNode *pgn; /* the current parent */ |
GNode *pgn; /* the current parent */ |
GNode *cgn; /* the child we've just examined */ |
GNode *cgn; /* the child we've just examined */ |
{ |
{ |
if (is_before(pgn->cmtime, cgn->mtime)) |
if (is_before(pgn->cmtime, cgn->mtime)) |
pgn->cmtime = cgn->mtime; |
pgn->cmtime = cgn->mtime; |
} |
} |
|
|
/* Wrapper to call Make_TimeStamp from a forEach loop */ |
/* Wrapper to call Make_TimeStamp from a forEach loop. */ |
static void |
static void |
MakeTimeStamp(pgn, cgn) |
MakeTimeStamp(pgn, cgn) |
void *pgn; /* the current parent */ |
void *pgn; /* the current parent */ |
|
|
{ |
{ |
Make_TimeStamp((GNode *)pgn, (GNode *)cgn); |
Make_TimeStamp((GNode *)pgn, (GNode *)cgn); |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* Make_OODate -- |
* Make_OODate -- |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
Boolean |
Boolean |
Make_OODate (gn) |
Make_OODate(gn) |
register GNode *gn; /* the node to check */ |
GNode *gn; /* the node to check */ |
{ |
{ |
Boolean oodate; |
Boolean oodate; |
|
|
/* |
/* |
* Certain types of targets needn't even be sought as their datedness |
* Certain types of targets needn't even be sought as their datedness |
|
|
(void)Dir_MTime(gn); |
(void)Dir_MTime(gn); |
if (DEBUG(MAKE)) { |
if (DEBUG(MAKE)) { |
if (!is_out_of_date(gn->mtime)) { |
if (!is_out_of_date(gn->mtime)) { |
printf ("modified %s...", Targ_FmtTime(gn->mtime)); |
printf("modified %s...", Targ_FmtTime(gn->mtime)); |
} else { |
} else { |
printf ("non-existent..."); |
printf("non-existent..."); |
} |
} |
} |
} |
} |
} |
|
|
* always out of date if no children and :: target |
* always out of date if no children and :: target |
*/ |
*/ |
|
|
oodate = Arch_LibOODate (gn) || |
oodate = Arch_LibOODate(gn) || |
(is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP)); |
(is_out_of_date(gn->cmtime) && (gn->type & OP_DOUBLEDEP)); |
} else if (gn->type & OP_JOIN) { |
} else if (gn->type & OP_JOIN) { |
/* |
/* |
|
|
if (!oodate) |
if (!oodate) |
Lst_ForEach(&gn->parents, MakeTimeStamp, gn); |
Lst_ForEach(&gn->parents, MakeTimeStamp, gn); |
|
|
return (oodate); |
return oodate; |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* MakeAddChild -- |
* MakeAddChild -- |
|
|
void *gnp; /* the node to add */ |
void *gnp; /* the node to add */ |
void *lp; /* the list to which to add it */ |
void *lp; /* the list to which to add it */ |
{ |
{ |
GNode *gn = (GNode *)gnp; |
GNode *gn = (GNode *)gnp; |
Lst l = (Lst)lp; |
Lst l = (Lst)lp; |
|
|
if (!gn->make && !(gn->type & OP_USE)) |
if (!gn->make && !(gn->type & OP_USE)) |
Lst_EnQueue(l, gn); |
Lst_EnQueue(l, gn); |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* Make_HandleUse -- |
* Make_HandleUse -- |
|
|
void |
void |
Make_HandleUse(cgn, pgn) |
Make_HandleUse(cgn, pgn) |
GNode *cgn; /* The .USE node */ |
GNode *cgn; /* The .USE node */ |
GNode *pgn; /* The target of the .USE node */ |
GNode *pgn; /* The target of the .USE node */ |
{ |
{ |
GNode *gn; /* A child of the .USE node */ |
GNode *gn; /* A child of the .USE node */ |
LstNode ln; /* An element in the children list */ |
LstNode ln; /* An element in the children list */ |
|
|
if (cgn->type & (OP_USE|OP_TRANSFORM)) { |
if (cgn->type & (OP_USE|OP_TRANSFORM)) { |
if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) { |
if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) { |
/* |
/* .USE or transformation and target has no commands -- append |
* .USE or transformation and target has no commands -- append |
* the child's commands to the parent. */ |
* the child's commands to the parent. |
|
*/ |
|
Lst_Concat(&pgn->commands, &cgn->commands); |
Lst_Concat(&pgn->commands, &cgn->commands); |
} |
} |
|
|
Lst_Open(&cgn->children); |
for (ln = Lst_First(&cgn->children); ln != NULL; ln = Lst_Adv(ln)) { |
while ((ln = Lst_Next(&cgn->children)) != NULL) { |
|
gn = (GNode *)Lst_Datum(ln); |
gn = (GNode *)Lst_Datum(ln); |
|
|
if (Lst_Member(&pgn->children, gn) == NULL) { |
if (Lst_AddNew(&pgn->children, gn) == SUCCESS) { |
Lst_AtEnd(&pgn->children, gn); |
|
Lst_AtEnd(&gn->parents, pgn); |
Lst_AtEnd(&gn->parents, pgn); |
pgn->unmade += 1; |
pgn->unmade += 1; |
} |
} |
} |
} |
Lst_Close(&cgn->children); |
|
|
|
pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM); |
pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM); |
|
|
|
|
{ |
{ |
Make_HandleUse((GNode *)pgn, (GNode *)cgn); |
Make_HandleUse((GNode *)pgn, (GNode *)cgn); |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* Make_Update -- |
* Make_Update -- |
* Perform update on the parents of a node. Used by JobFinish once |
* Perform update on the parents of a node. Used by JobFinish once |
* a node has been dealt with and by MakeStartJobs if it finds an |
* a node has been dealt with and by MakeStartJobs if it finds an |
* up-to-date node. |
* up-to-date node. |
|
|
* The unmade field of pgn is decremented and pgn may be placed on |
* The unmade field of pgn is decremented and pgn may be placed on |
* the toBeMade queue if this field becomes 0. |
* the toBeMade queue if this field becomes 0. |
* |
* |
* If the child was made, the parent's childMade field will be set true |
* If the child was made, the parent's childMade field will be set true |
* and its cmtime set to now. |
* and its cmtime set to now. |
* |
* |
* If the child wasn't made, the cmtime field of the parent will be |
* If the child wasn't made, the cmtime field of the parent will be |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Make_Update (cgn) |
Make_Update(cgn) |
register GNode *cgn; /* the child node */ |
GNode *cgn; /* the child node */ |
{ |
{ |
register GNode *pgn; /* the parent node */ |
GNode *pgn; /* the parent node */ |
register char *cname; /* the child's name */ |
char *cname; /* the child's name */ |
register LstNode ln; /* Element in parents and iParents lists */ |
LstNode ln; /* Element in parents and iParents lists */ |
|
|
cname = Varq_Value(TARGET_INDEX, cgn); |
cname = Varq_Value(TARGET_INDEX, cgn); |
|
|
|
|
* parse.h : parse.o |
* parse.h : parse.o |
* |
* |
* parse.o : parse.y |
* parse.o : parse.y |
* yacc -d parse.y |
* yacc -d parse.y |
* cc -c y.tab.c |
* cc -c y.tab.c |
* mv y.tab.o parse.o |
* mv y.tab.o parse.o |
* cmp -s y.tab.h parse.h || mv y.tab.h parse.h |
* cmp -s y.tab.h parse.h || mv y.tab.h parse.h |
* |
* |
* In this case, if the definitions produced by yacc haven't changed |
* In this case, if the definitions produced by yacc haven't changed |
* from before, parse.h won't have been updated and cgn->mtime will |
* from before, parse.h won't have been updated and cgn->mtime will |
|
|
* -- ardeb 1/12/88 |
* -- ardeb 1/12/88 |
*/ |
*/ |
/* |
/* |
* Christos, 4/9/92: If we are saving commands pretend that |
* Christos, 4/9/92: If we are saving commands pretend that |
* the target is made now. Otherwise archives with ... rules |
* the target is made now. Otherwise archives with ... rules |
* don't work! |
* don't work! |
*/ |
*/ |
if (noExecute || (cgn->type & OP_SAVE_CMDS) || |
if (noExecute || (cgn->type & OP_SAVE_CMDS) || |
is_out_of_date(Dir_MTime(cgn))) { |
is_out_of_date(Dir_MTime(cgn))) { |
cgn->mtime = now; |
cgn->mtime = now; |
} |
} |
|
|
#endif |
#endif |
} |
} |
|
|
Lst_Open(&cgn->parents); |
for (ln = Lst_First(&cgn->parents); ln != NULL; ln = Lst_Adv(ln)) { |
while ((ln = Lst_Next(&cgn->parents)) != NULL) { |
|
pgn = (GNode *)Lst_Datum(ln); |
pgn = (GNode *)Lst_Datum(ln); |
if (pgn->make) { |
if (pgn->make) { |
pgn->unmade -= 1; |
pgn->unmade -= 1; |
|
|
if ( ! (cgn->type & (OP_EXEC|OP_USE))) { |
if ( ! (cgn->type & (OP_EXEC|OP_USE))) { |
if (cgn->made == MADE) { |
if (cgn->made == MADE) { |
pgn->childMade = TRUE; |
pgn->childMade = TRUE; |
if (is_before(pgn->cmtime, cgn->mtime)) { |
if (is_before(pgn->cmtime, cgn->mtime)) |
pgn->cmtime = cgn->mtime; |
pgn->cmtime = cgn->mtime; |
} |
|
} else { |
} else { |
(void)Make_TimeStamp(pgn, cgn); |
(void)Make_TimeStamp(pgn, cgn); |
} |
} |
|
|
*/ |
*/ |
Lst_EnQueue(&toBeMade, pgn); |
Lst_EnQueue(&toBeMade, pgn); |
} else if (pgn->unmade < 0) { |
} else if (pgn->unmade < 0) { |
Error ("Graph cycles through %s", pgn->name); |
Error("Graph cycles through %s", pgn->name); |
} |
} |
} |
} |
} |
} |
Lst_Close(&cgn->parents); |
/* Deal with successor nodes. If any is marked for making and has an unmade |
/* |
|
* Deal with successor nodes. If any is marked for making and has an unmade |
|
* count of 0, has not been made and isn't in the examination queue, |
* count of 0, has not been made and isn't in the examination queue, |
* it means we need to place it in the queue as it restrained itself |
* it means we need to place it in the queue as it restrained itself |
* before. |
* before. */ |
*/ |
|
for (ln = Lst_First(&cgn->successors); ln != NULL; ln = Lst_Adv(ln)) { |
for (ln = Lst_First(&cgn->successors); ln != NULL; ln = Lst_Adv(ln)) { |
GNode *succ = (GNode *)Lst_Datum(ln); |
GNode *succ = (GNode *)Lst_Datum(ln); |
|
|
if (succ->make && succ->unmade == 0 && succ->made == UNMADE && |
if (succ->make && succ->unmade == 0 && succ->made == UNMADE) |
Lst_Member(&toBeMade, succ) == NULL) |
(void)Lst_QueueNew(&toBeMade, succ); |
Lst_EnQueue(&toBeMade, succ); |
|
} |
} |
|
|
/* |
/* Set the .PREFIX and .IMPSRC variables for all the implied parents |
* Set the .PREFIX and .IMPSRC variables for all the implied parents |
* of this node. */ |
* of this node. |
|
*/ |
|
{ |
{ |
char *cpref = Varq_Value(PREFIX_INDEX, cgn); |
char *cpref = Varq_Value(PREFIX_INDEX, cgn); |
|
|
Lst_Open(&cgn->iParents); |
for (ln = Lst_First(&cgn->iParents); ln != NULL; ln = Lst_Adv(ln)) { |
while ((ln = Lst_Next(&cgn->iParents)) != NULL) { |
pgn = (GNode *)Lst_Datum(ln); |
pgn = (GNode *)Lst_Datum (ln); |
if (pgn->make) { |
if (pgn->make) { |
Varq_Set(IMPSRC_INDEX, cname, pgn); |
Varq_Set(IMPSRC_INDEX, cname, pgn); |
Varq_Set(PREFIX_INDEX, cpref, pgn); |
Varq_Set(PREFIX_INDEX, cpref, pgn); |
|
} |
|
} |
} |
Lst_Close(&cgn->iParents); |
|
} |
} |
|
} |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* MakeAddAllSrc -- |
* MakeAddAllSrc -- |
|
|
*/ |
*/ |
static void |
static void |
MakeAddAllSrc(cgnp, pgnp) |
MakeAddAllSrc(cgnp, pgnp) |
void *cgnp; /* The child to add */ |
void *cgnp; /* The child to add */ |
void *pgnp; /* The parent to whose ALLSRC variable it should be */ |
void *pgnp; /* The parent to whose ALLSRC variable it should be */ |
/* added */ |
/* added */ |
{ |
{ |
GNode *cgn = (GNode *) cgnp; |
GNode *cgn = (GNode *)cgnp; |
GNode *pgn = (GNode *) pgnp; |
GNode *pgn = (GNode *)pgnp; |
if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) { |
if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) { |
char *child; |
const char *child; |
|
|
if (OP_NOP(cgn->type) || |
if (OP_NOP(cgn->type) || |
(child = Varq_Value(TARGET_INDEX, cgn)) == NULL) { |
(child = Varq_Value(TARGET_INDEX, cgn)) == NULL) { |
/* |
/* |
* this node is only source; use the specific pathname for it |
* this node is only source; use the specific pathname for it |
*/ |
*/ |
child = cgn->path ? cgn->path : cgn->name; |
child = cgn->path != NULL ? cgn->path : cgn->name; |
} |
} |
|
|
Varq_Append(ALLSRC_INDEX, child, pgn); |
Varq_Append(ALLSRC_INDEX, child, pgn); |
if (pgn->type & OP_JOIN) { |
if (pgn->type & OP_JOIN) { |
if (cgn->made == MADE) |
if (cgn->made == MADE) { |
Varq_Append(OODATE_INDEX, child, pgn); |
Varq_Append(OODATE_INDEX, child, pgn); |
|
} |
} else if (is_before(pgn->mtime, cgn->mtime) || |
} else if (is_before(pgn->mtime, cgn->mtime) || |
(!is_before(cgn->mtime, now) && cgn->made == MADE)) |
(!is_before(cgn->mtime, now) && cgn->made == MADE)) |
{ |
{ |
|
|
} |
} |
} |
} |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* Make_DoAllVar -- |
* Make_DoAllVar -- |
|
|
* variable. As for ALLSRC, the ordering is important and not |
* variable. As for ALLSRC, the ordering is important and not |
* guaranteed when in native mode, so it must be set here, too. |
* guaranteed when in native mode, so it must be set here, too. |
* |
* |
* Results: |
|
* None |
|
* |
|
* Side Effects: |
* Side Effects: |
* The ALLSRC and OODATE variables of the given node is filled in. |
* The ALLSRC and OODATE variables of the given node is filled in. |
* If the node is a .JOIN node, its TARGET variable will be set to |
* If the node is a .JOIN node, its TARGET variable will be set to |
* match its ALLSRC variable. |
* match its ALLSRC variable. |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Make_DoAllVar (gn) |
Make_DoAllVar(gn) |
GNode *gn; |
GNode *gn; |
{ |
{ |
Lst_ForEach(&gn->children, MakeAddAllSrc, gn); |
Lst_ForEach(&gn->children, MakeAddAllSrc, gn); |
|
|
if (!Varq_Exists(OODATE_INDEX, gn)) |
if (Varq_Value(OODATE_INDEX, gn) == NULL) |
Varq_Set(OODATE_INDEX, "", gn); |
Varq_Set(OODATE_INDEX, "", gn); |
if (!Varq_Exists(ALLSRC_INDEX, gn)) |
if (Varq_Value(ALLSRC_INDEX, gn) == NULL) |
Varq_Set(ALLSRC_INDEX, "", gn); |
Varq_Set(ALLSRC_INDEX, "", gn); |
|
|
if (gn->type & OP_JOIN) |
if (gn->type & OP_JOIN) |
Varq_Set(TARGET_INDEX, Varq_Value(ALLSRC_INDEX, gn), gn); |
Varq_Set(TARGET_INDEX, Varq_Value(ALLSRC_INDEX, gn), gn); |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* MakeStartJobs -- |
* MakeStartJobs -- |
|
|
* Side Effects: |
* Side Effects: |
* Nodes are removed from the toBeMade queue and job table slots |
* Nodes are removed from the toBeMade queue and job table slots |
* are filled. |
* are filled. |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Boolean |
static Boolean |
MakeStartJobs () |
MakeStartJobs() |
{ |
{ |
register GNode *gn; |
GNode *gn; |
|
|
while (!Job_Full() && (gn = (GNode *)Lst_DeQueue(&toBeMade)) != NULL) { |
while (!Job_Full() && (gn = (GNode *)Lst_DeQueue(&toBeMade)) != NULL) { |
if (DEBUG(MAKE)) { |
if (DEBUG(MAKE)) { |
printf ("Examining %s...", gn->name); |
printf("Examining %s...", gn->name); |
} |
} |
/* |
/* |
* Make sure any and all predecessors that are going to be made, |
* Make sure any and all predecessors that are going to be made, |
|
|
} |
} |
} |
} |
/* |
/* |
* If ln isn't null, there's a predecessor as yet unmade, so we |
* If ln isn't NULL, there's a predecessor as yet unmade, so we |
* just drop this node on the floor. When the node in question |
* just drop this node on the floor. When the node in question |
* has been made, it will notice this node as being ready to |
* has been made, it will notice this node as being ready to |
* make but as yet unmade and will place the node on the queue. |
* make but as yet unmade and will place the node on the queue. |
|
|
} |
} |
|
|
numNodes--; |
numNodes--; |
if (Make_OODate (gn)) { |
if (Make_OODate(gn)) { |
if (DEBUG(MAKE)) { |
if (DEBUG(MAKE)) { |
printf ("out-of-date\n"); |
printf("out-of-date\n"); |
} |
} |
if (queryFlag) { |
if (queryFlag) { |
return (TRUE); |
return TRUE; |
} |
} |
Make_DoAllVar (gn); |
Make_DoAllVar(gn); |
Job_Make (gn); |
Job_Make(gn); |
} else { |
} else { |
if (DEBUG(MAKE)) { |
if (DEBUG(MAKE)) { |
printf ("up-to-date\n"); |
printf("up-to-date\n"); |
} |
} |
gn->made = UPTODATE; |
gn->made = UPTODATE; |
if (gn->type & OP_JOIN) { |
if (gn->type & OP_JOIN) { |
|
|
* value for .TARGET when building up the context variables |
* value for .TARGET when building up the context variables |
* of its parent(s)... |
* of its parent(s)... |
*/ |
*/ |
Make_DoAllVar (gn); |
Make_DoAllVar(gn); |
} |
} |
|
|
Make_Update (gn); |
Make_Update(gn); |
} |
} |
} |
} |
return (FALSE); |
return FALSE; |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* MakePrintStatus -- |
* MakePrintStatus -- |
* Print the status of a top-level node, viz. it being up-to-date |
* Print the status of a top-level node, viz. it being up-to-date |
* already or not created due to an error in a lower level. |
* already or not created due to an error in a lower level. |
* Callback function for Make_Run via Lst_ForEach. |
* Callback function for Make_Run via Lst_ForEach. |
|
* |
|
* Side Effects: |
|
* A message may be printed. |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static void |
static void |
MakePrintStatus(gnp, cyclep) |
MakePrintStatus(gnp, cyclep) |
void *gnp; /* Node to examine */ |
void *gnp; /* Node to examine */ |
void *cyclep; /* True if gn->unmade being non-zero implies |
void *cyclep; /* True if gn->unmade being non-zero implies |
* a cycle in the graph, not an error in an |
* a cycle in the graph, not an error in an |
* inferior */ |
* inferior */ |
{ |
{ |
GNode *gn = (GNode *) gnp; |
GNode *gn = (GNode *)gnp; |
Boolean cycle = *(Boolean *) cyclep; |
Boolean cycle = *(Boolean *)cyclep; |
if (gn->made == UPTODATE) { |
if (gn->made == UPTODATE) { |
printf ("`%s' is up to date.\n", gn->name); |
printf("`%s' is up to date.\n", gn->name); |
} else if (gn->unmade != 0) { |
} else if (gn->unmade != 0) { |
if (cycle) { |
if (cycle) { |
Boolean t = TRUE; |
Boolean t = TRUE; |
|
|
Lst_ForEach(&gn->children, MakePrintStatus, &t); |
Lst_ForEach(&gn->children, MakePrintStatus, &t); |
} |
} |
} else { |
} else { |
printf ("`%s' not remade because of errors.\n", gn->name); |
printf("`%s' not remade because of errors.\n", gn->name); |
} |
} |
} |
} |
} |
} |
|
|
|
|
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* Make_Run -- |
* Make_Run -- |
|
|
*/ |
*/ |
Boolean |
Boolean |
Make_Run(targs) |
Make_Run(targs) |
Lst targs; /* the initial list of targets */ |
Lst targs; /* the initial list of targets */ |
{ |
{ |
register GNode *gn; /* a temporary pointer */ |
GNode *gn; /* a temporary pointer */ |
LIST examine; /* List of targets to examine */ |
LIST examine; /* List of targets to examine */ |
int errors; /* Number of errors the Job module reports */ |
int errors; /* Number of errors the Job module reports */ |
|
|
Lst_Init(&toBeMade); |
Lst_Init(&toBeMade); |
|
|
|
|
* and go on about our business. |
* and go on about our business. |
*/ |
*/ |
while ((gn = (GNode *)Lst_DeQueue(&examine)) != NULL) { |
while ((gn = (GNode *)Lst_DeQueue(&examine)) != NULL) { |
|
|
if (!gn->make) { |
if (!gn->make) { |
gn->make = TRUE; |
gn->make = TRUE; |
numNodes++; |
numNodes++; |
|
|
* to make sure everything has commands that should... |
* to make sure everything has commands that should... |
*/ |
*/ |
Lst_ForEach(&gn->children, MakeHandleUse, gn); |
Lst_ForEach(&gn->children, MakeHandleUse, gn); |
Suff_FindDeps (gn); |
Suff_FindDeps(gn); |
|
|
if (gn->unmade != 0) { |
if (gn->unmade != 0) { |
Lst_ForEach(&gn->children, MakeAddChild, &examine); |
Lst_ForEach(&gn->children, MakeAddChild, &examine); |
|
|
} |
} |
} |
} |
|
|
Lst_Destroy(&examine, NOFREE); |
|
|
|
if (queryFlag) { |
if (queryFlag) { |
/* |
/* |
* We wouldn't do any work unless we could start some jobs in the |
* We wouldn't do any work unless we could start some jobs in the |
* next loop... (we won't actually start any, of course, this is just |
* next loop... (we won't actually start any, of course, this is just |
* to see if any of the targets was out of date) |
* to see if any of the targets was out of date) |
*/ |
*/ |
return (MakeStartJobs()); |
return MakeStartJobs(); |
} else { |
} else { |
/* |
/* |
* Initialization. At the moment, no jobs are running and until some |
* Initialization. At the moment, no jobs are running and until some |
|
|
* the finishing of a job. So we fill the Job table as much as we can |
* the finishing of a job. So we fill the Job table as much as we can |
* before going into our loop. |
* before going into our loop. |
*/ |
*/ |
(void) MakeStartJobs(); |
(void)MakeStartJobs(); |
} |
} |
|
|
/* |
/* |
|
|
* Note that the Job module will exit if there were any errors unless the |
* Note that the Job module will exit if there were any errors unless the |
* keepgoing flag was given. |
* keepgoing flag was given. |
*/ |
*/ |
while (!Job_Empty ()) { |
while (!Job_Empty()) { |
Job_CatchOutput (); |
Job_CatchOutput(); |
Job_CatchChildren (!usePipes); |
Job_CatchChildren(!usePipes); |
(void)MakeStartJobs(); |
(void)MakeStartJobs(); |
} |
} |
|
|
|
|
* Print the final status of each target. E.g. if it wasn't made |
* Print the final status of each target. E.g. if it wasn't made |
* because some inferior reported an error. |
* because some inferior reported an error. |
*/ |
*/ |
errors = ((errors == 0) && (numNodes != 0)); |
errors = errors == 0 && numNodes != 0; |
Lst_ForEach(targs, MakePrintStatus, &errors); |
Lst_ForEach(targs, MakePrintStatus, &errors); |
|
|
return (TRUE); |
return TRUE; |
} |
} |