📄 suff.c
字号:
/* * Use default search path */ path = dirSearchPath; } /* * Expand the word along the chosen path */ exp = Lst_Init(FALSE); Dir_Expand(cgn->name, path, exp); while (!Lst_IsEmpty(exp)) { /* * Fetch next expansion off the list and find its GNode */ cp = (char *)Lst_DeQueue(exp); if (DEBUG(SUFF)) { printf("%s...", cp); } gn = Targ_FindNode(cp, TARG_CREATE); /* * 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, (ClientData)gn) == NILLNODE) { (void)Lst_Append(pgn->children, prevLN, (ClientData)gn); prevLN = Lst_Succ(prevLN); (void)Lst_AtEnd(gn->parents, (ClientData)pgn); pgn->unmade++; } } /* * Nuke what's left of the list */ Lst_Destroy(exp, NOFREE); /* * Now the source is expanded, remove it from the list of children to * keep it from being processed. */ ln = Lst_Member(pgn->children, (ClientData)cgn); pgn->unmade--; Lst_Remove(pgn->children, ln); if (DEBUG(SUFF)) { printf("\n"); } } return(0);}/*- *----------------------------------------------------------------------- * SuffApplyTransform -- * Apply a transformation rule, given the source and target nodes * and suffixes. * * Results: * TRUE if successful, FALSE if not. * * Side Effects: * The source and target are linked and the commands from the * transformation are added to the target node's commands list. * All attributes but OP_DEPMASK and OP_TRANSFORM are applied * to the target. The target also inherits all the sources for * the transformation rule. * *----------------------------------------------------------------------- */static BooleanSuffApplyTransform(tGn, sGn, t, s) GNode *tGn; /* Target node */ GNode *sGn; /* Source node */ Suff *t; /* Target suffix */ Suff *s; /* Source suffix */{ LstNode ln; /* General node */ char *tname; /* Name of transformation rule */ GNode *gn; /* Node for same */ if (Lst_Member(tGn->children, (ClientData)sGn) == NILLNODE) { /* * Not already linked, so form the proper links between the * target and source. */ (void)Lst_AtEnd(tGn->children, (ClientData)sGn); (void)Lst_AtEnd(sGn->parents, (ClientData)tGn); tGn->unmade += 1; } if ((sGn->type & OP_OPMASK) == OP_DOUBLEDEP) { /* * When a :: node is used as the implied source of a node, we have * to link all its cohorts in as sources as well. Only the initial * sGn gets the target in its iParents list, however, as that * will be sufficient to get the .IMPSRC variable set for tGn */ for (ln=Lst_First(sGn->cohorts); ln != NILLNODE; ln=Lst_Succ(ln)) { gn = (GNode *)Lst_Datum(ln); if (Lst_Member(tGn->children, (ClientData)gn) == NILLNODE) { /* * Not already linked, so form the proper links between the * target and source. */ (void)Lst_AtEnd(tGn->children, (ClientData)gn); (void)Lst_AtEnd(gn->parents, (ClientData)tGn); tGn->unmade += 1; } } } /* * Locate the transformation rule itself */ tname = str_concat(s->name, t->name, 0); ln = Lst_Find(transforms, (ClientData)tname, SuffGNHasNameP); free(tname); if (ln == NILLNODE) { /* * Not really such a transformation rule (can happen when we're * called to link an OP_MEMBER and OP_ARCHV node), so return * FALSE. */ return(FALSE); } gn = (GNode *)Lst_Datum(ln); if (DEBUG(SUFF)) { printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); } /* * Record last child for expansion purposes */ ln = Lst_Last(tGn->children); /* * Pass the buck to Make_HandleUse to apply the rule */ (void)Make_HandleUse(gn, tGn); /* * Deal with wildcards and variables in any acquired sources */ ln = Lst_Succ(ln); if (ln != NILLNODE) { Lst_ForEachFrom(tGn->children, ln, SuffExpandChildren, (ClientData)tGn); } /* * Keep track of another parent to which this beast is transformed so * the .IMPSRC variable can be set correctly for the parent. */ (void)Lst_AtEnd(sGn->iParents, (ClientData)tGn); return(TRUE);}/*- *----------------------------------------------------------------------- * SuffFindArchiveDeps -- * Locate dependencies for an OP_ARCHV node. * * Results: * None * * Side Effects: * Same as Suff_FindDeps * *----------------------------------------------------------------------- */static voidSuffFindArchiveDeps(gn) GNode *gn; /* Node for which to locate dependencies */{ char *eoarch; /* End of archive portion */ char *eoname; /* End of member portion */ GNode *mem; /* Node for member */ static char *copy[] = { /* Variables to be copied from the member node */ TARGET, /* Must be first */ PREFIX, /* Must be second */ }; char *vals[sizeof(copy)/sizeof(copy[0])]; int i; /* Index into copy and vals */ Suff *ms; /* Suffix descriptor for member */ char *name; /* Start of member's name */ /* * The node is an archive(member) pair. so we must find a * suffix for both of them. */ eoarch = strchr (gn->name, '('); eoname = strchr (eoarch, ')'); *eoname = '\0'; /* Nuke parentheses during suffix search */ *eoarch = '\0'; /* So a suffix can be found */ name = eoarch + 1; /* * To simplify things, call Suff_FindDeps recursively on the member now, * so we can simply compare the member's .PREFIX and .TARGET variables * to locate its suffix. This allows us to figure out the suffix to * use for the archive without having to do a quadratic search over the * suffix list, backtracking for each one... */ mem = Targ_FindNode(name, TARG_CREATE); Suff_FindDeps(mem); /* * Create the link between the two nodes right off */ if (Lst_Member(gn->children, (ClientData)mem) == NILLNODE) { (void)Lst_AtEnd(gn->children, (ClientData)mem); (void)Lst_AtEnd(mem->parents, (ClientData)gn); gn->unmade += 1; } /* * Copy in the variables from the member node to this one. */ for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) { vals[i] = Var_Value(copy[i], mem); Var_Set(copy[i], vals[i], gn); } ms = mem->suffix; if (ms == NULL) { /* * Didn't know what it was -- use .NULL suffix if not in make mode */ if (DEBUG(SUFF)) { printf("using null suffix\n"); } ms = suffNull; } /* * Set the other two local variables required for this target. */ Var_Set (MEMBER, name, gn); Var_Set (ARCHIVE, gn->name, gn); if (ms != NULL) { /* * Member has a known suffix, so look for a transformation rule from * it to a possible suffix of the archive. Rather than searching * through the entire list, we just look at suffixes to which the * member's suffix may be transformed... */ LstNode ln; /* * Use first matching suffix... */ ln = Lst_Find(ms->parents, eoarch, SuffSuffIsSuffixP); if (ln != NILLNODE) { /* * Got one -- apply it */ if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && DEBUG(SUFF)) { printf("\tNo transformation from %s -> %s\n", ms->name, ((Suff *)Lst_Datum(ln))->name); } } } /* * Replace the opening and closing parens now we've no need of the separate * pieces. */ *eoarch = '('; *eoname = ')'; /* * Pretend gn appeared to the left of a dependency operator so * the user needn't provide a transformation from the member to the * archive. */ if (OP_NOP(gn->type)) { gn->type |= OP_DEPENDS; } /* * Flag the member as such so we remember to look in the archive for * its modification time. */ mem->type |= OP_MEMBER;}/*- *----------------------------------------------------------------------- * SuffFindNormalDeps -- * Locate implicit dependencies for regular targets. * * Results: * None. * * Side Effects: * Same as Suff_FindDeps... * *----------------------------------------------------------------------- */static voidSuffFindNormalDeps(gn) GNode *gn; /* Node for which to find sources */{ char *eoname; /* End of name */ char *sopref; /* Start of prefix */ LstNode ln; /* Next suffix node to check */ Lst srcs; /* List of sources at which to look */ Lst targs; /* List of targets to which things can be * transformed. They all have the same file, * but different suff and pref fields */ Src *bottom; /* Start of found transformation path */ Src *src; /* General Src pointer */ char *pref; /* Prefix to use */ Src *targ; /* General Src target pointer */ eoname = gn->name + strlen(gn->name); sopref = gn->name; /* * Begin at the beginning... */ ln = Lst_First(sufflist); srcs = Lst_Init(FALSE); targs = Lst_Init(FALSE); /* * We're caught in a catch-22 here. On the one hand, we want to use any * transformation implied by the target's sources, but we can't examine * the sources until we've expanded any variables/wildcards they may hold, * and we can't do that until we've set up the target's local variables * and we can't do that until we know what the proper suffix for the * target is (in case there are two suffixes one of which is a suffix of * the other) and we can't know that until we've found its implied * source, which we may not want to use if there's an existing source * that implies a different transformation. * * In an attempt to get around this, which may not work all the time, * but should work most of the time, we look for implied sources first, * checking transformations to all possible suffixes of the target, * use what we find to set the target's local variables, expand the * children, then look for any overriding transformations they imply. * Should we find one, we discard the one we found before. */ while(ln != NILLNODE) { /* * Look for next possible suffix... */ ln = Lst_FindFrom(sufflist, ln, eoname, SuffSuffIsSuffixP); if (ln != NILLNODE) { int prefLen; /* Length of the prefix */ Src *targ; /* * Allocate a Src structure to which things can be transformed */ targ = (Src *)emalloc(sizeof(Src)); targ->file = strdup(gn->name); targ->suff = (Suff *)Lst_Datum(ln); targ->node = gn; targ->parent = (Src *)NULL; targ->children = 0; /* * Allocate room for the prefix, whose end is found by subtracting * the length of the suffix from the end of the name. */ prefLen = (eoname - targ->suff->nameLen) - sopref; targ->pref = emalloc(prefLen + 1); memcpy(targ->pref, sopref, prefLen); targ->pref[prefLen] = '\0'; /* * Add nodes from which the target can be made */ SuffAddLevel(srcs, targ); /* * Record the target so we can nuke it */ (void)Lst_AtEnd(targs, (ClientData)targ); /* * Search from this suffix's successor... */ ln = Lst_Succ(ln); } } /* * Handle target of unknown suffix... */ if (Lst_IsEmpty(targs) && suffNull != NULL) { if (DEBUG(SUFF)) { printf("\tNo known suffix on %s. Using .NULL suffix\n", gn->name); } targ = (Src *)emalloc(sizeof(Src)); targ->file = strdup(gn->name); targ->suff = suffNull; targ->node = gn; targ->parent = (Src *)NULL; targ->children = 0; targ->pref = strdup(sopref); SuffAddLevel(srcs, targ); (void)Lst_AtEnd(targs, (ClientData)targ); } /* * Using the list of possible sources built up from the target suffix(es), * try and find an existing file/target that matches. */ bottom = SuffFindThem(srcs); if (bottom == (Src *)NULL) { /* * No known transformations -- use the first suffix found for setting * the local variables. */ if (!Lst_IsEmpty(targs)) { targ = (Src *)Lst_Datum(Lst_First(targs)); } else { targ = (Src *)NULL; } } else { /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -