version 1.40, 2000/11/24 14:27:20 |
version 1.41, 2001/05/03 13:41:11 |
|
|
/* $OpenBSD$ */ |
/* $OpenPackages$ */ |
|
/* $OpenBSD$ */ |
/* $NetBSD: suff.c,v 1.13 1996/11/06 17:59:25 christos Exp $ */ |
/* $NetBSD: suff.c,v 1.13 1996/11/06 17:59:25 christos Exp $ */ |
|
|
/* |
/* |
|
|
* using suffix transformation rules |
* using suffix transformation rules |
* |
* |
* Interface: |
* Interface: |
* Suff_Init Initialize all things to do with suffixes. |
* Suff_Init Initialize all things to do with suffixes. |
* |
* |
* Suff_End Cleanup the module |
* Suff_End Cleanup the module |
* |
* |
* Suff_DoPaths This function is used to make life easier |
* Suff_DoPaths This function is used to make life easier |
* when searching for a file according to its |
* when searching for a file according to its |
* suffix. It takes the global search path, |
* suffix. It takes the global search path, |
* as defined using the .PATH: target, and appends |
* as defined using the .PATH: target, and appends |
* its directories to the path of each of the |
* its directories to the path of each of the |
* defined suffixes, as specified using |
* defined suffixes, as specified using |
* .PATH<suffix>: targets. In addition, all |
* .PATH<suffix>: targets. In addition, all |
* directories given for suffixes labeled as |
* directories given for suffixes labeled as |
* include files or libraries, using the .INCLUDES |
* include files or libraries, using the .INCLUDES |
* or .LIBS targets, are played with using |
* or .LIBS targets, are played with using |
* Dir_MakeFlags to create the .INCLUDES and |
* Dir_MakeFlags to create the .INCLUDES and |
* .LIBS global variables. |
* .LIBS global variables. |
* |
* |
* Suff_ClearSuffixes Clear out all the suffixes and defined |
* Suff_ClearSuffixes Clear out all the suffixes and defined |
* transformations. |
* transformations. |
* |
* |
* Suff_IsTransform Return TRUE if the passed string is the lhs |
* Suff_IsTransform Return TRUE if the passed string is the lhs |
* of a transformation rule. |
* of a transformation rule. |
* |
* |
* Suff_AddSuffix Add the passed string as another known suffix. |
* Suff_AddSuffix Add the passed string as another known suffix. |
* |
* |
* Suff_GetPath Return the search path for the given suffix. |
* Suff_GetPath Return the search path for the given suffix. |
* |
* |
* Suff_AddInclude Mark the given suffix as denoting an include |
* Suff_AddInclude Mark the given suffix as denoting an include |
* file. |
* file. |
* |
* |
* Suff_AddLib Mark the given suffix as denoting a library. |
* Suff_AddLib Mark the given suffix as denoting a library. |
* |
* |
* Suff_AddTransform Add another transformation to the suffix |
* Suff_AddTransform Add another transformation to the suffix |
* graph. Returns GNode suitable for framing, I |
* graph. Returns GNode suitable for framing, I |
* mean, tacking commands, attributes, etc. on. |
* mean, tacking commands, attributes, etc. on. |
* |
* |
* Suff_SetNull Define the suffix to consider the suffix of |
* Suff_SetNull Define the suffix to consider the suffix of |
* any file that doesn't have a known one. |
* any file that doesn't have a known one. |
* |
* |
* Suff_FindDeps Find implicit sources for and the location of |
* Suff_FindDeps Find implicit sources for and the location of |
* a target based on its suffix. Returns the |
* a target based on its suffix. Returns the |
* bottom-most node added to the graph or NULL |
* bottom-most node added to the graph or NULL |
* if the target had no implicit sources. |
* if the target had no implicit sources. |
*/ |
*/ |
|
|
#include <stddef.h> |
#include <stddef.h> |
#include <stdio.h> |
#include <stdio.h> |
#include "make.h" |
#include "make.h" |
#include "ohash.h" |
#include "ohash.h" |
#include "dir.h" |
#include "dir.h" |
|
|
#endif |
#endif |
#endif /* not lint */ |
#endif /* not lint */ |
|
|
static LIST sufflist; /* Lst of suffixes */ |
static LIST sufflist; /* Lst of suffixes */ |
#ifdef CLEANUP |
#ifdef CLEANUP |
static LIST suffClean; /* Lst of suffixes to be cleaned */ |
static LIST suffClean; /* Lst of suffixes to be cleaned */ |
#endif |
#endif |
static LIST srclist; /* Lst of sources */ |
static LIST srclist; /* Lst of sources */ |
static LIST transforms; /* Lst of transformation rules */ |
static LIST transforms; /* Lst of transformation rules */ |
|
|
static int sNum = 0; /* Counter for assigning suffix numbers */ |
static int sNum = 0; /* Counter for assigning suffix numbers */ |
|
|
/* |
/* |
* Structure describing an individual suffix. |
* Structure describing an individual suffix. |
*/ |
*/ |
typedef struct Suff_ { |
typedef struct Suff_ { |
char *name; /* The suffix itself */ |
char *name; /* The suffix itself */ |
int nameLen; /* Length of the suffix */ |
int nameLen; /* Length of the suffix */ |
short flags; /* Type of suffix */ |
short flags; /* Type of suffix */ |
#define SUFF_INCLUDE 0x01 /* One which is #include'd */ |
#define SUFF_INCLUDE 0x01 /* One which is #include'd */ |
#define SUFF_LIBRARY 0x02 /* One which contains a library */ |
#define SUFF_LIBRARY 0x02 /* One which contains a library */ |
#define SUFF_NULL 0x04 /* The empty suffix */ |
#define SUFF_NULL 0x04 /* The empty suffix */ |
LIST searchPath; /* The path along which files of this suffix |
LIST searchPath; /* The path along which files of this suffix |
* may be found */ |
* may be found */ |
int sNum; /* The suffix number */ |
int sNum; /* The suffix number */ |
LIST parents; /* Suffixes we have a transformation to */ |
LIST parents; /* Suffixes we have a transformation to */ |
LIST children; /* Suffixes we have a transformation from */ |
LIST children; /* Suffixes we have a transformation from */ |
LIST ref; /* List of lists this suffix is referenced */ |
LIST ref; /* List of lists this suffix is referenced */ |
} Suff; |
} Suff; |
|
|
|
|
* Structure used in the search for implied sources. |
* Structure used in the search for implied sources. |
*/ |
*/ |
typedef struct Src_ { |
typedef struct Src_ { |
char *file; /* The file to look for */ |
char *file; /* The file to look for */ |
char *pref; /* Prefix from which file was formed */ |
char *pref; /* Prefix from which file was formed */ |
Suff *suff; /* The suffix on the file */ |
Suff *suff; /* The suffix on the file */ |
struct Src_ *parent; /* The Src for which this is a source */ |
struct Src_ *parent; /* The Src for which this is a source */ |
GNode *node; /* The node describing the file */ |
GNode *node; /* The node describing the file */ |
int children; /* Count of existing children (so we don't free |
int children; /* Count of existing children (so we don't free |
* this thing too early or never nuke it) */ |
* this thing too early or never nuke it) */ |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
LIST cp; /* Debug; children list */ |
LIST cp; /* Debug; children list */ |
#endif |
#endif |
} Src; |
} Src; |
|
|
|
|
* function... |
* function... |
*/ |
*/ |
typedef struct { |
typedef struct { |
Lst l; |
Lst l; |
Src *s; |
Src *s; |
} LstSrc; |
} LstSrc; |
|
|
static Suff *suffNull; /* The NULL suffix for this run */ |
static Suff *suffNull; /* The NULL suffix for this run */ |
static Suff *emptySuff; /* The empty suffix required for POSIX |
static Suff *emptySuff; /* The empty suffix required for POSIX |
* single-suffix transformation rules */ |
* single-suffix transformation rules */ |
|
|
|
|
static char *SuffStrIsPrefix __P((char *, char *)); |
static char *SuffStrIsPrefix(const char *, const char *); |
static char *SuffSuffIsSuffix __P((Suff *, char *)); |
static char *SuffSuffIsSuffix(Suff *, const char *); |
static int SuffSuffIsSuffixP __P((void *, void *)); |
static int SuffSuffIsSuffixP(void *, const void *); |
static int SuffSuffHasNameP __P((void *, void *)); |
static int SuffSuffHasNameP(void *, const void *); |
static int SuffSuffIsPrefix __P((void *, void *)); |
static int SuffSuffIsPrefix(void *, const void *); |
static int SuffGNHasNameP __P((void *, void *)); |
static int SuffGNHasNameP(void *, const void *); |
static void SuffUnRef __P((Lst, Suff *)); |
static void SuffUnRef(Lst, Suff *); |
static void SuffInsert __P((Lst, Suff *)); |
#ifdef CLEANUP |
static void SuffRemove __P((Lst, Suff *)); |
static void SuffFree(void *); |
static Boolean SuffParseTransform __P((char *, Suff **, Suff **)); |
#endif |
static void SuffRebuildGraph __P((void *, void *)); |
static void SuffInsert(Lst, Suff *); |
static void SuffAddSrc __P((void *, void *)); |
static Boolean SuffParseTransform(const char *, Suff **, Suff **); |
static int SuffRemoveSrc __P((Lst)); |
static void SuffRebuildGraph(void *, void *); |
static void SuffAddLevel __P((Lst, Src *)); |
static void SuffAddSrc(void *, void *); |
static Src *SuffFindThem __P((Lst, Lst)); |
static int SuffRemoveSrc(Lst); |
static Src *SuffFindCmds __P((Src *, Lst)); |
static void SuffAddLevel(Lst, Src *); |
static void SuffExpandChildren __P((void *, void *)); |
static Src *SuffFindThem(Lst, Lst); |
static Boolean SuffApplyTransform __P((GNode *, GNode *, Suff *, Suff *)); |
static Src *SuffFindCmds(Src *, Lst); |
static void SuffFindDeps __P((GNode *, Lst)); |
static void SuffExpandChildren(void *, void *); |
static void SuffFindArchiveDeps __P((GNode *, Lst)); |
static void SuffExpandVarChildren(LstNode, GNode *, GNode *); |
static void SuffFindNormalDeps __P((GNode *, Lst)); |
static void SuffExpandWildChildren(LstNode, GNode *, GNode *); |
static void SuffPrintName __P((void *)); |
static Boolean SuffApplyTransform(GNode *, GNode *, Suff *, Suff *); |
static void SuffPrintSuff __P((void *)); |
static void SuffFindDeps(GNode *, Lst); |
static void SuffPrintTrans __P((void *)); |
static void SuffFindArchiveDeps(GNode *, Lst); |
|
static void SuffFindNormalDeps(GNode *, Lst); |
|
static void SuffPrintName(void *); |
|
static void SuffPrintSuff(void *); |
|
static void SuffPrintTrans(void *); |
|
|
/*************** Lst Predicates ****************/ |
/*************** Lst Predicates ****************/ |
/*- |
/*- |
|
|
* |
* |
* Results: |
* Results: |
* NULL if it ain't, pointer to character in str after prefix if so |
* NULL if it ain't, pointer to character in str after prefix if so |
* |
|
* Side Effects: |
|
* None |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static char * |
static char * |
SuffStrIsPrefix (pref, str) |
SuffStrIsPrefix(pref, str) |
register char *pref; /* possible prefix */ |
const char *pref; /* possible prefix */ |
register char *str; /* string to check */ |
const char *str; /* string to check */ |
{ |
{ |
while (*str && *pref == *str) { |
while (*str && *pref == *str) { |
pref++; |
pref++; |
str++; |
str++; |
} |
} |
|
|
return (*pref ? NULL : str); |
return *pref ? NULL : (char *)str; |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* SuffSuffIsSuffix -- |
* SuffSuffIsSuffix -- |
* See if suff is a suffix of str. Str should point to THE END of the |
* See if suff is a suffix of str. str should point to the end of the |
* string to check. (THE END == the null byte) |
* string to check. |
* |
* |
* Results: |
* Results: |
* NULL if it ain't, pointer to character in str before suffix if |
* NULL if it ain't, pointer to first character of suffix in str if |
* it is. |
* it is. |
* |
|
* Side Effects: |
|
* None |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static char * |
static char * |
SuffSuffIsSuffix (s, str) |
SuffSuffIsSuffix(s, str) |
register Suff *s; /* possible suffix */ |
Suff *s; /* possible suffix */ |
char *str; /* string to examine */ |
const char *str; /* string to examine */ |
{ |
{ |
register char *p1; /* Pointer into suffix name */ |
const char *p1; /* Pointer into suffix name */ |
register char *p2; /* Pointer into string being examined */ |
const char *p2; /* Pointer into string being examined */ |
|
|
p1 = s->name + s->nameLen; |
p1 = s->name + s->nameLen; |
p2 = str; |
p2 = str; |
|
|
while (p1 >= s->name && *p1 == *p2) { |
while (p1 != s->name) { |
p1--; |
p1--; |
p2--; |
p2--; |
|
if (*p1 != *p2) |
|
return NULL; |
} |
} |
|
|
return (p1 == s->name - 1 ? p2 : NULL); |
return (char *)p2; |
} |
} |
|
|
/*- |
/*- |
|
|
* |
* |
* Results: |
* Results: |
* 0 if the suffix is the one desired, non-zero if not. |
* 0 if the suffix is the one desired, non-zero if not. |
* |
|
* Side Effects: |
|
* None. |
|
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static int |
static int |
SuffSuffIsSuffixP(s, str) |
SuffSuffIsSuffixP(s, str) |
void *s; |
void *s; |
void *str; |
const void *str; |
{ |
{ |
return !SuffSuffIsSuffix((Suff *)s, (char *)str); |
return !SuffSuffIsSuffix((Suff *)s, (const char *)str); |
} |
} |
|
|
/*- |
/*- |
|
|
* |
* |
* Results: |
* Results: |
* 0 if the suffix is of the given name. non-zero otherwise. |
* 0 if the suffix is of the given name. non-zero otherwise. |
* |
|
* Side Effects: |
|
* None |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static int |
static int |
SuffSuffHasNameP (s, sname) |
SuffSuffHasNameP(s, sname) |
void *s; /* Suffix to check */ |
void *s; /* Suffix to check */ |
void *sname; /* Desired name */ |
const void *sname; /* Desired name */ |
{ |
{ |
return (strcmp ((char *) sname, ((Suff *) s)->name)); |
return strcmp((const char *)sname, ((Suff *)s)->name); |
} |
} |
|
|
/*- |
/*- |
|
|
* |
* |
* Results: |
* Results: |
* 0 if s is a prefix of str. non-zero otherwise |
* 0 if s is a prefix of str. non-zero otherwise |
* |
|
* Side Effects: |
|
* None |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static int |
static int |
SuffSuffIsPrefix(s, str) |
SuffSuffIsPrefix(s, str) |
void *s; /* suffix to compare */ |
void *s; /* suffix to compare */ |
void *str; /* string to examine */ |
const void *str; /* string to examine */ |
{ |
{ |
return SuffStrIsPrefix (((Suff *)s)->name, (char *)str) == NULL ? 1 : 0; |
return SuffStrIsPrefix(((Suff *)s)->name, (const char *)str) == NULL ? 1 : 0; |
} |
} |
|
|
/*- |
/*- |
|
|
* |
* |
* Results: |
* Results: |
* 0 if it does. non-zero if it doesn't |
* 0 if it does. non-zero if it doesn't |
* |
|
* Side Effects: |
|
* None |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static int |
static int |
SuffGNHasNameP(gn, name) |
SuffGNHasNameP(gn, name) |
void *gn; /* current node we're looking at */ |
void *gn; /* current node we're looking at */ |
void *name; /* name we're looking for */ |
const void *name; /* name we're looking for */ |
{ |
{ |
return strcmp((char *)name, ((GNode *)gn)->name); |
return strcmp((const char *)name, ((GNode *)gn)->name); |
} |
} |
|
|
/*********** Maintenance Functions ************/ |
/*********** Maintenance Functions ************/ |
|
|
static void |
static void |
SuffUnRef(l, s) |
SuffUnRef(l, sp) |
Lst l; |
Lst l; |
Suff *s; |
Suff *sp; |
{ |
{ |
LstNode ln = Lst_Member(l, s); |
LstNode ln = Lst_Member(l, sp); |
if (ln != NULL) |
if (ln != NULL) |
Lst_Remove(l, ln); |
Lst_Remove(l, ln); |
} |
} |
|
|
|
#ifdef CLEANUP |
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* SuffRemove -- |
* SuffFree -- |
* Remove the suffix from the list |
* Free up all memory associated with the given suffix structure. |
|
* |
|
* Side Effects: |
|
* the suffix entry is detroyed |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static void |
static void |
SuffRemove(l, s) |
SuffFree(sp) |
Lst l; |
void *sp; |
Suff *s; |
|
{ |
{ |
SuffUnRef(l, s); |
Suff *s = (Suff *)sp; |
|
|
|
if (s == suffNull) |
|
suffNull = NULL; |
|
|
|
if (s == emptySuff) |
|
emptySuff = NULL; |
|
|
|
Lst_Destroy(&s->ref, NOFREE); |
|
Lst_Destroy(&s->children, NOFREE); |
|
Lst_Destroy(&s->parents, NOFREE); |
|
Lst_Destroy(&s->searchPath, Dir_Destroy); |
|
|
|
free(s->name); |
|
free(s); |
} |
} |
|
#endif |
|
|
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
* SuffInsert -- |
* SuffInsert -- |
* Insert the suffix into the list keeping the list ordered by suffix |
* Insert the suffix into the list keeping the list ordered by suffix |
* numbers. |
* numbers. |
* |
* |
* Results: |
|
* None |
|
* |
|
* Side Effects: |
* Side Effects: |
* The reference count of the suffix is incremented |
* The reference count of the suffix is incremented |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static void |
static void |
SuffInsert (l, s) |
SuffInsert(l, s) |
Lst l; /* the list where in s should be inserted */ |
Lst l; /* the list where in s should be inserted */ |
Suff *s; /* the suffix to insert */ |
Suff *s; /* the suffix to insert */ |
{ |
{ |
LstNode ln; /* current element in l we're examining */ |
LstNode ln; /* current element in l we're examining */ |
Suff *s2 = NULL; /* the suffix descriptor in this element */ |
Suff *s2 = NULL; /* the suffix descriptor in this element */ |
|
|
Lst_Open(l); |
for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) { |
while ((ln = Lst_Next(l)) != NULL) { |
|
s2 = (Suff *)Lst_Datum(ln); |
s2 = (Suff *)Lst_Datum(ln); |
if (s2->sNum >= s->sNum) { |
if (s2->sNum >= s->sNum) |
break; |
break; |
} |
|
} |
} |
|
|
Lst_Close (l); |
|
if (DEBUG(SUFF)) { |
if (DEBUG(SUFF)) { |
printf("inserting %s(%d)...", s->name, s->sNum); |
printf("inserting %s(%d)...", s->name, s->sNum); |
} |
} |
|
|
* This function is called from the parse module when a |
* This function is called from the parse module when a |
* .SUFFIXES:\n line is encountered. |
* .SUFFIXES:\n line is encountered. |
* |
* |
* Results: |
|
* none |
|
* |
|
* Side Effects: |
* Side Effects: |
* the sufflist and its graph nodes are destroyed |
* the sufflist and its graph nodes are destroyed |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Suff_ClearSuffixes () |
Suff_ClearSuffixes() |
{ |
{ |
#ifdef CLEANUP |
#ifdef CLEANUP |
Lst_ConcatDestroy(&suffClean, &sufflist); |
Lst_ConcatDestroy(&suffClean, &sufflist); |
|
|
* |
* |
* Side Effects: |
* Side Effects: |
* The passed pointers are overwritten. |
* The passed pointers are overwritten. |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Boolean |
static Boolean |
SuffParseTransform(str, srcPtr, targPtr) |
SuffParseTransform(str, srcPtr, targPtr) |
char *str; /* String being parsed */ |
const char *str; /* String being parsed */ |
Suff **srcPtr; /* Place to store source of trans. */ |
Suff **srcPtr; /* Place to store source of trans. */ |
Suff **targPtr; /* Place to store target of trans. */ |
Suff **targPtr; /* Place to store target of trans. */ |
{ |
{ |
register LstNode srcLn; /* element in suffix list of trans source*/ |
LstNode srcLn; /* element in suffix list of trans source*/ |
register Suff *src; /* Source of transformation */ |
Suff *src; /* Source of transformation */ |
register LstNode targLn; /* element in suffix list of trans target*/ |
LstNode targLn; /* element in suffix list of trans target*/ |
register char *str2; /* Extra pointer (maybe target suffix) */ |
const char *str2; /* Extra pointer (maybe target suffix) */ |
LstNode singleLn; /* element in suffix list of any suffix |
LstNode singleLn; /* element in suffix list of any suffix |
* that exactly matches str */ |
* that exactly matches str */ |
Suff *single = NULL;/* Source of possible transformation to |
Suff *single = NULL;/* Source of possible transformation to |
* null suffix */ |
* null suffix */ |
|
|
srcLn = NULL; |
srcLn = NULL; |
|
|
* parsed the string. |
* parsed the string. |
*/ |
*/ |
for (;;) { |
for (;;) { |
|
if (srcLn == NULL) |
|
srcLn = Lst_FindConst(&sufflist, SuffSuffIsPrefix, str); |
|
else |
|
srcLn = Lst_FindFromConst(Lst_Succ(srcLn), SuffSuffIsPrefix, str); |
if (srcLn == NULL) { |
if (srcLn == NULL) { |
srcLn = Lst_Find(&sufflist, SuffSuffIsPrefix, str); |
|
} else { |
|
srcLn = Lst_FindFrom(Lst_Succ(srcLn), |
|
SuffSuffIsPrefix, str); |
|
} |
|
if (srcLn == NULL) { |
|
/* |
/* |
* Ran out of source suffixes -- no such rule |
* Ran out of source suffixes -- no such rule |
*/ |
*/ |
|
|
*/ |
*/ |
*srcPtr = single; |
*srcPtr = single; |
*targPtr = suffNull; |
*targPtr = suffNull; |
return(TRUE); |
return TRUE; |
} |
} |
return (FALSE); |
return FALSE; |
} |
} |
src = (Suff *)Lst_Datum(srcLn); |
src = (Suff *)Lst_Datum(srcLn); |
str2 = str + src->nameLen; |
str2 = str + src->nameLen; |
|
|
single = src; |
single = src; |
singleLn = srcLn; |
singleLn = srcLn; |
} else { |
} else { |
targLn = Lst_Find(&sufflist, SuffSuffHasNameP, str2); |
targLn = Lst_FindConst(&sufflist, SuffSuffHasNameP, str2); |
if (targLn != NULL) { |
if (targLn != NULL) { |
*srcPtr = src; |
*srcPtr = src; |
*targPtr = (Suff *)Lst_Datum(targLn); |
*targPtr = (Suff *)Lst_Datum(targLn); |
return (TRUE); |
return TRUE; |
} |
} |
} |
} |
} |
} |
|
|
* Suff_IsTransform -- |
* Suff_IsTransform -- |
* Return TRUE if the given string is a transformation rule |
* Return TRUE if the given string is a transformation rule |
* |
* |
* |
|
* Results: |
* Results: |
* TRUE if the string is a concatenation of two known suffixes. |
* TRUE if the string is a concatenation of two known suffixes. |
* FALSE otherwise |
* FALSE otherwise |
* |
|
* Side Effects: |
|
* None |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
Boolean |
Boolean |
Suff_IsTransform (str) |
Suff_IsTransform(str) |
char *str; /* string to check */ |
const char *str; /* string to check */ |
{ |
{ |
Suff *src, *targ; |
Suff *src, *targ; |
|
|
return (SuffParseTransform(str, &src, &targ)); |
return SuffParseTransform(str, &src, &targ); |
} |
} |
|
|
/*- |
/*- |
|
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
GNode * |
GNode * |
Suff_AddTransform (line) |
Suff_AddTransform(line) |
char *line; /* name of transformation to add */ |
const char *line; /* name of transformation to add */ |
{ |
{ |
GNode *gn; /* GNode of transformation rule */ |
GNode *gn; /* GNode of transformation rule */ |
Suff *s, /* source suffix */ |
Suff *s, /* source suffix */ |
*t; /* target suffix */ |
*t; /* target suffix */ |
LstNode ln; /* Node for existing transformation */ |
LstNode ln; /* Node for existing transformation */ |
|
|
ln = Lst_Find(&transforms, SuffGNHasNameP, line); |
ln = Lst_FindConst(&transforms, SuffGNHasNameP, line); |
if (ln == NULL) { |
if (ln == NULL) { |
/* |
/* |
* Make a new graph node for the transformation. It will be filled in |
* Make a new graph node for the transformation. It will be filled in |
|
|
*/ |
*/ |
gn = (GNode *)Lst_Datum(ln); |
gn = (GNode *)Lst_Datum(ln); |
Lst_Destroy(&gn->commands, NOFREE); |
Lst_Destroy(&gn->commands, NOFREE); |
Lst_Destroy(&gn->children, NOFREE); |
|
Lst_Init(&gn->commands); |
Lst_Init(&gn->commands); |
|
Lst_Destroy(&gn->children, NOFREE); |
Lst_Init(&gn->children); |
Lst_Init(&gn->children); |
} |
} |
|
|
|
|
SuffInsert(&t->children, s); |
SuffInsert(&t->children, s); |
SuffInsert(&s->parents, t); |
SuffInsert(&s->parents, t); |
|
|
return (gn); |
return gn; |
} |
} |
|
|
/*- |
/*- |
|
|
* Side Effects: |
* Side Effects: |
* If the node has no commands or children, the children and parents |
* If the node has no commands or children, the children and parents |
* lists of the affected suffices are altered. |
* lists of the affected suffices are altered. |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Suff_EndTransform(gnp) |
Suff_EndTransform(gnp) |
void *gnp; /* Node for transformation */ |
void *gnp; /* Node for transformation */ |
{ |
{ |
GNode *gn = (GNode *)gnp; |
GNode *gn = (GNode *)gnp; |
|
|
|
|
} |
} |
|
|
/* |
/* |
* Remove the source from the target's children list. |
* Remove the source from the target's children list. |
* |
* |
* We'll be called twice when the next target is seen, but .c and .o |
* We'll be called twice when the next target is seen, but .c and .o |
* are only linked once... |
* are only linked once... |
*/ |
*/ |
SuffRemove(&t->children, s); |
SuffUnRef(&t->children, s); |
|
|
/* |
/* |
* Remove the target from the source's parents list |
* Remove the target from the source's parents list |
*/ |
*/ |
SuffRemove(&s->parents, t); |
if (s != NULL) |
|
SuffUnRef(&s->parents, t); |
} else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { |
} else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { |
printf("transformation %s complete\n", gn->name); |
printf("transformation %s complete\n", gn->name); |
} |
} |
|
|
* Side Effects: |
* Side Effects: |
* The appropriate links will be made between this suffix and |
* The appropriate links will be made between this suffix and |
* others if transformation rules exist for it. |
* others if transformation rules exist for it. |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static void |
static void |
SuffRebuildGraph(transformp, sp) |
SuffRebuildGraph(transformp, sp) |
void *transformp; /* Transformation to test */ |
void *transformp; /* Transformation to test */ |
void *sp; /* Suffix to rebuild */ |
void *sp; /* Suffix to rebuild */ |
{ |
{ |
GNode *transform = (GNode *)transformp; |
GNode *transform = (GNode *)transformp; |
Suff *s = (Suff *)sp; |
Suff *s = (Suff *)sp; |
char *cp; |
char *cp; |
LstNode ln; |
LstNode ln; |
Suff *s2; |
Suff *s2; |
|
|
/* |
/* First see if it is a transformation from this suffix. */ |
* First see if it is a transformation from this suffix. |
|
*/ |
|
cp = SuffStrIsPrefix(s->name, transform->name); |
cp = SuffStrIsPrefix(s->name, transform->name); |
if (cp != NULL) { |
if (cp != NULL) { |
ln = Lst_Find(&sufflist, SuffSuffHasNameP, cp); |
ln = Lst_FindConst(&sufflist, SuffSuffHasNameP, cp); |
if (ln != NULL) { |
if (ln != NULL) { |
/* |
/* Found target. Link in and return, since it can't be anything |
* Found target. Link in and return, since it can't be anything |
* else. */ |
* else. |
|
*/ |
|
s2 = (Suff *)Lst_Datum(ln); |
s2 = (Suff *)Lst_Datum(ln); |
SuffInsert(&s2->children, s); |
SuffInsert(&s2->children, s); |
SuffInsert(&s->parents, s2); |
SuffInsert(&s->parents, s2); |
|
|
} |
} |
} |
} |
|
|
/* |
/* Not from, maybe to? */ |
* Not from, maybe to? |
|
*/ |
|
cp = SuffSuffIsSuffix(s, transform->name + strlen(transform->name)); |
cp = SuffSuffIsSuffix(s, transform->name + strlen(transform->name)); |
if (cp != NULL) { |
if (cp != NULL) { |
/* |
/* Null-terminate the source suffix in order to find it. */ |
* Null-terminate the source suffix in order to find it. |
*cp = '\0'; |
*/ |
ln = Lst_FindConst(&sufflist, SuffSuffHasNameP, transform->name); |
cp[1] = '\0'; |
/* Replace the start of the target suffix. */ |
ln = Lst_Find(&sufflist, SuffSuffHasNameP, transform->name); |
*cp = s->name[0]; |
/* |
|
* Replace the start of the target suffix |
|
*/ |
|
cp[1] = s->name[0]; |
|
if (ln != NULL) { |
if (ln != NULL) { |
/* |
/* Found it -- establish the proper relationship. */ |
* Found it -- establish the proper relationship |
|
*/ |
|
s2 = (Suff *)Lst_Datum(ln); |
s2 = (Suff *)Lst_Datum(ln); |
SuffInsert(&s->children, s2); |
SuffInsert(&s->children, s2); |
SuffInsert(&s2->parents, s); |
SuffInsert(&s2->parents, s); |
|
|
* Add the suffix in string to the end of the list of known suffixes. |
* Add the suffix in string to the end of the list of known suffixes. |
* Should we restructure the suffix graph? Make doesn't... |
* Should we restructure the suffix graph? Make doesn't... |
* |
* |
* Results: |
|
* None |
|
* |
|
* Side Effects: |
* Side Effects: |
* A GNode is created for the suffix and a Suff structure is created and |
* 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. |
* added to the suffixes list unless the suffix was already known. |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Suff_AddSuffix (str) |
Suff_AddSuffix(str) |
char *str; /* the name of the suffix to add */ |
char *str; /* the name of the suffix to add */ |
{ |
{ |
Suff *s; /* new suffix descriptor */ |
Suff *s; /* new suffix descriptor */ |
LstNode ln; |
LstNode ln; |
|
|
ln = Lst_Find(&sufflist, SuffSuffHasNameP, str); |
ln = Lst_FindConst(&sufflist, SuffSuffHasNameP, str); |
if (ln == NULL) { |
if (ln == NULL) { |
s = (Suff *) emalloc (sizeof (Suff)); |
s = emalloc(sizeof(Suff)); |
|
|
s->name = estrdup(str); |
s->name = estrdup(str); |
s->nameLen = strlen(s->name); |
s->nameLen = strlen(s->name); |
Lst_Init(&s->searchPath); |
Lst_Init(&s->searchPath); |
Lst_Init(&s->children); |
Lst_Init(&s->children); |
Lst_Init(&s->parents); |
Lst_Init(&s->parents); |
Lst_Init(&s->ref); |
Lst_Init(&s->ref); |
s->sNum = sNum++; |
s->sNum = sNum++; |
s->flags = 0; |
s->flags = 0; |
|
|
Lst_AtEnd(&sufflist, s); |
Lst_AtEnd(&sufflist, s); |
/* |
/* |
|
|
*/ |
*/ |
Lst |
Lst |
Suff_GetPath(sname) |
Suff_GetPath(sname) |
char *sname; |
char *sname; |
{ |
{ |
LstNode ln; |
LstNode ln; |
Suff *s; |
Suff *s; |
|
|
ln = Lst_Find(&sufflist, SuffSuffHasNameP, sname); |
ln = Lst_FindConst(&sufflist, SuffSuffHasNameP, sname); |
if (ln == NULL) |
if (ln == NULL) { |
return NULL; |
return NULL; |
else { |
} else { |
s = (Suff *)Lst_Datum(ln); |
s = (Suff *)Lst_Datum(ln); |
return &s->searchPath; |
return &s->searchPath; |
} |
} |
|
|
* Extend the search paths for all suffixes to include the default |
* Extend the search paths for all suffixes to include the default |
* search path. |
* search path. |
* |
* |
* Results: |
|
* None. |
|
* |
|
* Side Effects: |
* Side Effects: |
* The searchPath field of all the suffixes is extended by the |
* The searchPath field of all the suffixes is extended by the |
* directories in dirSearchPath. If paths were specified for the |
* directories in dirSearchPath. If paths were specified for the |
|
|
void |
void |
Suff_DoPaths() |
Suff_DoPaths() |
{ |
{ |
register Suff *s; |
Suff *s; |
register LstNode ln; |
LstNode ln; |
char *ptr; |
char *ptr; |
LIST inIncludes; /* Cumulative .INCLUDES path */ |
LIST inIncludes; /* Cumulative .INCLUDES path */ |
LIST inLibs; /* Cumulative .LIBS path */ |
LIST inLibs; /* Cumulative .LIBS path */ |
|
|
Lst_Open(&sufflist); |
|
|
|
Lst_Init(&inIncludes); |
Lst_Init(&inIncludes); |
Lst_Init(&inLibs); |
Lst_Init(&inLibs); |
|
|
while ((ln = Lst_Next(&sufflist)) != NULL) { |
for (ln = Lst_First(&sufflist); ln != NULL; ln = Lst_Adv(ln)) { |
s = (Suff *)Lst_Datum(ln); |
s = (Suff *)Lst_Datum(ln); |
if (!Lst_IsEmpty(&s->searchPath)) { |
if (!Lst_IsEmpty(&s->searchPath)) { |
#ifdef INCLUDES |
#ifdef INCLUDES |
|
|
|
|
Lst_Destroy(&inIncludes, Dir_Destroy); |
Lst_Destroy(&inIncludes, Dir_Destroy); |
Lst_Destroy(&inLibs, Dir_Destroy); |
Lst_Destroy(&inLibs, Dir_Destroy); |
|
|
Lst_Close(&sufflist); |
|
} |
} |
|
|
/*- |
/*- |
|
|
* Called from the parse module when a .INCLUDES line is parsed. |
* Called from the parse module when a .INCLUDES line is parsed. |
* The suffix must have already been defined. |
* The suffix must have already been defined. |
* |
* |
* Results: |
|
* None. |
|
* |
|
* Side Effects: |
* Side Effects: |
* The SUFF_INCLUDE bit is set in the suffix's flags field |
* The SUFF_INCLUDE bit is set in the suffix's flags field |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Suff_AddInclude (sname) |
Suff_AddInclude(sname) |
char *sname; /* Name of suffix to mark */ |
char *sname; /* Name of suffix to mark */ |
{ |
{ |
LstNode ln; |
LstNode ln; |
Suff *s; |
Suff *s; |
|
|
ln = Lst_Find(&sufflist, SuffSuffHasNameP, sname); |
ln = Lst_FindConst(&sufflist, SuffSuffHasNameP, sname); |
if (ln != NULL) { |
if (ln != NULL) { |
s = (Suff *)Lst_Datum(ln); |
s = (Suff *)Lst_Datum(ln); |
s->flags |= SUFF_INCLUDE; |
s->flags |= SUFF_INCLUDE; |
|
|
* suffix must have been defined via .SUFFIXES before this is |
* suffix must have been defined via .SUFFIXES before this is |
* called. |
* called. |
* |
* |
* Results: |
|
* None. |
|
* |
|
* Side Effects: |
* Side Effects: |
* The SUFF_LIBRARY bit is set in the suffix's flags field |
* The SUFF_LIBRARY bit is set in the suffix's flags field |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Suff_AddLib (sname) |
Suff_AddLib(sname) |
char *sname; /* Name of suffix to mark */ |
char *sname; /* Name of suffix to mark */ |
{ |
{ |
LstNode ln; |
LstNode ln; |
Suff *s; |
Suff *s; |
|
|
ln = Lst_Find(&sufflist, SuffSuffHasNameP, sname); |
ln = Lst_FindConst(&sufflist, SuffSuffHasNameP, sname); |
if (ln != NULL) { |
if (ln != NULL) { |
s = (Suff *)Lst_Datum(ln); |
s = (Suff *)Lst_Datum(ln); |
s->flags |= SUFF_LIBRARY; |
s->flags |= SUFF_LIBRARY; |
} |
} |
} |
} |
|
|
/********** Implicit Source Search Functions *********/ |
/********** Implicit Source Search Functions *********/ |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
|
|
void *lsp; /* list and parent for the new Src */ |
void *lsp; /* list and parent for the new Src */ |
{ |
{ |
Suff *s = (Suff *)sp; |
Suff *s = (Suff *)sp; |
LstSrc *ls = (LstSrc *)lsp; |
LstSrc *ls = (LstSrc *)lsp; |
Src *s2; /* new Src structure */ |
Src *s2; /* new Src structure */ |
Src *targ; /* Target structure */ |
Src *targ; /* Target structure */ |
|
|
targ = ls->s; |
targ = ls->s; |
|
|
if ((s->flags & SUFF_NULL) && (*s->name != '\0')) { |
if ((s->flags & SUFF_NULL) && *s->name != '\0') { |
/* |
/* |
* If the suffix has been marked as the NULL suffix, also create a Src |
* 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 |
* structure for a file with no suffix attached. Two birds, and all |
* that... |
* that... |
*/ |
*/ |
s2 = (Src *) emalloc (sizeof (Src)); |
s2 = emalloc(sizeof(Src)); |
s2->file = estrdup(targ->pref); |
s2->file = estrdup(targ->pref); |
s2->pref = targ->pref; |
s2->pref = targ->pref; |
s2->parent = targ; |
s2->parent = targ; |
s2->node = NULL; |
s2->node = NULL; |
s2->suff = s; |
s2->suff = s; |
s2->children = 0; |
s2->children = 0; |
targ->children += 1; |
targ->children += 1; |
Lst_AtEnd(ls->l, s2); |
Lst_AtEnd(ls->l, s2); |
|
|
printf("\n"); |
printf("\n"); |
#endif |
#endif |
} |
} |
s2 = (Src *) emalloc (sizeof (Src)); |
s2 = emalloc(sizeof(Src)); |
s2->file = str_concat(targ->pref, s->name, 0); |
s2->file = str_concat(targ->pref, s->name, 0); |
s2->pref = targ->pref; |
s2->pref = targ->pref; |
s2->parent = targ; |
s2->parent = targ; |
s2->node = NULL; |
s2->node = NULL; |
s2->suff = s; |
s2->suff = s; |
s2->children = 0; |
s2->children = 0; |
targ->children += 1; |
targ->children += 1; |
Lst_AtEnd(ls->l, s2); |
Lst_AtEnd(ls->l, s2); |
|
|
Lst_Every(ls->l, PrintAddr); |
Lst_Every(ls->l, PrintAddr); |
printf("\n"); |
printf("\n"); |
#endif |
#endif |
|
|
} |
} |
|
|
/*- |
/*- |
|
|
* SuffAddLevel -- |
* SuffAddLevel -- |
* Add all the children of targ as Src structures to the given list |
* Add all the children of targ as Src structures to the given list |
* |
* |
* Results: |
|
* None |
|
* |
|
* Side Effects: |
* Side Effects: |
* Lots of structures are created and added to the list |
* Lots of structures are created and added to the list |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static void |
static void |
SuffAddLevel (l, targ) |
SuffAddLevel(l, targ) |
Lst l; /* list to which to add the new level */ |
Lst l; /* list to which to add the new level */ |
Src *targ; /* Src structure to use as the parent */ |
Src *targ; /* Src structure to use as the parent */ |
{ |
{ |
LstSrc ls; |
LstSrc ls; |
|
|
ls.s = targ; |
ls.s = targ; |
ls.l = l; |
ls.l = l; |
|
|
* Free all src structures in list that don't have a reference count |
* Free all src structures in list that don't have a reference count |
* |
* |
* Results: |
* Results: |
* True if an src was removed |
* Ture if an src was removed |
* |
* |
* Side Effects: |
* Side Effects: |
* The memory is free'd. |
* The memory is free'd. |
*---------------------------------------------------------------------- |
*---------------------------------------------------------------------- |
*/ |
*/ |
static int |
static int |
SuffRemoveSrc (l) |
SuffRemoveSrc(l) |
Lst l; |
Lst l; |
{ |
{ |
LstNode ln; |
LstNode ln; |
Src *s; |
Src *s; |
int t = 0; |
int t = 0; |
|
|
Lst_Open(l); |
|
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
printf("cleaning %lx: ", (unsigned long) l); |
printf("cleaning %lx: ", (unsigned long)l); |
Lst_Every(l, PrintAddr); |
Lst_Every(l, PrintAddr); |
printf("\n"); |
printf("\n"); |
#endif |
#endif |
|
|
|
|
while ((ln = Lst_Next (l)) != NULL) { |
for (ln = Lst_First(l); ln != NULL; ln = Lst_Adv(ln)) { |
s = (Src *)Lst_Datum(ln); |
s = (Src *)Lst_Datum(ln); |
if (s->children == 0) { |
if (s->children == 0) { |
free(s->file); |
free(s->file); |
|
|
free(s->pref); |
free(s->pref); |
else { |
else { |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
LstNode ln = Lst_Member(&s->parent->cp, s); |
LstNode ln2 = Lst_Member(&s->parent->cp, s); |
if (ln != NULL) |
if (ln2 != NULL) |
Lst_Remove(&s->parent->cp, ln); |
Lst_Remove(&s->parent->cp, ln2); |
#endif |
#endif |
--s->parent->children; |
--s->parent->children; |
} |
} |
|
|
Lst_Remove(l, ln); |
Lst_Remove(l, ln); |
free(s); |
free(s); |
t |= 1; |
t |= 1; |
Lst_Close(l); |
|
return TRUE; |
return TRUE; |
} |
} |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
|
|
#endif |
#endif |
} |
} |
|
|
Lst_Close(l); |
|
|
|
return t; |
return t; |
} |
} |
|
|
|
|
* |
* |
* Results: |
* Results: |
* The lowest structure in the chain of transformations |
* The lowest structure in the chain of transformations |
* |
|
* Side Effects: |
|
* None |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Src * |
static Src * |
SuffFindThem (srcs, slst) |
SuffFindThem(srcs, slst) |
Lst srcs; /* list of Src structures to search through */ |
Lst srcs; /* list of Src structures to search through */ |
Lst slst; |
Lst slst; |
{ |
{ |
Src *s; /* current Src */ |
Src *s; /* current Src */ |
Src *rs; /* returned Src */ |
Src *rs; /* returned Src */ |
char *ptr; |
char *ptr; |
|
|
rs = (Src *) NULL; |
rs = NULL; |
|
|
while ((s = (Src *)Lst_DeQueue(srcs)) != NULL) { |
while ((s = (Src *)Lst_DeQueue(srcs)) != NULL) { |
if (DEBUG(SUFF)) { |
if (DEBUG(SUFF)) { |
printf ("\ttrying %s...", s->file); |
printf("\ttrying %s...", s->file); |
} |
} |
|
|
/* |
/* |
* A file is considered to exist if either a node exists in the |
* A file is considered to exist if either a node exists in the |
* graph for it or the file actually exists. |
* graph for it or the file actually exists. |
*/ |
*/ |
if (Targ_FindNode(s->file, TARG_NOCREATE) != NULL) { |
if (Targ_FindNode(s->file, NULL, TARG_NOCREATE) != NULL) { |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
printf("remove %x from %x\n", s, srcs); |
printf("remove %x from %x\n", s, srcs); |
#endif |
#endif |
|
|
} |
} |
|
|
if (DEBUG(SUFF)) { |
if (DEBUG(SUFF)) { |
printf ("not there\n"); |
printf("not there\n"); |
} |
} |
|
|
SuffAddLevel (srcs, s); |
SuffAddLevel(srcs, s); |
Lst_AtEnd(slst, s); |
Lst_AtEnd(slst, s); |
} |
} |
|
|
if (DEBUG(SUFF) && rs) { |
if (DEBUG(SUFF) && rs) { |
printf ("got it\n"); |
printf("got it\n"); |
} |
} |
return (rs); |
return rs; |
} |
} |
|
|
/*- |
/*- |
|
|
* |
* |
* Side Effects: |
* Side Effects: |
* A Src structure may be allocated. |
* A Src structure may be allocated. |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Src * |
static Src * |
SuffFindCmds (targ, slst) |
SuffFindCmds(targ, slst) |
Src *targ; /* Src structure to play with */ |
Src *targ; /* Src structure to play with */ |
Lst slst; |
Lst slst; |
{ |
{ |
LstNode ln; /* General-purpose list node */ |
LstNode ln; /* General-purpose list node */ |
register GNode *t, /* Target GNode */ |
GNode *t, /* Target GNode */ |
*s; /* Source GNode */ |
*s; /* Source GNode */ |
int prefLen;/* The length of the defined prefix */ |
int prefLen;/* The length of the defined prefix */ |
Suff *suff; /* Suffix on matching beastie */ |
Suff *suff; /* Suffix on matching beastie */ |
Src *ret; /* Return value */ |
Src *ret; /* Return value */ |
char *cp; |
const char *cp; |
|
|
t = targ->node; |
t = targ->node; |
Lst_Open(&t->children); |
prefLen = strlen(targ->pref); |
prefLen = strlen (targ->pref); |
|
|
|
while ((ln = Lst_Next(&t->children)) != NULL) { |
for (ln = Lst_First(&t->children); ln != NULL; ln = Lst_Adv(ln)) { |
s = (GNode *)Lst_Datum(ln); |
s = (GNode *)Lst_Datum(ln); |
|
|
cp = strrchr (s->name, '/'); |
cp = strrchr(s->name, '/'); |
if (cp == (char *)NULL) { |
if (cp == NULL) { |
cp = s->name; |
cp = s->name; |
} else { |
} else { |
cp++; |
cp++; |
} |
} |
if (strncmp (cp, targ->pref, prefLen) == 0) { |
if (strncmp(cp, targ->pref, prefLen) == 0) { |
/* |
/* The node matches the prefix ok, see if it has a known |
* The node matches the prefix ok, see if it has a known |
* suffix. */ |
* suffix. |
LstNode ln2; |
*/ |
ln2 = Lst_FindConst(&sufflist, SuffSuffHasNameP, &cp[prefLen]); |
ln = Lst_Find(&sufflist, SuffSuffHasNameP, &cp[prefLen]); |
if (ln2 != NULL) { |
if (ln != NULL) { |
|
/* |
/* |
* It even has a known suffix, see if there's a transformation |
* It even has a known suffix, see if there's a transformation |
* defined between the node's suffix and the target's suffix. |
* defined between the node's suffix and the target's suffix. |
* |
* |
* XXX: Handle multi-stage transformations here, too. |
* XXX: Handle multi-stage transformations here, too. |
*/ |
*/ |
suff = (Suff *)Lst_Datum(ln); |
suff = (Suff *)Lst_Datum(ln2); |
|
|
if (Lst_Member(&suff->parents, targ->suff) != NULL) |
if (Lst_Member(&suff->parents, targ->suff) != NULL) { |
{ |
|
/* |
/* |
* Hot Damn! Create a new Src structure to describe |
* Hot Damn! Create a new Src structure to describe |
* this transformation (making sure to duplicate the |
* this transformation (making sure to duplicate the |
* source node's name so Suff_FindDeps can free it |
* source node's name so Suff_FindDeps can free it |
* again (ick)), and return the new structure. |
* again (ick)), and return the new structure. |
*/ |
*/ |
ret = (Src *)emalloc (sizeof (Src)); |
ret = emalloc(sizeof(Src)); |
ret->file = estrdup(s->name); |
ret->file = estrdup(s->name); |
ret->pref = targ->pref; |
ret->pref = targ->pref; |
ret->suff = suff; |
ret->suff = suff; |
|
|
if (DEBUG(SUFF)) { |
if (DEBUG(SUFF)) { |
printf ("\tusing existing source %s\n", s->name); |
printf ("\tusing existing source %s\n", s->name); |
} |
} |
return (ret); |
return ret; |
} |
} |
} |
} |
} |
} |
} |
} |
Lst_Close(&t->children); |
return NULL; |
return ((Src *)NULL); |
|
} |
} |
|
|
/*- |
|
*----------------------------------------------------------------------- |
|
* SuffExpandChildren -- |
|
* Expand the names of any children of a given node that contain |
|
* variable invocations or file wildcards into actual targets. |
|
* |
|
* 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 void |
static void |
SuffExpandChildren(cgnp, pgnp) |
SuffExpandVarChildren(after, cgn, pgn) |
void *cgnp; /* Child to examine */ |
LstNode after; |
void *pgnp; /* Parent node being processed */ |
GNode *cgn; |
|
GNode *pgn; |
{ |
{ |
GNode *cgn = (GNode *)cgnp; |
GNode *gn; /* New source 8) */ |
GNode *pgn = (GNode *)pgnp; |
char *cp; /* Expanded value */ |
GNode *gn; /* New source 8) */ |
LIST members; |
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, cgn); |
|
|
|
/* |
if (DEBUG(SUFF)) |
* First do variable expansion -- this takes precedence over |
printf("Expanding \"%s\"...", cgn->name); |
* 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, '$') != NULL) { |
|
if (DEBUG(SUFF)) |
|
printf("Expanding \"%s\"...", cgn->name); |
|
cp = Var_Subst(cgn->name, &pgn->context, TRUE); |
|
|
|
if (cp != NULL) { |
cp = Var_Subst(cgn->name, &pgn->context, TRUE); |
LIST members; |
if (cp == NULL) { |
|
printf("Problem substituting in %s", cgn->name); |
|
printf("\n"); |
|
return; |
|
} |
|
|
Lst_Init(&members); |
Lst_Init(&members); |
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->context); |
if (cgn->type & OP_ARCHV) { |
} else { |
/* |
/* |
* Node was an archive(member) target, so we want to call |
* Break the result into a vector of strings whose nodes |
* on the Arch module to find the nodes for us, expanding |
* we can find, then add those nodes to the members list. |
* variables in the parent's context. |
* Unfortunately, we can't use brk_string b/c it |
*/ |
* doesn't understand about variable specifications with |
char *sacrifice = cp; |
* spaces in them... |
|
*/ |
|
char *start; |
|
char *initcp = cp; /* For freeing... */ |
|
|
|
for (start = cp; *start == ' ' || *start == '\t'; start++) |
(void)Arch_ParseArchive(&sacrifice, &members, &pgn->context); |
continue; |
} else { |
for (cp = start; *cp != '\0'; cp++) { |
/* Break the result into a vector of strings whose nodes |
if (*cp == ' ' || *cp == '\t') { |
* we can find, then add those nodes to the members list. |
/* |
* Unfortunately, we can't use brk_string because it |
* White-space -- terminate element, find the node, |
* doesn't understand about variable specifications with |
* add it, skip any further spaces. |
* spaces in them... */ |
*/ |
char *start, *cp2; |
*cp++ = '\0'; |
|
gn = Targ_FindNode(start, TARG_CREATE); |
|
Lst_AtEnd(&members, 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; |
|
size_t len; |
|
Boolean doFree; |
|
|
|
junk = Var_Parse(cp, &pgn->context, TRUE, &len, &doFree); |
for (start = cp; *start == ' ' || *start == '\t'; start++) |
if (junk != var_Error) |
continue; |
cp += len - 1; |
for (cp2 = start; *cp2 != '\0';) { |
|
if (isspace(*cp2)) { |
|
/* White-space -- terminate element, find the node, |
|
* add it, skip any further spaces. */ |
|
gn = Targ_FindNode(start, cp2, TARG_CREATE); |
|
cp2++; |
|
Lst_AtEnd(&members, gn); |
|
while (isspace(*cp2)) |
|
cp2++; |
|
/* Adjust cp2 for increment at start of loop, but |
|
* set start to first non-space. */ |
|
start = cp2; |
|
} else if (*cp2 == '$') |
|
/* Start of a variable spec -- contact variable module |
|
* to find the end so we can skip over it. */ |
|
cp2 += Var_ParseSkip(cp2, &pgn->context, NULL); |
|
else if (*cp2 == '\\' && cp2[1] != '\0') |
|
/* Escaped something -- skip over it. */ |
|
cp2+=2; |
|
} |
|
|
if (doFree) |
if (cp2 != start) { |
free(junk); |
/* Stuff left over -- add it to the list too. */ |
} else if (*cp == '\\' && *cp != '\0') { |
gn = Targ_FindNode(start, cp2, TARG_CREATE); |
/* |
Lst_AtEnd(&members, gn); |
* Escaped something -- skip over it |
|
*/ |
|
cp++; |
|
} |
|
} |
|
|
|
if (cp != start) { |
|
/* |
|
* Stuff left over -- add it to the list too |
|
*/ |
|
gn = Targ_FindNode(start, TARG_CREATE); |
|
Lst_AtEnd(&members, 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((gn = (GNode *)Lst_DeQueue(&members)) != NULL) { |
|
if (DEBUG(SUFF)) |
|
printf("%s...", gn->name); |
|
if (Lst_Member(&pgn->children, gn) == NULL) { |
|
Lst_Append(&pgn->children, prevLN, gn); |
|
prevLN = Lst_Succ(prevLN); |
|
Lst_AtEnd(&gn->parents, pgn); |
|
pgn->unmade++; |
|
} |
|
} |
|
Lst_Destroy(&members, NOFREE); |
|
/* Free the result */ |
|
free(cp); |
|
} |
} |
/* |
} |
* Now the source is expanded, remove it from the list of children to |
/* Add all elements of the members list to the parent node. */ |
* keep it from being processed. |
while ((gn = (GNode *)Lst_DeQueue(&members)) != NULL) { |
*/ |
|
ln = Lst_Member(&pgn->children, cgn); |
|
pgn->unmade--; |
|
Lst_Remove(&pgn->children, ln); |
|
if (DEBUG(SUFF)) |
if (DEBUG(SUFF)) |
printf("\n"); |
printf("%s...", gn->name); |
} else if (Dir_HasWildcards(cgn->name)) { |
if (Lst_Member(&pgn->children, gn) == NULL) { |
LIST exp; /* List of expansions */ |
Lst_Append(&pgn->children, after, gn); |
Lst path; /* Search path along which to expand */ |
after = Lst_Adv(after); |
|
Lst_AtEnd(&gn->parents, pgn); |
|
pgn->unmade++; |
|
} |
|
} |
|
/* Free the result. */ |
|
free(cp); |
|
if (DEBUG(SUFF)) |
|
printf("\n"); |
|
} |
|
|
/* |
static void |
* Find a path along which to expand the word. |
SuffExpandWildChildren(after, cgn, pgn) |
* |
LstNode after; |
* If the word has a known suffix, use that path. |
GNode *cgn; |
* If it has no known suffix and we're allowed to use the null |
GNode *pgn; |
* suffix, use its path. |
{ |
* Else use the default system search path. |
LstNode ln; /* List element for old source */ |
*/ |
char *cp; /* Expanded value */ |
cp = cgn->name + strlen(cgn->name); |
|
ln = Lst_Find(&sufflist, SuffSuffIsSuffixP, cp); |
|
|
|
if (DEBUG(SUFF)) |
LIST exp; /* List of expansions */ |
printf("Wildcard expanding \"%s\"...", cgn->name); |
Lst path; /* Search path along which to expand */ |
|
|
if (ln != NULL) { |
if (DEBUG(SUFF)) |
Suff *s = (Suff *)Lst_Datum(ln); |
printf("Wildcard expanding \"%s\"...", cgn->name); |
|
|
if (DEBUG(SUFF)) |
/* Find a path along which to expand the word. |
printf("suffix is \"%s\"...", s->name); |
* |
path = &s->searchPath; |
* If the word has a known suffix, use that path. |
} else { |
* If it has no known suffix and we're allowed to use the null |
/* |
* suffix, use its path. |
* Use default search path |
* Else use the default system search path. */ |
*/ |
cp = cgn->name + strlen(cgn->name); |
path = &dirSearchPath; |
ln = Lst_FindConst(&sufflist, SuffSuffIsSuffixP, cp); |
} |
|
|
|
/* Expand the word along the chosen path */ |
if (ln != NULL) { |
Lst_Init(&exp); |
Suff *s = (Suff *)Lst_Datum(ln); |
Dir_Expand(cgn->name, path, &exp); |
|
|
|
/* Fetch next expansion off the list and find its GNode. */ |
if (DEBUG(SUFF)) |
while ((cp = (char *)Lst_DeQueue(&exp)) != NULL) { |
printf("suffix is \"%s\"...", s->name); |
if (DEBUG(SUFF)) |
path = &s->searchPath; |
printf("%s...", cp); |
} else |
gn = Targ_FindNode(cp, TARG_CREATE); |
/* Use default search path. */ |
|
path = &dirSearchPath; |
|
|
/* |
/* Expand the word along the chosen path. */ |
* If gn isn't already a child of the parent, make it so and |
Lst_Init(&exp); |
* up the parent's count of unmade children. |
Dir_Expand(cgn->name, path, &exp); |
*/ |
|
if (Lst_Member(&pgn->children, gn) == NULL) { |
|
Lst_Append(&pgn->children, prevLN, gn); |
|
prevLN = Lst_Succ(prevLN); |
|
Lst_AtEnd(&gn->parents, pgn); |
|
pgn->unmade++; |
|
} |
|
} |
|
|
|
/* Nuke what's left of the list. */ |
/* Fetch next expansion off the list and find its GNode. */ |
Lst_Destroy(&exp, NOFREE); |
while ((cp = (char *)Lst_DeQueue(&exp)) != NULL) { |
|
GNode *gn; /* New source 8) */ |
/* |
|
* Now the source is expanded, remove it from the list of children to |
|
* keep it from being processed. |
|
*/ |
|
ln = Lst_Member(&pgn->children, cgn); |
|
pgn->unmade--; |
|
Lst_Remove(&pgn->children, ln); |
|
if (DEBUG(SUFF)) |
if (DEBUG(SUFF)) |
printf("\n"); |
printf("%s...", cp); |
|
gn = Targ_FindNode(cp, NULL, TARG_CREATE); |
|
|
|
/* If gn isn't already a child of the parent, make it so and |
|
* up the parent's count of unmade children. */ |
|
if (Lst_Member(&pgn->children, gn) == NULL) { |
|
Lst_Append(&pgn->children, after, gn); |
|
after = Lst_Adv(after); |
|
Lst_AtEnd(&gn->parents, pgn); |
|
pgn->unmade++; |
|
} |
} |
} |
|
|
|
if (DEBUG(SUFF)) |
|
printf("\n"); |
} |
} |
|
|
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
|
* SuffExpandChildren -- |
|
* Expand the names of any children of a given node that contain |
|
* variable invocations or file wildcards into actual targets. |
|
* |
|
* 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 void |
|
SuffExpandChildren(cgnp, pgnp) |
|
void *cgnp; /* Child to examine */ |
|
void *pgnp; /* Parent node being processed */ |
|
{ |
|
GNode *cgn = (GNode *)cgnp; |
|
GNode *pgn = (GNode *)pgnp; |
|
LstNode ln; |
|
/* New nodes effectively take the place of the child, so we place them |
|
* after the child. */ |
|
ln = Lst_Member(&pgn->children, 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, '$') != NULL) |
|
SuffExpandVarChildren(ln, cgn, pgn); |
|
else if (Dir_HasWildcards(cgn->name)) |
|
SuffExpandWildChildren(ln, cgn, pgn); |
|
else |
|
/* Third case: nothing to expand. */ |
|
return; |
|
|
|
/* Since the source was expanded, remove it from the list of children to |
|
* keep it from being processed. */ |
|
pgn->unmade--; |
|
Lst_Remove(&pgn->children, ln); |
|
} |
|
|
|
/*- |
|
*----------------------------------------------------------------------- |
* SuffApplyTransform -- |
* SuffApplyTransform -- |
* Apply a transformation rule, given the source and target nodes |
* Apply a transformation rule, given the source and target nodes |
* and suffixes. |
* and suffixes. |
|
|
* All attributes but OP_DEPMASK and OP_TRANSFORM are applied |
* All attributes but OP_DEPMASK and OP_TRANSFORM are applied |
* to the target. The target also inherits all the sources for |
* to the target. The target also inherits all the sources for |
* the transformation rule. |
* the transformation rule. |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Boolean |
static Boolean |
SuffApplyTransform(tGn, sGn, t, s) |
SuffApplyTransform(tGn, sGn, t, s) |
GNode *tGn; /* Target node */ |
GNode *tGn; /* Target node */ |
GNode *sGn; /* Source node */ |
GNode *sGn; /* Source node */ |
Suff *t; /* Target suffix */ |
Suff *t; /* Target suffix */ |
Suff *s; /* Source suffix */ |
Suff *s; /* Source suffix */ |
{ |
{ |
LstNode ln; /* General node */ |
LstNode ln; /* General node */ |
LstNode np; /* Next node for loop */ |
LstNode np; /* Next node for loop */ |
char *tname; /* Name of transformation rule */ |
char *tname; /* Name of transformation rule */ |
GNode *gn; /* Node for same */ |
GNode *gn; /* Node for same */ |
|
|
if (Lst_Member(&tGn->children, sGn) == NULL) { |
if (Lst_AddNew(&tGn->children, sGn) == SUCCESS) { |
/* |
/* Not already linked, so form the proper links between the |
* Not already linked, so form the proper links between the |
* target and source. */ |
* target and source. |
|
*/ |
|
Lst_AtEnd(&tGn->children, sGn); |
|
Lst_AtEnd(&sGn->parents, tGn); |
Lst_AtEnd(&sGn->parents, tGn); |
tGn->unmade += 1; |
tGn->unmade++; |
} |
} |
|
|
if ((sGn->type & OP_OPMASK) == OP_DOUBLEDEP) { |
if ((sGn->type & OP_OPMASK) == OP_DOUBLEDEP) { |
/* |
/* When a :: node is used as the implied source of a node, we have |
* When a :: node is used as the implied source of a node, we have |
|
* to link all its cohorts in as sources as well. Only the initial |
* to link all its cohorts in as sources as well. Only the initial |
* sGn gets the target in its iParents list, however, as that |
* sGn gets the target in its iParents list, however, as that |
* will be sufficient to get the .IMPSRC variable set for tGn |
* will be sufficient to get the .IMPSRC variable set for tGn. */ |
*/ |
|
for (ln=Lst_First(&sGn->cohorts); ln != NULL; ln=Lst_Adv(ln)) { |
for (ln=Lst_First(&sGn->cohorts); ln != NULL; ln=Lst_Adv(ln)) { |
gn = (GNode *)Lst_Datum(ln); |
gn = (GNode *)Lst_Datum(ln); |
|
|
if (Lst_Member(&tGn->children, gn) == NULL) { |
if (Lst_AddNew(&tGn->children, gn) == SUCCESS) { |
/* |
/* Not already linked, so form the proper links between the |
* Not already linked, so form the proper links between the |
* target and source. */ |
* target and source. |
|
*/ |
|
Lst_AtEnd(&tGn->children, gn); |
|
Lst_AtEnd(&gn->parents, tGn); |
Lst_AtEnd(&gn->parents, tGn); |
tGn->unmade += 1; |
tGn->unmade++; |
} |
} |
} |
} |
} |
} |
/* |
/* Locate the transformation rule itself. */ |
* Locate the transformation rule itself |
|
*/ |
|
tname = str_concat(s->name, t->name, 0); |
tname = str_concat(s->name, t->name, 0); |
ln = Lst_Find(&transforms, SuffGNHasNameP, tname); |
ln = Lst_FindConst(&transforms, SuffGNHasNameP, tname); |
free(tname); |
free(tname); |
|
|
if (ln == NULL) { |
if (ln == NULL) |
/* |
/* |
* Not really such a transformation rule (can happen when we're |
* Not really such a transformation rule (can happen when we're |
* called to link an OP_MEMBER and OP_ARCHV node), so return |
* called to link an OP_MEMBER and OP_ARCHV node), so return |
* FALSE. |
* FALSE. |
*/ |
*/ |
return(FALSE); |
return FALSE; |
} |
|
|
|
gn = (GNode *)Lst_Datum(ln); |
gn = (GNode *)Lst_Datum(ln); |
|
|
if (DEBUG(SUFF)) { |
if (DEBUG(SUFF)) |
printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); |
printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); |
} |
|
|
|
/* |
/* Record last child for expansion purposes. */ |
* Record last child for expansion purposes |
|
*/ |
|
ln = Lst_Last(&tGn->children); |
ln = Lst_Last(&tGn->children); |
|
|
/* |
/* Pass the buck to Make_HandleUse to apply the rule. */ |
* Pass the buck to Make_HandleUse to apply the rule |
Make_HandleUse(gn, tGn); |
*/ |
|
(void)Make_HandleUse(gn, tGn); |
|
|
|
/* |
/* Deal with wildcards and variables in any acquired sources. */ |
* Deal with wildcards and variables in any acquired sources |
|
*/ |
|
for (ln = Lst_Succ(ln); ln != NULL; ln = np) { |
for (ln = Lst_Succ(ln); ln != NULL; ln = np) { |
np = Lst_Adv(ln); |
np = Lst_Adv(ln); |
SuffExpandChildren(Lst_Datum(ln), tGn); |
SuffExpandChildren(Lst_Datum(ln), tGn); |
} |
} |
|
|
/* |
/* Keep track of another parent to which this beast is transformed so |
* Keep track of another parent to which this beast is transformed so |
* the .IMPSRC variable can be set correctly for the parent. */ |
* the .IMPSRC variable can be set correctly for the parent. |
|
*/ |
|
Lst_AtEnd(&sGn->iParents, tGn); |
Lst_AtEnd(&sGn->iParents, tGn); |
|
|
return(TRUE); |
return TRUE; |
} |
} |
|
|
|
|
|
|
* SuffFindArchiveDeps -- |
* SuffFindArchiveDeps -- |
* Locate dependencies for an OP_ARCHV node. |
* Locate dependencies for an OP_ARCHV node. |
* |
* |
* Results: |
|
* None |
|
* |
|
* Side Effects: |
* Side Effects: |
* Same as Suff_FindDeps |
* Same as Suff_FindDeps |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static void |
static void |
SuffFindArchiveDeps(gn, slst) |
SuffFindArchiveDeps(gn, slst) |
GNode *gn; /* Node for which to locate dependencies */ |
GNode *gn; /* Node for which to locate dependencies */ |
Lst slst; |
Lst slst; |
{ |
{ |
char *eoarch; /* End of archive portion */ |
char *eoarch; /* End of archive portion */ |
char *eoname; /* End of member portion */ |
char *eoname; /* End of member portion */ |
GNode *mem; /* Node for member */ |
GNode *mem; /* Node for member */ |
Suff *ms; /* Suffix descriptor for member */ |
Suff *ms; /* Suffix descriptor for member */ |
char *name; /* Start of member's name */ |
char *name; /* Start of member's name */ |
|
|
/* |
/* The node is an archive(member) pair. so we must find a suffix |
* The node is an archive(member) pair. so we must find a |
* for both of them. */ |
* suffix for both of them. |
eoarch = strchr(gn->name, '('); |
*/ |
if (eoarch == NULL) |
eoarch = strchr (gn->name, '('); |
|
eoname = strchr (eoarch, ')'); |
|
if (eoarch == NULL || eoname == NULL) |
|
return; |
return; |
|
|
*eoname = '\0'; /* Nuke parentheses during suffix search */ |
|
*eoarch = '\0'; /* So a suffix can be found */ |
|
|
|
name = eoarch + 1; |
name = eoarch + 1; |
|
|
/* |
eoname = strchr(name, ')'); |
* To simplify things, call Suff_FindDeps recursively on the member now, |
if (eoname == NULL) |
|
return; |
|
|
|
/* To simplify things, call Suff_FindDeps recursively on the member now, |
* so we can simply compare the member's .PREFIX and .TARGET variables |
* so we can simply compare the member's .PREFIX and .TARGET variables |
* to locate its suffix. This allows us to figure out the suffix to |
* to locate its suffix. This allows us to figure out the suffix to |
* use for the archive without having to do a quadratic search over the |
* use for the archive without having to do a quadratic search over the |
* suffix list, backtracking for each one... |
* suffix list, backtracking for each one... */ |
*/ |
mem = Targ_FindNode(name, eoname, TARG_CREATE); |
mem = Targ_FindNode(name, TARG_CREATE); |
|
SuffFindDeps(mem, slst); |
SuffFindDeps(mem, slst); |
|
|
/* |
/* Create the link between the two nodes right off. */ |
* Create the link between the two nodes right off |
if (Lst_AddNew(&gn->children, mem) == SUCCESS) { |
*/ |
|
if (Lst_Member(&gn->children, mem) == NULL) { |
|
Lst_AtEnd(&gn->children, mem); |
|
Lst_AtEnd(&mem->parents, gn); |
Lst_AtEnd(&mem->parents, gn); |
gn->unmade += 1; |
gn->unmade++; |
} |
} |
|
|
/* Copy variables from member node to this one. */ |
/* Copy variables from member node to this one. */ |
|
|
|
|
ms = mem->suffix; |
ms = mem->suffix; |
if (ms == NULL) { |
if (ms == NULL) { |
/* |
/* Didn't know what it was -- use .NULL suffix if not in make mode. */ |
* Didn't know what it was -- use .NULL suffix if not in make mode |
if (DEBUG(SUFF)) |
*/ |
|
if (DEBUG(SUFF)) { |
|
printf("using null suffix\n"); |
printf("using null suffix\n"); |
} |
|
ms = suffNull; |
ms = suffNull; |
} |
} |
|
|
|
|
/* |
/* Set the other two local variables required for this target. */ |
* Set the other two local variables required for this target. |
Varq_Set(MEMBER_INDEX, mem->name, gn); |
*/ |
|
Varq_Set(MEMBER_INDEX, name, gn); |
|
Varq_Set(ARCHIVE_INDEX, gn->name, gn); |
Varq_Set(ARCHIVE_INDEX, gn->name, gn); |
|
|
if (ms != NULL) { |
if (ms != NULL) { |
|
|
* through the entire list, we just look at suffixes to which the |
* through the entire list, we just look at suffixes to which the |
* member's suffix may be transformed... |
* member's suffix may be transformed... |
*/ |
*/ |
LstNode ln; |
LstNode ln; |
|
|
/* |
/* Use first matching suffix... */ |
* Use first matching suffix... |
ln = Lst_FindConst(&ms->parents, SuffSuffIsSuffixP, eoarch); |
*/ |
|
ln = Lst_Find(&ms->parents, SuffSuffIsSuffixP, eoarch); |
|
|
|
if (ln != NULL) { |
if (ln != NULL) { |
/* |
/* Got one -- apply it. */ |
* Got one -- apply it |
|
*/ |
|
if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && |
if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && |
DEBUG(SUFF)) |
DEBUG(SUFF)) |
{ |
|
printf("\tNo transformation from %s -> %s\n", |
printf("\tNo transformation from %s -> %s\n", |
ms->name, ((Suff *)Lst_Datum(ln))->name); |
ms->name, ((Suff *)Lst_Datum(ln))->name); |
} |
|
} |
} |
} |
} |
|
|
/* |
/* Pretend gn appeared to the left of a dependency operator so |
* Replace the opening and closing parens now we've no need of the separate |
|
* pieces. |
|
*/ |
|
*eoarch = '('; *eoname = ')'; |
|
|
|
/* |
|
* Pretend gn appeared to the left of a dependency operator so |
|
* the user needn't provide a transformation from the member to the |
* the user needn't provide a transformation from the member to the |
* archive. |
* archive. */ |
*/ |
if (OP_NOP(gn->type)) |
if (OP_NOP(gn->type)) { |
|
gn->type |= OP_DEPENDS; |
gn->type |= OP_DEPENDS; |
} |
|
|
|
/* |
/* Flag the member as such so we remember to look in the archive for |
* Flag the member as such so we remember to look in the archive for |
* its modification time. */ |
* its modification time. |
|
*/ |
|
mem->type |= OP_MEMBER; |
mem->type |= OP_MEMBER; |
} |
} |
|
|
|
|
* SuffFindNormalDeps -- |
* SuffFindNormalDeps -- |
* Locate implicit dependencies for regular targets. |
* Locate implicit dependencies for regular targets. |
* |
* |
* Results: |
|
* None. |
|
* |
|
* Side Effects: |
* Side Effects: |
* Same as Suff_FindDeps... |
* Same as Suff_FindDeps... |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static void |
static void |
SuffFindNormalDeps(gn, slst) |
SuffFindNormalDeps(gn, slst) |
GNode *gn; /* Node for which to find sources */ |
GNode *gn; /* Node for which to find sources */ |
Lst slst; |
Lst slst; |
{ |
{ |
char *eoname; /* End of name */ |
char *eoname; /* End of name */ |
char *sopref; /* Start of prefix */ |
char *sopref; /* Start of prefix */ |
LstNode ln; /* Next suffix node to check */ |
LstNode ln; /* Next suffix node to check */ |
LstNode np; |
LstNode np; |
LIST srcs; /* List of sources at which to look */ |
LIST srcs; /* List of sources at which to look */ |
LIST targs; /* List of targets to which things can be |
LIST targs; /* List of targets to which things can be |
* transformed. They all have the same file, |
* transformed. They all have the same file, |
* but different suff and pref fields */ |
* but different suff and pref fields */ |
Src *bottom; /* Start of found transformation path */ |
Src *bottom; /* Start of found transformation path */ |
Src *src; /* General Src pointer */ |
Src *src; /* General Src pointer */ |
char *pref; /* Prefix to use */ |
char *pref; /* Prefix to use */ |
Src *targ; /* General Src target pointer */ |
Src *targ; /* General Src target pointer */ |
|
|
|
|
eoname = gn->name + strlen(gn->name); |
eoname = gn->name + strlen(gn->name); |
|
|
sopref = gn->name; |
sopref = gn->name; |
|
|
/* |
/* Begin at the beginning... */ |
* Begin at the beginning... |
|
*/ |
|
ln = Lst_First(&sufflist); |
ln = Lst_First(&sufflist); |
Lst_Init(&srcs); |
Lst_Init(&srcs); |
Lst_Init(&targs); |
Lst_Init(&targs); |
|
|
/* |
/* We're caught in a catch-22 here. On the one hand, we want to use any |
* We're caught in a catch-22 here. On the one hand, we want to use any |
|
* transformation implied by the target's sources, but we can't examine |
* transformation implied by the target's sources, but we can't examine |
* the sources until we've expanded any variables/wildcards they may hold, |
* the sources until we've expanded any variables/wildcards they may hold, |
* and we can't do that until we've set up the target's local variables |
* and we can't do that until we've set up the target's local variables |
|
|
* checking transformations to all possible suffixes of the target, |
* checking transformations to all possible suffixes of the target, |
* use what we find to set the target's local variables, expand the |
* use what we find to set the target's local variables, expand the |
* children, then look for any overriding transformations they imply. |
* children, then look for any overriding transformations they imply. |
* Should we find one, we discard the one we found before. |
* Should we find one, we discard the one we found before. */ |
*/ |
|
|
|
while (ln != NULL) { |
while (ln != NULL) { |
/* |
/* Look for next possible suffix... */ |
* Look for next possible suffix... |
ln = Lst_FindFromConst(ln, SuffSuffIsSuffixP, eoname); |
*/ |
|
ln = Lst_FindFrom(ln, SuffSuffIsSuffixP, eoname); |
|
|
|
if (ln != NULL) { |
if (ln != NULL) { |
int prefLen; /* Length of the prefix */ |
int prefLen; /* Length of the prefix */ |
Src *targ; |
Src *targ; |
|
|
/* |
/* Allocate a Src structure to which things can be transformed. */ |
* Allocate a Src structure to which things can be transformed |
targ = emalloc(sizeof(Src)); |
*/ |
|
targ = (Src *)emalloc(sizeof (Src)); |
|
targ->file = estrdup(gn->name); |
targ->file = estrdup(gn->name); |
targ->suff = (Suff *)Lst_Datum(ln); |
targ->suff = (Suff *)Lst_Datum(ln); |
targ->node = gn; |
targ->node = gn; |
targ->parent = (Src *)NULL; |
targ->parent = NULL; |
targ->children = 0; |
targ->children = 0; |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
Lst_Init(&targ->cp); |
Lst_Init(&targ->cp); |
#endif |
#endif |
|
|
/* |
/* Allocate room for the prefix, whose end is found by subtracting |
* Allocate room for the prefix, whose end is found by subtracting |
* the length of the suffix from the end of the name. */ |
* the length of the suffix from the end of the name. |
|
*/ |
|
prefLen = (eoname - targ->suff->nameLen) - sopref; |
prefLen = (eoname - targ->suff->nameLen) - sopref; |
targ->pref = emalloc(prefLen + 1); |
targ->pref = emalloc(prefLen + 1); |
memcpy(targ->pref, sopref, prefLen); |
memcpy(targ->pref, sopref, prefLen); |
|
|
} |
} |
} |
} |
|
|
/* |
/* Handle target of unknown suffix... */ |
* Handle target of unknown suffix... |
|
*/ |
|
if (Lst_IsEmpty(&targs) && suffNull != NULL) { |
if (Lst_IsEmpty(&targs) && suffNull != NULL) { |
if (DEBUG(SUFF)) { |
if (DEBUG(SUFF)) { |
printf("\tNo known suffix on %s. Using .NULL suffix\n", gn->name); |
printf("\tNo known suffix on %s. Using .NULL suffix\n", gn->name); |
} |
} |
|
|
targ = (Src *)emalloc(sizeof (Src)); |
targ = emalloc(sizeof(Src)); |
targ->file = estrdup(gn->name); |
targ->file = estrdup(gn->name); |
targ->suff = suffNull; |
targ->suff = suffNull; |
targ->node = gn; |
targ->node = gn; |
targ->parent = (Src *)NULL; |
targ->parent = NULL; |
targ->children = 0; |
targ->children = 0; |
targ->pref = estrdup(sopref); |
targ->pref = estrdup(sopref); |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
Lst_Init(&targ->cp); |
Lst_Init(&targ->cp); |
#endif |
#endif |
|
|
/* |
/* Only use the default suffix rules if we don't have commands |
* Only use the default suffix rules if we don't have commands |
* or dependencies defined for this gnode. */ |
* or dependencies defined for this gnode |
|
*/ |
|
if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children)) |
if (Lst_IsEmpty(&gn->commands) && Lst_IsEmpty(&gn->children)) |
SuffAddLevel(&srcs, targ); |
SuffAddLevel(&srcs, targ); |
else { |
else { |
|
|
Lst_AtEnd(&targs, targ); |
Lst_AtEnd(&targs, targ); |
} |
} |
|
|
/* |
/* Using the list of possible sources built up from the target suffix(es), |
* Using the list of possible sources built up from the target suffix(es), |
* try and find an existing file/target that matches. */ |
* try and find an existing file/target that matches. |
|
*/ |
|
bottom = SuffFindThem(&srcs, slst); |
bottom = SuffFindThem(&srcs, slst); |
|
|
if (bottom == NULL) { |
if (bottom == NULL) { |
/* |
/* No known transformations -- use the first suffix found for setting |
* No known transformations -- use the first suffix found for setting |
* the local variables. */ |
* the local variables. |
|
*/ |
|
if (!Lst_IsEmpty(&targs)) |
if (!Lst_IsEmpty(&targs)) |
targ = (Src *)Lst_Datum(Lst_First(&targs)); |
targ = (Src *)Lst_Datum(Lst_First(&targs)); |
else |
else |
targ = NULL; |
targ = NULL; |
} else { |
} else { |
/* |
/* Work up the transformation path to find the suffix of the |
* Work up the transformation path to find the suffix of the |
* target to which the transformation was made. */ |
* target to which the transformation was made. |
|
*/ |
|
for (targ = bottom; targ->parent != NULL; targ = targ->parent) |
for (targ = bottom; targ->parent != NULL; targ = targ->parent) |
continue; |
continue; |
} |
} |
|
|
/* |
/* The .TARGET variable we always set to be the name at this point, |
* The .TARGET variable we always set to be the name at this point, |
|
* since it's only set to the path if the thing is only a source and |
* since it's only set to the path if the thing is only a source and |
* if it's only a source, it doesn't matter what we put here as far |
* if it's only a source, it doesn't matter what we put here as far |
* as expanding sources is concerned, since it has none... |
* as expanding sources is concerned, since it has none... */ |
*/ |
|
Varq_Set(TARGET_INDEX, gn->name, gn); |
Varq_Set(TARGET_INDEX, gn->name, gn); |
|
|
pref = (targ != NULL) ? targ->pref : gn->name; |
pref = targ != NULL ? targ->pref : gn->name; |
Varq_Set(PREFIX_INDEX, pref, gn); |
Varq_Set(PREFIX_INDEX, pref, gn); |
|
|
/* |
/* Now we've got the important local variables set, expand any sources |
* Now we've got the important local variables set, expand any sources |
* that still contain variables or wildcards in their names. */ |
* that still contain variables or wildcards in their names. |
|
*/ |
|
for (ln = Lst_First(&gn->children); ln != NULL; ln = np) { |
for (ln = Lst_First(&gn->children); ln != NULL; ln = np) { |
np = Lst_Adv(ln); |
np = Lst_Adv(ln); |
SuffExpandChildren(Lst_Datum(ln), gn); |
SuffExpandChildren(Lst_Datum(ln), gn); |
} |
} |
|
|
if (targ == NULL) { |
if (targ == NULL) { |
if (DEBUG(SUFF)) { |
if (DEBUG(SUFF)) |
printf("\tNo valid suffix on %s\n", gn->name); |
printf("\tNo valid suffix on %s\n", gn->name); |
} |
|
|
|
sfnd_abort: |
sfnd_abort: |
/* |
/* Deal with finding the thing on the default search path if the |
* Deal with finding the thing on the default search path if the |
|
* node is only a source (not on the lhs of a dependency operator |
* node is only a source (not on the lhs of a dependency operator |
* or [XXX] it has neither children or commands). |
* or [XXX] it has neither children or commands). */ |
*/ |
|
if (OP_NOP(gn->type) || |
if (OP_NOP(gn->type) || |
(Lst_IsEmpty(&gn->children) && Lst_IsEmpty(&gn->commands))) |
(Lst_IsEmpty(&gn->children) && Lst_IsEmpty(&gn->commands))) |
{ |
{ |
|
|
Varq_Set(TARGET_INDEX, gn->path, gn); |
Varq_Set(TARGET_INDEX, gn->path, gn); |
|
|
if (targ != NULL) { |
if (targ != NULL) { |
/* |
/* Suffix known for the thing -- trim the suffix off |
* Suffix known for the thing -- trim the suffix off |
* the path to form the proper .PREFIX variable. */ |
* the path to form the proper .PREFIX variable. |
int savep = strlen(gn->path) - targ->suff->nameLen; |
*/ |
|
int savep = strlen(gn->path) - targ->suff->nameLen; |
|
char savec; |
char savec; |
|
|
gn->suffix = targ->suff; |
gn->suffix = targ->suff; |
|
|
|
|
gn->path[savep] = savec; |
gn->path[savep] = savec; |
} else { |
} else { |
/* |
/* The .PREFIX gets the full path if the target has |
* The .PREFIX gets the full path if the target has |
* no known suffix. */ |
* no known suffix. |
|
*/ |
|
gn->suffix = NULL; |
gn->suffix = NULL; |
|
|
if ((ptr = strrchr(gn->path, '/')) != NULL) |
if ((ptr = strrchr(gn->path, '/')) != NULL) |
|
|
} |
} |
} |
} |
} else { |
} else { |
/* |
/* Not appropriate to search for the thing -- set the |
* Not appropriate to search for the thing -- set the |
|
* path to be the name so Dir_MTime won't go grovelling for |
* path to be the name so Dir_MTime won't go grovelling for |
* it. |
* it. */ |
*/ |
gn->suffix = targ == NULL ? NULL : targ->suff; |
gn->suffix = (targ == NULL) ? NULL : targ->suff; |
|
efree(gn->path); |
efree(gn->path); |
gn->path = estrdup(gn->name); |
gn->path = estrdup(gn->name); |
} |
} |
|
|
goto sfnd_return; |
goto sfnd_return; |
} |
} |
|
|
/* |
/* If the suffix indicates that the target is a library, mark that in |
* If the suffix indicates that the target is a library, mark that in |
* the node's type field. */ |
* the node's type field. |
|
*/ |
|
if (targ->suff->flags & SUFF_LIBRARY) { |
if (targ->suff->flags & SUFF_LIBRARY) { |
gn->type |= OP_LIB; |
gn->type |= OP_LIB; |
} |
} |
|
|
/* |
/* Check for overriding transformation rule implied by sources. */ |
* Check for overriding transformation rule implied by sources |
|
*/ |
|
if (!Lst_IsEmpty(&gn->children)) { |
if (!Lst_IsEmpty(&gn->children)) { |
src = SuffFindCmds(targ, slst); |
src = SuffFindCmds(targ, slst); |
|
|
if (src != (Src *)NULL) { |
if (src != NULL) { |
/* |
/* Free up all the Src structures in the transformation path |
* Free up all the Src structures in the transformation path |
* up to, but not including, the parent node. */ |
* up to, but not including, the parent node. |
|
*/ |
|
while (bottom && bottom->parent != NULL) { |
while (bottom && bottom->parent != NULL) { |
if (Lst_Member(slst, bottom) == NULL) { |
(void)Lst_AddNew(slst, bottom); |
Lst_AtEnd(slst, bottom); |
|
} |
|
bottom = bottom->parent; |
bottom = bottom->parent; |
} |
} |
bottom = src; |
bottom = src; |
|
|
} |
} |
|
|
if (bottom == NULL) { |
if (bottom == NULL) { |
/* |
/* No idea from where it can come -- return now. */ |
* No idea from where it can come -- return now. |
|
*/ |
|
goto sfnd_abort; |
goto sfnd_abort; |
} |
} |
|
|
/* |
/* We now have a list of Src structures headed by 'bottom' and linked via |
* We now have a list of Src structures headed by 'bottom' and linked via |
|
* their 'parent' pointers. What we do next is create links between |
* their 'parent' pointers. What we do next is create links between |
* source and target nodes (which may or may not have been created) |
* source and target nodes (which may or may not have been created) |
* and set the necessary local variables in each target. The |
* and set the necessary local variables in each target. The |
|
|
* suffix. Note that this causes the commands list of the original |
* suffix. Note that this causes the commands list of the original |
* node, gn, to be replaced by the commands of the final |
* node, gn, to be replaced by the commands of the final |
* transformation rule. Also, the unmade field of gn is incremented. |
* transformation rule. Also, the unmade field of gn is incremented. |
* Etc. |
* Etc. */ |
*/ |
|
if (bottom->node == NULL) { |
if (bottom->node == NULL) { |
bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); |
bottom->node = Targ_FindNode(bottom->file, NULL, TARG_CREATE); |
} |
} |
|
|
for (src = bottom; src->parent != (Src *)NULL; src = src->parent) { |
for (src = bottom; src->parent != NULL; src = src->parent) { |
targ = src->parent; |
targ = src->parent; |
|
|
src->node->suffix = src->suff; |
src->node->suffix = src->suff; |
|
|
if (targ->node == NULL) { |
if (targ->node == NULL) { |
targ->node = Targ_FindNode(targ->file, TARG_CREATE); |
targ->node = Targ_FindNode(targ->file, NULL, TARG_CREATE); |
} |
} |
|
|
SuffApplyTransform(targ->node, src->node, |
SuffApplyTransform(targ->node, src->node, |
targ->suff, src->suff); |
targ->suff, src->suff); |
|
|
if (targ->node != gn) { |
if (targ->node != gn) { |
/* |
/* Finish off the dependency-search process for any nodes |
* Finish off the dependency-search process for any nodes |
|
* between bottom and gn (no point in questing around the |
* between bottom and gn (no point in questing around the |
* filesystem for their implicit source when it's already |
* filesystem for their implicit source when it's already |
* known). Note that the node can't have any sources that |
* known). Note that the node can't have any sources that |
* need expanding, since SuffFindThem will stop on an existing |
* need expanding, since SuffFindThem will stop on an existing |
* node, so all we need to do is set the standard and System V |
* node, so all we need to do is set the standard and System V |
* variables. |
* variables. */ |
*/ |
|
targ->node->type |= OP_DEPS_FOUND; |
targ->node->type |= OP_DEPS_FOUND; |
|
|
Varq_Set(PREFIX_INDEX, targ->pref, targ->node); |
Varq_Set(PREFIX_INDEX, targ->pref, targ->node); |
|
|
|
|
gn->suffix = src->suff; |
gn->suffix = src->suff; |
|
|
/* |
/* So Dir_MTime doesn't go questing for it... */ |
* So Dir_MTime doesn't go questing for it... |
|
*/ |
|
efree(gn->path); |
efree(gn->path); |
gn->path = estrdup(gn->name); |
gn->path = estrdup(gn->name); |
|
|
/* |
/* Nuke the transformation path and the Src structures left over in the |
* Nuke the transformation path and the Src structures left over in the |
* two lists. */ |
* two lists. |
|
*/ |
|
sfnd_return: |
sfnd_return: |
if (bottom) |
if (bottom) |
if (Lst_Member(slst, bottom) == NULL) |
(void)Lst_AddNew(slst, bottom); |
Lst_AtEnd(slst, bottom); |
|
|
|
while (SuffRemoveSrc(&srcs) || SuffRemoveSrc(&targs)) |
while (SuffRemoveSrc(&srcs) || SuffRemoveSrc(&targs)) |
continue; |
continue; |
|
|
* Find implicit sources for the target described by the graph node |
* Find implicit sources for the target described by the graph node |
* gn |
* gn |
* |
* |
* Results: |
|
* Nothing. |
|
* |
|
* Side Effects: |
* Side Effects: |
* Nodes are added to the graph below the passed-in node. The nodes |
* Nodes are added to the graph below the passed-in node. The nodes |
* are marked to have their IMPSRC variable filled in. The |
* are marked to have their IMPSRC variable filled in. The |
|
|
* the .c and .l files don't, the search will branch out in |
* the .c and .l files don't, the search will branch out in |
* all directions from .o and again from all the nodes on the |
* all directions from .o and again from all the nodes on the |
* next level until the .l,v node is encountered. |
* next level until the .l,v node is encountered. |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
|
|
|
|
|
|
|
|
static void |
static void |
SuffFindDeps (gn, slst) |
SuffFindDeps(gn, slst) |
GNode *gn; /* node we're dealing with */ |
GNode *gn; /* node we're dealing with */ |
Lst slst; |
Lst slst; |
{ |
{ |
if (gn->type & OP_DEPS_FOUND) { |
if (gn->type & OP_DEPS_FOUND) { |
/* |
/* |
|
|
} |
} |
|
|
if (DEBUG(SUFF)) { |
if (DEBUG(SUFF)) { |
printf ("SuffFindDeps (%s)\n", gn->name); |
printf("SuffFindDeps (%s)\n", gn->name); |
} |
} |
|
|
if (gn->type & OP_ARCHV) { |
if (gn->type & OP_ARCHV) { |
|
|
* set the TARGET variable to the node's name in order to give it a |
* set the TARGET variable to the node's name in order to give it a |
* value). |
* value). |
*/ |
*/ |
LstNode ln; |
LstNode ln; |
Suff *s; |
Suff *s; |
|
|
ln = Lst_Find(&sufflist, SuffSuffHasNameP, LIBSUFF); |
ln = Lst_FindConst(&sufflist, SuffSuffHasNameP, LIBSUFF); |
if (ln != NULL) { |
if (ln != NULL) { |
gn->suffix = s = (Suff *)Lst_Datum(ln); |
gn->suffix = s = (Suff *)Lst_Datum(ln); |
Arch_FindLib(gn, &s->searchPath); |
Arch_FindLib(gn, &s->searchPath); |
|
|
* the thing. .PREFIX is simply made empty... |
* the thing. .PREFIX is simply made empty... |
*/ |
*/ |
Varq_Set(PREFIX_INDEX, "", gn); |
Varq_Set(PREFIX_INDEX, "", gn); |
} else { |
} else |
SuffFindNormalDeps(gn, slst); |
SuffFindNormalDeps(gn, slst); |
} |
|
} |
} |
|
|
/*- |
/*- |
|
|
* Suff_SetNull -- |
* Suff_SetNull -- |
* Define which suffix is the null suffix. |
* Define which suffix is the null suffix. |
* |
* |
* Results: |
|
* None. |
|
* |
|
* Side Effects: |
* Side Effects: |
* 'suffNull' is altered. |
* 'suffNull' is altered. |
* |
* |
* Notes: |
* Notes: |
* Need to handle the changing of the null suffix gracefully so the |
* Need to handle the changing of the null suffix gracefully so the |
* old transformation rules don't just go away. |
* old transformation rules don't just go away. |
* |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
|
|
Suff *s; |
Suff *s; |
LstNode ln; |
LstNode ln; |
|
|
ln = Lst_Find(&sufflist, SuffSuffHasNameP, name); |
ln = Lst_FindConst(&sufflist, SuffSuffHasNameP, name); |
if (ln != NULL) { |
if (ln != NULL) { |
s = (Suff *)Lst_Datum(ln); |
s = (Suff *)Lst_Datum(ln); |
if (suffNull != (Suff *)NULL) { |
if (suffNull != NULL) { |
suffNull->flags &= ~SUFF_NULL; |
suffNull->flags &= ~SUFF_NULL; |
} |
} |
s->flags |= SUFF_NULL; |
s->flags |= SUFF_NULL; |
|
|
*/ |
*/ |
suffNull = s; |
suffNull = s; |
} else { |
} else { |
Parse_Error (PARSE_WARNING, "Desired null suffix %s not defined.", |
Parse_Error(PARSE_WARNING, "Desired null suffix %s not defined.", |
name); |
name); |
} |
} |
} |
} |
|
|
* Suff_Init -- |
* Suff_Init -- |
* Initialize suffixes module |
* Initialize suffixes module |
* |
* |
* Results: |
|
* None |
|
* |
|
* Side Effects: |
* Side Effects: |
* Many |
* Many |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
void |
void |
Suff_Init () |
Suff_Init() |
{ |
{ |
Lst_Init(&sufflist); |
Lst_Init(&sufflist); |
#ifdef CLEANUP |
#ifdef CLEANUP |
|
|
* actually go on the suffix list or everyone will think that's its |
* actually go on the suffix list or everyone will think that's its |
* suffix. |
* suffix. |
*/ |
*/ |
emptySuff = suffNull = (Suff *) emalloc (sizeof (Suff)); |
emptySuff = suffNull = emalloc(sizeof(Suff)); |
|
|
suffNull->name = estrdup (""); |
suffNull->name = estrdup(""); |
suffNull->nameLen = 0; |
suffNull->nameLen = 0; |
Lst_Init(&suffNull->searchPath); |
Lst_Init(&suffNull->searchPath); |
Dir_Concat(&suffNull->searchPath, &dirSearchPath); |
Dir_Concat(&suffNull->searchPath, &dirSearchPath); |
Lst_Init(&suffNull->children); |
Lst_Init(&suffNull->children); |
Lst_Init(&suffNull->parents); |
Lst_Init(&suffNull->parents); |
Lst_Init(&suffNull->ref); |
Lst_Init(&suffNull->ref); |
suffNull->sNum = sNum++; |
suffNull->sNum = sNum++; |
suffNull->flags = SUFF_NULL; |
suffNull->flags = SUFF_NULL; |
|
|
} |
} |
|
|
|
|
* Suff_End -- |
* Suff_End -- |
* Cleanup the this module |
* Cleanup the this module |
* |
* |
* Results: |
|
* None |
|
* |
|
* Side Effects: |
* Side Effects: |
* The memory is free'd. |
* The memory is free'd. |
*---------------------------------------------------------------------- |
*---------------------------------------------------------------------- |
|
|
void *sp; |
void *sp; |
{ |
{ |
Suff *s = (Suff *)sp; |
Suff *s = (Suff *)sp; |
int flags; |
int flags; |
int flag; |
int flag; |
|
|
printf("# `%s' ", s->name); |
printf("# `%s' ", s->name); |
|
|
|
|
fputc(flags ? '|' : ')', stdout); |
fputc(flags ? '|' : ')', stdout); |
} |
} |
} |
} |
printf("\n#\tTo: "); |
fputc('\n', stdout); |
|
printf("#\tTo: "); |
Lst_Every(&s->parents, SuffPrintName); |
Lst_Every(&s->parents, SuffPrintName); |
printf("\n#\tFrom: "); |
fputc('\n', stdout); |
|
printf("#\tFrom: "); |
Lst_Every(&s->children, SuffPrintName); |
Lst_Every(&s->children, SuffPrintName); |
printf("\n#\tSearch Path: "); |
fputc('\n', stdout); |
|
printf("#\tSearch Path: "); |
Dir_PrintPath(&s->searchPath); |
Dir_PrintPath(&s->searchPath); |
fputc('\n', stdout); |
fputc('\n', stdout); |
} |
} |