Mon Oct 26 21:34:10 2020 UTC ()
make(1): group the command line options and arguments

By having a single struct that holds all command line options and
arguments, it is easy to see in the code when such a command line
argument is modified.  It also cleans up the namespace since the command
line options don't follow a common naming style.  Having them in a
struct also means that there is a single place for putting the
documentation, not two as before.

The struct also suggests to extract the initialization code out of main,
which is still too large, having more than 400 lines of code and
covering far too many topics.


(rillig)
diff -r1.168 -r1.169 src/usr.bin/make/compat.c
diff -r1.168 -r1.169 src/usr.bin/make/cond.c
diff -r1.289 -r1.290 src/usr.bin/make/job.c
diff -r1.57 -r1.58 src/usr.bin/make/job.h
diff -r1.390 -r1.391 src/usr.bin/make/main.c
diff -r1.180 -r1.181 src/usr.bin/make/make.c
diff -r1.172 -r1.173 src/usr.bin/make/make.h
diff -r1.400 -r1.401 src/usr.bin/make/parse.c
diff -r1.124 -r1.125 src/usr.bin/make/targ.c
diff -r1.589 -r1.590 src/usr.bin/make/var.c

cvs diff -r1.168 -r1.169 src/usr.bin/make/compat.c (expand / switch to unified diff)

