Bug Summary

File:dmake/dmake.c
Location:line 525, column 1
Description:Address of stack memory associated with local variable '_rl' is still referred to by the global variable 'Rule_tab' upon returning to the caller. This will be a dangling reference

Annotated 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 1
78
79#include "extern.h" /* this includes config.h */
80#include "sysintf.h"
81
82#ifndef MSDOS
83#define USAGE"Usage:\n%s [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n" \
84"Usage:\n%s [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n"
85#define USAGE2"%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n" \
86"%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n"
87#else
88#define USAGE"Usage:\n%s [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n" \
89"Usage:\n%s [-P#] [-{f|C|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n"
90#define USAGE2"%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n" \
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 a b
106
107static char *sccid = "Copyright (c) 1990,...,1997 by WTI Corp.";
108static char _warn = TRUE1; /* warnings on by default */
109
110static void _do_VPATH();
111static void _do_ReadEnvironment();
112#if !defined(__GNUC__4) && !defined(__IBMC__)
113static void _do_f_flag ANSI((char, char *, char **))(char, char *, char **);
114#else
115static void _do_f_flag ANSI((int, char *, char **))(int, char *, char **);
116#endif
117
118PUBLIC int
119main(argc, argv)
120int argc;
121char **argv;
122{
123#ifdef MSDOS
124 char* std_fil_name = NIL(char)((char*)((void*)0));
125#endif
126
127 char* fil_name = NIL(char)((char*)((void*)0));
128 char* state_name = NIL(char)((char*)((void*)0));
129 char* whatif = NIL(char)((char*)((void*)0));
130 char* cmdmacs;
131 char* targets;
132 STRINGPTR cltarget = NIL(STRING)((STRING*)((void*)0)); /* list of targets from command line. */
133 STRINGPTR cltarget_first = NIL(STRING)((STRING*)((void*)0)); /* 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 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 Create_macro_vars();
150 Catch_signals(Quit);
151
152 /* This macro is only defined for some OSs, see sysintf.c for details *
153 * and NULL if undefined. */
154 Def_macro("ABSMAKECMD", AbsPname, M_PRECIOUS0x0002|M_NOEXPORT0x0040|M_EXPANDED0x0008 );
155
156 Def_macro( "MAKECMD", Pname, M_PRECIOUS0x0002|M_NOEXPORT0x0040|M_EXPANDED0x0008 );
157 Pname = Basename(Pname);
158
159 DB_PROCESS(Pname);
160 (void) setvbuf(stdoutstdout, NULL((void*)0), _IOLBF1, BUFSIZ8192); /* stdout line buffered */
161
162 Continue = FALSE0;
163 Comment = FALSE0;
164 Get_env = FALSE0;
165 Force = FALSE0;
166 Target = FALSE0;
167 If_expand = FALSE0;
168 Listing = FALSE0;
169 Readenv = FALSE0;
170 Rules = TRUE1;
171 Trace = FALSE0;
172 Touch = FALSE0;
173 Check = FALSE0;
174 Microsoft = FALSE0;
175 Makemkf = FALSE0;
176 UseWinpath= FALSE0;
177 No_exec = FALSE0;
178 m_export = FALSE0;
179 cmdmacs = NIL(char)((char*)((void*)0));
180 targets = NIL(char)((char*)((void*)0));
181 Is_exec_shell = FALSE0;
182 Shell_exec_target = NIL(CELL)((CELL*)((void*)0));
183 stdout_redir = NIL(FILE)((FILE*)((void*)0));
184
185 /* Get fd for for @@-recipe silencing. */
186 if( (zerofd = open(NULLDEV"/dev/null", O_WRONLY01)) == -1 )
1
Taking false branch
187 Fatal( "Error opening %s !", NULLDEV"/dev/null" );
188
189 Verbose = V_NOFLAG0x00;
190 Measure = M_NOFLAG0x00;
191 Transitive = TRUE1;
192 Nest_level = 0;
193 Line_number = 0;
194 Suppress_temp_file = FALSE0;
195 Skip_to_eof = FALSE0;
196
197 while( --argc > 0 ) {
2
Loop condition is false. Execution continues on line 364
198 register char *p;
199 char *q;
200
201 if( *(p = *++argv) == '-' ) {
202 if( p[1] == '\0' ) Fatal("Missing option letter");
203
204 /* copy options to Buffer for $(MFLAGS), strip 'f' and 'C'*/
205 q = strchr(Buffer, '\0');
206 while (*p != '\0') {
207 char c = (*q++ = *p++);
208 if( c == 'f' || c == 'C' ) q--;
209 }
210
211 if( *(q-1) == '-' )
212 q--;
213 else
214 *q++ = ' ';
215
216 *q = '\0';
217
218 for( p = *argv+1; *p; p++) switch (*p) {
219 case 'f':
220 _do_f_flag( 'f', *++argv, &fil_name ); argc--;
221 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 _do_f_flag( 'K', *++argv, &state_name ); argc--;
232 Def_macro(".KEEP_STATE", state_name, M_EXPANDED0x0008|M_PRECIOUS0x0002);
233 break;
234
235 case 'W':
236 case 'w': {
237 CELLPTR wif;
238 _do_f_flag( 'w', *++argv, &whatif ); argc--;
239 wif = Def_cell(whatif);
240 wif->ce_attr |= A_WHATIF0x04000000;
241 whatif = NIL(char)((char*)((void*)0));
242
243 if ( *p == 'W')
244 break;
245 }
246 /*FALLTHRU*/
247
248 case 'n':
249 Trace = TRUE1;
250 break;
251
252 case 'k': Continue = TRUE1; break;
253 case 'c': Comment = TRUE1; break;
254 case 'p': Listing = TRUE1; break;
255 case 'r': Rules = FALSE0; break;
256 case 't': Touch = TRUE1; break;
257 case 'q': Check = TRUE1; break;
258 case 'u': Force = TRUE1; break;
259 case 'x': m_export = TRUE1; break;
260 case 'X': No_exec = TRUE1; break;
261 case 'T': Transitive = FALSE0; break;
262 case 'e': Get_env = 'e'; break;
263 case 'E': Get_env = 'E'; break;
264
265 case 'V': Version(); Quit(0); break;
266 case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED0x0008); break;
267 case 'B': Def_macro(".NOTABS", "y", M_EXPANDED0x0008); break;
268 case 'i': Def_macro(".IGNORE", "y", M_EXPANDED0x0008); break;
269 case 's': Def_macro(".SILENT", "y", M_EXPANDED0x0008); break;
270 case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED0x0008); break;
271 case 'g': Def_macro(".IGNOREGROUP","y", M_EXPANDED0x0008); break;
272 case 'd': Def_macro(".DIRCACHE",NIL(char)((char*)((void*)0)),M_EXPANDED0x0008); break;
273
274 case 'v':
275 if( p[-1] != '-' ) Usage(TRUE1);
276 while( p[1] ) switch( *++p ) {
277 case 'c': Verbose |= V_DIR_CACHE0x04; break;
278 case 'd': Verbose |= V_DIR_SET0x02; break;
279 case 'f': Verbose |= V_FILE_IO0x20; break;
280 case 'i': Verbose |= V_INFER0x08; break;
281 case 'm': Verbose |= V_MAKE0x10; break;
282 case 'r': Verbose |= V_FORCEECHO0x80; break;
283 case 't': Verbose |= V_LEAVE_TMP0x01; break;
284 case 'w': Verbose |= V_WARNALL0x40; break;
285
286 default: Usage(TRUE1); break;
287 }
288 if( !Verbose ) Verbose = V_ALL(0x01 | 0x02 | 0x08 | 0x10 | 0x20 | 0x04 | 0x40 | 0x80);
289 if( Verbose & V_FORCEECHO0x80 ) {
290 HASHPTR hp;
291 /* This cleans the .SILENT setting */
292 hp = Def_macro(".SILENT", "", M_EXPANDED0x0008);
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 hp->MV_MASKvar.mv_mask = A_DEFAULT0x00000;
299 }
300 break;
301
302 case 'm':
303 if( p[-1] != '-' ) Usage(TRUE1);
304 while( p[1] ) switch( *++p ) {
305 case 't': Measure |= M_TARGET0x01; break;
306 case 'r': Measure |= M_RECIPE0x02; break;
307 case 'a': Measure |= M_ABSPATH0x04; break;
308 case 'e': Measure |= M_SHELLESC0x08; break;
309
310 default: Usage(TRUE1); break;
311 }
312 if( !Measure ) Measure = M_TARGET0x01;
313 break;
314
315 case 'P':
316 if( p[1] ) {
317 /* Only set MAXPROCESS if -S flag is *not* used. */
318 if( !(Glob_attr & A_SEQ0x00200) ) {
319 Def_macro( "MAXPROCESS", p+1, M_MULTI0x0004|M_EXPANDED0x0008 );
320 }
321 p += strlen(p)-1;
322 }
323 else
324 Fatal( "Missing number for -P flag" );
325 break;
326
327#ifdef DBUG
328 case '#':
329 DB_PUSH(p+1);
330 p += strlen(p)-1;
331 break;
332#endif
333
334 case 'h': Usage(FALSE0); break;
335 case 0: break; /* lone - */
336 default: Usage(TRUE1); break;
337 }
338 }
339 else if( (q = strchr(p, '=')) != NIL(char)((char*)((void*)0)) ) {
340 cmdmacs = DmStrAdd( cmdmacs, DmStrDup2(p), TRUE1 );
341 /* Macros defined on the command line are marked precious.
342 * FIXME: The exception for += appears to be bogus. */
343 Parse_macro( p, (q[-1]!='+')?M_PRECIOUS0x0002:M_DEFAULT0x0000 );
344 }
345 else {
346 /* Remember the targets from the command line. */
347 register STRINGPTR nsp;
348
349 targets = DmStrAdd( targets, DmStrDup(p), TRUE1 );
350
351 TALLOC(nsp, 1, STRING)if ((nsp = (STRING*) calloc((unsigned int)(1), (size_t)sizeof
(STRING))) == (STRING*)0) {No_ram();}
;
352 nsp->st_string = DmStrDup( p );
353 nsp->st_next = NIL(STRING)((STRING*)((void*)0));
354
355 if(cltarget != NIL(STRING)((STRING*)((void*)0)) )
356 cltarget->st_next = nsp;
357 else
358 cltarget_first = nsp;
359
360 cltarget = nsp;
361 }
362 }
363
364 Def_macro( "MAKEMACROS", cmdmacs, M_PRECIOUS0x0002|M_NOEXPORT0x0040 );
365 Def_macro( "MAKETARGETS", targets, M_PRECIOUS0x0002|M_NOEXPORT0x0040 );
366 if( cmdmacs != NIL(char)((char*)((void*)0)) ) FREE(cmdmacs)free((char*)(cmdmacs));
3
Taking false branch
367 if( targets != NIL(char)((char*)((void*)0)) ) FREE(targets)free((char*)(targets));
4
Taking false branch
368
369 Def_macro( "MFLAGS", Buffer, M_PRECIOUS0x0002|M_NOEXPORT0x0040 );
370 Def_macro( "%", "$@", M_PRECIOUS0x0002|M_NOEXPORT0x0040 );
371
372 if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS0x0002|M_NOEXPORT0x0040 );
5
Taking false branch
373
374 _warn = FALSE0; /* disable warnings for builtin rules */
375 Target = TRUE1; /* make sure we don't mark any of the default rules as
376 * potential targets. */
377 Make_rules(); /* Parse the strings stored in Rule_tab. */
378 _warn = TRUE1;
379
380 /* If -r was not given find and parse startup-makefile. */
381 if( Rules )
6
Taking true branch
382 {
383 char *fname = NIL(char)((char*)((void*)0));
384
385 /* Search_file() also checks the environment variable. */
386 if( (mkfil=Search_file("MAKESTARTUP", &fname)) != NIL(FILE)((FILE*)((void*)0)) )
7
Taking true branch
387 {
388 Parse(mkfil);
389 Def_macro( "MAKESTARTUP", fname, M_EXPANDED0x0008|M_MULTI0x0004|M_FORCE0x0080 );
390 }
391 else
392 Fatal( "Configuration file `%s' not found", fname );
393 if ( fname != NIL(char)((char*)((void*)0))) { FREE( fname )free((char*)(fname)); fname = NIL(char)((char*)((void*)0)); }
8
Taking true branch
394 }
395
396 /* Define the targets set on the command line now. */
397 Target = FALSE0; /* Will be set to TRUE when the default targets are set. */
398 for( cltarget = cltarget_first; cltarget != NIL(STRING)((STRING*)((void*)0)); ) {
9
Loop condition is false. Execution continues on line 413
399 CELLPTR cp;
400 STRINGPTR nta = cltarget->st_next;
401
402 Add_prerequisite(Targets, cp = Def_cell(cltarget->st_string),
403 FALSE0, FALSE0);
404 cp->ce_flag |= F_TARGET0x0008;
405 cp->ce_attr |= A_FRINGE0x100000;
406 Target = TRUE1;
407
408 FREE(cltarget->st_string)free((char*)(cltarget->st_string));
409 FREE(cltarget)free((char*)(cltarget));
410 cltarget = nta;
411 }
412
413 if( Get_env == 'E' ) _do_ReadEnvironment();
10
Taking false branch
414
415 /* Search for and parse user makefile. */
416 if( fil_name != NIL(char)((char*)((void*)0)) )
11
Taking false branch
417 mkfil = Openfile( fil_name, FALSE0, TRUE1 );
418 else {
419 /* Search .MAKEFILES dependent list looking for a makefile.
420 */
421 register CELLPTR cp;
422
423 cp = Def_cell( ".MAKEFILES" );
424 mkfil = TryFiles(cp->CE_PRQce_prq);
425 }
426
427 if( mkfil != NIL(FILE)((FILE*)((void*)0)) ) {
12
Assuming 'mkfil' is equal to null
13
Taking false branch
428 char *f = Filename();
429 char *p;
430
431 if( strcmp(f, "stdin") == 0 ) f = "-";
432 Def_macro( "MAKEFILE", p = DmStrAdd( "-f", f, FALSE0 ), M_PRECIOUS0x0002|M_NOEXPORT0x0040 ); FREE(p)free((char*)(p));
433 Parse( mkfil );
434 }
435 else if( !Rules )
14
Taking false branch
436 Fatal( "No `makefile' present" );
437
438 if( Nest_level ) Fatal( "Missing .END for .IF" );
15
Taking false branch
439 if( Get_env == 'e' ) _do_ReadEnvironment();
16
Taking false branch
440
441 _do_VPATH(); /* kludge it up with .SOURCE */
17
Calling '_do_VPATH'
442
443 if( Listing ) Dump(); /* print out the structures */
444 if( Trace ) Glob_attr &= ~A_SILENT0x00002; /* make sure we see the trace */
445
446 if( !Target )
447 Fatal( "No target" );
448 else {
449 Test_circle( Root, TRUE1 );
450 Check_circle_dfa();
451 }
452
453 if( m_export ) {
454 int i;
455
456 for( i=0; i<HASH_TABLE_SIZE200; ++i ) {
457 HASHPTR hp = Macs[i];
458
459 while( hp ) {
460 if( !(hp->ht_flag & M_NOEXPORT0x0040) && hp->ht_value != NIL(char)((char*)((void*)0)) )
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;
464 }
465 }
466 }
467
468 if( Buffer != NIL(char)((char*)((void*)0)) ) {FREE( Buffer )free((char*)(Buffer)); Buffer = NIL(char)((char*)((void*)0));}
469 if( Trace ) Def_macro(".SEQUENTIAL", "y", M_EXPANDED0x0008);
470
471 ex_val = Make_targets();
472
473 Clear_signals();
474
475 /* Close fd for for @@-recipe silencing. */
476 if( close(zerofd) )
477 Fatal( "Error closing %s !", NULLDEV"/dev/null" );
478 Epilog(ex_val); /* Does not return -- EVER */
479 return 0;
480}
481
482
483static void
484_do_f_flag( flag, name, fname )
485char flag;
486char *name;
487char **fname;
488{
489 if( *fname == NIL(char)((char*)((void*)0)) ) {
490 if( name != NIL(char)((char*)((void*)0)) ) {
491 *fname = name;
492 } else
493 Fatal("No file name for -%c", flag);
494 } else
495 Fatal("Only one `-%c file' allowed", flag);
496}
497
498
499static void
500_do_ReadEnvironment()
501{
502 t_attr saveattr = Glob_attr;
503
504 Glob_attr |= A_SILENT0x00002;
505 ReadEnvironment();
506 Glob_attr = saveattr;
507}
508
509
510static void
511_do_VPATH()
512{
513 HASHPTR hp;
514 char *_rl[2];
515 extern char **Rule_tab;
516
517 hp = GET_MACRO("VPATH")Get_name("VPATH", Macs, 0);
518 if( hp == NIL(HASH)((HASH*)((void*)0)) ) return;
18
Assuming 'hp' is not equal to null
19
Taking false branch
519
520 _rl[0] = ".SOURCE :^ $(VPATH:s/:/ /)";
521 _rl[1] = NIL(char)((char*)((void*)0));
522
523 Rule_tab = _rl;
524 Parse( NIL(FILE)((FILE*)((void*)0)) );
525}
20
Address of stack memory associated with local variable '_rl' is still referred to by the global variable 'Rule_tab' upon returning to the caller. This will be a dangling reference
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
534static struct {
535 FILE *file; /* file pointer */
536 char *name; /* name of file */
537 int numb; /* line number */
538} ftab[ MAX_INC_DEPTH10 ];
539
540static 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 */
545static void
546_set_inc_depth()
547{
548 char buf[10];
549 sprintf( buf, "%d", next_file_slot );
550 Def_macro( "INCDEPTH", buf, M_MULTI0x0004|M_NOEXPORT0x0040 );
551 Def_macro( "INCFILENAME",
552 next_file_slot ? ftab[next_file_slot-1].name : "",
553 M_MULTI0x0004|M_NOEXPORT0x0040|M_EXPANDED0x0008 );
554}
555
556
557PUBLIC FILE *
558Openfile(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. */
563char *name;
564int mode;
565int err;
566{
567 FILE *fil;
568
569 DB_ENTER("Openfile");
570
571 if( name == NIL(char)((char*)((void*)0)) || !*name ) {
572 if( !err )
573 DB_RETURN(NIL(FILE))return (((FILE*)((void*)0)));
574 else
575 Fatal( "Openfile: NIL filename" );
576 }
577
578 if( next_file_slot == MAX_INC_DEPTH10 )
579 Fatal( "Too many open files. Max nesting level is %d.", MAX_INC_DEPTH10);
580
581 DB_PRINT( "io", ("Opening file [%s], in slot %d", name, next_file_slot) );
582
583 if( strcmp("-", name) == 0 ) {
584 name = "stdin";
585 fil = stdinstdin;
586 }
587 else
588 fil = fopen( name, mode ? "w":"r" );
589
590 if( Verbose & V_FILE_IO0x20 )
591 printf( "%s: Openning [%s] for %s", Pname, name, mode?"write":"read" );
592
593 if( fil == NIL(FILE)((FILE*)((void*)0)) ) {
594 if( Verbose & V_FILE_IO0x20 ) printf( " (fail)\n" );
595 if( err )
596 Fatal( mode ? "Cannot open file %s for write" : "File %s not found",
597 name );
598 }
599 else {
600 if( Verbose & V_FILE_IO0x20 ) 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();
606 }
607
608 DB_RETURN(fil)return (fil);
609}
610
611
612PUBLIC FILE *
613Closefile()/*
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 if( !next_file_slot )
622 DB_RETURN( NIL(FILE) )return (((FILE*)((void*)0)));
623
624 if( ftab[--next_file_slot].file != stdinstdin ) {
625 DB_PRINT( "io", ("Closing file in slot %d", next_file_slot) );
626
627 if( Verbose & V_FILE_IO0x20 )
628 printf( "%s: Closing [%s]\n", Pname, ftab[next_file_slot].name );
629
630 fclose( ftab[next_file_slot].file );
631 FREE( ftab[next_file_slot].name )free((char*)(ftab[next_file_slot].name));
632 }
633
634 _set_inc_depth();
635
636 if( next_file_slot > 0 ) {
637 Line_number = ftab[next_file_slot].numb;
638 DB_RETURN( ftab[next_file_slot-1].file )return (ftab[next_file_slot-1].file);
639 }
640 else
641 Line_number = 0;
642
643 DB_RETURN( NIL(FILE) )return (((FILE*)((void*)0)));
644}
645
646
647PUBLIC FILE *
648Search_file( macname, rname )
649char *macname;
650char **rname;
651{
652 HASHPTR hp;
653 FILE *fil = NIL(FILE)((FILE*)((void*)0));
654 char *fname = NIL(char)((char*)((void*)0));
655 char *ename = NIL(char)((char*)((void*)0));
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 if( (hp = GET_MACRO(macname)Get_name(macname, Macs, 0)) != NIL(HASH)((HASH*)((void*)0)) ) {
666 /* Only expand if needed. */
667 if( hp->ht_flag & M_EXPANDED0x0008 ) {
668 ename = fname = DmStrDup(hp->ht_value);
669 } else {
670 ename = fname = Expand(hp->ht_value);
671 }
672
673 if( hp->ht_flag & M_PRECIOUS0x0002 ) fil = Openfile(fname, FALSE0, FALSE0);
674 }
675
676 if( fil == NIL(FILE)((FILE*)((void*)0)) ) {
677 fname=Expand(Read_env_string(macname));
678 if( (fil = Openfile(fname, FALSE0, FALSE0)) != NIL(FILE)((FILE*)((void*)0)) ) FREE(ename)free((char*)(ename));
679 }
680
681 if( fil == NIL(FILE)((FILE*)((void*)0)) && hp != NIL(HASH)((HASH*)((void*)0)) ) {
682 if ( fname != NIL(char)((char*)((void*)0)) ) { FREE(fname)free((char*)(fname)); fname = NIL(char)((char*)((void*)0)); }
683 fil = Openfile(fname=ename, FALSE0, FALSE0);
684 }
685
686 if( rname ) *rname = fname;
687
688 return(fil);
689}
690
691
692PUBLIC char *
693Filename()/*
694============
695 Return name of file on top of stack */
696{
697 return( next_file_slot==0 ? NIL(char)((char*)((void*)0)) : ftab[next_file_slot-1].name );
698}
699
700
701PUBLIC int
702Nestlevel()/*
703=============
704 Return the file nesting level */
705{
706 return( next_file_slot );
707}
708
709
710PUBLIC FILE *
711TryFiles(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. */
716LINKPTR lp;
717{
718 FILE *mkfil = NIL(FILE)((FILE*)((void*)0));
719
720 if( lp != NIL(LINK)((LINK*)((void*)0)) ) {
721 int s_n, s_t, s_q;
722
723 s_n = Trace;
724 s_t = Touch;
725 s_q = Check;
726
727 Trace = Touch = Check = FALSE0;
728 /* We are making a makefile. Wait for it. */
729 Makemkf = Wait_for_completion = TRUE1;
730 mkfil = NIL(FILE)((FILE*)((void*)0));
731
732 for(; lp != NIL(LINK)((LINK*)((void*)0)) && mkfil == NIL(FILE)((FILE*)((void*)0)); lp=lp->cl_next) {
733 if( lp->cl_prq->ce_attr & A_FRINGE0x100000 ) continue;
734
735 mkfil = Openfile( lp->cl_prq->CE_NAMEce_name->ht_name, FALSE0, FALSE0 );
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 if( mkfil == NIL(FILE)((FILE*)((void*)0)) && Make(lp->cl_prq, NIL(CELL)((CELL*)((void*)0))) != -1 ) {
741 mkfil = Openfile( lp->cl_prq->CE_NAMEce_name->ht_name, FALSE0, FALSE0 );
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 Unmake(lp->cl_prq);
747 }
748 }
749
750 Trace = s_n;
751 Touch = s_t;
752 Check = s_q;
753 Makemkf = Wait_for_completion = FALSE0;
754 }
755
756 return(mkfil);
757}
758
759
760/*
761** print error message from variable arg list
762*/
763
764static int errflg = TRUE1;
765static int warnflg = FALSE0;
766
767static void
768errargs(fmt, args)
769char *fmt;
770va_list args;
771{
772 int warn = _warn && warnflg && !(Glob_attr & A_SILENT0x00002);
773
774 if( errflg || warn ) {
775 char *f = Filename();
776
777 fprintf( stderrstderr, "%s: ", Pname );
778 if( f != NIL(char)((char*)((void*)0)) ) fprintf(stderrstderr, "%s: line %d: ", f, Line_number);
779
780 if( errflg )
781 fprintf(stderrstderr, "Error: -- ");
782 else if( warn )
783 fprintf(stderrstderr, "Warning: -- ");
784
785 vfprintf( stderrstderr, fmt, args );
786 putc( '\n', stderr )_IO_putc ('\n', stderr);
787 if( errflg && !Continue ) Quit(0);
788 }
789}
790
791
792/*
793** Print error message and abort
794*/
795PUBLIC void
796Fatal(ARG(char *,fmt)char * fmt, ARG(va_alist_type,va_alist)...)
797DARG(char *,fmt)
798DARG(va_alist_type,va_alist)
799{
800 va_list args;
801
802 va_start(args, fmt)__builtin_va_start(args, fmt);
803 Continue = FALSE0;
804 errargs(fmt, args);
805 va_end(args);
806}
807
808/*
809** error message and exit (unless -k)
810*/
811PUBLIC void
812Error(ARG(char *,fmt)char * fmt, ARG(va_alist_type,va_alist)...)
813DARG(char *,fmt)
814DARG(va_alist_type,va_alist)
815{
816 va_list args;
817
818 va_start(args, fmt)__builtin_va_start(args, fmt);
819 errargs(fmt, args);
820 va_end(args);
821}
822
823
824/*
825** non-fatal message
826*/
827PUBLIC void
828Warning(ARG(char *,fmt)char * fmt, ARG(va_alist_type,va_alist)...)
829DARG(char *,fmt)
830DARG(va_alist_type,va_alist)
831{
832 va_list args;
833
834 va_start(args, fmt)__builtin_va_start(args, fmt);
835 warnflg = TRUE1;
836 errflg = FALSE0;
837 errargs(fmt, args);
838 errflg = TRUE1;
839 warnflg = FALSE0;
840 va_end(args);
841}
842
843
844PUBLIC void
845No_ram()
846{
847 Fatal( "No more memory" );
848}
849
850
851PUBLIC void
852Usage( eflag )
853int eflag;
854{
855 register char *p;
856 char *fill;
857
858 fill = DmStrDup(Pname);
859 for(p=fill; *p; p++) *p=' ';
860
861 if( eflag ) {
862 fprintf(stderrstderr, USAGE"Usage:\n%s [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n", Pname);
863 fprintf(stderrstderr, USAGE2"%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n", fill);
864 }
865 else {
866 printf(USAGE"Usage:\n%s [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n", Pname);
867 printf(USAGE2"%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n", fill);
868 puts(" -P# - set max number of child processes for parallel make");
869 puts(" -f file - use file as the makefile");
870#ifdef MSDOS
871 puts(" -C [+]file - duplicate console output to file, ('+' => append)");
872#endif
873 puts(" -K file - use file as the .KEEP_STATE file");
874 puts(" -w target - show what you would do if 'target' were out of date");
875 puts(" -W target - rebuild pretending that 'target' is out of date");
876 puts(" -v[cdfimrtw] - verbose, indicate what we are doing, (-v => -vcdfimrtw)");
877 puts(" c => dump directory cache info only" );
878 puts(" d => dump change of directory info only" );
879 puts(" f => dump file open/close info only" );
880 puts(" i => dump inference information only" );
881 puts(" m => dump make of target information only" );
882 puts(" r => Force output of recipe lines and warnings," );
883 puts(" overrides -s" );
884 puts(" t => keep temporary files when done" );
885 puts(" w => issue non-essential warnings\n" );
886
887 puts(" -m[trae] - Measure timing information, (-m => -mt)");
888 puts(" t => display the start and end time of each target" );
889 puts(" r => display the start and end time of each recipe" );
890 puts(" a => display the target as an absolute path" );
891 puts(" e => display the timing of shell escape macros\n" );
892
893 puts("Options: (can be catenated, ie -irn == -i -r -n)");
894 puts(" -A - enable AUGMAKE special target mapping");
895 puts(" -B - enable the use of spaces instead of tabs to start recipes");
896 puts(" -c - use non standard comment scanning");
897 puts(" -d - do not use directory cache");
898 puts(" -E - define environment strings as macros");
899 puts(" -e - same as -E but done after parsing makefile");
900 puts(" -g - disable the special meaning of [ ... ] for group recipes");
901 puts(" -h - print out usage info");
902 puts(" -i - ignore errors");
903 puts(" -k - make independent targets, even if errors");
904 puts(" -n - trace and print, do not execute commands");
905 puts(" -p - print out a version of the makefile");
906 puts(" -q - check if target is up to date. Does not do");
907 puts(" anything. Returns 0 if up to date, 1 otherwise");
908 puts(" -r - don't use internal rules");
909 puts(" -s - do your work silently");
910 puts(" -S - disable parallel (force sequential) make, overrides -P");
911 puts(" -t - touch, update time stamps without executing commands");
912 puts(" -T - do not apply transitive closure on inference rules");
913 puts(" -u - force unconditional update of target");
914 puts(" -V - print out version number");
915 puts(" -x - export macro values to environment");
916 puts(" -X - ignore #! lines at start of makefile");
917 }
918 FREE(fill)free((char*)(fill));
919
920 Quit(0);
921}
922
923
924PUBLIC void
925Version()
926{
927 extern char **Rule_tab;
928 char **p;
929
930 printf("%s - Version %s (%s)\n", Pname, VERSION"4.12", BUILDINFO"i686-pc-linux-gnu");
931 printf("%s\n\n", sccid);
932
933 puts("Default Configuration:");
934 for (p=Rule_tab; *p != NIL(char)((char*)((void*)0)); p++)
935 printf("\t%s\n", *p);
936
937 printf("\n");
938
939#if defined(HAVE_SPAWN_H1) || 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 printf("Subprocesses are executed using: fork/exec.\n\n");
946#endif
947#endif
948
949 printf("Please read the NEWS file for the latest release notes.\n");
950}