remove SYSV and is68k ifdef's
[unix-history] / usr / src / usr.bin / make / main.c
CommitLineData
9320ab9e
KB
1/*
2 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
3 * Copyright (c) 1988, 1989 by Adam de Boor
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.
9 *
10 * Redistribution and use in source and binary forms are permitted
11 * provided that the above copyright notice and this paragraph are
12 * duplicated in all such forms and that any documentation,
13 * advertising materials, and other materials related to such
14 * distribution and use acknowledge that the software was developed
15 * by the University of California, Berkeley. The name of the
16 * University may not be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23#ifndef lint
24char copyright[] =
25"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
26 All rights reserved.\n";
27#endif /* not lint */
28
29#ifndef lint
f0544510 30static char sccsid[] = "@(#)main.c 5.6 (Berkeley) %G%";
9320ab9e
KB
31#endif /* not lint */
32
ab950546
KB
33/*-
34 * main.c --
35 * The main file for this entire program. Exit routines etc
36 * reside here.
37 *
ab950546
KB
38 * Utility functions defined in this file:
39 * Main_ParseArgLine Takes a line of arguments, breaks them and
40 * treats them as if they were given when first
41 * invoked. Used by the parse module to implement
42 * the .MFLAGS target.
43 *
44 * Error Print a tagged error message. The global
45 * MAKE variable must have been defined. This
46 * takes a format string and two optional
47 * arguments for it.
48 *
49 * Fatal Print an error message and exit. Also takes
50 * a format string and two arguments.
51 *
52 * Punt Aborts all jobs and exits with a message. Also
53 * takes a format string and two arguments.
54 *
55 * Finish Finish things up by printing the number of
56 * errors which occured, as passed to it, and
57 * exiting.
58 */
ab950546 59
ab950546
KB
60#include <sys/types.h>
61#include <sys/signal.h>
62#include <sys/stat.h>
ab950546 63#include <sys/errno.h>
fb622282 64#include <fcntl.h>
ab950546 65#include <ctype.h>
fb622282 66#include <stdio.h>
ab950546
KB
67#include "make.h"
68
69extern int errno;
70
71
72#ifndef DEFMAXLOCAL
73#define DEFMAXLOCAL DEFMAXJOBS
74#endif DEFMAXLOCAL
75
76#define MAKEFLAGS ".MAKEFLAGS"
77
78static char *progName; /* Our invocation name */
ab950546
KB
79Lst create; /* Targets to be made */
80time_t now; /* Time at start of make */
81GNode *DEFAULT; /* .DEFAULT node */
82Boolean allPrecious; /* .PRECIOUS given on line by itself */
83
84static int printGraph; /* -p flag */
85static Boolean noBuiltins; /* -r flag */
ab950546
KB
86static Lst makefiles; /* List of makefiles to read (in
87 * order) */
88int maxJobs; /* -J argument */
89static int maxLocal; /* -L argument */
90Boolean debug; /* -d flag */
91Boolean amMake; /* -M flag */
92Boolean noWarnings; /* -W flag */
93Boolean noExecute; /* -n flag */
94Boolean keepgoing; /* -k flag */
95Boolean queryFlag; /* -q flag */
96Boolean touchFlag; /* -t flag */
97Boolean usePipes; /* !-P flag */
98Boolean backwards; /* -B flag */
99Boolean ignoreErrors; /* -i flag */
100Boolean beSilent; /* -s flag */
101Boolean sysVmake; /* -v flag */
102Boolean oldVars; /* -V flag */
103Boolean checkEnvFirst; /* -e flag */
104static Boolean XFlag=FALSE; /* -X flag given */
105static Boolean xFlag=FALSE; /* -x flag given */
106Boolean noExport; /* Set TRUE if shouldn't export */
107static Boolean jobsRunning; /* TRUE if the jobs might be running */
108
109static Boolean ReadMakefile();
110
111/*
112 * Initial value for optind when parsing args. Different getopts start it
113 * differently...
114 */
115static int initOptInd;
116
117#ifdef CAN_EXPORT
aa5839c2 118#define OPTSTR "BCD:I:J:L:MPSVWXd:ef:iknp:qrstvxh"
ab950546 119#else
aa5839c2 120#define OPTSTR "BCD:I:J:L:MPSVWd:ef:iknp:qrstvh"
ab950546
KB
121#endif
122
123static char *help[] = {
124"-B Be as backwards-compatible with make as possible without\n\
125 being make.",
126"-C Cancel any current indications of compatibility.",
127"-D<var> Define the variable <var> with value 1.",
128"-I<dir> Specify another directory in which to search for included\n\
129 makefiles.",
130"-J<num> Specify maximum overall concurrency.",
131"-L<num> Specify maximum local concurrency.",
132"-M Be Make as closely as possible.",
133"-P Don't use pipes to catch the output of jobs, use files.",
134"-S Turn off the -k flag (see below).",
135#ifndef POSIX
136"-V Use old-style variable substitution.",
137#endif
138"-W Don't print warning messages.",
139#ifdef CAN_EXPORT
140"-X Turn off exporting of commands.",
141#endif
142"-d<flags> Turn on debugging output.",
143"-e Give environment variables precedence over those in the\n\
144 makefile(s).",
145"-f<file> Specify a(nother) makefile to read",
146"-i Ignore errors from executed commands.",
147"-k On error, continue working on targets that do not depend on\n\
148 the one for which an error was detected.",
ab950546
KB
149"-n Don't execute commands, just print them.",
150"-p<num> Tell when to print the input graph: 1 (before processing),\n\
151 2 (after processing), or 3 (both).",
152"-q See if anything needs to be done. Exits 1 if so.",
153"-r Do not read the system makefile for pre-defined rules.",
154"-s Don't print commands as they are executed.",
155"-t Update targets by \"touching\" them (see touch(1)).",
aa5839c2 156"-v Be compatible with System V make. Implies -B, -V.",
ab950546
KB
157#ifdef CAN_EXPORT
158"-x Allow exportation of commands.",
159#endif
ab950546
KB
160};
161
162
163/*-
164 *----------------------------------------------------------------------
165 * MainParseArgs --
166 * Parse a given argument vector. Called from main() and from
167 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
168 *
169 * XXX: Deal with command line overriding .MAKEFLAGS in makefile
170 *
171 * Results:
172 * None
173 *
174 * Side Effects:
175 * Various global and local flags will be set depending on the flags
176 * given
177 *----------------------------------------------------------------------
178 */
179static void
180MainParseArgs (argc, argv)
181 int argc; /* Number of arguments in argv */
182 char **argv; /* The arguments themselves */
183{
184 register int i;
185 register char *cp;
186 extern int optind;
187 extern char *optarg;
188 char c;
189
190 optind = initOptInd;
191
192 while((c = getopt(argc, argv, OPTSTR)) != -1) {
193 switch(c) {
194 case 'B':
195 backwards = oldVars = TRUE;
196 Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
197 break;
198 case 'C':
199 oldVars = backwards = sysVmake = amMake = FALSE;
200 Var_Append(MAKEFLAGS, "-C", VAR_GLOBAL);
201 break;
202 case 'D':
203 Var_Set(optarg, "1", VAR_GLOBAL);
204 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
205 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
206 break;
207 case 'I':
208 Parse_AddIncludeDir(optarg);
209 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
210 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
211 break;
212 case 'J':
213 maxJobs = atoi(optarg);
214 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
215 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
216 break;
217 case 'L':
218 maxLocal = atoi(optarg);
219 Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
220 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
221 break;
222 case 'M':
223 amMake = TRUE;
224 Var_Append(MAKEFLAGS, "-M", VAR_GLOBAL);
225 break;
226 case 'P':
227 usePipes = FALSE;
228 Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
229 break;
230 case 'S':
231 keepgoing = FALSE;
232 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
233 break;
234 case 'V':
235 oldVars = TRUE;
236 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
237 break;
238 case 'W':
239 noWarnings = TRUE;
240 Var_Append(MAKEFLAGS, "-W", VAR_GLOBAL);
241 break;
242 case 'X':
243 XFlag = TRUE;
244 Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
245 break;
246 case 'd':
247 {
248 char *modules = optarg;
249
250 while (*modules) {
251 switch (*modules) {
252 case 's':
253 debug |= DEBUG_SUFF;
254 break;
255 case 'm':
256 debug |= DEBUG_MAKE;
257 break;
258 case 'j':
259 debug |= DEBUG_JOB;
260 break;
261 case 't':
262 debug |= DEBUG_TARG;
263 break;
264 case 'd':
265 debug |= DEBUG_DIR;
266 break;
267 case 'v':
268 debug |= DEBUG_VAR;
269 break;
270 case 'c':
271 debug |= DEBUG_COND;
272 break;
273 case 'p':
274 debug |= DEBUG_PARSE;
275 break;
276 case 'r':
277 debug |= DEBUG_RMT;
278 break;
279 case 'a':
280 debug |= DEBUG_ARCH;
281 break;
282 case '*':
283 debug = ~0;
284 break;
285 }
286 modules++;
287 }
288 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
289 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
290 break;
291 }
292 case 'e':
293 checkEnvFirst = TRUE;
294 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
295 break;
296 case 'f':
297 (void)Lst_AtEnd(makefiles, (ClientData)optarg);
298 break;
299 case 'i':
300 ignoreErrors = TRUE;
301 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
302 break;
303 case 'k':
304 keepgoing = TRUE;
305 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
306 break;
ab950546
KB
307 case 'n':
308 noExecute = TRUE;
309 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
310 break;
311 case 'p':
312 printGraph = atoi(optarg);
313 break;
314 case 'q':
315 queryFlag = TRUE;
316 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); /* Kind of
317 * nonsensical, wot?
318 */
319 break;
320 case 'r':
321 noBuiltins = TRUE;
322 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
323 break;
324 case 's':
325 beSilent = TRUE;
326 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
327 break;
328 case 't':
329 touchFlag = TRUE;
330 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
331 break;
332 case 'v':
aa5839c2 333 sysVmake = oldVars = backwards = TRUE;
ab950546
KB
334 Var_Append(MAKEFLAGS, "-v", VAR_GLOBAL);
335 break;
336 case 'h':
337 case '?':
338 {
339 int i;
340
341 for (i = 0; i < sizeof(help)/sizeof(help[0]); i++) {
342 printf("%s\n", help[i]);
343 }
344 exit(c == '?' ? -1 : 0);
345 }
346 }
347 }
348
349 /*
350 * Take care of encompassing compatibility levels...
351 */
352 if (amMake) {
353 backwards = TRUE;
354 }
355 if (backwards) {
356 oldVars = TRUE;
357 }
358
359 /*
360 * See if the rest of the arguments are variable assignments and perform
361 * them if so. Else take them to be targets and stuff them on the end
362 * of the "create" list.
363 */
364 for (i = optind; i < argc; i++) {
365 if (Parse_IsVar (argv[i])) {
366 Parse_DoVar(argv[i], VAR_CMD);
367 } else {
368 if (argv[i][0] == 0) {
369 Punt("Bogus argument in MainParseArgs");
370 }
371 (void)Lst_AtEnd (create, (ClientData)argv[i]);
372 }
373 }
374}
aa5839c2 375
ab950546
KB
376/*-
377 *----------------------------------------------------------------------
378 * Main_ParseArgLine --
379 * Used by the parse module when a .MFLAGS or .MAKEFLAGS target
380 * is encountered and by main() when reading the .MAKEFLAGS envariable.
381 * Takes a line of arguments and breaks it into its
382 * component words and passes those words and the number of them to the
383 * MainParseArgs function.
384 * The line should have all its leading whitespace removed.
385 *
386 * Results:
387 * None
388 *
389 * Side Effects:
390 * Only those that come from the various arguments.
391 *-----------------------------------------------------------------------
392 */
393void
394Main_ParseArgLine (line)
395 char *line; /* Line to fracture */
396{
397 char **argv; /* Manufactured argument vector */
398 int argc; /* Number of arguments in argv */
399
400 if (line == NULL) return;
401 while (*line == ' ') line++;
402
403 argv = Str_BreakString (line, " \t", "\n", &argc);
404
405 MainParseArgs(argc, argv);
406
407 Str_FreeVec(argc, argv);
408}
aa5839c2 409
ab950546
KB
410/*-
411 *----------------------------------------------------------------------
412 * main --
413 * The main function, for obvious reasons. Initializes variables
414 * and a few modules, then parses the arguments give it in the
415 * environment and on the command line. Reads the system makefile
416 * followed by either Makefile, makefile or the file given by the
417 * -f argument. Sets the .MAKEFLAGS PMake variable based on all the
418 * flags it has received by then uses either the Make or the Compat
419 * module to create the initial list of targets.
420 *
421 * Results:
422 * If -q was given, exits -1 if anything was out-of-date. Else it exits
423 * 0.
424 *
425 * Side Effects:
426 * The program exits when done. Targets are created. etc. etc. etc.
427 *
428 *----------------------------------------------------------------------
429 */
430main (argc, argv)
431 int argc;
432 char **argv;
433{
434 Lst targs; /* list of target nodes to create. Passed to
435 * Make_Init */
436 Boolean outOfDate; /* FALSE if all targets up to date */
437 char *cp;
438 extern int optind;
439
440
441 create = Lst_Init (FALSE);
442 makefiles = Lst_Init(FALSE);
443
444 beSilent = FALSE; /* Print commands as executed */
445 ignoreErrors = FALSE; /* Pay attention to non-zero returns */
446 noExecute = FALSE; /* Execute all commands */
447 keepgoing = FALSE; /* Stop on error */
448 allPrecious = FALSE; /* Remove targets when interrupted */
449 queryFlag = FALSE; /* This is not just a check-run */
450 noBuiltins = FALSE; /* Read the built-in rules */
451 touchFlag = FALSE; /* Actually update targets */
452 usePipes = TRUE; /* Catch child output in pipes */
ab950546
KB
453 debug = 0; /* No debug verbosity, please. */
454 noWarnings = FALSE; /* Print warning messages */
455 sysVmake = FALSE; /* Don't be System V compatible */
456
457 jobsRunning = FALSE;
458
459 maxJobs = DEFMAXJOBS; /* Set the default maximum concurrency */
460 maxLocal = DEFMAXLOCAL; /* Set the default local max concurrency */
461
462 /*
463 * Deal with disagreement between different getopt's as to what
464 * the initial value of optind should be by simply saving the
465 * damn thing.
466 */
467 initOptInd = optind;
468
469 /*
470 * See what the user calls us. If s/he calls us (yuck) "make", then
471 * act like it. Otherwise act like our normal, cheerful self.
472 */
473 cp = rindex (argv[0], '/');
474 if (cp != (char *)NULL) {
475 cp += 1;
476 } else {
477 cp = argv[0];
478 }
479 progName = cp;
480
481 if (strcmp (cp, "make") == 0) {
482 amMake = TRUE; /* Be like make */
483 backwards = TRUE; /* Do things the old-fashioned way */
484 oldVars = TRUE; /* Same with variables */
485 } else if (strcmp(cp, "smake") == 0 || strcmp(cp, "vmake") == 0) {
aa5839c2 486 sysVmake = oldVars = backwards = TRUE;
ab950546
KB
487 } else {
488 amMake = FALSE;
489 backwards = FALSE; /* Do things MY way, not MAKE's */
490#ifdef DEF_OLD_VARS
491 oldVars = TRUE;
492#else
493 oldVars = FALSE; /* don't substitute for undefined variables */
494#endif
495 }
496
497 /*
498 * Initialize the parsing, directory and variable modules to prepare
499 * for the reading of inclusion paths and variable settings on the
500 * command line
501 */
502 Dir_Init (); /* Initialize directory structures so -I flags
503 * can be processed correctly */
504 Parse_Init (); /* Need to initialize the paths of #include
505 * directories */
506 Var_Init (); /* As well as the lists of variables for
507 * parsing arguments */
508
509 /*
510 * Initialize various variables.
511 * .PMAKE gets how we were executed.
512 * MAKE also gets this name, for compatibility
513 * .MAKEFLAGS gets set to the empty string just in case.
514 * MFLAGS also gets initialized empty, for compatibility.
515 */
516 Var_Set (".PMAKE", argv[0], VAR_GLOBAL);
517 Var_Set ("MAKE", argv[0], VAR_GLOBAL);
518 Var_Set (MAKEFLAGS, "", VAR_GLOBAL);
519 Var_Set ("MFLAGS", "", VAR_GLOBAL);
520
521 /*
522 * First snag any flags out of the PMAKE environment variable.
523 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's in
524 * a different format).
525 */
526#ifdef POSIX
527 Main_ParseArgLine(getenv("MAKEFLAGS"));
528#else
529 Main_ParseArgLine (getenv("PMAKE"));
530#endif
531
532 MainParseArgs (argc, argv);
533
ab950546
KB
534 /*
535 * Initialize archive, target and suffix modules in preparation for
536 * parsing the makefile(s)
537 */
538 Arch_Init ();
539 Targ_Init ();
540 Suff_Init ();
541
542 DEFAULT = NILGNODE;
543
544 now = time(0);
545
546 /*
547 * Set up the .TARGETS variable to contain the list of targets to be
548 * created. If none specified, make the variable empty -- the parser
549 * will fill the thing in with the default or .MAIN target.
550 */
551 if (!Lst_IsEmpty(create)) {
552 LstNode ln;
553
554 for (ln = Lst_First(create); ln != NILLNODE; ln = Lst_Succ(ln)) {
555 char *name = (char *)Lst_Datum(ln);
556
557 Var_Append(".TARGETS", name, VAR_GLOBAL);
558 }
559 } else {
560 Var_Set(".TARGETS", "", VAR_GLOBAL);
561 }
562
563 /*
564 * Read in the built-in rules first, followed by the specified makefile,
565 * if it was (makefile != (char *) NULL), or the default Makefile and
566 * makefile, in that order, if it wasn't.
567 */
568 if (!noBuiltins && !ReadMakefile (DEFSYSMK)) {
569 Fatal ("Could not open system rules (%s)", DEFSYSMK);
570 }
571
572 if (!Lst_IsEmpty(makefiles)) {
573 LstNode ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
574
575 if (ln != NILLNODE) {
576 Fatal ("Cannot open %s", (char *)Lst_Datum(ln));
577 }
578 } else {
579#ifdef POSIX
580 if (!ReadMakefile("makefile")) {
581 (void)ReadMakefile("Makefile");
582 }
583#else
584 if (!ReadMakefile ((amMake || sysVmake) ? "makefile" : "Makefile")) {
585 (void) ReadMakefile ((amMake||sysVmake) ? "Makefile" : "makefile");
586 }
587#endif
588 }
589
590 /*
591 * Figure "noExport" out based on the current mode. Since exporting each
592 * command in make mode is rather inefficient, we only export if the -x
593 * flag was given. In regular mode though, we only refuse to export if
594 * -X was given. In case the operative flag was given in the environment,
595 * however, the opposite one may be given on the command line and cancel
596 * the action.
597 */
598 if (amMake) {
599 noExport = !xFlag || XFlag;
600 } else {
601 noExport = XFlag && !xFlag;
602 }
603
604 Var_Append ("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
605
606 /*
607 * Install all the flags into the PMAKE envariable.
608 */
609#ifdef POSIX
610 setenv("MAKEFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL));
611#else
612 setenv("PMAKE", Var_Value(MAKEFLAGS, VAR_GLOBAL));
613#endif
614
615 /*
616 * For compatibility, look at the directories in the VPATH variable
617 * and add them to the search path, if the variable is defined. The
618 * variable's value is in the same format as the PATH envariable, i.e.
619 * <directory>:<directory>:<directory>...
620 */
621 if (Var_Exists ("VPATH", VAR_CMD)) {
622 char *vpath;
623 char *path;
624 char *cp;
625 char savec;
626 static char VPATH[] = "${VPATH}"; /* GCC stores string constants in
627 * read-only memory, but Var_Subst
628 * will want to write this thing,
629 * so store it in an array */
630
631 vpath = Var_Subst (VPATH, VAR_CMD, FALSE);
632
633 path = vpath;
634 do {
635 /*
636 * Skip to end of directory
637 */
638 for (cp = path; *cp != ':' && *cp != '\0'; cp++) {
639 continue;
640 }
641 /*
642 * Save terminator character to figure out when to stop
643 */
644 savec = *cp;
645 *cp = '\0';
646 /*
647 * Add directory to search path
648 */
649 Dir_AddDir (dirSearchPath, path);
650 *cp = savec;
651 path = cp + 1;
652 } while (savec == ':');
653 free((Address)vpath);
654 }
655
656 /*
657 * Now that all search paths have been read for suffixes et al, it's
658 * time to add the default search path to their lists...
659 */
660 Suff_DoPaths();
661
662 /*
663 * Print the initial graph, if the user requested it
664 */
665 if (printGraph & 1) {
666 Targ_PrintGraph (1);
667 }
668
669 Rmt_Init();
670
671 /*
672 * Have now read the entire graph and need to make a list of targets to
673 * create. If none was given on the command line, we consult the parsing
674 * module to find the main target(s) to create.
675 */
676 if (Lst_IsEmpty (create)) {
677 targs = Parse_MainName ();
678 } else {
679 targs = Targ_FindList (create, TARG_CREATE);
680 }
681
682 if (!amMake) {
683 /*
684 * Initialize job module before traversing the graph, now that any
685 * .BEGIN and .END targets have been read. This is done only if the
686 * -q flag wasn't given (to prevent the .BEGIN from being executed
687 * should it exist).
688 */
689 if (!queryFlag) {
690 if (maxLocal == -1) {
691 maxLocal = maxJobs;
692 }
693 Job_Init (maxJobs, maxLocal);
694 jobsRunning = TRUE;
695 }
696
697 /*
698 * Traverse the graph, checking on all the targets
699 */
700 outOfDate = Make_Run (targs);
701 } else {
702 /*
703 * Compat_Init will take care of creating all the targets as well
704 * as initializing the module.
705 */
706 Compat_Run(targs);
707 }
708
709 /*
710 * Print the graph now it's been processed if the user requested it
711 */
712 if (printGraph & 2) {
713 Targ_PrintGraph (2);
714 }
715
716 if (queryFlag && outOfDate) {
717 exit (1);
718 } else {
719 exit (0);
720 }
721}
aa5839c2 722
ab950546
KB
723/*-
724 *-----------------------------------------------------------------------
725 * ReadMakefile --
726 * Open and parse the given makefile.
727 *
728 * Results:
729 * TRUE if ok. FALSE if couldn't open file.
730 *
731 * Side Effects:
732 * lots
733 *-----------------------------------------------------------------------
734 */
735static Boolean
736ReadMakefile (fname)
737 char *fname; /* makefile to read */
738{
739 if (strcmp (fname, "-") == 0) {
740 Parse_File ("(stdin)", stdin);
741 Var_Set("MAKEFILE", "", VAR_GLOBAL);
742 return (TRUE);
743 } else {
744 FILE * stream;
745 extern Lst parseIncPath, sysIncPath;
746
747 stream = fopen (fname, "r");
748
749 if (stream == (FILE *) NULL) {
750 /*
751 * Look in -I directories...
752 */
753 char *name = Dir_FindFile(fname, parseIncPath);
754
755 if (name == NULL) {
756 /*
757 * Last-ditch: look in system include directories.
758 */
759 name = Dir_FindFile(fname, sysIncPath);
760 if (name == NULL) {
761 return (FALSE);
762 }
763 }
764 stream = fopen(name, "r");
765 if (stream == (FILE *)NULL) {
766 /* Better safe than sorry... */
767 return(FALSE);
768 }
769 fname = name;
770 }
771 /*
772 * Set the MAKEFILE variable desired by System V fans -- the placement
773 * of the setting here means it gets set to the last makefile
774 * specified, as it is set by SysV make...
775 */
776 Var_Set("MAKEFILE", fname, VAR_GLOBAL);
777 Parse_File (fname, stream);
778 fclose (stream);
779 return (TRUE);
780 }
781}
aa5839c2 782
ab950546
KB
783/*-
784 *-----------------------------------------------------------------------
785 * Error --
786 * Print an error message given its format and 0, 1, 2 or 3 arguments.
787 *
788 * Results:
789 * None.
790 *
791 * Side Effects:
792 * The message is printed.
793 *
794 *-----------------------------------------------------------------------
795 */
796/*VARARGS1*/
797void
798Error (fmt, arg1, arg2, arg3)
799 char *fmt; /* Format string */
800 int arg1, /* First optional argument */
801 arg2, /* Second optional argument */
802 arg3; /* Third optional argument */
803{
804 static char estr[BSIZE]; /* output string */
805
806 sprintf (estr, "%s: ", Var_Value(".PMAKE", VAR_GLOBAL));
807 sprintf (&estr[strlen (estr)], fmt, arg1, arg2, arg3);
808 (void) strcat (estr, "\n");
809
810 fputs (estr, stderr);
811 fflush (stderr);
812}
aa5839c2 813
ab950546
KB
814/*-
815 *-----------------------------------------------------------------------
816 * Fatal --
817 * Produce a Fatal error message. If jobs are running, waits for them
818 * to finish.
819 *
820 * Results:
821 * None
822 *
823 * Side Effects:
824 * The program exits
825 *-----------------------------------------------------------------------
826 */
827/* VARARGS1 */
828void
829Fatal (fmt, arg1, arg2)
830 char *fmt; /* format string */
831 int arg1; /* first optional argument */
832 int arg2; /* second optional argument */
833{
834 if (jobsRunning) {
835 Job_Wait();
836 }
837
838 Error (fmt, arg1, arg2);
839
840 if (printGraph & 2) {
841 Targ_PrintGraph(2);
842 }
843 exit (2); /* Not 1 so -q can distinguish error */
844}
aa5839c2 845
ab950546
KB
846/*
847 *-----------------------------------------------------------------------
848 * Punt --
849 * Major exception once jobs are being created. Kills all jobs, prints
850 * a message and exits.
851 *
852 * Results:
853 * None
854 *
855 * Side Effects:
856 * All children are killed indiscriminately and the program Lib_Exits
857 *-----------------------------------------------------------------------
858 */
859/* VARARGS1 */
860void
861Punt (fmt, arg1, arg2)
862 char *fmt; /* format string */
863 int arg1; /* optional argument */
864 int arg2; /* optional second argument */
865{
866 Error (fmt, arg1, arg2);
867
868 DieHorribly();
869}
aa5839c2 870
ab950546
KB
871/*-
872 *-----------------------------------------------------------------------
873 * DieHorribly --
874 * Exit without giving a message.
875 *
876 * Results:
877 * None
878 *
879 * Side Effects:
880 * A big one...
881 *-----------------------------------------------------------------------
882 */
883void
884DieHorribly()
885{
886 if (jobsRunning) {
887 Job_AbortAll ();
888 }
889 if (printGraph & 2) {
890 Targ_PrintGraph(2);
891 }
892
893 exit (2); /* Not 1, so -q can distinguish error */
894}
aa5839c2 895
ab950546
KB
896/*
897 *-----------------------------------------------------------------------
898 * Finish --
899 * Called when aborting due to errors in child shell to signal
900 * abnormal exit.
901 *
902 * Results:
903 * None
904 *
905 * Side Effects:
906 * The program exits
907 * -----------------------------------------------------------------------
908 */
909void
910Finish (errors)
911 int errors; /* number of errors encountered in Make_Make */
912{
913 Fatal ("%d error%s", errors, errors == 1 ? "" : "s");
914}