--- src/usr.bin/make/compat.c 2020/10/24 04:40:45 1.168
+++ src/usr.bin/make/compat.c 2020/10/26 21:34:10 1.169
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: compat.c,v 1.168 2020/10/24 04:40:45 rillig Exp $ */ 1/* $NetBSD: compat.c,v 1.169 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -86,44 +86,44 @@ @@ -86,44 +86,44 @@
86#include <sys/stat.h> 86#include <sys/stat.h>
87#include <sys/wait.h> 87#include <sys/wait.h>
88 88
89#include <errno.h> 89#include <errno.h>
90#include <signal.h> 90#include <signal.h>
91 91
92#include "make.h" 92#include "make.h"
93#include "dir.h" 93#include "dir.h"
94#include "job.h" 94#include "job.h"
95#include "metachar.h" 95#include "metachar.h"
96#include "pathnames.h" 96#include "pathnames.h"
97 97
98/* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */ 98/* "@(#)compat.c 8.2 (Berkeley) 3/19/94" */
99MAKE_RCSID("$NetBSD: compat.c,v 1.168 2020/10/24 04:40:45 rillig Exp $"); 99MAKE_RCSID("$NetBSD: compat.c,v 1.169 2020/10/26 21:34:10 rillig Exp $");
100 100
101static GNode *curTarg = NULL; 101static GNode *curTarg = NULL;
102static pid_t compatChild; 102static pid_t compatChild;
103static int compatSigno; 103static int compatSigno;
104 104
105/* 105/*
106 * CompatDeleteTarget -- delete a failed, interrupted, or otherwise 106 * CompatDeleteTarget -- delete a failed, interrupted, or otherwise
107 * duffed target if not inhibited by .PRECIOUS. 107 * duffed target if not inhibited by .PRECIOUS.
108 */ 108 */
109static void 109static void
110CompatDeleteTarget(GNode *gn) 110CompatDeleteTarget(GNode *gn)
111{ 111{
112 if (gn != NULL && !Targ_Precious(gn)) { 112 if (gn != NULL && !Targ_Precious(gn)) {
113 char *file_freeIt; 113 char *file_freeIt;
114 const char *file = Var_Value(TARGET, gn, &file_freeIt); 114 const char *file = Var_Value(TARGET, gn, &file_freeIt);
115 115
116 if (!noExecute && eunlink(file) != -1) { 116 if (!opts.noExecute && eunlink(file) != -1) {
117 Error("*** %s removed", file); 117 Error("*** %s removed", file);
118 } 118 }
119 119
120 bmake_free(file_freeIt); 120 bmake_free(file_freeIt);
121 } 121 }
122} 122}
123 123
124/* Interrupt the creation of the current target and remove it if it ain't 124/* Interrupt the creation of the current target and remove it if it ain't
125 * precious. Then exit. 125 * precious. Then exit.
126 * 126 *
127 * If .INTERRUPT exists, its commands are run first WITH INTERRUPTS IGNORED. 127 * If .INTERRUPT exists, its commands are run first WITH INTERRUPTS IGNORED.
128 * 128 *
129 * XXX: is .PRECIOUS supposed to inhibit .INTERRUPT? I doubt it, but I've 129 * XXX: is .PRECIOUS supposed to inhibit .INTERRUPT? I doubt it, but I've
@@ -410,27 +410,27 @@ Compat_RunCommand(const char *cmdp, GNod @@ -410,27 +410,27 @@ Compat_RunCommand(const char *cmdp, GNod
410 status = WTERMSIG(reason); /* signaled */ 410 status = WTERMSIG(reason); /* signaled */
411 printf("*** Signal %d", status); 411 printf("*** Signal %d", status);
412 } 412 }
413 413
414 414
415 if (!WIFEXITED(reason) || status != 0) { 415 if (!WIFEXITED(reason) || status != 0) {
416 if (errCheck) { 416 if (errCheck) {
417#ifdef USE_META 417#ifdef USE_META
418 if (useMeta) { 418 if (useMeta) {
419 meta_job_error(NULL, gn, 0, status); 419 meta_job_error(NULL, gn, 0, status);
420 } 420 }
421#endif 421#endif
422 gn->made = ERROR; 422 gn->made = ERROR;
423 if (keepgoing) { 423 if (opts.keepgoing) {
424 /* Abort the current target, but let others continue. */ 424 /* Abort the current target, but let others continue. */
425 printf(" (continuing)\n"); 425 printf(" (continuing)\n");
426 } else { 426 } else {
427 printf("\n"); 427 printf("\n");
428 } 428 }
429 if (deleteOnError) 429 if (deleteOnError)
430 CompatDeleteTarget(gn); 430 CompatDeleteTarget(gn);
431 } else { 431 } else {
432 /* 432 /*
433 * Continue executing commands for this target. 433 * Continue executing commands for this target.
434 * If we return 0, this will happen... 434 * If we return 0, this will happen...
435 */ 435 */
436 printf(" (ignored)\n"); 436 printf(" (ignored)\n");
@@ -516,52 +516,52 @@ Compat_Make(GNode *gn, GNode *pgn) @@ -516,52 +516,52 @@ Compat_Make(GNode *gn, GNode *pgn)
516 */ 516 */
517 DEBUG1(MAKE, "Examining %s...", gn->name); 517 DEBUG1(MAKE, "Examining %s...", gn->name);
518 if (!Make_OODate(gn)) { 518 if (!Make_OODate(gn)) {
519 gn->made = UPTODATE; 519 gn->made = UPTODATE;
520 DEBUG0(MAKE, "up-to-date.\n"); 520 DEBUG0(MAKE, "up-to-date.\n");
521 goto cohorts; 521 goto cohorts;
522 } else 522 } else
523 DEBUG0(MAKE, "out-of-date.\n"); 523 DEBUG0(MAKE, "out-of-date.\n");
524 524
525 /* 525 /*
526 * If the user is just seeing if something is out-of-date, exit now 526 * If the user is just seeing if something is out-of-date, exit now
527 * to tell him/her "yes". 527 * to tell him/her "yes".
528 */ 528 */
529 if (queryFlag) { 529 if (opts.queryFlag) {
530 exit(1); 530 exit(1);
531 } 531 }
532 532
533 /* 533 /*
534 * We need to be re-made. We also have to make sure we've got a $? 534 * We need to be re-made. We also have to make sure we've got a $?
535 * variable. To be nice, we also define the $> variable using 535 * variable. To be nice, we also define the $> variable using
536 * Make_DoAllVar(). 536 * Make_DoAllVar().
537 */ 537 */
538 Make_DoAllVar(gn); 538 Make_DoAllVar(gn);
539 539
540 /* 540 /*
541 * Alter our type to tell if errors should be ignored or things 541 * Alter our type to tell if errors should be ignored or things
542 * should not be printed so CompatRunCommand knows what to do. 542 * should not be printed so CompatRunCommand knows what to do.
543 */ 543 */
544 if (Targ_Ignore(gn)) 544 if (Targ_Ignore(gn))
545 gn->type |= OP_IGNORE; 545 gn->type |= OP_IGNORE;
546 if (Targ_Silent(gn)) 546 if (Targ_Silent(gn))
547 gn->type |= OP_SILENT; 547 gn->type |= OP_SILENT;
548 548
549 if (Job_CheckCommands(gn, Fatal)) { 549 if (Job_CheckCommands(gn, Fatal)) {
550 /* 550 /*
551 * Our commands are ok, but we still have to worry about the -t 551 * Our commands are ok, but we still have to worry about the -t
552 * flag... 552 * flag...
553 */ 553 */
554 if (!touchFlag || (gn->type & OP_MAKE)) { 554 if (!opts.touchFlag || (gn->type & OP_MAKE)) {
555 curTarg = gn; 555 curTarg = gn;
556#ifdef USE_META 556#ifdef USE_META
557 if (useMeta && !NoExecute(gn)) { 557 if (useMeta && !NoExecute(gn)) {
558 meta_job_start(NULL, gn); 558 meta_job_start(NULL, gn);
559 } 559 }
560#endif 560#endif
561 RunCommands(gn); 561 RunCommands(gn);
562 curTarg = NULL; 562 curTarg = NULL;
563 } else { 563 } else {
564 Job_Touch(gn, (gn->type & OP_SILENT) != 0); 564 Job_Touch(gn, (gn->type & OP_SILENT) != 0);
565 } 565 }
566 } else { 566 } else {
567 gn->made = ERROR; 567 gn->made = ERROR;
@@ -576,27 +576,27 @@ Compat_Make(GNode *gn, GNode *pgn) @@ -576,27 +576,27 @@ Compat_Make(GNode *gn, GNode *pgn)
576 if (gn->made != ERROR) { 576 if (gn->made != ERROR) {
577 /* 577 /*
578 * If the node was made successfully, mark it so, update 578 * If the node was made successfully, mark it so, update
579 * its modification time and timestamp all its parents. Note 579 * its modification time and timestamp all its parents. Note
580 * that for .ZEROTIME targets, the timestamping isn't done. 580 * that for .ZEROTIME targets, the timestamping isn't done.
581 * This is to keep its state from affecting that of its parent. 581 * This is to keep its state from affecting that of its parent.
582 */ 582 */
583 gn->made = MADE; 583 gn->made = MADE;
584 pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0; 584 pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0;
585 if (!(gn->type & OP_EXEC)) { 585 if (!(gn->type & OP_EXEC)) {
586 pgn->flags |= CHILDMADE; 586 pgn->flags |= CHILDMADE;
587 Make_TimeStamp(pgn, gn); 587 Make_TimeStamp(pgn, gn);
588 } 588 }
589 } else if (keepgoing) { 589 } else if (opts.keepgoing) {
590 pgn->flags &= ~(unsigned)REMAKE; 590 pgn->flags &= ~(unsigned)REMAKE;
591 } else { 591 } else {
592 PrintOnError(gn, "\nStop."); 592 PrintOnError(gn, "\nStop.");
593 exit(1); 593 exit(1);
594 } 594 }
595 } else if (gn->made == ERROR) { 595 } else if (gn->made == ERROR) {
596 /* Already had an error when making this. Tell the parent to abort. */ 596 /* Already had an error when making this. Tell the parent to abort. */
597 pgn->flags &= ~(unsigned)REMAKE; 597 pgn->flags &= ~(unsigned)REMAKE;
598 } else { 598 } else {
599 if (Lst_FindDatum(gn->implicitParents, pgn) != NULL) { 599 if (Lst_FindDatum(gn->implicitParents, pgn) != NULL) {
600 char *target_freeIt; 600 char *target_freeIt;
601 const char *target = Var_Value(TARGET, gn, &target_freeIt); 601 const char *target = Var_Value(TARGET, gn, &target_freeIt);
602 Var_Set(IMPSRC, target != NULL ? target : "", pgn); 602 Var_Set(IMPSRC, target != NULL ? target : "", pgn);
@@ -649,27 +649,27 @@ Compat_Run(GNodeList *targs) @@ -649,27 +649,27 @@ Compat_Run(GNodeList *targs)
649 if (bmake_signal(SIGHUP, SIG_IGN) != SIG_IGN) 649 if (bmake_signal(SIGHUP, SIG_IGN) != SIG_IGN)
650 bmake_signal(SIGHUP, CompatInterrupt); 650 bmake_signal(SIGHUP, CompatInterrupt);
651 if (bmake_signal(SIGQUIT, SIG_IGN) != SIG_IGN) 651 if (bmake_signal(SIGQUIT, SIG_IGN) != SIG_IGN)
652 bmake_signal(SIGQUIT, CompatInterrupt); 652 bmake_signal(SIGQUIT, CompatInterrupt);
653 653
654 /* Create the .END node now, to keep the (debug) output of the 654 /* Create the .END node now, to keep the (debug) output of the
655 * counter.mk test the same as before 2020-09-23. This implementation 655 * counter.mk test the same as before 2020-09-23. This implementation
656 * detail probably doesn't matter though. */ 656 * detail probably doesn't matter though. */
657 (void)Targ_GetEndNode(); 657 (void)Targ_GetEndNode();
658 /* 658 /*
659 * If the user has defined a .BEGIN target, execute the commands attached 659 * If the user has defined a .BEGIN target, execute the commands attached
660 * to it. 660 * to it.
661 */ 661 */
662 if (!queryFlag) { 662 if (!opts.queryFlag) {
663 gn = Targ_FindNode(".BEGIN"); 663 gn = Targ_FindNode(".BEGIN");
664 if (gn != NULL) { 664 if (gn != NULL) {
665 Compat_Make(gn, gn); 665 Compat_Make(gn, gn);
666 if (gn->made == ERROR) { 666 if (gn->made == ERROR) {
667 PrintOnError(gn, "\nStop."); 667 PrintOnError(gn, "\nStop.");
668 exit(1); 668 exit(1);
669 } 669 }
670 } 670 }
671 } 671 }
672 672
673 /* 673 /*
674 * Expand .USE nodes right now, because they can modify the structure 674 * Expand .USE nodes right now, because they can modify the structure
675 * of the tree. 675 * of the tree.

cvs diff -r1.168 -r1.169 src/usr.bin/make/cond.c (expand / switch to unified diff)

--- src/usr.bin/make/cond.c 2020/10/24 04:51:19 1.168
+++ src/usr.bin/make/cond.c 2020/10/26 21:34:10 1.169
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cond.c,v 1.168 2020/10/24 04:51:19 rillig Exp $ */ 1/* $NetBSD: cond.c,v 1.169 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -83,27 +83,27 @@ @@ -83,27 +83,27 @@
83 * Cond_restore_depth 83 * Cond_restore_depth
84 * Save and restore the nesting of the conditions, at 84 * Save and restore the nesting of the conditions, at
85 * the start and end of including another makefile, to 85 * the start and end of including another makefile, to
86 * ensure that in each makefile the conditional 86 * ensure that in each makefile the conditional
87 * directives are well-balanced. 87 * directives are well-balanced.
88 */ 88 */
89 89
90#include <errno.h> 90#include <errno.h>
91 91
92#include "make.h" 92#include "make.h"
93#include "dir.h" 93#include "dir.h"
94 94
95/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */ 95/* "@(#)cond.c 8.2 (Berkeley) 1/2/94" */
96MAKE_RCSID("$NetBSD: cond.c,v 1.168 2020/10/24 04:51:19 rillig Exp $"); 96MAKE_RCSID("$NetBSD: cond.c,v 1.169 2020/10/26 21:34:10 rillig Exp $");
97 97
98/* 98/*
99 * The parsing of conditional expressions is based on this grammar: 99 * The parsing of conditional expressions is based on this grammar:
100 * E -> F || E 100 * E -> F || E
101 * E -> F 101 * E -> F
102 * F -> T && F 102 * F -> T && F
103 * F -> T 103 * F -> T
104 * T -> defined(variable) 104 * T -> defined(variable)
105 * T -> make(target) 105 * T -> make(target)
106 * T -> exists(file) 106 * T -> exists(file)
107 * T -> empty(varspec) 107 * T -> empty(varspec)
108 * T -> target(name) 108 * T -> target(name)
109 * T -> commands(name) 109 * T -> commands(name)
@@ -284,27 +284,27 @@ FuncDefined(size_t argLen MAKE_ATTR_UNUS @@ -284,27 +284,27 @@ FuncDefined(size_t argLen MAKE_ATTR_UNUS
284{ 284{
285 char *freeIt; 285 char *freeIt;
286 Boolean result = Var_Value(arg, VAR_CMD, &freeIt) != NULL; 286 Boolean result = Var_Value(arg, VAR_CMD, &freeIt) != NULL;
287 bmake_free(freeIt); 287 bmake_free(freeIt);
288 return result; 288 return result;
289} 289}
290 290
291/* See if the given target is being made. */ 291/* See if the given target is being made. */
292static Boolean 292static Boolean
293FuncMake(size_t argLen MAKE_ATTR_UNUSED, const char *arg) 293FuncMake(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
294{ 294{
295 StringListNode *ln; 295 StringListNode *ln;
296 296
297 for (ln = create->first; ln != NULL; ln = ln->next) 297 for (ln = opts.create->first; ln != NULL; ln = ln->next)
298 if (Str_Match(ln->datum, arg)) 298 if (Str_Match(ln->datum, arg))
299 return TRUE; 299 return TRUE;
300 return FALSE; 300 return FALSE;
301} 301}
302 302
303/* See if the given file exists. */ 303/* See if the given file exists. */
304static Boolean 304static Boolean
305FuncExists(size_t argLen MAKE_ATTR_UNUSED, const char *arg) 305FuncExists(size_t argLen MAKE_ATTR_UNUSED, const char *arg)
306{ 306{
307 Boolean result; 307 Boolean result;
308 char *path; 308 char *path;
309 309
310 path = Dir_FindFile(arg, dirSearchPath); 310 path = Dir_FindFile(arg, dirSearchPath);

cvs diff -r1.289 -r1.290 src/usr.bin/make/job.c (expand / switch to unified diff)

--- src/usr.bin/make/job.c 2020/10/26 20:11:02 1.289
+++ src/usr.bin/make/job.c 2020/10/26 21:34:10 1.290
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: job.c,v 1.289 2020/10/26 20:11:02 rillig Exp $ */ 1/* $NetBSD: job.c,v 1.290 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -133,27 +133,27 @@ @@ -133,27 +133,27 @@
133#ifndef USE_SELECT 133#ifndef USE_SELECT
134#include <poll.h> 134#include <poll.h>
135#endif 135#endif
136#include <signal.h> 136#include <signal.h>
137#include <utime.h> 137#include <utime.h>
138 138
139#include "make.h" 139#include "make.h"
140#include "dir.h" 140#include "dir.h"
141#include "job.h" 141#include "job.h"
142#include "pathnames.h" 142#include "pathnames.h"
143#include "trace.h" 143#include "trace.h"
144 144
145/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ 145/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */
146MAKE_RCSID("$NetBSD: job.c,v 1.289 2020/10/26 20:11:02 rillig Exp $"); 146MAKE_RCSID("$NetBSD: job.c,v 1.290 2020/10/26 21:34:10 rillig Exp $");
147 147
148/* A shell defines how the commands are run. All commands for a target are 148/* A shell defines how the commands are run. All commands for a target are
149 * written into a single file, which is then given to the shell to execute 149 * written into a single file, which is then given to the shell to execute
150 * the commands from it. The commands are written to the file using a few 150 * the commands from it. The commands are written to the file using a few
151 * templates for echo control and error control. 151 * templates for echo control and error control.
152 * 152 *
153 * The name of the shell is the basename for the predefined shells, such as 153 * The name of the shell is the basename for the predefined shells, such as
154 * "sh", "csh", "bash". For custom shells, it is the full pathname, and its 154 * "sh", "csh", "bash". For custom shells, it is the full pathname, and its
155 * basename is used to select the type of shell; the longest match wins. 155 * basename is used to select the type of shell; the longest match wins.
156 * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. 156 * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh.
157 * 157 *
158 * The echoing of command lines is controlled using hasEchoCtl, echoOff, 158 * The echoing of command lines is controlled using hasEchoCtl, echoOff,
159 * echoOn, noPrint and noPrintLen. When echoOff is executed by the shell, it 159 * echoOn, noPrint and noPrintLen. When echoOff is executed by the shell, it
@@ -392,27 +392,27 @@ static int readyfd(Job *); @@ -392,27 +392,27 @@ static int readyfd(Job *);
392static GNode *lastNode; /* The node for which output was most recently 392static GNode *lastNode; /* The node for which output was most recently
393 * produced. */ 393 * produced. */
394static char *targPrefix = NULL; /* What we print at the start of TARG_FMT */ 394static char *targPrefix = NULL; /* What we print at the start of TARG_FMT */
395static Job tokenWaitJob; /* token wait pseudo-job */ 395static Job tokenWaitJob; /* token wait pseudo-job */
396 396
397static Job childExitJob; /* child exit pseudo-job */ 397static Job childExitJob; /* child exit pseudo-job */
398#define CHILD_EXIT "." 398#define CHILD_EXIT "."
399#define DO_JOB_RESUME "R" 399#define DO_JOB_RESUME "R"
400 400
401enum { npseudojobs = 2 }; /* number of pseudo-jobs */ 401enum { npseudojobs = 2 }; /* number of pseudo-jobs */
402 402
403#define TARG_FMT "%s %s ---\n" /* Default format */ 403#define TARG_FMT "%s %s ---\n" /* Default format */
404#define MESSAGE(fp, gn) \ 404#define MESSAGE(fp, gn) \
405 if (maxJobs != 1 && targPrefix && *targPrefix) \ 405 if (opts.maxJobs != 1 && targPrefix && *targPrefix) \
406 (void)fprintf(fp, TARG_FMT, targPrefix, gn->name) 406 (void)fprintf(fp, TARG_FMT, targPrefix, gn->name)
407 407
408static sigset_t caught_signals; /* Set of signals we handle */ 408static sigset_t caught_signals; /* Set of signals we handle */
409 409
410static void JobDoOutput(Job *, Boolean); 410static void JobDoOutput(Job *, Boolean);
411static void JobInterrupt(int, int) MAKE_ATTR_DEAD; 411static void JobInterrupt(int, int) MAKE_ATTR_DEAD;
412static void JobRestartJobs(void); 412static void JobRestartJobs(void);
413static void JobSigReset(void); 413static void JobSigReset(void);
414 414
415static unsigned 415static unsigned
416nfds_per_job(void) 416nfds_per_job(void)
417{ 417{
418#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV) 418#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV)
@@ -439,27 +439,27 @@ job_table_dump(const char *where) @@ -439,27 +439,27 @@ job_table_dump(const char *where)
439 * unsuccessful job unless inhibited by .PRECIOUS. 439 * unsuccessful job unless inhibited by .PRECIOUS.
440 */ 440 */
441static void 441static void
442JobDeleteTarget(GNode *gn) 442JobDeleteTarget(GNode *gn)
443{ 443{
444 const char *file; 444 const char *file;
445 445
446 if (gn->type & OP_JOIN) 446 if (gn->type & OP_JOIN)
447 return; 447 return;
448 if (gn->type & OP_PHONY) 448 if (gn->type & OP_PHONY)
449 return; 449 return;
450 if (Targ_Precious(gn)) 450 if (Targ_Precious(gn))
451 return; 451 return;
452 if (noExecute) 452 if (opts.noExecute)
453 return; 453 return;
454 454
455 file = GNode_Path(gn); 455 file = GNode_Path(gn);
456 if (eunlink(file) != -1) 456 if (eunlink(file) != -1)
457 Error("*** %s removed", file); 457 Error("*** %s removed", file);
458} 458}
459 459
460/* 460/*
461 * JobSigLock/JobSigUnlock 461 * JobSigLock/JobSigUnlock
462 * 462 *
463 * Signal lock routines to get exclusive access. Currently used to 463 * Signal lock routines to get exclusive access. Currently used to
464 * protect `jobs' and `stoppedJobs' list manipulations. 464 * protect `jobs' and `stoppedJobs' list manipulations.
465 */ 465 */
@@ -1073,27 +1073,27 @@ JobFinish(Job *job, int status) @@ -1073,27 +1073,27 @@ JobFinish(Job *job, int status)
1073 job->node->made = MADE; 1073 job->node->made = MADE;
1074 if (!(job->flags & JOB_SPECIAL)) 1074 if (!(job->flags & JOB_SPECIAL))
1075 return_job_token = TRUE; 1075 return_job_token = TRUE;
1076 Make_Update(job->node); 1076 Make_Update(job->node);
1077 job->job_state = JOB_ST_FREE; 1077 job->job_state = JOB_ST_FREE;
1078 } else if (status != 0) { 1078 } else if (status != 0) {
1079 errors++; 1079 errors++;
1080 job->job_state = JOB_ST_FREE; 1080 job->job_state = JOB_ST_FREE;
1081 } 1081 }
1082 1082
1083 /* 1083 /*
1084 * Set aborting if any error. 1084 * Set aborting if any error.
1085 */ 1085 */
1086 if (errors && !keepgoing && (aborting != ABORT_INTERRUPT)) { 1086 if (errors && !opts.keepgoing && (aborting != ABORT_INTERRUPT)) {
1087 /* 1087 /*
1088 * If we found any errors in this batch of children and the -k flag 1088 * If we found any errors in this batch of children and the -k flag
1089 * wasn't given, we set the aborting flag so no more jobs get 1089 * wasn't given, we set the aborting flag so no more jobs get
1090 * started. 1090 * started.
1091 */ 1091 */
1092 aborting = ABORT_ERROR; 1092 aborting = ABORT_ERROR;
1093 } 1093 }
1094 1094
1095 if (return_job_token) 1095 if (return_job_token)
1096 Job_TokenReturn(); 1096 Job_TokenReturn();
1097 1097
1098 if (aborting == ABORT_ERROR && jobTokensRunning == 0) { 1098 if (aborting == ABORT_ERROR && jobTokensRunning == 0) {
1099 /* 1099 /*
@@ -1225,27 +1225,27 @@ Job_CheckCommands(GNode *gn, void (*abor @@ -1225,27 +1225,27 @@ Job_CheckCommands(GNode *gn, void (*abor
1225 fprintf(stdout, "%s: %s, %d: ignoring stale %s for %s\n", 1225 fprintf(stdout, "%s: %s, %d: ignoring stale %s for %s\n",
1226 progname, gn->fname, gn->lineno, makeDependfile, 1226 progname, gn->fname, gn->lineno, makeDependfile,
1227 gn->name); 1227 gn->name);
1228 return TRUE; 1228 return TRUE;
1229 } 1229 }
1230 1230
1231 if (gn->type & OP_OPTIONAL) { 1231 if (gn->type & OP_OPTIONAL) {
1232 (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n", 1232 (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n",
1233 progname, gn->name, "ignored"); 1233 progname, gn->name, "ignored");
1234 (void)fflush(stdout); 1234 (void)fflush(stdout);
1235 return TRUE; 1235 return TRUE;
1236 } 1236 }
1237 1237
1238 if (keepgoing) { 1238 if (opts.keepgoing) {
1239 (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n", 1239 (void)fprintf(stdout, "%s: don't know how to make %s (%s)\n",
1240 progname, gn->name, "continuing"); 1240 progname, gn->name, "continuing");
1241 (void)fflush(stdout); 1241 (void)fflush(stdout);
1242 return FALSE; 1242 return FALSE;
1243 } 1243 }
1244 1244
1245 abortProc("%s: don't know how to make %s. Stop", progname, gn->name); 1245 abortProc("%s: don't know how to make %s. Stop", progname, gn->name);
1246 return FALSE; 1246 return FALSE;
1247} 1247}
1248 1248
1249/* Execute the shell for the given job. 1249/* Execute the shell for the given job.
1250 * 1250 *
1251 * A shell is executed, its output is altered and the Job structure added 1251 * A shell is executed, its output is altered and the Job structure added
@@ -1514,28 +1514,28 @@ JobStart(GNode *gn, int flags) @@ -1514,28 +1514,28 @@ JobStart(GNode *gn, int flags)
1514 /* 1514 /*
1515 * Check the commands now so any attributes from .DEFAULT have a chance 1515 * Check the commands now so any attributes from .DEFAULT have a chance
1516 * to migrate to the node 1516 * to migrate to the node
1517 */ 1517 */
1518 cmdsOK = Job_CheckCommands(gn, Error); 1518 cmdsOK = Job_CheckCommands(gn, Error);
1519 1519
1520 job->inPollfd = NULL; 1520 job->inPollfd = NULL;
1521 /* 1521 /*
1522 * If the -n flag wasn't given, we open up OUR (not the child's) 1522 * If the -n flag wasn't given, we open up OUR (not the child's)
1523 * temporary file to stuff commands in it. The thing is rd/wr so we don't 1523 * temporary file to stuff commands in it. The thing is rd/wr so we don't
1524 * need to reopen it to feed it to the shell. If the -n flag *was* given, 1524 * need to reopen it to feed it to the shell. If the -n flag *was* given,
1525 * we just set the file to be stdout. Cute, huh? 1525 * we just set the file to be stdout. Cute, huh?
1526 */ 1526 */
1527 if (((gn->type & OP_MAKE) && !(noRecursiveExecute)) || 1527 if (((gn->type & OP_MAKE) && !opts.noRecursiveExecute) ||
1528 (!noExecute && !touchFlag)) { 1528 (!opts.noExecute && !opts.touchFlag)) {
1529 /* 1529 /*
1530 * tfile is the name of a file into which all shell commands are 1530 * tfile is the name of a file into which all shell commands are
1531 * put. It is removed before the child shell is executed, unless 1531 * put. It is removed before the child shell is executed, unless
1532 * DEBUG(SCRIPT) is set. 1532 * DEBUG(SCRIPT) is set.
1533 */ 1533 */
1534 char *tfile; 1534 char *tfile;
1535 sigset_t mask; 1535 sigset_t mask;
1536 /* 1536 /*
1537 * We're serious here, but if the commands were bogus, we're 1537 * We're serious here, but if the commands were bogus, we're
1538 * also dead... 1538 * also dead...
1539 */ 1539 */
1540 if (!cmdsOK) { 1540 if (!cmdsOK) {
1541 PrintOnError(gn, NULL); /* provide some clue */ 1541 PrintOnError(gn, NULL); /* provide some clue */
@@ -1814,27 +1814,27 @@ end_loop: @@ -1814,27 +1814,27 @@ end_loop:
1814 */ 1814 */
1815 job->outBuf[i] = '\0'; 1815 job->outBuf[i] = '\0';
1816 if (i >= job->curPos) { 1816 if (i >= job->curPos) {
1817 char *cp; 1817 char *cp;
1818 1818
1819 cp = JobOutput(job, job->outBuf, &job->outBuf[i]); 1819 cp = JobOutput(job, job->outBuf, &job->outBuf[i]);
1820 1820
1821 /* 1821 /*
1822 * There's still more in that thar buffer. This time, though, 1822 * There's still more in that thar buffer. This time, though,
1823 * we know there's no newline at the end, so we add one of 1823 * we know there's no newline at the end, so we add one of
1824 * our own free will. 1824 * our own free will.
1825 */ 1825 */
1826 if (*cp != '\0') { 1826 if (*cp != '\0') {
1827 if (!beSilent && job->node != lastNode) { 1827 if (!opts.beSilent && job->node != lastNode) {
1828 MESSAGE(stdout, job->node); 1828 MESSAGE(stdout, job->node);
1829 lastNode = job->node; 1829 lastNode = job->node;
1830 } 1830 }
1831#ifdef USE_META 1831#ifdef USE_META
1832 if (useMeta) { 1832 if (useMeta) {
1833 meta_job_output(job, cp, gotNL ? "\n" : ""); 1833 meta_job_output(job, cp, gotNL ? "\n" : "");
1834 } 1834 }
1835#endif 1835#endif
1836 (void)fprintf(stdout, "%s%s", cp, gotNL ? "\n" : ""); 1836 (void)fprintf(stdout, "%s%s", cp, gotNL ? "\n" : "");
1837 (void)fflush(stdout); 1837 (void)fflush(stdout);
1838 } 1838 }
1839 } 1839 }
1840 /* 1840 /*
@@ -2107,29 +2107,29 @@ Job_SetPrefix(void) @@ -2107,29 +2107,29 @@ Job_SetPrefix(void)
2107 } 2107 }
2108 2108
2109 (void)Var_Subst("${" MAKE_JOB_PREFIX "}", 2109 (void)Var_Subst("${" MAKE_JOB_PREFIX "}",
2110 VAR_GLOBAL, VARE_WANTRES, &targPrefix); 2110 VAR_GLOBAL, VARE_WANTRES, &targPrefix);
2111 /* TODO: handle errors */ 2111 /* TODO: handle errors */
2112} 2112}
2113 2113
2114/* Initialize the process module. */ 2114/* Initialize the process module. */
2115void 2115void
2116Job_Init(void) 2116Job_Init(void)
2117{ 2117{
2118 Job_SetPrefix(); 2118 Job_SetPrefix();
2119 /* Allocate space for all the job info */ 2119 /* Allocate space for all the job info */
2120 job_table = bmake_malloc((size_t)maxJobs * sizeof *job_table); 2120 job_table = bmake_malloc((size_t)opts.maxJobs * sizeof *job_table);
2121 memset(job_table, 0, (size_t)maxJobs * sizeof *job_table); 2121 memset(job_table, 0, (size_t)opts.maxJobs * sizeof *job_table);
2122 job_table_end = job_table + maxJobs; 2122 job_table_end = job_table + opts.maxJobs;
2123 wantToken = 0; 2123 wantToken = 0;
2124 2124
2125 aborting = 0; 2125 aborting = 0;
2126 errors = 0; 2126 errors = 0;
2127 2127
2128 lastNode = NULL; 2128 lastNode = NULL;
2129 2129
2130 /* 2130 /*
2131 * There is a non-zero chance that we already have children. 2131 * There is a non-zero chance that we already have children.
2132 * eg after 'make -f- <<EOF' 2132 * eg after 'make -f- <<EOF'
2133 * Since their termination causes a 'Child (pid) not in table' message, 2133 * Since their termination causes a 'Child (pid) not in table' message,
2134 * Collect the status of any that are already dead, and suppress the 2134 * Collect the status of any that are already dead, and suppress the
2135 * error message if there are any undead ones. 2135 * error message if there are any undead ones.
@@ -2140,29 +2140,29 @@ Job_Init(void) @@ -2140,29 +2140,29 @@ Job_Init(void)
2140 if (rval > 0) 2140 if (rval > 0)
2141 continue; 2141 continue;
2142 if (rval == 0) 2142 if (rval == 0)
2143 lurking_children = 1; 2143 lurking_children = 1;
2144 break; 2144 break;
2145 } 2145 }
2146 2146
2147 Shell_Init(); 2147 Shell_Init();
2148 2148
2149 JobCreatePipe(&childExitJob, 3); 2149 JobCreatePipe(&childExitJob, 3);
2150 2150
2151 /* Preallocate enough for the maximum number of jobs. */ 2151 /* Preallocate enough for the maximum number of jobs. */
2152 fds = bmake_malloc(sizeof(*fds) * 2152 fds = bmake_malloc(sizeof(*fds) *
2153 (npseudojobs + (size_t)maxJobs) * nfds_per_job()); 2153 (npseudojobs + (size_t)opts.maxJobs) * nfds_per_job());
2154 jobfds = bmake_malloc(sizeof(*jobfds) * 2154 jobfds = bmake_malloc(sizeof(*jobfds) *
2155 (npseudojobs + (size_t)maxJobs) * nfds_per_job()); 2155 (npseudojobs + (size_t)opts.maxJobs) * nfds_per_job());
2156 2156
2157 /* These are permanent entries and take slots 0 and 1 */ 2157 /* These are permanent entries and take slots 0 and 1 */
2158 watchfd(&tokenWaitJob); 2158 watchfd(&tokenWaitJob);
2159 watchfd(&childExitJob); 2159 watchfd(&childExitJob);
2160 2160
2161 sigemptyset(&caught_signals); 2161 sigemptyset(&caught_signals);
2162 /* 2162 /*
2163 * Install a SIGCHLD handler. 2163 * Install a SIGCHLD handler.
2164 */ 2164 */
2165 (void)bmake_signal(SIGCHLD, JobChildSig); 2165 (void)bmake_signal(SIGCHLD, JobChildSig);
2166 sigaddset(&caught_signals, SIGCHLD); 2166 sigaddset(&caught_signals, SIGCHLD);
2167 2167
2168#define ADDSIG(s,h) \ 2168#define ADDSIG(s,h) \
@@ -2464,30 +2464,30 @@ JobInterrupt(int runINTERRUPT, int signo @@ -2464,30 +2464,30 @@ JobInterrupt(int runINTERRUPT, int signo
2464 2464
2465 gn = job->node; 2465 gn = job->node;
2466 2466
2467 JobDeleteTarget(gn); 2467 JobDeleteTarget(gn);
2468 if (job->pid) { 2468 if (job->pid) {
2469 DEBUG2(JOB, "JobInterrupt passing signal %d to child %d.\n", 2469 DEBUG2(JOB, "JobInterrupt passing signal %d to child %d.\n",
2470 signo, job->pid); 2470 signo, job->pid);
2471 KILLPG(job->pid, signo); 2471 KILLPG(job->pid, signo);
2472 } 2472 }
2473 } 2473 }
2474 2474
2475 JobSigUnlock(&mask); 2475 JobSigUnlock(&mask);
2476 2476
2477 if (runINTERRUPT && !touchFlag) { 2477 if (runINTERRUPT && !opts.touchFlag) {
2478 interrupt = Targ_FindNode(".INTERRUPT"); 2478 interrupt = Targ_FindNode(".INTERRUPT");
2479 if (interrupt != NULL) { 2479 if (interrupt != NULL) {
2480 ignoreErrors = FALSE; 2480 opts.ignoreErrors = FALSE;
2481 JobRun(interrupt); 2481 JobRun(interrupt);
2482 } 2482 }
2483 } 2483 }
2484 Trace_Log(MAKEINTR, 0); 2484 Trace_Log(MAKEINTR, 0);
2485 exit(signo); 2485 exit(signo);
2486} 2486}
2487 2487
2488/* Do the final processing, i.e. run the commands attached to the .END target. 2488/* Do the final processing, i.e. run the commands attached to the .END target.
2489 * 2489 *
2490 * Return the number of errors reported. */ 2490 * Return the number of errors reported. */
2491int 2491int
2492Job_Finish(void) 2492Job_Finish(void)
2493{ 2493{
@@ -2720,27 +2720,27 @@ Job_TokenReturn(void) @@ -2720,27 +2720,27 @@ Job_TokenReturn(void)
2720 * 2720 *
2721 * Returns TRUE if a token was withdrawn, and FALSE if the pool is currently 2721 * Returns TRUE if a token was withdrawn, and FALSE if the pool is currently
2722 * empty. */ 2722 * empty. */
2723Boolean 2723Boolean
2724Job_TokenWithdraw(void) 2724Job_TokenWithdraw(void)
2725{ 2725{
2726 char tok, tok1; 2726 char tok, tok1;
2727 ssize_t count; 2727 ssize_t count;
2728 2728
2729 wantToken = 0; 2729 wantToken = 0;
2730 DEBUG3(JOB, "Job_TokenWithdraw(%d): aborting %d, running %d\n", 2730 DEBUG3(JOB, "Job_TokenWithdraw(%d): aborting %d, running %d\n",
2731 getpid(), aborting, jobTokensRunning); 2731 getpid(), aborting, jobTokensRunning);
2732 2732
2733 if (aborting || (jobTokensRunning >= maxJobs)) 2733 if (aborting || (jobTokensRunning >= opts.maxJobs))
2734 return FALSE; 2734 return FALSE;
2735 2735
2736 count = read(tokenWaitJob.inPipe, &tok, 1); 2736 count = read(tokenWaitJob.inPipe, &tok, 1);
2737 if (count == 0) 2737 if (count == 0)
2738 Fatal("eof on job pipe!"); 2738 Fatal("eof on job pipe!");
2739 if (count < 0 && jobTokensRunning != 0) { 2739 if (count < 0 && jobTokensRunning != 0) {
2740 if (errno != EAGAIN) { 2740 if (errno != EAGAIN) {
2741 Fatal("job pipe read: %s", strerror(errno)); 2741 Fatal("job pipe read: %s", strerror(errno));
2742 } 2742 }
2743 DEBUG1(JOB, "(%d) blocked for token\n", getpid()); 2743 DEBUG1(JOB, "(%d) blocked for token\n", getpid());
2744 return FALSE; 2744 return FALSE;
2745 } 2745 }
2746 2746

cvs diff -r1.57 -r1.58 src/usr.bin/make/job.h (expand / switch to unified diff)

--- src/usr.bin/make/job.h 2020/10/23 07:14:32 1.57
+++ src/usr.bin/make/job.h 2020/10/26 21:34:10 1.58
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: job.h,v 1.57 2020/10/23 07:14:32 rillig Exp $ */ 1/* $NetBSD: job.h,v 1.58 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 4 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -182,27 +182,26 @@ typedef struct Job { @@ -182,27 +182,26 @@ typedef struct Job {
182 char outBuf[JOB_BUFSIZE + 1]; 182 char outBuf[JOB_BUFSIZE + 1];
183 size_t curPos; /* Current position in outBuf. */ 183 size_t curPos; /* Current position in outBuf. */
184 184
185#ifdef USE_META 185#ifdef USE_META
186 struct BuildMon bm; 186 struct BuildMon bm;
187#endif 187#endif
188} Job; 188} Job;
189 189
190extern const char *shellPath; 190extern const char *shellPath;
191extern const char *shellName; 191extern const char *shellName;
192extern char *shellErrFlag; 192extern char *shellErrFlag;
193 193
194extern int jobTokensRunning; /* tokens currently "out" */ 194extern int jobTokensRunning; /* tokens currently "out" */
195extern int maxJobs; /* Max jobs we can run */ 
196 195
197void Shell_Init(void); 196void Shell_Init(void);
198const char *Shell_GetNewline(void); 197const char *Shell_GetNewline(void);
199void Job_Touch(GNode *, Boolean); 198void Job_Touch(GNode *, Boolean);
200Boolean Job_CheckCommands(GNode *, void (*abortProc)(const char *, ...)); 199Boolean Job_CheckCommands(GNode *, void (*abortProc)(const char *, ...));
201void Job_CatchChildren(void); 200void Job_CatchChildren(void);
202void Job_CatchOutput(void); 201void Job_CatchOutput(void);
203void Job_Make(GNode *); 202void Job_Make(GNode *);
204void Job_Init(void); 203void Job_Init(void);
205Boolean Job_ParseShell(char *); 204Boolean Job_ParseShell(char *);
206int Job_Finish(void); 205int Job_Finish(void);
207void Job_End(void); 206void Job_End(void);
208void Job_Wait(void); 207void Job_Wait(void);

cvs diff -r1.390 -r1.391 src/usr.bin/make/main.c (expand / switch to unified diff)

--- src/usr.bin/make/main.c 2020/10/25 19:19:07 1.390
+++ src/usr.bin/make/main.c 2020/10/26 21:34:10 1.391
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: main.c,v 1.390 2020/10/25 19:19:07 rillig Exp $ */ 1/* $NetBSD: main.c,v 1.391 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -108,86 +108,64 @@ @@ -108,86 +108,64 @@
108 108
109#include <errno.h> 109#include <errno.h>
110#include <signal.h> 110#include <signal.h>
111#include <stdarg.h> 111#include <stdarg.h>
112#include <time.h> 112#include <time.h>
113 113
114#include "make.h" 114#include "make.h"
115#include "dir.h" 115#include "dir.h"
116#include "job.h" 116#include "job.h"
117#include "pathnames.h" 117#include "pathnames.h"
118#include "trace.h" 118#include "trace.h"
119 119
120/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */ 120/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
121MAKE_RCSID("$NetBSD: main.c,v 1.390 2020/10/25 19:19:07 rillig Exp $"); 121MAKE_RCSID("$NetBSD: main.c,v 1.391 2020/10/26 21:34:10 rillig Exp $");
122#if defined(MAKE_NATIVE) && !defined(lint) 122#if defined(MAKE_NATIVE) && !defined(lint)
123__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 " 123__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
124 "The Regents of the University of California. " 124 "The Regents of the University of California. "
125 "All rights reserved."); 125 "All rights reserved.");
126#endif 126#endif
127 127
128#ifndef DEFMAXLOCAL 128#ifndef DEFMAXLOCAL
129#define DEFMAXLOCAL DEFMAXJOBS 129#define DEFMAXLOCAL DEFMAXJOBS
130#endif 130#endif
131 131
132StringList * create; /* Targets to be made */ 132CmdOpts opts;
133time_t now; /* Time at start of make */ 133time_t now; /* Time at start of make */
134GNode *DEFAULT; /* .DEFAULT node */ 134GNode *DEFAULT; /* .DEFAULT node */
135Boolean allPrecious; /* .PRECIOUS given on line by itself */ 135Boolean allPrecious; /* .PRECIOUS given on line by itself */
136Boolean deleteOnError; /* .DELETE_ON_ERROR: set */ 136Boolean deleteOnError; /* .DELETE_ON_ERROR: set */
137 137
138static Boolean noBuiltins; /* -r flag */ 
139static StringList * makefiles; /* ordered list of makefiles to read */ 
140static int printVars; /* -[vV] argument */ 
141#define COMPAT_VARS 1 
142#define EXPAND_VARS 2 
143static StringList * variables; /* list of variables to print 
144 * (for -v and -V) */ 
145int maxJobs; /* -j argument */ 
146static int maxJobTokens; /* -j argument */ 138static int maxJobTokens; /* -j argument */
147Boolean compatMake; /* -B argument */ 
148DebugFlags debug; /* -d argument */ 
149Boolean debugVflag; /* -dV */ 139Boolean debugVflag; /* -dV */
150Boolean noExecute; /* -n flag */ 
151Boolean noRecursiveExecute; /* -N flag */ 
152Boolean keepgoing; /* -k flag */ 
153Boolean queryFlag; /* -q flag */ 
154Boolean touchFlag; /* -t flag */ 
155Boolean enterFlag; /* -w flag */ 
156Boolean enterFlagObj; /* -w and objdir != srcdir */ 140Boolean enterFlagObj; /* -w and objdir != srcdir */
157Boolean ignoreErrors; /* -i flag */ 141
158Boolean beSilent; /* -s flag */ 
159Boolean oldVars; /* variable substitution style */ 142Boolean oldVars; /* variable substitution style */
160Boolean checkEnvFirst; /* -e flag */ 
161Boolean parseWarnFatal; /* -W flag */ 
162static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */ 143static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
163Boolean varNoExportEnv; /* -X flag */ 
164Boolean doing_depend; /* Set while reading .depend */ 144Boolean doing_depend; /* Set while reading .depend */
165static Boolean jobsRunning; /* TRUE if the jobs might be running */ 145static Boolean jobsRunning; /* TRUE if the jobs might be running */
166static const char * tracefile; 146static const char * tracefile;
167static int ReadMakefile(const char *); 147static int ReadMakefile(const char *);
168static void usage(void) MAKE_ATTR_DEAD; 148static void usage(void) MAKE_ATTR_DEAD;
169static void purge_cached_realpaths(void); 149static void purge_cached_realpaths(void);
170 150
171static Boolean ignorePWD; /* if we use -C, PWD is meaningless */ 151static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
172static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */ 152static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
173char curdir[MAXPATHLEN + 1]; /* Startup directory */ 153char curdir[MAXPATHLEN + 1]; /* Startup directory */
174char *progname; /* the program name */ 154char *progname; /* the program name */
175char *makeDependfile; 155char *makeDependfile;
176pid_t myPid; 156pid_t myPid;
177int makelevel; 157int makelevel;
178 158
179FILE *debug_file; 
180 
181Boolean forceJobs = FALSE; 159Boolean forceJobs = FALSE;
182 160
183extern SearchPath *parseIncPath; 161extern SearchPath *parseIncPath;
184 162
185/* 163/*
186 * For compatibility with the POSIX version of MAKEFLAGS that includes 164 * For compatibility with the POSIX version of MAKEFLAGS that includes
187 * all the options with out -, convert flags to -f -l -a -g -s. 165 * all the options with out -, convert flags to -f -l -a -g -s.
188 */ 166 */
189static char * 167static char *
190explode(const char *flags) 168explode(const char *flags)
191{ 169{
192 size_t len; 170 size_t len;
193 char *nf, *st; 171 char *nf, *st;
@@ -211,162 +189,162 @@ explode(const char *flags) @@ -211,162 +189,162 @@ explode(const char *flags)
211 *nf++ = ' '; 189 *nf++ = ' ';
212 } 190 }
213 *nf = '\0'; 191 *nf = '\0';
214 return st; 192 return st;
215} 193}
216 194
217static void 195static void
218parse_debug_option_F(const char *modules) 196parse_debug_option_F(const char *modules)
219{ 197{
220 const char *mode; 198 const char *mode;
221 size_t len; 199 size_t len;
222 char *fname; 200 char *fname;
223 201
224 if (debug_file != stdout && debug_file != stderr) 202 if (opts.debug_file != stdout && opts.debug_file != stderr)
225 fclose(debug_file); 203 fclose(opts.debug_file);
226 204
227 if (*modules == '+') { 205 if (*modules == '+') {
228 modules++; 206 modules++;
229 mode = "a"; 207 mode = "a";
230 } else 208 } else
231 mode = "w"; 209 mode = "w";
232 210
233 if (strcmp(modules, "stdout") == 0) { 211 if (strcmp(modules, "stdout") == 0) {
234 debug_file = stdout; 212 opts.debug_file = stdout;
235 return; 213 return;
236 } 214 }
237 if (strcmp(modules, "stderr") == 0) { 215 if (strcmp(modules, "stderr") == 0) {
238 debug_file = stderr; 216 opts.debug_file = stderr;
239 return; 217 return;
240 } 218 }
241 219
242 len = strlen(modules); 220 len = strlen(modules);
243 fname = bmake_malloc(len + 20); 221 fname = bmake_malloc(len + 20);
244 memcpy(fname, modules, len + 1); 222 memcpy(fname, modules, len + 1);
245 223
246 /* Let the filename be modified by the pid */ 224 /* Let the filename be modified by the pid */
247 if (strcmp(fname + len - 3, ".%d") == 0) 225 if (strcmp(fname + len - 3, ".%d") == 0)
248 snprintf(fname + len - 2, 20, "%d", getpid()); 226 snprintf(fname + len - 2, 20, "%d", getpid());
249 227
250 debug_file = fopen(fname, mode); 228 opts.debug_file = fopen(fname, mode);
251 if (!debug_file) { 229 if (!opts.debug_file) {
252 fprintf(stderr, "Cannot open debug file %s\n", 230 fprintf(stderr, "Cannot open debug file %s\n",
253 fname); 231 fname);
254 usage(); 232 usage();
255 } 233 }
256 free(fname); 234 free(fname);
257} 235}
258 236
259static void 237static void
260parse_debug_options(const char *argvalue) 238parse_debug_options(const char *argvalue)
261{ 239{
262 const char *modules; 240 const char *modules;
263 241
264 for (modules = argvalue; *modules; ++modules) { 242 for (modules = argvalue; *modules; ++modules) {
265 switch (*modules) { 243 switch (*modules) {
266 case '0': /* undocumented, only intended for tests */ 244 case '0': /* undocumented, only intended for tests */
267 debug &= DEBUG_LINT; 245 opts.debug &= DEBUG_LINT;
268 break; 246 break;
269 case 'A': 247 case 'A':
270 debug = ~(0|DEBUG_LINT); 248 opts.debug = ~(0|DEBUG_LINT);
271 break; 249 break;
272 case 'a': 250 case 'a':
273 debug |= DEBUG_ARCH; 251 opts.debug |= DEBUG_ARCH;
274 break; 252 break;
275 case 'C': 253 case 'C':
276 debug |= DEBUG_CWD; 254 opts.debug |= DEBUG_CWD;
277 break; 255 break;
278 case 'c': 256 case 'c':
279 debug |= DEBUG_COND; 257 opts.debug |= DEBUG_COND;
280 break; 258 break;
281 case 'd': 259 case 'd':
282 debug |= DEBUG_DIR; 260 opts.debug |= DEBUG_DIR;
283 break; 261 break;
284 case 'e': 262 case 'e':
285 debug |= DEBUG_ERROR; 263 opts.debug |= DEBUG_ERROR;
286 break; 264 break;
287 case 'f': 265 case 'f':
288 debug |= DEBUG_FOR; 266 opts.debug |= DEBUG_FOR;
289 break; 267 break;
290 case 'g': 268 case 'g':
291 if (modules[1] == '1') { 269 if (modules[1] == '1') {
292 debug |= DEBUG_GRAPH1; 270 opts.debug |= DEBUG_GRAPH1;
293 ++modules; 271 ++modules;
294 } 272 }
295 else if (modules[1] == '2') { 273 else if (modules[1] == '2') {
296 debug |= DEBUG_GRAPH2; 274 opts.debug |= DEBUG_GRAPH2;
297 ++modules; 275 ++modules;
298 } 276 }
299 else if (modules[1] == '3') { 277 else if (modules[1] == '3') {
300 debug |= DEBUG_GRAPH3; 278 opts.debug |= DEBUG_GRAPH3;
301 ++modules; 279 ++modules;
302 } 280 }
303 break; 281 break;
304 case 'h': 282 case 'h':
305 debug |= DEBUG_HASH; 283 opts.debug |= DEBUG_HASH;
306 break; 284 break;
307 case 'j': 285 case 'j':
308 debug |= DEBUG_JOB; 286 opts.debug |= DEBUG_JOB;
309 break; 287 break;
310 case 'L': 288 case 'L':
311 debug |= DEBUG_LINT; 289 opts.debug |= DEBUG_LINT;
312 break; 290 break;
313 case 'l': 291 case 'l':
314 debug |= DEBUG_LOUD; 292 opts.debug |= DEBUG_LOUD;
315 break; 293 break;
316 case 'M': 294 case 'M':
317 debug |= DEBUG_META; 295 opts.debug |= DEBUG_META;
318 break; 296 break;
319 case 'm': 297 case 'm':
320 debug |= DEBUG_MAKE; 298 opts.debug |= DEBUG_MAKE;
321 break; 299 break;
322 case 'n': 300 case 'n':
323 debug |= DEBUG_SCRIPT; 301 opts.debug |= DEBUG_SCRIPT;
324 break; 302 break;
325 case 'p': 303 case 'p':
326 debug |= DEBUG_PARSE; 304 opts.debug |= DEBUG_PARSE;
327 break; 305 break;
328 case 's': 306 case 's':
329 debug |= DEBUG_SUFF; 307 opts.debug |= DEBUG_SUFF;
330 break; 308 break;
331 case 't': 309 case 't':
332 debug |= DEBUG_TARG; 310 opts.debug |= DEBUG_TARG;
333 break; 311 break;
334 case 'V': 312 case 'V':
335 debugVflag = TRUE; 313 debugVflag = TRUE;
336 break; 314 break;
337 case 'v': 315 case 'v':
338 debug |= DEBUG_VAR; 316 opts.debug |= DEBUG_VAR;
339 break; 317 break;
340 case 'x': 318 case 'x':
341 debug |= DEBUG_SHELL; 319 opts.debug |= DEBUG_SHELL;
342 break; 320 break;
343 case 'F': 321 case 'F':
344 parse_debug_option_F(modules + 1); 322 parse_debug_option_F(modules + 1);
345 goto debug_setbuf; 323 goto debug_setbuf;
346 default: 324 default:
347 (void)fprintf(stderr, 325 (void)fprintf(stderr,
348 "%s: illegal argument to d option -- %c\n", 326 "%s: illegal argument to d option -- %c\n",
349 progname, *modules); 327 progname, *modules);
350 usage(); 328 usage();
351 } 329 }
352 } 330 }
353debug_setbuf: 331debug_setbuf:
354 /* 332 /*
355 * Make the debug_file unbuffered, and make 333 * Make the debug_file unbuffered, and make
356 * stdout line buffered (unless debugfile == stdout). 334 * stdout line buffered (unless debugfile == stdout).
357 */ 335 */
358 setvbuf(debug_file, NULL, _IONBF, 0); 336 setvbuf(opts.debug_file, NULL, _IONBF, 0);
359 if (debug_file != stdout) { 337 if (opts.debug_file != stdout) {
360 setvbuf(stdout, NULL, _IOLBF, 0); 338 setvbuf(stdout, NULL, _IOLBF, 0);
361 } 339 }
362} 340}
363 341
364/* 342/*
365 * does path contain any relative components 343 * does path contain any relative components
366 */ 344 */
367static Boolean 345static Boolean
368is_relpath(const char *path) 346is_relpath(const char *path)
369{ 347{
370 const char *cp; 348 const char *cp;
371 349
372 if (path[0] != '/') 350 if (path[0] != '/')
@@ -416,179 +394,180 @@ MainParseArgJobsInternal(const char *arg @@ -416,179 +394,180 @@ MainParseArgJobsInternal(const char *arg
416 progname, argvalue); 394 progname, argvalue);
417 usage(); 395 usage();
418 } 396 }
419 if ((fcntl(jp_0, F_GETFD, 0) < 0) || 397 if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
420 (fcntl(jp_1, F_GETFD, 0) < 0)) { 398 (fcntl(jp_1, F_GETFD, 0) < 0)) {
421#if 0 399#if 0
422 (void)fprintf(stderr, 400 (void)fprintf(stderr,
423 "%s: ###### warning -- J descriptors were closed!\n", 401 "%s: ###### warning -- J descriptors were closed!\n",
424 progname); 402 progname);
425 exit(2); 403 exit(2);
426#endif 404#endif
427 jp_0 = -1; 405 jp_0 = -1;
428 jp_1 = -1; 406 jp_1 = -1;
429 compatMake = TRUE; 407 opts.compatMake = TRUE;
430 } else { 408 } else {
431 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); 409 Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
432 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 410 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
433 } 411 }
434} 412}
435 413
436static void 414static void
437MainParseArgJobs(const char *argvalue) 415MainParseArgJobs(const char *argvalue)
438{ 416{
439 char *p; 417 char *p;
440 418
441 forceJobs = TRUE; 419 forceJobs = TRUE;
442 maxJobs = (int)strtol(argvalue, &p, 0); 420 opts.maxJobs = (int)strtol(argvalue, &p, 0);
443 if (*p != '\0' || maxJobs < 1) { 421 if (*p != '\0' || opts.maxJobs < 1) {
444 (void)fprintf(stderr, 422 (void)fprintf(stderr,
445 "%s: illegal argument to -j -- must be positive integer!\n", 423 "%s: illegal argument to -j -- must be positive integer!\n",
446 progname); 424 progname);
447 exit(1); /* XXX: why not 2? */ 425 exit(1); /* XXX: why not 2? */
448 } 426 }
449 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); 427 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
450 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 428 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
451 Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL); 429 Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL);
452 maxJobTokens = maxJobs; 430 maxJobTokens = opts.maxJobs;
453} 431}
454 432
455static void 433static void
456MainParseArgSysInc(const char *argvalue) 434MainParseArgSysInc(const char *argvalue)
457{ 435{
458 /* look for magic parent directory search string */ 436 /* look for magic parent directory search string */
459 if (strncmp(".../", argvalue, 4) == 0) { 437 if (strncmp(".../", argvalue, 4) == 0) {
460 char *found_path = Dir_FindHereOrAbove(curdir, argvalue + 4); 438 char *found_path = Dir_FindHereOrAbove(curdir, argvalue + 4);
461 if (found_path == NULL) 439 if (found_path == NULL)
462 return; 440 return;
463 (void)Dir_AddDir(sysIncPath, found_path); 441 (void)Dir_AddDir(sysIncPath, found_path);
464 free(found_path); 442 free(found_path);
465 } else { 443 } else {
466 (void)Dir_AddDir(sysIncPath, argvalue); 444 (void)Dir_AddDir(sysIncPath, argvalue);
467 } 445 }
468 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL); 446 Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
469 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 447 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
470} 448}
471 449
472static Boolean 450static Boolean
473MainParseArg(char c, const char *argvalue) 451MainParseArg(char c, const char *argvalue)
474{ 452{
475 switch (c) { 453 switch (c) {
476 case '\0': 454 case '\0':
477 break; 455 break;
478 case 'B': 456 case 'B':
479 compatMake = TRUE; 457 opts.compatMake = TRUE;
480 Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL); 458 Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
481 Var_Set(MAKE_MODE, "compat", VAR_GLOBAL); 459 Var_Set(MAKE_MODE, "compat", VAR_GLOBAL);
482 break; 460 break;
483 case 'C': 461 case 'C':
484 MainParseArgChdir(argvalue); 462 MainParseArgChdir(argvalue);
485 break; 463 break;
486 case 'D': 464 case 'D':
487 if (argvalue[0] == '\0') return FALSE; 465 if (argvalue[0] == '\0') return FALSE;
488 Var_Set(argvalue, "1", VAR_GLOBAL); 466 Var_Set(argvalue, "1", VAR_GLOBAL);
489 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL); 467 Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
490 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 468 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
491 break; 469 break;
492 case 'I': 470 case 'I':
493 Parse_AddIncludeDir(argvalue); 471 Parse_AddIncludeDir(argvalue);
494 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL); 472 Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
495 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 473 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
496 break; 474 break;
497 case 'J': 475 case 'J':
498 MainParseArgJobsInternal(argvalue); 476 MainParseArgJobsInternal(argvalue);
499 break; 477 break;
500 case 'N': 478 case 'N':
501 noExecute = TRUE; 479 opts.noExecute = TRUE;
502 noRecursiveExecute = TRUE; 480 opts.noRecursiveExecute = TRUE;
503 Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL); 481 Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
504 break; 482 break;
505 case 'S': 483 case 'S':
506 keepgoing = FALSE; 484 opts.keepgoing = FALSE;
507 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL); 485 Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
508 break; 486 break;
509 case 'T': 487 case 'T':
510 tracefile = bmake_strdup(argvalue); 488 tracefile = bmake_strdup(argvalue);
511 Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL); 489 Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
512 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 490 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
513 break; 491 break;
514 case 'V': 492 case 'V':
515 case 'v': 493 case 'v':
516 printVars = c == 'v' ? EXPAND_VARS : COMPAT_VARS; 494 opts.printVars = c == 'v' ? EXPAND_VARS : COMPAT_VARS;
517 Lst_Append(variables, bmake_strdup(argvalue)); 495 Lst_Append(opts.variables, bmake_strdup(argvalue));
 496 /* XXX: Why always -V? */
518 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); 497 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
519 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 498 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
520 break; 499 break;
521 case 'W': 500 case 'W':
522 parseWarnFatal = TRUE; 501 opts.parseWarnFatal = TRUE;
523 break; 502 break;
524 case 'X': 503 case 'X':
525 varNoExportEnv = TRUE; 504 opts.varNoExportEnv = TRUE;
526 Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL); 505 Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
527 break; 506 break;
528 case 'd': 507 case 'd':
529 /* If '-d-opts' don't pass to children */ 508 /* If '-d-opts' don't pass to children */
530 if (argvalue[0] == '-') 509 if (argvalue[0] == '-')
531 argvalue++; 510 argvalue++;
532 else { 511 else {
533 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL); 512 Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
534 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL); 513 Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
535 } 514 }
536 parse_debug_options(argvalue); 515 parse_debug_options(argvalue);
537 break; 516 break;
538 case 'e': 517 case 'e':
539 checkEnvFirst = TRUE; 518 opts.checkEnvFirst = TRUE;
540 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL); 519 Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
541 break; 520 break;
542 case 'f': 521 case 'f':
543 Lst_Append(makefiles, bmake_strdup(argvalue)); 522 Lst_Append(opts.makefiles, bmake_strdup(argvalue));
544 break; 523 break;
545 case 'i': 524 case 'i':
546 ignoreErrors = TRUE; 525 opts.ignoreErrors = TRUE;
547 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL); 526 Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
548 break; 527 break;
549 case 'j': 528 case 'j':
550 MainParseArgJobs(argvalue); 529 MainParseArgJobs(argvalue);
551 break; 530 break;
552 case 'k': 531 case 'k':
553 keepgoing = TRUE; 532 opts.keepgoing = TRUE;
554 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL); 533 Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
555 break; 534 break;
556 case 'm': 535 case 'm':
557 MainParseArgSysInc(argvalue); 536 MainParseArgSysInc(argvalue);
558 break; 537 break;
559 case 'n': 538 case 'n':
560 noExecute = TRUE; 539 opts.noExecute = TRUE;
561 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL); 540 Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
562 break; 541 break;
563 case 'q': 542 case 'q':
564 queryFlag = TRUE; 543 opts.queryFlag = TRUE;
565 /* Kind of nonsensical, wot? */ 544 /* Kind of nonsensical, wot? */
566 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); 545 Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
567 break; 546 break;
568 case 'r': 547 case 'r':
569 noBuiltins = TRUE; 548 opts.noBuiltins = TRUE;
570 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL); 549 Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
571 break; 550 break;
572 case 's': 551 case 's':
573 beSilent = TRUE; 552 opts.beSilent = TRUE;
574 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL); 553 Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
575 break; 554 break;
576 case 't': 555 case 't':
577 touchFlag = TRUE; 556 opts.touchFlag = TRUE;
578 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); 557 Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
579 break; 558 break;
580 case 'w': 559 case 'w':
581 enterFlag = TRUE; 560 opts.enterFlag = TRUE;
582 Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL); 561 Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
583 break; 562 break;
584 default: 563 default:
585 case '?': 564 case '?':
586 usage(); 565 usage();
587 } 566 }
588 return TRUE; 567 return TRUE;
589} 568}
590 569
591/* Parse the given arguments. Called from main() and from 570/* Parse the given arguments. Called from main() and from
592 * Main_ParseArgLine() when the .MAKEFLAGS target is used. 571 * Main_ParseArgLine() when the .MAKEFLAGS target is used.
593 * 572 *
594 * The arguments must be treated as read-only and will be freed after the 573 * The arguments must be treated as read-only and will be freed after the
@@ -667,27 +646,27 @@ rearg: @@ -667,27 +646,27 @@ rearg:
667 * See if the rest of the arguments are variable assignments and 646 * See if the rest of the arguments are variable assignments and
668 * perform them if so. Else take them to be targets and stuff them 647 * perform them if so. Else take them to be targets and stuff them
669 * on the end of the "create" list. 648 * on the end of the "create" list.
670 */ 649 */
671 for (; argc > 1; ++argv, --argc) { 650 for (; argc > 1; ++argv, --argc) {
672 VarAssign var; 651 VarAssign var;
673 if (Parse_IsVar(argv[1], &var)) { 652 if (Parse_IsVar(argv[1], &var)) {
674 Parse_DoVar(&var, VAR_CMD); 653 Parse_DoVar(&var, VAR_CMD);
675 } else { 654 } else {
676 if (!*argv[1]) 655 if (!*argv[1])
677 Punt("illegal (null) argument."); 656 Punt("illegal (null) argument.");
678 if (*argv[1] == '-' && !dashDash) 657 if (*argv[1] == '-' && !dashDash)
679 goto rearg; 658 goto rearg;
680 Lst_Append(create, bmake_strdup(argv[1])); 659 Lst_Append(opts.create, bmake_strdup(argv[1]));
681 } 660 }
682 } 661 }
683 662
684 return; 663 return;
685noarg: 664noarg:
686 (void)fprintf(stderr, "%s: option requires an argument -- %c\n", 665 (void)fprintf(stderr, "%s: option requires an argument -- %c\n",
687 progname, c); 666 progname, c);
688 usage(); 667 usage();
689} 668}
690 669
691/* Break a line of arguments into words and parse them. 670/* Break a line of arguments into words and parse them.
692 * 671 *
693 * Used when a .MFLAGS or .MAKEFLAGS target is encountered during parsing and 672 * Used when a .MFLAGS or .MAKEFLAGS target is encountered during parsing and
@@ -743,27 +722,27 @@ Main_SetObjdir(const char *fmt, ...) @@ -743,27 +722,27 @@ Main_SetObjdir(const char *fmt, ...)
743 722
744 /* look for the directory and try to chdir there */ 723 /* look for the directory and try to chdir there */
745 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 724 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
746 if (chdir(path)) { 725 if (chdir(path)) {
747 (void)fprintf(stderr, "make warning: %s: %s.\n", 726 (void)fprintf(stderr, "make warning: %s: %s.\n",
748 path, strerror(errno)); 727 path, strerror(errno));
749 } else { 728 } else {
750 snprintf(objdir, sizeof objdir, "%s", path); 729 snprintf(objdir, sizeof objdir, "%s", path);
751 Var_Set(".OBJDIR", objdir, VAR_GLOBAL); 730 Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
752 setenv("PWD", objdir, 1); 731 setenv("PWD", objdir, 1);
753 Dir_InitDot(); 732 Dir_InitDot();
754 purge_cached_realpaths(); 733 purge_cached_realpaths();
755 rc = TRUE; 734 rc = TRUE;
756 if (enterFlag && strcmp(objdir, curdir) != 0) 735 if (opts.enterFlag && strcmp(objdir, curdir) != 0)
757 enterFlagObj = TRUE; 736 enterFlagObj = TRUE;
758 } 737 }
759 } 738 }
760 739
761 return rc; 740 return rc;
762} 741}
763 742
764static Boolean 743static Boolean
765Main_SetVarObjdir(const char *var, const char *suffix) 744Main_SetVarObjdir(const char *var, const char *suffix)
766{ 745{
767 char *path_freeIt; 746 char *path_freeIt;
768 const char *path = Var_Value(var, VAR_CMD, &path_freeIt); 747 const char *path = Var_Value(var, VAR_CMD, &path_freeIt);
769 const char *xpath; 748 const char *xpath;
@@ -837,27 +816,27 @@ void @@ -837,27 +816,27 @@ void
837MakeMode(const char *mode) 816MakeMode(const char *mode)
838{ 817{
839 char *mode_freeIt = NULL; 818 char *mode_freeIt = NULL;
840 819
841 if (mode == NULL) { 820 if (mode == NULL) {
842 (void)Var_Subst("${" MAKE_MODE ":tl}", 821 (void)Var_Subst("${" MAKE_MODE ":tl}",
843 VAR_GLOBAL, VARE_WANTRES, &mode_freeIt); 822 VAR_GLOBAL, VARE_WANTRES, &mode_freeIt);
844 /* TODO: handle errors */ 823 /* TODO: handle errors */
845 mode = mode_freeIt; 824 mode = mode_freeIt;
846 } 825 }
847 826
848 if (mode[0] != '\0') { 827 if (mode[0] != '\0') {
849 if (strstr(mode, "compat")) { 828 if (strstr(mode, "compat")) {
850 compatMake = TRUE; 829 opts.compatMake = TRUE;
851 forceJobs = FALSE; 830 forceJobs = FALSE;
852 } 831 }
853#if USE_META 832#if USE_META
854 if (strstr(mode, "meta")) 833 if (strstr(mode, "meta"))
855 meta_mode_init(mode); 834 meta_mode_init(mode);
856#endif 835#endif
857 } 836 }
858 837
859 free(mode_freeIt); 838 free(mode_freeIt);
860} 839}
861 840
862static void 841static void
863PrintVar(const char *varname, Boolean expandVars) 842PrintVar(const char *varname, Boolean expandVars)
@@ -882,65 +861,65 @@ PrintVar(const char *varname, Boolean ex @@ -882,65 +861,65 @@ PrintVar(const char *varname, Boolean ex
882 char *freeIt; 861 char *freeIt;
883 const char *value = Var_Value(varname, VAR_GLOBAL, &freeIt); 862 const char *value = Var_Value(varname, VAR_GLOBAL, &freeIt);
884 printf("%s\n", value ? value : ""); 863 printf("%s\n", value ? value : "");
885 bmake_free(freeIt); 864 bmake_free(freeIt);
886 } 865 }
887} 866}
888 867
889static void 868static void
890doPrintVars(void) 869doPrintVars(void)
891{ 870{
892 StringListNode *ln; 871 StringListNode *ln;
893 Boolean expandVars; 872 Boolean expandVars;
894 873
895 if (printVars == EXPAND_VARS) 874 if (opts.printVars == EXPAND_VARS)
896 expandVars = TRUE; 875 expandVars = TRUE;
897 else if (debugVflag) 876 else if (debugVflag)
898 expandVars = FALSE; 877 expandVars = FALSE;
899 else 878 else
900 expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE); 879 expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
901 880
902 for (ln = variables->first; ln != NULL; ln = ln->next) { 881 for (ln = opts.variables->first; ln != NULL; ln = ln->next) {
903 const char *varname = ln->datum; 882 const char *varname = ln->datum;
904 PrintVar(varname, expandVars); 883 PrintVar(varname, expandVars);
905 } 884 }
906} 885}
907 886
908static Boolean 887static Boolean
909runTargets(void) 888runTargets(void)
910{ 889{
911 GNodeList *targs; /* target nodes to create -- passed to Make_Init */ 890 GNodeList *targs; /* target nodes to create -- passed to Make_Init */
912 Boolean outOfDate; /* FALSE if all targets up to date */ 891 Boolean outOfDate; /* FALSE if all targets up to date */
913 892
914 /* 893 /*
915 * Have now read the entire graph and need to make a list of 894 * Have now read the entire graph and need to make a list of
916 * targets to create. If none was given on the command line, 895 * targets to create. If none was given on the command line,
917 * we consult the parsing module to find the main target(s) 896 * we consult the parsing module to find the main target(s)
918 * to create. 897 * to create.
919 */ 898 */
920 if (Lst_IsEmpty(create)) 899 if (Lst_IsEmpty(opts.create))
921 targs = Parse_MainName(); 900 targs = Parse_MainName();
922 else 901 else
923 targs = Targ_FindList(create); 902 targs = Targ_FindList(opts.create);
924 903
925 if (!compatMake) { 904 if (!opts.compatMake) {
926 /* 905 /*
927 * Initialize job module before traversing the graph 906 * Initialize job module before traversing the graph
928 * now that any .BEGIN and .END targets have been read. 907 * now that any .BEGIN and .END targets have been read.
929 * This is done only if the -q flag wasn't given 908 * This is done only if the -q flag wasn't given
930 * (to prevent the .BEGIN from being executed should 909 * (to prevent the .BEGIN from being executed should
931 * it exist). 910 * it exist).
932 */ 911 */
933 if (!queryFlag) { 912 if (!opts.queryFlag) {
934 Job_Init(); 913 Job_Init();
935 jobsRunning = TRUE; 914 jobsRunning = TRUE;
936 } 915 }
937 916
938 /* Traverse the graph, checking on all the targets */ 917 /* Traverse the graph, checking on all the targets */
939 outOfDate = Make_Run(targs); 918 outOfDate = Make_Run(targs);
940 } else { 919 } else {
941 /* 920 /*
942 * Compat_Init will take care of creating all the 921 * Compat_Init will take care of creating all the
943 * targets as well as initializing the module. 922 * targets as well as initializing the module.
944 */ 923 */
945 Compat_Run(targs); 924 Compat_Run(targs);
946 outOfDate = FALSE; 925 outOfDate = FALSE;
@@ -949,32 +928,32 @@ runTargets(void) @@ -949,32 +928,32 @@ runTargets(void)
949 return outOfDate; 928 return outOfDate;
950} 929}
951 930
952/* 931/*
953 * Set up the .TARGETS variable to contain the list of targets to be 932 * Set up the .TARGETS variable to contain the list of targets to be
954 * created. If none specified, make the variable empty -- the parser 933 * created. If none specified, make the variable empty -- the parser
955 * will fill the thing in with the default or .MAIN target. 934 * will fill the thing in with the default or .MAIN target.
956 */ 935 */
957static void 936static void
958InitVarTargets(void) 937InitVarTargets(void)
959{ 938{
960 StringListNode *ln; 939 StringListNode *ln;
961 940
962 if (Lst_IsEmpty(create)) { 941 if (Lst_IsEmpty(opts.create)) {
963 Var_Set(".TARGETS", "", VAR_GLOBAL); 942 Var_Set(".TARGETS", "", VAR_GLOBAL);
964 return; 943 return;
965 } 944 }
966 945
967 for (ln = create->first; ln != NULL; ln = ln->next) { 946 for (ln = opts.create->first; ln != NULL; ln = ln->next) {
968 char *name = ln->datum; 947 char *name = ln->datum;
969 Var_Append(".TARGETS", name, VAR_GLOBAL); 948 Var_Append(".TARGETS", name, VAR_GLOBAL);
970 } 949 }
971} 950}
972 951
973static const char * 952static const char *
974init_machine(const struct utsname *utsname) 953init_machine(const struct utsname *utsname)
975{ 954{
976 const char *machine = getenv("MACHINE"); 955 const char *machine = getenv("MACHINE");
977 if (machine != NULL) 956 if (machine != NULL)
978 return machine; 957 return machine;
979 958
980#ifdef MAKE_NATIVE 959#ifdef MAKE_NATIVE
@@ -1093,27 +1072,27 @@ main(int argc, char **argv) @@ -1093,27 +1072,27 @@ main(int argc, char **argv)
1093 char *p1, *path; 1072 char *p1, *path;
1094 char mdpath[MAXPATHLEN]; 1073 char mdpath[MAXPATHLEN];
1095 const char *machine; 1074 const char *machine;
1096 const char *machine_arch; 1075 const char *machine_arch;
1097 char *syspath = getenv("MAKESYSPATH"); 1076 char *syspath = getenv("MAKESYSPATH");
1098 StringList *sysMkPath; /* Path of sys.mk */ 1077 StringList *sysMkPath; /* Path of sys.mk */
1099 char *cp = NULL, *start; 1078 char *cp = NULL, *start;
1100 /* avoid faults on read-only strings */ 1079 /* avoid faults on read-only strings */
1101 static char defsyspath[] = _PATH_DEFSYSPATH; 1080 static char defsyspath[] = _PATH_DEFSYSPATH;
1102 struct timeval rightnow; /* to initialize random seed */ 1081 struct timeval rightnow; /* to initialize random seed */
1103 struct utsname utsname; 1082 struct utsname utsname;
1104 1083
1105 /* default to writing debug to stderr */ 1084 /* default to writing debug to stderr */
1106 debug_file = stderr; 1085 opts.debug_file = stderr;
1107 1086
1108#ifdef SIGINFO 1087#ifdef SIGINFO
1109 (void)bmake_signal(SIGINFO, siginfo); 1088 (void)bmake_signal(SIGINFO, siginfo);
1110#endif 1089#endif
1111 /* 1090 /*
1112 * Set the seed to produce a different random sequence 1091 * Set the seed to produce a different random sequence
1113 * on each program execution. 1092 * on each program execution.
1114 */ 1093 */
1115 gettimeofday(&rightnow, NULL); 1094 gettimeofday(&rightnow, NULL);
1116 srandom((unsigned int)(rightnow.tv_sec + rightnow.tv_usec)); 1095 srandom((unsigned int)(rightnow.tv_sec + rightnow.tv_usec));
1117 1096
1118 if ((progname = strrchr(argv[0], '/')) != NULL) 1097 if ((progname = strrchr(argv[0], '/')) != NULL)
1119 progname++; 1098 progname++;
@@ -1164,47 +1143,47 @@ main(int argc, char **argv) @@ -1164,47 +1143,47 @@ main(int argc, char **argv)
1164 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL); 1143 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);
1165#endif 1144#endif
1166 Var_Set(".newline", "\n", VAR_GLOBAL); /* handy for :@ loops */ 1145 Var_Set(".newline", "\n", VAR_GLOBAL); /* handy for :@ loops */
1167 /* 1146 /*
1168 * This is the traditional preference for makefiles. 1147 * This is the traditional preference for makefiles.
1169 */ 1148 */
1170#ifndef MAKEFILE_PREFERENCE_LIST 1149#ifndef MAKEFILE_PREFERENCE_LIST
1171# define MAKEFILE_PREFERENCE_LIST "makefile Makefile" 1150# define MAKEFILE_PREFERENCE_LIST "makefile Makefile"
1172#endif 1151#endif
1173 Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST, 1152 Var_Set(MAKEFILE_PREFERENCE, MAKEFILE_PREFERENCE_LIST,
1174 VAR_GLOBAL); 1153 VAR_GLOBAL);
1175 Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL); 1154 Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL);
1176 1155
1177 create = Lst_New(); 1156 opts.create = Lst_New();
1178 makefiles = Lst_New(); 1157 opts.makefiles = Lst_New();
1179 printVars = 0; 1158 opts.printVars = 0;
1180 debugVflag = FALSE; 1159 debugVflag = FALSE;
1181 variables = Lst_New(); 1160 opts.variables = Lst_New();
1182 beSilent = FALSE; /* Print commands as executed */ 1161 opts.beSilent = FALSE; /* Print commands as executed */
1183 ignoreErrors = FALSE; /* Pay attention to non-zero returns */ 1162 opts.ignoreErrors = FALSE; /* Pay attention to non-zero returns */
1184 noExecute = FALSE; /* Execute all commands */ 1163 opts.noExecute = FALSE; /* Execute all commands */
1185 noRecursiveExecute = FALSE; /* Execute all .MAKE targets */ 1164 opts.noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
1186 keepgoing = FALSE; /* Stop on error */ 1165 opts.keepgoing = FALSE; /* Stop on error */
1187 allPrecious = FALSE; /* Remove targets when interrupted */ 1166 allPrecious = FALSE; /* Remove targets when interrupted */
1188 deleteOnError = FALSE; /* Historical default behavior */ 1167 deleteOnError = FALSE; /* Historical default behavior */
1189 queryFlag = FALSE; /* This is not just a check-run */ 1168 opts.queryFlag = FALSE; /* This is not just a check-run */
1190 noBuiltins = FALSE; /* Read the built-in rules */ 1169 opts.noBuiltins = FALSE; /* Read the built-in rules */
1191 touchFlag = FALSE; /* Actually update targets */ 1170 opts.touchFlag = FALSE; /* Actually update targets */
1192 debug = 0; /* No debug verbosity, please. */ 1171 opts.debug = 0; /* No debug verbosity, please. */
1193 jobsRunning = FALSE; 1172 jobsRunning = FALSE;
1194 1173
1195 maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */ 1174 opts.maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */
1196 maxJobTokens = maxJobs; 1175 maxJobTokens = opts.maxJobs;
1197 compatMake = FALSE; /* No compat mode */ 1176 opts.compatMake = FALSE; /* No compat mode */
1198 ignorePWD = FALSE; 1177 ignorePWD = FALSE;
1199 1178
1200 /* 1179 /*
1201 * Initialize the parsing, directory and variable modules to prepare 1180 * Initialize the parsing, directory and variable modules to prepare
1202 * for the reading of inclusion paths and variable settings on the 1181 * for the reading of inclusion paths and variable settings on the
1203 * command line 1182 * command line
1204 */ 1183 */
1205 1184
1206 /* 1185 /*
1207 * Initialize various variables. 1186 * Initialize various variables.
1208 * MAKE also gets this name, for compatibility 1187 * MAKE also gets this name, for compatibility
1209 * .MAKEFLAGS gets set to the empty string just in case. 1188 * .MAKEFLAGS gets set to the empty string just in case.
1210 * MFLAGS also gets initialized empty, for compatibility. 1189 * MFLAGS also gets initialized empty, for compatibility.
@@ -1278,27 +1257,27 @@ main(int argc, char **argv) @@ -1278,27 +1257,27 @@ main(int argc, char **argv)
1278 1257
1279 /* 1258 /*
1280 * Find where we are (now). 1259 * Find where we are (now).
1281 * We take care of PWD for the automounter below... 1260 * We take care of PWD for the automounter below...
1282 */ 1261 */
1283 if (getcwd(curdir, MAXPATHLEN) == NULL) { 1262 if (getcwd(curdir, MAXPATHLEN) == NULL) {
1284 (void)fprintf(stderr, "%s: getcwd: %s.\n", 1263 (void)fprintf(stderr, "%s: getcwd: %s.\n",
1285 progname, strerror(errno)); 1264 progname, strerror(errno));
1286 exit(2); 1265 exit(2);
1287 } 1266 }
1288 1267
1289 MainParseArgs(argc, argv); 1268 MainParseArgs(argc, argv);
1290 1269
1291 if (enterFlag) 1270 if (opts.enterFlag)
1292 printf("%s: Entering directory `%s'\n", progname, curdir); 1271 printf("%s: Entering directory `%s'\n", progname, curdir);
1293 1272
1294 /* 1273 /*
1295 * Verify that cwd is sane. 1274 * Verify that cwd is sane.
1296 */ 1275 */
1297 if (stat(curdir, &sa) == -1) { 1276 if (stat(curdir, &sa) == -1) {
1298 (void)fprintf(stderr, "%s: %s: %s.\n", 1277 (void)fprintf(stderr, "%s: %s: %s.\n",
1299 progname, curdir, strerror(errno)); 1278 progname, curdir, strerror(errno));
1300 exit(2); 1279 exit(2);
1301 } 1280 }
1302 1281
1303#ifndef NO_PWD_OVERRIDE 1282#ifndef NO_PWD_OVERRIDE
1304 HandlePWD(&sa); 1283 HandlePWD(&sa);
@@ -1366,114 +1345,115 @@ main(int argc, char **argv) @@ -1366,114 +1345,115 @@ main(int argc, char **argv)
1366 (void)Dir_AddDir(defIncPath, dir); 1345 (void)Dir_AddDir(defIncPath, dir);
1367 free(dir); 1346 free(dir);
1368 } 1347 }
1369 } 1348 }
1370 } 1349 }
1371 if (syspath != defsyspath) 1350 if (syspath != defsyspath)
1372 free(syspath); 1351 free(syspath);
1373 1352
1374 /* 1353 /*
1375 * Read in the built-in rules first, followed by the specified 1354 * Read in the built-in rules first, followed by the specified
1376 * makefiles, or the default makefile and Makefile, in that order, 1355 * makefiles, or the default makefile and Makefile, in that order,
1377 * if no makefiles were given on the command line. 1356 * if no makefiles were given on the command line.
1378 */ 1357 */
1379 if (!noBuiltins) { 1358 if (!opts.noBuiltins) {
1380 sysMkPath = Lst_New(); 1359 sysMkPath = Lst_New();
1381 Dir_Expand(_PATH_DEFSYSMK, 1360 Dir_Expand(_PATH_DEFSYSMK,
1382 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath, 1361 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
1383 sysMkPath); 1362 sysMkPath);
1384 if (Lst_IsEmpty(sysMkPath)) 1363 if (Lst_IsEmpty(sysMkPath))
1385 Fatal("%s: no system rules (%s).", progname, 1364 Fatal("%s: no system rules (%s).", progname,
1386 _PATH_DEFSYSMK); 1365 _PATH_DEFSYSMK);
1387 if (!Lst_ForEachUntil(sysMkPath, ReadMakefileSucceeded, NULL)) 1366 if (!Lst_ForEachUntil(sysMkPath, ReadMakefileSucceeded, NULL))
1388 Fatal("%s: cannot open %s.", progname, 1367 Fatal("%s: cannot open %s.", progname,
1389 (char *)sysMkPath->first->datum); 1368 (char *)sysMkPath->first->datum);
1390 } 1369 }
1391 1370
1392 if (makefiles->first != NULL) { 1371 if (opts.makefiles->first != NULL) {
1393 StringListNode *ln; 1372 StringListNode *ln;
1394 1373
1395 for (ln = makefiles->first; ln != NULL; ln = ln->next) { 1374 for (ln = opts.makefiles->first; ln != NULL; ln = ln->next) {
1396 if (ReadMakefile(ln->datum) != 0) 1375 if (ReadMakefile(ln->datum) != 0)
1397 Fatal("%s: cannot open %s.", 1376 Fatal("%s: cannot open %s.",
1398 progname, (char *)ln->datum); 1377 progname, (char *)ln->datum);
1399 } 1378 }
1400 } else { 1379 } else {
1401 (void)Var_Subst("${" MAKEFILE_PREFERENCE "}", 1380 (void)Var_Subst("${" MAKEFILE_PREFERENCE "}",
1402 VAR_CMD, VARE_WANTRES, &p1); 1381 VAR_CMD, VARE_WANTRES, &p1);
1403 /* TODO: handle errors */ 1382 /* TODO: handle errors */
1404 (void)str2Lst_Append(makefiles, p1, NULL); 1383 (void)str2Lst_Append(opts.makefiles, p1, NULL);
1405 (void)Lst_ForEachUntil(makefiles, ReadMakefileSucceeded, NULL); 1384 (void)Lst_ForEachUntil(opts.makefiles,
 1385 ReadMakefileSucceeded, NULL);
1406 free(p1); 1386 free(p1);
1407 } 1387 }
1408 1388
1409 /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */ 1389 /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
1410 if (!noBuiltins || !printVars) { 1390 if (!opts.noBuiltins || !opts.printVars) {
1411 /* ignore /dev/null and anything starting with "no" */ 1391 /* ignore /dev/null and anything starting with "no" */
1412 (void)Var_Subst("${.MAKE.DEPENDFILE:N/dev/null:Nno*:T}", 1392 (void)Var_Subst("${.MAKE.DEPENDFILE:N/dev/null:Nno*:T}",
1413 VAR_CMD, VARE_WANTRES, &makeDependfile); 1393 VAR_CMD, VARE_WANTRES, &makeDependfile);
1414 if (makeDependfile[0] != '\0') { 1394 if (makeDependfile[0] != '\0') {
1415 /* TODO: handle errors */ 1395 /* TODO: handle errors */
1416 doing_depend = TRUE; 1396 doing_depend = TRUE;
1417 (void)ReadMakefile(makeDependfile); 1397 (void)ReadMakefile(makeDependfile);
1418 doing_depend = FALSE; 1398 doing_depend = FALSE;
1419 } 1399 }
1420 } 1400 }
1421 1401
1422 if (enterFlagObj) 1402 if (enterFlagObj)
1423 printf("%s: Entering directory `%s'\n", progname, objdir); 1403 printf("%s: Entering directory `%s'\n", progname, objdir);
1424 1404
1425 MakeMode(NULL); 1405 MakeMode(NULL);
1426 1406
1427 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); 1407 Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
1428 bmake_free(p1); 1408 bmake_free(p1);
1429 1409
1430 if (!forceJobs && !compatMake && 1410 if (!forceJobs && !opts.compatMake &&
1431 Var_Exists(".MAKE.JOBS", VAR_GLOBAL)) { 1411 Var_Exists(".MAKE.JOBS", VAR_GLOBAL)) {
1432 char *value; 1412 char *value;
1433 int n; 1413 int n;
1434 1414
1435 (void)Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES, &value); 1415 (void)Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES, &value);
1436 /* TODO: handle errors */ 1416 /* TODO: handle errors */
1437 n = (int)strtol(value, NULL, 0); 1417 n = (int)strtol(value, NULL, 0);
1438 if (n < 1) { 1418 if (n < 1) {
1439 (void)fprintf(stderr, "%s: illegal value for .MAKE.JOBS -- must be positive integer!\n", 1419 (void)fprintf(stderr, "%s: illegal value for .MAKE.JOBS -- must be positive integer!\n",
1440 progname); 1420 progname);
1441 exit(1); 1421 exit(1);
1442 } 1422 }
1443 if (n != maxJobs) { 1423 if (n != opts.maxJobs) {
1444 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); 1424 Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
1445 Var_Append(MAKEFLAGS, value, VAR_GLOBAL); 1425 Var_Append(MAKEFLAGS, value, VAR_GLOBAL);
1446 } 1426 }
1447 maxJobs = n; 1427 opts.maxJobs = n;
1448 maxJobTokens = maxJobs; 1428 maxJobTokens = opts.maxJobs;
1449 forceJobs = TRUE; 1429 forceJobs = TRUE;
1450 free(value); 1430 free(value);
1451 } 1431 }
1452 1432
1453 /* 1433 /*
1454 * Be compatible if user did not specify -j and did not explicitly 1434 * Be compatible if user did not specify -j and did not explicitly
1455 * turned compatibility on 1435 * turned compatibility on
1456 */ 1436 */
1457 if (!compatMake && !forceJobs) { 1437 if (!opts.compatMake && !forceJobs) {
1458 compatMake = TRUE; 1438 opts.compatMake = TRUE;
1459 } 1439 }
1460 1440
1461 if (!compatMake) 1441 if (!opts.compatMake)
1462 Job_ServerStart(maxJobTokens, jp_0, jp_1); 1442 Job_ServerStart(maxJobTokens, jp_0, jp_1);
1463 DEBUG5(JOB, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n", 1443 DEBUG5(JOB, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
1464 jp_0, jp_1, maxJobs, maxJobTokens, compatMake ? 1 : 0); 1444 jp_0, jp_1, opts.maxJobs, maxJobTokens, opts.compatMake ? 1 : 0);
1465 1445
1466 if (!printVars) 1446 if (!opts.printVars)
1467 Main_ExportMAKEFLAGS(TRUE); /* initial export */ 1447 Main_ExportMAKEFLAGS(TRUE); /* initial export */
1468 1448
1469 1449
1470 /* 1450 /*
1471 * For compatibility, look at the directories in the VPATH variable 1451 * For compatibility, look at the directories in the VPATH variable
1472 * and add them to the search path, if the variable is defined. The 1452 * and add them to the search path, if the variable is defined. The
1473 * variable's value is in the same format as the PATH envariable, i.e. 1453 * variable's value is in the same format as the PATH envariable, i.e.
1474 * <directory>:<directory>:<directory>... 1454 * <directory>:<directory>:<directory>...
1475 */ 1455 */
1476 if (Var_Exists("VPATH", VAR_CMD)) { 1456 if (Var_Exists("VPATH", VAR_CMD)) {
1477 char *vpath, savec; 1457 char *vpath, savec;
1478 /* 1458 /*
1479 * GCC stores string constants in read-only memory, but 1459 * GCC stores string constants in read-only memory, but
@@ -1506,48 +1486,48 @@ main(int argc, char **argv) @@ -1506,48 +1486,48 @@ main(int argc, char **argv)
1506 */ 1486 */
1507 Suff_DoPaths(); 1487 Suff_DoPaths();
1508 1488
1509 /* 1489 /*
1510 * Propagate attributes through :: dependency lists. 1490 * Propagate attributes through :: dependency lists.
1511 */ 1491 */
1512 Targ_Propagate(); 1492 Targ_Propagate();
1513 1493
1514 /* print the initial graph, if the user requested it */ 1494 /* print the initial graph, if the user requested it */
1515 if (DEBUG(GRAPH1)) 1495 if (DEBUG(GRAPH1))
1516 Targ_PrintGraph(1); 1496 Targ_PrintGraph(1);
1517 1497
1518 /* print the values of any variables requested by the user */ 1498 /* print the values of any variables requested by the user */
1519 if (printVars) { 1499 if (opts.printVars) {
1520 doPrintVars(); 1500 doPrintVars();
1521 outOfDate = FALSE; 1501 outOfDate = FALSE;
1522 } else { 1502 } else {
1523 outOfDate = runTargets(); 1503 outOfDate = runTargets();
1524 } 1504 }
1525 1505
1526#ifdef CLEANUP 1506#ifdef CLEANUP
1527 Lst_Free(variables); 1507 Lst_Free(opts.variables);
1528 Lst_Free(makefiles); 1508 Lst_Free(opts.makefiles);
1529 Lst_Destroy(create, free); 1509 Lst_Destroy(opts.create, free);
1530#endif 1510#endif
1531 1511
1532 /* print the graph now it's been processed if the user requested it */ 1512 /* print the graph now it's been processed if the user requested it */
1533 if (DEBUG(GRAPH2)) 1513 if (DEBUG(GRAPH2))
1534 Targ_PrintGraph(2); 1514 Targ_PrintGraph(2);
1535 1515
1536 Trace_Log(MAKEEND, 0); 1516 Trace_Log(MAKEEND, 0);
1537 1517
1538 if (enterFlagObj) 1518 if (enterFlagObj)
1539 printf("%s: Leaving directory `%s'\n", progname, objdir); 1519 printf("%s: Leaving directory `%s'\n", progname, objdir);
1540 if (enterFlag) 1520 if (opts.enterFlag)
1541 printf("%s: Leaving directory `%s'\n", progname, curdir); 1521 printf("%s: Leaving directory `%s'\n", progname, curdir);
1542 1522
1543#ifdef USE_META 1523#ifdef USE_META
1544 meta_finish(); 1524 meta_finish();
1545#endif 1525#endif
1546 Suff_End(); 1526 Suff_End();
1547 Targ_End(); 1527 Targ_End();
1548 Arch_End(); 1528 Arch_End();
1549 Var_End(); 1529 Var_End();
1550 Parse_End(); 1530 Parse_End();
1551 Dir_End(); 1531 Dir_End();
1552 Job_End(); 1532 Job_End();
1553 Trace_End(); 1533 Trace_End();
@@ -1750,27 +1730,27 @@ bad: @@ -1750,27 +1730,27 @@ bad:
1750 return bmake_strdup(""); 1730 return bmake_strdup("");
1751} 1731}
1752 1732
1753/* Print a printf-style error message. 1733/* Print a printf-style error message.
1754 * 1734 *
1755 * This error message has no consequences, in particular it does not affect 1735 * This error message has no consequences, in particular it does not affect
1756 * the exit status. */ 1736 * the exit status. */
1757void 1737void
1758Error(const char *fmt, ...) 1738Error(const char *fmt, ...)
1759{ 1739{
1760 va_list ap; 1740 va_list ap;
1761 FILE *err_file; 1741 FILE *err_file;
1762 1742
1763 err_file = debug_file; 1743 err_file = opts.debug_file;
1764 if (err_file == stdout) 1744 if (err_file == stdout)
1765 err_file = stderr; 1745 err_file = stderr;
1766 (void)fflush(stdout); 1746 (void)fflush(stdout);
1767 for (;;) { 1747 for (;;) {
1768 va_start(ap, fmt); 1748 va_start(ap, fmt);
1769 fprintf(err_file, "%s: ", progname); 1749 fprintf(err_file, "%s: ", progname);
1770 (void)vfprintf(err_file, fmt, ap); 1750 (void)vfprintf(err_file, fmt, ap);
1771 va_end(ap); 1751 va_end(ap);
1772 (void)fprintf(err_file, "\n"); 1752 (void)fprintf(err_file, "\n");
1773 (void)fflush(err_file); 1753 (void)fflush(err_file);
1774 if (err_file == stderr) 1754 if (err_file == stderr)
1775 break; 1755 break;
1776 err_file = stderr; 1756 err_file = stderr;

cvs diff -r1.180 -r1.181 src/usr.bin/make/make.c (expand / switch to unified diff)

--- src/usr.bin/make/make.c 2020/10/25 21:51:48 1.180
+++ src/usr.bin/make/make.c 2020/10/26 21:34:10 1.181
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: make.c,v 1.180 2020/10/25 21:51:48 rillig Exp $ */ 1/* $NetBSD: make.c,v 1.181 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -97,46 +97,46 @@ @@ -97,46 +97,46 @@
97 * Make_OODate Determine if a target is out-of-date. 97 * Make_OODate Determine if a target is out-of-date.
98 * 98 *
99 * Make_HandleUse See if a child is a .USE node for a parent 99 * Make_HandleUse See if a child is a .USE node for a parent
100 * and perform the .USE actions if so. 100 * and perform the .USE actions if so.
101 * 101 *
102 * Make_ExpandUse Expand .USE nodes 102 * Make_ExpandUse Expand .USE nodes
103 */ 103 */
104 104
105#include "make.h" 105#include "make.h"
106#include "dir.h" 106#include "dir.h"
107#include "job.h" 107#include "job.h"
108 108
109/* "@(#)make.c 8.1 (Berkeley) 6/6/93" */ 109/* "@(#)make.c 8.1 (Berkeley) 6/6/93" */
110MAKE_RCSID("$NetBSD: make.c,v 1.180 2020/10/25 21:51:48 rillig Exp $"); 110MAKE_RCSID("$NetBSD: make.c,v 1.181 2020/10/26 21:34:10 rillig Exp $");
111 111
112/* Sequence # to detect recursion. */ 112/* Sequence # to detect recursion. */
113static unsigned int checked = 1; 113static unsigned int checked = 1;
114 114
115/* The current fringe of the graph. 115/* The current fringe of the graph.
116 * These are nodes which await examination by MakeOODate. 116 * These are nodes which await examination by MakeOODate.
117 * It is added to by Make_Update and subtracted from by MakeStartJobs */ 117 * It is added to by Make_Update and subtracted from by MakeStartJobs */
118static GNodeList *toBeMade; 118static GNodeList *toBeMade;
119 119
120static int MakeCheckOrder(void *, void *); 120static int MakeCheckOrder(void *, void *);
121static int MakeBuildParent(void *, void *); 121static int MakeBuildParent(void *, void *);
122 122
123void 123void
124debug_printf(const char *fmt, ...) 124debug_printf(const char *fmt, ...)
125{ 125{
126 va_list args; 126 va_list args;
127 127
128 va_start(args, fmt); 128 va_start(args, fmt);
129 vfprintf(debug_file, fmt, args); 129 vfprintf(opts.debug_file, fmt, args);
130 va_end(args); 130 va_end(args);
131} 131}
132 132
133MAKE_ATTR_DEAD static void 133MAKE_ATTR_DEAD static void
134make_abort(GNode *gn, int line) 134make_abort(GNode *gn, int line)
135{ 135{
136 debug_printf("make_abort from line %d\n", line); 136 debug_printf("make_abort from line %d\n", line);
137 Targ_PrintNode(gn, 2); 137 Targ_PrintNode(gn, 2);
138 Targ_PrintNodes(toBeMade, 2); 138 Targ_PrintNodes(toBeMade, 2);
139 Targ_PrintGraph(3); 139 Targ_PrintGraph(3);
140 abort(); 140 abort();
141} 141}
142 142
@@ -170,27 +170,27 @@ GNode_FprintDetails(FILE *f, const char  @@ -170,27 +170,27 @@ GNode_FprintDetails(FILE *f, const char
170 fprintf(f, "%smade %s, type %s, flags %s%s", 170 fprintf(f, "%smade %s, type %s, flags %s%s",
171 prefix, 171 prefix,
172 Enum_ValueToString(gn->made, GNodeMade_ToStringSpecs), 172 Enum_ValueToString(gn->made, GNodeMade_ToStringSpecs),
173 Enum_FlagsToString(type_buf, sizeof type_buf, 173 Enum_FlagsToString(type_buf, sizeof type_buf,
174 gn->type, GNodeType_ToStringSpecs), 174 gn->type, GNodeType_ToStringSpecs),
175 Enum_FlagsToString(flags_buf, sizeof flags_buf, 175 Enum_FlagsToString(flags_buf, sizeof flags_buf,
176 gn->flags, GNodeFlags_ToStringSpecs), 176 gn->flags, GNodeFlags_ToStringSpecs),
177 suffix); 177 suffix);
178} 178}
179 179
180Boolean 180Boolean
181NoExecute(GNode *gn) 181NoExecute(GNode *gn)
182{ 182{
183 return (gn->type & OP_MAKE) ? noRecursiveExecute : noExecute; 183 return (gn->type & OP_MAKE) ? opts.noRecursiveExecute : opts.noExecute;
184} 184}
185 185
186/* Update the youngest child of the node, according to the given child. */ 186/* Update the youngest child of the node, according to the given child. */
187void 187void
188Make_TimeStamp(GNode *pgn, GNode *cgn) 188Make_TimeStamp(GNode *pgn, GNode *cgn)
189{ 189{
190 if (pgn->youngestChild == NULL || cgn->mtime > pgn->youngestChild->mtime) { 190 if (pgn->youngestChild == NULL || cgn->mtime > pgn->youngestChild->mtime) {
191 pgn->youngestChild = cgn; 191 pgn->youngestChild = cgn;
192 } 192 }
193} 193}
194 194
195/* See if the node is out of date with respect to its sources. 195/* See if the node is out of date with respect to its sources.
196 * 196 *
@@ -968,27 +968,27 @@ MakeStartJobs(void) @@ -968,27 +968,27 @@ MakeStartJobs(void)
968 * We can't build this yet, add all unmade children to toBeMade, 968 * We can't build this yet, add all unmade children to toBeMade,
969 * just before the current first element. 969 * just before the current first element.
970 */ 970 */
971 gn->made = DEFERRED; 971 gn->made = DEFERRED;
972 Lst_ForEachUntil(gn->children, MakeBuildChild, toBeMade->first); 972 Lst_ForEachUntil(gn->children, MakeBuildChild, toBeMade->first);
973 /* and drop this node on the floor */ 973 /* and drop this node on the floor */
974 DEBUG2(MAKE, "dropped %s%s\n", gn->name, gn->cohort_num); 974 DEBUG2(MAKE, "dropped %s%s\n", gn->name, gn->cohort_num);
975 continue; 975 continue;
976 } 976 }
977 977
978 gn->made = BEINGMADE; 978 gn->made = BEINGMADE;
979 if (Make_OODate(gn)) { 979 if (Make_OODate(gn)) {
980 DEBUG0(MAKE, "out-of-date\n"); 980 DEBUG0(MAKE, "out-of-date\n");
981 if (queryFlag) { 981 if (opts.queryFlag) {
982 return TRUE; 982 return TRUE;
983 } 983 }
984 Make_DoAllVar(gn); 984 Make_DoAllVar(gn);
985 Job_Make(gn); 985 Job_Make(gn);
986 have_token = 0; 986 have_token = 0;
987 } else { 987 } else {
988 DEBUG0(MAKE, "up-to-date\n"); 988 DEBUG0(MAKE, "up-to-date\n");
989 gn->made = UPTODATE; 989 gn->made = UPTODATE;
990 if (gn->type & OP_JOIN) { 990 if (gn->type & OP_JOIN) {
991 /* 991 /*
992 * Even for an up-to-date .JOIN node, we need it to have its 992 * Even for an up-to-date .JOIN node, we need it to have its
993 * context variables so references to it get the correct 993 * context variables so references to it get the correct
994 * value for .TARGET when building up the context variables 994 * value for .TARGET when building up the context variables
@@ -1007,30 +1007,30 @@ MakeStartJobs(void) @@ -1007,30 +1007,30 @@ MakeStartJobs(void)
1007} 1007}
1008 1008
1009static void 1009static void
1010MakePrintStatusOrderNode(GNode *ogn, GNode *gn) 1010MakePrintStatusOrderNode(GNode *ogn, GNode *gn)
1011{ 1011{
1012 if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED) 1012 if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED)
1013 /* not waiting for this one */ 1013 /* not waiting for this one */
1014 return; 1014 return;
1015 1015
1016 printf(" `%s%s' has .ORDER dependency against %s%s ", 1016 printf(" `%s%s' has .ORDER dependency against %s%s ",
1017 gn->name, gn->cohort_num, ogn->name, ogn->cohort_num); 1017 gn->name, gn->cohort_num, ogn->name, ogn->cohort_num);
1018 GNode_FprintDetails(stdout, "(", ogn, ")\n"); 1018 GNode_FprintDetails(stdout, "(", ogn, ")\n");
1019 1019
1020 if (DEBUG(MAKE) && debug_file != stdout) { 1020 if (DEBUG(MAKE) && opts.debug_file != stdout) {
1021 debug_printf(" `%s%s' has .ORDER dependency against %s%s ", 1021 debug_printf(" `%s%s' has .ORDER dependency against %s%s ",
1022 gn->name, gn->cohort_num, ogn->name, ogn->cohort_num); 1022 gn->name, gn->cohort_num, ogn->name, ogn->cohort_num);
1023 GNode_FprintDetails(debug_file, "(", ogn, ")\n"); 1023 GNode_FprintDetails(opts.debug_file, "(", ogn, ")\n");
1024 } 1024 }
1025} 1025}
1026 1026
1027static void 1027static void
1028MakePrintStatusOrder(GNode *gn) 1028MakePrintStatusOrder(GNode *gn)
1029{ 1029{
1030 GNodeListNode *ln; 1030 GNodeListNode *ln;
1031 for (ln = gn->order_pred->first; ln != NULL; ln = ln->next) 1031 for (ln = gn->order_pred->first; ln != NULL; ln = ln->next)
1032 MakePrintStatusOrderNode(ln->datum, gn); 1032 MakePrintStatusOrderNode(ln->datum, gn);
1033} 1033}
1034 1034
1035static void MakePrintStatusList(GNodeList *, int *); 1035static void MakePrintStatusList(GNodeList *, int *);
1036 1036
@@ -1050,38 +1050,38 @@ MakePrintStatus(GNode *gn, int *errors) @@ -1050,38 +1050,38 @@ MakePrintStatus(GNode *gn, int *errors)
1050 switch (gn->made) { 1050 switch (gn->made) {
1051 case UPTODATE: 1051 case UPTODATE:
1052 printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num); 1052 printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num);
1053 break; 1053 break;
1054 case MADE: 1054 case MADE:
1055 break; 1055 break;
1056 case UNMADE: 1056 case UNMADE:
1057 case DEFERRED: 1057 case DEFERRED:
1058 case REQUESTED: 1058 case REQUESTED:
1059 case BEINGMADE: 1059 case BEINGMADE:
1060 (*errors)++; 1060 (*errors)++;
1061 printf("`%s%s' was not built", gn->name, gn->cohort_num); 1061 printf("`%s%s' was not built", gn->name, gn->cohort_num);
1062 GNode_FprintDetails(stdout, " (", gn, ")!\n"); 1062 GNode_FprintDetails(stdout, " (", gn, ")!\n");
1063 if (DEBUG(MAKE) && debug_file != stdout) { 1063 if (DEBUG(MAKE) && opts.debug_file != stdout) {
1064 debug_printf("`%s%s' was not built", gn->name, gn->cohort_num); 1064 debug_printf("`%s%s' was not built", gn->name, gn->cohort_num);
1065 GNode_FprintDetails(debug_file, " (", gn, ")!\n"); 1065 GNode_FprintDetails(opts.debug_file, " (", gn, ")!\n");
1066 } 1066 }
1067 /* Most likely problem is actually caused by .ORDER */ 1067 /* Most likely problem is actually caused by .ORDER */
1068 MakePrintStatusOrder(gn); 1068 MakePrintStatusOrder(gn);
1069 break; 1069 break;
1070 default: 1070 default:
1071 /* Errors - already counted */ 1071 /* Errors - already counted */
1072 printf("`%s%s' not remade because of errors.\n", 1072 printf("`%s%s' not remade because of errors.\n",
1073 gn->name, gn->cohort_num); 1073 gn->name, gn->cohort_num);
1074 if (DEBUG(MAKE) && debug_file != stdout) 1074 if (DEBUG(MAKE) && opts.debug_file != stdout)
1075 debug_printf("`%s%s' not remade because of errors.\n", 1075 debug_printf("`%s%s' not remade because of errors.\n",
1076 gn->name, gn->cohort_num); 1076 gn->name, gn->cohort_num);
1077 break; 1077 break;
1078 } 1078 }
1079 return FALSE; 1079 return FALSE;
1080 } 1080 }
1081 1081
1082 DEBUG3(MAKE, "MakePrintStatus: %s%s has %d unmade children\n", 1082 DEBUG3(MAKE, "MakePrintStatus: %s%s has %d unmade children\n",
1083 gn->name, gn->cohort_num, gn->unmade); 1083 gn->name, gn->cohort_num, gn->unmade);
1084 /* 1084 /*
1085 * If printing cycles and came to one that has unmade children, 1085 * If printing cycles and came to one that has unmade children,
1086 * print out the cycle by recursing on its children. 1086 * print out the cycle by recursing on its children.
1087 */ 1087 */
@@ -1312,27 +1312,27 @@ Make_Run(GNodeList *targs) @@ -1312,27 +1312,27 @@ Make_Run(GNodeList *targs)
1312 int errors; /* Number of errors the Job module reports */ 1312 int errors; /* Number of errors the Job module reports */
1313 1313
1314 /* Start trying to make the current targets... */ 1314 /* Start trying to make the current targets... */
1315 toBeMade = Lst_New(); 1315 toBeMade = Lst_New();
1316 1316
1317 Make_ExpandUse(targs); 1317 Make_ExpandUse(targs);
1318 Make_ProcessWait(targs); 1318 Make_ProcessWait(targs);
1319 1319
1320 if (DEBUG(MAKE)) { 1320 if (DEBUG(MAKE)) {
1321 debug_printf("#***# full graph\n"); 1321 debug_printf("#***# full graph\n");
1322 Targ_PrintGraph(1); 1322 Targ_PrintGraph(1);
1323 } 1323 }
1324 1324
1325 if (queryFlag) { 1325 if (opts.queryFlag) {
1326 /* 1326 /*
1327 * We wouldn't do any work unless we could start some jobs in the 1327 * We wouldn't do any work unless we could start some jobs in the
1328 * next loop... (we won't actually start any, of course, this is just 1328 * next loop... (we won't actually start any, of course, this is just
1329 * to see if any of the targets was out of date) 1329 * to see if any of the targets was out of date)
1330 */ 1330 */
1331 return MakeStartJobs(); 1331 return MakeStartJobs();
1332 } 1332 }
1333 /* 1333 /*
1334 * Initialization. At the moment, no jobs are running and until some 1334 * Initialization. At the moment, no jobs are running and until some
1335 * get started, nothing will happen since the remaining upward 1335 * get started, nothing will happen since the remaining upward
1336 * traversal of the graph is performed by the routines in job.c upon 1336 * traversal of the graph is performed by the routines in job.c upon
1337 * the finishing of a job. So we fill the Job table as much as we can 1337 * the finishing of a job. So we fill the Job table as much as we can
1338 * before going into our loop. 1338 * before going into our loop.

cvs diff -r1.172 -r1.173 src/usr.bin/make/make.h (expand / switch to unified diff)

--- src/usr.bin/make/make.h 2020/10/25 21:51:49 1.172
+++ src/usr.bin/make/make.h 2020/10/26 21:34:10 1.173
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: make.h,v 1.172 2020/10/25 21:51:49 rillig Exp $ */ 1/* $NetBSD: make.h,v 1.173 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -410,60 +410,33 @@ typedef enum CondEvalResult { @@ -410,60 +410,33 @@ typedef enum CondEvalResult {
410#define ARCHIVE "!" /* Archive in "archive(member)" syntax */ 410#define ARCHIVE "!" /* Archive in "archive(member)" syntax */
411#define MEMBER "%" /* Member in "archive(member)" syntax */ 411#define MEMBER "%" /* Member in "archive(member)" syntax */
412 412
413#define FTARGET "@F" /* file part of TARGET */ 413#define FTARGET "@F" /* file part of TARGET */
414#define DTARGET "@D" /* directory part of TARGET */ 414#define DTARGET "@D" /* directory part of TARGET */
415#define FIMPSRC "<F" /* file part of IMPSRC */ 415#define FIMPSRC "<F" /* file part of IMPSRC */
416#define DIMPSRC "<D" /* directory part of IMPSRC */ 416#define DIMPSRC "<D" /* directory part of IMPSRC */
417#define FPREFIX "*F" /* file part of PREFIX */ 417#define FPREFIX "*F" /* file part of PREFIX */
418#define DPREFIX "*D" /* directory part of PREFIX */ 418#define DPREFIX "*D" /* directory part of PREFIX */
419 419
420/* 420/*
421 * Global Variables 421 * Global Variables
422 */ 422 */
423extern StringList *create; /* The list of target names specified on the 
424 * command line. used to resolve #if 
425 * make(...) statements */ 
426extern SearchPath *dirSearchPath; 423extern SearchPath *dirSearchPath;
427 /* The list of directories to search when 424 /* The list of directories to search when
428 * looking for targets */ 425 * looking for targets */
429 
430extern Boolean compatMake; /* True if we are make compatible */ 
431extern Boolean ignoreErrors; /* True if should ignore all errors */ 
432extern Boolean beSilent; /* True if should print no commands */ 
433extern Boolean noExecute; /* True if should execute almost nothing */ 
434extern Boolean noRecursiveExecute; 
435 /* True if should execute nothing */ 
436extern Boolean allPrecious; /* True if every target is precious */ 426extern Boolean allPrecious; /* True if every target is precious */
437extern Boolean deleteOnError; /* True if failed targets should be deleted */ 427extern Boolean deleteOnError; /* True if failed targets should be deleted */
438extern Boolean keepgoing; /* True if should continue on unaffected 
439 * portions of the graph when an error occurs 
440 * in one portion */ 
441extern Boolean touchFlag; /* TRUE if targets should just be 'touched' 
442 * if out of date. Set by the -t flag */ 
443extern Boolean queryFlag; /* TRUE if we aren't supposed to really make 
444 * anything, just see if the targets are out- 
445 * of-date */ 
446extern Boolean doing_depend; /* TRUE if processing .depend */ 428extern Boolean doing_depend; /* TRUE if processing .depend */
447 429
448extern Boolean checkEnvFirst; /* TRUE if environment should be searched for 
449 * variables before the global context */ 
450 
451extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are 
452 * treated as errors */ 
453 
454extern Boolean varNoExportEnv; /* TRUE if we should not export variables 
455 * set on the command line to the env. */ 
456 
457extern GNode *DEFAULT; /* .DEFAULT rule */ 430extern GNode *DEFAULT; /* .DEFAULT rule */
458 431
459extern GNode *VAR_INTERNAL; /* Variables defined internally by make 432extern GNode *VAR_INTERNAL; /* Variables defined internally by make
460 * which should not override those set by 433 * which should not override those set by
461 * makefiles. 434 * makefiles.
462 */ 435 */
463extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g 436extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
464 * in the Makefile itself */ 437 * in the Makefile itself */
465extern GNode *VAR_CMD; /* Variables defined on the command line */ 438extern GNode *VAR_CMD; /* Variables defined on the command line */
466extern char var_Error[]; /* Value returned by Var_Parse when an error 439extern char var_Error[]; /* Value returned by Var_Parse when an error
467 * is encountered. It actually points to 440 * is encountered. It actually points to
468 * an empty string, so naive callers needn't 441 * an empty string, so naive callers needn't
469 * worry about it. */ 442 * worry about it. */
@@ -519,37 +492,29 @@ typedef enum DebugFlags { @@ -519,37 +492,29 @@ typedef enum DebugFlags {
519 DEBUG_ERROR = 1 << 12, 492 DEBUG_ERROR = 1 << 12,
520 DEBUG_LOUD = 1 << 13, 493 DEBUG_LOUD = 1 << 13,
521 DEBUG_META = 1 << 14, 494 DEBUG_META = 1 << 14,
522 DEBUG_HASH = 1 << 15, 495 DEBUG_HASH = 1 << 15,
523 496
524 DEBUG_GRAPH3 = 1 << 16, 497 DEBUG_GRAPH3 = 1 << 16,
525 DEBUG_SCRIPT = 1 << 17, 498 DEBUG_SCRIPT = 1 << 17,
526 DEBUG_PARSE = 1 << 18, 499 DEBUG_PARSE = 1 << 18,
527 DEBUG_CWD = 1 << 19, 500 DEBUG_CWD = 1 << 19,
528 501
529 DEBUG_LINT = 1 << 20 502 DEBUG_LINT = 1 << 20
530} DebugFlags; 503} DebugFlags;
531 504
532/* 
533 * debug control: 
534 * There is one bit per module. It is up to the module what debug 
535 * information to print. 
536 */ 
537extern FILE *debug_file; /* Output is written here - default stderr */ 
538extern DebugFlags debug; 
539 
540#define CONCAT(a,b) a##b 505#define CONCAT(a,b) a##b
541 506
542#define DEBUG(module) (debug & CONCAT(DEBUG_,module)) 507#define DEBUG(module) (opts.debug & CONCAT(DEBUG_,module))
543 508
544void debug_printf(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2); 509void debug_printf(const char *, ...) MAKE_ATTR_PRINTFLIKE(1, 2);
545 510
546#define DEBUG0(module, text) \ 511#define DEBUG0(module, text) \
547 if (!DEBUG(module)) (void)0; \ 512 if (!DEBUG(module)) (void)0; \
548 else debug_printf("%s", text) 513 else debug_printf("%s", text)
549 514
550#define DEBUG1(module, fmt, arg1) \ 515#define DEBUG1(module, fmt, arg1) \
551 if (!DEBUG(module)) (void)0; \ 516 if (!DEBUG(module)) (void)0; \
552 else debug_printf(fmt, arg1) 517 else debug_printf(fmt, arg1)
553 518
554#define DEBUG2(module, fmt, arg1, arg2) \ 519#define DEBUG2(module, fmt, arg1, arg2) \
555 if (!DEBUG(module)) (void)0; \ 520 if (!DEBUG(module)) (void)0; \
@@ -557,26 +522,103 @@ void debug_printf(const char *, ...) MAK @@ -557,26 +522,103 @@ void debug_printf(const char *, ...) MAK
557 522
558#define DEBUG3(module, fmt, arg1, arg2, arg3) \ 523#define DEBUG3(module, fmt, arg1, arg2, arg3) \
559 if (!DEBUG(module)) (void)0; \ 524 if (!DEBUG(module)) (void)0; \
560 else debug_printf(fmt, arg1, arg2, arg3) 525 else debug_printf(fmt, arg1, arg2, arg3)
561 526
562#define DEBUG4(module, fmt, arg1, arg2, arg3, arg4) \ 527#define DEBUG4(module, fmt, arg1, arg2, arg3, arg4) \
563 if (!DEBUG(module)) (void)0; \ 528 if (!DEBUG(module)) (void)0; \
564 else debug_printf(fmt, arg1, arg2, arg3, arg4) 529 else debug_printf(fmt, arg1, arg2, arg3, arg4)
565 530
566#define DEBUG5(module, fmt, arg1, arg2, arg3, arg4, arg5) \ 531#define DEBUG5(module, fmt, arg1, arg2, arg3, arg4, arg5) \
567 if (!DEBUG(module)) (void)0; \ 532 if (!DEBUG(module)) (void)0; \
568 else debug_printf(fmt, arg1, arg2, arg3, arg4, arg5) 533 else debug_printf(fmt, arg1, arg2, arg3, arg4, arg5)
569 534
 535typedef enum PrintVarsMode {
 536 COMPAT_VARS = 1,
 537 EXPAND_VARS
 538} PrintVarsMode;
 539
 540/* Command line options */
 541typedef struct CmdOpts {
 542 /* -B: whether we are make compatible */
 543 Boolean compatMake;
 544
 545 /* -d: debug control: There is one bit per module. It is up to the
 546 * module what debug information to print. */
 547 DebugFlags debug;
 548
 549 /* -df: debug output is written here - default stderr */
 550 FILE *debug_file;
 551
 552 /* -e: check environment variables before global variables */
 553 Boolean checkEnvFirst;
 554
 555 /* -f: the makefiles to read */
 556 StringList *makefiles;
 557
 558 /* -i: if true, ignore all errors from shell commands */
 559 Boolean ignoreErrors;
 560
 561 /* -j: the maximum number of jobs that can run in parallel;
 562 * this is coordinated with the submakes */
 563 int maxJobs;
 564
 565 /* -k: if true, continue on unaffected portions of the graph when an
 566 * error occurs in one portion */
 567 Boolean keepgoing;
 568
 569 /* -N: execute no commands from the targets */
 570 Boolean noRecursiveExecute;
 571
 572 /* -n: execute almost no commands from the targets */
 573 Boolean noExecute;
 574
 575 /* -q: if true, we aren't supposed to really make anything, just see if
 576 * the targets are out-of-date */
 577 Boolean queryFlag;
 578
 579 /* -r: raw mode, without loading the builtin rules. */
 580 Boolean noBuiltins;
 581
 582 /* -s: don't echo the shell commands before executing them */
 583 Boolean beSilent;
 584
 585 /* -t: touch the targets if they are out-of-date, but don't actually
 586 * make them */
 587 Boolean touchFlag;
 588
 589 /* -[Vv]: print expanded or unexpanded selected variables */
 590 PrintVarsMode printVars;
 591 /* -[Vv]: the variables to print */
 592 StringList *variables;
 593
 594 /* -W: if true, makefile parsing warnings are treated as errors */
 595 Boolean parseWarnFatal;
 596
 597 /* -w: print Entering and Leaving for submakes */
 598 Boolean enterFlag;
 599
 600 /* -X: if true, do not export variables set on the command line to the
 601 * environment. */
 602 Boolean varNoExportEnv;
 603
 604 /* The target names specified on the command line.
 605 * Used to resolve .if make(...) statements. */
 606 StringList *create;
 607
 608} CmdOpts;
 609
 610extern CmdOpts opts;
 611
