📄 suff.c
字号:
* Work up the transformation path to find the suffix of the * target to which the transformation was made. */ for (targ = bottom; targ->parent != NULL; targ = targ->parent) continue; } /* * The .TARGET variable we always set to be the name at this point, * since it's only set to the path if the thing is only a source and * if it's only a source, it doesn't matter what we put here as far * as expanding sources is concerned, since it has none... */ Var_Set(TARGET, gn->name, gn); pref = (targ != NULL) ? targ->pref : gn->name; Var_Set(PREFIX, pref, gn); /* * 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, (ClientData)gn); if (targ == NULL) { if (DEBUG(SUFF)) { printf("\tNo valid suffix on %s\n", gn->name); }sfnd_abort: /* * Deal with finding the thing on the default search path if the * node is only a source (not on the lhs of a dependency operator * or [XXX] it has neither children or commands). */ if (OP_NOP(gn->type) || (Lst_IsEmpty(gn->children) && Lst_IsEmpty(gn->commands))) { gn->path = Dir_FindFile(gn->name, (targ == NULL ? dirSearchPath : targ->suff->searchPath)); if (gn->path != NULL) { Var_Set(TARGET, gn->path, gn); if (targ != NULL) { /* * Suffix known for the thing -- trim the suffix off * the path to form the proper .PREFIX variable. */ int len = strlen(gn->path); char savec; gn->suffix = targ->suff; savec = gn->path[len-targ->suff->nameLen]; gn->path[len-targ->suff->nameLen] = '\0'; Var_Set(PREFIX, gn->path, gn); gn->path[len-targ->suff->nameLen] = savec; } else { /* * The .PREFIX gets the full path if the target has * no known suffix. */ gn->suffix = NULL; Var_Set(PREFIX, gn->path, gn); } } } else { /* * Not appropriate to search for the thing -- set the * path to be the name so Dir_MTime won't go grovelling for * it. */ gn->suffix = (targ == NULL) ? NULL : targ->suff; gn->path = gn->name; } goto sfnd_return; } /* * If the suffix indicates that the target is a library, mark that in * the node's type field. */ if (targ->suff->flags & SUFF_LIBRARY) { gn->type |= OP_LIB; } /* * Check for overriding transformation rule implied by sources */ if (!Lst_IsEmpty(gn->children)) { src = SuffFindCmds(targ); if (src != (Src *)NULL) { /* * Free up all the Src structures in the transformation path * up to, but not including, the parent node. */ while (bottom && bottom->parent != NULL) { Src *p = bottom->parent; SuffFreeSrc(bottom); bottom = p; } bottom = src; } } if (bottom == NULL) { /* * No idea from where it can come -- return now. */ goto sfnd_abort; } /* * We now have a list of Src structures headed by 'bottom' and linked via * their 'parent' pointers. What we do next is create links between * source and target nodes (which may or may not have been created) * and set the necessary local variables in each target. The * commands for each target are set from the commands of the * transformation rule used to get from the src suffix to the targ * suffix. Note that this causes the commands list of the original * node, gn, to be replaced by the commands of the final * transformation rule. Also, the unmade field of gn is incremented. * Etc. */ if (bottom->node == NILGNODE) { bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); } for (src = bottom; src->parent != (Src *)NULL; src = src->parent) { targ = src->parent; src->node->suffix = src->suff; if (targ->node == NILGNODE) { targ->node = Targ_FindNode(targ->file, TARG_CREATE); } SuffApplyTransform(targ->node, src->node, targ->suff, src->suff); if (targ->node != gn) { /* * Finish off the dependency-search process for any nodes * between bottom and gn (no point in questing around the * filesystem for their implicit source when it's already * known). Note that the node can't have any sources that * need expanding, since SuffFindThem will stop on an existing * node, so all we need to do is set the standard and System V * variables. */ targ->node->type |= OP_DEPS_FOUND; Var_Set(PREFIX, targ->pref, targ->node); Var_Set(TARGET, targ->node->name, targ->node); } } gn->suffix = src->suff; /* * So Dir_MTime doesn't go questing for it... */ gn->path = gn->name; /* * Nuke the transformation path and the Src structures left over in the * two lists. */ SuffFreeSrc(bottom);sfnd_return: Lst_Destroy(srcs, SuffFreeSrc); Lst_Destroy(targs, SuffFreeSrc);} /*- *----------------------------------------------------------------------- * Suff_FindDeps -- * Find implicit sources for the target described by the graph node * gn * * Results: * Nothing. * * Side Effects: * Nodes are added to the graph below the passed-in node. The nodes * are marked to have their IMPSRC variable filled in. The * PREFIX variable is set for the given node and all its * implied children. * * Notes: * The path found by this target is the shortest path in the * transformation graph, which may pass through non-existent targets, * to an existing target. The search continues on all paths from the * root suffix until a file is found. I.e. if there's a path * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but * the .c and .l files don't, the search will branch out in * all directions from .o and again from all the nodes on the * next level until the .l,v node is encountered. * *----------------------------------------------------------------------- */voidSuff_FindDeps (gn) GNode *gn; /* node we're dealing with */{ if (gn->type & OP_DEPS_FOUND) { /* * If dependencies already found, no need to do it again... */ return; } else { gn->type |= OP_DEPS_FOUND; } if (DEBUG(SUFF)) { printf ("Suff_FindDeps (%s)\n", gn->name); } if (gn->type & OP_ARCHV) { SuffFindArchiveDeps(gn); } else if (gn->type & OP_LIB) { /* * If the node is a library, it is the arch module's job to find it * and set the TARGET variable accordingly. We merely provide the * search path, assuming all libraries end in ".a" (if the suffix * hasn't been defined, there's nothing we can do for it, so we just * set the TARGET variable to the node's name in order to give it a * value). */ LstNode ln; Suff *s; ln = Lst_Find (sufflist, (ClientData)LIBSUFF, SuffSuffHasNameP); if (ln != NILLNODE) { gn->suffix = s = (Suff *) Lst_Datum (ln); Arch_FindLib (gn, s->searchPath); } else { gn->suffix = NULL; Var_Set (TARGET, gn->name, gn); } /* * Because a library (-lfoo) target doesn't follow the standard * filesystem conventions, we don't set the regular variables for * the thing. .PREFIX is simply made empty... */ Var_Set(PREFIX, "", gn); } else { SuffFindNormalDeps(gn); }}/*- *----------------------------------------------------------------------- * Suff_SetNull -- * Define which suffix is the null suffix. * * Results: * None. * * Side Effects: * 'suffNull' is altered. * * Notes: * Need to handle the changing of the null suffix gracefully so the * old transformation rules don't just go away. * *----------------------------------------------------------------------- */voidSuff_SetNull(name) char *name; /* Name of null suffix */{ Suff *s; LstNode ln; ln = Lst_Find(sufflist, (ClientData)name, SuffSuffHasNameP); if (ln != NILLNODE) { s = (Suff *)Lst_Datum(ln); if (suffNull != (Suff *)NULL) { suffNull->flags &= ~SUFF_NULL; } s->flags |= SUFF_NULL; /* * XXX: Here's where the transformation mangling would take place */ suffNull = s; } else { Parse_Error (PARSE_WARNING, "Desired null suffix %s not defined.", name); }}/*- *----------------------------------------------------------------------- * Suff_Init -- * Initialize suffixes module * * Results: * None * * Side Effects: * Many *----------------------------------------------------------------------- */voidSuff_Init (){ sufflist = Lst_Init (FALSE); transforms = Lst_Init (FALSE); sNum = 0; /* * Create null suffix for single-suffix rules (POSIX). The thing doesn't * actually go on the suffix list or everyone will think that's its * suffix. */ emptySuff = suffNull = (Suff *) emalloc (sizeof (Suff)); suffNull->name = strdup (""); suffNull->nameLen = 0; suffNull->searchPath = Lst_Init (FALSE); Dir_Concat(suffNull->searchPath, dirSearchPath); suffNull->children = Lst_Init (FALSE); suffNull->parents = Lst_Init (FALSE); suffNull->sNum = sNum++; suffNull->flags = SUFF_NULL;}/*- *----------------------------------------------------------------------- * SuffCopy -- * Create a copy of the source suffix. * Currently does not copy children or parents * * Results: * a new suffix is returned * * Side Effects: * none *----------------------------------------------------------------------- */static Suff *SuffCopy(s) Suff *s;{ Suff *n = (Suff *) emalloc (sizeof (Suff)); n->name = strdup (s->name); n->nameLen = s->nameLen; n->searchPath = Lst_Init (FALSE); Dir_Concat(suffNull->searchPath, s->searchPath); n->children = Lst_Init (FALSE); n->parents = Lst_Init (FALSE); n->sNum = s->sNum; n->flags = s->flags; return n;}/********************* DEBUGGING FUNCTIONS **********************/static int SuffPrintName(s) Suff *s; {printf ("%s ", s->name); return (0);}static intSuffPrintSuff (s) Suff *s;{ int flags; int flag; printf ("# `%s'", s->name); flags = s->flags; if (flags) { fputs (" (", stdout); while (flags) { flag = 1 << (ffs(flags) - 1); flags &= ~flag; switch (flag) { case SUFF_NULL: printf ("NULL"); break; case SUFF_INCLUDE: printf ("INCLUDE"); break; case SUFF_LIBRARY: printf ("LIBRARY"); break; } fputc(flags ? '|' : ')', stdout); } } fputc ('\n', stdout); printf ("#\tTo: "); Lst_ForEach (s->parents, SuffPrintName, (ClientData)0); fputc ('\n', stdout); printf ("#\tFrom: "); Lst_ForEach (s->children, SuffPrintName, (ClientData)0); fputc ('\n', stdout); printf ("#\tSearch Path: "); Dir_PrintPath (s->searchPath); fputc ('\n', stdout); return (0);}static intSuffPrintTrans (t) GNode *t;{ extern int Targ_PrintCmd(); printf ("%-16s: ", t->name); Targ_PrintType (t->type); fputc ('\n', stdout); Lst_ForEach (t->commands, Targ_PrintCmd, (ClientData)0); fputc ('\n', stdout); return(0);}voidSuff_PrintAll(){ printf ("#*** Suffixes:\n"); Lst_ForEach (sufflist, SuffPrintSuff, (ClientData)0); printf ("#*** Transformations:\n"); Lst_ForEach (transforms, SuffPrintTrans, (ClientData)0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -