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