📄 suff.c
字号:
/* * 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 + -