Kaydet (Commit) f6c2da4d authored tarafından Ivo Hinkelmann's avatar Ivo Hinkelmann

INTEGRATION: CWS dmake411 (1.7.4); FILE MERGED

2007/08/10 17:39:24 vq 1.7.4.7: #i66751# Make sure that infered phony %-targets do not have a time stamp.
2007/08/10 15:42:07 vq 1.7.4.6: #i66751# Accept .PHONY attribute in %-targets.
2007/08/05 17:51:32 vq 1.7.4.5: #i80144# Clean-up.
2007/08/05 17:03:43 vq 1.7.4.4: #i80144# Change error about ambigous inference targets to warning.
2007/08/01 00:29:43 vq 1.7.4.3: #i80143# Fix problem marking some intermediate targets removable.
2007/07/30 02:28:10 vq 1.7.4.2: #i80144# Improve check for ambiguous inference chains.
2007/07/29 16:10:54 vq 1.7.4.1: #i10000# Add comments to documents aspects of the inference mechanism.
üst e848d1bf
/* $RCSfile: infer.c,v $ /* $RCSfile: infer.c,v $
-- $Revision: 1.7 $ -- $Revision: 1.8 $
-- last change: $Author: obo $ $Date: 2007-06-12 06:06:11 $ -- last change: $Author: ihi $ $Date: 2007-10-15 15:39:49 $
-- --
-- SYNOPSIS -- SYNOPSIS
-- Infer how to make a target. -- Infer how to make a target.
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#define A_TRANSFER (A_EPILOG | A_PRECIOUS | A_SILENT | A_SHELL | A_SETDIR |\ #define A_TRANSFER (A_EPILOG | A_PRECIOUS | A_SILENT | A_SHELL | A_SETDIR |\
A_SEQ | A_LIBRARY | A_IGNORE | A_PROLOG | A_SWAP |\ A_SEQ | A_LIBRARY | A_IGNORE | A_PROLOG | A_SWAP |\
A_NOSTATE ) A_PHONY | A_NOSTATE )
/* Define local static functions */ /* Define local static functions */
...@@ -72,6 +72,8 @@ CELLPTR setdirroot; ...@@ -72,6 +72,8 @@ CELLPTR setdirroot;
if( cp->ce_attr & A_NOINFER ) {DB_VOID_RETURN;} if( cp->ce_attr & A_NOINFER ) {DB_VOID_RETURN;}
DB_PRINT("inf", ("Inferring rule for [%s]", cp->CE_NAME));
match = NIL(ICELL); match = NIL(ICELL);
nomatch = add_iset( NIL(ICELL), NIL(ICELL), NIL(CELL), NIL(DFALINK), nomatch = add_iset( NIL(ICELL), NIL(ICELL), NIL(CELL), NIL(DFALINK),
setdirroot, Prep+count_dots(cp->CE_NAME), 0, setdirroot, Prep+count_dots(cp->CE_NAME), 0,
...@@ -83,11 +85,12 @@ CELLPTR setdirroot; ...@@ -83,11 +85,12 @@ CELLPTR setdirroot;
DB_EXECUTE( "inf", _dump_iset("nomatch",nomatch); ); DB_EXECUTE( "inf", _dump_iset("nomatch",nomatch); );
/* If nomatch is non-empty there was no match with an existing
* prerrequisite, try to derive one. */
while( nomatch != NIL(ICELL) ) { while( nomatch != NIL(ICELL) ) {
ICELLPTR new_nomatch = NIL(ICELL); ICELLPTR new_nomatch = NIL(ICELL);
ICELLPTR ic, pmatch, mmatch; ICELLPTR ic, pmatch, mmatch;
CELLPTR prereq; CELLPTR prereq;
int first;
for( ic=nomatch; ic != NIL(ICELL); ic=ic->ic_next ) { for( ic=nomatch; ic != NIL(ICELL); ic=ic->ic_next ) {
int ipush = FALSE; int ipush = FALSE;
...@@ -112,7 +115,10 @@ CELLPTR setdirroot; ...@@ -112,7 +115,10 @@ CELLPTR setdirroot;
*/ */
if( match == NIL(ICELL) ) { if( match == NIL(ICELL) ) {
nomatch = new_nomatch; nomatch = new_nomatch;
/* Skip the rest and try one level deeper. */
if( Transitive ) continue; if( Transitive ) continue;
goto all_done; goto all_done;
} }
...@@ -133,6 +139,10 @@ CELLPTR setdirroot; ...@@ -133,6 +139,10 @@ CELLPTR setdirroot;
* prerequisites that already exist. */ * prerequisites that already exist. */
pmatch = mmatch = NIL(ICELL); pmatch = mmatch = NIL(ICELL);
for(; match; match = ic ) { for(; match; match = ic ) {
/* This loop checks all possible matches. */
DB_PRINT("inf", ("Target [%s] : prerequisite [%s]",
match->ic_meta->CE_NAME, match->ic_name));
ic = match->ic_next; ic = match->ic_next;
match->ic_next = NIL(ICELL); match->ic_next = NIL(ICELL);
...@@ -142,33 +152,23 @@ CELLPTR setdirroot; ...@@ -142,33 +152,23 @@ CELLPTR setdirroot;
mmatch = union_iset(mmatch, match); mmatch = union_iset(mmatch, match);
} }
/* Prefer %-targets with existing prerequisites. */
if( pmatch ) if( pmatch )
match = pmatch; match = pmatch;
else else
match = mmatch; match = mmatch;
/* Make sure it is unique */ /* Make sure it is unique. It would be easy to check
* match->ic_meta->ce_prq for existence and prefer no prerequisites
* over prerequisites that are present, but we are currently not
* doing it. */
if( match->ic_next != NIL(ICELL) ) { if( match->ic_next != NIL(ICELL) ) {
int dump = (match->ic_next->ic_next != NIL(ICELL)); int count = 1;
/* Check for definite ambiguity */ Warning( "Ambiguous inference chains for target '%s'", cp->CE_NAME );
if( !dump ) { for( ic=match; ic; ic=ic->ic_next )
if( (match->ic_meta->ce_prq && match->ic_next->ic_meta->ce_prq) || (void) dump_inf_chain(ic, TRUE, count++);
(!match->ic_meta->ce_prq && !match->ic_next->ic_meta->ce_prq) ) Warning( "First matching rule is chosen.");
dump = TRUE;
else if(!match->ic_meta->ce_prq && match->ic_next->ic_meta->ce_prq )
match = match->ic_next;
}
else {
int count = 1;
Continue = TRUE;
Error( "Ambiguous inference chains for target '%s'", cp->CE_NAME );
for( ic=match; ic; ic=ic->ic_next )
(void) dump_inf_chain(ic, TRUE, count++);
Fatal( "resolve ambiguity before proceeding.");
/*NOTREACHED*/
}
} }
/* MATCH now points at the derived prerequisite chain(s). We must now /* MATCH now points at the derived prerequisite chain(s). We must now
...@@ -185,8 +185,8 @@ CELLPTR setdirroot; ...@@ -185,8 +185,8 @@ CELLPTR setdirroot;
pmatch = NIL(ICELL); pmatch = NIL(ICELL);
prereq = NIL(CELL); prereq = NIL(CELL);
first = TRUE;
/* This loop treats the inferred targets last to first. */
while( match ) { while( match ) {
CELLPTR infcell=NIL(CELL); CELLPTR infcell=NIL(CELL);
...@@ -200,14 +200,13 @@ CELLPTR setdirroot; ...@@ -200,14 +200,13 @@ CELLPTR setdirroot;
infcell->ce_flag |= F_TARGET; infcell->ce_flag |= F_TARGET;
if( infcell != cp ) { if( infcell != cp ) {
infcell->ce_flag |= F_INFER; infcell->ce_flag |= F_INFER|F_REMOVE;
if( !first ) infcell->ce_flag |= F_REMOVE; DB_PRINT("remove", ("Mark for deletion [%s]",
infcell->CE_NAME));
} }
if( !match->ic_flag ) if( !match->ic_flag )
infcell->ce_attr |= A_NOINFER; infcell->ce_attr |= A_NOINFER;
first = FALSE;
} }
/* Add global prerequisites from previous rule if there are any and /* Add global prerequisites from previous rule if there are any and
...@@ -216,9 +215,21 @@ CELLPTR setdirroot; ...@@ -216,9 +215,21 @@ CELLPTR setdirroot;
CELLPTR imeta = pmatch->ic_meta; CELLPTR imeta = pmatch->ic_meta;
LINKPTR lp; LINKPTR lp;
DB_PRINT("inf", ("%%-target [%s] - infered target [%s]\n",
imeta->CE_NAME, infcell->CE_NAME));
infcell->ce_per = pmatch->ic_dfa->dl_per; infcell->ce_per = pmatch->ic_dfa->dl_per;
infcell->ce_attr |= (imeta->ce_attr & A_TRANSFER); infcell->ce_attr |= (imeta->ce_attr & A_TRANSFER);
/* The .PHONY mechanism relies on having phony targets not
* being STATed and having a zero time stamp. While inferring
* the this target it might have been created and stated
* therefore these values need to be reset. */
if( infcell->ce_attr & A_PHONY ){
infcell->ce_time = 0L;
infcell->ce_flag &= ~F_STAT;
}
if( !(infcell->ce_flag & F_RULES) ) { if( !(infcell->ce_flag & F_RULES) ) {
infcell->ce_flag |= (imeta->ce_flag&(F_SINGLE|F_GROUP))|F_RULES; infcell->ce_flag |= (imeta->ce_flag&(F_SINGLE|F_GROUP))|F_RULES;
infcell->ce_recipe = imeta->ce_recipe; infcell->ce_recipe = imeta->ce_recipe;
...@@ -289,8 +300,10 @@ CELLPTR setdirroot; ...@@ -289,8 +300,10 @@ CELLPTR setdirroot;
if( prereq ) if( prereq )
(Add_prerequisite(infcell,prereq,FALSE,FALSE))->cl_flag |=F_TARGET; (Add_prerequisite(infcell,prereq,FALSE,FALSE))->cl_flag |=F_TARGET;
pmatch = match; pmatch = match; /* Previous member in inference chain ... */
prereq = infcell; prereq = infcell; /* is a prerequisite to the next match. */
/* ip->ic_parent is the next target in the inference chain to be
* build. If it is empty we are done. */
match = match->ic_parent; match = match->ic_parent;
} }
...@@ -326,6 +339,8 @@ ICELLPTR *nnmp; ...@@ -326,6 +339,8 @@ ICELLPTR *nnmp;
DB_ENTER("derive_prerequisites"); DB_ENTER("derive_prerequisites");
DB_PRINT("inf", ("for [%s]\n", ic->ic_name));
/* If none of the inference nodes match then forget about the inference. /* If none of the inference nodes match then forget about the inference.
* The user did not tell us how to make such a target. We also stop the * The user did not tell us how to make such a target. We also stop the
* Inference if the new set of DFA's is a proper subset of a previous * Inference if the new set of DFA's is a proper subset of a previous
...@@ -386,6 +401,7 @@ ICELLPTR *nnmp; ...@@ -386,6 +401,7 @@ ICELLPTR *nnmp;
int noinf; int noinf;
int exists; int exists;
/* Name of the prerequisite, can be empty. */
if( meta->ce_prq ) if( meta->ce_prq )
name = meta->ce_prq->cl_prq->CE_NAME; name = meta->ce_prq->cl_prq->CE_NAME;
...@@ -480,6 +496,7 @@ ICELLPTR *nnmp; ...@@ -480,6 +496,7 @@ ICELLPTR *nnmp;
printf( "%s: Trying prerequisite [%s] for [%s]\n", Pname, printf( "%s: Trying prerequisite [%s] for [%s]\n", Pname,
iprqh.ht_name, ic->ic_name ); iprqh.ht_name, ic->ic_name );
/* irpq is a temporary target cell, a stat will not be remembered. */
if( !(iprq.ce_flag & F_STAT) ) Stat_target(&iprq, FALSE, FALSE); if( !(iprq.ce_flag & F_STAT) ) Stat_target(&iprq, FALSE, FALSE);
} }
...@@ -494,7 +511,9 @@ ICELLPTR *nnmp; ...@@ -494,7 +511,9 @@ ICELLPTR *nnmp;
if( meta->ce_prq ) if( meta->ce_prq )
noinf |= ((meta->ce_prq->cl_prq->ce_attr)&A_NOINFER); noinf |= ((meta->ce_prq->cl_prq->ce_attr)&A_NOINFER);
trans = Transitive || !noinf; trans = Transitive || !noinf;
exists = (iprq.ce_time != (time_t)0L);
/* If no prereq is given treat it as if it is existing. */
exists = (iprq.ce_time != (time_t)0L) || (name == NIL(char));
if( exists || (ircp != NIL(STRING)) || !name ) { if( exists || (ircp != NIL(STRING)) || !name ) {
match = add_iset( match, ic, meta, pdfa, idirroot, ic->ic_dmax, match = add_iset( match, ic, meta, pdfa, idirroot, ic->ic_dmax,
...@@ -774,6 +793,7 @@ int print; ...@@ -774,6 +793,7 @@ int print;
if( ip == NIL(ICELL) ) return(NIL(char)); if( ip == NIL(ICELL) ) return(NIL(char));
/* ip->ic_parent is the target to be build after ip. */
tmp = dump_inf_chain(ip->ic_parent, FALSE, FALSE); tmp = dump_inf_chain(ip->ic_parent, FALSE, FALSE);
if( ip->ic_meta ) { if( ip->ic_meta ) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment