📄 suff.c
字号:
* The SUFF_LIBRARY bit is set in the suffix's flags field * *----------------------------------------------------------------------- */voidSuff_AddLib (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_LIBRARY; }} /********** Implicit Source Search Functions *********//*- *----------------------------------------------------------------------- * SuffAddSrc -- * Add a suffix as a Src structure to the given list with its parent * being the given Src structure. If the suffix is the null suffix, * the prefix is used unaltered as the file name in the Src structure. * * Results: * always returns 0 * * Side Effects: * A Src structure is created and tacked onto the end of the list *----------------------------------------------------------------------- */static intSuffAddSrc (s, ls) Suff *s; /* suffix for which to create a Src structure */ LstSrc *ls; /* list and parent for the new Src */{ Src *s2; /* new Src structure */ Src *targ; /* Target structure */ targ = ls->s; if ((s->flags & SUFF_NULL) && (*s->name != '\0')) { /* * If the suffix has been marked as the NULL suffix, also create a Src * structure for a file with no suffix attached. Two birds, and all * that... */ s2 = (Src *) emalloc (sizeof (Src)); s2->file = strdup(targ->pref); s2->pref = targ->pref; s2->parent = targ; s2->node = NILGNODE; s2->suff = s; s2->children = 0; targ->children += 1; (void)Lst_AtEnd (ls->l, (ClientData)s2); } s2 = (Src *) emalloc (sizeof (Src)); s2->file = str_concat (targ->pref, s->name, 0); s2->pref = targ->pref; s2->parent = targ; s2->node = NILGNODE; s2->suff = s; s2->children = 0; targ->children += 1; (void)Lst_AtEnd (ls->l, (ClientData)s2); return(0);}/*- *----------------------------------------------------------------------- * SuffAddLevel -- * Add all the children of targ as Src structures to the given list * * Results: * None * * Side Effects: * Lots of structures are created and added to the list *----------------------------------------------------------------------- */static voidSuffAddLevel (l, targ) Lst l; /* list to which to add the new level */ Src *targ; /* Src structure to use as the parent */{ LstSrc ls; ls.s = targ; ls.l = l; Lst_ForEach (targ->suff->children, SuffAddSrc, (ClientData)&ls);}/*- *---------------------------------------------------------------------- * SuffFreeSrc -- * Free all memory associated with a Src structure * * Results: * None * * Side Effects: * The memory is free'd. *---------------------------------------------------------------------- */static voidSuffFreeSrc (s) Src *s;{ free ((Address)s->file); if (!s->parent) { free((Address)s->pref); } else if (--s->parent->children == 0 && s->parent->parent) { /* * Parent has no more children, now we're gone, and it's not * at the top of the tree, so blow it away too. */ SuffFreeSrc(s->parent); } free ((Address)s);}/*- *----------------------------------------------------------------------- * SuffFindThem -- * Find the first existing file/target in the list srcs * * Results: * The lowest structure in the chain of transformations * * Side Effects: * None *----------------------------------------------------------------------- */static Src *SuffFindThem (srcs) Lst srcs; /* list of Src structures to search through */{ Src *s; /* current Src */ Src *rs; /* returned Src */ rs = (Src *) NULL; while (!Lst_IsEmpty (srcs)) { s = (Src *) Lst_DeQueue (srcs); if (DEBUG(SUFF)) { printf ("\ttrying %s...", s->file); } /* * A file is considered to exist if either a node exists in the * graph for it or the file actually exists. */ if ((Targ_FindNode(s->file, TARG_NOCREATE) != NILGNODE) || (Dir_FindFile (s->file, s->suff->searchPath) != (char *) NULL)) { if (DEBUG(SUFF)) { printf ("got it\n"); } rs = s; break; } else { if (DEBUG(SUFF)) { printf ("not there\n"); } SuffAddLevel (srcs, s); } } return (rs);}/*- *----------------------------------------------------------------------- * SuffFindCmds -- * See if any of the children of the target in the Src structure is * one from which the target can be transformed. If there is one, * a Src structure is put together for it and returned. * * Results: * The Src structure of the "winning" child, or NIL if no such beast. * * Side Effects: * A Src structure may be allocated. * *----------------------------------------------------------------------- */static Src *SuffFindCmds (targ) Src *targ; /* Src structure to play with */{ LstNode ln; /* General-purpose list node */ register GNode *t, /* Target GNode */ *s; /* Source GNode */ int prefLen;/* The length of the defined prefix */ Suff *suff; /* Suffix on matching beastie */ Src *ret; /* Return value */ char *cp; t = targ->node; (void) Lst_Open (t->children); prefLen = strlen (targ->pref); while ((ln = Lst_Next (t->children)) != NILLNODE) { s = (GNode *)Lst_Datum (ln); cp = strrchr (s->name, '/'); if (cp == (char *)NULL) { cp = s->name; } else { cp++; } if (strncmp (cp, targ->pref, prefLen) == 0) { /* * The node matches the prefix ok, see if it has a known * suffix. */ ln = Lst_Find (sufflist, (ClientData)&cp[prefLen], SuffSuffHasNameP); if (ln != NILLNODE) { /* * It even has a known suffix, see if there's a transformation * defined between the node's suffix and the target's suffix. * * XXX: Handle multi-stage transformations here, too. */ suff = (Suff *)Lst_Datum (ln); if (Lst_Member (suff->parents, (ClientData)targ->suff) != NILLNODE) { /* * Hot Damn! Create a new Src structure to describe * this transformation (making sure to duplicate the * source node's name so Suff_FindDeps can free it * again (ick)), and return the new structure. */ ret = (Src *)emalloc (sizeof(Src)); ret->file = strdup(s->name); ret->pref = targ->pref; ret->suff = suff; ret->parent = targ; ret->node = s; ret->children = 0; targ->children += 1; if (DEBUG(SUFF)) { printf ("\tusing existing source %s\n", s->name); } return (ret); } } } } Lst_Close (t->children); return ((Src *)NULL);}/*- *----------------------------------------------------------------------- * 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 intSuffExpandChildren(cgn, pgn) GNode *cgn; /* Child to examine */ GNode *pgn; /* Parent node being processed */{ 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 */ /* * New nodes effectively take the place of the child, so place them * after the child */ prevLN = Lst_Member(pgn->children, (ClientData)cgn); /* * 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. */ if (strchr(cgn->name, '$') != (char *)NULL) { if (DEBUG(SUFF)) { printf("Expanding \"%s\"...", cgn->name); } cp = Var_Subst(NULL, cgn->name, pgn, TRUE); if (cp != (char *)NULL) { Lst members = Lst_Init(FALSE); if (cgn->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. */ char *sacrifice = cp; (void)Arch_ParseArchive(&sacrifice, members, pgn); } else { /* * 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... */ char *start; char *initcp = cp; /* For freeing... */ 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); (void)Lst_AtEnd(members, (ClientData)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; int len; 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++; } } if (cp != start) { /* * Stuff left over -- add it to the list too */ gn = Targ_FindNode(start, TARG_CREATE); (void)Lst_AtEnd(members, (ClientData)gn); } /* * Point cp back at the beginning again so the variable value * can be freed. */ cp = initcp; } /* * Add all elements of the members list to the parent node. */ while(!Lst_IsEmpty(members)) { gn = (GNode *)Lst_DeQueue(members); if (DEBUG(SUFF)) { printf("%s...", gn->name); } 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++; } } Lst_Destroy(members, NOFREE); /* * Free the result */ free((char *)cp); } /* * 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"); } } else if (Dir_HasWildcards(cgn->name)) { Lst exp; /* List of expansions */ Lst path; /* Search path along which to expand */ /* * 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 = cgn->name + strlen(cgn->name); ln = Lst_Find(sufflist, (ClientData)cp, SuffSuffIsSuffixP); if (DEBUG(SUFF)) { printf("Wildcard expanding \"%s\"...", cgn->name); } if (ln != NILLNODE) { Suff *s = (Suff *)Lst_Datum(ln); if (DEBUG(SUFF)) { printf("suffix is \"%s\"...", s->name); } path = s->searchPath; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -