update dev300-m58
[ooovba.git] / dmake / make.c
blob0dfad3b34d3f60c9be85f6e664d8e08bd7b2a2d5
1 /* $RCSfile: make.c,v $
2 -- $Revision: 1.12 $
3 -- last change: $Author: kz $ $Date: 2008-03-05 18:29:19 $
4 --
5 -- SYNOPSIS
6 -- Perform the update of all outdated targets.
7 --
8 -- DESCRIPTION
9 -- This is where we traverse the make graph looking for targets that
10 -- are out of date, and we try to infer how to make them if we can.
11 -- The usual make macros are understood, as well as some new ones:
13 -- $$ - expands to $
14 -- $@ - full target name
15 -- $* - target name with no suffix, same as $(@:db)
16 -- or, the value of % in % meta rule recipes
17 -- $? - list of out of date prerequisites
18 -- $< - all prerequisites associated with rules line
19 -- $& - all prerequisites associated with target
20 -- $> - library name for target (if any)
21 -- $^ - out of date prerequisites taken from value of $<
22 --
23 -- AUTHOR
24 -- Dennis Vadura, dvadura@dmake.wticorp.com
26 -- WWW
27 -- http://dmake.wticorp.com/
29 -- COPYRIGHT
30 -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
31 --
32 -- This program is NOT free software; you can redistribute it and/or
33 -- modify it under the terms of the Software License Agreement Provided
34 -- in the file <distribution-root>/readme/license.txt.
36 -- LOG
37 -- Use cvs log to obtain detailed change logs.
40 #include "extern.h"
41 #include "sysintf.h"
43 typedef struct cell {
44 char *datum;
45 struct cell *next;
46 size_t len;
47 } LISTCELL, *LISTCELLPTR;
49 typedef struct {
50 LISTCELLPTR first;
51 LISTCELLPTR last;
52 size_t len;
53 } LISTSTRING, *LISTSTRINGPTR;
56 static void _drop_mac ANSI((HASHPTR));
57 static void _set_recipe ANSI((char*, int));
58 static void _set_tmd ANSI(());
59 static void _append_file ANSI((STRINGPTR, FILE*, char*, int));
60 static LINKPTR _dup_prq ANSI((LINKPTR));
61 static LINKPTR _expand_dynamic_prq ANSI(( LINKPTR, LINKPTR, char * ));
62 static char* _prefix ANSI((char *, char *));
63 static char* _pool_lookup ANSI((char *));
64 static int _explode_graph ANSI((CELLPTR, LINKPTR, CELLPTR));
67 #define RP_GPPROLOG 0
68 #define RP_RECIPE 1
69 #define RP_GPEPILOG 2
70 #define NUM_RECIPES 3
72 static STRINGPTR _recipes[NUM_RECIPES];
73 static LISTCELLPTR _freelist=NULL;
75 static LISTCELLPTR
76 get_cell()
78 LISTCELLPTR cell;
80 if (!_freelist) {
81 if ((cell=MALLOC(1,LISTCELL)) == NULL)
82 No_ram();
84 else {
85 cell = _freelist;
86 _freelist = cell->next;
89 return(cell);
93 static void
94 free_cell(LISTCELLPTR cell)
96 cell->next = _freelist;
97 _freelist = cell;
101 static void
102 free_list(LISTCELLPTR c)
104 if(c) {
105 free_list(c->next);
106 free_cell(c);
111 static void
112 list_init(LISTSTRINGPTR s)
114 s->first = NULL;
115 s->last = NULL;
116 s->len = 0;
120 static void
121 list_add(LISTSTRINGPTR s, char *str)
123 LISTCELLPTR p;
124 int l;
126 if ((l = strlen(str)) == 0)
127 return;
129 p = get_cell();
130 p->datum = str;
131 p->next = NULL;
132 p->len = l;
134 if(s->first == NULL)
135 s->first = p;
136 else
137 s->last->next = p;
139 s->last = p;
140 s->len += l+1;
144 static char *
145 gen_path_list_string(LISTSTRINGPTR s)/*
146 =======================================
147 Take a list of filepaths and create a string from it separating
148 the filenames by a space.
149 This function honors the cygwin specific .WINPATH attribute. */
151 LISTCELLPTR next, cell;
152 int len;
153 int slen, slen_rest;
154 char *result;
155 char *p, *tpath;
157 if( (slen_rest = slen = s->len) == 0)
158 return(NIL(char));
160 /* reserve enough space to hold the concated original filenames. */
161 if((p = result = MALLOC(slen, char)) == NULL) No_ram();
163 for (cell=s->first; cell; cell=next) {
164 #if !defined(__CYGWIN__)
165 tpath = cell->datum;
166 len=cell->len;
167 #else
168 /* For cygwin with .WINPATH set the lenght of the converted
169 * filepaths might be longer. Extra checking is needed ... */
170 tpath = DO_WINPATH(cell->datum);
171 if( tpath == cell->datum ) {
172 len=cell->len;
174 else {
175 /* ... but only if DO_WINPATH() did something. */
176 len = strlen(tpath);
178 if( len >= slen_rest ) {
179 /* We need more memory. As DOS paths are usually shorter than the
180 * original cygwin POSIX paths (exception mounted paths) this should
181 * rarely happen. */
182 int p_offset = p - result;
183 /* Get more than needed. */
184 slen = slen + len - slen_rest + 128;
185 if((result = realloc( result, slen ) ) == NULL)
186 No_ram();
187 p = result + p_offset;
189 #endif
191 memcpy((void *)p, (void *)tpath, len);
192 p += len;
193 *p++ = ' ';
195 #if defined(__CYGWIN__)
196 /* slen_rest is only used in the cygwin / .WINPATH case. */
197 slen_rest = slen - (p - result);
198 #endif
200 next = cell->next;
201 free_cell(cell);
204 *--p = '\0';
205 list_init(s);
207 return(result);
211 PUBLIC int
212 Make_targets()/*
213 ================
214 Actually go and make the targets on the target list */
216 LINKPTR lp;
217 int done = 0;
219 DB_ENTER( "Make_targets" );
221 Read_state();
222 _set_recipe( ".GROUPPROLOG", RP_GPPROLOG );
223 _set_recipe( ".GROUPEPILOG", RP_GPEPILOG );
225 /* Prevent recipe inference for .ROOT */
226 if ( Root->ce_recipe == NIL(STRING) ) {
227 TALLOC( Root->ce_recipe, 1, STRING );
228 Root->ce_recipe->st_string = "";
231 /* Prevent recipe inference for .TARGETS */
232 if ( Targets->ce_recipe == NIL(STRING) ) {
233 TALLOC( Targets->ce_recipe, 1, STRING );
234 Targets->ce_recipe->st_string = "";
237 /* Make sure that user defined targets are marked as root targets */
238 for( lp = Targets->ce_prq; lp != NIL(LINK); lp = lp->cl_next )
239 lp->cl_prq->ce_attr |= A_ROOT;
241 while( !done ) {
242 int rval;
244 if( (rval = Make(Root, NIL(CELL))) == -1 )
245 DB_RETURN(1);
246 else
247 done = Root->ce_flag & F_MADE;
249 if( !rval && !done ) Wait_for_child( FALSE, -1 );
252 for( lp = Targets->ce_prq; lp != NIL(LINK); lp = lp->cl_next ) {
253 CELLPTR tgt = lp->cl_prq;
254 if( !(tgt->ce_attr & A_UPDATED) )
255 printf( "`%s' is up to date\n", tgt->CE_NAME );
258 DB_RETURN( 0 );
263 PUBLIC int
264 Make( cp, setdirroot )/*
265 ========================
266 Make target cp. Make() is also called on prerequisites that have no rule
267 associated (F_TARGET is not set) to verify that they exist. */
268 CELLPTR cp;
269 CELLPTR setdirroot;
271 register LINKPTR dp, prev,next;
272 register CELLPTR tcp;
273 CELLPTR nsetdirroot;
274 char *name, *lib;
275 HASHPTR m_at, m_q, m_b, m_g, m_l, m_bb, m_up;
276 LISTSTRING all_list, imm_list, outall_list, inf_list;
277 char *all = NIL(char);
278 char *inf = NIL(char);
279 char *outall = NIL(char);
280 char *imm = NIL(char);
281 int rval = 0; /* 0==ready, 1==target still running, -1==error */
282 int push = 0;
283 int made = F_MADE;
284 int ignore;
285 time_t otime = (time_t) 1L; /* Hold time of newest prerequisite. */
286 int mark_made = FALSE;
288 #if defined(__CYGWIN__)
289 /* static variable to hold .WINPATH status of previously made target.
290 * 0, 1 are .WINPATH states, -1 indicates the first target. */
291 static int prev_winpath_attr = -1;
292 #endif
294 DB_ENTER( "Make" );
295 DB_PRINT( "mem", ("%s:-> mem %ld", cp->CE_NAME, (long) coreleft()) );
297 /* Initialize the various temporary storage */
298 m_q = m_b = m_g = m_l = m_bb = m_up = NIL(HASH);
299 list_init(&all_list);
300 list_init(&imm_list);
301 list_init(&outall_list);
302 list_init(&inf_list);
304 if (cp->ce_set && cp->ce_set != cp) {
305 if( Verbose & V_MAKE )
306 printf( "%s: Building .UPDATEALL representative [%s]\n", Pname,
307 cp->ce_set->CE_NAME );
308 cp = cp->ce_set;
311 /* If we are supposed to change directories for this target then do so.
312 * If we do change dir, then modify the setdirroot variable to reflect
313 * that fact for all of the prerequisites that we will be making. */
315 nsetdirroot = setdirroot;
316 ignore = (((cp->ce_attr|Glob_attr)&A_IGNORE) != 0);
318 /* Set the UseWinpath variable to reflect the (global/local) .WINPATH
319 * attribute. The variable is used by DO_WINPATH() and in some other
320 * places. */
321 UseWinpath = (((cp->ce_attr|Glob_attr)&A_WINPATH) != 0);
323 /* m_at needs to be defined before going to a "stop_making_it" where
324 * a _drop_mac( m_at ) would try to free it. */
325 /* FIXME: m_at can most probably not be changed before the next
326 * Def_macro("@", ...) command. Check if both this and the next
327 * call are needed. */
328 m_at = Def_macro("@", DO_WINPATH(cp->ce_fname), M_MULTI);
330 if( cp->ce_attr & A_SETDIR ) {
331 /* Change directory only if the previous .SETDIR is a different
332 * directory from the current one. ie. all cells with the same .SETDIR
333 * attribute are assumed to come from the same directory. */
335 if( (setdirroot == NIL(CELL) || setdirroot->ce_dir != cp->ce_dir) &&
336 (push = Push_dir(cp->ce_dir,cp->CE_NAME,ignore)) != 0 )
337 setdirroot = cp;
340 DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) );
342 /* FIXME: F_MULTI targets don't have cp->ce_recipe set but the recipes
343 * are known nevertheless. It is not necessary to infer them.
344 * If (cp->ce_flag & F_MULTI) is true the recipes of the corresponding
345 * subtargets can be used. */
346 if( cp->ce_recipe == NIL(STRING) ) {
347 char *dir = cp->ce_dir;
349 if( Verbose & V_MAKE )
350 printf( "%s: Infering prerequisite(s) and recipe for [%s]\n", Pname,
351 cp->CE_NAME );
353 Infer_recipe( cp, setdirroot );
355 /* See if the directory has changed, if it has then make sure we
356 * push it. */
357 if( dir != cp->ce_dir ) {
358 if( push ) Pop_dir(FALSE);
359 push = Push_dir( cp->ce_dir, cp->CE_NAME, ignore );
360 setdirroot = cp;
364 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
365 tcp = dp->cl_prq;
366 if( push ) {
367 /* If we changed the directory because of .SETDIR write Pwd into
368 * tcp->ce_dir so that it holds an absolute path. */
369 if( !(tcp->ce_attr & A_POOL) && tcp->ce_dir ) FREE( tcp->ce_dir );
370 tcp->ce_dir = _pool_lookup(Pwd);
371 tcp->ce_attr |= A_SETDIR|A_POOL;
373 tcp->ce_setdir = nsetdirroot;
376 DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) );
377 /* If we have not yet statted the target then do so. */
378 if( !(cp->ce_flag & F_STAT) && !(cp->ce_attr&A_PHONY) ) {
379 if (cp->ce_parent && (cp->ce_parent->ce_flag & F_MULTI)) {
380 /* Inherit the stat info from the F_MULTI parent. */
381 cp->ce_time = cp->ce_parent->ce_time;
382 cp->ce_flag |= F_STAT;
383 /* Propagate the A_PRECIOUS attribute from the parent. */
384 cp->ce_attr |= cp->ce_parent->ce_attr & A_PRECIOUS;
386 else {
387 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
388 tcp = dp->cl_prq;
389 /* Check if target already exists. */
390 Stat_target( tcp, 1, FALSE );
392 if( tcp->ce_time != (time_t)0L ) {
393 /* File exists so don't remove it later. */
394 tcp->ce_attr |= A_PRECIOUS;
397 if( Verbose & V_MAKE )
398 printf("%s: Time stamp of [%s] is %ld\n",Pname,tcp->CE_NAME,
399 tcp->ce_time);
404 DB_PRINT( "make", ("(%s, %ld, 0x%08x, 0x%04x)", cp->CE_NAME,
405 cp->ce_time, cp->ce_attr, cp->ce_flag) );
407 /* Handle targets without rule and without existing file. */
408 if( !(cp->ce_flag & F_TARGET) && (cp->ce_time == (time_t) 0L) ) {
409 if( Makemkf ) {
410 rval = -1;
411 goto stop_making_it;
413 else if( cp->ce_prq != NIL(LINK)
414 || (STOBOOL(Augmake) && (cp->ce_flag&F_EXPLICIT)))
415 /* Assume an empty recipe for a target that we have run inference on
416 * but do not have a set of rules for but for which we have inferred
417 * a list of prerequisites. */
418 cp->ce_flag |= F_RULES;
419 else
420 Fatal( "`%s' not found, and can't be made", cp->CE_NAME );
423 DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) );
425 /* set value of $* if we have not infered a recipe, in this case $* is
426 * the same as $(@:db), this allows us to be compatible with BSD make */
427 if( cp->ce_per == NIL(char) ) cp->ce_per = "$(@:db)";
429 /* Search the prerequisite list for dynamic prerequisites and if we find
430 * them copy the list of prerequisites for potential later re-use. */
431 if ( cp->ce_prqorg == NIL(LINK) ) {
432 for( dp = cp->ce_prq; dp != NIL(LINK); dp = dp->cl_next )
433 if ( strchr(dp->cl_prq->CE_NAME, '$') != NULL )
434 break;
436 if (dp != NIL(LINK)) {
437 cp->ce_prqorg = _dup_prq(cp->ce_prq);
441 /* Define $@ macro. The only reason for defining it here (that I see ATM)
442 * is that $@ is already defined in conditional macros. */
443 /* FIXME: check if both this and the previous Def_macro("@", ...) call
444 * are needed. */
445 m_at = Def_macro("@", DO_WINPATH(cp->ce_fname), M_MULTI);
447 /* Define conditional macros if any, note this is done BEFORE we process
448 * prerequisites for the current target. Thus the making of a prerequisite
449 * is done using the current value of the conditional macro. */
450 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
451 tcp=dp->cl_prq;
452 if (tcp->ce_cond != NIL(STRING)) {
453 STRINGPTR sp;
455 tcp->ce_pushed = NIL(HASH);
456 for(sp=tcp->ce_cond; sp; sp=sp->st_next) {
457 if(Parse_macro(sp->st_string,M_MULTI|M_PUSH)) {
458 HASHPTR hp;
460 hp = GET_MACRO(LastMacName);
461 hp->ht_link = tcp->ce_pushed;
462 tcp->ce_pushed = hp;
464 else {
465 Error("Invalid conditional macro expression [%s]",sp->st_string);
471 /* First round, will be repeated a second time below. */
472 for( prev=NULL,dp=cp->ce_prq; dp != NIL(LINK); prev=dp, dp=next ) {
473 int seq;
475 /* This loop executes Make() to build prerequisites if needed.
476 * The only macro that needs to be reset after a Make() was executed
477 * is $@ as it might be used when expanding potential dynamic
478 * prerequisites. As UseWinpath is a global variable we also
479 * need to restore it. */
480 if (m_at->ht_value == NIL(char)) {
481 /* This check effectively tests if Make() was run before because
482 * Make() frees all dynamic macro values at the end. */
483 UseWinpath = (((cp->ce_attr|Glob_attr)&A_WINPATH) != 0);
484 m_at = Def_macro("@", DO_WINPATH(cp->ce_fname), M_MULTI);
487 /* Make the prerequisite, note that if the current target has the
488 * .LIBRARY attribute set we pass on to the prerequisite the .LIBRARYM
489 * attribute and pass on the name of the current target as the library
490 * name, and we take it away when we are done. */
491 next = dp->cl_next;
493 tcp = dp->cl_prq;
494 if( Verbose & V_MAKE )
495 printf("Checking prerequisite [%s]\n", tcp->CE_NAME);
497 seq = (((cp->ce_attr | Glob_attr) & A_SEQ) != 0);
499 /* This checks if this prerequisite is still in the making, if yes
500 * come back later. */
501 if( tcp->ce_flag & F_VISITED ) {
502 /* Check if this currently or fully made target has the same
503 * .SETDIR setting. If yes, continue if it was made or come
504 * back later otherwise. */
505 if( _explode_graph(tcp, dp, setdirroot) == 0 ) {
506 /* didn't blow it up so see if we need to wait for it. */
507 if( tcp->ce_flag & F_MADE ) {
508 /* Target was made. */
509 continue;
511 else
512 /* Target is still in the making ... */
513 goto stop_making_it;
515 else
516 /* Use the new prerequisite with the new .SETDIR value. */
517 tcp = dp->cl_prq;
520 /* If the previous target (prereq) is not yet ready return if
521 * seq is TRUE. */
522 if( seq && !made ) goto stop_making_it;
524 /* Expand dynamic prerequisites. The F_MARK flag is guarging against
525 * possible double expandion of dynamic prerequisites containing more
526 * than one prerequisite. */
527 /* A new A_DYNAMIC attribute could save a lot of strchr( ,'$') calls. */
528 if ( tcp && !(tcp->ce_flag & F_MARK) && strchr(tcp->CE_NAME, '$') ) {
529 /* Replace this dynamic prerequisite with the the real prerequisite,
530 * and add the additional prerequisites if there are more than one.*/
532 name = Expand( tcp->CE_NAME );
533 if( strcmp(name,cp->CE_NAME) == 0 )
534 Fatal("Detected circular dynamic dependency; generated '%s'",name);
536 /* Call helper for dynamic prerequisite expansion to replace the
537 * prerequisite with the expanded version and add the new
538 * prerequisites, if the macro expanded to more than one, after
539 * the current list element. */
540 dp = _expand_dynamic_prq( cp->ce_prq, dp, name );
541 FREE( name );
543 /* _expand_dynamic_prq() probably changed dp->cl_prq. */
544 tcp = dp->cl_prq;
545 if ( tcp ) {
546 next = dp->cl_next;
550 /* Dynamic expansion results in a NULL cell only when the the new
551 * prerequisite is already in the prerequisite list or empty. In this
552 * case delete the cell and continue. */
553 if ( tcp == NIL(CELL) ) {
554 FREE(dp);
555 if ( prev == NIL(LINK) ) {
556 cp->ce_prq = next;
557 dp = NULL; /* dp will be the new value of prev. */
559 else {
560 prev->cl_next = next;
561 dp = prev;
563 continue;
566 /* Clear F_MARK flag that could have been set by _expand_dynamic_prq(). */
567 tcp->ce_flag &= ~(F_MARK);
569 if( cp->ce_attr & A_LIBRARY ) {
570 tcp->ce_attr |= A_LIBRARYM;
571 tcp->ce_lib = cp->ce_fname;
574 /* Propagate the parent's F_REMOVE and F_INFER flags to the
575 * prerequisites. */
576 tcp->ce_flag |= cp->ce_flag & (F_REMOVE|F_INFER);
578 /* Propagate parents A_ROOT attribute to a child if the parent is a
579 * F_MULTI target. */
580 if( (cp->ce_flag & F_MULTI) && (cp->ce_attr & A_ROOT) )
581 tcp->ce_attr |= A_ROOT;
583 tcp->ce_parent = cp;
584 rval |= Make(tcp, setdirroot);
586 if( cp->ce_attr & A_LIBRARY )
587 tcp->ce_attr ^= A_LIBRARYM;
589 /* Return on error or if Make() is still running and A_SEQ is set.
590 * (All F_MULTI targets have the A_SEQ attribute.) */
591 if( rval == -1 || (seq && (rval==1)) )
592 goto stop_making_it;
594 /* If tcp is ready, set made = F_MADE. */
595 made &= tcp->ce_flag & F_MADE;
599 /* Do the loop again. We are most definitely going to make the current
600 * cell now. NOTE: doing this loop here also results in a reduction
601 * in peak memory usage by the algorithm. */
603 for( dp = cp->ce_prq; dp != NIL(LINK); dp = dp->cl_next ) {
604 int tgflg;
605 tcp = dp->cl_prq;
606 if( tcp == NIL(CELL) )
607 Fatal("Internal Error: Found prerequisite list cell without prerequisite!");
609 name = tcp->ce_fname;
611 /* make certain that all prerequisites are made prior to advancing. */
612 if( !(tcp->ce_flag & F_MADE) ) goto stop_making_it;
614 /* If the target is a library, then check to make certain that a member
615 * is newer than an object file sitting on disk. If the disk version
616 * is newer then set the time stamps so that the archived member is
617 * replaced. */
618 if( cp->ce_attr & A_LIBRARY )
619 if( tcp->ce_time <= cp->ce_time ) {
620 time_t mtime = Do_stat( name, tcp->ce_lib, NIL(char *), FALSE );
621 if( mtime < tcp->ce_time ) tcp->ce_time = cp->ce_time+1L;
624 /* Set otime to the newest time stamp of all prereqs or 1 if there
625 * are no prerequisites. */
626 if( tcp->ce_time > otime ) otime = tcp->ce_time;
628 list_add(&all_list, name);
629 if( (tgflg = (dp->cl_flag & F_TARGET)) != 0 )
630 list_add(&inf_list, name);
632 if((cp->ce_time<tcp->ce_time) || ((tcp->ce_flag & F_TARGET) && Force)) {
633 list_add(&outall_list, name);
634 if( tgflg )
635 list_add(&imm_list, name);
639 /* If we are building a F_MULTI target inherit the time from
640 * its children. */
641 if( (cp->ce_flag & F_MULTI) )
642 cp->ce_time = otime;
644 /* All prerequisites are made, now make the current target. */
646 /* Restore UseWinpath and $@ if needed, see above for an explanation. */
647 if (m_at->ht_value == NIL(char)) {
648 /* This check effectively tests if Make() was run before because
649 * Make() frees all dynamic macro values at the end. */
650 UseWinpath = (((cp->ce_attr|Glob_attr)&A_WINPATH) != 0);
651 m_at = Def_macro("@", DO_WINPATH(cp->ce_fname), M_MULTI);
654 /* Create a string with all concatenate filenames. The function
655 * respects .WINPATH. Note that gen_path_list_string empties its
656 * parameter :( */
657 all = gen_path_list_string(&all_list);
658 imm = gen_path_list_string(&imm_list);
659 outall = gen_path_list_string(&outall_list);
660 inf = gen_path_list_string(&inf_list);
662 DB_PRINT( "mem", ("%s:-C mem %ld", cp->CE_NAME, (long) coreleft()) );
663 DB_PRINT( "make", ("I make '%s' if %ld > %ld", cp->CE_NAME, otime,
664 cp->ce_time) );
666 if( Verbose & V_MAKE ) {
667 printf( "%s: >>>> Making ", Pname );
668 /* Also print the F_MULTI master target. */
669 if( cp->ce_flag & F_MULTI )
670 printf( "(::-\"master\" target) " );
671 if( cp->ce_count != 0 )
672 printf( "[%s::{%d}]\n", cp->CE_NAME, cp->ce_count );
673 else
674 printf( "[%s]\n", cp->CE_NAME );
678 /* Only PWD, TMD, MAKEDIR and the dynamic macros are affected by
679 * .WINPATH. $@ is handled earlier, do the rest now. */
680 #if defined(__CYGWIN__)
681 /* This is only relevant for cygwin. */
682 if( UseWinpath != prev_winpath_attr ) {
683 Def_macro( "MAKEDIR", Makedir, M_FORCE | M_EXPANDED );
684 /* If push is TRUE (Push_dir() was used) PWD and TMD are already
685 * set. */
686 if( !push ) {
687 Def_macro( "PWD", Pwd, M_FORCE | M_EXPANDED );
688 _set_tmd();
691 prev_winpath_attr = UseWinpath;
692 #endif
694 /* Set the remaining dynamic macros $*, $>, $?, $<, $& and $^. */
696 /* $* is either expanded as the result of a % inference or defined to
697 * $(@:db) and hence unexpanded otherwise. The latter doesn't start
698 * with / and will therefore not be touched by DO_WINPATH(). */
699 m_bb = Def_macro( "*", DO_WINPATH(cp->ce_per), M_MULTI );
701 /* This is expanded. */
702 m_g = Def_macro( ">", DO_WINPATH(cp->ce_lib), M_MULTI|M_EXPANDED );
703 /* These strings are generated with gen_path_list_string() and honor
704 * .WINPATH */
705 m_q = Def_macro( "?", outall, M_MULTI|M_EXPANDED );
706 m_b = Def_macro( "<", inf, M_MULTI|M_EXPANDED );
707 m_l = Def_macro( "&", all, M_MULTI|M_EXPANDED );
708 m_up = Def_macro( "^", imm, M_MULTI|M_EXPANDED );
710 _recipes[ RP_RECIPE ] = cp->ce_recipe;
712 /* We attempt to make the target if
713 * 1. it has a newer prerequisite
714 * 2. It is a target and Force is set
715 * 3. It's set of recipe lines has changed.
717 if( Check_state(cp, _recipes, NUM_RECIPES )
718 || (cp->ce_time < otime)
719 || ((cp->ce_flag & F_TARGET) && Force)
722 if( Measure & M_TARGET )
723 Do_profile_output( "s", M_TARGET, cp );
725 /* Only checking so stop as soon as we determine we will make
726 * something */
727 if( Check ) {
728 rval = -1;
729 goto stop_making_it;
732 if( Verbose & V_MAKE )
733 printf( "%s: Updating [%s], (%ld > %ld)\n", Pname,
734 cp->CE_NAME, otime, cp->ce_time );
736 /* In order to check if a targets time stamp was properly updated
737 * after the target was made and to keep the dependency chain valid
738 * for targets without recipes we store the minimum required file
739 * time. If the target time stamp is older than the newest
740 * prerequisite use that time, otherwise the current time. (This
741 * avoids the call to Do_time() for every target, still checks
742 * if the target time is new enough for the given prerequisite and
743 * mintime is also the newest time of the given prerequisites and
744 * can be used for targets without recipes.)
745 * We reuse the ce_time member to store this minimum time until
746 * the target is finished by Update_time_stamp(). This function
747 * checks if the file time was updated properly and warns if it was
748 * not. (While making a target this value does not change.) */
749 cp->ce_time = ( cp->ce_time < otime ? otime : Do_time() );
750 DB_PRINT( "make", ("Set ce_time (mintime) to: %ld", cp->ce_time) );
752 if( Touch ) {
753 name = cp->ce_fname;
754 lib = cp->ce_lib;
756 if( (!(Glob_attr & A_SILENT) || !Trace) && !(cp->ce_attr & A_PHONY) ) {
757 if( lib == NIL(char) )
758 printf("touch(%s)", name );
759 else if( cp->ce_attr & A_SYMBOL )
760 printf("touch(%s((%s)))", lib, name );
761 else
762 printf("touch(%s(%s))", lib, name );
765 if( !Trace && !(cp->ce_attr & A_PHONY) )
766 if( Do_touch( name, lib,
767 (cp->ce_attr & A_SYMBOL) ? &name : NIL(char *) ) != 0 )
768 printf( " not touched - non-existant" );
770 if( (!(Glob_attr & A_SILENT) || !Trace) && !(cp->ce_attr & A_PHONY) )
771 printf( "\n" );
773 Update_time_stamp( cp );
775 else if( cp->ce_recipe != NIL(STRING) ) {
776 /* If a recipe is found use it. Note this misses F_MULTI targets. */
777 if( !(cp->ce_flag & F_SINGLE) ) /* Execute the recipes once ... */
778 rval = Exec_commands( cp );
779 /* Update_time_stamp() is called inside Exec_commands() after the
780 * last recipe line is finished. (In _finished_child()) */
781 else { /* or for every out of date dependency
782 * if the ruleop ! was used. */
783 TKSTR tk;
785 /* We will redefine $? to be the prerequisite that the recipes
786 * are currently evaluated for. */
787 _drop_mac( m_q );
789 /* Execute recipes for each out out of date prerequisites.
790 * WARNING! If no prerequisite is given the recipes are not
791 * executed at all! */
792 if( outall && *outall ) {
793 /* Wait for each prerequisite to finish, save the status
794 * of Wait_for_completion. */
795 int wait_for_completion_status = Wait_for_completion;
796 Wait_for_completion = TRUE;
798 SET_TOKEN( &tk, outall );
800 /* No need to update the target timestamp/removing temporary
801 * prerequisites (Update_time_stamp() in _finished_child())
802 * until all prerequisites are done. */
803 Doing_bang = TRUE;
804 name = Get_token( &tk, "", FALSE );
805 /* This loop might fail if outall contains filenames with
806 * spaces. */
807 do {
808 /* Set $? to current prerequisite. */
809 m_q->ht_value = name;
811 rval = Exec_commands( cp );
812 /* Thanks to Wait_for_completion = TRUE we are allowed
813 * to remove the temp files here. */
814 Unlink_temp_files(cp);
816 while( *(name = Get_token( &tk, "", FALSE )) != '\0' );
817 Wait_for_completion = wait_for_completion_status;
818 Doing_bang = FALSE;
821 Update_time_stamp( cp );
822 /* Erase $? again. Don't free the pointer, it was part of outall. */
823 m_q->ht_value = NIL(char);
826 else if( !(cp->ce_flag & F_RULES) && !(cp->ce_flag & F_STAT) &&
827 (!(cp->ce_attr & A_ROOT) || !(cp->ce_flag & F_EXPLICIT)) &&
828 !(cp->ce_count) )
829 /* F_MULTI subtargets should evaluate its parents F_RULES value
830 * but _make_multi always sets the F_RULES value of the master
831 * target. Assume F_RULES is set for subtargets. This might not
832 * be true if there are no prerequisites and no recipes in any
833 * of the subtargets. (FIXME) */
834 Fatal( "Don't know how to make `%s'",cp->CE_NAME );
835 else {
836 /* Empty recipe, set the flag as MADE and update the time stamp */
837 /* This might be a the master cell of a F_MULTI target. */
838 Update_time_stamp( cp );
841 else {
842 if( Verbose & V_MAKE )
843 printf( "%s: Up to date [%s], prq time = %ld , target time = %ld)\n", Pname,
844 cp->CE_NAME, otime, cp->ce_time );
845 mark_made = TRUE;
848 /* If mark_made == TRUE the target is up-to-date otherwise it is
849 * currently in the making. */
851 /* Update all targets in .UPDATEALL rule / only target cp. */
852 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
853 tcp=dp->cl_prq;
855 /* Set the time stamp of those prerequisites without rule to the current
856 * time if Force is TRUE to make sure that targets depending on those
857 * prerequisites get remade. */
858 if( !(tcp->ce_flag & F_TARGET) && Force ) tcp->ce_time = Do_time();
859 if( mark_made ) {
860 tcp->ce_flag |= F_MADE;
861 if( tcp->ce_flag & F_MULTI ) {
862 LINKPTR tdp;
863 for( tdp = tcp->ce_prq; tdp != NIL(LINK); tdp = tdp->cl_next )
864 tcp->ce_attr |= tdp->cl_prq->ce_attr & A_UPDATED;
868 /* Note that the target is in the making. */
869 tcp->ce_flag |= F_VISITED;
871 /* Note: If the prerequisite was made using a .SETDIR= attribute
872 * directory then we will include the directory in the fname
873 * of the target. */
874 if( push ) {
875 char *dir = nsetdirroot ? nsetdirroot->ce_dir : Makedir;
876 /* get relative path from current SETDIR to new SETDIR. */
877 /* Attention, even with .WINPATH set this has to be a POSIX
878 * path as ce_fname neeed to be POSIX. */
879 char *pref = _prefix( dir, tcp->ce_dir );
880 char *nname = Build_path(pref, tcp->ce_fname);
882 FREE(pref);
883 if( (tcp->ce_attr & A_FFNAME) && (tcp->ce_fname != NIL(char)) )
884 FREE( tcp->ce_fname );
886 tcp->ce_fname = DmStrDup(nname);
887 tcp->ce_attr |= A_FFNAME;
891 stop_making_it:
892 _drop_mac( m_g );
893 _drop_mac( m_q );
894 _drop_mac( m_b );
895 _drop_mac( m_l );
896 _drop_mac( m_bb );
897 _drop_mac( m_up );
898 _drop_mac( m_at );
900 /* undefine conditional macros if any */
901 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
902 tcp=dp->cl_prq;
904 while (tcp->ce_pushed != NIL(HASH)) {
905 HASHPTR cur = tcp->ce_pushed;
906 tcp->ce_pushed = cur->ht_link;
908 Pop_macro(cur);
909 FREE(cur->ht_name);
910 if(cur->ht_value)
911 FREE(cur->ht_value);
912 FREE(cur);
916 if( push )
917 Pop_dir(FALSE);
919 /* Undefine the strings that we used for constructing inferred
920 * prerequisites. */
921 if( inf != NIL(char) ) FREE( inf );
922 if( all != NIL(char) ) FREE( all );
923 if( imm != NIL(char) ) FREE( imm );
924 if( outall != NIL(char) ) FREE( outall );
925 free_list(all_list.first);
926 free_list(imm_list.first);
927 free_list(outall_list.first);
928 free_list(inf_list.first);
930 DB_PRINT( "mem", ("%s:-< mem %ld", cp->CE_NAME, (long) coreleft()) );
931 DB_RETURN(rval);
935 static char *
936 _prefix( pfx, pat )/*
937 =====================
938 Return the relative path from pfx to pat. Both paths have to be absolute
939 paths. If the paths are on different resources or drives (if applicable)
940 or only share a relative path going up to the root dir and down again
941 return pat. */
942 char *pfx;
943 char *pat;
945 char *cmp1=pfx;
946 char *cmp2=pat;
947 char *tpat=pat; /* Keep pointer to original pat. */
948 char *result;
949 char *up;
950 int first = 1;
951 int samerootdir = 1; /* Marks special treatment for the root dir. */
952 #ifdef HAVE_DRIVE_LETTERS
953 int pfxdl = 0;
954 int patdl = 0;
955 #endif
957 /* Micro optimization return immediately if pfx and pat are equal. */
958 if( strcmp(pfx, pat) == 0 )
959 return(DmStrDup(""));
961 #ifdef HAVE_DRIVE_LETTERS
962 /* remove the drive letters to avoid getting them into the relative
963 * path later. */
964 if( *pfx && pfx[1] == ':' && isalpha(*pfx) ) {
965 pfxdl = 1;
966 cmp1 = DmStrSpn(pfx+2, DirBrkStr);
968 if( *pat && pat[1] == ':' && isalpha(*pat) ) {
969 patdl = 1;
970 cmp2 = DmStrSpn(pat+2, DirBrkStr);
972 /* If the drive letters are different use the abs. path. */
973 if( pfxdl && patdl && (tolower(*pfx) != tolower(*pat)) )
974 return(DmStrDup(pat));
976 /* If only one has a drive letter also use the abs. path. */
977 if( pfxdl != patdl )
978 return(DmStrDup(pat));
979 else if( pfxdl )
980 /* If both are the same drive letter, disable the special top
981 * dir treatment. */
982 samerootdir = 0;
984 /* Continue without the drive letters. (Either none was present,
985 * or both were the same. This also solves the problem that the
986 * case of the drive letters sometimes depends on the shell.
987 * (cmd.exe vs. cygwin bash) */
988 pfx = cmp1;
989 pat = cmp2;
990 #endif
992 /* Cut off equal leading parts of pfx, pat. Both have to be abs. paths. */
993 while(*pfx && *pat) {
994 /* skip leading dir. separators. */
995 pfx = DmStrSpn(cmp1, DirBrkStr);
996 pat = DmStrSpn(cmp2, DirBrkStr);
998 /* Only check in the first run of the loop. Leading slashes can only
999 * mean POSIX paths or Windows resources (two) slashes. Drive letters
1000 * have no leading slash. In any case, if the number of slashes are
1001 * not equal there can be no relative path from one two the other.
1002 * In this case return the absolute path. */
1003 if( first ) {
1004 if( cmp1-pfx != cmp2-pat ) {
1005 return(DmStrDup(tpat));
1007 first = 0;
1010 /* find next dir. separator (or ""). */
1011 cmp1 = DmStrPbrk(pfx, DirBrkStr);
1012 cmp2 = DmStrPbrk(pat, DirBrkStr);
1014 /* if length of directory name is equal compare the strings. If equal
1015 * go into next loop. If not equal and directory names in the root
1016 * dir are compared return the absolut path otherwise break the loop
1017 * and construct the relative path from pfx to pat. */
1018 if ( (cmp1-pfx) != (cmp2-pat) || strncmp(pfx,pat,cmp1-pfx) != 0 ) {
1019 if( samerootdir ) {
1020 return(DmStrDup(tpat));
1022 break;
1025 if( samerootdir ) {
1026 #if __CYGWIN__
1027 /* If the toplevel directory is /cygdrive (or the equivalent prefix)
1028 * treat the following level also as rootdir. If we are here cmp1-pfx
1029 * cannot be zero so we won't compare with an empty cygdrive prefix. */
1030 if ( (cmp1-pfx) == CygDrvPreLen && strncmp(pfx,CygDrvPre,CygDrvPreLen) == 0 )
1031 samerootdir = 1;
1032 else
1033 #endif
1034 samerootdir = 0;
1038 result = DmStrDup("");
1039 up = DmStrJoin("..",DirSepStr,-1,FALSE);
1040 cmp1 = pfx;
1041 /* Add "../" for each directory in pfx */
1042 while ( *(pfx=DmStrSpn(cmp1,DirBrkStr)) != '\0' ) {
1043 cmp1 = DmStrPbrk(pfx,DirBrkStr);
1044 result = DmStrJoin(result,up,-1,TRUE);
1047 pat = DmStrSpn(pat,DirBrkStr);
1048 /* Append pat to result. */
1049 if( *pat != '\0' ) {
1050 cmp2 = DmStrDup(Build_path(result, pat));
1051 FREE(result);
1052 result = cmp2;
1053 } else {
1054 /* if pat is empty and result exists remove the trailing slash
1055 * from the last "../". */
1056 if( *result ) {
1057 result[strlen(result)-1] = '\0';
1061 return(result);
1065 static LINKPTR
1066 _dup_prq( lp )
1067 LINKPTR lp;
1069 LINKPTR tlp;
1071 if( lp == NIL(LINK) ) return(lp);
1073 TALLOC(tlp, 1, LINK);
1074 tlp->cl_prq = lp->cl_prq;
1075 tlp->cl_flag = lp->cl_flag;
1076 tlp->cl_next = _dup_prq( lp->cl_next );
1078 return(tlp);
1082 static LINKPTR
1083 _expand_dynamic_prq( head, lp, name )/*
1084 =======================================
1085 The string name can contain one or more target names. Check if these are
1086 already a prerequisite for the current target. If not add them to the list
1087 of prerequisites. If no prerequisites were added set lp->cl_prq to NULL.
1088 Set the F_MARK flag to indicate that the prerequisite was expanded.
1089 Use cl_flag instead?? */
1090 LINKPTR head;
1091 LINKPTR lp;
1092 char *name;
1094 CELLPTR cur = lp->cl_prq;
1096 if( !(*name) ) {
1097 /* If name is empty this leaves lp->cl_prq unchanged -> No prerequisite added. */
1100 else if ( strchr(name, ' ') == NIL(char) ) {
1101 /* If condition above is true, no space is found. */
1102 CELLPTR prq = Def_cell(name);
1103 LINKPTR tmp;
1105 /* Check if prq already exists. */
1106 for(tmp=head;tmp != NIL(LINK) && tmp->cl_prq != prq;tmp=tmp->cl_next);
1108 /* If tmp is NULL then the prerequisite is new and is added to the list. */
1109 if ( !tmp ) {
1110 /* replace the prerequisite with the expanded version. */
1111 lp->cl_prq = prq;
1112 lp->cl_prq->ce_flag |= F_MARK;
1115 else {
1116 LINKPTR tlp = lp;
1117 LINKPTR next = lp->cl_next;
1118 TKSTR token;
1119 char *p;
1120 int first=TRUE;
1122 /* Handle more than one prerequisite. */
1123 SET_TOKEN(&token, name);
1124 while (*(p=Get_token(&token, "", FALSE)) != '\0') {
1125 CELLPTR prq = Def_cell(p);
1126 LINKPTR tmp;
1128 for(tmp=head;tmp != NIL(LINK) && tmp->cl_prq != prq;tmp=tmp->cl_next);
1130 /* If tmp is not NULL the prerequisite already exists. */
1131 if ( tmp ) continue;
1133 /* Add list elements behind the first if more then one new
1134 * prerequisite is found. */
1135 if ( first ) {
1136 first = FALSE;
1138 else {
1139 TALLOC(tlp->cl_next,1,LINK);
1140 tlp = tlp->cl_next;
1141 tlp->cl_flag |= F_TARGET;
1142 tlp->cl_next = next;
1145 tlp->cl_prq = prq;
1146 tlp->cl_prq->ce_flag |= F_MARK;
1148 CLEAR_TOKEN( &token );
1151 /* If the condition is true no new prerequisits were found. */
1152 if ( lp->cl_prq == cur ) {
1153 lp->cl_prq = NIL(CELL);
1154 lp->cl_flag = 0;
1157 /* Is returned unchanged. */
1158 return(lp);
1162 static void
1163 _drop_mac( hp )/*
1164 ================ set a macro value to zero. */
1165 HASHPTR hp;
1167 if( hp && hp->ht_value != NIL(char) ) {
1168 FREE( hp->ht_value );
1169 hp->ht_value = NIL(char);
1175 static int
1176 _explode_graph( cp, parent, setdirroot )/*
1177 ==========================================
1178 Check to see if we have made the node already. If so then don't do
1179 it again, except if the cell's ce_setdir field is set to something other
1180 than the value of setdirroot. If they differ then, and we have made it
1181 already, then make it again and set the cell's stat bit to off so that
1182 we do the stat again. */
1183 CELLPTR cp;
1184 LINKPTR parent;
1185 CELLPTR setdirroot;
1187 static CELLPTR removecell = NIL(CELL);
1189 if ( removecell == NIL(CELL) )
1190 removecell = Def_cell(".REMOVE");
1192 /* we may return if we made it already from the same setdir location,
1193 * or if it is not a library member whose lib field is non NULL. (if
1194 * it is such a member then we have a line of the form:
1195 * lib1 lib2 .LIBRARY : member_list...
1196 * and we have to make sure all members are up to date in both libs. */
1198 if ( setdirroot == removecell )
1199 return( 0 );
1201 if( cp->ce_setdir == setdirroot &&
1202 !((cp->ce_attr & A_LIBRARYM) && (cp->ce_lib != NIL(char))) )
1203 return( 0 );
1205 /* We check to make sure that we are comming from a truly different
1206 * directory, ie. ".SETDIR=joe : a.c b.c d.c" are all assumed to come
1207 * from the same directory, even though setdirroot is different when
1208 * making dependents of each of these targets. */
1210 if( cp->ce_setdir != NIL(CELL) &&
1211 setdirroot != NIL(CELL) &&
1212 cp->ce_dir &&
1213 setdirroot->ce_dir &&
1214 !strcmp(cp->ce_dir, setdirroot->ce_dir) )
1215 return( 0 );
1217 if( Max_proc > 1 ) {
1218 LINKPTR dp;
1220 TALLOC(parent->cl_prq, 1, CELL);
1221 *parent->cl_prq = *cp;
1222 cp = parent->cl_prq;
1223 cp->ce_prq = _dup_prq(cp->ce_prqorg);
1224 cp->ce_all.cl_prq = cp;
1225 CeNotMe(cp) = _dup_prq(CeNotMe(cp));
1227 for(dp=CeNotMe(cp);dp;dp=dp->cl_next) {
1228 CELLPTR tcp = dp->cl_prq;
1229 TALLOC(dp->cl_prq,1,CELL);
1230 *dp->cl_prq = *tcp;
1231 dp->cl_prq->ce_flag &= ~(F_STAT|F_VISITED|F_MADE);
1232 dp->cl_prq->ce_set = cp;
1235 cp->ce_flag &= ~(F_STAT|F_VISITED|F_MADE);
1237 /* Indicate that we exploded the graph and that the current node should
1238 * be made. */
1239 return(1);
1244 PUBLIC int
1245 Exec_commands( cp )/*
1246 =====================
1247 Execute the commands one at a time that are pointed to by the rules pointer
1248 of the target cp if normal (non-group) recipes are defined. If a group recipe
1249 is found all commands are written into a temporary file first and this
1250 (group-) shell script is executed all at once.
1251 If a group is indicated, then the ce_attr determines .IGNORE and .SILENT
1252 treatment for the group.
1254 The function returns 0, if the command is executed and has successfully
1255 returned, and it returns 1 if the command is executing but has not yet
1256 returned or -1 if an error occured (Return value from Do_cmnd()).
1258 Macros that are found in recipe lines are expanded in this function, in
1259 parallel builds this can mean they are expanded before the previous recipe
1260 lines are finished. (Exception: $(shell ..) waits until all previous recipe
1261 lines are done.)
1263 The F_MADE bit in the cell is guaranteed set when the command has
1264 successfully completed. */
1265 CELLPTR cp;
1267 static HASHPTR useshell = NIL(HASH);
1268 static HASHPTR command = NIL(HASH);
1269 static int read_cmnd = 0;
1270 register STRINGPTR rp;
1271 STRINGPTR orp;
1272 char *cmnd;
1273 char *groupfile;
1274 FILE *tmpfile = 0;
1275 int do_it;
1276 t_attr attr;
1277 int group;
1278 int trace;
1279 int rval = 0;
1281 DB_ENTER( "Exec_commands" );
1283 if( cp->ce_recipe == NIL(STRING) )
1284 Fatal("Internal Error: No recipe found!");
1286 attr = Glob_attr | cp->ce_attr;
1287 trace = Trace || !(attr & A_SILENT);
1288 group = cp->ce_flag & F_GROUP;
1290 /* Do it again here for those that call us from places other than Make()
1291 * above. */
1292 orp = _recipes[ RP_RECIPE ];
1293 _recipes[ RP_RECIPE ] = cp->ce_recipe;
1295 if( group ) {
1296 /* Leave this assignment of Current_target here. It is needed just
1297 * incase the user hits ^C after the tempfile for the group recipe
1298 * has been opened. */
1299 Current_target = cp;
1300 trace = Trace || !(attr & A_SILENT);
1302 if( !Trace ) tmpfile = Start_temp( Grp_suff, cp, &groupfile );
1303 if( trace ) fputs( "[\n", stdout );
1305 /* Emit group prolog */
1306 if( attr & A_PROLOG )
1307 _append_file( _recipes[RP_GPPROLOG], tmpfile, cp->CE_NAME, trace );
1310 if( !useshell )
1311 useshell=Def_macro("USESHELL",NIL(char),M_MULTI|M_EXPANDED);
1313 if( !read_cmnd ) {
1314 command = GET_MACRO("COMMAND");
1315 read_cmnd = 1;
1318 /* Process commands in recipe. If in group, merely append to file.
1319 * Otherwise, run them. */
1320 for( rp=_recipes[RP_RECIPE]; rp != NIL(STRING); rp=rp->st_next) {
1321 t_attr a_attr = A_DEFAULT;
1322 t_attr l_attr;
1323 char *p;
1324 int new_attr = FALSE;
1325 int shell; /* True if the recipe shall run in shell. */
1327 /* Reset it for each recipe line otherwise tempfiles don't get removed.
1328 * Since processing of $(mktmp ...) depends on Current_target being
1329 * correctly set. */
1330 Current_target = cp;
1332 /* Only check for +,-,%,@ if the recipe line begins with a '$' macro
1333 * expansion. Otherwise there is no way it is going to find these
1334 * now. */
1335 if( *rp->st_string == '$' && !group ) {
1336 t_attr s_attr = Glob_attr;
1337 Glob_attr |= A_SILENT;
1338 Suppress_temp_file = TRUE;
1339 cmnd = Expand(rp->st_string);
1340 Suppress_temp_file = FALSE;
1341 a_attr |= Rcp_attribute(cmnd);
1342 FREE(cmnd);
1343 ++new_attr;
1344 Glob_attr = s_attr;
1347 l_attr = attr|a_attr|rp->st_attr;
1348 shell = ((l_attr & A_SHELL) != 0);
1349 useshell->ht_value = (group||shell)?"yes":"no";
1351 /* All macros are expanded before putting them in the "process queue".
1352 * Nothing in Expand() should be able to change dynamic macros. */
1353 cmnd = Expand( rp->st_string );
1355 if( new_attr && (p = DmStrSpn(cmnd," \t\n+-@%")) != cmnd )
1356 strcpy(cmnd,p);
1358 /* COMMAND macro is set to "$(CMNDNAME) $(CMNDARGS)" by default, it is
1359 * possible for the user to reset it to, for example
1360 * COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS))
1361 * in order to get a different interface for his command execution. */
1362 if( command != NIL(HASH) && !group ) {
1363 char *cname = cmnd;
1364 char cmndbuf[30];
1366 if ( *(p=DmStrPbrk(cmnd," \t\n")) != '\0' ) {
1367 *p = '\0';
1368 (void)Def_macro("CMNDARGS",DmStrSpn(p+1," \t\n"),M_MULTI|M_EXPANDED);
1370 else
1371 (void) Def_macro("CMNDARGS","",M_MULTI|M_EXPANDED);
1373 (void) Def_macro("CMNDNAME",cname,M_MULTI|M_EXPANDED);
1375 strcpy(cmndbuf, "$(COMMAND)");
1376 cmnd = Expand(cmndbuf);
1377 FREE(cname); /* cname == cmnd at this point. */
1379 /* Collect up any new attributes */
1380 l_attr |= Rcp_attribute(cmnd);
1381 shell = ((l_attr & A_SHELL) != 0);
1383 /* clean up the attributes that we may have just added. */
1384 if( (p = DmStrSpn(cmnd," \t\n+-@%")) != cmnd )
1385 strcpy(cmnd,p);
1388 #if defined(MSDOS)
1389 Swap_on_exec = ((l_attr & A_SWAP) != 0); /* Swapping for DOS only */
1390 #endif
1391 do_it = !Trace;
1393 /* We force execution of the recipe if we are tracing and the .EXECUTE
1394 * attribute was given or if the it is not a group recipe and the
1395 * recipe line contains the string $(MAKE). Wait_for_completion might
1396 * be changed gobaly but this is without consequences as we wait for
1397 * every recipe with .EXECUTE and don't start anything else. */
1398 if( Trace
1399 && ((l_attr & A_EXECUTE)||(!group && DmStrStr(rp->st_string,"$(MAKE)")))
1401 Wait_for_completion |= Trace;
1402 do_it = TRUE;
1405 if( group )
1406 /* Append_line() calls Print_cmnd(). */
1407 Append_line( cmnd, TRUE, tmpfile, cp->CE_NAME, trace, 0 );
1408 else {
1409 /* Don't print empty recipe lines. .ROOT and .TARGETS
1410 * deliberately might have empty "" recipes and we don't want
1411 * to output empty recipe lines for them. */
1412 if ( *cmnd ) {
1413 /* Print command and remove continuation sequence from cmnd. */
1414 Print_cmnd(cmnd, !(do_it && (l_attr & A_SILENT)), 0);
1416 rval=Do_cmnd(&cmnd,FALSE,do_it,cp,l_attr,
1417 rp->st_next == NIL(STRING) );
1420 FREE(cmnd);
1423 /* If it is a group then output the EPILOG if required and possibly
1424 * execute the command */
1425 if( group && !(cp->ce_attr & A_ERROR) ) {
1426 if( attr & A_EPILOG ) /* emit epilog */
1427 _append_file( _recipes[RP_GPEPILOG], tmpfile, cp->CE_NAME, trace );
1429 if( trace ) fputs("]\n", stdout);
1431 do_it = !Trace;
1432 if( do_it )
1434 Close_temp( cp, tmpfile );
1435 #if defined(UNIX)
1437 chmod(groupfile,0700);
1438 #endif
1440 rval = Do_cmnd(&groupfile, TRUE, do_it, cp, attr | A_SHELL, TRUE);
1443 _recipes[ RP_RECIPE ] = orp;
1444 cp->ce_attr &= ~A_ERROR;
1445 DB_RETURN( rval );
1449 PUBLIC void
1450 Print_cmnd( cmnd, echo, map )/*
1451 ================================
1452 This routine is called to print out the command to stdout. If echo is
1453 false the printing to stdout is supressed.
1454 The routine is also used to remove the line continuation sequence
1455 \<nl> from the command string and convert escape sequences if the
1456 map flag is set.
1457 The changed string is used later to actually to execute the command. */
1458 char *cmnd;
1459 int echo;
1460 int map;
1462 register char *p;
1463 register char *n;
1464 char tmp[3];
1466 DB_ENTER( "Print_cmnd" );
1468 if( echo ) {
1469 printf( "%s\n", cmnd );
1470 fflush(stdout);
1473 tmp[0] = ESCAPE_CHAR;
1474 tmp[1] = CONTINUATION_CHAR;
1475 tmp[2] = '\0';
1477 for( p=cmnd; *(n = DmStrPbrk(p,tmp)) != '\0'; )
1478 /* Remove the \<nl> sequences. */
1479 if(*n == CONTINUATION_CHAR && n[1] == '\n') {
1480 DB_PRINT( "make", ("fixing [%s]", p) );
1481 strcpy( n, n+2 );
1482 p = n;
1484 /* Look for an escape sequence and replace it by it's corresponding
1485 * character value. */
1486 else {
1487 if( *n == ESCAPE_CHAR && map ) Map_esc( n );
1488 p = n+1;
1491 DB_VOID_RETURN;
1496 /* These routines are used to maintain a stack of directories when making
1497 * the targets. If a target cd's to the directory then it is assumed that
1498 * it will undo it when it is finished making itself. */
1500 static STRINGPTR dir_stack = NIL(STRING);
1502 PUBLIC int
1503 Push_dir( dir, name, ignore )/*
1504 ===============================
1505 Change the current working directory to dir and save the current
1506 working directory on the stack so that we can come back.
1508 If ignore is TRUE then do not complain about _ch_dir if not possible.
1510 Return 1 if the directory change was successfull and 0 otherwise. */
1511 char *dir;
1512 char *name;
1513 int ignore;
1515 STRINGPTR new_dir;
1516 int freedir=FALSE;
1518 DB_ENTER( "Push_dir" );
1520 if( dir == NIL(char) || *dir == '\0' ) dir = Pwd;
1521 if( *dir == '\'' && dir[strlen(dir)-1] == '\'' ) {
1522 dir = DmStrDup(dir+1);
1523 dir[strlen(dir)-1]='\0';
1524 freedir=TRUE;
1526 else if (strchr(dir,'$') != NIL(char)) {
1527 dir = Expand(dir);
1528 freedir=TRUE;
1530 else
1531 dir = DmStrDup(dir);
1533 if( Set_dir(dir) ) {
1534 if( !ignore )
1535 Fatal( "Unable to change to directory `%s', target is [%s]",
1536 dir, name );
1537 if (freedir) FREE(dir);
1538 DB_RETURN( 0 );
1541 DB_PRINT( "dir", ("Push: [%s]", dir) );
1542 if( Verbose & V_DIR_SET )
1543 printf( "%s: Changed to directory [%s]\n", Pname, dir );
1545 if (freedir) FREE( dir );
1546 TALLOC( new_dir, 1, STRING );
1547 new_dir->st_next = dir_stack;
1548 dir_stack = new_dir;
1549 new_dir->st_string = DmStrDup( Pwd );
1551 Def_macro( "PWD", Get_current_dir(), M_FORCE | M_EXPANDED );
1552 _set_tmd();
1554 DB_RETURN( 1 );
1559 PUBLIC void
1560 Pop_dir(ignore)/*
1561 =================
1562 Change the current working directory to the previous saved dir. */
1563 int ignore;
1565 STRINGPTR old_dir;
1566 char *dir;
1568 DB_ENTER( "Pop_dir" );
1570 if( dir_stack == NIL(STRING) ) {
1571 if( ignore ) {
1572 DB_VOID_RETURN;
1574 else
1575 Error( "Directory stack empty for return from .SETDIR" );
1578 if( Set_dir(dir = dir_stack->st_string) )
1579 Fatal( "Could not change to directory `%s'", dir );
1581 Def_macro( "PWD", dir, M_FORCE | M_EXPANDED );
1582 DB_PRINT( "dir", ("Pop: [%s]", dir) );
1583 if( Verbose & V_DIR_SET )
1584 printf( "%s: Changed back to directory [%s]\n", Pname, dir);
1586 old_dir = dir_stack;
1587 dir_stack = dir_stack->st_next;
1589 FREE( old_dir->st_string );
1590 FREE( old_dir );
1591 _set_tmd();
1593 DB_VOID_RETURN;
1598 static void
1599 _set_tmd()/*
1600 ============
1601 Set the TMD Macro and the Tmd global variable. TMD stands for "To MakeDir"
1602 and is the path from the present directory (value of $(PWD)) to the directory
1603 dmake was started up in (value of $(MAKEDIR)). As _prefix() can return absolute
1604 paths some special .WINPATH treatment is needed.
1607 char *tmd;
1609 if( Tmd )
1610 FREE(Tmd);
1612 tmd = _prefix(Pwd, Makedir);
1613 if( *tmd ) {
1614 Def_macro( "TMD", DO_WINPATH(tmd), M_FORCE | M_EXPANDED );
1615 Tmd = DmStrDup(tmd);
1616 } else {
1617 Def_macro( "TMD", ".", M_FORCE | M_EXPANDED );
1618 Tmd = DmStrDup(".");
1620 FREE( tmd );
1624 static void
1625 _set_recipe( target, ind )/*
1626 ============================
1627 Set up the _recipes static variable so that the slot passed in points
1628 at the rules corresponding to the target supplied. */
1629 char *target;
1630 int ind;
1632 CELLPTR cp;
1633 HASHPTR hp;
1635 if( (hp = Get_name(target, Defs, FALSE)) != NIL(HASH) ) {
1636 cp = hp->CP_OWNR;
1637 _recipes[ ind ] = cp->ce_recipe;
1639 else
1640 _recipes[ ind ] = NIL(STRING);
1645 PUBLIC void
1646 Append_line( cmnd, newline, tmpfile, name, printit, map )
1647 char *cmnd;
1648 int newline;
1649 FILE *tmpfile;
1650 char *name;
1651 int printit;
1652 int map;
1654 Print_cmnd( cmnd, printit, map );
1656 if( Trace ) return;
1658 fputs(cmnd, tmpfile);
1659 if( newline ) fputc('\n', tmpfile);
1660 fflush(tmpfile);
1662 if( ferror(tmpfile) )
1663 Fatal("Write error on temporary file, while processing `%s'", name);
1668 static void
1669 _append_file( rp, tmpfile, name, printit )
1670 register STRINGPTR rp;
1671 FILE *tmpfile;
1672 char *name;
1673 int printit;
1675 char *cmnd;
1677 while( rp != NIL(STRING) ) {
1678 Append_line(cmnd = Expand(rp->st_string), TRUE, tmpfile, name, printit,0);
1679 FREE(cmnd);
1680 rp = rp->st_next;
1685 #define NUM_BUCKETS 20
1687 typedef struct strpool {
1688 char *string; /* a pointer to the string value */
1689 uint32 keyval; /* the strings hash value */
1690 struct strpool *next; /* hash table link pointer */
1691 } POOL, *POOLPTR;
1693 static POOLPTR strings[ NUM_BUCKETS ];
1695 static char *
1696 _pool_lookup( str )/*
1697 =====================
1698 Scan down the list of chained strings and see if one of them matches
1699 the string we are looking for. */
1700 char *str;
1702 register POOLPTR key;
1703 uint32 keyval;
1704 uint16 hv;
1705 uint16 keyindex;
1706 char *string;
1708 DB_ENTER( "_pool_lookup" );
1710 if( str == NIL(char) ) DB_RETURN("");
1712 hv = Hash(str, &keyval);
1713 key = strings[ keyindex = (hv % NUM_BUCKETS) ];
1715 while( key != NIL(POOL) )
1716 if( (key->keyval != keyval) || strcmp(str, key->string) )
1717 key = key->next;
1718 else
1719 break;
1721 if( key == NIL(POOL) ) {
1722 DB_PRINT( "pool", ("Adding string [%s]", str) );
1723 TALLOC( key, 1, POOL ); /* not found so add string */
1725 key->string = string = DmStrDup(str);
1726 key->keyval = keyval;
1728 key->next = strings[ keyindex ];
1729 strings[ keyindex ] = key;
1731 else {
1732 DB_PRINT( "pool", ("Found string [%s], key->string") );
1733 string = key->string;
1736 DB_RETURN( string );
1740 void
1741 Unmake( cp )/*
1742 ==============
1743 Remove flags indicating that a target was previously made. This
1744 is used for infered makefiles. */
1745 CELLPTR cp;
1747 LINKPTR dp, ep;
1748 CELLPTR tcp, pcp;
1750 DB_ENTER( "Unmake" );
1752 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
1753 tcp = dp->cl_prq;
1755 /* Unmake the prerequisites. */
1756 for( ep = tcp->ce_prq; ep != NIL(LINK); ep = ep->cl_next ) {
1757 pcp = ep->cl_prq;
1759 Unmake(pcp);
1761 DB_PRINT( "unmake", ("Unmake [%s]", tcp->CE_NAME) );
1763 tcp->ce_flag &= ~(F_MADE|F_VISITED|F_STAT);
1764 tcp->ce_time = (time_t)0L;
1767 DB_VOID_RETURN;