version 1.29, 2000/06/17 14:38:19 |
version 1.30, 2000/06/17 14:43:36 |
|
|
#include "hash.h" |
#include "hash.h" |
#include "dir.h" |
#include "dir.h" |
|
|
static Lst 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 |
|
|
#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 */ |
Lst 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 */ |
|
|
static int SuffSuffHasNameP __P((void *, void *)); |
static int SuffSuffHasNameP __P((void *, void *)); |
static int SuffSuffIsPrefix __P((void *, void *)); |
static int SuffSuffIsPrefix __P((void *, void *)); |
static int SuffGNHasNameP __P((void *, void *)); |
static int SuffGNHasNameP __P((void *, void *)); |
static void SuffUnRef __P((void *, void *)); |
static void SuffUnRef __P((Lst, Suff *)); |
static void SuffFree __P((void *)); |
static void SuffFree __P((void *)); |
static void SuffInsert __P((Lst, Suff *)); |
static void SuffInsert __P((Lst, Suff *)); |
static void SuffRemove __P((Lst, Suff *)); |
static void SuffRemove __P((Lst, Suff *)); |
|
|
/*********** Maintenance Functions ************/ |
/*********** Maintenance Functions ************/ |
|
|
static void |
static void |
SuffUnRef(lp, sp) |
SuffUnRef(l, s) |
void *lp; |
Lst l; |
void *sp; |
Suff *s; |
{ |
{ |
Lst l = (Lst) lp; |
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); |
} |
} |
|
|
Lst_Destroy(&s->ref, NOFREE); |
Lst_Destroy(&s->ref, NOFREE); |
Lst_Destroy(&s->children, NOFREE); |
Lst_Destroy(&s->children, NOFREE); |
Lst_Destroy(&s->parents, NOFREE); |
Lst_Destroy(&s->parents, NOFREE); |
Lst_Delete(s->searchPath, Dir_Destroy); |
Lst_Destroy(&s->searchPath, Dir_Destroy); |
|
|
free(s->name); |
free(s->name); |
free(s); |
free(s); |
|
|
Suff_ClearSuffixes () |
Suff_ClearSuffixes () |
{ |
{ |
#ifdef CLEANUP |
#ifdef CLEANUP |
Lst_Concat(&suffClean, sufflist, LST_CONCLINK); |
Lst_ConcatDestroy(&suffClean, &sufflist); |
#endif |
#endif |
sufflist = Lst_New(); |
Lst_Init(&sufflist); |
sNum = 0; |
sNum = 0; |
suffNull = emptySuff; |
suffNull = emptySuff; |
} |
} |
|
|
*/ |
*/ |
for (;;) { |
for (;;) { |
if (srcLn == NULL) { |
if (srcLn == NULL) { |
srcLn = Lst_Find(sufflist, SuffSuffIsPrefix, str); |
srcLn = Lst_Find(&sufflist, SuffSuffIsPrefix, str); |
} else { |
} else { |
srcLn = Lst_FindFrom(Lst_Succ(srcLn), |
srcLn = Lst_FindFrom(Lst_Succ(srcLn), |
SuffSuffIsPrefix, str); |
SuffSuffIsPrefix, str); |
|
|
single = src; |
single = src; |
singleLn = srcLn; |
singleLn = srcLn; |
} else { |
} else { |
targLn = Lst_Find(sufflist, SuffSuffHasNameP, str2); |
targLn = Lst_Find(&sufflist, SuffSuffHasNameP, str2); |
if (targLn != NULL) { |
if (targLn != NULL) { |
*srcPtr = src; |
*srcPtr = src; |
*targPtr = (Suff *)Lst_Datum(targLn); |
*targPtr = (Suff *)Lst_Datum(targLn); |
|
|
*/ |
*/ |
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_Find(&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 |
|
|
* Null-terminate the source suffix in order to find it. |
* Null-terminate the source suffix in order to find it. |
*/ |
*/ |
cp[1] = '\0'; |
cp[1] = '\0'; |
ln = Lst_Find(sufflist, SuffSuffHasNameP, transform->name); |
ln = Lst_Find(&sufflist, SuffSuffHasNameP, transform->name); |
/* |
/* |
* Replace the start of the target suffix |
* Replace the start of the target suffix |
*/ |
*/ |
|
|
Suff *s; /* new suffix descriptor */ |
Suff *s; /* new suffix descriptor */ |
LstNode ln; |
LstNode ln; |
|
|
ln = Lst_Find(sufflist, SuffSuffHasNameP, str); |
ln = Lst_Find(&sufflist, SuffSuffHasNameP, str); |
if (ln == NULL) { |
if (ln == NULL) { |
s = (Suff *) emalloc (sizeof (Suff)); |
s = (Suff *) emalloc (sizeof (Suff)); |
|
|
s->name = estrdup (str); |
s->name = estrdup(str); |
s->nameLen = strlen (s->name); |
s->nameLen = strlen(s->name); |
s->searchPath = Lst_New(); |
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); |
/* |
/* |
* Look for any existing transformations from or to this suffix. |
* Look for any existing transformations from or to this suffix. |
* XXX: Only do this after a Suff_ClearSuffixes? |
* XXX: Only do this after a Suff_ClearSuffixes? |
|
|
* Results: |
* Results: |
* The searchPath for the desired suffix or NULL if the suffix isn't |
* The searchPath for the desired suffix or NULL if the suffix isn't |
* defined. |
* defined. |
* |
|
* Side Effects: |
|
* None |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
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_Find(&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; |
} |
} |
} |
} |
|
|
|
|
LIST inIncludes; /* Cumulative .INCLUDES path */ |
LIST inIncludes; /* Cumulative .INCLUDES path */ |
LIST inLibs; /* Cumulative .LIBS path */ |
LIST inLibs; /* Cumulative .LIBS path */ |
|
|
if (Lst_Open (sufflist) == FAILURE) { |
if (Lst_Open(&sufflist) == FAILURE) |
return; |
return; |
} |
|
|
|
Lst_Init(&inIncludes); |
Lst_Init(&inIncludes); |
Lst_Init(&inLibs); |
Lst_Init(&inLibs); |
|
|
while ((ln = Lst_Next (sufflist)) != NULL) { |
while ((ln = Lst_Next(&sufflist)) != NULL) { |
s = (Suff *) Lst_Datum (ln); |
s = (Suff *) Lst_Datum (ln); |
if (!Lst_IsEmpty (s->searchPath)) { |
if (!Lst_IsEmpty(&s->searchPath)) { |
#ifdef INCLUDES |
#ifdef INCLUDES |
if (s->flags & SUFF_INCLUDE) { |
if (s->flags & SUFF_INCLUDE) { |
Dir_Concat(&inIncludes, s->searchPath); |
Dir_Concat(&inIncludes, &s->searchPath); |
} |
} |
#endif /* INCLUDES */ |
#endif /* INCLUDES */ |
#ifdef LIBRARIES |
#ifdef LIBRARIES |
if (s->flags & SUFF_LIBRARY) { |
if (s->flags & SUFF_LIBRARY) { |
Dir_Concat(&inLibs, s->searchPath); |
Dir_Concat(&inLibs, &s->searchPath); |
} |
} |
#endif /* LIBRARIES */ |
#endif /* LIBRARIES */ |
Dir_Concat(s->searchPath, &dirSearchPath); |
Dir_Concat(&s->searchPath, &dirSearchPath); |
} else { |
} else { |
Lst_Delete(s->searchPath, Dir_Destroy); |
Lst_Destroy(&s->searchPath, Dir_Destroy); |
s->searchPath = Lst_Duplicate(&dirSearchPath, Dir_CopyDir); |
Lst_Clone(&s->searchPath, &dirSearchPath, Dir_CopyDir); |
} |
} |
} |
} |
|
|
|
|
Lst_Destroy(&inIncludes, Dir_Destroy); |
Lst_Destroy(&inIncludes, Dir_Destroy); |
Lst_Destroy(&inLibs, Dir_Destroy); |
Lst_Destroy(&inLibs, Dir_Destroy); |
|
|
Lst_Close (sufflist); |
Lst_Close(&sufflist); |
} |
} |
|
|
/*- |
/*- |
|
|
LstNode ln; |
LstNode ln; |
Suff *s; |
Suff *s; |
|
|
ln = Lst_Find(sufflist, SuffSuffHasNameP, sname); |
ln = Lst_Find(&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; |
|
|
LstNode ln; |
LstNode ln; |
Suff *s; |
Suff *s; |
|
|
ln = Lst_Find(sufflist, SuffSuffHasNameP, sname); |
ln = Lst_Find(&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; |
|
|
break; |
break; |
} |
} |
|
|
if ((ptr = Dir_FindFile (s->file, s->suff->searchPath)) != NULL) { |
if ((ptr = Dir_FindFile(s->file, &s->suff->searchPath)) != NULL) { |
rs = s; |
rs = s; |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
printf("remove %x from %x\n", s, srcs); |
printf("remove %x from %x\n", s, srcs); |
|
|
* 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. |
*/ |
*/ |
ln = Lst_Find(sufflist, SuffSuffHasNameP, &cp[prefLen]); |
ln = Lst_Find(&sufflist, SuffSuffHasNameP, &cp[prefLen]); |
if (ln != 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 |
|
|
* Else use the default system search path. |
* Else use the default system search path. |
*/ |
*/ |
cp = cgn->name + strlen(cgn->name); |
cp = cgn->name + strlen(cgn->name); |
ln = Lst_Find(sufflist, SuffSuffIsSuffixP, cp); |
ln = Lst_Find(&sufflist, SuffSuffIsSuffixP, cp); |
|
|
if (DEBUG(SUFF)) |
if (DEBUG(SUFF)) |
printf("Wildcard expanding \"%s\"...", cgn->name); |
printf("Wildcard expanding \"%s\"...", cgn->name); |
|
|
|
|
if (DEBUG(SUFF)) |
if (DEBUG(SUFF)) |
printf("suffix is \"%s\"...", s->name); |
printf("suffix is \"%s\"...", s->name); |
path = s->searchPath; |
path = &s->searchPath; |
} else { |
} else { |
/* |
/* |
* Use default search path |
* Use default search path |
|
|
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 */ |
Lst srcs; /* List of sources at which to look */ |
LIST srcs; /* List of sources at which to look */ |
Lst 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 */ |
|
|
/* |
/* |
* Begin at the beginning... |
* Begin at the beginning... |
*/ |
*/ |
ln = Lst_First(sufflist); |
ln = Lst_First(&sufflist); |
srcs = Lst_New(); |
Lst_Init(&srcs); |
targs = Lst_New(); |
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 |
|
|
memcpy(targ->pref, sopref, prefLen); |
memcpy(targ->pref, sopref, prefLen); |
targ->pref[prefLen] = '\0'; |
targ->pref[prefLen] = '\0'; |
|
|
/* |
/* Add nodes from which the target can be made. */ |
* Add nodes from which the target can be made |
SuffAddLevel(&srcs, targ); |
*/ |
|
SuffAddLevel(srcs, targ); |
|
|
|
/* |
/* Record the target so we can nuke it. */ |
* Record the target so we can nuke it |
Lst_AtEnd(&targs, targ); |
*/ |
|
Lst_AtEnd(targs, targ); |
|
|
|
/* |
/* Search from this suffix's successor... */ |
* Search from this suffix's successor... |
|
*/ |
|
ln = Lst_Succ(ln); |
ln = Lst_Succ(ln); |
} |
} |
} |
} |
|
|
/* |
/* |
* 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); |
} |
} |
|
|
* 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 { |
if (DEBUG(SUFF)) |
if (DEBUG(SUFF)) |
printf("not "); |
printf("not "); |
|
|
if (DEBUG(SUFF)) |
if (DEBUG(SUFF)) |
printf("adding suffix rules\n"); |
printf("adding suffix rules\n"); |
|
|
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 == (Src *)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 = (Src *)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 |
|
|
{ |
{ |
gn->path = Dir_FindFile(gn->name, |
gn->path = Dir_FindFile(gn->name, |
(targ == NULL ? &dirSearchPath : |
(targ == NULL ? &dirSearchPath : |
targ->suff->searchPath)); |
&targ->suff->searchPath)); |
if (gn->path != NULL) { |
if (gn->path != NULL) { |
char *ptr; |
char *ptr; |
Var_Set(TARGET, gn->path, gn); |
Var_Set(TARGET, gn->path, gn); |
|
|
if (Lst_Member(slst, bottom) == NULL) |
if (Lst_Member(slst, bottom) == NULL) |
Lst_AtEnd(slst, bottom); |
Lst_AtEnd(slst, bottom); |
|
|
while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs)) |
while (SuffRemoveSrc(&srcs) || SuffRemoveSrc(&targs)) |
continue; |
continue; |
|
|
Lst_Concat(slst, srcs, LST_CONCLINK); |
Lst_ConcatDestroy(slst, &srcs); |
Lst_Concat(slst, targs, LST_CONCLINK); |
Lst_ConcatDestroy(slst, &targs); |
} |
} |
|
|
|
|
|
|
LstNode ln; |
LstNode ln; |
Suff *s; |
Suff *s; |
|
|
ln = Lst_Find(sufflist, SuffSuffHasNameP, LIBSUFF); |
ln = Lst_Find(&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); |
} else { |
} else { |
gn->suffix = NULL; |
gn->suffix = NULL; |
Var_Set (TARGET, gn->name, gn); |
Var_Set (TARGET, gn->name, gn); |
|
|
Suff *s; |
Suff *s; |
LstNode ln; |
LstNode ln; |
|
|
ln = Lst_Find(sufflist, SuffSuffHasNameP, name); |
ln = Lst_Find(&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 != (Suff *)NULL) { |
|
|
void |
void |
Suff_Init () |
Suff_Init () |
{ |
{ |
sufflist = Lst_New(); |
Lst_Init(&sufflist); |
#ifdef CLEANUP |
#ifdef CLEANUP |
Lst_Init(&suffClean); |
Lst_Init(&suffClean); |
#endif |
#endif |
|
|
|
|
suffNull->name = estrdup (""); |
suffNull->name = estrdup (""); |
suffNull->nameLen = 0; |
suffNull->nameLen = 0; |
suffNull->searchPath = Lst_New(); |
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); |
|
|
Suff_End() |
Suff_End() |
{ |
{ |
#ifdef CLEANUP |
#ifdef CLEANUP |
Lst_Delete(sufflist, SuffFree); |
Lst_Destroy(&sufflist, SuffFree); |
Lst_Destroy(&suffClean, SuffFree); |
Lst_Destroy(&suffClean, SuffFree); |
if (suffNull) |
if (suffNull) |
SuffFree(suffNull); |
SuffFree(suffNull); |
|
|
printf("\n#\tFrom: "); |
printf("\n#\tFrom: "); |
Lst_Every(&s->children, SuffPrintName); |
Lst_Every(&s->children, SuffPrintName); |
printf("\n#\tSearch Path: "); |
printf("\n#\tSearch Path: "); |
Dir_PrintPath(s->searchPath); |
Dir_PrintPath(&s->searchPath); |
fputc('\n', stdout); |
fputc('\n', stdout); |
} |
} |
|
|
|
|
Suff_PrintAll() |
Suff_PrintAll() |
{ |
{ |
printf("#*** Suffixes:\n"); |
printf("#*** Suffixes:\n"); |
Lst_Every(sufflist, SuffPrintSuff); |
Lst_Every(&sufflist, SuffPrintSuff); |
|
|
printf("#*** Transformations:\n"); |
printf("#*** Transformations:\n"); |
Lst_Every(&transforms, SuffPrintTrans); |
Lst_Every(&transforms, SuffPrintTrans); |