Update ooo320-m1
[ooovba.git] / dmake / make.c
blob93878c40170a8cb72a4fe32afeb79e0311130e00
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 && (Verbose & V_MAKE) )
256 printf( "`%s' is up to date\n", tgt->CE_NAME );
259 DB_RETURN( 0 );
264 PUBLIC int
265 Make( cp, setdirroot )/*
266 ========================
267 Make target cp. Make() is also called on prerequisites that have no rule
268 associated (F_TARGET is not set) to verify that they exist. */
269 CELLPTR cp;
270 CELLPTR setdirroot;
272 register LINKPTR dp, prev,next;
273 register CELLPTR tcp;
274 CELLPTR nsetdirroot;
275 char *name, *lib;
276 HASHPTR m_at, m_q, m_b, m_g, m_l, m_bb, m_up;
277 LISTSTRING all_list, imm_list, outall_list, inf_list;
278 char *all = NIL(char);
279 char *inf = NIL(char);
280 char *outall = NIL(char);
281 char *imm = NIL(char);
282 int rval = 0; /* 0==ready, 1==target still running, -1==error */
283 int push = 0;
284 int made = F_MADE;
285 int ignore;
286 time_t otime = (time_t) 1L; /* Hold time of newest prerequisite. */
287 int mark_made = FALSE;
289 #if defined(__CYGWIN__)
290 /* static variable to hold .WINPATH status of previously made target.
291 * 0, 1 are .WINPATH states, -1 indicates the first target. */
292 static int prev_winpath_attr = -1;
293 #endif
295 DB_ENTER( "Make" );
296 DB_PRINT( "mem", ("%s:-> mem %ld", cp->CE_NAME, (long) coreleft()) );
298 /* Initialize the various temporary storage */
299 m_q = m_b = m_g = m_l = m_bb = m_up = NIL(HASH);
300 list_init(&all_list);
301 list_init(&imm_list);
302 list_init(&outall_list);
303 list_init(&inf_list);
305 if (cp->ce_set && cp->ce_set != cp) {
306 if( Verbose & V_MAKE )
307 printf( "%s: Building .UPDATEALL representative [%s]\n", Pname,
308 cp->ce_set->CE_NAME );
309 cp = cp->ce_set;
312 /* If we are supposed to change directories for this target then do so.
313 * If we do change dir, then modify the setdirroot variable to reflect
314 * that fact for all of the prerequisites that we will be making. */
316 nsetdirroot = setdirroot;
317 ignore = (((cp->ce_attr|Glob_attr)&A_IGNORE) != 0);
319 /* Set the UseWinpath variable to reflect the (global/local) .WINPATH
320 * attribute. The variable is used by DO_WINPATH() and in some other
321 * places. */
322 UseWinpath = (((cp->ce_attr|Glob_attr)&A_WINPATH) != 0);
324 /* m_at needs to be defined before going to a "stop_making_it" where
325 * a _drop_mac( m_at ) would try to free it. */
326 /* FIXME: m_at can most probably not be changed before the next
327 * Def_macro("@", ...) command. Check if both this and the next
328 * call are needed. */
329 m_at = Def_macro("@", DO_WINPATH(cp->ce_fname), M_MULTI);
331 if( cp->ce_attr & A_SETDIR ) {
332 /* Change directory only if the previous .SETDIR is a different
333 * directory from the current one. ie. all cells with the same .SETDIR
334 * attribute are assumed to come from the same directory. */
336 if( (setdirroot == NIL(CELL) || setdirroot->ce_dir != cp->ce_dir) &&
337 (push = Push_dir(cp->ce_dir,cp->CE_NAME,ignore)) != 0 )
338 setdirroot = cp;
341 DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) );
343 /* FIXME: F_MULTI targets don't have cp->ce_recipe set but the recipes
344 * are known nevertheless. It is not necessary to infer them.
345 * If (cp->ce_flag & F_MULTI) is true the recipes of the corresponding
346 * subtargets can be used. */
347 if( cp->ce_recipe == NIL(STRING) ) {
348 char *dir = cp->ce_dir;
350 if( Verbose & V_MAKE )
351 printf( "%s: Infering prerequisite(s) and recipe for [%s]\n", Pname,
352 cp->CE_NAME );
354 Infer_recipe( cp, setdirroot );
356 /* See if the directory has changed, if it has then make sure we
357 * push it. */
358 if( dir != cp->ce_dir ) {
359 if( push ) Pop_dir(FALSE);
360 push = Push_dir( cp->ce_dir, cp->CE_NAME, ignore );
361 setdirroot = cp;
365 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
366 tcp = dp->cl_prq;
367 if( push ) {
368 /* If we changed the directory because of .SETDIR write Pwd into
369 * tcp->ce_dir so that it holds an absolute path. */
370 if( !(tcp->ce_attr & A_POOL) && tcp->ce_dir ) FREE( tcp->ce_dir );
371 tcp->ce_dir = _pool_lookup(Pwd);
372 tcp->ce_attr |= A_SETDIR|A_POOL;
374 tcp->ce_setdir = nsetdirroot;
377 DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) );
378 /* If we have not yet statted the target then do so. */
379 if( !(cp->ce_flag & F_STAT) && !(cp->ce_attr&A_PHONY) ) {
380 if (cp->ce_parent && (cp->ce_parent->ce_flag & F_MULTI)) {
381 /* Inherit the stat info from the F_MULTI parent. */
382 cp->ce_time = cp->ce_parent->ce_time;
383 cp->ce_flag |= F_STAT;
384 /* Propagate the A_PRECIOUS attribute from the parent. */
385 cp->ce_attr |= cp->ce_parent->ce_attr & A_PRECIOUS;
387 else {
388 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
389 tcp = dp->cl_prq;
390 /* Check if target already exists. */
391 Stat_target( tcp, 1, FALSE );
393 if( tcp->ce_time != (time_t)0L ) {
394 /* File exists so don't remove it later. */
395 tcp->ce_attr |= A_PRECIOUS;
398 if( Verbose & V_MAKE )
399 printf("%s: Time stamp of [%s] is %ld\n",Pname,tcp->CE_NAME,
400 tcp->ce_time);
405 DB_PRINT( "make", ("(%s, %ld, 0x%08x, 0x%04x)", cp->CE_NAME,
406 cp->ce_time, cp->ce_attr, cp->ce_flag) );
408 /* Handle targets without rule and without existing file. */
409 if( !(cp->ce_flag & F_TARGET) && (cp->ce_time == (time_t) 0L) ) {
410 if( Makemkf ) {
411 rval = -1;
412 goto stop_making_it;
414 else if( cp->ce_prq != NIL(LINK)
415 || (STOBOOL(Augmake) && (cp->ce_flag&F_EXPLICIT)))
416 /* Assume an empty recipe for a target that we have run inference on
417 * but do not have a set of rules for but for which we have inferred
418 * a list of prerequisites. */
419 cp->ce_flag |= F_RULES;
420 else
421 Fatal( "`%s' not found, and can't be made", cp->CE_NAME );
424 DB_PRINT( "mem", ("%s:-A mem %ld", cp->CE_NAME, (long) coreleft()) );
426 /* set value of $* if we have not infered a recipe, in this case $* is
427 * the same as $(@:db), this allows us to be compatible with BSD make */
428 if( cp->ce_per == NIL(char) ) cp->ce_per = "$(@:db)";
430 /* Search the prerequisite list for dynamic prerequisites and if we find
431 * them copy the list of prerequisites for potential later re-use. */
432 if ( cp->ce_prqorg == NIL(LINK) ) {
433 for( dp = cp->ce_prq; dp != NIL(LINK); dp = dp->cl_next )
434 if ( strchr(dp->cl_prq->CE_NAME, '$') != NULL )
435 break;
437 if (dp != NIL(LINK)) {
438 cp->ce_prqorg = _dup_prq(cp->ce_prq);
442 /* Define $@ macro. The only reason for defining it here (that I see ATM)
443 * is that $@ is already defined in conditional macros. */
444 /* FIXME: check if both this and the previous Def_macro("@", ...) call
445 * are needed. */
446 m_at = Def_macro("@", DO_WINPATH(cp->ce_fname), M_MULTI);
448 /* Define conditional macros if any, note this is done BEFORE we process
449 * prerequisites for the current target. Thus the making of a prerequisite
450 * is done using the current value of the conditional macro. */
451 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
452 tcp=dp->cl_prq;
453 if (tcp->ce_cond != NIL(STRING)) {
454 STRINGPTR sp;
456 tcp->ce_pushed = NIL(HASH);
457 for(sp=tcp->ce_cond; sp; sp=sp->st_next) {
458 if(Parse_macro(sp->st_string,M_MULTI|M_PUSH)) {
459 HASHPTR hp;
461 hp = GET_MACRO(LastMacName);
462 hp->ht_link = tcp->ce_pushed;
463 tcp->ce_pushed = hp;
465 else {
466 Error("Invalid conditional macro expression [%s]",sp->st_string);
472 /* First round, will be repeated a second time below. */
473 for( prev=NULL,dp=cp->ce_prq; dp != NIL(LINK); prev=dp, dp=next ) {
474 int seq;
476 /* This loop executes Make() to build prerequisites if needed.
477 * The only macro that needs to be reset after a Make() was executed
478 * is $@ as it might be used when expanding potential dynamic
479 * prerequisites. As UseWinpath is a global variable we also
480 * need to restore it. */
481 if (m_at->ht_value == NIL(char)) {
482 /* This check effectively tests if Make() was run before because
483 * Make() frees all dynamic macro values at the end. */
484 UseWinpath = (((cp->ce_attr|Glob_attr)&A_WINPATH) != 0);
485 m_at = Def_macro("@", DO_WINPATH(cp->ce_fname), M_MULTI);
488 /* Make the prerequisite, note that if the current target has the
489 * .LIBRARY attribute set we pass on to the prerequisite the .LIBRARYM
490 * attribute and pass on the name of the current target as the library
491 * name, and we take it away when we are done. */
492 next = dp->cl_next;
494 tcp = dp->cl_prq;
495 if( Verbose & V_MAKE )
496 printf("Checking prerequisite [%s]\n", tcp->CE_NAME);
498 seq = (((cp->ce_attr | Glob_attr) & A_SEQ) != 0);
500 /* This checks if this prerequisite is still in the making, if yes
501 * come back later. */
502 if( tcp->ce_flag & F_VISITED ) {
503 /* Check if this currently or fully made target has the same
504 * .SETDIR setting. If yes, continue if it was made or come
505 * back later otherwise. */
506 if( _explode_graph(tcp, dp, setdirroot) == 0 ) {
507 /* didn't blow it up so see if we need to wait for it. */
508 if( tcp->ce_flag & F_MADE ) {
509 /* Target was made. */
510 continue;
512 else
513 /* Target is still in the making ... */
514 goto stop_making_it;
516 else
517 /* Use the new prerequisite with the new .SETDIR value. */
518 tcp = dp->cl_prq;
521 /* If the previous target (prereq) is not yet ready return if
522 * seq is TRUE. */
523 if( seq && !made ) goto stop_making_it;
525 /* Expand dynamic prerequisites. The F_MARK flag is guarging against
526 * possible double expandion of dynamic prerequisites containing more
527 * than one prerequisite. */
528 /* A new A_DYNAMIC attribute could save a lot of strchr( ,'$') calls. */
529 if ( tcp && !(tcp->ce_flag & F_MARK) && strchr(tcp->CE_NAME, '$') ) {
530 /* Replace this dynamic prerequisite with the the real prerequisite,
531 * and add the additional prerequisites if there are more than one.*/
533 name = Expand( tcp->CE_NAME );
534 if( strcmp(name,cp->CE_NAME) == 0 )
535 Fatal("Detected circular dynamic dependency; generated '%s'",name);
537 /* Call helper for dynamic prerequisite expansion to replace the
538 * prerequisite with the expanded version and add the new
539 * prerequisites, if the macro expanded to more than one, after
540 * the current list element. */
541 dp = _expand_dynamic_prq( cp->ce_prq, dp, name );
542 FREE( name );
544 /* _expand_dynamic_prq() probably changed dp->cl_prq. */
545 tcp = dp->cl_prq;
546 if ( tcp ) {
547 next = dp->cl_next;
551 /* Dynamic expansion results in a NULL cell only when the the new
552 * prerequisite is already in the prerequisite list or empty. In this
553 * case delete the cell and continue. */
554 if ( tcp == NIL(CELL) ) {
555 FREE(dp);
556 if ( prev == NIL(LINK) ) {
557 cp->ce_prq = next;
558 dp = NULL; /* dp will be the new value of prev. */
560 else {
561 prev->cl_next = next;
562 dp = prev;
564 continue;
567 /* Clear F_MARK flag that could have been set by _expand_dynamic_prq(). */
568 tcp->ce_flag &= ~(F_MARK);
570 if( cp->ce_attr & A_LIBRARY ) {
571 tcp->ce_attr |= A_LIBRARYM;
572 tcp->ce_lib = cp->ce_fname;
575 /* Propagate the parent's F_REMOVE and F_INFER flags to the
576 * prerequisites. */
577 tcp->ce_flag |= cp->ce_flag & (F_REMOVE|F_INFER);
579 /* Propagate parents A_ROOT attribute to a child if the parent is a
580 * F_MULTI target. */
581 if( (cp->ce_flag & F_MULTI) && (cp->ce_attr & A_ROOT) )
582 tcp->ce_attr |= A_ROOT;
584 tcp->ce_parent = cp;
585 rval |= Make(tcp, setdirroot);
587 if( cp->ce_attr & A_LIBRARY )
588 tcp->ce_attr ^= A_LIBRARYM;
590 /* Return on error or if Make() is still running and A_SEQ is set.
591 * (All F_MULTI targets have the A_SEQ attribute.) */
592 if( rval == -1 || (seq && (rval==1)) )
593 goto stop_making_it;
595 /* If tcp is ready, set made = F_MADE. */
596 made &= tcp->ce_flag & F_MADE;
600 /* Do the loop again. We are most definitely going to make the current
601 * cell now. NOTE: doing this loop here also results in a reduction
602 * in peak memory usage by the algorithm. */
604 for( dp = cp->ce_prq; dp != NIL(LINK); dp = dp->cl_next ) {
605 int tgflg;
606 tcp = dp->cl_prq;
607 if( tcp == NIL(CELL) )
608 Fatal("Internal Error: Found prerequisite list cell without prerequisite!");
610 name = tcp->ce_fname;
612 /* make certain that all prerequisites are made prior to advancing. */
613 if( !(tcp->ce_flag & F_MADE) ) goto stop_making_it;
615 /* If the target is a library, then check to make certain that a member
616 * is newer than an object file sitting on disk. If the disk version
617 * is newer then set the time stamps so that the archived member is
618 * replaced. */
619 if( cp->ce_attr & A_LIBRARY )
620 if( tcp->ce_time <= cp->ce_time ) {
621 time_t mtime = Do_stat( name, tcp->ce_lib, NIL(char *), FALSE );
622 if( mtime < tcp->ce_time ) tcp->ce_time = cp->ce_time+1L;
625 /* Set otime to the newest time stamp of all prereqs or 1 if there
626 * are no prerequisites. */
627 if( tcp->ce_time > otime ) otime = tcp->ce_time;
629 list_add(&all_list, name);
630 if( (tgflg = (dp->cl_flag & F_TARGET)) != 0 )
631 list_add(&inf_list, name);
633 if((cp->ce_time<tcp->ce_time) || ((tcp->ce_flag & F_TARGET) && Force)) {
634 list_add(&outall_list, name);
635 if( tgflg )
636 list_add(&imm_list, name);
640 /* If we are building a F_MULTI target inherit the time from
641 * its children. */
642 if( (cp->ce_flag & F_MULTI) )
643 cp->ce_time = otime;
645 /* All prerequisites are made, now make the current target. */
647 /* Restore UseWinpath and $@ if needed, see above for an explanation. */
648 if (m_at->ht_value == NIL(char)) {
649 /* This check effectively tests if Make() was run before because
650 * Make() frees all dynamic macro values at the end. */
651 UseWinpath = (((cp->ce_attr|Glob_attr)&A_WINPATH) != 0);
652 m_at = Def_macro("@", DO_WINPATH(cp->ce_fname), M_MULTI);
655 /* Create a string with all concatenate filenames. The function
656 * respects .WINPATH. Note that gen_path_list_string empties its
657 * parameter :( */
658 all = gen_path_list_string(&all_list);
659 imm = gen_path_list_string(&imm_list);
660 outall = gen_path_list_string(&outall_list);
661 inf = gen_path_list_string(&inf_list);
663 DB_PRINT( "mem", ("%s:-C mem %ld", cp->CE_NAME, (long) coreleft()) );
664 DB_PRINT( "make", ("I make '%s' if %ld > %ld", cp->CE_NAME, otime,
665 cp->ce_time) );
667 if( Verbose & V_MAKE ) {
668 printf( "%s: >>>> Making ", Pname );
669 /* Also print the F_MULTI master target. */
670 if( cp->ce_flag & F_MULTI )
671 printf( "(::-\"master\" target) " );
672 if( cp->ce_count != 0 )
673 printf( "[%s::{%d}]\n", cp->CE_NAME, cp->ce_count );
674 else
675 printf( "[%s]\n", cp->CE_NAME );
679 /* Only PWD, TMD, MAKEDIR and the dynamic macros are affected by
680 * .WINPATH. $@ is handled earlier, do the rest now. */
681 #if defined(__CYGWIN__)
682 /* This is only relevant for cygwin. */
683 if( UseWinpath != prev_winpath_attr ) {
684 Def_macro( "MAKEDIR", Makedir, M_FORCE | M_EXPANDED );
685 /* If push is TRUE (Push_dir() was used) PWD and TMD are already
686 * set. */
687 if( !push ) {
688 Def_macro( "PWD", Pwd, M_FORCE | M_EXPANDED );
689 _set_tmd();
692 prev_winpath_attr = UseWinpath;
693 #endif
695 /* Set the remaining dynamic macros $*, $>, $?, $<, $& and $^. */
697 /* $* is either expanded as the result of a % inference or defined to
698 * $(@:db) and hence unexpanded otherwise. The latter doesn't start
699 * with / and will therefore not be touched by DO_WINPATH(). */
700 m_bb = Def_macro( "*", DO_WINPATH(cp->ce_per), M_MULTI );
702 /* This is expanded. */
703 m_g = Def_macro( ">", DO_WINPATH(cp->ce_lib), M_MULTI|M_EXPANDED );
704 /* These strings are generated with gen_path_list_string() and honor
705 * .WINPATH */
706 m_q = Def_macro( "?", outall, M_MULTI|M_EXPANDED );
707 m_b = Def_macro( "<", inf, M_MULTI|M_EXPANDED );
708 m_l = Def_macro( "&", all, M_MULTI|M_EXPANDED );
709 m_up = Def_macro( "^", imm, M_MULTI|M_EXPANDED );
711 _recipes[ RP_RECIPE ] = cp->ce_recipe;
713 /* We attempt to make the target if
714 * 1. it has a newer prerequisite
715 * 2. It is a target and Force is set
716 * 3. It's set of recipe lines has changed.
718 if( Check_state(cp, _recipes, NUM_RECIPES )
719 || (cp->ce_time < otime)
720 || ((cp->ce_flag & F_TARGET) && Force)
723 if( Measure & M_TARGET )
724 Do_profile_output( "s", M_TARGET, cp );
726 /* Only checking so stop as soon as we determine we will make
727 * something */
728 if( Check ) {
729 rval = -1;
730 goto stop_making_it;
733 if( Verbose & V_MAKE )
734 printf( "%s: Updating [%s], (%ld > %ld)\n", Pname,
735 cp->CE_NAME, otime, cp->ce_time );
737 /* In order to check if a targets time stamp was properly updated
738 * after the target was made and to keep the dependency chain valid
739 * for targets without recipes we store the minimum required file
740 * time. If the target time stamp is older than the newest
741 * prerequisite use that time, otherwise the current time. (This
742 * avoids the call to Do_time() for every target, still checks
743 * if the target time is new enough for the given prerequisite and
744 * mintime is also the newest time of the given prerequisites and
745 * can be used for targets without recipes.)
746 * We reuse the ce_time member to store this minimum time until
747 * the target is finished by Update_time_stamp(). This function
748 * checks if the file time was updated properly and warns if it was
749 * not. (While making a target this value does not change.) */
750 cp->ce_time = ( cp->ce_time < otime ? otime : Do_time() );
751 DB_PRINT( "make", ("Set ce_time (mintime) to: %ld", cp->ce_time) );
753 if( Touch ) {
754 name = cp->ce_fname;
755 lib = cp->ce_lib;
757 if( (!(Glob_attr & A_SILENT) || !Trace) && !(cp->ce_attr & A_PHONY) ) {
758 if( lib == NIL(char) )
759 printf("touch(%s)", name );
760 else if( cp->ce_attr & A_SYMBOL )
761 printf("touch(%s((%s)))", lib, name );
762 else
763 printf("touch(%s(%s))", lib, name );
766 if( !Trace && !(cp->ce_attr & A_PHONY) )
767 if( Do_touch( name, lib,
768 (cp->ce_attr & A_SYMBOL) ? &name : NIL(char *) ) != 0 )
769 printf( " not touched - non-existant" );
771 if( (!(Glob_attr & A_SILENT) || !Trace) && !(cp->ce_attr & A_PHONY) )
772 printf( "\n" );
774 Update_time_stamp( cp );
776 else if( cp->ce_recipe != NIL(STRING) ) {
777 /* If a recipe is found use it. Note this misses F_MULTI targets. */
778 if( !(cp->ce_flag & F_SINGLE) ) /* Execute the recipes once ... */
779 rval = Exec_commands( cp );
780 /* Update_time_stamp() is called inside Exec_commands() after the
781 * last recipe line is finished. (In _finished_child()) */
782 else { /* or for every out of date dependency
783 * if the ruleop ! was used. */
784 TKSTR tk;
786 /* We will redefine $? to be the prerequisite that the recipes
787 * are currently evaluated for. */
788 _drop_mac( m_q );
790 /* Execute recipes for each out out of date prerequisites.
791 * WARNING! If no prerequisite is given the recipes are not
792 * executed at all! */
793 if( outall && *outall ) {
794 /* Wait for each prerequisite to finish, save the status
795 * of Wait_for_completion. */
796 int wait_for_completion_status = Wait_for_completion;
797 Wait_for_completion = TRUE;
799 SET_TOKEN( &tk, outall );
801 /* No need to update the target timestamp/removing temporary
802 * prerequisites (Update_time_stamp() in _finished_child())
803 * until all prerequisites are done. */
804 Doing_bang = TRUE;
805 name = Get_token( &tk, "", FALSE );
806 /* This loop might fail if outall contains filenames with
807 * spaces. */
808 do {
809 /* Set $? to current prerequisite. */
810 m_q->ht_value = name;
812 rval = Exec_commands( cp );
813 /* Thanks to Wait_for_completion = TRUE we are allowed
814 * to remove the temp files here. */
815 Unlink_temp_files(cp);
817 while( *(name = Get_token( &tk, "", FALSE )) != '\0' );
818 Wait_for_completion = wait_for_completion_status;
819 Doing_bang = FALSE;
822 Update_time_stamp( cp );
823 /* Erase $? again. Don't free the pointer, it was part of outall. */
824 m_q->ht_value = NIL(char);
827 else if( !(cp->ce_flag & F_RULES) && !(cp->ce_flag & F_STAT) &&
828 (!(cp->ce_attr & A_ROOT) || !(cp->ce_flag & F_EXPLICIT)) &&
829 !(cp->ce_count) )
830 /* F_MULTI subtargets should evaluate its parents F_RULES value
831 * but _make_multi always sets the F_RULES value of the master
832 * target. Assume F_RULES is set for subtargets. This might not
833 * be true if there are no prerequisites and no recipes in any
834 * of the subtargets. (FIXME) */
835 Fatal( "Don't know how to make `%s'",cp->CE_NAME );
836 else {
837 /* Empty recipe, set the flag as MADE and update the time stamp */
838 /* This might be a the master cell of a F_MULTI target. */
839 Update_time_stamp( cp );
842 else {
843 if( Verbose & V_MAKE )
844 printf( "%s: Up to date [%s], prq time = %ld , target time = %ld)\n", Pname,
845 cp->CE_NAME, otime, cp->ce_time );
846 mark_made = TRUE;
849 /* If mark_made == TRUE the target is up-to-date otherwise it is
850 * currently in the making. */
852 /* Update all targets in .UPDATEALL rule / only target cp. */
853 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
854 tcp=dp->cl_prq;
856 /* Set the time stamp of those prerequisites without rule to the current
857 * time if Force is TRUE to make sure that targets depending on those
858 * prerequisites get remade. */
859 if( !(tcp->ce_flag & F_TARGET) && Force ) tcp->ce_time = Do_time();
860 if( mark_made ) {
861 tcp->ce_flag |= F_MADE;
862 if( tcp->ce_flag & F_MULTI ) {
863 LINKPTR tdp;
864 for( tdp = tcp->ce_prq; tdp != NIL(LINK); tdp = tdp->cl_next )
865 tcp->ce_attr |= tdp->cl_prq->ce_attr & A_UPDATED;
869 /* Note that the target is in the making. */
870 tcp->ce_flag |= F_VISITED;
872 /* Note: If the prerequisite was made using a .SETDIR= attribute
873 * directory then we will include the directory in the fname
874 * of the target. */
875 if( push ) {
876 char *dir = nsetdirroot ? nsetdirroot->ce_dir : Makedir;
877 /* get relative path from current SETDIR to new SETDIR. */
878 /* Attention, even with .WINPATH set this has to be a POSIX
879 * path as ce_fname neeed to be POSIX. */
880 char *pref = _prefix( dir, tcp->ce_dir );
881 char *nname = Build_path(pref, tcp->ce_fname);
883 FREE(pref);
884 if( (tcp->ce_attr & A_FFNAME) && (tcp->ce_fname != NIL(char)) )
885 FREE( tcp->ce_fname );
887 tcp->ce_fname = DmStrDup(nname);
888 tcp->ce_attr |= A_FFNAME;
892 stop_making_it:
893 _drop_mac( m_g );
894 _drop_mac( m_q );
895 _drop_mac( m_b );
896 _drop_mac( m_l );
897 _drop_mac( m_bb );
898 _drop_mac( m_up );
899 _drop_mac( m_at );
901 /* undefine conditional macros if any */
902 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
903 tcp=dp->cl_prq;
905 while (tcp->ce_pushed != NIL(HASH)) {
906 HASHPTR cur = tcp->ce_pushed;
907 tcp->ce_pushed = cur->ht_link;
909 Pop_macro(cur);
910 FREE(cur->ht_name);
911 if(cur->ht_value)
912 FREE(cur->ht_value);
913 FREE(cur);
917 if( push )
918 Pop_dir(FALSE);
920 /* Undefine the strings that we used for constructing inferred
921 * prerequisites. */
922 if( inf != NIL(char) ) FREE( inf );
923 if( all != NIL(char) ) FREE( all );
924 if( imm != NIL(char) ) FREE( imm );
925 if( outall != NIL(char) ) FREE( outall );
926 free_list(all_list.first);
927 free_list(imm_list.first);
928 free_list(outall_list.first);
929 free_list(inf_list.first);
931 DB_PRINT( "mem", ("%s:-< mem %ld", cp->CE_NAME, (long) coreleft()) );
932 DB_RETURN(rval);
936 static char *
937 _prefix( pfx, pat )/*
938 =====================
939 Return the relative path from pfx to pat. Both paths have to be absolute
940 paths. If the paths are on different resources or drives (if applicable)
941 or only share a relative path going up to the root dir and down again
942 return pat. */
943 char *pfx;
944 char *pat;
946 char *cmp1=pfx;
947 char *cmp2=pat;
948 char *tpat=pat; /* Keep pointer to original pat. */
949 char *result;
950 char *up;
951 int first = 1;
952 int samerootdir = 1; /* Marks special treatment for the root dir. */
953 #ifdef HAVE_DRIVE_LETTERS
954 int pfxdl = 0;
955 int patdl = 0;
956 #endif
958 /* Micro optimization return immediately if pfx and pat are equal. */
959 if( strcmp(pfx, pat) == 0 )
960 return(DmStrDup(""));
962 #ifdef HAVE_DRIVE_LETTERS
963 /* remove the drive letters to avoid getting them into the relative
964 * path later. */
965 if( *pfx && pfx[1] == ':' && isalpha(*pfx) ) {
966 pfxdl = 1;
967 cmp1 = DmStrSpn(pfx+2, DirBrkStr);
969 if( *pat && pat[1] == ':' && isalpha(*pat) ) {
970 patdl = 1;
971 cmp2 = DmStrSpn(pat+2, DirBrkStr);
973 /* If the drive letters are different use the abs. path. */
974 if( pfxdl && patdl && (tolower(*pfx) != tolower(*pat)) )
975 return(DmStrDup(pat));
977 /* If only one has a drive letter also use the abs. path. */
978 if( pfxdl != patdl )
979 return(DmStrDup(pat));
980 else if( pfxdl )
981 /* If both are the same drive letter, disable the special top
982 * dir treatment. */
983 samerootdir = 0;
985 /* Continue without the drive letters. (Either none was present,
986 * or both were the same. This also solves the problem that the
987 * case of the drive letters sometimes depends on the shell.
988 * (cmd.exe vs. cygwin bash) */
989 pfx = cmp1;
990 pat = cmp2;
991 #endif
993 /* Cut off equal leading parts of pfx, pat. Both have to be abs. paths. */
994 while(*pfx && *pat) {
995 /* skip leading dir. separators. */
996 pfx = DmStrSpn(cmp1, DirBrkStr);
997 pat = DmStrSpn(cmp2, DirBrkStr);
999 /* Only check in the first run of the loop. Leading slashes can only
1000 * mean POSIX paths or Windows resources (two) slashes. Drive letters
1001 * have no leading slash. In any case, if the number of slashes are
1002 * not equal there can be no relative path from one two the other.
1003 * In this case return the absolute path. */
1004 if( first ) {
1005 if( cmp1-pfx != cmp2-pat ) {
1006 return(DmStrDup(tpat));
1008 first = 0;
1011 /* find next dir. separator (or ""). */
1012 cmp1 = DmStrPbrk(pfx, DirBrkStr);
1013 cmp2 = DmStrPbrk(pat, DirBrkStr);
1015 /* if length of directory name is equal compare the strings. If equal
1016 * go into next loop. If not equal and directory names in the root
1017 * dir are compared return the absolut path otherwise break the loop
1018 * and construct the relative path from pfx to pat. */
1019 if ( (cmp1-pfx) != (cmp2-pat) || strncmp(pfx,pat,cmp1-pfx) != 0 ) {
1020 if( samerootdir ) {
1021 return(DmStrDup(tpat));
1023 break;
1026 if( samerootdir ) {
1027 #if __CYGWIN__
1028 /* If the toplevel directory is /cygdrive (or the equivalent prefix)
1029 * treat the following level also as rootdir. If we are here cmp1-pfx
1030 * cannot be zero so we won't compare with an empty cygdrive prefix. */
1031 if ( (cmp1-pfx) == CygDrvPreLen && strncmp(pfx,CygDrvPre,CygDrvPreLen) == 0 )
1032 samerootdir = 1;
1033 else
1034 #endif
1035 samerootdir = 0;
1039 result = DmStrDup("");
1040 up = DmStrJoin("..",DirSepStr,-1,FALSE);
1041 cmp1 = pfx;
1042 /* Add "../" for each directory in pfx */
1043 while ( *(pfx=DmStrSpn(cmp1,DirBrkStr)) != '\0' ) {
1044 cmp1 = DmStrPbrk(pfx,DirBrkStr);
1045 result = DmStrJoin(result,up,-1,TRUE);
1048 pat = DmStrSpn(pat,DirBrkStr);
1049 /* Append pat to result. */
1050 if( *pat != '\0' ) {
1051 cmp2 = DmStrDup(Build_path(result, pat));
1052 FREE(result);
1053 result = cmp2;
1054 } else {
1055 /* if pat is empty and result exists remove the trailing slash
1056 * from the last "../". */
1057 if( *result ) {
1058 result[strlen(result)-1] = '\0';
1062 return(result);
1066 static LINKPTR
1067 _dup_prq( lp )
1068 LINKPTR lp;
1070 LINKPTR tlp;
1072 if( lp == NIL(LINK) ) return(lp);
1074 TALLOC(tlp, 1, LINK);
1075 tlp->cl_prq = lp->cl_prq;
1076 tlp->cl_flag = lp->cl_flag;
1077 tlp->cl_next = _dup_prq( lp->cl_next );
1079 return(tlp);
1083 static LINKPTR
1084 _expand_dynamic_prq( head, lp, name )/*
1085 =======================================
1086 The string name can contain one or more target names. Check if these are
1087 already a prerequisite for the current target. If not add them to the list
1088 of prerequisites. If no prerequisites were added set lp->cl_prq to NULL.
1089 Set the F_MARK flag to indicate that the prerequisite was expanded.
1090 Use cl_flag instead?? */
1091 LINKPTR head;
1092 LINKPTR lp;
1093 char *name;
1095 CELLPTR cur = lp->cl_prq;
1097 if( !(*name) ) {
1098 /* If name is empty this leaves lp->cl_prq unchanged -> No prerequisite added. */
1101 else if ( strchr(name, ' ') == NIL(char) ) {
1102 /* If condition above is true, no space is found. */
1103 CELLPTR prq = Def_cell(name);
1104 LINKPTR tmp;
1106 /* Check if prq already exists. */
1107 for(tmp=head;tmp != NIL(LINK) && tmp->cl_prq != prq;tmp=tmp->cl_next);
1109 /* If tmp is NULL then the prerequisite is new and is added to the list. */
1110 if ( !tmp ) {
1111 /* replace the prerequisite with the expanded version. */
1112 lp->cl_prq = prq;
1113 lp->cl_prq->ce_flag |= F_MARK;
1116 else {
1117 LINKPTR tlp = lp;
1118 LINKPTR next = lp->cl_next;
1119 TKSTR token;
1120 char *p;
1121 int first=TRUE;
1123 /* Handle more than one prerequisite. */
1124 SET_TOKEN(&token, name);
1125 while (*(p=Get_token(&token, "", FALSE)) != '\0') {
1126 CELLPTR prq = Def_cell(p);
1127 LINKPTR tmp;
1129 for(tmp=head;tmp != NIL(LINK) && tmp->cl_prq != prq;tmp=tmp->cl_next);
1131 /* If tmp is not NULL the prerequisite already exists. */
1132 if ( tmp ) continue;
1134 /* Add list elements behind the first if more then one new
1135 * prerequisite is found. */
1136 if ( first ) {
1137 first = FALSE;
1139 else {
1140 TALLOC(tlp->cl_next,1,LINK);
1141 tlp = tlp->cl_next;
1142 tlp->cl_flag |= F_TARGET;
1143 tlp->cl_next = next;
1146 tlp->cl_prq = prq;
1147 tlp->cl_prq->ce_flag |= F_MARK;
1149 CLEAR_TOKEN( &token );
1152 /* If the condition is true no new prerequisits were found. */
1153 if ( lp->cl_prq == cur ) {
1154 lp->cl_prq = NIL(CELL);
1155 lp->cl_flag = 0;
1158 /* Is returned unchanged. */
1159 return(lp);
1163 static void
1164 _drop_mac( hp )/*
1165 ================ set a macro value to zero. */
1166 HASHPTR hp;
1168 if( hp && hp->ht_value != NIL(char) ) {
1169 FREE( hp->ht_value );
1170 hp->ht_value = NIL(char);
1176 static int
1177 _explode_graph( cp, parent, setdirroot )/*
1178 ==========================================
1179 Check to see if we have made the node already. If so then don't do
1180 it again, except if the cell's ce_setdir field is set to something other
1181 than the value of setdirroot. If they differ then, and we have made it
1182 already, then make it again and set the cell's stat bit to off so that
1183 we do the stat again. */
1184 CELLPTR cp;
1185 LINKPTR parent;
1186 CELLPTR setdirroot;
1188 static CELLPTR removecell = NIL(CELL);
1190 if ( removecell == NIL(CELL) )
1191 removecell = Def_cell(".REMOVE");
1193 /* we may return if we made it already from the same setdir location,
1194 * or if it is not a library member whose lib field is non NULL. (if
1195 * it is such a member then we have a line of the form:
1196 * lib1 lib2 .LIBRARY : member_list...
1197 * and we have to make sure all members are up to date in both libs. */
1199 if ( setdirroot == removecell )
1200 return( 0 );
1202 if( cp->ce_setdir == setdirroot &&
1203 !((cp->ce_attr & A_LIBRARYM) && (cp->ce_lib != NIL(char))) )
1204 return( 0 );
1206 /* We check to make sure that we are comming from a truly different
1207 * directory, ie. ".SETDIR=joe : a.c b.c d.c" are all assumed to come
1208 * from the same directory, even though setdirroot is different when
1209 * making dependents of each of these targets. */
1211 if( cp->ce_setdir != NIL(CELL) &&
1212 setdirroot != NIL(CELL) &&
1213 cp->ce_dir &&
1214 setdirroot->ce_dir &&
1215 !strcmp(cp->ce_dir, setdirroot->ce_dir) )
1216 return( 0 );
1218 if( Max_proc > 1 ) {
1219 LINKPTR dp;
1221 TALLOC(parent->cl_prq, 1, CELL);
1222 *parent->cl_prq = *cp;
1223 cp = parent->cl_prq;
1224 cp->ce_prq = _dup_prq(cp->ce_prqorg);
1225 cp->ce_all.cl_prq = cp;
1226 CeNotMe(cp) = _dup_prq(CeNotMe(cp));
1228 for(dp=CeNotMe(cp);dp;dp=dp->cl_next) {
1229 CELLPTR tcp = dp->cl_prq;
1230 TALLOC(dp->cl_prq,1,CELL);
1231 *dp->cl_prq = *tcp;
1232 dp->cl_prq->ce_flag &= ~(F_STAT|F_VISITED|F_MADE);
1233 dp->cl_prq->ce_set = cp;
1236 cp->ce_flag &= ~(F_STAT|F_VISITED|F_MADE);
1238 /* Indicate that we exploded the graph and that the current node should
1239 * be made. */
1240 return(1);
1245 PUBLIC int
1246 Exec_commands( cp )/*
1247 =====================
1248 Execute the commands one at a time that are pointed to by the rules pointer
1249 of the target cp if normal (non-group) recipes are defined. If a group recipe
1250 is found all commands are written into a temporary file first and this
1251 (group-) shell script is executed all at once.
1252 If a group is indicated, then the ce_attr determines .IGNORE and .SILENT
1253 treatment for the group.
1255 The function returns 0, if the command is executed and has successfully
1256 returned, and it returns 1 if the command is executing but has not yet
1257 returned or -1 if an error occured (Return value from Do_cmnd()).
1259 Macros that are found in recipe lines are expanded in this function, in
1260 parallel builds this can mean they are expanded before the previous recipe
1261 lines are finished. (Exception: $(shell ..) waits until all previous recipe
1262 lines are done.)
1264 The F_MADE bit in the cell is guaranteed set when the command has
1265 successfully completed. */
1266 CELLPTR cp;
1268 static HASHPTR useshell = NIL(HASH);
1269 static HASHPTR command = NIL(HASH);
1270 static int read_cmnd = 0;
1271 register STRINGPTR rp;
1272 STRINGPTR orp;
1273 char *cmnd;
1274 char *groupfile;
1275 FILE *tmpfile = 0;
1276 int do_it;
1277 t_attr attr;
1278 int group;
1279 int trace;
1280 int rval = 0;
1282 DB_ENTER( "Exec_commands" );
1284 if( cp->ce_recipe == NIL(STRING) )
1285 Fatal("Internal Error: No recipe found!");
1287 attr = Glob_attr | cp->ce_attr;
1288 trace = Trace || !(attr & A_SILENT);
1289 group = cp->ce_flag & F_GROUP;
1291 /* Do it again here for those that call us from places other than Make()
1292 * above. */
1293 orp = _recipes[ RP_RECIPE ];
1294 _recipes[ RP_RECIPE ] = cp->ce_recipe;
1296 if( group ) {
1297 /* Leave this assignment of Current_target here. It is needed just
1298 * incase the user hits ^C after the tempfile for the group recipe
1299 * has been opened. */
1300 Current_target = cp;
1301 trace = Trace || !(attr & A_SILENT);
1303 if( !Trace ) tmpfile = Start_temp( Grp_suff, cp, &groupfile );
1304 if( trace ) fputs( "[\n", stdout );
1306 /* Emit group prolog */
1307 if( attr & A_PROLOG )
1308 _append_file( _recipes[RP_GPPROLOG], tmpfile, cp->CE_NAME, trace );
1311 if( !useshell )
1312 useshell=Def_macro("USESHELL",NIL(char),M_MULTI|M_EXPANDED);
1314 if( !read_cmnd ) {
1315 command = GET_MACRO("COMMAND");
1316 read_cmnd = 1;
1319 /* Process commands in recipe. If in group, merely append to file.
1320 * Otherwise, run them. */
1321 for( rp=_recipes[RP_RECIPE]; rp != NIL(STRING); rp=rp->st_next) {
1322 t_attr a_attr = A_DEFAULT;
1323 t_attr l_attr;
1324 char *p;
1325 int new_attr = FALSE;
1326 int shell; /* True if the recipe shall run in shell. */
1328 /* Reset it for each recipe line otherwise tempfiles don't get removed.
1329 * Since processing of $(mktmp ...) depends on Current_target being
1330 * correctly set. */
1331 Current_target = cp;
1333 /* Only check for +,-,%,@ if the recipe line begins with a '$' macro
1334 * expansion. Otherwise there is no way it is going to find these
1335 * now. */
1336 if( *rp->st_string == '$' && !group ) {
1337 t_attr s_attr = Glob_attr;
1338 Glob_attr |= A_SILENT;
1339 Suppress_temp_file = TRUE;
1340 cmnd = Expand(rp->st_string);
1341 Suppress_temp_file = FALSE;
1342 a_attr |= Rcp_attribute(cmnd);
1343 FREE(cmnd);
1344 ++new_attr;
1345 Glob_attr = s_attr;
1348 l_attr = attr|a_attr|rp->st_attr;
1349 shell = ((l_attr & A_SHELL) != 0);
1350 useshell->ht_value = (group||shell)?"yes":"no";
1352 /* All macros are expanded before putting them in the "process queue".
1353 * Nothing in Expand() should be able to change dynamic macros. */
1354 cmnd = Expand( rp->st_string );
1356 if( new_attr && (p = DmStrSpn(cmnd," \t\n+-@%")) != cmnd ) {
1357 size_t len = strlen(p)+1;
1358 memmove(cmnd,p,len);
1361 /* COMMAND macro is set to "$(CMNDNAME) $(CMNDARGS)" by default, it is
1362 * possible for the user to reset it to, for example
1363 * COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS))
1364 * in order to get a different interface for his command execution. */
1365 if( command != NIL(HASH) && !group ) {
1366 char *cname = cmnd;
1367 char cmndbuf[30];
1369 if ( *(p=DmStrPbrk(cmnd," \t\n")) != '\0' ) {
1370 *p = '\0';
1371 (void)Def_macro("CMNDARGS",DmStrSpn(p+1," \t\n"),M_MULTI|M_EXPANDED);
1373 else
1374 (void) Def_macro("CMNDARGS","",M_MULTI|M_EXPANDED);
1376 (void) Def_macro("CMNDNAME",cname,M_MULTI|M_EXPANDED);
1378 strcpy(cmndbuf, "$(COMMAND)");
1379 cmnd = Expand(cmndbuf);
1380 FREE(cname); /* cname == cmnd at this point. */
1382 /* Collect up any new attributes */
1383 l_attr |= Rcp_attribute(cmnd);
1384 shell = ((l_attr & A_SHELL) != 0);
1386 /* clean up the attributes that we may have just added. */
1387 if( (p = DmStrSpn(cmnd," \t\n+-@%")) != cmnd ) {
1388 size_t len = strlen(p)+1;
1389 memmove(cmnd,p,len);
1393 #if defined(MSDOS)
1394 Swap_on_exec = ((l_attr & A_SWAP) != 0); /* Swapping for DOS only */
1395 #endif
1396 do_it = !Trace;
1398 /* We force execution of the recipe if we are tracing and the .EXECUTE
1399 * attribute was given or if the it is not a group recipe and the
1400 * recipe line contains the string $(MAKE). Wait_for_completion might
1401 * be changed gobaly but this is without consequences as we wait for
1402 * every recipe with .EXECUTE and don't start anything else. */
1403 if( Trace
1404 && ((l_attr & A_EXECUTE)||(!group && DmStrStr(rp->st_string,"$(MAKE)")))
1406 Wait_for_completion |= Trace;
1407 do_it = TRUE;
1410 if( group )
1411 /* Append_line() calls Print_cmnd(). */
1412 Append_line( cmnd, TRUE, tmpfile, cp->CE_NAME, trace, 0 );
1413 else {
1414 /* Don't print empty recipe lines. .ROOT and .TARGETS
1415 * deliberately might have empty "" recipes and we don't want
1416 * to output empty recipe lines for them. */
1417 if ( *cmnd ) {
1418 /* Print command and remove continuation sequence from cmnd. */
1419 Print_cmnd(cmnd, !(do_it && (l_attr & A_SILENT)), 0);
1421 rval=Do_cmnd(&cmnd,FALSE,do_it,cp,l_attr,
1422 rp->st_next == NIL(STRING) );
1425 FREE(cmnd);
1428 /* If it is a group then output the EPILOG if required and possibly
1429 * execute the command */
1430 if( group && !(cp->ce_attr & A_ERROR) ) {
1431 if( attr & A_EPILOG ) /* emit epilog */
1432 _append_file( _recipes[RP_GPEPILOG], tmpfile, cp->CE_NAME, trace );
1434 if( trace ) fputs("]\n", stdout);
1436 do_it = !Trace;
1437 if( do_it )
1439 Close_temp( cp, tmpfile );
1440 #if defined(UNIX)
1442 chmod(groupfile,0700);
1443 #endif
1445 rval = Do_cmnd(&groupfile, TRUE, do_it, cp, attr | A_SHELL, TRUE);
1448 _recipes[ RP_RECIPE ] = orp;
1449 cp->ce_attr &= ~A_ERROR;
1450 DB_RETURN( rval );
1454 PUBLIC void
1455 Print_cmnd( cmnd, echo, map )/*
1456 ================================
1457 This routine is called to print out the command to stdout. If echo is
1458 false the printing to stdout is supressed.
1459 The routine is also used to remove the line continuation sequence
1460 \<nl> from the command string and convert escape sequences if the
1461 map flag is set.
1462 The changed string is used later to actually to execute the command. */
1463 char *cmnd;
1464 int echo;
1465 int map;
1467 register char *p;
1468 register char *n;
1469 char tmp[3];
1471 DB_ENTER( "Print_cmnd" );
1473 if( echo ) {
1474 printf( "%s\n", cmnd );
1475 fflush(stdout);
1478 tmp[0] = ESCAPE_CHAR;
1479 tmp[1] = CONTINUATION_CHAR;
1480 tmp[2] = '\0';
1482 for( p=cmnd; *(n = DmStrPbrk(p,tmp)) != '\0'; )
1483 /* Remove the \<nl> sequences. */
1484 if(*n == CONTINUATION_CHAR && n[1] == '\n') {
1485 size_t len = strlen(n+2)+1;
1486 DB_PRINT( "make", ("fixing [%s]", p) );
1487 memmove( n, n+2, len );
1488 p = n;
1490 /* Look for an escape sequence and replace it by it's corresponding
1491 * character value. */
1492 else {
1493 if( *n == ESCAPE_CHAR && map ) Map_esc( n );
1494 p = n+1;
1497 DB_VOID_RETURN;
1502 /* These routines are used to maintain a stack of directories when making
1503 * the targets. If a target cd's to the directory then it is assumed that
1504 * it will undo it when it is finished making itself. */
1506 static STRINGPTR dir_stack = NIL(STRING);
1508 PUBLIC int
1509 Push_dir( dir, name, ignore )/*
1510 ===============================
1511 Change the current working directory to dir and save the current
1512 working directory on the stack so that we can come back.
1514 If ignore is TRUE then do not complain about _ch_dir if not possible.
1516 Return 1 if the directory change was successfull and 0 otherwise. */
1517 char *dir;
1518 char *name;
1519 int ignore;
1521 STRINGPTR new_dir;
1522 int freedir=FALSE;
1524 DB_ENTER( "Push_dir" );
1526 if( dir == NIL(char) || *dir == '\0' ) dir = Pwd;
1527 if( *dir == '\'' && dir[strlen(dir)-1] == '\'' ) {
1528 dir = DmStrDup(dir+1);
1529 dir[strlen(dir)-1]='\0';
1530 freedir=TRUE;
1532 else if (strchr(dir,'$') != NIL(char)) {
1533 dir = Expand(dir);
1534 freedir=TRUE;
1536 else
1537 dir = DmStrDup(dir);
1539 if( Set_dir(dir) ) {
1540 if( !ignore )
1541 Fatal( "Unable to change to directory `%s', target is [%s]",
1542 dir, name );
1543 if (freedir) FREE(dir);
1544 DB_RETURN( 0 );
1547 DB_PRINT( "dir", ("Push: [%s]", dir) );
1548 if( Verbose & V_DIR_SET )
1549 printf( "%s: Changed to directory [%s]\n", Pname, dir );
1551 if (freedir) FREE( dir );
1552 TALLOC( new_dir, 1, STRING );
1553 new_dir->st_next = dir_stack;
1554 dir_stack = new_dir;
1555 new_dir->st_string = DmStrDup( Pwd );
1557 Def_macro( "PWD", Get_current_dir(), M_FORCE | M_EXPANDED );
1558 _set_tmd();
1560 DB_RETURN( 1 );
1565 PUBLIC void
1566 Pop_dir(ignore)/*
1567 =================
1568 Change the current working directory to the previous saved dir. */
1569 int ignore;
1571 STRINGPTR old_dir;
1572 char *dir;
1574 DB_ENTER( "Pop_dir" );
1576 if( dir_stack == NIL(STRING) ) {
1577 if( ignore ) {
1578 DB_VOID_RETURN;
1580 else
1581 Error( "Directory stack empty for return from .SETDIR" );
1584 if( Set_dir(dir = dir_stack->st_string) )
1585 Fatal( "Could not change to directory `%s'", dir );
1587 Def_macro( "PWD", dir, M_FORCE | M_EXPANDED );
1588 DB_PRINT( "dir", ("Pop: [%s]", dir) );
1589 if( Verbose & V_DIR_SET )
1590 printf( "%s: Changed back to directory [%s]\n", Pname, dir);
1592 old_dir = dir_stack;
1593 dir_stack = dir_stack->st_next;
1595 FREE( old_dir->st_string );
1596 FREE( old_dir );
1597 _set_tmd();
1599 DB_VOID_RETURN;
1604 static void
1605 _set_tmd()/*
1606 ============
1607 Set the TMD Macro and the Tmd global variable. TMD stands for "To MakeDir"
1608 and is the path from the present directory (value of $(PWD)) to the directory
1609 dmake was started up in (value of $(MAKEDIR)). As _prefix() can return absolute
1610 paths some special .WINPATH treatment is needed.
1613 char *tmd;
1615 if( Tmd )
1616 FREE(Tmd);
1618 tmd = _prefix(Pwd, Makedir);
1619 if( *tmd ) {
1620 Def_macro( "TMD", DO_WINPATH(tmd), M_FORCE | M_EXPANDED );
1621 Tmd = DmStrDup(tmd);
1622 } else {
1623 Def_macro( "TMD", ".", M_FORCE | M_EXPANDED );
1624 Tmd = DmStrDup(".");
1626 FREE( tmd );
1630 static void
1631 _set_recipe( target, ind )/*
1632 ============================
1633 Set up the _recipes static variable so that the slot passed in points
1634 at the rules corresponding to the target supplied. */
1635 char *target;
1636 int ind;
1638 CELLPTR cp;
1639 HASHPTR hp;
1641 if( (hp = Get_name(target, Defs, FALSE)) != NIL(HASH) ) {
1642 cp = hp->CP_OWNR;
1643 _recipes[ ind ] = cp->ce_recipe;
1645 else
1646 _recipes[ ind ] = NIL(STRING);
1651 PUBLIC void
1652 Append_line( cmnd, newline, tmpfile, name, printit, map )
1653 char *cmnd;
1654 int newline;
1655 FILE *tmpfile;
1656 char *name;
1657 int printit;
1658 int map;
1660 Print_cmnd( cmnd, printit, map );
1662 if( Trace ) return;
1664 fputs(cmnd, tmpfile);
1665 if( newline ) fputc('\n', tmpfile);
1666 fflush(tmpfile);
1668 if( ferror(tmpfile) )
1669 Fatal("Write error on temporary file, while processing `%s'", name);
1674 static void
1675 _append_file( rp, tmpfile, name, printit )
1676 register STRINGPTR rp;
1677 FILE *tmpfile;
1678 char *name;
1679 int printit;
1681 char *cmnd;
1683 while( rp != NIL(STRING) ) {
1684 Append_line(cmnd = Expand(rp->st_string), TRUE, tmpfile, name, printit,0);
1685 FREE(cmnd);
1686 rp = rp->st_next;
1691 #define NUM_BUCKETS 20
1693 typedef struct strpool {
1694 char *string; /* a pointer to the string value */
1695 uint32 keyval; /* the strings hash value */
1696 struct strpool *next; /* hash table link pointer */
1697 } POOL, *POOLPTR;
1699 static POOLPTR strings[ NUM_BUCKETS ];
1701 static char *
1702 _pool_lookup( str )/*
1703 =====================
1704 Scan down the list of chained strings and see if one of them matches
1705 the string we are looking for. */
1706 char *str;
1708 register POOLPTR key;
1709 uint32 keyval;
1710 uint16 hv;
1711 uint16 keyindex;
1712 char *string;
1714 DB_ENTER( "_pool_lookup" );
1716 if( str == NIL(char) ) DB_RETURN("");
1718 hv = Hash(str, &keyval);
1719 key = strings[ keyindex = (hv % NUM_BUCKETS) ];
1721 while( key != NIL(POOL) )
1722 if( (key->keyval != keyval) || strcmp(str, key->string) )
1723 key = key->next;
1724 else
1725 break;
1727 if( key == NIL(POOL) ) {
1728 DB_PRINT( "pool", ("Adding string [%s]", str) );
1729 TALLOC( key, 1, POOL ); /* not found so add string */
1731 key->string = string = DmStrDup(str);
1732 key->keyval = keyval;
1734 key->next = strings[ keyindex ];
1735 strings[ keyindex ] = key;
1737 else {
1738 DB_PRINT( "pool", ("Found string [%s], key->string") );
1739 string = key->string;
1742 DB_RETURN( string );
1746 void
1747 Unmake( cp )/*
1748 ==============
1749 Remove flags indicating that a target was previously made. This
1750 is used for infered makefiles. */
1751 CELLPTR cp;
1753 LINKPTR dp, ep;
1754 CELLPTR tcp, pcp;
1756 DB_ENTER( "Unmake" );
1758 for(dp=CeMeToo(cp); dp; dp=dp->cl_next) {
1759 tcp = dp->cl_prq;
1761 /* Unmake the prerequisites. */
1762 for( ep = tcp->ce_prq; ep != NIL(LINK); ep = ep->cl_next ) {
1763 pcp = ep->cl_prq;
1765 Unmake(pcp);
1767 DB_PRINT( "unmake", ("Unmake [%s]", tcp->CE_NAME) );
1769 tcp->ce_flag &= ~(F_MADE|F_VISITED|F_STAT);
1770 tcp->ce_time = (time_t)0L;
1773 DB_VOID_RETURN;