wire in DEF_OLD_VARS, still needs more work (oldVars variable)
[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
43563d42 30static char sccsid[] = "@(#)main.c 5.7 (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 */
ab950546 490 oldVars = TRUE;
ab950546
KB
491 }
492
493 /*
494 * Initialize the parsing, directory and variable modules to prepare
495 * for the reading of inclusion paths and variable settings on the
496 * command line
497 */
498 Dir_Init (); /* Initialize directory structures so -I flags
499 * can be processed correctly */
500 Parse_Init (); /* Need to initialize the paths of #include
501 * directories */
502 Var_Init (); /* As well as the lists of variables for
503 * parsing arguments */
504
505 /*
506 * Initialize various variables.
507 * .PMAKE gets how we were executed.
508 * MAKE also gets this name, for compatibility
509 * .MAKEFLAGS gets set to the empty string just in case.
510 * MFLAGS also gets initialized empty, for compatibility.
511 */
512 Var_Set (".PMAKE", argv[0], VAR_GLOBAL);
513 Var_Set ("MAKE", argv[0], VAR_GLOBAL);
514 Var_Set (MAKEFLAGS, "", VAR_GLOBAL);
515 Var_Set ("MFLAGS", "", VAR_GLOBAL);
516
517 /*
518 * First snag any flags out of the PMAKE environment variable.
519 * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's in
520 * a different format).
521 */
522#ifdef POSIX
523 Main_ParseArgLine(getenv("MAKEFLAGS"));
524#else
525 Main_ParseArgLine (getenv("PMAKE"));
526#endif
527
528 MainParseArgs (argc, argv);
529
ab950546
KB
530 /*
531 * Initialize archive, target and suffix modules in preparation for
532 * parsing the makefile(s)
533 */
534 Arch_Init ();
535 Targ_Init ();
536 Suff_Init ();
537
538 DEFAULT = NILGNODE;
539
540 now = time(0);
541
542 /*
543 * Set up the .TARGETS variable to contain the list of targets to be
544 * created. If none specified, make the variable empty -- the parser
545 * will fill the thing in with the default or .MAIN target.
546 */
547 if (!Lst_IsEmpty(create)) {
548 LstNode ln;
549
550 for (ln = Lst_First(create); ln != NILLNODE; ln = Lst_Succ(ln)) {
551 char *name = (char *)Lst_Datum(ln);
552
553 Var_Append(".TARGETS", name, VAR_GLOBAL);
554 }
555 } else {
556 Var_Set(".TARGETS", "", VAR_GLOBAL);
557 }
558
559 /*
560 * Read in the built-in rules first, followed by the specified makefile,
561 * if it was (makefile != (char *) NULL), or the default Makefile and
562 * makefile, in that order, if it wasn't.
563 */
564 if (!noBuiltins && !ReadMakefile (DEFSYSMK)) {
565 Fatal ("Could not open system rules (%s)", DEFSYSMK);
566 }
567
568 if (!Lst_IsEmpty(makefiles)) {
569 LstNode ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
570
571 if (ln != NILLNODE) {
572 Fatal ("Cannot open %s", (char *)Lst_Datum(ln));
573 }
574 } else {
575#ifdef POSIX
576 if (!ReadMakefile("makefile")) {
577 (void)ReadMakefile("Makefile");
578 }
579#else
580 if (!ReadMakefile ((amMake || sysVmake) ? "makefile" : "Makefile")) {
581 (void) ReadMakefile ((amMake||sysVmake) ? "Makefile" : "makefile");
582 }
583#endif
584 }
585
586 /*
587 * Figure "noExport" out based on the current mode. Since exporting each
588 * command in make mode is rather inefficient, we only export if the -x
589 * flag was given. In regular mode though, we only refuse to export if
590 * -X was given. In case the operative flag was given in the environment,
591 * however, the opposite one may be given on the command line and cancel
592 * the action.
593 */
594 if (amMake) {
595 noExport = !xFlag || XFlag;
596 } else {
597 noExport = XFlag && !xFlag;
598 }
599
600 Var_Append ("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL), VAR_GLOBAL);
601
602 /*
603 * Install all the flags into the PMAKE envariable.
604 */
605#ifdef POSIX
606 setenv("MAKEFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL));
607#else
608 setenv("PMAKE", Var_Value(MAKEFLAGS, VAR_GLOBAL));
609#endif
610
611 /*
612 * For compatibility, look at the directories in the VPATH variable
613 * and add them to the search path, if the variable is defined. The
614 * variable's value is in the same format as the PATH envariable, i.e.
615 * <directory>:<directory>:<directory>...
616 */
617 if (Var_Exists ("VPATH", VAR_CMD)) {
618 char *vpath;
619 char *path;
620 char *cp;
621 char savec;
622 static char VPATH[] = "${VPATH}"; /* GCC stores string constants in
623 * read-only memory, but Var_Subst
624 * will want to write this thing,
625 * so store it in an array */
626
627 vpath = Var_Subst (VPATH, VAR_CMD, FALSE);
628
629 path = vpath;
630 do {
631 /*
632 * Skip to end of directory
633 */
634 for (cp = path; *cp != ':' && *cp != '\0'; cp++) {
635 continue;
636 }
637 /*
638 * Save terminator character to figure out when to stop
639 */
640 savec = *cp;
641 *cp = '\0';
642 /*
643 * Add directory to search path
644 */
645 Dir_AddDir (dirSearchPath, path);
646 *cp = savec;
647 path = cp + 1;
648 } while (savec == ':');
649 free((Address)vpath);
650 }
651
652 /*
653 * Now that all search paths have been read for suffixes et al, it's
654 * time to add the default search path to their lists...
655 */
656 Suff_DoPaths();
657
658 /*
659 * Print the initial graph, if the user requested it
660 */
661 if (printGraph & 1) {
662 Targ_PrintGraph (1);
663 }
664
665 Rmt_Init();
666
667 /*
668 * Have now read the entire graph and need to make a list of targets to
669 * create. If none was given on the command line, we consult the parsing
670 * module to find the main target(s) to create.
671 */
672 if (Lst_IsEmpty (create)) {
673 targs = Parse_MainName ();
674 } else {
675 targs = Targ_FindList (create, TARG_CREATE);
676 }
677
678 if (!amMake) {
679 /*
680 * Initialize job module before traversing the graph, now that any
681 * .BEGIN and .END targets have been read. This is done only if the
682 * -q flag wasn't given (to prevent the .BEGIN from being executed
683 * should it exist).
684 */
685 if (!queryFlag) {
686 if (maxLocal == -1) {
687 maxLocal = maxJobs;
688 }
689 Job_Init (maxJobs, maxLocal);
690 jobsRunning = TRUE;
691 }
692
693 /*
694 * Traverse the graph, checking on all the targets
695 */
696 outOfDate = Make_Run (targs);
697 } else {
698 /*
699 * Compat_Init will take care of creating all the targets as well
700 * as initializing the module.
701 */
702 Compat_Run(targs);
703 }
704
705 /*
706 * Print the graph now it's been processed if the user requested it
707 */
708 if (printGraph & 2) {
709 Targ_PrintGraph (2);
710 }
711
712 if (queryFlag && outOfDate) {
713 exit (1);
714 } else {
715 exit (0);
716 }
717}
aa5839c2 718
ab950546
KB
719/*-
720 *-----------------------------------------------------------------------
721 * ReadMakefile --
722 * Open and parse the given makefile.
723 *
724 * Results:
725 * TRUE if ok. FALSE if couldn't open file.
726 *
727 * Side Effects:
728 * lots
729 *-----------------------------------------------------------------------
730 */
731static Boolean
732ReadMakefile (fname)
733 char *fname; /* makefile to read */
734{
735 if (strcmp (fname, "-") == 0) {
736 Parse_File ("(stdin)", stdin);
737 Var_Set("MAKEFILE", "", VAR_GLOBAL);
738 return (TRUE);
739 } else {
740 FILE * stream;
741 extern Lst parseIncPath, sysIncPath;
742
743 stream = fopen (fname, "r");
744
745 if (stream == (FILE *) NULL) {
746 /*
747 * Look in -I directories...
748 */
749 char *name = Dir_FindFile(fname, parseIncPath);
750
751 if (name == NULL) {
752 /*
753 * Last-ditch: look in system include directories.
754 */
755 name = Dir_FindFile(fname, sysIncPath);
756 if (name == NULL) {
757 return (FALSE);
758 }
759 }
760 stream = fopen(name, "r");
761 if (stream == (FILE *)NULL) {
762 /* Better safe than sorry... */
763 return(FALSE);
764 }
765 fname = name;
766 }
767 /*
768 * Set the MAKEFILE variable desired by System V fans -- the placement
769 * of the setting here means it gets set to the last makefile
770 * specified, as it is set by SysV make...
771 */
772 Var_Set("MAKEFILE", fname, VAR_GLOBAL);
773 Parse_File (fname, stream);
774 fclose (stream);
775 return (TRUE);
776 }
777}
aa5839c2 778
ab950546
KB
779/*-
780 *-----------------------------------------------------------------------
781 * Error --
782 * Print an error message given its format and 0, 1, 2 or 3 arguments.
783 *
784 * Results:
785 * None.
786 *
787 * Side Effects:
788 * The message is printed.
789 *
790 *-----------------------------------------------------------------------
791 */
792/*VARARGS1*/
793void
794Error (fmt, arg1, arg2, arg3)
795 char *fmt; /* Format string */
796 int arg1, /* First optional argument */
797 arg2, /* Second optional argument */
798 arg3; /* Third optional argument */
799{
800 static char estr[BSIZE]; /* output string */
801
802 sprintf (estr, "%s: ", Var_Value(".PMAKE", VAR_GLOBAL));
803 sprintf (&estr[strlen (estr)], fmt, arg1, arg2, arg3);
804 (void) strcat (estr, "\n");
805
806 fputs (estr, stderr);
807 fflush (stderr);
808}
aa5839c2 809
ab950546
KB
810/*-
811 *-----------------------------------------------------------------------
812 * Fatal --
813 * Produce a Fatal error message. If jobs are running, waits for them
814 * to finish.
815 *
816 * Results:
817 * None
818 *
819 * Side Effects:
820 * The program exits
821 *-----------------------------------------------------------------------
822 */
823/* VARARGS1 */
824void
825Fatal (fmt, arg1, arg2)
826 char *fmt; /* format string */
827 int arg1; /* first optional argument */
828 int arg2; /* second optional argument */
829{
830 if (jobsRunning) {
831 Job_Wait();
832 }
833
834 Error (fmt, arg1, arg2);
835
836 if (printGraph & 2) {
837 Targ_PrintGraph(2);
838 }
839 exit (2); /* Not 1 so -q can distinguish error */
840}
aa5839c2 841
ab950546
KB
842/*
843 *-----------------------------------------------------------------------
844 * Punt --
845 * Major exception once jobs are being created. Kills all jobs, prints
846 * a message and exits.
847 *
848 * Results:
849 * None
850 *
851 * Side Effects:
852 * All children are killed indiscriminately and the program Lib_Exits
853 *-----------------------------------------------------------------------
854 */
855/* VARARGS1 */
856void
857Punt (fmt, arg1, arg2)
858 char *fmt; /* format string */
859 int arg1; /* optional argument */
860 int arg2; /* optional second argument */
861{
862 Error (fmt, arg1, arg2);
863
864 DieHorribly();
865}
aa5839c2 866
ab950546
KB
867/*-
868 *-----------------------------------------------------------------------
869 * DieHorribly --
870 * Exit without giving a message.
871 *
872 * Results:
873 * None
874 *
875 * Side Effects:
876 * A big one...
877 *-----------------------------------------------------------------------
878 */
879void
880DieHorribly()
881{
882 if (jobsRunning) {
883 Job_AbortAll ();
884 }
885 if (printGraph & 2) {
886 Targ_PrintGraph(2);
887 }
888
889 exit (2); /* Not 1, so -q can distinguish error */
890}
aa5839c2 891
ab950546
KB
892/*
893 *-----------------------------------------------------------------------
894 * Finish --
895 * Called when aborting due to errors in child shell to signal
896 * abnormal exit.
897 *
898 * Results:
899 * None
900 *
901 * Side Effects:
902 * The program exits
903 * -----------------------------------------------------------------------
904 */
905void
906Finish (errors)
907 int errors; /* number of errors encountered in Make_Make */
908{
909 Fatal ("%d error%s", errors, errors == 1 ? "" : "s");
910}