570#include "nonints.h" 612#include "nonints.h"
571 613
572void Make_TimeStamp(GNode *, GNode *); 614void Make_TimeStamp(GNode *, GNode *);
573Boolean Make_OODate(GNode *); 615Boolean Make_OODate(GNode *);
574void Make_ExpandUse(GNodeList *); 616void Make_ExpandUse(GNodeList *);
575time_t Make_Recheck(GNode *); 617time_t Make_Recheck(GNode *);
576void Make_HandleUse(GNode *, GNode *); 618void Make_HandleUse(GNode *, GNode *);
577void Make_Update(GNode *); 619void Make_Update(GNode *);
578void Make_DoAllVar(GNode *); 620void Make_DoAllVar(GNode *);
579Boolean Make_Run(GNodeList *); 621Boolean Make_Run(GNodeList *);
580int dieQuietly(GNode *, int); 622int dieQuietly(GNode *, int);
581void PrintOnError(GNode *, const char *); 623void PrintOnError(GNode *, const char *);
582void Main_ExportMAKEFLAGS(Boolean); 624void Main_ExportMAKEFLAGS(Boolean);

cvs diff -r1.400 -r1.401 src/usr.bin/make/parse.c (expand / switch to unified diff)

--- src/usr.bin/make/parse.c 2020/10/25 13:06:12 1.400
+++ src/usr.bin/make/parse.c 2020/10/26 21:34:10 1.401
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: parse.c,v 1.400 2020/10/25 13:06:12 rillig Exp $ */ 1/* $NetBSD: parse.c,v 1.401 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -121,27 +121,27 @@ @@ -121,27 +121,27 @@
121#ifndef MAP_FILE 121#ifndef MAP_FILE
122#define MAP_FILE 0 122#define MAP_FILE 0
123#endif 123#endif
124#ifndef MAP_COPY 124#ifndef MAP_COPY
125#define MAP_COPY MAP_PRIVATE 125#define MAP_COPY MAP_PRIVATE
126#endif 126#endif
127 127
128#include "make.h" 128#include "make.h"
129#include "dir.h" 129#include "dir.h"
130#include "job.h" 130#include "job.h"
131#include "pathnames.h" 131#include "pathnames.h"
132 132
133/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ 133/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
134MAKE_RCSID("$NetBSD: parse.c,v 1.400 2020/10/25 13:06:12 rillig Exp $"); 134MAKE_RCSID("$NetBSD: parse.c,v 1.401 2020/10/26 21:34:10 rillig Exp $");
135 135
136/* types and constants */ 136/* types and constants */
137 137
138/* 138/*
139 * Structure for a file being read ("included file") 139 * Structure for a file being read ("included file")
140 */ 140 */
141typedef struct IFile { 141typedef struct IFile {
142 char *fname; /* name of file */ 142 char *fname; /* name of file */
143 Boolean fromForLoop; /* simulated .include by the .for loop */ 143 Boolean fromForLoop; /* simulated .include by the .for loop */
144 int lineno; /* current line number in file */ 144 int lineno; /* current line number in file */
145 int first_lineno; /* line number of start of text */ 145 int first_lineno; /* line number of start of text */
146 unsigned int cond_depth; /* 'if' nesting when file opened */ 146 unsigned int cond_depth; /* 'if' nesting when file opened */
147 Boolean depending; /* state of doing_depend on EOF */ 147 Boolean depending; /* state of doing_depend on EOF */
@@ -658,48 +658,49 @@ ParseVErrorInternal(FILE *f, const char  @@ -658,48 +658,49 @@ ParseVErrorInternal(FILE *f, const char
658 658
659 (void)fprintf(f, "%s: ", progname); 659 (void)fprintf(f, "%s: ", progname);
660 660
661 if (cfname != NULL) 661 if (cfname != NULL)
662 PrintLocation(f, cfname, clineno); 662 PrintLocation(f, cfname, clineno);
663 if (type == PARSE_WARNING) 663 if (type == PARSE_WARNING)
664 (void)fprintf(f, "warning: "); 664 (void)fprintf(f, "warning: ");
665 (void)vfprintf(f, fmt, ap); 665 (void)vfprintf(f, fmt, ap);
666 (void)fprintf(f, "\n"); 666 (void)fprintf(f, "\n");
667 (void)fflush(f); 667 (void)fflush(f);
668 668
669 if (type == PARSE_INFO) 669 if (type == PARSE_INFO)
670 return; 670 return;
671 if (type == PARSE_FATAL || parseWarnFatal) 671 if (type == PARSE_FATAL || opts.parseWarnFatal)
672 fatals++; 672 fatals++;
673 if (parseWarnFatal && !fatal_warning_error_printed) { 673 if (opts.parseWarnFatal && !fatal_warning_error_printed) {
674 Error("parsing warnings being treated as errors"); 674 Error("parsing warnings being treated as errors");
675 fatal_warning_error_printed = TRUE; 675 fatal_warning_error_printed = TRUE;
676 } 676 }
677} 677}
678 678
679static void 679static void
680ParseErrorInternal(const char *cfname, size_t clineno, ParseErrorLevel type, 680ParseErrorInternal(const char *cfname, size_t clineno, ParseErrorLevel type,
681 const char *fmt, ...) 681 const char *fmt, ...)
682{ 682{
683 va_list ap; 683 va_list ap;
684 684
685 va_start(ap, fmt); 685 va_start(ap, fmt);
686 (void)fflush(stdout); 686 (void)fflush(stdout);
687 ParseVErrorInternal(stderr, cfname, clineno, type, fmt, ap); 687 ParseVErrorInternal(stderr, cfname, clineno, type, fmt, ap);
688 va_end(ap); 688 va_end(ap);
689 689
690 if (debug_file != stderr && debug_file != stdout) { 690 if (opts.debug_file != stderr && opts.debug_file != stdout) {
691 va_start(ap, fmt); 691 va_start(ap, fmt);
692 ParseVErrorInternal(debug_file, cfname, clineno, type, fmt, ap); 692 ParseVErrorInternal(opts.debug_file, cfname, clineno, type,
 693 fmt, ap);
693 va_end(ap); 694 va_end(ap);
694 } 695 }
695} 696}
696 697
697/* External interface to ParseErrorInternal; uses the default filename and 698/* External interface to ParseErrorInternal; uses the default filename and
698 * line number. 699 * line number.
699 * 700 *
700 * Fmt is given without a trailing newline. */ 701 * Fmt is given without a trailing newline. */
701void 702void
702Parse_Error(ParseErrorLevel type, const char *fmt, ...) 703Parse_Error(ParseErrorLevel type, const char *fmt, ...)
703{ 704{
704 va_list ap; 705 va_list ap;
705 const char *fname; 706 const char *fname;
@@ -708,29 +709,30 @@ Parse_Error(ParseErrorLevel type, const  @@ -708,29 +709,30 @@ Parse_Error(ParseErrorLevel type, const
708 if (curFile == NULL) { 709 if (curFile == NULL) {
709 fname = NULL; 710 fname = NULL;
710 lineno = 0; 711 lineno = 0;
711 } else { 712 } else {
712 fname = curFile->fname; 713 fname = curFile->fname;
713 lineno = (size_t)curFile->lineno; 714 lineno = (size_t)curFile->lineno;
714 } 715 }
715 716
716 va_start(ap, fmt); 717 va_start(ap, fmt);
717 (void)fflush(stdout); 718 (void)fflush(stdout);
718 ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap); 719 ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap);
719 va_end(ap); 720 va_end(ap);
720 721
721 if (debug_file != stderr && debug_file != stdout) { 722 if (opts.debug_file != stderr && opts.debug_file != stdout) {
722 va_start(ap, fmt); 723 va_start(ap, fmt);
723 ParseVErrorInternal(debug_file, fname, lineno, type, fmt, ap); 724 ParseVErrorInternal(opts.debug_file, fname, lineno, type,
 725 fmt, ap);
724 va_end(ap); 726 va_end(ap);
725 } 727 }
726} 728}
727 729
728 730
729/* Parse a .info .warning or .error directive. 731/* Parse a .info .warning or .error directive.
730 * 732 *
731 * The input is the line minus the ".". We substitute variables, print the 733 * The input is the line minus the ".". We substitute variables, print the
732 * message and exit(1) (for .error) or just print a warning if the directive 734 * message and exit(1) (for .error) or just print a warning if the directive
733 * is malformed. 735 * is malformed.
734 */ 736 */
735static Boolean 737static Boolean
736ParseMessage(const char *directive) 738ParseMessage(const char *directive)
@@ -900,27 +902,27 @@ ParseDoSrcKeyword(const char *src, Parse @@ -900,27 +902,27 @@ ParseDoSrcKeyword(const char *src, Parse
900} 902}
901 903
902static void 904static void
903ParseDoSrcMain(const char *src) 905ParseDoSrcMain(const char *src)
904{ 906{
905 /* 907 /*
906 * If we have noted the existence of a .MAIN, it means we need 908 * If we have noted the existence of a .MAIN, it means we need
907 * to add the sources of said target to the list of things 909 * to add the sources of said target to the list of things
908 * to create. The string 'src' is likely to be free, so we 910 * to create. The string 'src' is likely to be free, so we
909 * must make a new copy of it. Note that this will only be 911 * must make a new copy of it. Note that this will only be
910 * invoked if the user didn't specify a target on the command 912 * invoked if the user didn't specify a target on the command
911 * line. This is to allow #ifmake's to succeed, or something... 913 * line. This is to allow #ifmake's to succeed, or something...
912 */ 914 */
913 Lst_Append(create, bmake_strdup(src)); 915 Lst_Append(opts.create, bmake_strdup(src));
914 /* 916 /*
915 * Add the name to the .TARGETS variable as well, so the user can 917 * Add the name to the .TARGETS variable as well, so the user can
916 * employ that, if desired. 918 * employ that, if desired.
917 */ 919 */
918 Var_Append(".TARGETS", src, VAR_GLOBAL); 920 Var_Append(".TARGETS", src, VAR_GLOBAL);
919} 921}
920 922
921static void 923static void
922ParseDoSrcOrder(const char *src) 924ParseDoSrcOrder(const char *src)
923{ 925{
924 GNode *gn; 926 GNode *gn;
925 /* 927 /*
926 * Create proper predecessor/successor links between the previous 928 * Create proper predecessor/successor links between the previous
@@ -1115,57 +1117,57 @@ ParseDependencyTargetWord(/*const*/ char @@ -1115,57 +1117,57 @@ ParseDependencyTargetWord(/*const*/ char
1115static void 1117static void
1116ParseDoDependencyTargetSpecial(ParseSpecial *inout_specType, 1118ParseDoDependencyTargetSpecial(ParseSpecial *inout_specType,
1117 const char *line, 1119 const char *line,
1118 SearchPathList **inout_paths) 1120 SearchPathList **inout_paths)
1119{ 1121{
1120 switch (*inout_specType) { 1122 switch (*inout_specType) {
1121 case ExPath: 1123 case ExPath:
1122 if (*inout_paths == NULL) { 1124 if (*inout_paths == NULL) {
1123 *inout_paths = Lst_New(); 1125 *inout_paths = Lst_New();
1124 } 1126 }
1125 Lst_Append(*inout_paths, dirSearchPath); 1127 Lst_Append(*inout_paths, dirSearchPath);
1126 break; 1128 break;
1127 case Main: 1129 case Main:
1128 if (!Lst_IsEmpty(create)) { 1130 if (!Lst_IsEmpty(opts.create)) {
1129 *inout_specType = Not; 1131 *inout_specType = Not;
1130 } 1132 }
1131 break; 1133 break;
1132 case Begin: 1134 case Begin:
1133 case End: 1135 case End:
1134 case Stale: 1136 case Stale:
1135 case dotError: 1137 case dotError:
1136 case Interrupt: { 1138 case Interrupt: {
1137 GNode *gn = Targ_GetNode(line); 1139 GNode *gn = Targ_GetNode(line);
1138 if (doing_depend) 1140 if (doing_depend)
1139 ParseMark(gn); 1141 ParseMark(gn);
1140 gn->type |= OP_NOTMAIN|OP_SPECIAL; 1142 gn->type |= OP_NOTMAIN|OP_SPECIAL;
1141 Lst_Append(targets, gn); 1143 Lst_Append(targets, gn);
1142 break; 1144 break;
1143 } 1145 }
1144 case Default: { 1146 case Default: {
1145 GNode *gn = Targ_NewGN(".DEFAULT"); 1147 GNode *gn = Targ_NewGN(".DEFAULT");
1146 gn->type |= OP_NOTMAIN|OP_TRANSFORM; 1148 gn->type |= OP_NOTMAIN|OP_TRANSFORM;
1147 Lst_Append(targets, gn); 1149 Lst_Append(targets, gn);
1148 DEFAULT = gn; 1150 DEFAULT = gn;
1149 break; 1151 break;
1150 } 1152 }
1151 case DeleteOnError: 1153 case DeleteOnError:
1152 deleteOnError = TRUE; 1154 deleteOnError = TRUE;
1153 break; 1155 break;
1154 case NotParallel: 1156 case NotParallel:
1155 maxJobs = 1; 1157 opts.maxJobs = 1;
1156 break; 1158 break;
1157 case SingleShell: 1159 case SingleShell:
1158 compatMake = TRUE; 1160 opts.compatMake = TRUE;
1159 break; 1161 break;
1160 case Order: 1162 case Order:
1161 predecessor = NULL; 1163 predecessor = NULL;
1162 break; 1164 break;
1163 default: 1165 default:
1164 break; 1166 break;
1165 } 1167 }
1166} 1168}
1167 1169
1168/* 1170/*
1169 * .PATH<suffix> has to be handled specially. 1171 * .PATH<suffix> has to be handled specially.
1170 * Call on the suffix module to give us a path to modify. 1172 * Call on the suffix module to give us a path to modify.
1171 */ 1173 */
@@ -1351,30 +1353,30 @@ ClearPaths(SearchPathList *paths) @@ -1351,30 +1353,30 @@ ClearPaths(SearchPathList *paths)
1351} 1353}
1352 1354
1353static void 1355static void
1354ParseDoDependencySourcesEmpty(ParseSpecial specType, SearchPathList *paths) 1356ParseDoDependencySourcesEmpty(ParseSpecial specType, SearchPathList *paths)
1355{ 1357{
1356 switch (specType) { 1358 switch (specType) {
1357 case Suffixes: 1359 case Suffixes:
1358 Suff_ClearSuffixes(); 1360 Suff_ClearSuffixes();
1359 break; 1361 break;
1360 case Precious: 1362 case Precious:
1361 allPrecious = TRUE; 1363 allPrecious = TRUE;
1362 break; 1364 break;
1363 case Ignore: 1365 case Ignore:
1364 ignoreErrors = TRUE; 1366 opts.ignoreErrors = TRUE;
1365 break; 1367 break;
1366 case Silent: 1368 case Silent:
1367 beSilent = TRUE; 1369 opts.beSilent = TRUE;
1368 break; 1370 break;
1369 case ExPath: 1371 case ExPath:
1370 ClearPaths(paths); 1372 ClearPaths(paths);
1371 break; 1373 break;
1372#ifdef POSIX 1374#ifdef POSIX
1373 case Posix: 1375 case Posix:
1374 Var_Set("%POSIX", "1003.2", VAR_GLOBAL); 1376 Var_Set("%POSIX", "1003.2", VAR_GLOBAL);
1375 break; 1377 break;
1376#endif 1378#endif
1377 default: 1379 default:
1378 break; 1380 break;
1379 } 1381 }
1380} 1382}

cvs diff -r1.124 -r1.125 src/usr.bin/make/targ.c (expand / switch to unified diff)

--- src/usr.bin/make/targ.c 2020/10/25 21:51:49 1.124
+++ src/usr.bin/make/targ.c 2020/10/26 21:34:10 1.125
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: targ.c,v 1.124 2020/10/25 21:51:49 rillig Exp $ */ 1/* $NetBSD: targ.c,v 1.125 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -111,27 +111,27 @@ @@ -111,27 +111,27 @@
111 * Debugging: 111 * Debugging:
112 * Targ_PrintGraph 112 * Targ_PrintGraph
113 * Print out the entire graphm all variables and 113 * Print out the entire graphm all variables and
114 * statistics for the directory cache. Should print 114 * statistics for the directory cache. Should print
115 * something for suffixes, too, but... 115 * something for suffixes, too, but...
116 */ 116 */
117 117
118#include <time.h> 118#include <time.h>
119 119
120#include "make.h" 120#include "make.h"
121#include "dir.h" 121#include "dir.h"
122 122
123/* "@(#)targ.c 8.2 (Berkeley) 3/19/94" */ 123/* "@(#)targ.c 8.2 (Berkeley) 3/19/94" */
124MAKE_RCSID("$NetBSD: targ.c,v 1.124 2020/10/25 21:51:49 rillig Exp $"); 124MAKE_RCSID("$NetBSD: targ.c,v 1.125 2020/10/26 21:34:10 rillig Exp $");
125 125
126static GNodeList *allTargets; /* the list of all targets found so far */ 126static GNodeList *allTargets; /* the list of all targets found so far */
127#ifdef CLEANUP 127#ifdef CLEANUP
128static GNodeList *allGNs; /* List of all the GNodes */ 128static GNodeList *allGNs; /* List of all the GNodes */
129#endif 129#endif
130static HashTable targets; /* a hash table of same */ 130static HashTable targets; /* a hash table of same */
131 131
132#ifdef CLEANUP 132#ifdef CLEANUP
133static void TargFreeGN(void *); 133static void TargFreeGN(void *);
134#endif 134#endif
135 135
136void 136void
137Targ_Init(void) 137Targ_Init(void)
@@ -295,34 +295,34 @@ Targ_FindList(StringList *names) @@ -295,34 +295,34 @@ Targ_FindList(StringList *names)
295 GNodeList *nodes = Lst_New(); 295 GNodeList *nodes = Lst_New();
296 for (ln = names->first; ln != NULL; ln = ln->next) { 296 for (ln = names->first; ln != NULL; ln = ln->next) {
297 const char *name = ln->datum; 297 const char *name = ln->datum;
298 GNode *gn = Targ_GetNode(name); 298 GNode *gn = Targ_GetNode(name);
299 Lst_Append(nodes, gn); 299 Lst_Append(nodes, gn);
300 } 300 }
301 return nodes; 301 return nodes;
302} 302}
303 303
304/* Return true if should ignore errors when creating gn. */ 304/* Return true if should ignore errors when creating gn. */
305Boolean 305Boolean
306Targ_Ignore(GNode *gn) 306Targ_Ignore(GNode *gn)
307{ 307{
308 return ignoreErrors || gn->type & OP_IGNORE; 308 return opts.ignoreErrors || gn->type & OP_IGNORE;
309} 309}
310 310
311/* Return true if be silent when creating gn. */ 311/* Return true if be silent when creating gn. */
312Boolean 312Boolean
313Targ_Silent(GNode *gn) 313Targ_Silent(GNode *gn)
314{ 314{
315 return beSilent || gn->type & OP_SILENT; 315 return opts.beSilent || gn->type & OP_SILENT;
316} 316}
317 317
318/* See if the given target is precious. */ 318/* See if the given target is precious. */
319Boolean 319Boolean
320Targ_Precious(GNode *gn) 320Targ_Precious(GNode *gn)
321{ 321{
322 return allPrecious || gn->type & (OP_PRECIOUS | OP_DOUBLEDEP); 322 return allPrecious || gn->type & (OP_PRECIOUS | OP_DOUBLEDEP);
323} 323}
324 324
325/******************* DEBUG INFO PRINTING ****************/ 325/******************* DEBUG INFO PRINTING ****************/
326 326
327static GNode *mainTarg; /* the main target, as set by Targ_SetMain */ 327static GNode *mainTarg; /* the main target, as set by Targ_SetMain */
328 328
@@ -439,27 +439,27 @@ GNode_OpName(const GNode *gn) @@ -439,27 +439,27 @@ GNode_OpName(const GNode *gn)
439 case OP_FORCE: 439 case OP_FORCE:
440 return "!"; 440 return "!";
441 case OP_DOUBLEDEP: 441 case OP_DOUBLEDEP:
442 return "::"; 442 return "::";
443 } 443 }
444 return ""; 444 return "";
445} 445}
446 446
447/* Print the contents of a node. */ 447/* Print the contents of a node. */
448void 448void
449Targ_PrintNode(GNode *gn, int pass) 449Targ_PrintNode(GNode *gn, int pass)
450{ 450{
451 debug_printf("# %s%s", gn->name, gn->cohort_num); 451 debug_printf("# %s%s", gn->name, gn->cohort_num);
452 GNode_FprintDetails(debug_file, ", ", gn, "\n"); 452 GNode_FprintDetails(opts.debug_file, ", ", gn, "\n");
453 if (gn->flags == 0) 453 if (gn->flags == 0)
454 return; 454 return;
455 455
456 if (GNode_IsTarget(gn)) { 456 if (GNode_IsTarget(gn)) {
457 debug_printf("#\n"); 457 debug_printf("#\n");
458 if (gn == mainTarg) { 458 if (gn == mainTarg) {
459 debug_printf("# *** MAIN TARGET ***\n"); 459 debug_printf("# *** MAIN TARGET ***\n");
460 } 460 }
461 if (pass >= 2) { 461 if (pass >= 2) {
462 if (gn->unmade) { 462 if (gn->unmade) {
463 debug_printf("# %d unmade children\n", gn->unmade); 463 debug_printf("# %d unmade children\n", gn->unmade);
464 } else { 464 } else {
465 debug_printf("# No unmade children\n"); 465 debug_printf("# No unmade children\n");

cvs diff -r1.589 -r1.590 src/usr.bin/make/var.c (expand / switch to unified diff)

--- src/usr.bin/make/var.c 2020/10/25 21:51:49 1.589
+++ src/usr.bin/make/var.c 2020/10/26 21:34:10 1.590
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.589 2020/10/25 21:51:49 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.590 2020/10/26 21:34:10 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -111,27 +111,27 @@ @@ -111,27 +111,27 @@
111#include <sys/types.h> 111#include <sys/types.h>
112#include <regex.h> 112#include <regex.h>
113#endif 113#endif
114#include <inttypes.h> 114#include <inttypes.h>
115#include <limits.h> 115#include <limits.h>
116#include <time.h> 116#include <time.h>
117 117
118#include "make.h" 118#include "make.h"
119#include "dir.h" 119#include "dir.h"
120#include "job.h" 120#include "job.h"
121#include "metachar.h" 121#include "metachar.h"
122 122
123/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ 123/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
124MAKE_RCSID("$NetBSD: var.c,v 1.589 2020/10/25 21:51:49 rillig Exp $"); 124MAKE_RCSID("$NetBSD: var.c,v 1.590 2020/10/26 21:34:10 rillig Exp $");
125 125
126#define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1) 126#define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1)
127#define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2) 127#define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2)
128#define VAR_DEBUG3(fmt, arg1, arg2, arg3) DEBUG3(VAR, fmt, arg1, arg2, arg3) 128#define VAR_DEBUG3(fmt, arg1, arg2, arg3) DEBUG3(VAR, fmt, arg1, arg2, arg3)
129#define VAR_DEBUG4(fmt, arg1, arg2, arg3, arg4) DEBUG4(VAR, fmt, arg1, arg2, arg3, arg4) 129#define VAR_DEBUG4(fmt, arg1, arg2, arg3, arg4) DEBUG4(VAR, fmt, arg1, arg2, arg3, arg4)
130 130
131ENUM_FLAGS_RTTI_3(VarEvalFlags, 131ENUM_FLAGS_RTTI_3(VarEvalFlags,
132 VARE_UNDEFERR, VARE_WANTRES, VARE_ASSIGN); 132 VARE_UNDEFERR, VARE_WANTRES, VARE_ASSIGN);
133 133
134/* 134/*
135 * This lets us tell if we have replaced the original environ 135 * This lets us tell if we have replaced the original environ
136 * (which we cannot free). 136 * (which we cannot free).
137 */ 137 */
@@ -370,45 +370,45 @@ VarFind(const char *name, GNode *ctxt, V @@ -370,45 +370,45 @@ VarFind(const char *name, GNode *ctxt, V
370 name = CanonicalVarname(name); 370 name = CanonicalVarname(name);
371 nameHash = Hash_Hash(name); 371 nameHash = Hash_Hash(name);
372 372
373 /* 373 /*
374 * First look for the variable in the given context. If it's not there, 374 * First look for the variable in the given context. If it's not there,
375 * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order, 375 * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
376 * depending on the FIND_* flags in 'flags' 376 * depending on the FIND_* flags in 'flags'
377 */ 377 */
378 var = GNode_FindVar(ctxt, name, nameHash); 378 var = GNode_FindVar(ctxt, name, nameHash);
379 379
380 if (var == NULL && (flags & FIND_CMD) && ctxt != VAR_CMD) 380 if (var == NULL && (flags & FIND_CMD) && ctxt != VAR_CMD)
381 var = GNode_FindVar(VAR_CMD, name, nameHash); 381 var = GNode_FindVar(VAR_CMD, name, nameHash);
382 382
383 if (!checkEnvFirst && var == NULL && (flags & FIND_GLOBAL) && 383 if (!opts.checkEnvFirst && var == NULL && (flags & FIND_GLOBAL) &&
384 ctxt != VAR_GLOBAL) 384 ctxt != VAR_GLOBAL)
385 { 385 {
386 var = GNode_FindVar(VAR_GLOBAL, name, nameHash); 386 var = GNode_FindVar(VAR_GLOBAL, name, nameHash);
387 if (var == NULL && ctxt != VAR_INTERNAL) { 387 if (var == NULL && ctxt != VAR_INTERNAL) {
388 /* VAR_INTERNAL is subordinate to VAR_GLOBAL */ 388 /* VAR_INTERNAL is subordinate to VAR_GLOBAL */
389 var = GNode_FindVar(VAR_INTERNAL, name, nameHash); 389 var = GNode_FindVar(VAR_INTERNAL, name, nameHash);
390 } 390 }
391 } 391 }
392 392
393 if (var == NULL && (flags & FIND_ENV)) { 393 if (var == NULL && (flags & FIND_ENV)) {
394 char *env; 394 char *env;
395 395
396 if ((env = getenv(name)) != NULL) { 396 if ((env = getenv(name)) != NULL) {
397 char *varname = bmake_strdup(name); 397 char *varname = bmake_strdup(name);
398 return VarNew(varname, varname, env, VAR_FROM_ENV); 398 return VarNew(varname, varname, env, VAR_FROM_ENV);
399 } 399 }
400 400
401 if (checkEnvFirst && (flags & FIND_GLOBAL) && ctxt != VAR_GLOBAL) { 401 if (opts.checkEnvFirst && (flags & FIND_GLOBAL) && ctxt != VAR_GLOBAL) {
402 var = GNode_FindVar(VAR_GLOBAL, name, nameHash); 402 var = GNode_FindVar(VAR_GLOBAL, name, nameHash);
403 if (var == NULL && ctxt != VAR_INTERNAL) 403 if (var == NULL && ctxt != VAR_INTERNAL)
404 var = GNode_FindVar(VAR_INTERNAL, name, nameHash); 404 var = GNode_FindVar(VAR_INTERNAL, name, nameHash);
405 return var; 405 return var;
406 } 406 }
407 407
408 return NULL; 408 return NULL;
409 } 409 }
410 410
411 return var; 411 return var;
412} 412}
413 413
414/*- 414/*-
@@ -834,27 +834,27 @@ Var_Set_with_flags(const char *name, con @@ -834,27 +834,27 @@ Var_Set_with_flags(const char *name, con
834 if (ctxt == VAR_CMD && !(flags & VAR_NO_EXPORT) && name[0] != '.') { 834 if (ctxt == VAR_CMD && !(flags & VAR_NO_EXPORT) && name[0] != '.') {
835 if (v == NULL) { 835 if (v == NULL) {
836 /* we just added it */ 836 /* we just added it */
837 v = VarFind(name, ctxt, 0); 837 v = VarFind(name, ctxt, 0);
838 } 838 }
839 if (v != NULL) 839 if (v != NULL)
840 v->flags |= VAR_FROM_CMD; 840 v->flags |= VAR_FROM_CMD;
841 /* 841 /*
842 * If requested, don't export these in the environment 842 * If requested, don't export these in the environment
843 * individually. We still put them in MAKEOVERRIDES so 843 * individually. We still put them in MAKEOVERRIDES so
844 * that the command-line settings continue to override 844 * that the command-line settings continue to override
845 * Makefile settings. 845 * Makefile settings.
846 */ 846 */
847 if (!varNoExportEnv) 847 if (!opts.varNoExportEnv)
848 setenv(name, val ? val : "", 1); 848 setenv(name, val ? val : "", 1);
849 849
850 Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL); 850 Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
851 } 851 }
852 if (name[0] == '.' && strcmp(name, SAVE_DOLLARS) == 0) 852 if (name[0] == '.' && strcmp(name, SAVE_DOLLARS) == 0)
853 save_dollars = s2Boolean(val, save_dollars); 853 save_dollars = s2Boolean(val, save_dollars);
854 854
855out: 855out:
856 free(name_freeIt); 856 free(name_freeIt);
857 if (v != NULL) 857 if (v != NULL)
858 VarFreeEnv(v, TRUE); 858 VarFreeEnv(v, TRUE);
859} 859}
860 860