summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.bin/make/suff.c369
1 files changed, 190 insertions, 179 deletions
diff --git a/usr.bin/make/suff.c b/usr.bin/make/suff.c
index d8d0e4b..f61fa79 100644
--- a/usr.bin/make/suff.c
+++ b/usr.bin/make/suff.c
@@ -1272,229 +1272,240 @@ SuffFindCmds(Src *targ, Lst *slst)
}
/*-
- *-----------------------------------------------------------------------
- * SuffExpandChildren --
- * Expand the names of any children of a given node that contain
- * variable invocations or file wildcards into actual targets.
- *
- * Results:
- * == 0 (continue)
- *
- * Side Effects:
- * The expanded node is removed from the parent's list of children,
- * and the parent's unmade counter is decremented, but other nodes
- * may be added.
- *
- *-----------------------------------------------------------------------
+ * The child node contains variable references. Expand them and return
+ * a list of expansions.
*/
-static int
-SuffExpandChildren(void *cgnp, void *pgnp)
+static void
+SuffExpandVariables(GNode *parent, GNode *child, Lst *members)
{
- GNode *cgn = cgnp;
- GNode *pgn = pgnp;
- GNode *gn; /* New source 8) */
- LstNode *prevLN; /* Node after which new source should be put */
- LstNode *ln; /* List element for old source */
- char *cp; /* Expanded value */
+ Buffer *buf;
+ char *cp;
+ char *start;
- /*
- * New nodes effectively take the place of the child, so place them
- * after the child
- */
- prevLN = Lst_Member(&pgn->children, cgn);
+ Lst_Init(members);
+
+ DEBUGF(SUFF, ("Expanding \"%s\"...", child->name));
+ buf = Var_Subst(NULL, child->name, parent, TRUE);
+ cp = Buf_GetAll(buf, NULL);
+ if (child->type & OP_ARCHV) {
+ /*
+ * Node was an archive(member) target, so we
+ * want to call on the Arch module to find the
+ * nodes for us, expanding variables in the
+ * parent's context.
+ */
+ Arch_ParseArchive(&cp, members, parent);
+ Buf_Destroy(buf, TRUE);
+ return;
+ }
/*
- * First do variable expansion -- this takes precedence over
- * wildcard expansion. If the result contains wildcards, they'll be
- * gotten to later since the resulting words are tacked on to the
- * end of the children list.
+ * Break the result into a vector of strings whose nodes we can find,
+ * then add those nodes to the members list. Unfortunately, we can't use
+ * brk_string b/c it doesn't understand about variable specifications
+ * with spaces in them... XXX
*/
- if (strchr(cgn->name, '$') != NULL) {
- Buffer *buf;
+ for (start = cp; *start == ' ' || *start == '\t'; start++)
+ ;
- DEBUGF(SUFF, ("Expanding \"%s\"...", cgn->name));
- buf = Var_Subst(NULL, cgn->name, pgn, TRUE);
- cp = Buf_GetAll(buf, NULL);
-
- Lst members = Lst_Initializer(members);
+ for (cp = start; *cp != '\0'; cp++) {
+ if (*cp == ' ' || *cp == '\t') {
+ /*
+ * White-space -- terminate element, find the node,
+ * add it, skip any further spaces.
+ */
+ *cp++ = '\0';
+ Lst_AtEnd(members, Targ_FindNode(start, TARG_CREATE));
- if (cgn->type & OP_ARCHV) {
+ while (*cp == ' ' || *cp == '\t') {
+ cp++;
+ }
/*
- * Node was an archive(member) target, so we
- * want to call on the Arch module to find the
- * nodes for us, expanding variables in the
- * parent's context.
+ * Adjust cp for increment at
+ * start of loop, but set start
+ * to first non-space.
*/
- Arch_ParseArchive(&cp, &members, pgn);
- } else {
+ start = cp--;
+
+ } else if (*cp == '$') {
/*
- * Break the result into a vector of strings
- * whose nodes we can find, then add those
- * nodes to the members list. Unfortunately,
- * we can't use brk_string b/c it doesn't
- * understand about variable specifications with
- * spaces in them...
+ * Start of a variable spec -- contact variable module
+ * to find the end so we can skip over it.
*/
- char *start;
-
- for (start = cp; *start == ' ' ||
- *start == '\t'; start++)
- continue;
- for (cp = start; *cp != '\0'; cp++) {
- if (*cp == ' ' || *cp == '\t') {
- /*
- * White-space -- terminate element,
- * find the node, add it, skip any
- * further spaces.
- */
- *cp++ = '\0';
- gn = Targ_FindNode(start, TARG_CREATE);
- Lst_AtEnd(&members, gn);
- while (*cp == ' ' || *cp == '\t') {
- cp++;
- }
- /*
- * Adjust cp for increment at
- * start of loop, but set start
- * to first non-space.
- */
- start = cp--;
-
- } else if (*cp == '$') {
- /*
- * Start of a variable spec --
- * contact variable module
- * to find the end so we can
- * skip over it.
- */
- char *junk;
- size_t len = 0;
- Boolean doFree;
-
- junk = Var_Parse(cp, pgn, TRUE,
- &len, &doFree);
- if (junk != var_Error) {
- cp += len - 1;
- }
- if (doFree) {
- free(junk);
- }
-
- } else if (*cp == '\\' && *cp != '\0') {
- /*
- * Escaped something -- skip over it
- */
- cp++;
- }
- }
+ char *junk;
+ size_t len = 0;
+ Boolean doFree;
- if (cp != start) {
- /*
- * Stuff left over -- add it to the
- * list too
- */
- gn = Targ_FindNode(start, TARG_CREATE);
- Lst_AtEnd(&members, gn);
+ junk = Var_Parse(cp, parent, TRUE, &len, &doFree);
+ if (junk != var_Error) {
+ cp += len - 1;
}
+ if (doFree) {
+ free(junk);
+ }
+
+ } else if (*cp == '\\' && *cp != '\0') {
+ /*
+ * Escaped something -- skip over it
+ */
+ cp++;
}
+ }
+ if (cp != start) {
/*
- * Free the result of Var_Subst
+ * Stuff left over -- add it to the
+ * list too
*/
- Buf_Destroy(buf, TRUE);
+ Lst_AtEnd(members, Targ_FindNode(start, TARG_CREATE));
+ }
+
+ Buf_Destroy(buf, TRUE);
+}
+
+/*-
+ * The child node contains wildcards. Expand them and return a list of
+ * expansions.
+ */
+static void
+SuffExpandWildcards(GNode *child, Lst *members)
+{
+ char *cp;
+ Lst exp; /* List of expansions */
+ LstNode *ln;
+ Lst *path; /* Search path along which to expand */
+
+ Lst_Init(members);
+
+ /*
+ * Find a path along which to expand the word.
+ *
+ * If the word has a known suffix, use that path.
+ * If it has no known suffix and we're allowed to use the null
+ * suffix, use its path.
+ * Else use the default system search path.
+ */
+ cp = child->name + strlen(child->name);
+ ln = Lst_Find(&sufflist, cp, SuffSuffIsSuffixP);
+
+ DEBUGF(SUFF, ("Wildcard expanding \"%s\"...", child->name));
+
+ if (ln != NULL) {
+ Suff *s = Lst_Datum(ln);
+ DEBUGF(SUFF, ("suffix is \"%s\"...", s->name));
+ path = &s->searchPath;
+ } else {
/*
- * Add all elements of the members list to
- * the parent node.
+ * Use default search path
*/
- while(!Lst_IsEmpty(&members)) {
- gn = Lst_DeQueue(&members);
+ path = &dirSearchPath;
+ }
- DEBUGF(SUFF, ("%s...", gn->name));
- if (Lst_Member(&pgn->children, gn) == NULL) {
- Lst_Append(&pgn->children, prevLN, gn);
- prevLN = Lst_Succ(prevLN);
- Lst_AtEnd(&gn->parents, pgn);
- pgn->unmade++;
- }
- }
+ /*
+ * Expand the word along the chosen path
+ */
+ Lst_Init(&exp);
+ Dir_Expand(child->name, path, &exp);
+ while (!Lst_IsEmpty(&exp)) {
/*
- * Now the source is expanded, remove it from the list
- * of children to keep it from being processed.
+ * Fetch next expansion off the list and find its GNode
*/
- ln = Lst_Member(&pgn->children, cgn);
- pgn->unmade--;
- Lst_Remove(&pgn->children, ln);
- DEBUGF(SUFF, ("\n"));
+ cp = Lst_DeQueue(&exp);
+
+ DEBUGF(SUFF, ("%s...", cp));
+ Lst_AtEnd(members, Targ_FindNode(cp, TARG_CREATE));
+ }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * SuffExpandChildren --
+ * Expand the names of any children of a given node that contain
+ * variable invocations or file wildcards into actual targets.
+ *
+ * Results:
+ * == 0 (continue)
+ *
+ * Side Effects:
+ * The expanded node is removed from the parent's list of children,
+ * and the parent's unmade counter is decremented, but other nodes
+ * may be added.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+SuffExpandChildren(GNode *parent, LstNode *current)
+{
+ GNode *cchild; /* current child */
+ GNode *gn;
+ LstNode *prev; /* node after which to append new source */
+ Lst members; /* expanded nodes */
+
+ if (current == NULL) {
+ /* start from begin of parent's children list */
+ current = Lst_First(&parent->children);
+ }
- } else if (Dir_HasWildcards(cgn->name)) {
- Lst exp; /* List of expansions */
- Lst *path; /* Search path along which to expand */
+ while (current != NULL) {
+ cchild = Lst_Datum(current);
/*
- * Find a path along which to expand the word.
+ * First do variable expansion -- this takes precedence over
+ * wildcard expansion. If the result contains wildcards, they'll
+ * be gotten to later since the resulting words are tacked
+ * instead of the current child onto the children list.
*
- * If the word has a known suffix, use that path.
- * If it has no known suffix and we're allowed to use the null
- * suffix, use its path.
- * Else use the default system search path.
+ * XXXHB what if cchild contains lib.a(t1.o t2.o t3.o) but
+ * no $?
*/
- cp = cgn->name + strlen(cgn->name);
- ln = Lst_Find(&sufflist, cp, SuffSuffIsSuffixP);
-
- DEBUGF(SUFF, ("Wildcard expanding \"%s\"...", cgn->name));
+ if (strchr(cchild->name, '$') != NULL) {
+ SuffExpandVariables(parent, cchild, &members);
- if (ln != NULL) {
- Suff *s = Lst_Datum(ln);
+ } else if (Dir_HasWildcards(cchild->name)) {
+ SuffExpandWildcards(cchild, &members);
- DEBUGF(SUFF, ("suffix is \"%s\"...", s->name));
- path = &s->searchPath;
} else {
- /*
- * Use default search path
- */
- path = &dirSearchPath;
+ /* nothing special just advance to next child */
+ current = LST_NEXT(current);
+ continue;
}
/*
- * Expand the word along the chosen path
+ * New nodes effectively take the place of the child,
+ * so place them after the child
*/
- Lst_Init(&exp);
- Dir_Expand(cgn->name, path, &exp);
-
- while (!Lst_IsEmpty(&exp)) {
- /*
- * Fetch next expansion off the list and find its GNode
- */
- cp = Lst_DeQueue(&exp);
+ prev = current;
- DEBUGF(SUFF, ("%s...", cp));
- gn = Targ_FindNode(cp, TARG_CREATE);
+ /*
+ * Add all new elements to the parent node if they aren't
+ * already children of it.
+ */
+ while(!Lst_IsEmpty(&members)) {
+ gn = Lst_DeQueue(&members);
- /*
- * If gn isn't already a child of the parent, make it
- * so and up the parent's count of unmade children.
- */
- if (Lst_Member(&pgn->children, gn) == NULL) {
- Lst_Append(&pgn->children, prevLN, gn);
- prevLN = Lst_Succ(prevLN);
- Lst_AtEnd(&gn->parents, pgn);
- pgn->unmade++;
+ DEBUGF(SUFF, ("%s...", gn->name));
+ if (Lst_Member(&parent->children, gn) == NULL) {
+ Lst_Append(&parent->children, prev, gn);
+ prev = Lst_Succ(prev);
+ Lst_AtEnd(&gn->parents, parent);
+ parent->unmade++;
}
}
/*
- * Now the source is expanded, remove it from the list of
- * children to keep it from being processed.
+ * Now the source is expanded, remove it from the list
+ * of children to keep it from being processed.
+ * Advance to the next child.
*/
- ln = Lst_Member(&pgn->children, cgn);
- pgn->unmade--;
- Lst_Remove(&pgn->children, ln);
+ prev = current;
+ current = LST_NEXT(current);
+
+ parent->unmade--;
+ Lst_Remove(&parent->children, prev);
DEBUGF(SUFF, ("\n"));
}
-
- return (0);
}
/*-
@@ -1588,7 +1599,7 @@ SuffApplyTransform(GNode *tGn, GNode *sGn, Suff *t, Suff *s)
*/
ln = Lst_Succ(ln);
if (ln != NULL) {
- Lst_ForEachFrom(&tGn->children, ln, SuffExpandChildren, tGn);
+ SuffExpandChildren(tGn, ln);
}
/*
@@ -1915,7 +1926,7 @@ SuffFindNormalDeps(GNode *gn, Lst *slst)
* Now we've got the important local variables set, expand any sources
* that still contain variables or wildcards in their names.
*/
- Lst_ForEach(&gn->children, SuffExpandChildren, (void *)gn);
+ SuffExpandChildren(gn, NULL);
if (targ == NULL) {
DEBUGF(SUFF, ("\tNo valid suffix on %s\n", gn->name));
OpenPOWER on IntegriCloud