/*- *----------------------------------------------------------------------- * Targ_FindList -- * Make a complete list of GNodes from the given list of names * * Results: * A complete list of graph nodes corresponding to all instances of all * the names in names. * * Side Effects: * If flags is TARG_CREATE, nodes will be created for all names in * names which do not yet have graph nodes. If flags is TARG_NOCREATE, * an error message will be printed for each name which can't be found. * ----------------------------------------------------------------------- */ Lst Targ_FindList ( Lst names, /* list of names to find */ int flags) /* flags used if no node is found for a given * name */ { Lst nodes; /* result list */ register LstNode ln; /* name list element */ register GNode *gn; /* node in tLn */ string_t name; nodes = Lst_Init(); Lst_Open (names); while ((ln = Lst_Next (names)) != NILLNODE) { name = (string_t)Lst_Datum(ln); gn = Targ_FindNode (name, flags); if (gn != NILGNODE) { /* * Note: Lst_AtEnd must come before the Lst_Concat so the nodes * are added to the list in the order in which they were * encountered in the makefile. */ (void) Lst_AtEnd (nodes, (ClientData)gn); if (gn->type & OP_DOUBLEDEP) { (void)Lst_Concat (nodes, gn->cohorts, LST_CONCNEW); } } else if (flags == TARG_NOCREATE) { Error ("\"%s\" -- target unknown.", name->data); } } Lst_Close (names); return (nodes); }
void Make_HandleUse(GNode *cgn, /* The .USE node */ GNode *pgn) /* The target of the .USE node */ { GNode *gn; /* A child of the .USE node */ LstNode ln; /* An element in the children list */ assert(cgn->type & (OP_USE|OP_TRANSFORM)); if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) { /* .USE or transformation and target has no commands * -- append the child's commands to the parent. */ Lst_Concat(&pgn->commands, &cgn->commands); } for (ln = Lst_First(&cgn->children); ln != NULL; ln = Lst_Adv(ln)) { gn = (GNode *)Lst_Datum(ln); if (Lst_AddNew(&pgn->children, gn)) { Lst_AtEnd(&gn->parents, pgn); pgn->unmade++; } } pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM); /* * This child node is now "made", so we decrement the count of * unmade children in the parent... We also remove the child * from the parent's list to accurately reflect the number of * decent children the parent has. This is used by Make_Run to * decide whether to queue the parent or examine its children... */ if (cgn->type & OP_USE) pgn->unmade--; /* if the parent node doesn't have any location, then inherit the * use stuff, since that gives us better error messages. */ if (!pgn->lineno) { pgn->lineno = cgn->lineno; pgn->fname = cgn->fname; } }
void Targ_FindList(Lst nodes, Lst names) { LstNode ln; GNode *gn; char *name; for (ln = Lst_First(names); ln != NULL; ln = Lst_Adv(ln)) { name = (char *)Lst_Datum(ln); gn = Targ_FindNode(name, TARG_CREATE); /* Note: Lst_AtEnd must come before the Lst_Concat so the nodes * are added to the list in the order in which they were * encountered in the makefile. */ Lst_AtEnd(nodes, gn); if (gn->type & OP_DOUBLEDEP) Lst_Concat(nodes, &gn->cohorts); } }
/*- *----------------------------------------------------------------------- * Make_HandleUse -- * Function called by Make_Run and SuffApplyTransform on the downward * pass to handle .USE and transformation nodes. It implements the * .USE and transformation functionality by copying the node's commands, * type flags and children to the parent node. * * A .USE node is much like an explicit transformation rule, except * its commands are always added to the target node, even if the * target already has commands. * * Input: * cgn The .USE node * pgn The target of the .USE node * * Results: * none * * Side Effects: * Children and commands may be added to the parent and the parent's * type may be changed. * *----------------------------------------------------------------------- */ void Make_HandleUse(GNode *cgn, GNode *pgn) { LstNode ln; /* An element in the children list */ #ifdef DEBUG_SRC if ((cgn->type & (OP_USE|OP_USEBEFORE|OP_TRANSFORM)) == 0) { fprintf(debug_file, "Make_HandleUse: called for plain node %s\n", cgn->name); return; } #endif if ((cgn->type & (OP_USE|OP_USEBEFORE)) || Lst_IsEmpty(pgn->commands)) { if (cgn->type & OP_USEBEFORE) { /* * .USEBEFORE -- * prepend the child's commands to the parent. */ Lst cmds = pgn->commands; pgn->commands = Lst_Duplicate(cgn->commands, NULL); (void)Lst_Concat(pgn->commands, cmds, LST_CONCNEW); Lst_Destroy(cmds, NULL); } else { /* * .USE or target has no commands -- * append the child's commands to the parent. */ (void)Lst_Concat(pgn->commands, cgn->commands, LST_CONCNEW); } } if (Lst_Open(cgn->children) == SUCCESS) { while ((ln = Lst_Next(cgn->children)) != NULL) { GNode *tgn, *gn = (GNode *)Lst_Datum(ln); /* * Expand variables in the .USE node's name * and save the unexpanded form. * We don't need to do this for commands. * They get expanded properly when we execute. */ if (gn->uname == NULL) { gn->uname = gn->name; } else { free(gn->name); } gn->name = Var_Subst(NULL, gn->uname, pgn, VARF_WANTRES); if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) { /* See if we have a target for this node. */ tgn = Targ_FindNode(gn->name, TARG_NOCREATE); if (tgn != NULL) gn = tgn; } (void)Lst_AtEnd(pgn->children, gn); (void)Lst_AtEnd(gn->parents, pgn); pgn->unmade += 1; } Lst_Close(cgn->children); } pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_USEBEFORE|OP_TRANSFORM); }