update dev300-m58
[ooovba.git] / dmake / dmake.c
blobcae60beb727108bc2ba05b72368b8a896a7e4e46
1 /* $RCSfile: dmake.c,v $
2 -- $Revision: 1.13 $
3 -- last change: $Author: kz $ $Date: 2008-03-05 18:28:04 $
4 --
5 -- SYNOPSIS
6 -- The main program.
7 --
8 -- DESCRIPTION
9 --
10 -- dmake [-#dbug_string] [ options ]
11 -- [ macro definitions ] [ target ... ]
12 --
13 -- This file contains the main command line parser for the
14 -- make utility. The valid flags recognized are as follows:
15 --
16 -- -f file - use file as the makefile
17 -- -C file - duplicate console output to file (MSDOS only)
18 -- -K file - .KEEP_STATE file
19 -- -#dbug_string - dump out debugging info, see below
20 -- -v[cdfimrtw] - verbose, print what we are doing, as we do it
21 -- -m[trae] - measure timing information
22 --
23 -- options: (can be catenated, ie -irn == -i -r -n)
24 --
25 -- -A - enable AUGMAKE special target mapping
26 -- -B - enable non-use of TABS to start recipe lines
27 -- -c - use non-standard comment scanning
28 -- -d - do not use directory cache
29 -- -i - ignore errors
30 -- -n - trace and print, do not execute commands
31 -- -t - touch, update dates without executing commands
32 -- -T - do not apply transitive closure on inference rules
33 -- -r - don't use internal rules
34 -- -s - do your work silently
35 -- -S - force Sequential make, overrides -P
36 -- -q - check if target is up to date. Does not
37 -- do anything. Returns 0 if up to date, -1
38 -- otherwise.
39 -- -p - print out a version of the makefile
40 -- -P# - set value of MAXPROCESS
41 -- -E - define environment strings as macros
42 -- -e - as -E but done after parsing makefile
43 -- -u - force unconditional update of target
44 -- -k - make all independent targets even if errors
45 -- -V - print out this make version number
46 -- -M - Microsoft make compatibility, (* disabled *)
47 -- -h - print out usage info
48 -- -x - export macro defs to environment
49 -- -X - ignore #! lines found in makefile
50 --
51 -- NOTE: - #ddbug_string is only availabe for versions of dmake that
52 -- have been compiled with -DDBUG switch on. Not the case for
53 -- distributed versions. Any such versions must be linked
54 -- together with a version of Fred Fish's debug code.
55 --
56 -- NOTE: - in order to compile the code the include file stddef.h
57 -- must be shipped with the bundled code.
58 --
59 -- AUTHOR
60 -- Dennis Vadura, dvadura@dmake.wticorp.com
62 -- WWW
63 -- http://dmake.wticorp.com/
65 -- COPYRIGHT
66 -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
67 --
68 -- This program is NOT free software; you can redistribute it and/or
69 -- modify it under the terms of the Software License Agreement Provided
70 -- in the file <distribution-root>/readme/license.txt.
72 -- LOG
73 -- Use cvs log to obtain detailed change logs.
76 /* Set this flag to one, and the global variables in vextern.h will not
77 * be defined as 'extern', instead they will be defined as global vars
78 * when this module is compiled. */
79 #define _DEFINE_GLOBALS_ 1
81 #include "extern.h" /* this includes config.h */
82 #include "sysintf.h"
84 #ifndef MSDOS
85 #define USAGE \
86 "Usage:\n%s [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n"
87 #define USAGE2 \
88 "%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n"
89 #else
90 #define USAGE \
91 "Usage:\n%s [-P#] [-{f|C|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n"
92 #define USAGE2 \
93 "%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n"
94 #endif
96 /* We don't use va_end at all, so define it out so that it doesn't produce
97 * lots of "Value not used" warnings. */
98 #ifdef va_end
99 #undef va_end
100 #endif
101 #define va_end(expand_to_null)
103 /* Make certain that ARG macro is correctly defined. */
104 #ifdef ARG
105 #undef ARG
106 #endif
107 #define ARG(a,b) a b
109 static char *sccid = "Copyright (c) 1990,...,1997 by WTI Corp.";
110 static char _warn = TRUE; /* warnings on by default */
112 static void _do_VPATH();
113 static void _do_ReadEnvironment();
114 #if !defined(__GNUC__) && !defined(__IBMC__)
115 static void _do_f_flag ANSI((char, char *, char **));
116 #else
117 static void _do_f_flag ANSI((int, char *, char **));
118 #endif
120 PUBLIC int
121 main(argc, argv)
122 int argc;
123 char **argv;
125 #ifdef MSDOS
126 char* std_fil_name = NIL(char);
127 #endif
129 char* fil_name = NIL(char);
130 char* state_name = NIL(char);
131 char* whatif = NIL(char);
132 char* cmdmacs;
133 char* targets;
134 STRINGPTR cltarget = NIL(STRING); /* list of targets from command line. */
135 STRINGPTR cltarget_first = NIL(STRING); /* Pointer to first element. */
136 FILE* mkfil;
137 int ex_val;
138 int m_export;
140 /* Uncomment the following line to pass commands to the DBUG engine
141 * before the command line switches (-#..) are evaluated. */
143 DB_PUSH("d,path");
145 DB_ENTER("main");
147 /* Initialize Global variables to their default values */
148 Prolog(argc, argv);
149 /* Set internal macros to their initial values, some are changed
150 * later again by Make_rules() that parses the values from ruletab.c. */
151 Create_macro_vars();
152 Catch_signals(Quit);
154 /* This macro is only defined for some OSs, see sysintf.c for details *
155 * and NULL if undefined. */
156 Def_macro("ABSMAKECMD", AbsPname, M_PRECIOUS|M_NOEXPORT|M_EXPANDED );
158 Def_macro( "MAKECMD", Pname, M_PRECIOUS|M_NOEXPORT|M_EXPANDED );
159 Pname = Basename(Pname);
161 DB_PROCESS(Pname);
162 (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* stdout line buffered */
164 Continue = FALSE;
165 Comment = FALSE;
166 Get_env = FALSE;
167 Force = FALSE;
168 Target = FALSE;
169 If_expand = FALSE;
170 Listing = FALSE;
171 Readenv = FALSE;
172 Rules = TRUE;
173 Trace = FALSE;
174 Touch = FALSE;
175 Check = FALSE;
176 Microsoft = FALSE;
177 Makemkf = FALSE;
178 UseWinpath= FALSE;
179 No_exec = FALSE;
180 m_export = FALSE;
181 cmdmacs = NIL(char);
182 targets = NIL(char);
183 Is_exec_shell = FALSE;
184 Shell_exec_target = NIL(CELL);
185 stdout_redir = NIL(FILE);
187 /* Get fd for for @@-recipe silencing. */
188 if( (zerofd = open(NULLDEV, O_WRONLY)) == -1 )
189 Fatal( "Error opening %s !", NULLDEV );
191 Verbose = V_NOFLAG;
192 Measure = M_NOFLAG;
193 Transitive = TRUE;
194 Nest_level = 0;
195 Line_number = 0;
196 Suppress_temp_file = FALSE;
197 Skip_to_eof = FALSE;
199 while( --argc > 0 ) {
200 register char *p;
201 char *q;
203 if( *(p = *++argv) == '-' ) {
204 if( p[1] == '\0' ) Fatal("Missing option letter");
206 /* copy options to Buffer for $(MFLAGS), strip 'f' and 'C'*/
207 q = strchr(Buffer, '\0');
208 while (*p != '\0') {
209 char c = (*q++ = *p++);
210 if( c == 'f' || c == 'C' ) q--;
213 if( *(q-1) == '-' )
214 q--;
215 else
216 *q++ = ' ';
218 *q = '\0';
220 for( p = *argv+1; *p; p++) switch (*p) {
221 case 'f':
222 _do_f_flag( 'f', *++argv, &fil_name ); argc--;
223 break;
225 #if defined(MSDOS) && !defined(OS2)
226 case 'C':
227 _do_f_flag( 'C', *++argv, &std_fil_name ); argc--;
228 Hook_std_writes( std_fil_name );
229 break;
230 #endif
232 case 'K':
233 _do_f_flag( 'K', *++argv, &state_name ); argc--;
234 Def_macro(".KEEP_STATE", state_name, M_EXPANDED|M_PRECIOUS);
235 break;
237 case 'W':
238 case 'w': {
239 CELLPTR wif;
240 _do_f_flag( 'w', *++argv, &whatif ); argc--;
241 wif = Def_cell(whatif);
242 wif->ce_attr |= A_WHATIF;
243 whatif = NIL(char);
245 if ( *p == 'W')
246 break;
248 /*FALLTHRU*/
250 case 'n':
251 Trace = TRUE;
252 break;
254 case 'k': Continue = TRUE; break;
255 case 'c': Comment = TRUE; break;
256 case 'p': Listing = TRUE; break;
257 case 'r': Rules = FALSE; break;
258 case 't': Touch = TRUE; break;
259 case 'q': Check = TRUE; break;
260 case 'u': Force = TRUE; break;
261 case 'x': m_export = TRUE; break;
262 case 'X': No_exec = TRUE; break;
263 case 'T': Transitive = FALSE; break;
264 case 'e': Get_env = 'e'; break;
265 case 'E': Get_env = 'E'; break;
267 case 'V': Version(); Quit(0); break;
268 case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED); break;
269 case 'B': Def_macro(".NOTABS", "y", M_EXPANDED); break;
270 case 'i': Def_macro(".IGNORE", "y", M_EXPANDED); break;
271 case 's': Def_macro(".SILENT", "y", M_EXPANDED); break;
272 case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED); break;
273 case 'g': Def_macro(".IGNOREGROUP","y", M_EXPANDED); break;
274 case 'd': Def_macro(".DIRCACHE",NIL(char),M_EXPANDED); break;
276 case 'v':
277 if( p[-1] != '-' ) Usage(TRUE);
278 while( p[1] ) switch( *++p ) {
279 case 'c': Verbose |= V_DIR_CACHE; break;
280 case 'd': Verbose |= V_DIR_SET; break;
281 case 'f': Verbose |= V_FILE_IO; break;
282 case 'i': Verbose |= V_INFER; break;
283 case 'm': Verbose |= V_MAKE; break;
284 case 'r': Verbose |= V_FORCEECHO; break;
285 case 't': Verbose |= V_LEAVE_TMP; break;
286 case 'w': Verbose |= V_WARNALL; break;
288 default: Usage(TRUE); break;
290 if( !Verbose ) Verbose = V_ALL;
291 if( Verbose & V_FORCEECHO ) {
292 HASHPTR hp;
293 /* This cleans the .SILENT setting */
294 hp = Def_macro(".SILENT", "", M_EXPANDED);
295 /* This overrides the bitmask for further occurences of
296 * .SILENT to "no bits allowed", see bit variables in the
297 * set_macro_value() definition in dag.c.
298 * The bitmask is already set by Create_macro_vars() in
299 * imacs.c and is overridden for the V_FORCEECHO case. */
300 hp->MV_MASK = A_DEFAULT;
302 break;
304 case 'm':
305 if( p[-1] != '-' ) Usage(TRUE);
306 while( p[1] ) switch( *++p ) {
307 case 't': Measure |= M_TARGET; break;
308 case 'r': Measure |= M_RECIPE; break;
309 case 'a': Measure |= M_ABSPATH; break;
310 case 'e': Measure |= M_SHELLESC; break;
312 default: Usage(TRUE); break;
314 if( !Measure ) Measure = M_TARGET;
315 break;
317 case 'P':
318 if( p[1] ) {
319 /* Only set MAXPROCESS if -S flag is *not* used. */
320 if( !(Glob_attr & A_SEQ) ) {
321 Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
323 p += strlen(p)-1;
325 else
326 Fatal( "Missing number for -P flag" );
327 break;
329 #ifdef DBUG
330 case '#':
331 DB_PUSH(p+1);
332 p += strlen(p)-1;
333 break;
334 #endif
336 case 'h': Usage(FALSE); break;
337 case 0: break; /* lone - */
338 default: Usage(TRUE); break;
341 else if( (q = strchr(p, '=')) != NIL(char) ) {
342 cmdmacs = DmStrAdd( cmdmacs, DmStrDup2(p), TRUE );
343 /* Macros defined on the command line are marked precious.
344 * FIXME: The exception for += appears to be bogus. */
345 Parse_macro( p, (q[-1]!='+')?M_PRECIOUS:M_DEFAULT );
347 else {
348 /* Remember the targets from the command line. */
349 register STRINGPTR nsp;
351 targets = DmStrAdd( targets, DmStrDup(p), TRUE );
353 TALLOC(nsp, 1, STRING);
354 nsp->st_string = DmStrDup( p );
355 nsp->st_next = NIL(STRING);
357 if(cltarget != NIL(STRING) )
358 cltarget->st_next = nsp;
359 else
360 cltarget_first = nsp;
362 cltarget = nsp;
366 Def_macro( "MAKEMACROS", cmdmacs, M_PRECIOUS|M_NOEXPORT );
367 Def_macro( "MAKETARGETS", targets, M_PRECIOUS|M_NOEXPORT );
368 if( cmdmacs != NIL(char) ) FREE(cmdmacs);
369 if( targets != NIL(char) ) FREE(targets);
371 Def_macro( "MFLAGS", Buffer, M_PRECIOUS|M_NOEXPORT );
372 Def_macro( "%", "$@", M_PRECIOUS|M_NOEXPORT );
374 if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS|M_NOEXPORT );
376 _warn = FALSE; /* disable warnings for builtin rules */
377 Target = TRUE; /* make sure we don't mark any of the default rules as
378 * potential targets. */
379 Make_rules(); /* Parse the strings stored in Rule_tab. */
380 _warn = TRUE;
382 /* If -r was not given find and parse startup-makefile. */
383 if( Rules ) {
384 char *fname;
386 /* Search_file() also checks the environment variable. */
387 if( (mkfil=Search_file("MAKESTARTUP", &fname)) != NIL(FILE) ) {
388 Parse(mkfil);
389 Def_macro( "MAKESTARTUP", fname, M_EXPANDED|M_MULTI|M_FORCE );
391 else
392 Fatal( "Configuration file `%s' not found", fname );
395 /* Define the targets set on the command line now. */
396 Target = FALSE; /* Will be set to TRUE when the default targets are set. */
397 for( cltarget = cltarget_first; cltarget != NIL(STRING); ) {
398 CELLPTR cp;
399 STRINGPTR nta = cltarget->st_next;
401 Add_prerequisite(Targets, cp = Def_cell(cltarget->st_string),
402 FALSE, FALSE);
403 cp->ce_flag |= F_TARGET;
404 cp->ce_attr |= A_FRINGE;
405 Target = TRUE;
407 FREE(cltarget->st_string);
408 FREE(cltarget);
409 cltarget = nta;
412 if( Get_env == 'E' ) _do_ReadEnvironment();
414 /* Search for and parse user makefile. */
415 if( fil_name != NIL(char) )
416 mkfil = Openfile( fil_name, FALSE, TRUE );
417 else {
418 /* Search .MAKEFILES dependent list looking for a makefile.
420 register CELLPTR cp;
422 cp = Def_cell( ".MAKEFILES" );
423 mkfil = TryFiles(cp->CE_PRQ);
426 if( mkfil != NIL(FILE) ) {
427 char *f = Filename();
428 char *p;
430 if( strcmp(f, "stdin") == 0 ) f = "-";
431 p = DmStrAdd( "-f", f, FALSE );
432 Def_macro( "MAKEFILE", p, M_PRECIOUS|M_NOEXPORT );
433 Parse( mkfil );
435 else if( !Rules )
436 Fatal( "No `makefile' present" );
438 if( Nest_level ) Fatal( "Missing .END for .IF" );
439 if( Get_env == 'e' ) _do_ReadEnvironment();
441 _do_VPATH(); /* kludge it up with .SOURCE */
443 if( Listing ) Dump(); /* print out the structures */
444 if( Trace ) Glob_attr &= ~A_SILENT; /* make sure we see the trace */
446 if( !Target )
447 Fatal( "No target" );
448 else {
449 Test_circle( Root, TRUE );
450 Check_circle_dfa();
453 if( m_export ) {
454 int i;
456 for( i=0; i<HASH_TABLE_SIZE; ++i ) {
457 HASHPTR hp = Macs[i];
459 while( hp ) {
460 if( !(hp->ht_flag & M_NOEXPORT) && hp->ht_value != NIL(char) )
461 if( Write_env_string(hp->ht_name, hp->ht_value) != 0 )
462 Warning( "Could not export %s", hp->ht_name );
463 hp = hp->ht_next;
468 if( Buffer != NIL(char) ) {FREE( Buffer ); Buffer = NIL(char);}
469 if( Trace ) Def_macro(".SEQUENTIAL", "y", M_EXPANDED);
471 ex_val = Make_targets();
473 Clear_signals();
475 /* Close fd for for @@-recipe silencing. */
476 if( close(zerofd) )
477 Fatal( "Error closing %s !", NULLDEV );
478 Epilog(ex_val); /* Does not return -- EVER */
479 return 0;
483 static void
484 _do_f_flag( flag, name, fname )
485 char flag;
486 char *name;
487 char **fname;
489 if( *fname == NIL(char) ) {
490 if( name != NIL(char) ) {
491 *fname = name;
492 } else
493 Fatal("No file name for -%c", flag);
494 } else
495 Fatal("Only one `-%c file' allowed", flag);
499 static void
500 _do_ReadEnvironment()
502 t_attr saveattr = Glob_attr;
504 Glob_attr |= A_SILENT;
505 ReadEnvironment();
506 Glob_attr = saveattr;
510 static void
511 _do_VPATH()
513 HASHPTR hp;
514 char *_rl[2];
515 extern char **Rule_tab;
517 hp = GET_MACRO("VPATH");
518 if( hp == NIL(HASH) ) return;
520 _rl[0] = ".SOURCE :^ $(VPATH:s/:/ /)";
521 _rl[1] = NIL(char);
523 Rule_tab = _rl;
524 Parse( NIL(FILE) );
528 /* The file table and pointer to the next FREE slot for use by both
529 Openfile and Closefile. Each open stacks the new file onto the open
530 file stack, and a corresponding close will close the passed file, and
531 return the next file on the stack. The maximum number of nested
532 include files is limited by the value of MAX_INC_DEPTH */
534 static struct {
535 FILE *file; /* file pointer */
536 char *name; /* name of file */
537 int numb; /* line number */
538 } ftab[ MAX_INC_DEPTH ];
540 static int next_file_slot = 0;
542 /* Set the proper macro value to reflect the depth of the .INCLUDE directives
543 * and the name of the file we are reading.
545 static void
546 _set_inc_depth()
548 char buf[10];
549 sprintf( buf, "%d", next_file_slot );
550 Def_macro( "INCDEPTH", buf, M_MULTI|M_NOEXPORT );
551 Def_macro( "INCFILENAME",
552 next_file_slot ? ftab[next_file_slot-1].name : "",
553 M_MULTI|M_NOEXPORT|M_EXPANDED );
557 PUBLIC FILE *
558 Openfile(name, mode, err)/*
559 ===========================
560 This routine opens a file for input or output depending on mode.
561 If the file name is `-' then it returns standard input.
562 The file is pushed onto the open file stack. */
563 char *name;
564 int mode;
565 int err;
567 FILE *fil;
569 DB_ENTER("Openfile");
571 if( name == NIL(char) || !*name ) {
572 if( !err )
573 DB_RETURN(NIL(FILE));
574 else
575 Fatal( "Openfile: NIL filename" );
578 if( next_file_slot == MAX_INC_DEPTH )
579 Fatal( "Too many open files. Max nesting level is %d.", MAX_INC_DEPTH);
581 DB_PRINT( "io", ("Opening file [%s], in slot %d", name, next_file_slot) );
583 if( strcmp("-", name) == 0 ) {
584 name = "stdin";
585 fil = stdin;
587 else
588 fil = fopen( name, mode ? "w":"r" );
590 if( Verbose & V_FILE_IO )
591 printf( "%s: Openning [%s] for %s", Pname, name, mode?"write":"read" );
593 if( fil == NIL(FILE) ) {
594 if( Verbose & V_FILE_IO ) printf( " (fail)\n" );
595 if( err )
596 Fatal( mode ? "Cannot open file %s for write" : "File %s not found",
597 name );
599 else {
600 if( Verbose & V_FILE_IO ) printf( " (success)\n" );
601 ftab[next_file_slot].file = fil;
602 ftab[next_file_slot].numb = Line_number;
603 ftab[next_file_slot++].name = DmStrDup(name);
604 Line_number = 0;
605 _set_inc_depth();
608 DB_RETURN(fil);
612 PUBLIC FILE *
613 Closefile()/*
614 =============
615 This routine is used to close the last file opened. This forces make
616 to open files in a last open first close fashion. It returns the
617 file pointer to the next file on the stack, and NULL if the stack is empty.*/
619 DB_ENTER("Closefile");
621 if( !next_file_slot )
622 DB_RETURN( NIL(FILE) );
624 if( ftab[--next_file_slot].file != stdin ) {
625 DB_PRINT( "io", ("Closing file in slot %d", next_file_slot) );
627 if( Verbose & V_FILE_IO )
628 printf( "%s: Closing [%s]\n", Pname, ftab[next_file_slot].name );
630 fclose( ftab[next_file_slot].file );
631 FREE( ftab[next_file_slot].name );
634 _set_inc_depth();
636 if( next_file_slot > 0 ) {
637 Line_number = ftab[next_file_slot].numb;
638 DB_RETURN( ftab[next_file_slot-1].file );
640 else
641 Line_number = 0;
643 DB_RETURN( NIL(FILE) );
647 PUBLIC FILE *
648 Search_file( macname, rname )
649 char *macname;
650 char **rname;
652 HASHPTR hp;
653 FILE *fil = NIL(FILE);
654 char *fname = NIL(char);
655 char *ename = NIL(char);
657 /* order of precedence is:
659 * MACNAME from command line (precious is marked)
660 * ... via MACNAME:=filename definition.
661 * MACNAME from environment
662 * MACNAME from builtin rules (not precious)
665 if( (hp = GET_MACRO(macname)) != NIL(HASH) ) {
666 /* Only expand if needed. */
667 if( hp->ht_flag & M_EXPANDED ) {
668 ename = fname = DmStrDup(hp->ht_value);
669 } else {
670 ename = fname = Expand(hp->ht_value);
673 if( hp->ht_flag & M_PRECIOUS ) fil = Openfile(fname, FALSE, FALSE);
676 if( fil == NIL(FILE) ) {
677 fname=Expand(Read_env_string(macname));
678 if( (fil = Openfile(fname, FALSE, FALSE)) != NIL(FILE) ) FREE(ename);
681 if( fil == NIL(FILE) && hp != NIL(HASH) )
682 fil = Openfile(fname=ename, FALSE, FALSE);
684 if( rname ) *rname = fname;
686 return(fil);
690 PUBLIC char *
691 Filename()/*
692 ============
693 Return name of file on top of stack */
695 return( next_file_slot==0 ? NIL(char) : ftab[next_file_slot-1].name );
699 PUBLIC int
700 Nestlevel()/*
701 =============
702 Return the file nesting level */
704 return( next_file_slot );
708 PUBLIC FILE *
709 TryFiles(lp)/*
710 ==============
711 Try to open a makefile, try to make it if needed and return a
712 filepointer to the first successful found or generated file.
713 The function returns NIL(FILE) if nothing was found. */
714 LINKPTR lp;
716 FILE *mkfil = NIL(FILE);
718 if( lp != NIL(LINK) ) {
719 int s_n, s_t, s_q;
721 s_n = Trace;
722 s_t = Touch;
723 s_q = Check;
725 Trace = Touch = Check = FALSE;
726 /* We are making a makefile. Wait for it. */
727 Makemkf = Wait_for_completion = TRUE;
728 mkfil = NIL(FILE);
730 for(; lp != NIL(LINK) && mkfil == NIL(FILE); lp=lp->cl_next) {
731 if( lp->cl_prq->ce_attr & A_FRINGE ) continue;
733 mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE );
735 /* Note that no error handling for failed Make() calls is possible
736 * as expected errors (no rule to make the makefile) or unexpected
737 * errors both return -1. */
738 if( mkfil == NIL(FILE) && Make(lp->cl_prq, NIL(CELL)) != -1 ) {
739 mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE );
740 /* Remove flags that indicate that the target was already made.
741 * This is also needed to avoid conflicts with the circular
742 * dependency check in rulparse(), see issues 62118 and 81296
743 * for details. */
744 Unmake(lp->cl_prq);
748 Trace = s_n;
749 Touch = s_t;
750 Check = s_q;
751 Makemkf = Wait_for_completion = FALSE;
754 return(mkfil);
759 ** print error message from variable arg list
762 static int errflg = TRUE;
763 static int warnflg = FALSE;
765 static void
766 errargs(fmt, args)
767 char *fmt;
768 va_list args;
770 int warn = _warn && warnflg && !(Glob_attr & A_SILENT);
772 if( errflg || warn ) {
773 char *f = Filename();
775 fprintf( stderr, "%s: ", Pname );
776 if( f != NIL(char) ) fprintf(stderr, "%s: line %d: ", f, Line_number);
778 if( errflg )
779 fprintf(stderr, "Error: -- ");
780 else if( warn )
781 fprintf(stderr, "Warning: -- ");
783 vfprintf( stderr, fmt, args );
784 putc( '\n', stderr );
785 if( errflg && !Continue ) Quit(0);
791 ** Print error message and abort
793 PUBLIC void
794 #ifndef __MWERKS__
795 Fatal(ARG(char *,fmt), ARG(va_alist_type,va_alist))
796 #else
797 Fatal(char * fmt, ...)
798 #endif
799 DARG(char *,fmt)
800 DARG(va_alist_type,va_alist)
802 va_list args;
804 va_start(args, fmt);
805 Continue = FALSE;
806 errargs(fmt, args);
807 va_end(args);
811 ** error message and exit (unless -k)
813 PUBLIC void
814 #ifndef __MWERKS__
815 Error(ARG(char *,fmt), ARG(va_alist_type,va_alist))
816 #else
817 Error(char * fmt, ...)
818 #endif
819 DARG(char *,fmt)
820 DARG(va_alist_type,va_alist)
822 va_list args;
824 va_start(args, fmt);
825 errargs(fmt, args);
826 va_end(args);
831 ** non-fatal message
833 PUBLIC void
834 #ifndef __MWERKS__
835 Warning(ARG(char *,fmt), ARG(va_alist_type,va_alist))
836 #else
837 Warning(char * fmt , ...)
838 #endif
839 DARG(char *,fmt)
840 DARG(va_alist_type,va_alist)
842 va_list args;
844 va_start(args, fmt);
845 warnflg = TRUE;
846 errflg = FALSE;
847 errargs(fmt, args);
848 errflg = TRUE;
849 warnflg = FALSE;
850 va_end(args);
854 PUBLIC void
855 No_ram()
857 Fatal( "No more memory" );
861 PUBLIC void
862 Usage( eflag )
863 int eflag;
865 register char *p;
866 char *fill;
868 fill = DmStrDup(Pname);
869 for(p=fill; *p; p++) *p=' ';
871 if( eflag ) {
872 fprintf(stderr, USAGE, Pname);
873 fprintf(stderr, USAGE2, fill);
875 else {
876 printf(USAGE, Pname);
877 printf(USAGE2, fill);
878 puts(" -P# - set max number of child processes for parallel make");
879 puts(" -f file - use file as the makefile");
880 #ifdef MSDOS
881 puts(" -C [+]file - duplicate console output to file, ('+' => append)");
882 #endif
883 puts(" -K file - use file as the .KEEP_STATE file");
884 puts(" -w target - show what you would do if 'target' were out of date");
885 puts(" -W target - rebuild pretending that 'target' is out of date");
886 puts(" -v[cdfimrtw] - verbose, indicate what we are doing, (-v => -vcdfimrtw)");
887 puts(" c => dump directory cache info only" );
888 puts(" d => dump change of directory info only" );
889 puts(" f => dump file open/close info only" );
890 puts(" i => dump inference information only" );
891 puts(" m => dump make of target information only" );
892 puts(" r => Force output of recipe lines and warnings," );
893 puts(" overrides -s" );
894 puts(" t => keep temporary files when done" );
895 puts(" w => issue non-essential warnings\n" );
897 puts(" -m[trae] - Measure timing information, (-m => -mt)");
898 puts(" t => display the start and end time of each target" );
899 puts(" r => display the start and end time of each recipe" );
900 puts(" a => display the target as an absolute path" );
901 puts(" e => display the timing of shell escape macros\n" );
903 puts("Options: (can be catenated, ie -irn == -i -r -n)");
904 puts(" -A - enable AUGMAKE special target mapping");
905 puts(" -B - enable the use of spaces instead of tabs to start recipes");
906 puts(" -c - use non standard comment scanning");
907 puts(" -d - do not use directory cache");
908 puts(" -E - define environment strings as macros");
909 puts(" -e - same as -E but done after parsing makefile");
910 puts(" -g - disable the special meaning of [ ... ] for group recipes");
911 puts(" -h - print out usage info");
912 puts(" -i - ignore errors");
913 puts(" -k - make independent targets, even if errors");
914 puts(" -n - trace and print, do not execute commands");
915 puts(" -p - print out a version of the makefile");
916 puts(" -q - check if target is up to date. Does not do");
917 puts(" anything. Returns 0 if up to date, 1 otherwise");
918 puts(" -r - don't use internal rules");
919 puts(" -s - do your work silently");
920 puts(" -S - disable parallel (force sequential) make, overrides -P");
921 puts(" -t - touch, update time stamps without executing commands");
922 puts(" -T - do not apply transitive closure on inference rules");
923 puts(" -u - force unconditional update of target");
924 puts(" -V - print out version number");
925 puts(" -x - export macro values to environment");
926 puts(" -X - ignore #! lines at start of makefile");
929 Quit(0);
933 PUBLIC void
934 Version()
936 extern char **Rule_tab;
937 char **p;
939 printf("%s - Version %s (%s)\n", Pname, VERSION, BUILDINFO);
940 printf("%s\n\n", sccid);
942 puts("Default Configuration:");
943 for (p=Rule_tab; *p != NIL(char); p++)
944 printf("\t%s\n", *p);
946 printf("\n");
948 #if defined(HAVE_SPAWN_H) || defined(__CYGWIN__)
949 /* Only systems that have spawn ar concerned whether spawn or fork/exec
950 * are used. */
951 #if ENABLE_SPAWN
952 printf("Subprocesses are executed using: spawn.\n\n");
953 #else
954 printf("Subprocesses are executed using: fork/exec.\n\n");
955 #endif
956 #endif
958 printf("Please read the NEWS file for the latest release notes.\n");