version 1.83, 2012/12/06 10:33:16 |
version 1.84, 2012/12/22 19:02:05 |
|
|
*/ |
*/ |
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 *prefix; /* 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 */ |
|
|
targ = ls->s; |
targ = ls->s; |
|
|
s2 = emalloc(sizeof(Src)); |
s2 = emalloc(sizeof(Src)); |
s2->file = Str_concat(targ->pref, s->name, 0); |
s2->file = Str_concat(targ->prefix, s->name, 0); |
s2->pref = targ->pref; |
s2->prefix = targ->prefix; |
s2->parent = targ; |
s2->parent = targ; |
s2->node = NULL; |
s2->node = NULL; |
s2->suff = s; |
s2->suff = s; |
|
|
if (s->children == 0) { |
if (s->children == 0) { |
free(s->file); |
free(s->file); |
if (!s->parent) |
if (!s->parent) |
free(s->pref); |
free(s->prefix); |
else { |
else { |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
LstNode ln2 = Lst_Member(&s->parent->cp, s); |
LstNode ln2 = Lst_Member(&s->parent->cp, s); |
|
|
* See if any of the children of the target in the Src structure is |
* See if any of the children of the target in the Src structure is |
* one from which the target can be transformed. If there is one, |
* one from which the target can be transformed. If there is one, |
* a Src structure is put together for it and returned. |
* a Src structure is put together for it and returned. |
* |
|
* Results: |
|
* The Src structure of the "winning" child, or NULL if no such beast. |
|
* |
|
* Side Effects: |
|
* A Src structure may be allocated. |
|
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Src * |
static Src * |
SuffFindCmds( |
SuffFindCmds(Src *targ, Lst slst) |
Src *targ, /* Src structure to play with */ |
|
Lst slst) |
|
{ |
{ |
LstNode ln; /* General-purpose list node */ |
LstNode ln; /* General-purpose list node */ |
GNode *t; /* Target GNode */ |
GNode *t; /* Target GNode */ |
GNode *s; /* Source GNode */ |
GNode *s; /* Source GNode */ |
int prefLen; /* The length of the defined prefix */ |
int prefixLen; /* 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 */ |
const char *cp; |
const char *cp; |
|
|
t = targ->node; |
t = targ->node; |
prefLen = strlen(targ->pref); |
prefixLen = strlen(targ->prefix); |
|
|
for (ln = Lst_First(&t->children); ln != NULL; ln = Lst_Adv(ln)) { |
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 == NULL) { |
if (cp == NULL) |
cp = s->name; |
cp = s->name; |
} else { |
else |
cp++; |
cp++; |
} |
if (strncmp(cp, targ->prefix, prefixLen) != 0) |
if (strncmp(cp, targ->pref, prefLen) == 0) { |
continue; |
/* 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. */ |
suff = find_suff(&cp[prefLen]); |
suff = find_suff(&cp[prefixLen]); |
if (suff != NULL) { |
if (suff == NULL) |
/* |
continue; |
* It even has a known suffix, see if there's a |
/* |
* transformation defined between the node's |
* It even has a known suffix, see if there's a transformation |
* suffix and the target's suffix. |
* defined between the node's suffix and the target's suffix. |
* |
* |
* XXX: Handle multi-stage transformations |
* XXX: Handle multi-stage transformations here, too. |
* here, too. |
*/ |
*/ |
if (Lst_Member(&suff->parents, targ->suff) == NULL) |
if (Lst_Member(&suff->parents, targ->suff) |
continue; |
!= NULL) { |
/* |
/* |
* Create a new Src structure to describe this transformation |
* Hot Damn! Create a new Src structure |
* (making sure to duplicate the source node's name so |
* to describe this transformation |
* Suff_FindDeps can free it again (ick)), and return the new |
* (making sure to duplicate the source |
* structure. |
* node's name so Suff_FindDeps can |
*/ |
* free it again (ick)), and return the |
ret = emalloc(sizeof(Src)); |
* new structure. |
ret->file = estrdup(s->name); |
*/ |
ret->prefix = targ->prefix; |
ret = emalloc(sizeof(Src)); |
ret->suff = suff; |
ret->file = estrdup(s->name); |
ret->parent = targ; |
ret->pref = targ->pref; |
ret->node = s; |
ret->suff = suff; |
ret->children = 0; |
ret->parent = targ; |
targ->children++; |
ret->node = s; |
|
ret->children = 0; |
|
targ->children++; |
|
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
Lst_Init(&ret->cp); |
Lst_Init(&ret->cp); |
printf("3 add %x %x\n", targ, ret); |
printf("3 add %x %x\n", targ, ret); |
Lst_AtEnd(&targ->cp, ret); |
Lst_AtEnd(&targ->cp, ret); |
#endif |
#endif |
Lst_AtEnd(slst, ret); |
Lst_AtEnd(slst, ret); |
if (DEBUG(SUFF)) |
if (DEBUG(SUFF)) |
printf( |
printf("\tusing existing source %s\n", s->name); |
"\tusing existing source %s\n", |
return ret; |
s->name); |
|
return ret; |
|
} |
|
} |
|
} |
|
} |
} |
return NULL; |
return NULL; |
} |
} |
|
|
static void |
static void |
record_possible_suffix(Suff *s, GNode *gn, char *eoname, Lst srcs, Lst targs) |
record_possible_suffix(Suff *s, GNode *gn, char *eoname, Lst srcs, Lst targs) |
{ |
{ |
int prefLen; |
int prefixLen; |
Src *targ; |
Src *targ; |
char *sopref = gn->name; |
|
|
|
targ = emalloc(sizeof(Src)); |
targ = emalloc(sizeof(Src)); |
targ->file = estrdup(gn->name); |
targ->file = estrdup(gn->name); |
|
|
/* Allocate room for the prefix, whose end is found by |
/* Allocate room for the prefix, whose end is found by |
* subtracting the length of the suffix from the end of |
* subtracting the length of the suffix from the end of |
* the name. */ |
* the name. */ |
prefLen = (eoname - targ->suff->nameLen) - sopref; |
prefixLen = (eoname - targ->suff->nameLen) - gn->name; |
targ->pref = emalloc(prefLen + 1); |
targ->prefix = emalloc(prefixLen + 1); |
memcpy(targ->pref, sopref, prefLen); |
memcpy(targ->prefix, gn->name, prefixLen); |
targ->pref[prefLen] = '\0'; |
targ->prefix[prefixLen] = '\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); |
|
|
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 prefix 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 *prefix; /* Prefix to use */ |
Src *targ; /* General Src target pointer */ |
Src *targ; /* General Src target pointer */ |
|
|
|
|
|
|
targ->node = gn; |
targ->node = gn; |
targ->parent = NULL; |
targ->parent = NULL; |
targ->children = 0; |
targ->children = 0; |
targ->pref = estrdup(gn->name); |
targ->prefix = estrdup(gn->name); |
#ifdef DEBUG_SRC |
#ifdef DEBUG_SRC |
Lst_Init(&targ->cp); |
Lst_Init(&targ->cp); |
#endif |
#endif |
|
|
* as expanding sources is concerned, since it has none... */ |
* as expanding sources is concerned, since it has none... */ |
Var(TARGET_INDEX, gn) = gn->name; |
Var(TARGET_INDEX, gn) = gn->name; |
|
|
pref = targ != NULL ? estrdup(targ->pref) : gn->name; |
prefix = targ != NULL ? estrdup(targ->prefix) : gn->name; |
Var(PREFIX_INDEX, gn) = pref; |
Var(PREFIX_INDEX, gn) = prefix; |
|
|
/* 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. */ |
|
|
* is set the standard and System V variables. */ |
* is set the standard and System V variables. */ |
targ->node->type |= OP_DEPS_FOUND; |
targ->node->type |= OP_DEPS_FOUND; |
|
|
Var(PREFIX_INDEX, targ->node) = estrdup(targ->pref); |
Var(PREFIX_INDEX, targ->node) = estrdup(targ->prefix); |
|
|
Var(TARGET_INDEX, targ->node) = targ->node->name; |
Var(TARGET_INDEX, targ->node) = targ->node->name; |
} |
} |