merge the formfield patch from ooo-build
[ooovba.git] / dmake / dag.c
bloba1e11457617fb7ca3b185cec324dc919c19a7588
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 size_t len = strlen(p+2)+1;
374 memmove ( p, p+2, len );
376 else
377 p++;
379 p = DmStrSpn(q ," \t"); /* Strip white space before ... */
380 if( p != q ) {
381 size_t len = strlen(p)+1;
382 memmove( q, p, len );
383 p = q;
386 if( *p ) { /* ... and after the value. */
387 for(q=p+strlen(p)-1; ((*q == ' ')||(*q == '\t')); q--);
388 *++q = '\0';
390 flags &= ~M_LITERAL;
392 else
393 p = DmStrDup( value ); /* take string literally */
395 if( !*p ) { /* check if result is "" */
396 FREE( p );
397 p = NIL(char);
398 flags |= M_EXPANDED;
400 else if( *DmStrPbrk( p, "${}" ) == '\0' )
401 flags |= M_EXPANDED;
403 hp->ht_value = p;
405 else {
406 hp->ht_value = NIL(char);
407 flags |= M_EXPANDED;
410 /* Assign the hash table flag less the M_MULTI flag, it is used only
411 * to silence the warning. But carry it over if it was previously
412 * defined in ht_flag, as this is a permanent M_MULTI variable. Keep
413 * the M_PRECIOUS flag and strip the M_INIT flag. */
415 hp->ht_flag = ((flags & ~(M_MULTI|M_FORCE)) |
416 (hp->ht_flag & (M_VAR_MASK|M_MULTI|M_PRECIOUS))) & ~M_INIT;
418 /* Check for macro variables and make the necessary adjustment in the
419 * corresponding global variables */
421 if( hp->ht_flag & M_VAR_MASK ) {
422 if( !(flags & M_EXPANDED) )
423 Error( "Macro variable '%s' must be assigned with :=", name );
424 else
425 set_macro_value(hp);
428 DB_RETURN( hp );
433 PUBLIC CELLPTR
434 Def_cell( name )/*
435 ==================
436 Check if a cell for "name" already exists, if not create a new cell.
437 The value of name is normalized before checking/creating the cell to
438 avoid creating multiple cells for the same target file.
439 The function returns a pointer to the cell. */
440 char *name;
442 register HASHPTR hp;
443 register CELLPTR cp;
444 register CELLPTR lib;
445 char *member;
446 char *end;
448 DB_ENTER( "Def_cell" );
450 /* Check to see if the cell is a member of the form lib(member) or
451 * lib((symbol)) and handle the cases appropriately.
452 * What we do is we look at the target, if it is of the above two
453 * forms we get the lib, and add the member/symbol to the list of
454 * prerequisites for the library. If this is a symbol name def'n
455 * we additionally add the attribute A_SYMBOL, so that stat can
456 * try to do the right thing. */
458 if( ((member = strchr(name, '(')) != NIL(char)) &&
459 ((end = strrchr(member, ')')) != NIL(char)) &&
460 (member > name) && (member[-1] != '$') &&
461 (end > member+1) && (end[1] == '\0') )
463 *member++ = *end = '\0';
465 if( (*member == '(') && (member[strlen(member)-1] == ')') ) {
466 member[ strlen(member)-1 ] = '\0';
467 cp = Def_cell( member+1 );
468 cp->ce_attr |= A_SYMBOL;
470 else
471 cp = Def_cell( member );
473 lib = Def_cell( name );
475 Add_prerequisite( lib, cp, FALSE, FALSE );
476 lib->ce_attr |= A_LIBRARY | A_COMPOSITE;
478 if( !Def_targets ) cp = lib;
480 else {
481 /* Normalize the name. */
482 DB_PRINT( "path", ("Normalizing [%s]", name) );
484 /* The normalizing function returns a pointer to a static buffer. */
485 name = normalize_path(name);
487 hp = Get_name( name, Defs, TRUE );/* get the name from hash table */
489 if( hp->CP_OWNR == NIL(CELL) ) /* was it previously defined */
490 { /* NO, so define a new cell */
491 DB_PRINT( "cell", ("Defining cell [%s]", name) );
493 TALLOC( cp, 1, CELL );
494 hp->CP_OWNR = cp;
495 cp->ce_name = hp;
496 cp->ce_fname = hp->ht_name;
497 cp->ce_all.cl_prq = cp;
499 else /* YES, so return the old cell */
501 DB_PRINT( "cell", ("Getting cell [%s]", hp->ht_name) );
502 cp = hp->CP_OWNR;
506 DB_RETURN( cp );
512 PUBLIC LINKPTR
513 Add_prerequisite( cell, prq, head, force )/*
514 ============================================
515 Add a dependency node to the dag. It adds it to the prerequisites,
516 if any, of the cell and makes certain they are in linear order.
517 If head == 1, then add to head of the prerequisite list, else
518 add to tail. */
519 CELLPTR cell;
520 CELLPTR prq;
521 int head;
522 int force;
524 register LINKPTR lp, tlp;
526 DB_ENTER( "Add_prerequisite" );
527 DB_PRINT( "cell", ("Defining prerequisite %s", prq->CE_NAME) );
529 if( (prq->ce_flag & (F_MAGIC | F_PERCENT)) && !force )
530 Fatal( "Special target [%s] cannot be a prerequisite",
531 prq->CE_NAME );
533 if( cell->ce_prq == NIL(LINK) ) { /* it's the first one */
534 TALLOC( lp, 1, LINK );
535 lp->cl_prq = prq;
536 cell->ce_prq = lp;
538 else { /* search the list, checking for duplicates */
539 for( lp = cell->ce_prq;
540 (lp->cl_next != NIL(LINK)) && (lp->cl_prq != prq);
541 lp = lp->cl_next );
543 /* If the prq is not found and we are at the last prq in the list,
544 * allocate a new prq and place it into the list, insert it at the
545 * head if head == 1, else we add it to the end. */
547 if( lp->cl_prq != prq ) {
548 TALLOC( tlp, 1, LINK );
549 tlp->cl_prq = prq;
551 if( head ) {
552 tlp->cl_next = cell->ce_prq;
553 cell->ce_prq = tlp;
555 else
556 lp->cl_next = tlp;
558 lp = tlp;
562 DB_RETURN( lp );
567 PUBLIC void
568 Clear_prerequisites( cell )/*
569 =============================
570 Clear out the list of prerequisites, freeing all of the LINK nodes,
571 and setting the list to NULL */
572 CELLPTR cell;
574 LINKPTR lp, tlp;
576 DB_ENTER( "Clear_prerequisites" );
577 DB_PRINT( "cell", ("Nuking prerequisites") );
579 if( cell == NIL(CELL) ) { DB_VOID_RETURN; }
581 for( lp=cell->ce_prq; lp != NIL(LINK); lp=tlp ) {
582 tlp=lp->cl_next;
583 FREE( lp );
586 cell->ce_prq = NIL(LINK);
588 DB_VOID_RETURN;
592 PUBLIC int
593 Test_circle( cp, fail )/*
594 =========================
595 Actually run through the graph */
596 CELLPTR cp;
597 int fail;
599 register LINKPTR lp;
600 int res = 0;
602 DB_ENTER( "Test_circle" );
603 DB_PRINT( "tc", ("checking [%s]", cp->CE_NAME) );
605 if( cp->ce_flag & F_MARK ) {
606 if( fail )
607 Fatal("Detected circular dependency in graph at [%s]", cp->CE_NAME);
608 else
609 DB_RETURN( 1 );
612 cp->ce_flag |= F_MARK;
613 for( lp = cp->ce_prq; !res && lp != NIL(LINK); lp = lp->cl_next )
614 res = Test_circle( lp->cl_prq, fail );
615 cp->ce_flag ^= F_MARK;
617 DB_RETURN( res );
622 PUBLIC STRINGPTR
623 Def_recipe( rcp, sp, white_too, no_check )/*
624 =============================================
625 Take the recipe (rcp) and add it to the list of recipes pointed to by
626 sp (sp points to the last element). If white_too == TRUE add the recipe
627 even if it contains only white space or an empty string.
628 Return a pointer to the new recipe (or sp if it was discarded).
629 If no_check is true then don't look for -@ at the start of the recipe
630 line. */
631 char *rcp;
632 STRINGPTR sp;
633 int white_too;
634 int no_check;
636 register STRINGPTR nsp;
637 register char *rp;
639 DB_ENTER( "Def_recipe" );
640 DB_PRINT( "rul", ("Defining recipe %s", rcp) );
642 if( !white_too ) rcp = DmStrSpn( rcp, " \t" );
643 if( (rcp == NIL(char)) || (*rcp == 0 && !white_too) )
644 DB_RETURN( sp ); /* return last recipe when new recipe not added */
646 rp = no_check ? rcp : DmStrSpn( rcp, " \t@-+%" );
648 TALLOC(nsp, 1, STRING);
649 nsp->st_string = DmStrDup( rp );
651 if( sp != NIL(STRING) ) sp->st_next = nsp;
652 nsp->st_next = NIL(STRING);
654 if( !no_check ) nsp->st_attr |= Rcp_attribute( rcp );
656 DB_RETURN( nsp );
660 PUBLIC t_attr
661 Rcp_attribute( rp )/*
662 ======================
663 Look at the recipe and return the set of attributes that it defines. */
664 char *rp;
666 t_attr flag = A_DEFAULT;
667 int done = FALSE;
668 int atcount = 0;
670 while( !done )
671 switch( *rp++ )
673 case '@' : ++atcount; break;
674 case '-' : flag |= A_IGNORE; break;
675 case '+' : flag |= A_SHELL; break;
676 case '%' :
677 #if defined(MSDOS)
678 /* Ignore % in the non-MSDOS case. */
679 flag |= A_SWAP;
680 #endif
681 break;
683 case ' ' :
684 case '\t': break;
686 default: done = TRUE; break;
689 if( !(Verbose & V_FORCEECHO) && atcount-- ) {
690 flag |= A_SILENT;
691 /* hide output if more than one @ are encountered. */
692 if( atcount )
693 flag |= A_MUTE;
696 return(flag);