aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2021-01-14 01:24:34 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2021-01-14 01:24:34 +0000
commit8e11a9b4250be3c3379c45fa820bff78d99d5946 (patch)
treeea4954dbe7647b6211a20458b2a881e3d943639f /main.c
parent1b65f0bd2bda7121a90f8cb4c1cacaa20f1b681d (diff)
downloadsrc-8e11a9b4250be3c3379c45fa820bff78d99d5946.tar.gz
src-8e11a9b4250be3c3379c45fa820bff78d99d5946.zip
Import bmake-20210110vendor/NetBSD/bmake/20210110
Quite a lot of churn on style, but lots of good work refactoring complicated functions and lots more unit-tests. Thanks mostly to rillig at NetBSD Some interesting entries from ChangeLog o .MAKE.{UID,GID} represent uid and gid running make. o allow env var MAKE_OBJDIR_CHECK_WRITABLE=no to skip writable checks in InitObjdir. Explicit .OBJDIR target always allows read-only directory. o add more unit tests for META MODE Change-Id: I4d3bcf08b4c864d98b343f602efe5a75dbfa7a94
Diffstat (limited to 'main.c')
-rw-r--r--main.c364
1 files changed, 192 insertions, 172 deletions
diff --git a/main.c b/main.c
index 6e97a9a12541..f2813d263c2a 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.476 2020/11/16 22:08:20 rillig Exp $ */
+/* $NetBSD: main.c,v 1.512 2021/01/10 23:59:53 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -68,7 +68,8 @@
* SUCH DAMAGE.
*/
-/* The main file for this entire program. Exit routines etc. reside here.
+/*
+ * The main file for this entire program. Exit routines etc. reside here.
*
* Utility functions defined in this file:
*
@@ -109,17 +110,13 @@
#include "trace.h"
/* "@(#)main.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: main.c,v 1.476 2020/11/16 22:08:20 rillig Exp $");
+MAKE_RCSID("$NetBSD: main.c,v 1.512 2021/01/10 23:59:53 rillig Exp $");
#if defined(MAKE_NATIVE) && !defined(lint)
__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 "
"The Regents of the University of California. "
"All rights reserved.");
#endif
-#ifndef DEFMAXLOCAL
-#define DEFMAXLOCAL DEFMAXJOBS
-#endif
-
#ifndef __arraycount
# define __arraycount(__x) (sizeof(__x) / sizeof(__x[0]))
#endif
@@ -133,7 +130,6 @@ Boolean deleteOnError; /* .DELETE_ON_ERROR: set */
static int maxJobTokens; /* -j argument */
Boolean enterFlagObj; /* -w and objdir != srcdir */
-Boolean preserveUndefined;
static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
Boolean doing_depend; /* Set while reading .depend */
static Boolean jobsRunning; /* TRUE if the jobs might be running */
@@ -144,13 +140,13 @@ static void purge_relative_cached_realpaths(void);
static Boolean ignorePWD; /* if we use -C, PWD is meaningless */
static char objdir[MAXPATHLEN + 1]; /* where we chdir'ed to */
char curdir[MAXPATHLEN + 1]; /* Startup directory */
-char *progname; /* the program name */
+const char *progname;
char *makeDependfile;
pid_t myPid;
int makelevel;
Boolean forceJobs = FALSE;
-static int errors = 0;
+static int main_errors = 0;
static HashTable cached_realpaths;
/*
@@ -167,16 +163,16 @@ explode(const char *flags)
if (flags == NULL)
return NULL;
- for (f = flags; *f; f++)
+ for (f = flags; *f != '\0'; f++)
if (!ch_isalpha(*f))
break;
- if (*f)
+ if (*f != '\0')
return bmake_strdup(flags);
len = strlen(flags);
st = nf = bmake_malloc(len * 3 + 1);
- while (*flags) {
+ while (*flags != '\0') {
*nf++ = '-';
*nf++ = *flags++;
*nf++ = ' ';
@@ -251,7 +247,7 @@ parse_debug_options(const char *argvalue)
const char *modules;
DebugFlags debug = opts.debug;
- for (modules = argvalue; *modules; ++modules) {
+ for (modules = argvalue; *modules != '\0'; ++modules) {
switch (*modules) {
case '0': /* undocumented, only intended for tests */
debug = DEBUG_NONE;
@@ -296,7 +292,7 @@ parse_debug_options(const char *argvalue)
debug |= DEBUG_JOB;
break;
case 'L':
- opts.lint = TRUE;
+ opts.strict = TRUE;
break;
case 'l':
debug |= DEBUG_LOUD;
@@ -381,7 +377,7 @@ MainParseArgChdir(const char *argvalue)
if (chdir(argvalue) == -1) {
(void)fprintf(stderr, "%s: chdir %s: %s\n",
progname, argvalue, strerror(errno));
- exit(1);
+ exit(2); /* Not 1 so -q can distinguish error */
}
if (getcwd(curdir, MAXPATHLEN) == NULL) {
(void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
@@ -434,7 +430,7 @@ MainParseArgJobs(const char *argvalue)
(void)fprintf(stderr,
"%s: illegal argument to -j -- must be positive integer!\n",
progname);
- exit(1); /* XXX: why not 2? */
+ exit(2); /* Not 1 so -q can distinguish error */
}
Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
@@ -504,7 +500,7 @@ MainParseArg(char c, const char *argvalue)
case 'V':
case 'v':
opts.printVars = c == 'v' ? PVM_EXPANDED : PVM_UNEXPANDED;
- Lst_Append(opts.variables, bmake_strdup(argvalue));
+ Lst_Append(&opts.variables, bmake_strdup(argvalue));
/* XXX: Why always -V? */
Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
@@ -532,7 +528,7 @@ MainParseArg(char c, const char *argvalue)
Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
break;
case 'f':
- Lst_Append(opts.makefiles, bmake_strdup(argvalue));
+ Lst_Append(&opts.makefiles, bmake_strdup(argvalue));
break;
case 'i':
opts.ignoreErrors = TRUE;
@@ -581,13 +577,15 @@ MainParseArg(char c, const char *argvalue)
return TRUE;
}
-/* Parse the given arguments. Called from main() and from
+/*
+ * Parse the given arguments. Called from main() and from
* Main_ParseArgLine() when the .MAKEFLAGS target is used.
*
* The arguments must be treated as read-only and will be freed after the
* call.
*
- * XXX: Deal with command line overriding .MAKEFLAGS in makefile */
+ * XXX: Deal with command line overriding .MAKEFLAGS in makefile
+ */
static void
MainParseArgs(int argc, char **argv)
{
@@ -668,7 +666,7 @@ rearg:
Punt("illegal (null) argument.");
if (argv[1][0] == '-' && !dashDash)
goto rearg;
- Lst_Append(opts.create, bmake_strdup(argv[1]));
+ Lst_Append(&opts.create, bmake_strdup(argv[1]));
}
}
@@ -679,10 +677,12 @@ noarg:
usage();
}
-/* Break a line of arguments into words and parse them.
+/*
+ * Break a line of arguments into words and parse them.
*
* Used when a .MFLAGS or .MAKEFLAGS target is encountered during parsing and
- * by main() when reading the MAKEFLAGS environment variable. */
+ * by main() when reading the MAKEFLAGS environment variable.
+ */
void
Main_ParseArgLine(const char *line)
{
@@ -691,6 +691,7 @@ Main_ParseArgLine(const char *line)
if (line == NULL)
return;
+ /* XXX: don't use line as an iterator variable */
for (; *line == ' '; ++line)
continue;
if (line[0] == '\0')
@@ -711,10 +712,9 @@ Main_ParseArgLine(const char *line)
}
#endif
{
- void *freeIt;
- const char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &freeIt);
- buf = str_concat3(argv0, " ", line);
- free(freeIt);
+ FStr argv0 = Var_Value(".MAKE", VAR_GLOBAL);
+ buf = str_concat3(argv0.str, " ", line);
+ FStr_Done(&argv0);
}
words = Str_Words(buf, TRUE);
@@ -772,34 +772,34 @@ Main_SetObjdir(Boolean writable, const char *fmt, ...)
static Boolean
SetVarObjdir(Boolean writable, const char *var, const char *suffix)
{
- void *path_freeIt;
- const char *path = Var_Value(var, VAR_CMDLINE, &path_freeIt);
- const char *xpath;
- char *xpath_freeIt;
+ FStr path = Var_Value(var, VAR_CMDLINE);
+ FStr xpath;
- if (path == NULL || path[0] == '\0') {
- bmake_free(path_freeIt);
+ if (path.str == NULL || path.str[0] == '\0') {
+ FStr_Done(&path);
return FALSE;
}
/* expand variable substitutions */
- xpath = path;
- xpath_freeIt = NULL;
- if (strchr(path, '$') != 0) {
- (void)Var_Subst(path, VAR_GLOBAL, VARE_WANTRES, &xpath_freeIt);
+ xpath = FStr_InitRefer(path.str);
+ if (strchr(path.str, '$') != 0) {
+ char *expanded;
+ (void)Var_Subst(path.str, VAR_GLOBAL, VARE_WANTRES, &expanded);
/* TODO: handle errors */
- xpath = xpath_freeIt;
+ xpath = FStr_InitOwn(expanded);
}
- (void)Main_SetObjdir(writable, "%s%s", xpath, suffix);
+ (void)Main_SetObjdir(writable, "%s%s", xpath.str, suffix);
- bmake_free(xpath_freeIt);
- bmake_free(path_freeIt);
+ FStr_Done(&xpath);
+ FStr_Done(&path);
return TRUE;
}
-/* Splits str into words, adding them to the list.
- * The string must be kept alive as long as the list. */
+/*
+ * Splits str into words, adding them to the list.
+ * The string must be kept alive as long as the list.
+ */
int
str2Lst_Append(StringList *lp, char *str)
{
@@ -808,7 +808,7 @@ str2Lst_Append(StringList *lp, char *str)
const char *sep = " \t";
- for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
+ for (n = 0, cp = strtok(str, sep); cp != NULL; cp = strtok(NULL, sep)) {
Lst_Append(lp, cp);
n++;
}
@@ -831,39 +831,38 @@ siginfo(int signo MAKE_ATTR_UNUSED)
}
#endif
-/*
- * Allow makefiles some control over the mode we run in.
- */
-void
-MakeMode(const char *mode)
+/* Allow makefiles some control over the mode we run in. */
+static void
+MakeMode(void)
{
- char *mode_freeIt = NULL;
+ FStr mode = FStr_InitRefer(NULL);
- if (mode == NULL) {
+ if (mode.str == NULL) {
+ char *expanded;
(void)Var_Subst("${" MAKE_MODE ":tl}",
- VAR_GLOBAL, VARE_WANTRES, &mode_freeIt);
+ VAR_GLOBAL, VARE_WANTRES, &expanded);
/* TODO: handle errors */
- mode = mode_freeIt;
+ mode = FStr_InitOwn(expanded);
}
- if (mode[0] != '\0') {
- if (strstr(mode, "compat")) {
+ if (mode.str[0] != '\0') {
+ if (strstr(mode.str, "compat") != NULL) {
opts.compatMake = TRUE;
forceJobs = FALSE;
}
#if USE_META
- if (strstr(mode, "meta"))
- meta_mode_init(mode);
+ if (strstr(mode.str, "meta") != NULL)
+ meta_mode_init(mode.str);
#endif
}
- free(mode_freeIt);
+ FStr_Done(&mode);
}
static void
PrintVar(const char *varname, Boolean expandVars)
{
- if (strchr(varname, '$')) {
+ if (strchr(varname, '$') != NULL) {
char *evalue;
(void)Var_Subst(varname, VAR_GLOBAL, VARE_WANTRES, &evalue);
/* TODO: handle errors */
@@ -880,10 +879,9 @@ PrintVar(const char *varname, Boolean expandVars)
bmake_free(evalue);
} else {
- void *freeIt;
- const char *value = Var_Value(varname, VAR_GLOBAL, &freeIt);
- printf("%s\n", value ? value : "");
- bmake_free(freeIt);
+ FStr value = Var_Value(varname, VAR_GLOBAL);
+ printf("%s\n", value.str != NULL ? value.str : "");
+ FStr_Done(&value);
}
}
@@ -922,7 +920,7 @@ doPrintVars(void)
else
expandVars = GetBooleanVar(".MAKE.EXPAND_VARIABLES", FALSE);
- for (ln = opts.variables->first; ln != NULL; ln = ln->next) {
+ for (ln = opts.variables.first; ln != NULL; ln = ln->next) {
const char *varname = ln->datum;
PrintVar(varname, expandVars);
}
@@ -931,7 +929,7 @@ doPrintVars(void)
static Boolean
runTargets(void)
{
- GNodeList *targs; /* target nodes to create */
+ GNodeList targs = LST_INIT; /* target nodes to create */
Boolean outOfDate; /* FALSE if all targets up to date */
/*
@@ -940,10 +938,10 @@ runTargets(void)
* we consult the parsing module to find the main target(s)
* to create.
*/
- if (Lst_IsEmpty(opts.create))
- targs = Parse_MainName();
+ if (Lst_IsEmpty(&opts.create))
+ Parse_MainName(&targs);
else
- targs = Targ_FindList(opts.create);
+ Targ_FindList(&targs, &opts.create);
if (!opts.compatMake) {
/*
@@ -959,16 +957,16 @@ runTargets(void)
}
/* Traverse the graph, checking on all the targets */
- outOfDate = Make_Run(targs);
+ outOfDate = Make_Run(&targs);
} else {
/*
* Compat_Init will take care of creating all the
* targets as well as initializing the module.
*/
- Compat_Run(targs);
+ Compat_Run(&targs);
outOfDate = FALSE;
}
- Lst_Free(targs);
+ Lst_Done(&targs); /* Don't free the nodes. */
return outOfDate;
}
@@ -982,12 +980,12 @@ InitVarTargets(void)
{
StringListNode *ln;
- if (Lst_IsEmpty(opts.create)) {
+ if (Lst_IsEmpty(&opts.create)) {
Var_Set(".TARGETS", "", VAR_GLOBAL);
return;
}
- for (ln = opts.create->first; ln != NULL; ln = ln->next) {
+ for (ln = opts.create.first; ln != NULL; ln = ln->next) {
char *name = ln->datum;
Var_Append(".TARGETS", name, VAR_GLOBAL);
}
@@ -1040,11 +1038,11 @@ InitVarMachineArch(void)
const int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
size_t len = sizeof machine_arch_buf;
- if (sysctl(mib, __arraycount(mib), machine_arch_buf,
- &len, NULL, 0) < 0) {
- (void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname,
- strerror(errno));
- exit(2);
+ if (sysctl(mib, (unsigned int)__arraycount(mib),
+ machine_arch_buf, &len, NULL, 0) < 0) {
+ (void)fprintf(stderr, "%s: sysctl failed (%s).\n",
+ progname, strerror(errno));
+ exit(2);
}
return machine_arch_buf;
@@ -1077,21 +1075,20 @@ static void
HandlePWD(const struct stat *curdir_st)
{
char *pwd;
- void *prefix_freeIt, *makeobjdir_freeIt;
- const char *makeobjdir;
+ FStr prefix, makeobjdir;
struct stat pwd_st;
if (ignorePWD || (pwd = getenv("PWD")) == NULL)
return;
- if (Var_Value("MAKEOBJDIRPREFIX", VAR_CMDLINE, &prefix_freeIt) !=
- NULL) {
- bmake_free(prefix_freeIt);
+ prefix = Var_Value("MAKEOBJDIRPREFIX", VAR_CMDLINE);
+ if (prefix.str != NULL) {
+ FStr_Done(&prefix);
return;
}
- makeobjdir = Var_Value("MAKEOBJDIR", VAR_CMDLINE, &makeobjdir_freeIt);
- if (makeobjdir != NULL && strchr(makeobjdir, '$') != NULL)
+ makeobjdir = Var_Value("MAKEOBJDIR", VAR_CMDLINE);
+ if (makeobjdir.str != NULL && strchr(makeobjdir.str, '$') != NULL)
goto ignore_pwd;
if (stat(pwd, &pwd_st) == 0 &&
@@ -1100,7 +1097,7 @@ HandlePWD(const struct stat *curdir_st)
(void)strncpy(curdir, pwd, MAXPATHLEN);
ignore_pwd:
- bmake_free(makeobjdir_freeIt);
+ FStr_Done(&makeobjdir);
}
#endif
@@ -1118,7 +1115,7 @@ InitObjdir(const char *machine, const char *machine_arch)
{
Boolean writable;
- Dir_InitDir(curdir);
+ Dir_InitCur(curdir);
writable = GetBooleanVar("MAKE_OBJDIR_CHECK_WRITABLE", TRUE);
(void)Main_SetObjdir(FALSE, "%s", curdir);
@@ -1147,35 +1144,37 @@ UnlimitFiles(void)
static void
CmdOpts_Init(void)
{
- opts.compatMake = FALSE; /* No compat mode */
- opts.debug = 0; /* No debug verbosity, please. */
+ opts.compatMake = FALSE;
+ opts.debug = DEBUG_NONE;
/* opts.debug_file has been initialized earlier */
- opts.lint = FALSE;
+ opts.strict = FALSE;
opts.debugVflag = FALSE;
opts.checkEnvFirst = FALSE;
- opts.makefiles = Lst_New();
+ Lst_Init(&opts.makefiles);
opts.ignoreErrors = FALSE; /* Pay attention to non-zero returns */
- opts.maxJobs = DEFMAXLOCAL; /* Set default local max concurrency */
+ opts.maxJobs = 1;
opts.keepgoing = FALSE; /* Stop on error */
opts.noRecursiveExecute = FALSE; /* Execute all .MAKE targets */
opts.noExecute = FALSE; /* Execute all commands */
- opts.queryFlag = FALSE; /* This is not just a check-run */
+ opts.queryFlag = FALSE;
opts.noBuiltins = FALSE; /* Read the built-in rules */
opts.beSilent = FALSE; /* Print commands as executed */
- opts.touchFlag = FALSE; /* Actually update targets */
+ opts.touchFlag = FALSE;
opts.printVars = PVM_NONE;
- opts.variables = Lst_New();
+ Lst_Init(&opts.variables);
opts.parseWarnFatal = FALSE;
opts.enterFlag = FALSE;
opts.varNoExportEnv = FALSE;
- opts.create = Lst_New();
+ Lst_Init(&opts.create);
}
-/* Initialize MAKE and .MAKE to the path of the executable, so that it can be
+/*
+ * Initialize MAKE and .MAKE to the path of the executable, so that it can be
* found by execvp(3) and the shells, even after a chdir.
*
* If it's a relative path and contains a '/', resolve it to an absolute path.
- * Otherwise keep it as is, assuming it will be found in the PATH. */
+ * Otherwise keep it as is, assuming it will be found in the PATH.
+ */
static void
InitVarMake(const char *argv0)
{
@@ -1183,18 +1182,21 @@ InitVarMake(const char *argv0)
if (argv0[0] != '/' && strchr(argv0, '/') != NULL) {
char pathbuf[MAXPATHLEN];
- const char *abs = cached_realpath(argv0, pathbuf);
+ const char *abspath = cached_realpath(argv0, pathbuf);
struct stat st;
- if (abs != NULL && abs[0] == '/' && stat(make, &st) == 0)
- make = abs;
+ if (abspath != NULL && abspath[0] == '/' &&
+ stat(make, &st) == 0)
+ make = abspath;
}
Var_Set("MAKE", make, VAR_GLOBAL);
Var_Set(".MAKE", make, VAR_GLOBAL);
}
-/* Add the directories from the colon-separated syspath to defSysIncPath.
- * After returning, the contents of syspath is unspecified. */
+/*
+ * Add the directories from the colon-separated syspath to defSysIncPath.
+ * After returning, the contents of syspath is unspecified.
+ */
static void
InitDefSysIncPath(char *syspath)
{
@@ -1237,25 +1239,25 @@ static void
ReadBuiltinRules(void)
{
StringListNode *ln;
- StringList *sysMkPath = Lst_New();
+ StringList sysMkPath = LST_INIT;
Dir_Expand(_PATH_DEFSYSMK,
Lst_IsEmpty(sysIncPath) ? defSysIncPath : sysIncPath,
- sysMkPath);
- if (Lst_IsEmpty(sysMkPath))
+ &sysMkPath);
+ if (Lst_IsEmpty(&sysMkPath))
Fatal("%s: no system rules (%s).", progname, _PATH_DEFSYSMK);
- for (ln = sysMkPath->first; ln != NULL; ln = ln->next)
+ for (ln = sysMkPath.first; ln != NULL; ln = ln->next)
if (ReadMakefile(ln->datum) == 0)
break;
if (ln == NULL)
Fatal("%s: cannot open %s.",
- progname, (const char *)sysMkPath->first->datum);
+ progname, (const char *)sysMkPath.first->datum);
/* Free the list but not the actual filenames since these may still
* be used in GNodes. */
- Lst_Free(sysMkPath);
+ Lst_Done(&sysMkPath);
}
static void
@@ -1276,7 +1278,7 @@ InitMaxJobs(void)
"%s: illegal value for .MAKE.JOBS "
"-- must be positive integer!\n",
progname);
- exit(1);
+ exit(2); /* Not 1 so -q can distinguish error */
}
if (n != opts.maxJobs) {
@@ -1315,7 +1317,7 @@ InitVpath(void)
savec = *cp;
*cp = '\0';
/* Add directory to search path */
- (void)Dir_AddDir(dirSearchPath, path);
+ (void)Dir_AddDir(&dirSearchPath, path);
*cp = savec;
path = cp + 1;
} while (savec == ':');
@@ -1348,18 +1350,20 @@ ReadFirstDefaultMakefile(void)
* since these makefiles do not come from the command line. They
* also have different semantics in that only the first file that
* is found is processed. See ReadAllMakefiles. */
- (void)str2Lst_Append(opts.makefiles, prefs);
+ (void)str2Lst_Append(&opts.makefiles, prefs);
- for (ln = opts.makefiles->first; ln != NULL; ln = ln->next)
+ for (ln = opts.makefiles.first; ln != NULL; ln = ln->next)
if (ReadMakefile(ln->datum) == 0)
break;
free(prefs);
}
-/* Initialize variables such as MAKE, MACHINE, .MAKEFLAGS.
+/*
+ * Initialize variables such as MAKE, MACHINE, .MAKEFLAGS.
* Initialize a few modules.
- * Parse the arguments from MAKEFLAGS and the command line. */
+ * Parse the arguments from MAKEFLAGS and the command line.
+ */
static void
main_Init(int argc, char **argv)
{
@@ -1380,10 +1384,7 @@ main_Init(int argc, char **argv)
InitRandom();
- if ((progname = strrchr(argv[0], '/')) != NULL)
- progname++;
- else
- progname = argv[0];
+ progname = str_basename(argv[0]);
UnlimitFiles();
@@ -1469,6 +1470,10 @@ main_Init(int argc, char **argv)
Var_Set(".MAKE.PID", tmp, VAR_GLOBAL);
snprintf(tmp, sizeof tmp, "%u", getppid());
Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL);
+ snprintf(tmp, sizeof tmp, "%u", getuid());
+ Var_Set(".MAKE.UID", tmp, VAR_GLOBAL);
+ snprintf(tmp, sizeof tmp, "%u", getgid());
+ Var_Set(".MAKE.GID", tmp, VAR_GLOBAL);
}
if (makelevel > 0) {
char pn[1024];
@@ -1545,8 +1550,10 @@ main_Init(int argc, char **argv)
InitDefSysIncPath(syspath);
}
-/* Read the system makefile followed by either makefile, Makefile or the
- * files given by the -f option. Exit on parse errors. */
+/*
+ * Read the system makefile followed by either makefile, Makefile or the
+ * files given by the -f option. Exit on parse errors.
+ */
static void
main_ReadFiles(void)
{
@@ -1554,8 +1561,8 @@ main_ReadFiles(void)
if (!opts.noBuiltins)
ReadBuiltinRules();
- if (!Lst_IsEmpty(opts.makefiles))
- ReadAllMakefiles(opts.makefiles);
+ if (!Lst_IsEmpty(&opts.makefiles))
+ ReadAllMakefiles(&opts.makefiles);
else
ReadFirstDefaultMakefile();
}
@@ -1566,8 +1573,7 @@ main_PrepareMaking(void)
{
/* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
if (!opts.noBuiltins || opts.printVars == PVM_NONE) {
- /* ignore /dev/null and anything starting with "no" */
- (void)Var_Subst("${.MAKE.DEPENDFILE:N/dev/null:Nno*:T}",
+ (void)Var_Subst("${.MAKE.DEPENDFILE}",
VAR_CMDLINE, VARE_WANTRES, &makeDependfile);
if (makeDependfile[0] != '\0') {
/* TODO: handle errors */
@@ -1580,13 +1586,12 @@ main_PrepareMaking(void)
if (enterFlagObj)
printf("%s: Entering directory `%s'\n", progname, objdir);
- MakeMode(NULL);
+ MakeMode();
{
- void *freeIt;
- Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &freeIt),
- VAR_GLOBAL);
- bmake_free(freeIt);
+ FStr makeflags = Var_Value(MAKEFLAGS, VAR_GLOBAL);
+ Var_Append("MFLAGS", makeflags.str, VAR_GLOBAL);
+ FStr_Done(&makeflags);
}
InitMaxJobs();
@@ -1624,9 +1629,11 @@ main_PrepareMaking(void)
Targ_PrintGraph(1);
}
-/* Make the targets.
+/*
+ * Make the targets.
* If the -v or -V options are given, print variables instead.
- * Return whether any of the targets is out-of-date. */
+ * Return whether any of the targets is out-of-date.
+ */
static Boolean
main_Run(void)
{
@@ -1644,9 +1651,13 @@ static void
main_CleanUp(void)
{
#ifdef CLEANUP
- Lst_Destroy(opts.variables, free);
- Lst_Free(opts.makefiles); /* don't free, may be used in GNodes */
- Lst_Destroy(opts.create, free);
+ Lst_DoneCall(&opts.variables, free);
+ /*
+ * Don't free the actual strings from opts.makefiles, they may be
+ * used in GNodes.
+ */
+ Lst_Done(&opts.makefiles);
+ Lst_DoneCall(&opts.create, free);
#endif
/* print the graph now it's been processed if the user requested it */
@@ -1677,7 +1688,7 @@ main_CleanUp(void)
static int
main_Exit(Boolean outOfDate)
{
- if (opts.lint && (errors > 0 || Parse_GetFatals() > 0))
+ if (opts.strict && (main_errors > 0 || Parse_GetFatals() > 0))
return 2; /* Not 1 so -q can distinguish error */
return outOfDate ? 1 : 0;
}
@@ -1695,7 +1706,8 @@ main(int argc, char **argv)
return main_Exit(outOfDate);
}
-/* Open and parse the given makefile, with all its side effects.
+/*
+ * Open and parse the given makefile, with all its side effects.
*
* Results:
* 0 if ok. -1 if couldn't open file.
@@ -1776,7 +1788,7 @@ char *
Cmd_Exec(const char *cmd, const char **errfmt)
{
const char *args[4]; /* Args for invoking the shell */
- int fds[2]; /* Pipe streams */
+ int pipefds[2];
int cpid; /* Child PID */
int pid; /* PID from wait() */
int status; /* command exit status */
@@ -1789,7 +1801,7 @@ Cmd_Exec(const char *cmd, const char **errfmt)
*errfmt = NULL;
- if (!shellName)
+ if (shellName == NULL)
Shell_Init();
/*
* Set up arguments for shell
@@ -1802,27 +1814,27 @@ Cmd_Exec(const char *cmd, const char **errfmt)
/*
* Open a pipe for fetching its output
*/
- if (pipe(fds) == -1) {
+ if (pipe(pipefds) == -1) {
*errfmt = "Couldn't create pipe for \"%s\"";
goto bad;
}
+ Var_ReexportVars();
+
/*
* Fork
*/
switch (cpid = vFork()) {
case 0:
- (void)close(fds[0]); /* Close input side of pipe */
+ (void)close(pipefds[0]); /* Close input side of pipe */
/*
* Duplicate the output stream to the shell's output, then
* shut the extra thing down. Note we don't fetch the error
* stream...why not? Why?
*/
- (void)dup2(fds[1], 1);
- (void)close(fds[1]);
-
- Var_ExportVars();
+ (void)dup2(pipefds[1], 1);
+ (void)close(pipefds[1]);
(void)execv(shellPath, UNCONST(args));
_exit(1);
@@ -1833,14 +1845,14 @@ Cmd_Exec(const char *cmd, const char **errfmt)
goto bad;
default:
- (void)close(fds[1]); /* No need for the writing half */
+ (void)close(pipefds[1]); /* No need for the writing half */
savederr = 0;
Buf_Init(&buf);
do {
char result[BUFSIZ];
- bytes_read = read(fds[0], result, sizeof result);
+ bytes_read = read(pipefds[0], result, sizeof result);
if (bytes_read > 0)
Buf_AddBytes(&buf, result, (size_t)bytes_read);
} while (bytes_read > 0 ||
@@ -1848,8 +1860,7 @@ Cmd_Exec(const char *cmd, const char **errfmt)
if (bytes_read == -1)
savederr = errno;
- (void)close(
- fds[0]); /* Close the input side of the pipe. */
+ (void)close(pipefds[0]); /* Close the input side of the pipe. */
/* Wait for the process to exit. */
while ((pid = waitpid(cpid, &status, 0)) != cpid && pid >= 0)
@@ -1879,10 +1890,12 @@ bad:
return bmake_strdup("");
}
-/* Print a printf-style error message.
+/*
+ * Print a printf-style error message.
*
* In default mode, this error message has no consequences, in particular it
- * does not affect the exit status. Only in lint mode (-dL) it does. */
+ * does not affect the exit status. Only in lint mode (-dL) it does.
+ */
void
Error(const char *fmt, ...)
{
@@ -1904,14 +1917,16 @@ Error(const char *fmt, ...)
break;
err_file = stderr;
}
- errors++;
+ main_errors++;
}
-/* Wait for any running jobs to finish, then produce an error message,
+/*
+ * Wait for any running jobs to finish, then produce an error message,
* finally exit immediately.
*
* Exiting immediately differs from Parse_Error, which exits only after the
- * current top-level makefile has been parsed completely. */
+ * current top-level makefile has been parsed completely.
+ */
void
Fatal(const char *fmt, ...)
{
@@ -1935,8 +1950,10 @@ Fatal(const char *fmt, ...)
exit(2); /* Not 1 so -q can distinguish error */
}
-/* Major exception once jobs are being created.
- * Kills all jobs, prints a message and exits. */
+/*
+ * Major exception once jobs are being created.
+ * Kills all jobs, prints a message and exits.
+ */
void
Punt(const char *fmt, ...)
{
@@ -1964,12 +1981,14 @@ DieHorribly(void)
if (DEBUG(GRAPH2))
Targ_PrintGraph(2);
Trace_Log(MAKEERROR, NULL);
- exit(2); /* Not 1, so -q can distinguish error */
+ exit(2); /* Not 1 so -q can distinguish error */
}
-/* Called when aborting due to errors in child shell to signal abnormal exit.
+/*
+ * Called when aborting due to errors in child shell to signal abnormal exit.
* The program exits.
- * Errors is the number of errors encountered in Make_Make. */
+ * Errors is the number of errors encountered in Make_Make.
+ */
void
Finish(int errs)
{
@@ -2101,7 +2120,7 @@ shouldDieQuietly(GNode *gn, int bf)
else if (bf >= 0)
quietly = bf;
else
- quietly = gn != NULL && (gn->type & OP_MAKE);
+ quietly = (gn != NULL && (gn->type & OP_MAKE)) ? 1 : 0;
}
return quietly;
}
@@ -2117,7 +2136,7 @@ SetErrorVars(GNode *gn)
Var_Set(".ERROR_TARGET", gn->name, VAR_GLOBAL);
Var_Delete(".ERROR_CMD", VAR_GLOBAL);
- for (ln = gn->commands->first; ln != NULL; ln = ln->next) {
+ for (ln = gn->commands.first; ln != NULL; ln = ln->next) {
const char *cmd = ln->datum;
if (cmd == NULL)
@@ -2126,8 +2145,10 @@ SetErrorVars(GNode *gn)
}
}
-/* Print some helpful information in case of an error.
- * The caller should exit soon after calling this function. */
+/*
+ * Print some helpful information in case of an error.
+ * The caller should exit soon after calling this function.
+ */
void
PrintOnError(GNode *gn, const char *msg)
{
@@ -2138,16 +2159,16 @@ PrintOnError(GNode *gn, const char *msg)
Var_Stats();
}
- /* we generally want to keep quiet if a sub-make died */
- if (shouldDieQuietly(gn, -1))
- return;
+ if (errorNode != NULL)
+ return; /* we've been here! */
if (msg != NULL)
printf("%s", msg);
printf("\n%s: stopped in %s\n", progname, curdir);
- if (errorNode != NULL)
- return; /* we've been here! */
+ /* we generally want to keep quiet if a sub-make died */
+ if (shouldDieQuietly(gn, -1))
+ return;
if (gn != NULL)
SetErrorVars(gn);
@@ -2241,11 +2262,10 @@ mkTempFile(const char *pattern, char **out_fname)
if ((fd = mkstemp(tfile)) < 0)
Punt("Could not create temporary file %s: %s", tfile,
strerror(errno));
- if (out_fname) {
+ if (out_fname != NULL) {
*out_fname = bmake_strdup(tfile);
} else {
- unlink(
- tfile); /* we just want the descriptor */
+ unlink(tfile); /* we just want the descriptor */
}
return fd;
}