diff options
author | Simon J. Gerraty <sjg@FreeBSD.org> | 2021-01-14 01:24:34 +0000 |
---|---|---|
committer | Simon J. Gerraty <sjg@FreeBSD.org> | 2021-01-14 01:24:34 +0000 |
commit | 8e11a9b4250be3c3379c45fa820bff78d99d5946 (patch) | |
tree | ea4954dbe7647b6211a20458b2a881e3d943639f /main.c | |
parent | 1b65f0bd2bda7121a90f8cb4c1cacaa20f1b681d (diff) | |
download | src-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.c | 364 |
1 files changed, 192 insertions, 172 deletions
@@ -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; } |