diff options
author | Simon J. Gerraty <sjg@FreeBSD.org> | 2020-09-05 16:11:04 +0000 |
---|---|---|
committer | Simon J. Gerraty <sjg@FreeBSD.org> | 2020-09-05 16:11:04 +0000 |
commit | 6bbc783f48498b808e19db4441299dc7d85a278b (patch) | |
tree | be201219a56594c76537191ee91fdd3ef8cfb348 /main.c | |
parent | 367d32e2b15fe0397ddecccaa04cf9ed0164c969 (diff) | |
download | src-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.c | 376 |
1 files changed, 172 insertions, 204 deletions
@@ -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; } |