version 1.41, 2001/05/03 13:41:11 |
version 1.42, 2001/05/23 12:34:49 |
|
|
* 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. |
|
|
* if the target had no implicit sources. |
* if the target had no implicit sources. |
*/ |
*/ |
|
|
#include <stddef.h> |
#include <ctype.h> |
#include <stdio.h> |
#include <stdio.h> |
#include "make.h" |
#include <string.h> |
#include "ohash.h" |
#include "config.h" |
#include "dir.h" |
#include "defines.h" |
|
#include "dir.h" |
|
#include "arch.h" |
|
#include "suff.h" |
|
#include "var.h" |
|
#include "targ.h" |
|
#include "error.h" |
|
#include "str.h" |
|
#include "lst.h" |
|
#include "memory.h" |
|
#include "gnode.h" |
|
#include "make.h" |
|
|
#ifndef lint |
|
#if 0 |
|
static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94"; |
|
#else |
|
UNUSED |
|
static char rcsid[] = "$OpenBSD$"; |
|
#endif |
|
#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 */ |
|
|
static void SuffFree(void *); |
static void SuffFree(void *); |
#endif |
#endif |
static void SuffInsert(Lst, Suff *); |
static void SuffInsert(Lst, Suff *); |
static Boolean SuffParseTransform(const char *, Suff **, Suff **); |
static bool SuffParseTransform(const char *, Suff **, Suff **); |
static void SuffRebuildGraph(void *, void *); |
static void SuffRebuildGraph(void *, void *); |
static void SuffAddSrc(void *, void *); |
static void SuffAddSrc(void *, void *); |
static int SuffRemoveSrc(Lst); |
static int SuffRemoveSrc(Lst); |
|
|
static void SuffExpandChildren(void *, void *); |
static void SuffExpandChildren(void *, void *); |
static void SuffExpandVarChildren(LstNode, GNode *, GNode *); |
static void SuffExpandVarChildren(LstNode, GNode *, GNode *); |
static void SuffExpandWildChildren(LstNode, GNode *, GNode *); |
static void SuffExpandWildChildren(LstNode, GNode *, GNode *); |
static Boolean SuffApplyTransform(GNode *, GNode *, Suff *, Suff *); |
static bool SuffApplyTransform(GNode *, GNode *, Suff *, Suff *); |
static void SuffFindDeps(GNode *, Lst); |
static void SuffFindDeps(GNode *, Lst); |
static void SuffFindArchiveDeps(GNode *, Lst); |
static void SuffFindArchiveDeps(GNode *, Lst); |
static void SuffFindNormalDeps(GNode *, Lst); |
static void SuffFindNormalDeps(GNode *, Lst); |
|
|
static void SuffPrintSuff(void *); |
static void SuffPrintSuff(void *); |
static void SuffPrintTrans(void *); |
static void SuffPrintTrans(void *); |
|
|
|
#ifdef DEBUG_SRC |
|
static void PrintAddr(void *); |
|
#endif |
/*************** Lst Predicates ****************/ |
/*************** Lst Predicates ****************/ |
/*- |
/*- |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
|
|
* Parse a transformation string to find its two component suffixes. |
* Parse a transformation string to find its two component suffixes. |
* |
* |
* Results: |
* Results: |
* TRUE if the string is a valid transformation and FALSE otherwise. |
* true if the string is a valid transformation and false otherwise. |
* |
* |
* Side Effects: |
* Side Effects: |
* The passed pointers are overwritten. |
* The passed pointers are overwritten. |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Boolean |
static bool |
SuffParseTransform(str, srcPtr, targPtr) |
SuffParseTransform(str, srcPtr, targPtr) |
const 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. */ |
|
|
*/ |
*/ |
*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; |
|
|
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 |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
Boolean |
bool |
Suff_IsTransform(str) |
Suff_IsTransform(str) |
const char *str; /* string to check */ |
const char *str; /* string to check */ |
{ |
{ |
|
|
* 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 |
* by the Parse module. |
* by the Parse module. |
*/ |
*/ |
gn = Targ_NewGN(line, NULL); |
gn = Targ_NewGN(line); |
Lst_AtEnd(&transforms, gn); |
Lst_AtEnd(&transforms, gn); |
} else { |
} else { |
/* |
/* |
|
|
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_Destroy(&s->searchPath, Dir_Destroy); |
Lst_Clone(&s->searchPath, dirSearchPath, Dir_CopyDir); |
Lst_Clone(&s->searchPath, &dirSearchPath, Dir_CopyDir); |
|
} |
|
} |
} |
|
|
Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", &inIncludes), VAR_GLOBAL); |
Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", &inIncludes), VAR_GLOBAL); |
|
|
#endif |
#endif |
} |
} |
s2 = 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; |
|
|
Lst_Remove(l, ln); |
Lst_Remove(l, ln); |
free(s); |
free(s); |
t |= 1; |
t |= 1; |
return TRUE; |
return true; |
} |
} |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
else { |
else { |
|
|
* 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, NULL, TARG_NOCREATE) != NULL) { |
if (Targ_FindNode(s->file, 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("Expanding \"%s\"...", cgn->name); |
printf("Expanding \"%s\"...", cgn->name); |
|
|
cp = Var_Subst(cgn->name, &pgn->context, TRUE); |
cp = Var_Subst(cgn->name, &pgn->context, true); |
if (cp == NULL) { |
if (cp == NULL) { |
printf("Problem substituting in %s", cgn->name); |
printf("Problem substituting in %s", cgn->name); |
printf("\n"); |
printf("\n"); |
|
|
if (isspace(*cp2)) { |
if (isspace(*cp2)) { |
/* White-space -- terminate element, find the node, |
/* White-space -- terminate element, find the node, |
* add it, skip any further spaces. */ |
* add it, skip any further spaces. */ |
gn = Targ_FindNode(start, cp2, TARG_CREATE); |
gn = Targ_FindNodei(start, cp2, TARG_CREATE); |
cp2++; |
cp2++; |
Lst_AtEnd(&members, gn); |
Lst_AtEnd(&members, gn); |
while (isspace(*cp2)) |
while (isspace(*cp2)) |
|
|
|
|
if (cp2 != start) { |
if (cp2 != start) { |
/* Stuff left over -- add it to the list too. */ |
/* Stuff left over -- add it to the list too. */ |
gn = Targ_FindNode(start, cp2, TARG_CREATE); |
gn = Targ_FindNodei(start, cp2, TARG_CREATE); |
Lst_AtEnd(&members, gn); |
Lst_AtEnd(&members, gn); |
} |
} |
} |
} |
|
|
path = &s->searchPath; |
path = &s->searchPath; |
} else |
} else |
/* Use default search path. */ |
/* Use default search path. */ |
path = &dirSearchPath; |
path = dirSearchPath; |
|
|
/* Expand the word along the chosen path. */ |
/* Expand the word along the chosen path. */ |
Lst_Init(&exp); |
Lst_Init(&exp); |
|
|
GNode *gn; /* New source 8) */ |
GNode *gn; /* New source 8) */ |
if (DEBUG(SUFF)) |
if (DEBUG(SUFF)) |
printf("%s...", cp); |
printf("%s...", cp); |
gn = Targ_FindNode(cp, NULL, TARG_CREATE); |
gn = Targ_FindNode(cp, TARG_CREATE); |
|
|
/* If gn isn't already a child of the parent, make it so and |
/* If gn isn't already a child of the parent, make it so and |
* up the parent's count of unmade children. */ |
* up the parent's count of unmade children. */ |
|
|
* and suffixes. |
* and suffixes. |
* |
* |
* Results: |
* Results: |
* TRUE if successful, FALSE if not. |
* true if successful, false if not. |
* |
* |
* Side Effects: |
* Side Effects: |
* The source and target are linked and the commands from the |
* The source and target are linked and the commands from the |
|
|
* the transformation rule. |
* the transformation rule. |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Boolean |
static bool |
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 */ |
|
|
char *tname; /* Name of transformation rule */ |
char *tname; /* Name of transformation rule */ |
GNode *gn; /* Node for same */ |
GNode *gn; /* Node for same */ |
|
|
if (Lst_AddNew(&tGn->children, sGn) == SUCCESS) { |
if (Lst_AddNew(&tGn->children, sGn)) { |
/* 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(&sGn->parents, tGn); |
Lst_AtEnd(&sGn->parents, 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_AddNew(&tGn->children, gn) == SUCCESS) { |
if (Lst_AddNew(&tGn->children, gn)) { |
/* 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(&gn->parents, tGn); |
Lst_AtEnd(&gn->parents, tGn); |
|
|
} |
} |
} |
} |
/* 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_FindConst(&transforms, SuffGNHasNameP, tname); |
ln = Lst_FindConst(&transforms, SuffGNHasNameP, tname); |
free(tname); |
free(tname); |
|
|
|
|
/* |
/* |
* 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); |
|
|
|
|
* 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; |
} |
} |
|
|
|
|
|
|
* 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_FindNodei(name, eoname, 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_AddNew(&gn->children, mem)) { |
Lst_AtEnd(&mem->parents, gn); |
Lst_AtEnd(&mem->parents, gn); |
gn->unmade++; |
gn->unmade++; |
} |
} |
|
|
(Lst_IsEmpty(&gn->children) && Lst_IsEmpty(&gn->commands))) |
(Lst_IsEmpty(&gn->children) && Lst_IsEmpty(&gn->commands))) |
{ |
{ |
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; |
|
|
* 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, NULL, TARG_CREATE); |
bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); |
} |
} |
|
|
for (src = bottom; src->parent != NULL; src = src->parent) { |
for (src = bottom; src->parent != NULL; src = 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, NULL, TARG_CREATE); |
targ->node = Targ_FindNode(targ->file, TARG_CREATE); |
} |
} |
|
|
SuffApplyTransform(targ->node, src->node, |
SuffApplyTransform(targ->node, src->node, |
|
|
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); |
|
|
*---------------------------------------------------------------------- |
*---------------------------------------------------------------------- |
*/ |
*/ |
|
|
|
#ifdef CLEANUP |
void |
void |
Suff_End() |
Suff_End() |
{ |
{ |
#ifdef CLEANUP |
|
Lst_Destroy(&sufflist, SuffFree); |
Lst_Destroy(&sufflist, SuffFree); |
Lst_Destroy(&suffClean, SuffFree); |
Lst_Destroy(&suffClean, SuffFree); |
if (suffNull) |
if (suffNull) |
SuffFree(suffNull); |
SuffFree(suffNull); |
Lst_Destroy(&srclist, NOFREE); |
Lst_Destroy(&srclist, NOFREE); |
Lst_Destroy(&transforms, NOFREE); |
Lst_Destroy(&transforms, NOFREE); |
#endif |
|
} |
} |
|
#endif |
|
|
|
|
/********************* DEBUGGING FUNCTIONS **********************/ |
/********************* DEBUGGING FUNCTIONS **********************/ |
|
|
printf("#*** Transformations:\n"); |
printf("#*** Transformations:\n"); |
Lst_Every(&transforms, SuffPrintTrans); |
Lst_Every(&transforms, SuffPrintTrans); |
} |
} |
|
|
|
#ifdef DEBUG_SRC |
|
static void |
|
PrintAddr(a) |
|
void *a; |
|
{ |
|
printf("%lx ", (unsigned long)a); |
|
} |
|
#endif |