update dev300-m58
[ooovba.git] / dmake / dag.c
blobcee947503e68f6f9c6c75c99740c806f12f4413f
1 /* $RCSfile: dag.c,v $
2 -- $Revision: 1.12 $
3 -- last change: $Author: kz $ $Date: 2008-03-05 18:27:48 $
4 --
5 -- SYNOPSIS
6 -- Routines to construct the internal dag.
7 --
8 -- DESCRIPTION
9 -- This file contains all the routines that are responsible for
10 -- defining and manipulating all objects used by the make facility.
11 --
12 -- AUTHOR
13 -- Dennis Vadura, dvadura@dmake.wticorp.com
15 -- WWW
16 -- http://dmake.wticorp.com/
18 -- COPYRIGHT
19 -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
20 --
21 -- This program is NOT free software; you can redistribute it and/or
22 -- modify it under the terms of the Software License Agreement Provided
23 -- in the file <distribution-root>/readme/license.txt.
25 -- LOG
26 -- Use cvs log to obtain detailed change logs.
29 #include "extern.h"
32 static void
33 set_macro_value(hp)/*
34 =====================
35 Set the macro according to its type. In addition to the string value
36 in hp->ht_value a macro can stores a value casted with its type.
38 HASHPTR hp;
40 switch( hp->ht_flag & M_VAR_MASK ) /* only one var type per var */
42 case M_VAR_STRING:
43 *hp->MV_SVAR = hp->ht_value;
44 /* Add special treatment for PWD/MAKEDIR for .WINPATH. */
45 if( hp->MV_SVAR == &Pwd_macval ) {
46 if( Pwd )
47 FREE(Pwd);
48 Pwd = hp->ht_value;
49 /* Use the "DOSified" path for the macro. */
50 *hp->MV_SVAR = hp->ht_value = DmStrDup(DO_WINPATH(hp->ht_value));
51 DB_PRINT( "smv", ("PWD: %s/%s", Pwd_macval, Pwd) );
52 } else if( hp->MV_SVAR == &Makedir_macval ) {
53 if( Makedir )
54 FREE(Makedir);
55 Makedir = hp->ht_value;
56 /* Use the "DOSified" path for the macro. */
57 *hp->MV_SVAR = hp->ht_value = DmStrDup(DO_WINPATH(hp->ht_value));
58 DB_PRINT( "smv", ("MAKEDIR: %s/%s", Makedir_macval, Makedir) );
60 /* No special treatment for TMD needed. */
61 break;
63 case M_VAR_CHAR:
64 *hp->MV_CVAR = (hp->ht_value == NIL(char)) ? '\0':*hp->ht_value;
65 break;
67 case M_VAR_INT: {
68 int tvalue;
69 if( hp->MV_IVAR == NIL(int) ) break; /* first time */
71 tvalue = atoi(hp->ht_value);
72 if( hp->MV_IVAR == &Buffer_size ) {
73 /* If Buffer_size (MAXLINELENGTH) is modified then make sure
74 * you change the size of the real buffer as well. As the
75 * value will at least be BUFSIZ this might lead to the
76 * situation that the (string) value of MAXLINELENGTH is
77 * smaller than the integer value. */
78 tvalue = (tvalue < (BUFSIZ-2)) ? BUFSIZ : tvalue+2;
79 if( Buffer_size == tvalue ) break;
80 if( Buffer ) FREE(Buffer);
81 if((Buffer=MALLOC(tvalue, char)) == NIL(char)) No_ram();
82 *Buffer = '\0';
84 *hp->MV_IVAR = tvalue;
86 if( hp->MV_IVAR == &Max_proc || hp->MV_IVAR == &Max_proclmt ) {
87 if( tvalue < 1 )
88 Fatal( "Process limit value must be > 1" );
90 #if defined(USE_CREATEPROCESS)
91 if( Max_proclmt > MAXIMUM_WAIT_OBJECTS )
92 Fatal( "Specified maximum # of processes (MAXPROCESSLIMIT)"
93 " exceeds OS limit of [%d].", MAXIMUM_WAIT_OBJECTS );
94 #endif
96 if( Max_proc > Max_proclmt )
97 Fatal( "Specified # of processes exceeds limit of [%d]",
98 Max_proclmt );
100 /* Don't change MAXPROCESS value if .SEQUENTIAL is set. */
101 if( (Glob_attr & A_SEQ) && (Max_proc != 1) ) {
102 Warning( "Macro MAXPROCESS set to 1 because .SEQUENTIAL is set." );
103 Max_proc = 1;
104 if( hp->ht_value != NIL(char) ) FREE(hp->ht_value);
105 hp->ht_value = DmStrDup( "1" );
108 } break;
110 case M_VAR_BIT:
111 /* Bit variables are set to 1 if ht_value is not NULL and 0
112 * otherwise */
114 if( hp->ht_value == NIL(char) )
115 *hp->MV_BVAR &= ~hp->MV_MASK;
116 else {
117 *hp->MV_BVAR |= hp->MV_MASK;
118 /* If we're setting .SEQUENTIAL set MAXPROCESS=1. */
119 if( (hp->MV_MASK & A_SEQ) && (Max_proc != 1) )
120 Def_macro( "MAXPROCESS", "1", M_MULTI|M_EXPANDED);
123 #if defined(__CYGWIN__)
124 /* Global .WINPATH change. Only needed for cygwin. */
125 if(hp->MV_MASK & A_WINPATH) {
126 UseWinpath = ((Glob_attr&A_WINPATH) != 0);
127 /* Change MAKEDIR, PWD according to .WINPATH. During
128 * makefile evaluation this cannot change TMD (it is "."
129 * and later TMD is set in Make() according to the
130 * .WINPATH attribute. */
131 Def_macro( "MAKEDIR", Makedir, M_FORCE | M_EXPANDED );
132 Def_macro( "PWD", Pwd, M_FORCE | M_EXPANDED );
134 #endif
135 break;
140 PUBLIC HASHPTR
141 Get_name( name, tab, define )/*
142 ===============================
143 Look to see if the name is defined, if it is then return
144 a pointer to its node, if not return NIL(HASH).
145 If define is TRUE and the name is not found it will be added. */
147 char *name; /* name we are looking for */
148 HASHPTR *tab; /* the hash table to look in */
149 int define; /* TRUE => add to table */
151 register HASHPTR hp;
152 register char *p;
153 uint16 hv;
154 uint32 hash_key;
156 DB_ENTER( "Get_name" );
157 DB_PRINT( "name", ("Looking for %s", name) );
159 hp = Search_table( tab, name, &hv, &hash_key );
161 if( hp == NIL(HASH) && define ) {
162 /* Check to make sure that CELL name contains only printable chars */
163 for( p=name; *p; p++ )
164 if( !isprint(*p) && !iswhite(*p) && *p != '\n' )
165 Fatal( "Name contains non-printable character [0x%02x]", *p );
167 TALLOC( hp, 1, HASH ); /* allocate a cell and add it in */
169 hp->ht_name = DmStrDup( name );
170 hp->ht_hash = hash_key;
171 hp->ht_next = tab[ hv ];
172 tab[ hv ] = hp;
174 DB_PRINT( "name", ("Adding %s", name) );
177 DB_PRINT( "name",("Returning: [%s,%lu]",
178 (hp == NIL(HASH)) ? "":hp->ht_name, hv) );
179 DB_RETURN( hp );
183 PUBLIC HASHPTR
184 Search_table( tab, name, phv, phkey )
185 HASHPTR *tab;
186 char *name;
187 uint16 *phv;
188 uint32 *phkey;
190 HASHPTR hp;
192 *phv = Hash( name, phkey );
194 for( hp = tab[ *phv ]; hp != NIL(HASH); hp = hp->ht_next )
195 if( hp->ht_hash == *phkey
196 && !strcmp(hp->ht_name, name) )
197 break;
199 return( hp );
203 PUBLIC HASHPTR
204 Push_macro(hp)/*
205 ================
206 This function pushes hp into the hash of all macros. If a previous
207 instance of the macro exists it is hidden by the new one. If one
208 existed before the new instance inherits some values from the preexisting
209 macro (see below for details).
211 HASHPTR hp;
213 HASHPTR cur,prev;
214 uint16 hv;
215 uint32 key;
217 hv = Hash(hp->ht_name, &key);
219 /* Search for an existing instance of hp->ht_name, if found cur will point
220 * to it. */
221 for(prev=NIL(HASH),cur=Macs[hv]; cur!=NIL(HASH); prev=cur,cur=cur->ht_next)
222 if( cur->ht_hash == key
223 && !strcmp(cur->ht_name, hp->ht_name) )
224 break;
226 if (cur == NIL(HASH) || prev == NIL(HASH)) {
227 /* If no match or was found or the first element of Macs[hv] was
228 * the match insert hp at the beginning. */
229 hp->ht_next = Macs[hv];
230 Macs[hv] = hp;
232 else {
233 /* otherwise insert hp in the chain. */
234 hp->ht_next = prev->ht_next;
235 prev->ht_next = hp;
238 /* Inherit some parts of the former instance. Copying cur->var to hp->var
239 * copies the old value. Keeping the M_VAR_MASK (variable type) makes sure
240 * the type stays the same keeping M_PRECIOUS assures that the old values
241 * cannot be overridden if it is/was set. */
242 if (cur) {
243 memcpy((void *)&hp->var, (void *)&cur->var, sizeof(hp->var));
244 hp->ht_flag |= ((M_VAR_MASK|M_PRECIOUS) & cur->ht_flag);
247 return(hp);
251 PUBLIC HASHPTR
252 Pop_macro(hp)/*
253 ================
254 This function pops (removes) hp from the hash of all macros. If a previous
255 instance of the macro existed it becomes accessible again.
258 HASHPTR hp;
260 HASHPTR cur,prev;
261 uint16 hv;
262 uint32 key;
264 hv = Hash(hp->ht_name, &key);
266 /* Try to find hp. */
267 for(prev=NIL(HASH),cur=Macs[hv]; cur != NIL(HASH);prev=cur,cur=cur->ht_next)
268 if (cur == hp)
269 break;
271 /* If cur == NIL macros was not found. */
272 if (cur == NIL(HASH))
273 return(NIL(HASH));
275 /* Remove hp from the linked list. */
276 if (prev)
277 prev->ht_next = cur->ht_next;
278 else
279 Macs[hv] = cur->ht_next;
281 /* Look for a previous (older) instance of hp->ht_name. */
282 for(cur=cur->ht_next; cur != NIL(HASH); cur=cur->ht_next)
283 if( cur->ht_hash == key
284 && !strcmp(cur->ht_name, hp->ht_name) )
285 break;
287 /* If one was found we restore the typecast values. */
288 if (cur)
289 set_macro_value(cur);
291 hp->ht_next = NIL(HASH);
292 return(hp);
297 PUBLIC HASHPTR
298 Def_macro( name, value, flags )/*
299 =================================
300 This routine is used to define a macro, and it's value. A copy of
301 the content of value is stored and not the pointer to the value.
302 The flags indicates if it is a permanent macro or if it's value
303 can be redefined. A flags of M_PRECIOUS means it is a precious
304 macro and cannot be further redefined unless M_FORCE is used.
305 If the flags flag contains the M_MULTI bit it means that the macro
306 can be redefined multiple times and no warning of the redefinitions
307 should be issued.
308 Once a macro's VAR flags are set they are preserved through all future
309 macro definitions.
311 Macro definitions that have one of the variable bits set are treated
312 specially. In each case the hash table entry var field points at the
313 global variable that can be set by assigning to the macro.
315 bit valued global vars must be computed when the macro value is changed.
316 char valued global vars must have the first char of ht_value copied to
317 them. string valued global vars have the same value as ht_value and should
318 just have the new value of ht_value copied to them. */
320 char *name; /* macro name to define */
321 char *value; /* macro value to set */
322 int flags; /* initial ht_flags */
324 register HASHPTR hp;
325 register char *p, *q;
327 DB_ENTER( "Def_macro" );
328 DB_PRINT( "mac", ("Defining macro %s = %s, %x", name, value, flags) );
330 /* check to see if name is in the table, if so then just overwrite
331 the previous definition. Otherwise allocate a new node, and
332 stuff it in the hash table, at the front of any linked list */
334 if( Readenv ) flags |= M_LITERAL|M_EXPANDED;
336 hp = Get_name( name, Macs, TRUE );
338 if ((flags & M_PUSH) && hp->ht_name != NIL(char)) {
339 HASHPTR thp=hp;
340 TALLOC(hp,1,HASH);
341 hp->ht_name = DmStrDup(thp->ht_name);
342 hp->ht_hash = thp->ht_hash;
343 Push_macro(hp);
344 flags |= hp->ht_flag;
346 flags &= ~M_PUSH;
348 if( (hp->ht_flag & M_PRECIOUS) && !(flags & M_FORCE) ) {
349 if (Verbose & V_WARNALL)
350 Warning( "Macro `%s' cannot be redefined", name );
351 DB_RETURN( hp );
354 /* Make sure we don't export macros whose names contain legal macro
355 * assignment operators, since we can't do proper quoting in the
356 * environment. */
357 if( *DmStrPbrk(name, "*+:=") != '\0' ) flags |= M_NOEXPORT;
359 if( hp->ht_value != NIL(char) ) FREE( hp->ht_value );
361 if( (hp->ht_flag & M_USED) && !((flags | hp->ht_flag) & M_MULTI) )
362 Warning( "Macro `%s' redefined after use", name );
364 /* If an empty string ("") is given set ht_value to NIL(char) */
365 if( (value != NIL(char)) && (*value) ) {
367 if( !(flags & M_LITERAL) ) {
368 q = DmStrDup(value);
369 /* strip out any \<nl> combinations where \ is the current
370 * CONTINUATION char */
371 for(p=q; (p=strchr(p,CONTINUATION_CHAR))!=NIL(char); )
372 if( p[1] == '\n' )
373 strcpy( p, p+2 );
374 else
375 p++;
377 p = DmStrSpn(q ," \t"); /* Strip white space before ... */
378 if( p != q ) {
379 strcpy( q, p);
380 p = q;
383 if( *p ) { /* ... and after the value. */
384 for(q=p+strlen(p)-1; ((*q == ' ')||(*q == '\t')); q--);
385 *++q = '\0';
387 flags &= ~M_LITERAL;
389 else
390 p = DmStrDup( value ); /* take string literally */
392 if( !*p ) { /* check if result is "" */
393 FREE( p );
394 p = NIL(char);
395 flags |= M_EXPANDED;
397 else if( *DmStrPbrk( p, "${}" ) == '\0' )
398 flags |= M_EXPANDED;
400 hp->ht_value = p;
402 else {
403 hp->ht_value = NIL(char);
404 flags |= M_EXPANDED;
407 /* Assign the hash table flag less the M_MULTI flag, it is used only
408 * to silence the warning. But carry it over if it was previously
409 * defined in ht_flag, as this is a permanent M_MULTI variable. Keep
410 * the M_PRECIOUS flag and strip the M_INIT flag. */
412 hp->ht_flag = ((flags & ~(M_MULTI|M_FORCE)) |
413 (hp->ht_flag & (M_VAR_MASK|M_MULTI|M_PRECIOUS))) & ~M_INIT;
415 /* Check for macro variables and make the necessary adjustment in the
416 * corresponding global variables */
418 if( hp->ht_flag & M_VAR_MASK ) {
419 if( !(flags & M_EXPANDED) )
420 Error( "Macro variable '%s' must be assigned with :=", name );
421 else
422 set_macro_value(hp);
425 DB_RETURN( hp );
430 PUBLIC CELLPTR
431 Def_cell( name )/*
432 ==================
433 Check if a cell for "name" already exists, if not create a new cell.
434 The value of name is normalized before checking/creating the cell to
435 avoid creating multiple cells for the same target file.
436 The function returns a pointer to the cell. */
437 char *name;
439 register HASHPTR hp;
440 register CELLPTR cp;
441 register CELLPTR lib;
442 char *member;
443 char *end;
445 DB_ENTER( "Def_cell" );
447 /* Check to see if the cell is a member of the form lib(member) or
448 * lib((symbol)) and handle the cases appropriately.
449 * What we do is we look at the target, if it is of the above two
450 * forms we get the lib, and add the member/symbol to the list of
451 * prerequisites for the library. If this is a symbol name def'n
452 * we additionally add the attribute A_SYMBOL, so that stat can
453 * try to do the right thing. */
455 if( ((member = strchr(name, '(')) != NIL(char)) &&
456 ((end = strrchr(member, ')')) != NIL(char)) &&
457 (member > name) && (member[-1] != '$') &&
458 (end > member+1) && (end[1] == '\0') )
460 *member++ = *end = '\0';
462 if( (*member == '(') && (member[strlen(member)-1] == ')') ) {
463 member[ strlen(member)-1 ] = '\0';
464 cp = Def_cell( member+1 );
465 cp->ce_attr |= A_SYMBOL;
467 else
468 cp = Def_cell( member );
470 lib = Def_cell( name );
472 Add_prerequisite( lib, cp, FALSE, FALSE );
473 lib->ce_attr |= A_LIBRARY | A_COMPOSITE;
475 if( !Def_targets ) cp = lib;
477 else {
478 /* Normalize the name. */
479 DB_PRINT( "path", ("Normalizing [%s]", name) );
481 /* The normalizing function returns a pointer to a static buffer. */
482 name = normalize_path(name);
484 hp = Get_name( name, Defs, TRUE );/* get the name from hash table */
486 if( hp->CP_OWNR == NIL(CELL) ) /* was it previously defined */
487 { /* NO, so define a new cell */
488 DB_PRINT( "cell", ("Defining cell [%s]", name) );
490 TALLOC( cp, 1, CELL );
491 hp->CP_OWNR = cp;
492 cp->ce_name = hp;
493 cp->ce_fname = hp->ht_name;
494 cp->ce_all.cl_prq = cp;
496 else /* YES, so return the old cell */
498 DB_PRINT( "cell", ("Getting cell [%s]", hp->ht_name) );
499 cp = hp->CP_OWNR;
503 DB_RETURN( cp );
509 PUBLIC LINKPTR
510 Add_prerequisite( cell, prq, head, force )/*
511 ============================================
512 Add a dependency node to the dag. It adds it to the prerequisites,
513 if any, of the cell and makes certain they are in linear order.
514 If head == 1, then add to head of the prerequisite list, else
515 add to tail. */
516 CELLPTR cell;
517 CELLPTR prq;
518 int head;
519 int force;
521 register LINKPTR lp, tlp;
523 DB_ENTER( "Add_prerequisite" );
524 DB_PRINT( "cell", ("Defining prerequisite %s", prq->CE_NAME) );
526 if( (prq->ce_flag & (F_MAGIC | F_PERCENT)) && !force )
527 Fatal( "Special target [%s] cannot be a prerequisite",
528 prq->CE_NAME );
530 if( cell->ce_prq == NIL(LINK) ) { /* it's the first one */
531 TALLOC( lp, 1, LINK );
532 lp->cl_prq = prq;
533 cell->ce_prq = lp;
535 else { /* search the list, checking for duplicates */
536 for( lp = cell->ce_prq;
537 (lp->cl_next != NIL(LINK)) && (lp->cl_prq != prq);
538 lp = lp->cl_next );
540 /* If the prq is not found and we are at the last prq in the list,
541 * allocate a new prq and place it into the list, insert it at the
542 * head if head == 1, else we add it to the end. */
544 if( lp->cl_prq != prq ) {
545 TALLOC( tlp, 1, LINK );
546 tlp->cl_prq = prq;
548 if( head ) {
549 tlp->cl_next = cell->ce_prq;
550 cell->ce_prq = tlp;
552 else
553 lp->cl_next = tlp;
555 lp = tlp;
559 DB_RETURN( lp );
564 PUBLIC void
565 Clear_prerequisites( cell )/*
566 =============================
567 Clear out the list of prerequisites, freeing all of the LINK nodes,
568 and setting the list to NULL */
569 CELLPTR cell;
571 LINKPTR lp, tlp;
573 DB_ENTER( "Clear_prerequisites" );
574 DB_PRINT( "cell", ("Nuking prerequisites") );
576 if( cell == NIL(CELL) ) { DB_VOID_RETURN; }
578 for( lp=cell->ce_prq; lp != NIL(LINK); lp=tlp ) {
579 tlp=lp->cl_next;
580 FREE( lp );
583 cell->ce_prq = NIL(LINK);
585 DB_VOID_RETURN;
589 PUBLIC int
590 Test_circle( cp, fail )/*
591 =========================
592 Actually run through the graph */
593 CELLPTR cp;
594 int fail;
596 register LINKPTR lp;
597 int res = 0;
599 DB_ENTER( "Test_circle" );
600 DB_PRINT( "tc", ("checking [%s]", cp->CE_NAME) );
602 if( cp->ce_flag & F_MARK ) {
603 if( fail )
604 Fatal("Detected circular dependency in graph at [%s]", cp->CE_NAME);
605 else
606 DB_RETURN( 1 );
609 cp->ce_flag |= F_MARK;
610 for( lp = cp->ce_prq; !res && lp != NIL(LINK); lp = lp->cl_next )
611 res = Test_circle( lp->cl_prq, fail );
612 cp->ce_flag ^= F_MARK;
614 DB_RETURN( res );
619 PUBLIC STRINGPTR
620 Def_recipe( rcp, sp, white_too, no_check )/*
621 =============================================
622 Take the recipe (rcp) and add it to the list of recipes pointed to by
623 sp (sp points to the last element). If white_too == TRUE add the recipe
624 even if it contains only white space or an empty string.
625 Return a pointer to the new recipe (or sp if it was discarded).
626 If no_check is true then don't look for -@ at the start of the recipe
627 line. */
628 char *rcp;
629 STRINGPTR sp;
630 int white_too;
631 int no_check;
633 register STRINGPTR nsp;
634 register char *rp;
636 DB_ENTER( "Def_recipe" );
637 DB_PRINT( "rul", ("Defining recipe %s", rcp) );
639 if( !white_too ) rcp = DmStrSpn( rcp, " \t" );
640 if( (rcp == NIL(char)) || (*rcp == 0 && !white_too) )
641 DB_RETURN( sp ); /* return last recipe when new recipe not added */
643 rp = no_check ? rcp : DmStrSpn( rcp, " \t@-+%" );
645 TALLOC(nsp, 1, STRING);
646 nsp->st_string = DmStrDup( rp );
648 if( sp != NIL(STRING) ) sp->st_next = nsp;
649 nsp->st_next = NIL(STRING);
651 if( !no_check ) nsp->st_attr |= Rcp_attribute( rcp );
653 DB_RETURN( nsp );
657 PUBLIC t_attr
658 Rcp_attribute( rp )/*
659 ======================
660 Look at the recipe and return the set of attributes that it defines. */
661 char *rp;
663 t_attr flag = A_DEFAULT;
664 int done = FALSE;
665 int atcount = 0;
667 while( !done )
668 switch( *rp++ )
670 case '@' : ++atcount; break;
671 case '-' : flag |= A_IGNORE; break;
672 case '+' : flag |= A_SHELL; break;
673 case '%' :
674 #if defined(MSDOS)
675 /* Ignore % in the non-MSDOS case. */
676 flag |= A_SWAP;
677 #endif
678 break;
680 case ' ' :
681 case '\t': break;
683 default: done = TRUE; break;
686 if( !(Verbose & V_FORCEECHO) && atcount-- ) {
687 flag |= A_SILENT;
688 /* hide output if more than one @ are encountered. */
689 if( atcount )
690 flag |= A_MUTE;
693 return(flag);