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

📄 suff.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 1988, 1989, 1990, 1993 *	The Regents of the University of California.  All rights reserved. * Copyright (c) 1989 by Berkeley Softworks * All rights reserved. * * This code is derived from software contributed to Berkeley by * Adam de Boor. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)suff.c	8.4 (Berkeley) 3/21/94";#endif /* not lint *//*- * suff.c -- *	Functions to maintain suffix lists and find implicit dependents *	using suffix transformation rules * * Interface: *	Suff_Init 	    	Initialize all things to do with suffixes. * *	Suff_DoPaths	    	This function is used to make life easier *	    	  	    	when searching for a file according to its *	    	  	    	suffix. It takes the global search path, *	    	  	    	as defined using the .PATH: target, and appends *	    	  	    	its directories to the path of each of the *	    	  	    	defined suffixes, as specified using *	    	  	    	.PATH<suffix>: targets. In addition, all *	    	  	    	directories given for suffixes labeled as *	    	  	    	include files or libraries, using the .INCLUDES *	    	  	    	or .LIBS targets, are played with using *	    	  	    	Dir_MakeFlags to create the .INCLUDES and *	    	  	    	.LIBS global variables. * *	Suff_ClearSuffixes  	Clear out all the suffixes and defined *	    	  	    	transformations. * *	Suff_IsTransform    	Return TRUE if the passed string is the lhs *	    	  	    	of a transformation rule. * *	Suff_AddSuffix	    	Add the passed string as another known suffix. * *	Suff_GetPath	    	Return the search path for the given suffix. * *	Suff_AddInclude	    	Mark the given suffix as denoting an include *	    	  	    	file. * *	Suff_AddLib	    	Mark the given suffix as denoting a library. * *	Suff_AddTransform   	Add another transformation to the suffix *	    	  	    	graph. Returns  GNode suitable for framing, I *	    	  	    	mean, tacking commands, attributes, etc. on. * *	Suff_SetNull	    	Define the suffix to consider the suffix of *	    	  	    	any file that doesn't have a known one. * *	Suff_FindDeps	    	Find implicit sources for and the location of *	    	  	    	a target based on its suffix. Returns the *	    	  	    	bottom-most node added to the graph or NILGNODE *	    	  	    	if the target had no implicit sources. */#include    	  <stdio.h>#include	  "make.h"#include	  "hash.h"#include	  "dir.h"#include    	  "bit.h"static Lst       sufflist;	/* Lst of suffixes */static Lst       transforms;	/* Lst of transformation rules */static int        sNum = 0;	/* Counter for assigning suffix numbers *//* * Structure describing an individual suffix. */typedef struct _Suff {    char         *name;	    	/* The suffix itself */    int		 nameLen;	/* Length of the suffix */    short	 flags;      	/* Type of suffix */#define SUFF_INCLUDE	  0x01	    /* One which is #include'd */#define SUFF_LIBRARY	  0x02	    /* One which contains a library */#define SUFF_NULL 	  0x04	    /* The empty suffix */    Lst    	 searchPath;	/* The path along which files of this suffix				 * may be found */    int          sNum;	      	/* The suffix number */    Lst          parents;	/* Suffixes we have a transformation to */    Lst          children;	/* Suffixes we have a transformation from */} Suff;/* * Structure used in the search for implied sources. */typedef struct _Src {    char            *file;	/* The file to look for */    char    	    *pref;  	/* Prefix from which file was formed */    Suff            *suff;	/* The suffix on the file */    struct _Src     *parent;	/* The Src for which this is a source */    GNode           *node;	/* The node describing the file */    int	    	    children;	/* Count of existing children (so we don't free				 * this thing too early or never nuke it) */} Src;/* * A structure for passing more than one argument to the Lst-library-invoked * function... */typedef struct {    Lst            l;    Src            *s;} LstSrc;static Suff 	    *suffNull;	/* The NULL suffix for this run */static Suff 	    *emptySuff;	/* The empty suffix required for POSIX				 * single-suffix transformation rules */static char *SuffStrIsPrefix __P((char *, char *));static char *SuffSuffIsSuffix __P((Suff *, char *));static int SuffSuffIsSuffixP __P((Suff *, char *));static int SuffSuffHasNameP __P((Suff *, char *));static int SuffSuffIsPrefix __P((Suff *, char *));static int SuffGNHasNameP __P((GNode *, char *));static void SuffFree __P((Suff *));static Suff* SuffCopy __P((Suff *));static void SuffInsert __P((Lst, Suff *));static Boolean SuffParseTransform __P((char *, Suff **, Suff **));static int SuffRebuildGraph __P((GNode *, Suff *));static int SuffAddSrc __P((Suff *, LstSrc *));static void SuffAddLevel __P((Lst, Src *));static void SuffFreeSrc __P((Src *));static Src *SuffFindThem __P((Lst));static Src *SuffFindCmds __P((Src *));static int SuffExpandChildren __P((GNode *, GNode *));static Boolean SuffApplyTransform __P((GNode *, GNode *, Suff *, Suff *));static void SuffFindArchiveDeps __P((GNode *));static void SuffFindNormalDeps __P((GNode *));static int SuffPrintName __P((Suff *));static int SuffPrintSuff __P((Suff *));static int SuffPrintTrans __P((GNode *));	/*************** Lst Predicates ****************//*- *----------------------------------------------------------------------- * SuffStrIsPrefix  -- *	See if pref is a prefix of str. * * Results: *	NULL if it ain't, pointer to character in str after prefix if so * * Side Effects: *	None *----------------------------------------------------------------------- */static char    *SuffStrIsPrefix (pref, str)    register char  *pref;	/* possible prefix */    register char  *str;	/* string to check */{    while (*str && *pref == *str) {	pref++;	str++;    }    return (*pref ? NULL : str);}/*- *----------------------------------------------------------------------- * SuffSuffIsSuffix  -- *	See if suff is a suffix of str. Str should point to THE END of the *	string to check. (THE END == the null byte) * * Results: *	NULL if it ain't, pointer to character in str before suffix if *	it is. * * Side Effects: *	None *----------------------------------------------------------------------- */static char *SuffSuffIsSuffix (s, str)    register Suff  *s;		/* possible suffix */    char           *str;	/* string to examine */{    register char  *p1;	    	/* Pointer into suffix name */    register char  *p2;	    	/* Pointer into string being examined */    p1 = s->name + s->nameLen;    p2 = str;    while (p1 >= s->name && *p1 == *p2) {	p1--;	p2--;    }    return (p1 == s->name - 1 ? p2 : NULL);}/*- *----------------------------------------------------------------------- * SuffSuffIsSuffixP -- *	Predicate form of SuffSuffIsSuffix. Passed as the callback function *	to Lst_Find. * * Results: *	0 if the suffix is the one desired, non-zero if not. * * Side Effects: *	None. * *----------------------------------------------------------------------- */static intSuffSuffIsSuffixP(s, str)    Suff    	*s;    char    	*str;{    return(!SuffSuffIsSuffix(s, str));}/*- *----------------------------------------------------------------------- * SuffSuffHasNameP -- *	Callback procedure for finding a suffix based on its name. Used by *	Suff_GetPath. * * Results: *	0 if the suffix is of the given name. non-zero otherwise. * * Side Effects: *	None *----------------------------------------------------------------------- */static intSuffSuffHasNameP (s, sname)    Suff    *s;	    	    /* Suffix to check */    char    *sname; 	    /* Desired name */{    return (strcmp (sname, s->name));}/*- *----------------------------------------------------------------------- * SuffSuffIsPrefix  -- *	See if the suffix described by s is a prefix of the string. Care *	must be taken when using this to search for transformations and *	what-not, since there could well be two suffixes, one of which *	is a prefix of the other... * * Results: *	0 if s is a prefix of str. non-zero otherwise * * Side Effects: *	None *----------------------------------------------------------------------- */static intSuffSuffIsPrefix (s, str)    Suff           *s;		/* suffix to compare */    char           *str;	/* string to examine */{    return (SuffStrIsPrefix (s->name, str) == NULL ? 1 : 0);}/*- *----------------------------------------------------------------------- * SuffGNHasNameP  -- *	See if the graph node has the desired name * * Results: *	0 if it does. non-zero if it doesn't * * Side Effects: *	None *----------------------------------------------------------------------- */static intSuffGNHasNameP (gn, name)    GNode          *gn;		/* current node we're looking at */    char           *name;	/* name we're looking for */{    return (strcmp (name, gn->name));} 	    /*********** Maintenance Functions ************//*- *----------------------------------------------------------------------- * SuffFree  -- *	Free up all memory associated with the given suffix structure. * * Results: *	none * * Side Effects: *	the suffix entry is detroyed *----------------------------------------------------------------------- */static voidSuffFree (s)    Suff           *s;{    Lst_Destroy (s->children, NOFREE);    Lst_Destroy (s->parents, NOFREE);    Lst_Destroy (s->searchPath, Dir_Destroy);    free ((Address)s->name);    free ((Address)s);}/*- *----------------------------------------------------------------------- * SuffInsert  -- *	Insert the suffix into the list keeping the list ordered by suffix *	numbers. * * Results: *	None * * Side Effects: *	Not really *----------------------------------------------------------------------- */static voidSuffInsert (l, s)    Lst           l;		/* the list where in s should be inserted */    Suff          *s;		/* the suffix to insert */{    LstNode 	  ln;		/* current element in l we're examining */    Suff          *s2 = NULL;	/* the suffix descriptor in this element */    if (Lst_Open (l) == FAILURE) {	return;    }    while ((ln = Lst_Next (l)) != NILLNODE) {	s2 = (Suff *) Lst_Datum (ln);	if (s2->sNum >= s->sNum) {	    break;	}    }    Lst_Close (l);    if (DEBUG(SUFF)) {	printf("inserting %s(%d)...", s->name, s->sNum);    }    if (ln == NILLNODE) {	if (DEBUG(SUFF)) {	    printf("at end of list\n");	}	(void)Lst_AtEnd (l, (ClientData)s);    } else if (s2->sNum != s->sNum) {	if (DEBUG(SUFF)) {	    printf("before %s(%d)\n", s2->name, s2->sNum);	}	(void)Lst_Insert (l, ln, (ClientData)s);    } else if (DEBUG(SUFF)) {	printf("already there\n");    }}/*- *----------------------------------------------------------------------- * Suff_ClearSuffixes -- *	This is gross. Nuke the list of suffixes but keep all transformation *	rules around. The transformation graph is destroyed in this process, *	but we leave the list of rules so when a new graph is formed the rules *	will remain. *	This function is called from the parse module when a *	.SUFFIXES:\n line is encountered. * * Results: *	none * * Side Effects: *	the sufflist and its graph nodes are destroyed *----------------------------------------------------------------------- */voidSuff_ClearSuffixes (){    Lst_Destroy (sufflist, SuffFree);    sufflist = Lst_Init(FALSE);    sNum = 0;    suffNull = emptySuff;}/*- *----------------------------------------------------------------------- * SuffParseTransform -- *	Parse a transformation string to find its two component suffixes. * * Results: *	TRUE if the string is a valid transformation and FALSE otherwise. * * Side Effects: *	The passed pointers are overwritten. * *----------------------------------------------------------------------- */static BooleanSuffParseTransform(str, srcPtr, targPtr)    char    	  	*str;	    	/* String being parsed */    Suff    	  	**srcPtr;   	/* Place to store source of trans. */    Suff    	  	**targPtr;  	/* Place to store target of trans. */{    register LstNode	srcLn;	    /* element in suffix list of trans source*/    register Suff    	*src;	    /* Source of transformation */    register LstNode    targLn;	    /* element in suffix list of trans target*/    register char    	*str2;	    /* Extra pointer (maybe target suffix) */    LstNode 	    	singleLn;   /* element in suffix list of any suffix				     * that exactly matches str */    Suff    	    	*single = NULL;/* Source of possible transformation to				     * null suffix */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -