📄 suff.c
字号:
srcLn = NILLNODE; singleLn = NILLNODE; /* * Loop looking first for a suffix that matches the start of the * string and then for one that exactly matches the rest of it. If * we can find two that meet these criteria, we've successfully * parsed the string. */ for (;;) { if (srcLn == NILLNODE) { srcLn = Lst_Find(sufflist, (ClientData)str, SuffSuffIsPrefix); } else { srcLn = Lst_FindFrom (sufflist, Lst_Succ(srcLn), (ClientData)str, SuffSuffIsPrefix); } if (srcLn == NILLNODE) { /* * Ran out of source suffixes -- no such rule */ if (singleLn != NILLNODE) { /* * Not so fast Mr. Smith! There was a suffix that encompassed * the entire string, so we assume it was a transformation * to the null suffix (thank you POSIX). We still prefer to * find a double rule over a singleton, hence we leave this * check until the end. * * XXX: Use emptySuff over suffNull? */ *srcPtr = single; *targPtr = SuffCopy(suffNull); return(TRUE); } return (FALSE); } src = (Suff *) Lst_Datum (srcLn); str2 = str + src->nameLen; if (*str2 == '\0') { single = src; singleLn = srcLn; } else { targLn = Lst_Find(sufflist, (ClientData)str2, SuffSuffHasNameP); if (targLn != NILLNODE) { *srcPtr = src; *targPtr = (Suff *)Lst_Datum(targLn); return (TRUE); } } }}/*- *----------------------------------------------------------------------- * Suff_IsTransform -- * Return TRUE if the given string is a transformation rule * * * Results: * TRUE if the string is a concatenation of two known suffixes. * FALSE otherwise * * Side Effects: * None *----------------------------------------------------------------------- */BooleanSuff_IsTransform (str) char *str; /* string to check */{ Suff *src, *targ; return (SuffParseTransform(str, &src, &targ));}/*- *----------------------------------------------------------------------- * Suff_AddTransform -- * Add the transformation rule described by the line to the * list of rules and place the transformation itself in the graph * * Results: * The node created for the transformation in the transforms list * * Side Effects: * The node is placed on the end of the transforms Lst and links are * made between the two suffixes mentioned in the target name *----------------------------------------------------------------------- */GNode *Suff_AddTransform (line) char *line; /* name of transformation to add */{ GNode *gn; /* GNode of transformation rule */ Suff *s, /* source suffix */ *t; /* target suffix */ LstNode ln; /* Node for existing transformation */ ln = Lst_Find (transforms, (ClientData)line, SuffGNHasNameP); if (ln == NILLNODE) { /* * Make a new graph node for the transformation. It will be filled in * by the Parse module. */ gn = Targ_NewGN (line); (void)Lst_AtEnd (transforms, (ClientData)gn); } else { /* * New specification for transformation rule. Just nuke the old list * of commands so they can be filled in again... We don't actually * free the commands themselves, because a given command can be * attached to several different transformations. */ gn = (GNode *) Lst_Datum (ln); Lst_Destroy (gn->commands, NOFREE); Lst_Destroy (gn->children, NOFREE); gn->commands = Lst_Init (FALSE); gn->children = Lst_Init (FALSE); } gn->type = OP_TRANSFORM; (void)SuffParseTransform(line, &s, &t); /* * link the two together in the proper relationship and order */ if (DEBUG(SUFF)) { printf("defining transformation from `%s' to `%s'\n", s->name, t->name); } SuffInsert (t->children, s); SuffInsert (s->parents, t); return (gn);}/*- *----------------------------------------------------------------------- * Suff_EndTransform -- * Handle the finish of a transformation definition, removing the * transformation from the graph if it has neither commands nor * sources. This is a callback procedure for the Parse module via * Lst_ForEach * * Results: * === 0 * * Side Effects: * If the node has no commands or children, the children and parents * lists of the affected suffices are altered. * *----------------------------------------------------------------------- */intSuff_EndTransform(gn) GNode *gn; /* Node for transformation */{ if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) && Lst_IsEmpty(gn->children)) { Suff *s, *t; LstNode ln; (void)SuffParseTransform(gn->name, &s, &t); if (DEBUG(SUFF)) { printf("deleting transformation from %s to %s\n", s->name, t->name); } /* * Remove the source from the target's children list. We check for a * nil return to handle a beanhead saying something like * .c.o .c.o: * * We'll be called twice when the next target is seen, but .c and .o * are only linked once... */ ln = Lst_Member(t->children, (ClientData)s); if (ln != NILLNODE) { (void)Lst_Remove(t->children, ln); } /* * Remove the target from the source's parents list */ ln = Lst_Member(s->parents, (ClientData)t); if (ln != NILLNODE) { (void)Lst_Remove(s->parents, ln); } } else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { printf("transformation %s complete\n", gn->name); } return(0);}/*- *----------------------------------------------------------------------- * SuffRebuildGraph -- * Called from Suff_AddSuffix via Lst_ForEach to search through the * list of existing transformation rules and rebuild the transformation * graph when it has been destroyed by Suff_ClearSuffixes. If the * given rule is a transformation involving this suffix and another, * existing suffix, the proper relationship is established between * the two. * * Results: * Always 0. * * Side Effects: * The appropriate links will be made between this suffix and * others if transformation rules exist for it. * *----------------------------------------------------------------------- */static intSuffRebuildGraph(transform, s) GNode *transform; /* Transformation to test */ Suff *s; /* Suffix to rebuild */{ register char *cp; register LstNode ln; register Suff *s2; /* * First see if it is a transformation from this suffix. */ cp = SuffStrIsPrefix(s->name, transform->name); if (cp != (char *)NULL) { ln = Lst_Find(sufflist, (ClientData)cp, SuffSuffHasNameP); if (ln != NILLNODE) { /* * Found target. Link in and return, since it can't be anything * else. */ s2 = (Suff *)Lst_Datum(ln); SuffInsert(s2->children, s); SuffInsert(s->parents, s2); return(0); } } /* * Not from, maybe to? */ cp = SuffSuffIsSuffix(s, transform->name + strlen(transform->name)); if (cp != (char *)NULL) { /* * Null-terminate the source suffix in order to find it. */ cp[1] = '\0'; ln = Lst_Find(sufflist, (ClientData)transform->name, SuffSuffHasNameP); /* * Replace the start of the target suffix */ cp[1] = s->name[0]; if (ln != NILLNODE) { /* * Found it -- establish the proper relationship */ s2 = (Suff *)Lst_Datum(ln); SuffInsert(s->children, s2); SuffInsert(s2->parents, s); } } return(0);}/*- *----------------------------------------------------------------------- * Suff_AddSuffix -- * Add the suffix in string to the end of the list of known suffixes. * Should we restructure the suffix graph? Make doesn't... * * Results: * None * * Side Effects: * A GNode is created for the suffix and a Suff structure is created and * added to the suffixes list unless the suffix was already known. *----------------------------------------------------------------------- */voidSuff_AddSuffix (str) char *str; /* the name of the suffix to add */{ Suff *s; /* new suffix descriptor */ LstNode ln; ln = Lst_Find (sufflist, (ClientData)str, SuffSuffHasNameP); if (ln == NILLNODE) { s = (Suff *) emalloc (sizeof (Suff)); s->name = strdup (str); s->nameLen = strlen (s->name); s->searchPath = Lst_Init (FALSE); s->children = Lst_Init (FALSE); s->parents = Lst_Init (FALSE); s->sNum = sNum++; s->flags = 0; (void)Lst_AtEnd (sufflist, (ClientData)s); /* * Look for any existing transformations from or to this suffix. * XXX: Only do this after a Suff_ClearSuffixes? */ Lst_ForEach (transforms, SuffRebuildGraph, (ClientData)s); } }/*- *----------------------------------------------------------------------- * Suff_GetPath -- * Return the search path for the given suffix, if it's defined. * * Results: * The searchPath for the desired suffix or NILLST if the suffix isn't * defined. * * Side Effects: * None *----------------------------------------------------------------------- */LstSuff_GetPath (sname) char *sname;{ LstNode ln; Suff *s; ln = Lst_Find (sufflist, (ClientData)sname, SuffSuffHasNameP); if (ln == NILLNODE) { return (NILLST); } else { s = (Suff *) Lst_Datum (ln); return (s->searchPath); }}/*- *----------------------------------------------------------------------- * Suff_DoPaths -- * Extend the search paths for all suffixes to include the default * search path. * * Results: * None. * * Side Effects: * The searchPath field of all the suffixes is extended by the * directories in dirSearchPath. If paths were specified for the * ".h" suffix, the directories are stuffed into a global variable * called ".INCLUDES" with each directory preceeded by a -I. The same * is done for the ".a" suffix, except the variable is called * ".LIBS" and the flag is -L. *----------------------------------------------------------------------- */voidSuff_DoPaths(){ register Suff *s; register LstNode ln; Lst inIncludes; /* Cumulative .INCLUDES path */ Lst inLibs; /* Cumulative .LIBS path */ if (Lst_Open (sufflist) == FAILURE) { return; } inIncludes = Lst_Init(FALSE); inLibs = Lst_Init(FALSE); while ((ln = Lst_Next (sufflist)) != NILLNODE) { s = (Suff *) Lst_Datum (ln); if (!Lst_IsEmpty (s->searchPath)) {#ifdef INCLUDES if (s->flags & SUFF_INCLUDE) { Dir_Concat(inIncludes, s->searchPath); }#endif /* INCLUDES */#ifdef LIBRARIES if (s->flags & SUFF_LIBRARY) { Dir_Concat(inLibs, s->searchPath); }#endif /* LIBRARIES */ Dir_Concat(s->searchPath, dirSearchPath); } else { Lst_Destroy (s->searchPath, Dir_Destroy); s->searchPath = Lst_Duplicate(dirSearchPath, Dir_CopyDir); } } Var_Set(".INCLUDES", Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL); Var_Set(".LIBS", Dir_MakeFlags("-L", inLibs), VAR_GLOBAL); Lst_Destroy(inIncludes, Dir_Destroy); Lst_Destroy(inLibs, Dir_Destroy); Lst_Close (sufflist);}/*- *----------------------------------------------------------------------- * Suff_AddInclude -- * Add the given suffix as a type of file which gets included. * Called from the parse module when a .INCLUDES line is parsed. * The suffix must have already been defined. * * Results: * None. * * Side Effects: * The SUFF_INCLUDE bit is set in the suffix's flags field * *----------------------------------------------------------------------- */voidSuff_AddInclude (sname) char *sname; /* Name of suffix to mark */{ LstNode ln; Suff *s; ln = Lst_Find (sufflist, (ClientData)sname, SuffSuffHasNameP); if (ln != NILLNODE) { s = (Suff *) Lst_Datum (ln); s->flags |= SUFF_INCLUDE; }}/*- *----------------------------------------------------------------------- * Suff_AddLib -- * Add the given suffix as a type of file which is a library. * Called from the parse module when parsing a .LIBS line. The * suffix must have been defined via .SUFFIXES before this is * called. * * Results: * None. * * Side Effects:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -