⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 suff.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
 *	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 + -