Kaydet (Commit) 88f776d9 authored tarafından Vladimir Glazounov's avatar Vladimir Glazounov

INTEGRATION: CWS dmake47 (1.7.2); FILE MERGED

2006/11/19 05:27:24 vq 1.7.2.11: #i71704# Let the global .SEQUENTIAL attribute implicitely set MAXPROCESS=1
and disallow MAXPROCESS to be changed if the global .SEQUENTIAL is set.
2006/11/12 05:06:38 vq 1.7.2.10: #i71422# Add a new feature: Using @@ as a recipe prefix redirects the
output (stdout and stderr) of a recipe to /dev/null (or NUL on W32)
completely suppressing the output of that recipe to the terminal.
As for the @ prefix this can be disabled using the -v[r] switch.
2006/11/09 22:33:22 vq 1.7.2.9: #i69821# Fix/improve $(TMD) handling.
2006/11/09 18:16:33 vq 1.7.2.8: #i69821# Add comment where TMD is detecting different drive letters for
native W32 dmake versions.
2006/10/08 23:27:11 vq 1.7.2.7: #i70210# Fix dmakes handling of empty dynamic prerequisites.
2006/10/08 22:57:22 vq 1.7.2.6: #i70168# Remove FIXME.
2006/10/08 22:49:03 vq 1.7.2.5: #i70168# Improve $ handling in targets/prerequisites.
2006/10/06 04:02:35 vq 1.7.2.4: #i69742# Don't targets with $ in the filepath as dynamic macros. ($$ means
a single $ in the filepath.)
2006/09/29 21:20:45 vq 1.7.2.3: #i69953# Remove NO_DRIVE_LETTERS, use HAVE_DRIVE_LETTERS instead.
2006/09/29 18:50:23 vq 1.7.2.2: #i69814# Add/fix option to make directory cache case insensitive. (Make
this the default for Windows and Mac OS X.) Added testcase.
2006/09/28 21:42:38 vq 1.7.2.1: #i69821# Fix TMD macro and add testcase.
üst 4ed2a92b
/* $RCSfile: make.c,v $ /* $RCSfile: make.c,v $
-- $Revision: 1.7 $ -- $Revision: 1.8 $
-- last change: $Author: vg $ $Date: 2006-09-25 09:40:24 $ -- last change: $Author: vg $ $Date: 2007-01-18 09:30:56 $
-- --
-- SYNOPSIS -- SYNOPSIS
-- Perform the update of all outdated targets. -- Perform the update of all outdated targets.
...@@ -307,6 +307,8 @@ CELLPTR setdirroot; ...@@ -307,6 +307,8 @@ CELLPTR setdirroot;
for(dp=CeMeToo(cp); dp; dp=dp->cl_next) { for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
tcp = dp->cl_prq; tcp = dp->cl_prq;
if( push ) { if( push ) {
/* If we changed the directory because of .SETDIR write Pwd into
* tcp->ce_dir so that it holds an absolute path. */
if( !(tcp->ce_attr & A_POOL) && tcp->ce_dir ) FREE( tcp->ce_dir ); if( !(tcp->ce_attr & A_POOL) && tcp->ce_dir ) FREE( tcp->ce_dir );
tcp->ce_dir = _pool_lookup(Pwd); tcp->ce_dir = _pool_lookup(Pwd);
tcp->ce_attr |= A_SETDIR|A_POOL; tcp->ce_attr |= A_SETDIR|A_POOL;
...@@ -320,7 +322,7 @@ CELLPTR setdirroot; ...@@ -320,7 +322,7 @@ CELLPTR setdirroot;
time_t itime = cp->ce_time; time_t itime = cp->ce_time;
if (cp->ce_parent && (cp->ce_parent->ce_flag & F_MULTI)) { if (cp->ce_parent && (cp->ce_parent->ce_flag & F_MULTI)) {
/* Inherit the stat info from the parent. */ /* Inherit the stat info from the F_MULTI parent. */
cp->ce_time = cp->ce_parent->ce_time; cp->ce_time = cp->ce_parent->ce_time;
cp->ce_flag |= F_STAT; cp->ce_flag |= F_STAT;
/* Propagate the A_PRECIOUS attribute from the parent. */ /* Propagate the A_PRECIOUS attribute from the parent. */
...@@ -329,7 +331,8 @@ CELLPTR setdirroot; ...@@ -329,7 +331,8 @@ CELLPTR setdirroot;
else { else {
for(dp=CeMeToo(cp); dp; dp=dp->cl_next) { for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
tcp = dp->cl_prq; tcp = dp->cl_prq;
Stat_target( tcp, TRUE, FALSE ); /* Check if target already exists. */
Stat_target( tcp, 1, FALSE );
if( tcp->ce_time == (time_t)0L ) { if( tcp->ce_time == (time_t)0L ) {
if( tcp->ce_flag & F_INFER ) if( tcp->ce_flag & F_INFER )
...@@ -412,7 +415,6 @@ CELLPTR setdirroot; ...@@ -412,7 +415,6 @@ CELLPTR setdirroot;
/* First round, will be repeated a second time below. */ /* First round, will be repeated a second time below. */
for( prev=NULL,dp=cp->ce_prq; dp != NIL(LINK); prev=dp, dp=next ) { for( prev=NULL,dp=cp->ce_prq; dp != NIL(LINK); prev=dp, dp=next ) {
int seq; int seq;
int nesting_count;
/* This is the only macro that needs to be reset while building /* This is the only macro that needs to be reset while building
* prerequisites since it is set when we make each prerequisite. */ * prerequisites since it is set when we make each prerequisite. */
...@@ -443,27 +445,30 @@ CELLPTR setdirroot; ...@@ -443,27 +445,30 @@ CELLPTR setdirroot;
tcp = dp->cl_prq; tcp = dp->cl_prq;
} }
/* If the previous target (prereq) is not yet ready return if
* seq is TRUE. */
if( seq && !made ) goto stop_making_it; if( seq && !made ) goto stop_making_it;
nesting_count = 0; /* Expand dynamic prerequisites. The F_MARK flag is guarging against
while ( tcp * possible double expandion of dynamic prerequisites containing more
&& strchr(tcp->CE_NAME, '$') * than one prerequisite. */
) { /* A new A_DYNAMIC attribute could save a lot of strchr( ,'$') calls. */
if ( nesting_count++ > DynamicNestLevel ) { if ( tcp && !(tcp->ce_flag & F_MARK) && strchr(tcp->CE_NAME, '$') ) {
Fatal( "Dynamic Macro nesting level exceeded [%s]", /* Replace this dynamic prerequisite with the the real prerequisite,
cp->CE_NAME ); * and add the additional prerequisites if there are more than one.*/
}
/* Make this prerequisite link point at the real prerequisite we
* are after, ie figure out what the dynamic one is and point at it.*/
name = Expand( tcp->CE_NAME ); name = Expand( tcp->CE_NAME );
if( strcmp(name,cp->CE_NAME) == 0 ) if( strcmp(name,cp->CE_NAME) == 0 )
Fatal("Detected circular dynamic dependency; generated '%s'",name); Fatal("Detected circular dynamic dependency; generated '%s'",name);
/* Call helper for dynamic prerequisite expansion. */ /* Call helper for dynamic prerequisite expansion to replace the
* prerequisite with the expanded version and add the new
* prerequisites, if the macro expanded to more than one, after
* the current list element. */
dp = _expand_dynamic_prq( cp->ce_prq, dp, name ); dp = _expand_dynamic_prq( cp->ce_prq, dp, name );
FREE( name ); FREE( name );
/* _expand_dynamic_prq() probably changed dp->cl_prq. */
tcp = dp->cl_prq; tcp = dp->cl_prq;
if ( tcp ) { if ( tcp ) {
next = dp->cl_next; next = dp->cl_next;
...@@ -471,8 +476,8 @@ CELLPTR setdirroot; ...@@ -471,8 +476,8 @@ CELLPTR setdirroot;
} }
/* Dynamic expansion results in a NULL cell only when the the new /* Dynamic expansion results in a NULL cell only when the the new
* prerequisite is already in the prerequisite list. In this case * prerequisite is already in the prerequisite list or empty. In this
* delete the cell and continue. */ * case delete the cell and continue. */
if ( tcp == NIL(CELL) ) { if ( tcp == NIL(CELL) ) {
FREE(dp); FREE(dp);
if ( prev == NIL(LINK) ) { if ( prev == NIL(LINK) ) {
...@@ -486,6 +491,9 @@ CELLPTR setdirroot; ...@@ -486,6 +491,9 @@ CELLPTR setdirroot;
continue; continue;
} }
/* Clear F_MARK flag that could have been set by _expand_dynamic_prq(). */
tcp->ce_attr &= ~(F_MARK);
if( cp->ce_attr & A_LIBRARY ) { if( cp->ce_attr & A_LIBRARY ) {
tcp->ce_attr |= A_LIBRARYM; tcp->ce_attr |= A_LIBRARYM;
tcp->ce_lib = cp->ce_fname; tcp->ce_lib = cp->ce_fname;
...@@ -511,10 +519,13 @@ CELLPTR setdirroot; ...@@ -511,10 +519,13 @@ CELLPTR setdirroot;
if( cp->ce_attr & A_LIBRARY ) if( cp->ce_attr & A_LIBRARY )
tcp->ce_attr ^= A_LIBRARYM; tcp->ce_attr ^= A_LIBRARYM;
/* Return on error or if Make() is still running and A_SEQ is set. */
if( rval == -1 || (seq && (rval==1)) ) if( rval == -1 || (seq && (rval==1)) )
goto stop_making_it; goto stop_making_it;
if( tcp->ce_time > ttime ) ttime = tcp->ce_time; if( tcp->ce_time > ttime ) ttime = tcp->ce_time;
/* If tcp is ready, set made = F_MADE. */
made &= tcp->ce_flag & F_MADE; made &= tcp->ce_flag & F_MADE;
} }
...@@ -712,6 +723,7 @@ CELLPTR setdirroot; ...@@ -712,6 +723,7 @@ CELLPTR setdirroot;
* of the target. */ * of the target. */
if( push ) { if( push ) {
char *dir = nsetdirroot ? nsetdirroot->ce_dir : Makedir; char *dir = nsetdirroot ? nsetdirroot->ce_dir : Makedir;
/* get relative path from current SETDIR to new SETDIR. */
char *pref = _prefix(dir,tcp->ce_dir); char *pref = _prefix(dir,tcp->ce_dir);
char *nname = Build_path(pref, tcp->ce_fname); char *nname = Build_path(pref, tcp->ce_fname);
...@@ -769,42 +781,104 @@ stop_making_it: ...@@ -769,42 +781,104 @@ stop_making_it:
static char * static char *
_prefix( pfx, pat ) _prefix( pfx, pat )/*
=====================
Return the relative path from pfx to pat. Both paths have to be absolute
paths. If the paths are on different resources or drives (if applicable)
return pat. */
char *pfx; char *pfx;
char *pat; char *pat;
{ {
char *cmp1=pfx; char *cmp1=pfx;
char *cmp2=pat; char *cmp2=pat;
char *result = DmStrDup(""); char *result;
char *up; char *up;
int first = 1;
#ifdef HAVE_DRIVE_LETTERS
int pfxdl = 0;
int patdl = 0;
#endif
/* Micro optimization return immediately if pfx and pat are equal. */
if( strcmp(pfx, pat) == 0 )
return(DmStrDup(""));
#ifdef HAVE_DRIVE_LETTERS
/* remove the drive letters to avoid getting them into the relative
* path later. */
if( *pfx && pfx[1] == ':' && isalpha(*pfx) ) {
pfxdl = 1;
cmp1 = DmStrSpn(pfx+2, DirBrkStr);
}
if( *pat && pat[1] == ':' && isalpha(*pat) ) {
patdl = 1;
cmp2 = DmStrSpn(pat+2, DirBrkStr);
}
/* If the drive letters are different use the abs. path. */
if( pfxdl && patdl && (tolower(*pfx) != tolower(*pat)) )
return(DmStrDup(pat));
/* If only one has a drive letter also use the abs. path. */
if( pfxdl != patdl )
return(DmStrDup(pat));
/* Continue without the drive letters. (Either none was present,
* or both were the same. This also solves the problem that the
* case of the drive letters sometimes depends on the shell.
* (cmd.exe vs. cygwin bash) */
pfx = cmp1;
pat = cmp2;
#endif
/* Cut off equal leading parts of pfx, pat. Both have to be abs. paths. */
while(*pfx && *pat) { while(*pfx && *pat) {
/* skip leading dir. separators. */
pfx = DmStrSpn(cmp1, DirBrkStr); pfx = DmStrSpn(cmp1, DirBrkStr);
pat = DmStrSpn(cmp2, DirBrkStr); pat = DmStrSpn(cmp2, DirBrkStr);
/* Only check in the first run of the loop. Leading slashes can only
* mean POSIX paths or Windows resources (two) slashes. Drive letters
* have no leading slash. In any case, if the number of slashes are
* not equal there can be no relative path from one two the other.
* In this case return the absolute path. */
if( first ) {
if( cmp1-pfx != cmp2-pat ) {
return(DmStrDup(pat));
}
first = 0;
}
/* find next dir. separator (or ""). */
cmp1 = DmStrPbrk(pfx, DirBrkStr); cmp1 = DmStrPbrk(pfx, DirBrkStr);
cmp2 = DmStrPbrk(pat, DirBrkStr); cmp2 = DmStrPbrk(pat, DirBrkStr);
/* if length of directory name is equal compare the strings. If equal
* go into next loop. */
if ( (cmp1-pfx) != (cmp2-pat) || strncmp(pfx,pat,cmp1-pfx) != 0 ) if ( (cmp1-pfx) != (cmp2-pat) || strncmp(pfx,pat,cmp1-pfx) != 0 )
break; break;
} }
result = DmStrDup("");
up = DmStrJoin("..",DirSepStr,-1,FALSE); up = DmStrJoin("..",DirSepStr,-1,FALSE);
cmp1 = pfx; cmp1 = pfx;
/* Add "../" for each directory in pfx */
while ( *(pfx=DmStrSpn(cmp1,DirBrkStr)) != '\0' ) { while ( *(pfx=DmStrSpn(cmp1,DirBrkStr)) != '\0' ) {
cmp1 = DmStrPbrk(pfx,DirBrkStr); cmp1 = DmStrPbrk(pfx,DirBrkStr);
result = DmStrJoin(result,up,-1,TRUE); result = DmStrJoin(result,up,-1,TRUE);
} }
cmp2 = pat; pat = DmStrSpn(pat,DirBrkStr);
while ( *(pat=DmStrSpn(cmp2,DirBrkStr)) != '\0' ) { /* Append pat to result. */
char *tmp; if( *pat != '\0' ) {
char *x; cmp2 = DmStrDup(Build_path(result, pat));
cmp2 = DmStrPbrk(pat, DirBrkStr);
tmp = DmStrDup(Build_path(result,x=DmSubStr(pat,cmp2)));
FREE(result); FREE(result);
FREE(x); result = cmp2;
result = tmp; } else {
/* if pat is empty and result exists remove the trailing slash
* from the last "../". */
if( *result ) {
result[strlen(result)-1] = '\0';
}
} }
return(result); return(result);
...@@ -833,23 +907,33 @@ _expand_dynamic_prq( head, lp, name )/* ...@@ -833,23 +907,33 @@ _expand_dynamic_prq( head, lp, name )/*
======================================= =======================================
The string name can contain one or more target names. Check if these are The string name can contain one or more target names. Check if these are
already a prerequisite for the current target. If not add them to the list already a prerequisite for the current target. If not add them to the list
of prerequisites. If no prerequisites were added set lp->cl_prq to NULL. */ of prerequisites. If no prerequisites were added set lp->cl_prq to NULL.
Set the F_MARK flag to indicate that the prerequisite was expanded.
Use cl_flag instead?? */
LINKPTR head; LINKPTR head;
LINKPTR lp; LINKPTR lp;
char *name; char *name;
{ {
CELLPTR cur = lp->cl_prq; CELLPTR cur = lp->cl_prq;
/* If condition is true, no space is found. */ if( !(*name) ) {
if ( strchr(name, ' ') == NIL(char) ) { /* If name is empty this leaves lp->cl_prq unchanged -> No prerequisite added. */
CELLPTR prq = Def_cell(name); ;
}
else if ( strchr(name, ' ') == NIL(char) ) {
/* If condition above is true, no space is found. */
CELLPTR prq = Def_cell(name);
LINKPTR tmp; LINKPTR tmp;
/* Check if prq already exists. */
for(tmp=head;tmp != NIL(LINK) && tmp->cl_prq != prq;tmp=tmp->cl_next); for(tmp=head;tmp != NIL(LINK) && tmp->cl_prq != prq;tmp=tmp->cl_next);
/* If tmp is NULL then the prerequisite is new and is added to the list. */ /* If tmp is NULL then the prerequisite is new and is added to the list. */
if ( !tmp ) if ( !tmp ) {
/* replace the prerequisite with the expanded version. */
lp->cl_prq = prq; lp->cl_prq = prq;
lp->cl_prq->ce_flag |= F_MARK;
}
} }
else { else {
LINKPTR tlp = lp; LINKPTR tlp = lp;
...@@ -869,7 +953,8 @@ char *name; ...@@ -869,7 +953,8 @@ char *name;
/* If tmp is not NULL the prerequisite already exists. */ /* If tmp is not NULL the prerequisite already exists. */
if ( tmp ) continue; if ( tmp ) continue;
/* Add list elements when more then one new prerequisite is found. */ /* Add list elements behind the first if more then one new
* prerequisite is found. */
if ( first ) { if ( first ) {
first = FALSE; first = FALSE;
} }
...@@ -881,6 +966,7 @@ char *name; ...@@ -881,6 +966,7 @@ char *name;
} }
tlp->cl_prq = prq; tlp->cl_prq = prq;
tlp->cl_prq->ce_flag |= F_MARK;
} }
CLEAR_TOKEN( &token ); CLEAR_TOKEN( &token );
} }
...@@ -891,6 +977,7 @@ char *name; ...@@ -891,6 +977,7 @@ char *name;
lp->cl_flag = 0; lp->cl_flag = 0;
} }
/* Is returned unchanged. */
return(lp); return(lp);
} }
...@@ -1145,7 +1232,7 @@ CELLPTR cp; ...@@ -1145,7 +1232,7 @@ CELLPTR cp;
/* Print command and remove continuation sequence from cmnd. */ /* Print command and remove continuation sequence from cmnd. */
Print_cmnd(cmnd, !(do_it && (l_attr & A_SILENT)), 0); Print_cmnd(cmnd, !(do_it && (l_attr & A_SILENT)), 0);
} }
rval=Do_cmnd(cmnd,FALSE,do_it,cp,(l_attr&A_IGNORE)!=0, shell, rval=Do_cmnd(cmnd,FALSE,do_it,cp,l_attr,
rp->st_next == NIL(STRING) ); rp->st_next == NIL(STRING) );
} }
} }
...@@ -1167,8 +1254,7 @@ CELLPTR cp; ...@@ -1167,8 +1254,7 @@ CELLPTR cp;
chmod(groupfile,0700); chmod(groupfile,0700);
#endif #endif
} }
rval = Do_cmnd(groupfile, TRUE, do_it, cp, (attr & A_IGNORE)!=0, rval = Do_cmnd(groupfile, TRUE, do_it, cp, attr | A_SHELL, TRUE);
TRUE, TRUE);
} }
_recipes[ RP_RECIPE ] = orp; _recipes[ RP_RECIPE ] = orp;
...@@ -1327,103 +1413,19 @@ int ignore; ...@@ -1327,103 +1413,19 @@ int ignore;
static void static void
_set_tmd()/* _set_tmd()/*
============ ============
Set the TMD Macro */ Set the TMD Macro. This is the path from the present directory (value of
$(PWD)) to the directory dmake was started up in (value of $(MAKEDIR)).
*/
{ {
char *m, *p;
char *mend, *pend;
char *mtd, *ptd;
int mleadslash, pleadslash;
char *tmd; char *tmd;
int first = 1;
/* Don't use Get_token because this fails on paths that contain spaces. */
m = DmStrSpn(Makedir, DirBrkStr);
mleadslash = m - Makedir;
p = DmStrSpn(Pwd, DirBrkStr);
pleadslash = p - Pwd;
/* leading slashes can only mean POSIX paths or Windows resources (two)
* slashes. In any case if the number of slashes are not equal there
* can be no relative path from one two the other. Use the Makedir path. */
if(mleadslash != pleadslash) {
tmd = Makedir;
goto tmd_end;
}
/* If Makedir and Pwd are identical skip to the end. */ tmd = _prefix(Pwd, Makedir);
for(mend=m, pend=p; *mend && *pend && *mend==*pend; mend++, pend++) if( *tmd ) {
; Def_macro( "TMD", tmd, M_MULTI | M_EXPANDED );
if( ( ! *mend ) && ( ! *pend ) ) { } else {
tmd = DmStrDup( "." ); Def_macro( "TMD", ".", M_MULTI | M_EXPANDED );
goto tmd_end;
} }
FREE( tmd );
/* If Makedir and Pwd are not identical we will construct TMD. */
tmd = DmStrDup( "" );
do {
/* get the next top directory name */
mend = DmStrPbrk( m, DirBrkStr );
/* For DOSish filenames the first part might be a drive letter */
#if !defined(NO_DRIVE_LETTERS)
if( first && *mend == ':' )
mend++;
#endif
mtd = DmSubStr( m, mend ); /* Free later */
/* {m|p}end either points to a DirBrkStr member or the end of string. */
if(*mend) mend++;
m = mend;
pend = DmStrPbrk( p, DirBrkStr );
#if !defined(NO_DRIVE_LETTERS)
if( first && *pend == ':' )
pend++;
#endif
ptd = DmSubStr( p, pend ); /* Free later */
if(*pend) pend++;
p = pend;
if( strcmp(mtd, ptd) ) { /* they differ */
char *tmp = 0;
if( first ) { /* They differ in the first component */
FREE( tmd );
FREE( mtd );
FREE( ptd );
tmd = Makedir; /* In this case use the full path */
break;
}
if( *ptd ) {
/* Build_path puts a DirSepStr behind the first parameter if
* its length is greater null, even if the second parameter
* is empty. */
if(*tmd)
tmp = Build_path( "..", tmd );
else
tmp = "..";
FREE( tmd );
tmd = DmStrDup( tmp );
}
if( *mtd ) {
tmp = Build_path( tmd, mtd );
FREE( tmd );
tmd = DmStrDup( tmp );
}
}
FREE( mtd );
FREE( ptd );
first = 0;
} while (*m || *p);
tmd_end:
Def_macro( "TMD", tmd, M_MULTI | M_EXPANDED );
if( tmd != Makedir ) FREE( tmd );
} }
......
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