aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2020-09-05 16:11:04 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2020-09-05 16:11:04 +0000
commit6bbc783f48498b808e19db4441299dc7d85a278b (patch)
treebe201219a56594c76537191ee91fdd3ef8cfb348 /main.c
parent367d32e2b15fe0397ddecccaa04cf9ed0164c969 (diff)
downloadsrc-6bbc783f48498b808e19db4441299dc7d85a278b.tar.gz
src-6bbc783f48498b808e19db4441299dc7d85a278b.zip
Import bmake-20200902vendor/NetBSD/bmake/20200902
Lots of code refactoring, simplification and cleanup. Lots of new unit-tests providing much higher code coverage. All courtesy of rillig at netbsd. Other significant changes: o new read-only variable .SHELL which provides the path of the shell used to run scripts (as defined by the .SHELL target). o new debug option -dl: LINT mode, does the equivalent of := for all variable assignments so that file and line number are reported for variable parse errors.
Notes
Notes: svn path=/vendor/NetBSD/bmake/dist/; revision=365361 svn path=/vendor/NetBSD/bmake/20200902/; revision=365363; tag=vendor/NetBSD/bmake/20200902
Diffstat (limited to 'main.c')
-rw-r--r--main.c376
1 files changed, 172 insertions, 204 deletions
diff --git a/main.c b/main.c
index 25141625e55c..f27320c57451 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $ */
+/* $NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
@@ -81,7 +81,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $");
+__RCSID("$NetBSD: main.c,v 1.331 2020/08/30 19:56:02 rillig Exp $");
#endif
#endif /* not lint */
#endif
@@ -124,13 +124,13 @@ __RCSID("$NetBSD: main.c,v 1.279 2020/07/03 08:13:23 rillig Exp $");
#include <sys/utsname.h>
#include "wait.h"
+#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include <ctype.h>
#include "make.h"
#include "hash.h"
@@ -162,7 +162,8 @@ static Lst makefiles; /* ordered list of makefiles to read */
static int printVars; /* -[vV] argument */
#define COMPAT_VARS 1
#define EXPAND_VARS 2
-static Lst variables; /* list of variables to print */
+static Lst variables; /* list of variables to print
+ * (for -v and -V) */
int maxJobs; /* -j argument */
static int maxJobTokens; /* -j argument */
Boolean compatMake; /* -B argument */
@@ -180,14 +181,13 @@ Boolean beSilent; /* -s flag */
Boolean oldVars; /* variable substitution style */
Boolean checkEnvFirst; /* -e flag */
Boolean parseWarnFatal; /* -W flag */
-Boolean jobServer; /* -J flag */
static int jp_0 = -1, jp_1 = -1; /* ends of parent job pipe */
Boolean varNoExportEnv; /* -X flag */
Boolean doing_depend; /* Set while reading .depend */
static Boolean jobsRunning; /* TRUE if the jobs might be running */
static const char * tracefile;
static void MainParseArgs(int, char **);
-static int ReadMakefile(const void *, const void *);
+static int ReadMakefile(const char *);
static void usage(void) MAKE_ATTR_DEAD;
static void purge_cached_realpaths(void);
@@ -257,7 +257,7 @@ parse_debug_options(const char *argvalue)
for (modules = argvalue; *modules; ++modules) {
switch (*modules) {
case 'A':
- debug = ~0;
+ debug = ~(0|DEBUG_LINT);
break;
case 'a':
debug |= DEBUG_ARCH;
@@ -291,9 +291,15 @@ parse_debug_options(const char *argvalue)
++modules;
}
break;
+ case 'h':
+ debug |= DEBUG_HASH;
+ break;
case 'j':
debug |= DEBUG_JOB;
break;
+ case 'L':
+ debug |= DEBUG_LINT;
+ break;
case 'l':
debug |= DEBUG_LOUD;
break;
@@ -375,7 +381,7 @@ debug_setbuf:
/*
* does path contain any relative components
*/
-static int
+static Boolean
is_relpath(const char *path)
{
const char *cp;
@@ -383,10 +389,7 @@ is_relpath(const char *path)
if (path[0] != '/')
return TRUE;
cp = path;
- do {
- cp = strstr(cp, "/.");
- if (!cp)
- break;
+ while ((cp = strstr(cp, "/.")) != NULL) {
cp += 2;
if (cp[0] == '/' || cp[0] == '\0')
return TRUE;
@@ -394,7 +397,7 @@ is_relpath(const char *path)
if (cp[1] == '/' || cp[1] == '\0')
return TRUE;
}
- } while (cp);
+ }
return FALSE;
}
@@ -416,7 +419,7 @@ static void
MainParseArgs(int argc, char **argv)
{
char *p;
- int c = '?';
+ char c = '?';
int arginc;
char *argvalue;
const char *getopt_def;
@@ -531,7 +534,6 @@ rearg:
} else {
Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
- jobServer = TRUE;
}
break;
case 'N':
@@ -553,7 +555,7 @@ rearg:
case 'v':
if (argvalue == NULL) goto noarg;
printVars = c == 'v' ? EXPAND_VARS : COMPAT_VARS;
- (void)Lst_AtEnd(variables, argvalue);
+ Lst_Append(variables, argvalue);
Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
break;
@@ -581,7 +583,7 @@ rearg:
break;
case 'f':
if (argvalue == NULL) goto noarg;
- (void)Lst_AtEnd(makefiles, argvalue);
+ Lst_Append(makefiles, argvalue);
break;
case 'i':
ignoreErrors = TRUE;
@@ -674,7 +676,7 @@ rearg:
Punt("illegal (null) argument.");
if (*argv[1] == '-' && !dashDash)
goto rearg;
- (void)Lst_AtEnd(create, bmake_strdup(argv[1]));
+ Lst_Append(create, bmake_strdup(argv[1]));
}
return;
@@ -705,12 +707,10 @@ noarg:
void
Main_ParseArgLine(const char *line)
{
- char **argv; /* Manufactured argument vector */
- int argc; /* Number of arguments in argv */
- char *args; /* Space used by the args */
- char *buf, *p1;
- char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
- size_t len;
+ Words words;
+ char *p1;
+ const char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1);
+ char *buf;
if (line == NULL)
return;
@@ -733,21 +733,19 @@ Main_ParseArgLine(const char *line)
return;
}
#endif
- buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2);
- (void)snprintf(buf, len, "%s %s", argv0, line);
+ buf = str_concat3(argv0, " ", line);
free(p1);
- argv = brk_string(buf, &argc, TRUE, &args);
- if (argv == NULL) {
+ words = Str_Words(buf, TRUE);
+ if (words.words == NULL) {
Error("Unterminated quoted string [%s]", buf);
free(buf);
return;
}
free(buf);
- MainParseArgs(argc, argv);
+ MainParseArgs((int)words.len, words.words);
- free(args);
- free(argv);
+ Words_Free(words);
}
Boolean
@@ -775,7 +773,7 @@ Main_SetObjdir(const char *fmt, ...)
(void)fprintf(stderr, "make warning: %s: %s.\n",
path, strerror(errno));
} else {
- strncpy(objdir, path, MAXPATHLEN);
+ snprintf(objdir, sizeof objdir, "%s", path);
Var_Set(".OBJDIR", objdir, VAR_GLOBAL);
setenv("PWD", objdir, 1);
Dir_InitDot();
@@ -792,37 +790,44 @@ Main_SetObjdir(const char *fmt, ...)
static Boolean
Main_SetVarObjdir(const char *var, const char *suffix)
{
- char *p, *path, *xpath;
+ char *path_freeIt;
+ const char *path = Var_Value(var, VAR_CMD, &path_freeIt);
+ const char *xpath;
+ char *xpath_freeIt;
- if ((path = Var_Value(var, VAR_CMD, &p)) == NULL ||
- *path == '\0')
+ if (path == NULL || path[0] == '\0') {
+ bmake_free(path_freeIt);
return FALSE;
+ }
/* expand variable substitutions */
+ xpath = path;
+ xpath_freeIt = NULL;
if (strchr(path, '$') != 0)
- xpath = Var_Subst(NULL, path, VAR_GLOBAL, VARF_WANTRES);
- else
- xpath = path;
+ xpath = xpath_freeIt = Var_Subst(path, VAR_GLOBAL,
+ VARE_WANTRES);
(void)Main_SetObjdir("%s%s", xpath, suffix);
- if (xpath != path)
- free(xpath);
- free(p);
+ bmake_free(xpath_freeIt);
+ bmake_free(path_freeIt);
return TRUE;
}
-/*-
- * ReadAllMakefiles --
- * wrapper around ReadMakefile() to read all.
- *
- * Results:
- * TRUE if ok, FALSE on error
- */
-static int
-ReadAllMakefiles(const void *p, const void *q)
+/* Read and parse the makefile.
+ * Return TRUE if reading the makefile succeeded, for Lst_Find. */
+static Boolean
+ReadMakefileSucceeded(const void *fname, const void *unused)
+{
+ return ReadMakefile(fname) == 0;
+}
+
+/* Read and parse the makefile.
+ * Return TRUE if reading the makefile failed, for Lst_Find. */
+static Boolean
+ReadMakefileFailed(const void *fname, const void *unused)
{
- return ReadMakefile(p, q) == 0;
+ return ReadMakefile(fname) != 0;
}
int
@@ -835,7 +840,7 @@ str2Lst_Append(Lst lp, char *str, const char *sep)
sep = " \t";
for (n = 0, cp = strtok(str, sep); cp; cp = strtok(NULL, sep)) {
- (void)Lst_AtEnd(lp, cp);
+ Lst_Append(lp, cp);
n++;
}
return n;
@@ -863,13 +868,13 @@ siginfo(int signo MAKE_ATTR_UNUSED)
void
MakeMode(const char *mode)
{
- char *mp = NULL;
+ char *mode_freeIt = NULL;
- if (!mode)
- mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}",
- VAR_GLOBAL, VARF_WANTRES);
+ if (mode == NULL)
+ mode = mode_freeIt = Var_Subst("${" MAKE_MODE ":tl}",
+ VAR_GLOBAL, VARE_WANTRES);
- if (mode && *mode) {
+ if (mode[0] != '\0') {
if (strstr(mode, "compat")) {
compatMake = TRUE;
forceJobs = FALSE;
@@ -880,7 +885,7 @@ MakeMode(const char *mode)
#endif
}
- free(mp);
+ free(mode_freeIt);
}
static void
@@ -896,15 +901,13 @@ doPrintVars(void)
else
expandVars = getBoolean(".MAKE.EXPAND_VARIABLES", FALSE);
- for (ln = Lst_First(variables); ln != NULL;
- ln = Lst_Succ(ln)) {
- char *var = (char *)Lst_Datum(ln);
- char *value;
+ for (ln = Lst_First(variables); ln != NULL; ln = LstNode_Next(ln)) {
+ char *var = LstNode_Datum(ln);
+ const char *value;
char *p1;
if (strchr(var, '$')) {
- value = p1 = Var_Subst(NULL, var, VAR_GLOBAL,
- VARF_WANTRES);
+ value = p1 = Var_Subst(var, VAR_GLOBAL, VARE_WANTRES);
} else if (expandVars) {
char tmp[128];
int len = snprintf(tmp, sizeof(tmp), "${%s}", var);
@@ -912,13 +915,12 @@ doPrintVars(void)
if (len >= (int)sizeof(tmp))
Fatal("%s: variable name too big: %s",
progname, var);
- value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL,
- VARF_WANTRES);
+ value = p1 = Var_Subst(tmp, VAR_GLOBAL, VARE_WANTRES);
} else {
value = Var_Value(var, VAR_GLOBAL, &p1);
}
printf("%s\n", value ? value : "");
- free(p1);
+ bmake_free(p1);
}
}
@@ -962,7 +964,7 @@ runTargets(void)
Compat_Run(targs);
outOfDate = FALSE;
}
- Lst_Destroy(targs, NULL);
+ Lst_Free(targs);
return outOfDate;
}
@@ -1079,7 +1081,7 @@ main(int argc, char **argv)
#else
#ifndef MACHINE_ARCH
#ifdef MAKE_MACHINE_ARCH
- machine_arch = MAKE_MACHINE_ARCH;
+ machine_arch = MAKE_MACHINE_ARCH;
#else
machine_arch = "unknown";
#endif
@@ -1113,11 +1115,11 @@ main(int argc, char **argv)
VAR_GLOBAL);
Var_Set(MAKE_DEPENDFILE, ".depend", VAR_GLOBAL);
- create = Lst_Init(FALSE);
- makefiles = Lst_Init(FALSE);
+ create = Lst_Init();
+ makefiles = Lst_Init();
printVars = 0;
debugVflag = FALSE;
- variables = Lst_Init(FALSE);
+ variables = Lst_Init();
beSilent = FALSE; /* Print commands as executed */
ignoreErrors = FALSE; /* Pay attention to non-zero returns */
noExecute = FALSE; /* Execute all commands */
@@ -1199,7 +1201,7 @@ main(int argc, char **argv)
#ifdef USE_META
meta_init();
#endif
- Dir_Init(NULL); /* Dir_* safe to call from MainParseArgs */
+ Dir_Init();
/*
* First snag any flags out of the MAKE environment variable.
@@ -1265,8 +1267,8 @@ main(int argc, char **argv)
(void)strncpy(curdir, pwd, MAXPATHLEN);
}
}
- free(ptmp1);
- free(ptmp2);
+ bmake_free(ptmp1);
+ bmake_free(ptmp2);
}
#endif
Var_Set(".CURDIR", curdir, VAR_GLOBAL);
@@ -1280,7 +1282,7 @@ main(int argc, char **argv)
* and * finally _PATH_OBJDIRPREFIX`pwd`, in that order. If none
* of these paths exist, just use .CURDIR.
*/
- Dir_Init(curdir);
+ Dir_InitDir(curdir);
(void)Main_SetObjdir("%s", curdir);
if (!Main_SetVarObjdir("MAKEOBJDIRPREFIX", curdir) &&
@@ -1312,10 +1314,8 @@ main(int argc, char **argv)
if (!Lst_IsEmpty(create)) {
LstNode ln;
- for (ln = Lst_First(create); ln != NULL;
- ln = Lst_Succ(ln)) {
- char *name = (char *)Lst_Datum(ln);
-
+ for (ln = Lst_First(create); ln != NULL; ln = LstNode_Next(ln)) {
+ char *name = LstNode_Datum(ln);
Var_Append(".TARGETS", name, VAR_GLOBAL);
}
} else
@@ -1327,7 +1327,8 @@ main(int argc, char **argv)
* add the directories from the DEFSYSPATH (more than one may be given
* as dir1:...:dirn) to the system include path.
*/
- if (syspath == NULL || *syspath == '\0')
+ /* XXX: mismatch: the -m option sets sysIncPath, not syspath */
+ if (syspath == NULL || syspath[0] == '\0')
syspath = defsyspath;
else
syspath = bmake_strdup(syspath);
@@ -1353,48 +1354,46 @@ main(int argc, char **argv)
/*
* Read in the built-in rules first, followed by the specified
- * makefile, if it was (makefile != NULL), or the default
- * makefile and Makefile, in that order, if it wasn't.
+ * makefiles, or the default makefile and Makefile, in that order,
+ * if no makefiles were given on the command line.
*/
if (!noBuiltins) {
LstNode ln;
- sysMkPath = Lst_Init(FALSE);
+ sysMkPath = Lst_Init();
Dir_Expand(_PATH_DEFSYSMK,
Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath,
sysMkPath);
if (Lst_IsEmpty(sysMkPath))
Fatal("%s: no system rules (%s).", progname,
_PATH_DEFSYSMK);
- ln = Lst_Find(sysMkPath, NULL, ReadMakefile);
+ ln = Lst_Find(sysMkPath, ReadMakefileSucceeded, NULL);
if (ln == NULL)
Fatal("%s: cannot open %s.", progname,
- (char *)Lst_Datum(ln));
+ (char *)LstNode_Datum(Lst_First(sysMkPath)));
}
if (!Lst_IsEmpty(makefiles)) {
LstNode ln;
- ln = Lst_Find(makefiles, NULL, ReadAllMakefiles);
+ ln = Lst_Find(makefiles, ReadMakefileFailed, NULL);
if (ln != NULL)
Fatal("%s: cannot open %s.", progname,
- (char *)Lst_Datum(ln));
+ (char *)LstNode_Datum(ln));
} else {
- p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
- VAR_CMD, VARF_WANTRES);
- if (p1) {
+ p1 = Var_Subst("${" MAKEFILE_PREFERENCE "}",
+ VAR_CMD, VARE_WANTRES);
(void)str2Lst_Append(makefiles, p1, NULL);
- (void)Lst_Find(makefiles, NULL, ReadMakefile);
+ (void)Lst_Find(makefiles, ReadMakefileSucceeded, NULL);
free(p1);
- }
}
/* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */
if (!noBuiltins || !printVars) {
- makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}",
- VAR_CMD, VARF_WANTRES);
+ makeDependfile = Var_Subst("${.MAKE.DEPENDFILE:T}",
+ VAR_CMD, VARE_WANTRES);
doing_depend = TRUE;
- (void)ReadMakefile(makeDependfile, NULL);
+ (void)ReadMakefile(makeDependfile);
doing_depend = FALSE;
}
@@ -1404,14 +1403,14 @@ main(int argc, char **argv)
MakeMode(NULL);
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
- free(p1);
+ bmake_free(p1);
if (!forceJobs && !compatMake &&
Var_Exists(".MAKE.JOBS", VAR_GLOBAL)) {
char *value;
int n;
- value = Var_Subst(NULL, "${.MAKE.JOBS}", VAR_GLOBAL, VARF_WANTRES);
+ value = Var_Subst("${.MAKE.JOBS}", VAR_GLOBAL, VARE_WANTRES);
n = strtol(value, NULL, 0);
if (n < 1) {
(void)fprintf(stderr, "%s: illegal value for .MAKE.JOBS -- must be positive integer!\n",
@@ -1439,8 +1438,9 @@ main(int argc, char **argv)
if (!compatMake)
Job_ServerStart(maxJobTokens, jp_0, jp_1);
if (DEBUG(JOB))
- fprintf(debug_file, "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
- jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
+ fprintf(debug_file,
+ "job_pipe %d %d, maxjobs %d, tokens %d, compat %d\n",
+ jp_0, jp_1, maxJobs, maxJobTokens, compatMake ? 1 : 0);
if (!printVars)
Main_ExportMAKEFLAGS(TRUE); /* initial export */
@@ -1461,7 +1461,7 @@ main(int argc, char **argv)
*/
static char VPATH[] = "${VPATH}";
- vpath = Var_Subst(NULL, VPATH, VAR_CMD, VARF_WANTRES);
+ vpath = Var_Subst(VPATH, VAR_CMD, VARE_WANTRES);
path = vpath;
do {
/* skip to end of directory */
@@ -1502,9 +1502,9 @@ main(int argc, char **argv)
}
#ifdef CLEANUP
- Lst_Destroy(variables, NULL);
- Lst_Destroy(makefiles, NULL);
- Lst_Destroy(create, (FreeProc *)free);
+ Lst_Free(variables);
+ Lst_Free(makefiles);
+ Lst_Destroy(create, free);
#endif
/* print the graph now it's been processed if the user requested it */
@@ -1522,7 +1522,7 @@ main(int argc, char **argv)
meta_finish();
#endif
Suff_End();
- Targ_End();
+ Targ_End();
Arch_End();
Var_End();
Parse_End();
@@ -1533,23 +1533,16 @@ main(int argc, char **argv)
return outOfDate ? 1 : 0;
}
-/*-
- * ReadMakefile --
- * Open and parse the given makefile.
+/* Open and parse the given makefile, with all its side effects.
*
* Results:
* 0 if ok. -1 if couldn't open file.
- *
- * Side Effects:
- * lots
*/
static int
-ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
+ReadMakefile(const char *fname)
{
- const char *fname = p; /* makefile to read */
int fd;
- size_t len = MAXPATHLEN;
- char *name, *path = bmake_malloc(len);
+ char *name, *path = NULL;
if (!strcmp(fname, "-")) {
Parse_File(NULL /*stdin*/, -1);
@@ -1557,22 +1550,16 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
} else {
/* if we've chdir'd, rebuild the path name */
if (strcmp(curdir, objdir) && *fname != '/') {
- size_t plen = strlen(curdir) + strlen(fname) + 2;
- if (len < plen)
- path = bmake_realloc(path, len = 2 * plen);
-
- (void)snprintf(path, len, "%s/%s", curdir, fname);
+ path = str_concat3(curdir, "/", fname);
fd = open(path, O_RDONLY);
if (fd != -1) {
fname = path;
goto found;
}
+ free(path);
/* If curdir failed, try objdir (ala .depend) */
- plen = strlen(objdir) + strlen(fname) + 2;
- if (len < plen)
- path = bmake_realloc(path, len = 2 * plen);
- (void)snprintf(path, len, "%s/%s", objdir, fname);
+ path = str_concat3(objdir, "/", fname);
fd = open(path, O_RDONLY);
if (fd != -1) {
fname = path;
@@ -1613,31 +1600,32 @@ found:
/*-
* Cmd_Exec --
* Execute the command in cmd, and return the output of that command
- * in a string.
+ * in a string. In the output, newlines are replaced with spaces.
*
* Results:
- * A string containing the output of the command, or the empty string
- * If errnum is not NULL, it contains the reason for the command failure
+ * A string containing the output of the command, or the empty string.
+ * *errfmt returns a format string describing the command failure,
+ * if any, using a single %s conversion specification.
*
* Side Effects:
* The string must be freed by the caller.
*/
char *
-Cmd_Exec(const char *cmd, const char **errnum)
+Cmd_Exec(const char *cmd, const char **errfmt)
{
const char *args[4]; /* Args for invoking the shell */
int fds[2]; /* Pipe streams */
int cpid; /* Child PID */
int pid; /* PID from wait() */
- char *res; /* result */
WAIT_T status; /* command exit status */
Buffer buf; /* buffer to store the result */
+ ssize_t bytes_read;
+ char *res; /* result */
+ size_t res_len;
char *cp;
- int cc; /* bytes read, or -1 */
int savederr; /* saved errno */
-
- *errnum = NULL;
+ *errfmt = NULL;
if (!shellName)
Shell_Init();
@@ -1653,7 +1641,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
* Open a pipe for fetching its output
*/
if (pipe(fds) == -1) {
- *errnum = "Couldn't create pipe for \"%s\"";
+ *errfmt = "Couldn't create pipe for \"%s\"";
goto bad;
}
@@ -1682,7 +1670,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
/*NOTREACHED*/
case -1:
- *errnum = "Couldn't exec \"%s\"";
+ *errfmt = "Couldn't exec \"%s\"";
goto bad;
default:
@@ -1696,12 +1684,12 @@ Cmd_Exec(const char *cmd, const char **errnum)
do {
char result[BUFSIZ];
- cc = read(fds[0], result, sizeof(result));
- if (cc > 0)
- Buf_AddBytes(&buf, cc, result);
+ bytes_read = read(fds[0], result, sizeof(result));
+ if (bytes_read > 0)
+ Buf_AddBytes(&buf, result, (size_t)bytes_read);
}
- while (cc > 0 || (cc == -1 && errno == EINTR));
- if (cc == -1)
+ while (bytes_read > 0 || (bytes_read == -1 && errno == EINTR));
+ if (bytes_read == -1)
savederr = errno;
/*
@@ -1716,43 +1704,28 @@ Cmd_Exec(const char *cmd, const char **errnum)
JobReapChild(pid, status, FALSE);
continue;
}
- cc = Buf_Size(&buf);
+ res_len = Buf_Size(&buf);
res = Buf_Destroy(&buf, FALSE);
if (savederr != 0)
- *errnum = "Couldn't read shell's output for \"%s\"";
+ *errfmt = "Couldn't read shell's output for \"%s\"";
if (WIFSIGNALED(status))
- *errnum = "\"%s\" exited on a signal";
+ *errfmt = "\"%s\" exited on a signal";
else if (WEXITSTATUS(status) != 0)
- *errnum = "\"%s\" returned non-zero status";
-
- /*
- * Null-terminate the result, convert newlines to spaces and
- * install it in the variable.
- */
- res[cc] = '\0';
- cp = &res[cc];
+ *errfmt = "\"%s\" returned non-zero status";
- if (cc > 0 && *--cp == '\n') {
- /*
- * A final newline is just stripped
- */
- *cp-- = '\0';
- }
- while (cp >= res) {
- if (*cp == '\n') {
+ /* Convert newlines to spaces. A final newline is just stripped */
+ if (res_len > 0 && res[res_len - 1] == '\n')
+ res[res_len - 1] = '\0';
+ for (cp = res; *cp != '\0'; cp++)
+ if (*cp == '\n')
*cp = ' ';
- }
- cp--;
- }
break;
}
return res;
bad:
- res = bmake_malloc(1);
- *res = '\0';
- return res;
+ return bmake_strdup("");
}
/*-
@@ -1888,7 +1861,7 @@ DieHorribly(void)
*/
void
Finish(int errors)
- /* number of errors encountered in Make_Make */
+ /* number of errors encountered in Make_Make */
{
if (dieQuietly(NULL, -1))
exit(2);
@@ -1956,13 +1929,13 @@ usage(void)
{
char *p;
if ((p = strchr(progname, '[')) != NULL)
- *p = '\0';
+ *p = '\0';
(void)fprintf(stderr,
-"usage: %s [-BeikNnqrstWwX] \n\
- [-C directory] [-D variable] [-d flags] [-f makefile]\n\
- [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
- [-V variable] [-v variable] [variable=value] [target ...]\n",
+"usage: %s [-BeikNnqrstWwX] \n"
+" [-C directory] [-D variable] [-d flags] [-f makefile]\n"
+" [-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n"
+" [-V variable] [-v variable] [variable=value] [target ...]\n",
progname);
exit(2);
}
@@ -2010,7 +1983,8 @@ char *
cached_realpath(const char *pathname, char *resolved)
{
GNode *cache;
- char *rp, *cp;
+ const char *rp;
+ char *cp;
if (!pathname || !pathname[0])
return NULL;
@@ -2024,7 +1998,7 @@ cached_realpath(const char *pathname, char *resolved)
Var_Set(pathname, rp, cache);
} /* else should we negative-cache? */
- free(cp);
+ bmake_free(cp);
return rp ? resolved : NULL;
}
@@ -2070,9 +2044,14 @@ void
PrintOnError(GNode *gn, const char *s)
{
static GNode *en = NULL;
- char tmp[64];
+ const char *expr;
char *cp;
+ if (DEBUG(HASH)) {
+ Targ_Stats();
+ Var_Stats();
+ }
+
/* we generally want to keep quiet if a sub-make died */
if (dieQuietly(gn, -1))
return;
@@ -2092,14 +2071,10 @@ PrintOnError(GNode *gn, const char *s)
Var_Delete(".ERROR_CMD", VAR_GLOBAL);
Lst_ForEach(gn->commands, addErrorCMD, gn);
}
- strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}",
- sizeof(tmp) - 1);
- cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
- if (cp) {
- if (*cp)
- printf("%s", cp);
- free(cp);
- }
+ expr = "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}";
+ cp = Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES);
+ printf("%s", cp);
+ free(cp);
fflush(stdout);
/*
@@ -2115,18 +2090,17 @@ PrintOnError(GNode *gn, const char *s)
void
Main_ExportMAKEFLAGS(Boolean first)
{
- static int once = 1;
- char tmp[64];
+ static Boolean once = TRUE;
+ const char *expr;
char *s;
if (once != first)
return;
- once = 0;
+ once = FALSE;
- strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
- sizeof(tmp));
- s = Var_Subst(NULL, tmp, VAR_CMD, VARF_WANTRES);
- if (s && *s) {
+ expr = "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}";
+ s = Var_Subst(expr, VAR_CMD, VARE_WANTRES);
+ if (s[0] != '\0') {
#ifdef POSIX
setenv("MAKEFLAGS", s, 1);
#else
@@ -2147,8 +2121,8 @@ getTmpdir(void)
* Honor $TMPDIR but only if it is valid.
* Ensure it ends with /.
*/
- tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
- VARF_WANTRES);
+ tmpdir = Var_Subst("${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
+ VARE_WANTRES);
if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
free(tmpdir);
tmpdir = bmake_strdup(_PATH_TMP);
@@ -2235,18 +2209,12 @@ s2Boolean(const char *s, Boolean bf)
* is FALSE, otherwise TRUE.
*/
Boolean
-getBoolean(const char *name, Boolean bf)
+getBoolean(const char *name, Boolean fallback)
{
- char tmp[64];
- char *cp;
-
- if (snprintf(tmp, sizeof(tmp), "${%s:U:tl}", name) < (int)(sizeof(tmp))) {
- cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
-
- if (cp) {
- bf = s2Boolean(cp, bf);
- free(cp);
- }
- }
- return bf;
+ char *expr = str_concat3("${", name, ":U:tl}");
+ char *value = Var_Subst(expr, VAR_GLOBAL, VARE_WANTRES);
+ Boolean res = s2Boolean(value, fallback);
+ free(value);
+ free(expr);
+ return res;
}