From ce40971ce25292a0274be1ca4e5af0a73db78dd7 Mon Sep 17 00:00:00 2001 From: "Simon J. Gerraty" Date: Wed, 21 Oct 2015 22:14:23 +0000 Subject: [PATCH] Import bmake-20151020 --- ChangeLog | 37 +++++++ FILES | 2 + Makefile | 5 +- arch.c | 14 +-- compat.c | 54 +++------- cond.c | 12 +-- configure.in | 5 +- for.c | 8 +- job.c | 13 +-- main.c | 40 ++++--- make-bootstrap.sh.in | 2 +- make.c | 8 +- make.h | 11 +- meta.c | 29 ++---- metachar.c | 88 ++++++++++++++++ metachar.h | 61 +++++++++++ mk/ChangeLog | 45 ++++++++ mk/auto.obj.mk | 7 +- mk/dirdeps.mk | 17 ++- mk/doc.mk | 18 ++-- mk/gendirdeps.mk | 8 +- mk/host-target.mk | 17 ++- mk/install-mk | 4 +- mk/meta.autodep.mk | 4 +- mk/meta.stage.mk | 37 ++++--- mk/meta.sys.mk | 7 +- mk/own.mk | 5 +- mk/rst2htm.mk | 13 ++- nonints.h | 6 +- os.sh | 12 ++- parse.c | 22 ++-- suff.c | 10 +- unit-tests/varmisc.exp | 18 ++++ unit-tests/varmisc.mk | 38 ++++++- var.c | 231 ++++++++++++++++++++++------------------- 35 files changed, 631 insertions(+), 277 deletions(-) create mode 100644 metachar.c create mode 100644 metachar.h diff --git a/ChangeLog b/ChangeLog index e1d6f10c3414..ec3255e6ffd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2015-10-20 Simon J. Gerraty + + * Makefile (MAKE_VERSION): 20151020 + Merge with NetBSD make, pick up + o var.c: fix uninitialized var + +2015-10-12 Simon J. Gerraty + + * var.c: the conditional expressions used with ':?' can be + expensive, if already discarding do not evaluate or expand + anything. + +2015-10-10 Simon J. Gerraty + + * Makefile (MAKE_VERSION): 20151010 + Merge with NetBSD make, pick up + o Add Boolean wantit flag to Var_Subst and Var_Parse + when FALSE we know we are discarding the result and can + skip operations like Cmd_Exec. + +2015-10-09 Simon J. Gerraty + + * Makefile (MAKE_VERSION): 20151009 + Merge with NetBSD make, pick up + o var.c: don't check for NULL before free() + o meta.c: meta_oodate, do not hard code ignore of makeDependfile + +2015-09-10 Simon J. Gerraty + + * Makefile (MAKE_VERSION): 20150910 + Merge with NetBSD make, pick up + o main.c: with -w print Enter/Leaving messages for objdir too + if necessary. + o centralize shell metachar handling + + * FILES: add metachar.[ch] + 2015-06-06 Simon J. Gerraty * Makefile (MAKE_VERSION): 20150606 diff --git a/FILES b/FILES index c46e74bd7a46..720eb1b9bfb7 100644 --- a/FILES +++ b/FILES @@ -71,6 +71,8 @@ make_malloc.h makefile.in meta.c meta.h +metachar.c +metachar.h missing/sys/cdefs.h mkdeps.sh nonints.h diff --git a/Makefile b/Makefile index e5427a877f20..a059ec4df01a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ -# $Id: Makefile,v 1.39 2015/06/07 15:54:37 sjg Exp $ +# $Id: Makefile,v 1.44 2015/10/20 21:41:40 sjg Exp $ # Base version on src date -MAKE_VERSION= 20150606 +MAKE_VERSION= 20151020 PROG= bmake @@ -18,6 +18,7 @@ SRCS= \ make.c \ make_malloc.c \ meta.c \ + metachar.c \ parse.c \ str.c \ strlist.c \ diff --git a/arch.c b/arch.c index 943f41ee8392..9ceee10cddb7 100644 --- a/arch.c +++ b/arch.c @@ -1,4 +1,4 @@ -/* $NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $ */ +/* $NetBSD: arch.c,v 1.64 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $"; +static char rcsid[] = "$NetBSD: arch.c,v 1.64 2015/10/11 04:51:24 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94"; #else -__RCSID("$NetBSD: arch.c,v 1.63 2012/06/12 19:21:50 joerg Exp $"); +__RCSID("$NetBSD: arch.c,v 1.64 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -310,7 +310,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) void *freeIt; char *result; - result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt); + result = Var_Parse(cp, ctxt, TRUE, TRUE, &length, &freeIt); if (freeIt) free(freeIt); if (result == var_Error) { @@ -325,7 +325,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) *cp++ = '\0'; if (subLibName) { - libName = Var_Subst(NULL, libName, ctxt, TRUE); + libName = Var_Subst(NULL, libName, ctxt, TRUE, TRUE); } @@ -351,7 +351,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) void *freeIt; char *result; - result = Var_Parse(cp, ctxt, TRUE, &length, &freeIt); + result = Var_Parse(cp, ctxt, TRUE, TRUE, &length, &freeIt); if (freeIt) free(freeIt); if (result == var_Error) { @@ -404,7 +404,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt) char *oldMemName = memName; size_t sz; - memName = Var_Subst(NULL, memName, ctxt, TRUE); + memName = Var_Subst(NULL, memName, ctxt, TRUE, TRUE); /* * Now form an archive spec and recurse to deal with nested diff --git a/compat.c b/compat.c index fd00eb7e03c3..6cf963ffb2da 100644 --- a/compat.c +++ b/compat.c @@ -1,4 +1,4 @@ -/* $NetBSD: compat.c,v 1.96 2014/09/07 20:55:34 joerg Exp $ */ +/* $NetBSD: compat.c,v 1.101 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: compat.c,v 1.96 2014/09/07 20:55:34 joerg Exp $"; +static char rcsid[] = "$NetBSD: compat.c,v 1.101 2015/10/11 04:51:24 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: compat.c,v 1.96 2014/09/07 20:55:34 joerg Exp $"); +__RCSID("$NetBSD: compat.c,v 1.101 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -111,37 +111,14 @@ __RCSID("$NetBSD: compat.c,v 1.96 2014/09/07 20:55:34 joerg Exp $"); #include "hash.h" #include "dir.h" #include "job.h" +#include "metachar.h" #include "pathnames.h" -/* - * The following array is used to make a fast determination of which - * characters are interpreted specially by the shell. If a command - * contains any of these characters, it is executed by the shell, not - * directly by us. - */ - -static char meta[256]; static GNode *curTarg = NULL; static GNode *ENDNode; static void CompatInterrupt(int); -static void -Compat_Init(void) -{ - const char *cp; - - Shell_Init(); /* setup default shell */ - - for (cp = "~#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) { - meta[(unsigned char) *cp] = 1; - } - /* - * The null character serves as a sentinel in the string. - */ - meta[0] = 1; -} - /*- *----------------------------------------------------------------------- * CompatInterrupt -- @@ -236,7 +213,7 @@ CompatRunCommand(void *cmdp, void *gnp) doIt = FALSE; cmdNode = Lst_Member(gn->commands, cmd); - cmdStart = Var_Subst(NULL, cmd, gn, FALSE); + cmdStart = Var_Subst(NULL, cmd, gn, FALSE, TRUE); /* * brk_string will return an argv with a NULL in av[0], thus causing @@ -271,8 +248,8 @@ CompatRunCommand(void *cmdp, void *gnp) break; case '+': doIt = TRUE; - if (!meta[0]) /* we came here from jobs */ - Compat_Init(); + if (!shellName) /* we came here from jobs */ + Shell_Init(); break; } cmd++; @@ -300,11 +277,13 @@ CompatRunCommand(void *cmdp, void *gnp) * Search for meta characters in the command. If there are no meta * characters, there's no need to execute a shell to execute the * command. + * + * Additionally variable assignments and empty commands + * go to the shell. Therefore treat '=' and ':' like shell + * meta characters as documented in make(1). */ - for (cp = cmd; !meta[(unsigned char)*cp]; cp++) { - continue; - } - useShell = (*cp != '\0'); + + useShell = needshell(cmd, FALSE); #endif /* @@ -512,8 +491,8 @@ Compat_Make(void *gnp, void *pgnp) GNode *gn = (GNode *)gnp; GNode *pgn = (GNode *)pgnp; - if (!meta[0]) /* we came here from jobs */ - Compat_Init(); + if (!shellName) /* we came here from jobs */ + Shell_Init(); if (gn->made == UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) { /* * First mark ourselves to be made, then apply whatever transformations @@ -693,7 +672,8 @@ Compat_Run(Lst targs) GNode *gn = NULL;/* Current root target */ int errors; /* Number of targets not remade due to errors */ - Compat_Init(); + if (!shellName) + Shell_Init(); if (bmake_signal(SIGINT, SIG_IGN) != SIG_IGN) { bmake_signal(SIGINT, CompatInterrupt); diff --git a/cond.c b/cond.c index b05a56cbcc86..2d2f08760c7a 100644 --- a/cond.c +++ b/cond.c @@ -1,4 +1,4 @@ -/* $NetBSD: cond.c,v 1.68 2015/05/05 21:51:09 sjg Exp $ */ +/* $NetBSD: cond.c,v 1.69 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: cond.c,v 1.68 2015/05/05 21:51:09 sjg Exp $"; +static char rcsid[] = "$NetBSD: cond.c,v 1.69 2015/10/11 04:51:24 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94"; #else -__RCSID("$NetBSD: cond.c,v 1.68 2015/05/05 21:51:09 sjg Exp $"); +__RCSID("$NetBSD: cond.c,v 1.69 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -289,7 +289,7 @@ CondGetArg(char **linePtr, char **argPtr, const char *func) int len; void *freeIt; - cp2 = Var_Parse(cp, VAR_CMD, TRUE, &len, &freeIt); + cp2 = Var_Parse(cp, VAR_CMD, TRUE, TRUE, &len, &freeIt); Buf_AddBytes(&buf, strlen(cp2), cp2); if (freeIt) free(freeIt); @@ -571,7 +571,7 @@ CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS) case '$': /* if we are in quotes, then an undefined variable is ok */ str = Var_Parse(condExpr, VAR_CMD, (qt ? 0 : doEval), - &len, freeIt); + TRUE, &len, freeIt); if (str == var_Error) { if (*freeIt) { free(*freeIt); @@ -823,7 +823,7 @@ get_mpt_arg(char **linePtr, char **argPtr, const char *func MAKE_ATTR_UNUSED) /* We do all the work here and return the result as the length */ *argPtr = NULL; - val = Var_Parse(cp - 1, VAR_CMD, FALSE, &length, &freeIt); + val = Var_Parse(cp - 1, VAR_CMD, FALSE, TRUE, &length, &freeIt); /* * Advance *linePtr to beyond the closing ). Note that * we subtract one because 'length' is calculated from 'cp - 1'. diff --git a/configure.in b/configure.in index e2249b0db261..ae3e425f16af 100644 --- a/configure.in +++ b/configure.in @@ -1,11 +1,11 @@ dnl dnl RCSid: -dnl $Id: configure.in,v 1.53 2014/11/06 01:49:40 sjg Exp $ +dnl $Id: configure.in,v 1.54 2015/10/10 04:17:10 sjg Exp $ dnl dnl Process this file with autoconf to produce a configure script dnl AC_PREREQ(2.50) -AC_INIT([bmake], [20140214], [sjg@NetBSD.org]) +AC_INIT([bmake], [20151009], [sjg@NetBSD.org]) AC_CONFIG_HEADERS(config.h) dnl make srcdir absolute @@ -105,6 +105,7 @@ AC_CHECK_HEADERS( \ ar.h \ err.h \ fcntl.h \ + limits.h \ paths.h \ poll.h \ ranlib.h \ diff --git a/for.c b/for.c index 33bcf1392b8e..7f10e5626f9a 100644 --- a/for.c +++ b/for.c @@ -1,4 +1,4 @@ -/* $NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $ */ +/* $NetBSD: for.c,v 1.50 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1992, The Regents of the University of California. @@ -30,14 +30,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $"; +static char rcsid[] = "$NetBSD: for.c,v 1.50 2015/10/11 04:51:24 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: for.c,v 1.49 2012/06/03 04:29:40 sjg Exp $"); +__RCSID("$NetBSD: for.c,v 1.50 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -216,7 +216,7 @@ For_Eval(char *line) * We can't do the escapes here - because we don't know whether * we are substuting into ${...} or $(...). */ - sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE); + sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE, TRUE); /* * Split into words allowing for quoted strings. diff --git a/job.c b/job.c index 6dfdce4c2ff4..cc209e6c136f 100644 --- a/job.c +++ b/job.c @@ -1,4 +1,4 @@ -/* $NetBSD: job.c,v 1.180 2015/04/16 13:31:03 joerg Exp $ */ +/* $NetBSD: job.c,v 1.181 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. @@ -70,14 +70,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: job.c,v 1.180 2015/04/16 13:31:03 joerg Exp $"; +static char rcsid[] = "$NetBSD: job.c,v 1.181 2015/10/11 04:51:24 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: job.c,v 1.180 2015/04/16 13:31:03 joerg Exp $"); +__RCSID("$NetBSD: job.c,v 1.181 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -715,7 +715,7 @@ JobPrintCommand(void *cmdp, void *jobp) numCommands += 1; - cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE); + cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE, TRUE); cmdTemplate = "%s\n"; @@ -903,7 +903,7 @@ JobPrintCommand(void *cmdp, void *jobp) static int JobSaveCommand(void *cmd, void *gn) { - cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, FALSE); + cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, FALSE, TRUE); (void)Lst_AtEnd(postCommands->commands, cmd); return(0); } @@ -2194,7 +2194,8 @@ Job_SetPrefix(void) Var_Set(MAKE_JOB_PREFIX, "---", VAR_GLOBAL, 0); } - targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}", VAR_GLOBAL, 0); + targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}", + VAR_GLOBAL, FALSE, TRUE); } /*- diff --git a/main.c b/main.c index 3287115cf8b2..d7fe53412900 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.232 2015/03/26 22:20:42 sjg Exp $ */ +/* $NetBSD: main.c,v 1.234 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,7 +69,7 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: main.c,v 1.232 2015/03/26 22:20:42 sjg Exp $"; +static char rcsid[] = "$NetBSD: main.c,v 1.234 2015/10/11 04:51:24 sjg Exp $"; #else #include #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.232 2015/03/26 22:20:42 sjg Exp $"); +__RCSID("$NetBSD: main.c,v 1.234 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -172,6 +172,7 @@ Boolean keepgoing; /* -k flag */ Boolean queryFlag; /* -q flag */ Boolean touchFlag; /* -t flag */ Boolean enterFlag; /* -w flag */ +Boolean enterFlagObj; /* -w and objdir != srcdir */ Boolean ignoreErrors; /* -i flag */ Boolean beSilent; /* -s flag */ Boolean oldVars; /* variable substitution style */ @@ -722,7 +723,7 @@ Main_SetObjdir(const char *path) /* expand variable substitutions */ if (strchr(path, '$') != 0) { snprintf(buf, MAXPATHLEN, "%s", path); - path = p = Var_Subst(NULL, buf, VAR_GLOBAL, 0); + path = p = Var_Subst(NULL, buf, VAR_GLOBAL, FALSE, TRUE); } if (path[0] != '/') { @@ -741,6 +742,8 @@ Main_SetObjdir(const char *path) setenv("PWD", objdir, 1); Dir_InitDot(); rc = TRUE; + if (enterFlag && strcmp(objdir, curdir) != 0) + enterFlagObj = TRUE; } } @@ -803,7 +806,8 @@ MakeMode(const char *mode) char *mp = NULL; if (!mode) - mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", VAR_GLOBAL, 0); + mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}", + VAR_GLOBAL, FALSE, TRUE); if (mode && *mode) { if (strstr(mode, "compat")) { @@ -1249,7 +1253,7 @@ main(int argc, char **argv) (char *)Lst_Datum(ln)); } else { p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}", - VAR_CMD, 0); + VAR_CMD, FALSE, TRUE); if (p1) { (void)str2Lst_Append(makefiles, p1, NULL); (void)Lst_Find(makefiles, NULL, ReadMakefile); @@ -1260,12 +1264,15 @@ main(int argc, char **argv) /* In particular suppress .depend for '-r -V .OBJDIR -f /dev/null' */ if (!noBuiltins || !printVars) { makeDependfile = Var_Subst(NULL, "${.MAKE.DEPENDFILE:T}", - VAR_CMD, 0); + VAR_CMD, FALSE, TRUE); doing_depend = TRUE; (void)ReadMakefile(makeDependfile, NULL); doing_depend = FALSE; } + if (enterFlagObj) + printf("%s: Entering directory `%s'\n", progname, objdir); + MakeMode(NULL); Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); @@ -1295,7 +1302,7 @@ main(int argc, char **argv) */ static char VPATH[] = "${VPATH}"; - vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); + vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE, TRUE); path = vpath; do { /* skip to end of directory */ @@ -1342,14 +1349,16 @@ main(int argc, char **argv) char *value; if (strchr(var, '$')) { - value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, 0); + value = p1 = Var_Subst(NULL, var, VAR_GLOBAL, + FALSE, TRUE); } else if (expandVars) { char tmp[128]; if (snprintf(tmp, sizeof(tmp), "${%s}", var) >= (int)(sizeof(tmp))) Fatal("%s: variable name too big: %s", progname, var); - value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL, + FALSE, TRUE); } else { value = Var_Value(var, VAR_GLOBAL, &p1); } @@ -1406,6 +1415,8 @@ main(int argc, char **argv) Trace_Log(MAKEEND, 0); + if (enterFlagObj) + printf("%s: Leaving directory `%s'\n", progname, objdir); if (enterFlag) printf("%s: Leaving directory `%s'\n", progname, curdir); @@ -1885,7 +1896,7 @@ PrintOnError(GNode *gn, const char *s) } strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}", sizeof(tmp) - 1); - cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + cp = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); if (cp) { if (*cp) printf("%s", cp); @@ -1914,7 +1925,7 @@ Main_ExportMAKEFLAGS(Boolean first) strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}", sizeof(tmp)); - s = Var_Subst(NULL, tmp, VAR_CMD, 0); + s = Var_Subst(NULL, tmp, VAR_CMD, FALSE, TRUE); if (s && *s) { #ifdef POSIX setenv("MAKEFLAGS", s, 1); @@ -1936,7 +1947,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, 0); + tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL, + FALSE, TRUE); if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) { free(tmpdir); tmpdir = bmake_strdup(_PATH_TMP); @@ -1991,7 +2003,7 @@ getBoolean(const char *name, Boolean bf) char *cp; if (snprintf(tmp, sizeof(tmp), "${%s:tl}", name) < (int)(sizeof(tmp))) { - cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + cp = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); if (cp) { switch(*cp) { diff --git a/make-bootstrap.sh.in b/make-bootstrap.sh.in index 2bb4c25a7058..638e29319ba2 100755 --- a/make-bootstrap.sh.in +++ b/make-bootstrap.sh.in @@ -52,7 +52,7 @@ do_link() { } BASE_OBJECTS="arch.o buf.o compat.o cond.o dir.o for.o getopt hash.o \ -job.o make.o make_malloc.o parse.o sigcompat.o str.o strlist.o \ +job.o make.o make_malloc.o metachar.o parse.o sigcompat.o str.o strlist.o \ suff.o targ.o trace.o var.o util.o" LST_OBJECTS="lstAppend.o lstDupl.o lstInit.o lstOpen.o \ diff --git a/make.c b/make.c index fde185065fab..b43bfd578cf0 100644 --- a/make.c +++ b/make.c @@ -1,4 +1,4 @@ -/* $NetBSD: make.c,v 1.91 2014/10/18 08:33:30 snj Exp $ */ +/* $NetBSD: make.c,v 1.92 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: make.c,v 1.91 2014/10/18 08:33:30 snj Exp $"; +static char rcsid[] = "$NetBSD: make.c,v 1.92 2015/10/11 04:51:24 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93"; #else -__RCSID("$NetBSD: make.c,v 1.91 2014/10/18 08:33:30 snj Exp $"); +__RCSID("$NetBSD: make.c,v 1.92 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -485,7 +485,7 @@ Make_HandleUse(GNode *cgn, GNode *pgn) if (gn->name) free(gn->name); } - gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE); + gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE, TRUE); if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) { /* See if we have a target for this node. */ tgn = Targ_FindNode(gn->name, TARG_NOCREATE); diff --git a/make.h b/make.h index 9cf7243b58c9..7cf34d82e0a6 100644 --- a/make.h +++ b/make.h @@ -1,4 +1,4 @@ -/* $NetBSD: make.h,v 1.95 2014/09/07 20:55:34 joerg Exp $ */ +/* $NetBSD: make.h,v 1.96 2015/09/21 21:50:16 pooka Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -519,8 +519,15 @@ int str2Lst_Append(Lst, char *, const char *); #define MAX(a, b) ((a > b) ? a : b) #endif +/* At least GNU/Hurd systems lack hardcoded MAXPATHLEN/PATH_MAX */ +#ifdef HAVE_LIMITS_H +#include +#endif #ifndef MAXPATHLEN -#define MAXPATHLEN BMAKE_PATH_MAX +#define MAXPATHLEN BMAKE_PATH_MAX +#endif +#ifndef PATH_MAX +#define PATH_MAX MAXPATHLEN #endif #endif /* _MAKE_H_ */ diff --git a/meta.c b/meta.c index 5600a772bed4..09febfc4c1fd 100644 --- a/meta.c +++ b/meta.c @@ -1,4 +1,4 @@ -/* $NetBSD: meta.c,v 1.38 2015/04/11 05:24:30 sjg Exp $ */ +/* $NetBSD: meta.c,v 1.40 2015/10/11 04:51:24 sjg Exp $ */ /* * Implement 'meta' mode. @@ -324,7 +324,7 @@ is_submake(void *cmdp, void *gnp) } cp = strchr(cmd, '$'); if ((cp)) { - mp = Var_Subst(NULL, cmd, gn, FALSE); + mp = Var_Subst(NULL, cmd, gn, FALSE, TRUE); cmd = mp; } cp2 = strstr(cmd, p_make); @@ -367,7 +367,7 @@ printCMD(void *cmdp, void *mfpp) char *cp = NULL; if (strchr(cmd, '$')) { - cmd = cp = Var_Subst(NULL, cmd, mfp->gn, FALSE); + cmd = cp = Var_Subst(NULL, cmd, mfp->gn, FALSE, TRUE); } fprintf(mfp->fp, "CMD %s\n", cmd); if (cp) @@ -462,7 +462,7 @@ meta_create(BuildMon *pbm, GNode *gn) char *mp; /* Describe the target we are building */ - mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, 0); + mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, FALSE, TRUE); if (*mp) fprintf(stdout, "%s\n", mp); free(mp); @@ -605,7 +605,8 @@ meta_mode_init(const char *make_mode) * We consider ourselves master of all within ${.MAKE.META.BAILIWICK} */ metaBailiwick = Lst_Init(FALSE); - cp = Var_Subst(NULL, "${.MAKE.META.BAILIWICK:O:u:tA}", VAR_GLOBAL, 0); + cp = Var_Subst(NULL, "${.MAKE.META.BAILIWICK:O:u:tA}", VAR_GLOBAL, + FALSE, TRUE); if (cp) { str2Lst_Append(metaBailiwick, cp, NULL); } @@ -616,7 +617,8 @@ meta_mode_init(const char *make_mode) Var_Append(MAKE_META_IGNORE_PATHS, "/dev /etc /proc /tmp /var/run /var/tmp ${TMPDIR}", VAR_GLOBAL); cp = Var_Subst(NULL, - "${" MAKE_META_IGNORE_PATHS ":O:u:tA}", VAR_GLOBAL, 0); + "${" MAKE_META_IGNORE_PATHS ":O:u:tA}", VAR_GLOBAL, + FALSE, TRUE); if (cp) { str2Lst_Append(metaIgnorePaths, cp, NULL); } @@ -727,7 +729,8 @@ meta_job_output(Job *job, char *cp, const char *nl) if (!meta_prefix) { char *cp2; - meta_prefix = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", VAR_GLOBAL, 0); + meta_prefix = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", + VAR_GLOBAL, FALSE, TRUE); if ((cp2 = strchr(meta_prefix, '$'))) meta_prefix_len = cp2 - meta_prefix; else @@ -1209,16 +1212,6 @@ meta_oodate(GNode *gn, Boolean oodate) break; } - if ((cp = strrchr(p, '/'))) { - cp++; - /* - * We don't normally expect to see this, - * but we do expect it to change. - */ - if (strcmp(cp, makeDependfile) == 0) - break; - } - /* * The rest of the record is the file name. * Check if it's not an absolute path. @@ -1322,7 +1315,7 @@ meta_oodate(GNode *gn, Boolean oodate) if (DEBUG(META)) fprintf(debug_file, "%s: %d: cannot compare command using .OODATE\n", fname, lineno); } - cmd = Var_Subst(NULL, cmd, gn, TRUE); + cmd = Var_Subst(NULL, cmd, gn, TRUE, TRUE); if ((cp = strchr(cmd, '\n'))) { int n; diff --git a/metachar.c b/metachar.c new file mode 100644 index 000000000000..49603383e660 --- /dev/null +++ b/metachar.c @@ -0,0 +1,88 @@ +/* $NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#if defined(MAKE_NATIVE) || defined(HAVE_NBTOOL_CONFIG_H) +#include +#endif + +#if defined(__RCSID) && !defined(lint) +__RCSID("$NetBSD: metachar.c,v 1.5 2015/06/19 08:03:35 mlelstv Exp $"); +#endif + +#include "metachar.h" +/* + * The following array is used to make a fast determination of which + * characters are interpreted specially by the shell. If a command + * contains any of these characters, it is executed by the shell, not + * directly by us. + * + * perhaps move it to ctype? + */ + +unsigned char _metachar[128] = { +// nul soh stx etx eot enq ack bel + 1, 0, 0, 0, 0, 0, 0, 0, +// bs ht nl vt np cr so si + 0, 0, 1, 0, 0, 0, 0, 0, +// dle dc1 dc2 dc3 dc4 nak syn etb + 0, 0, 0, 0, 0, 0, 0, 0, +// can em sub esc fs gs rs us + 0, 0, 0, 0, 0, 0, 0, 0, +// sp ! " # $ % & ' + 0, 1, 1, 1, 1, 0, 1, 1, +// ( ) * + , - . / + 1, 1, 1, 0, 0, 0, 0, 0, +// 0 1 2 3 4 5 6 7 + 0, 0, 0, 0, 0, 0, 0, 0, +// 8 9 : ; < = > ? + 0, 0, 0, 1, 1, 0, 1, 1, +// @ A B C D E F G + 0, 0, 0, 0, 0, 0, 0, 0, +// H I J K L M N O + 0, 0, 0, 0, 0, 0, 0, 0, +// P Q R S T U V W + 0, 0, 0, 0, 0, 0, 0, 0, +// X Y Z [ \ ] ^ _ + 0, 0, 0, 1, 1, 1, 1, 0, +// ` a b c d e f g + 1, 0, 0, 0, 0, 0, 0, 0, +// h i j k l m n o + 0, 0, 0, 0, 0, 0, 0, 0, +// p q r s t u v w + 0, 0, 0, 0, 0, 0, 0, 0, +// x y z { | } ~ del + 0, 0, 0, 1, 1, 1, 1, 0, +}; + diff --git a/metachar.h b/metachar.h new file mode 100644 index 000000000000..db88d671067e --- /dev/null +++ b/metachar.h @@ -0,0 +1,61 @@ +/* $NetBSD: metachar.h,v 1.4 2015/06/21 20:26:02 christos Exp $ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _METACHAR_H +#define _METACHAR_H + +#include + +extern unsigned char _metachar[]; + +#define ismeta(c) _metachar[(c) & 0x7f] + +static inline int +hasmeta(const char *cmd) +{ + while (!ismeta(*cmd)) + cmd++; + + return *cmd != '\0'; +} + +static inline int +needshell(const char *cmd, int white) +{ + while (!ismeta(*cmd) && *cmd != ':' && *cmd != '=') { + if (white && isspace((unsigned char)*cmd)) + break; + cmd++; + } + + return *cmd != '\0'; +} + +#endif /* _METACHAR_H */ diff --git a/mk/ChangeLog b/mk/ChangeLog index 85c8ae1715b2..e7f71b5ffb40 100644 --- a/mk/ChangeLog +++ b/mk/ChangeLog @@ -1,3 +1,48 @@ +2015-10-20 Simon J. Gerraty + + * install-mk (MK_VERSION): 20151020 + + * dirdeps.mk: Add logic for + make -f dirdeps.mk some/dir.${TARGET_SPEC} + +2015-10-14 Simon J. Gerraty + + * install-mk (MK_VERSION): 20151010 + +2015-10-02 Simon J. Gerraty + + * meta.stage.mk: use staging: ${STAGE_TARGETS:... + to have stage_lins run last in non-jobs mode. + Use .ORDER only for jobs mode. + +2015-09-02 Simon J. Gerraty + + * rst2htm.mk: allow for per target flags etc. + +2015-09-01 Simon J. Gerraty + + * install-mk (MK_VERSION): 20150901 + + * doc.mk: create dir if needed use DOC_INSTALL_OWN + +2015-06-15 Simon J. Gerraty + + * install-mk (MK_VERSION): 20150615 + + * auto.obj.mk: allow use of MAKEOBJDIRPREFIX too. + Follow make's normal precedence rules. + + * gendirdeps.mk: allow customization of the header. + eg. for FreeBSD: + GENDIRDEPS_HEADER= echo '\# ${FreeBSD:L:@v@$$$v$$ @:M*F*}'; + + * meta.autodep.mk: ignore dirdeps.cache* + + * meta.stage.mk: when bootstrapping options it can be handy to + throw warnings rather than errors for staging conflicts. + + * meta.sys.mk: include local.meta.sys.mk for customization + 2015-06-06 Simon J. Gerraty * install-mk (MK_VERSION): 20150606 diff --git a/mk/auto.obj.mk b/mk/auto.obj.mk index e25a721cdf69..fee3de29b7d5 100644 --- a/mk/auto.obj.mk +++ b/mk/auto.obj.mk @@ -1,4 +1,4 @@ -# $Id: auto.obj.mk,v 1.10 2015/04/16 16:59:00 sjg Exp $ +# $Id: auto.obj.mk,v 1.11 2015/06/16 06:28:21 sjg Exp $ # # @(#) Copyright (c) 2004, Simon J. Gerraty # @@ -40,7 +40,10 @@ MKOBJDIRS= auto .if !defined(NOOBJ) && !defined(NO_OBJ) && ${MKOBJDIRS:Uno} == auto # Use __objdir here so it is easier to tweak without impacting # the logic. -__objdir?= ${MAKEOBJDIR} +.if !empty(MAKEOBJDIRPREFIX) && exists(${MAKEOBJDIRPREFIX}) +__objdir?= ${MAKEOBJDIRPREFIX}${.CURDIR} +.endif +__objdir?= ${MAKEOBJDIR:Uobj} __objdir:= ${__objdir:tA} .if ${.OBJDIR} != ${__objdir} # We need to chdir, make the directory if needed diff --git a/mk/dirdeps.mk b/mk/dirdeps.mk index 4aa101fbd8d0..823115d7a8ce 100644 --- a/mk/dirdeps.mk +++ b/mk/dirdeps.mk @@ -1,4 +1,4 @@ -# $Id: dirdeps.mk,v 1.54 2015/06/08 20:55:11 sjg Exp $ +# $Id: dirdeps.mk,v 1.55 2015/10/20 22:04:53 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -242,6 +242,21 @@ DEP_${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]} DEP_MACHINE := ${_DEP_TARGET_SPEC} .endif +.if ${MAKEFILE:T} == ${.PARSEFILE} && empty(DIRDEPS) && ${.TARGETS:Uall:M*/*} != "" +# This little trick let's us do +# +# mk -f dirdeps.mk some/dir.${TARGET_SPEC} +# +all: +${.TARGETS:Nall}: all +DIRDEPS := ${.TARGETS:M*/*} +# so that -DNO_DIRDEPS works +DEP_RELDIR := ${DIRDEPS:R:[1]} +# disable DIRDEPS_CACHE as it does not like this trick +MK_DIRDEPS_CACHE = no +.endif + + # pickup customizations # as below you can use !target(_DIRDEP_USE) to protect things # which should only be done once. diff --git a/mk/doc.mk b/mk/doc.mk index d496c42aeefb..d1385e9a4e82 100644 --- a/mk/doc.mk +++ b/mk/doc.mk @@ -1,4 +1,4 @@ -# $Id: doc.mk,v 1.4 2012/11/11 22:37:02 sjg Exp $ +# $Id: doc.mk,v 1.5 2015/09/08 06:15:31 sjg Exp $ .if !target(__${.PARSEFILE}__) __${.PARSEFILE}__: @@ -47,17 +47,19 @@ install: .else FILES?= ${SRCS} install: - ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m 444 \ - Makefile ${FILES} ${EXTRA} ${DESTDIR}${BINDIR}/${DIR} + test -d ${DESTDIR}${DOCDIR}/${DIR} || \ + ${INSTALL} -d ${DOC_INSTALL_OWN} -m ${DIRMODE} ${DESTDIR}${DOCDIR}/${DIR} + ${INSTALL} ${COPY} ${DOC_INSTALL_OWN} -m ${DOCMODE} \ + Makefile ${FILES} ${EXTRA} ${DESTDIR}${DOCDIR}/${DIR} .endif spell: ${SRCS} spell ${SRCS} | sort | comm -23 - spell.ok > paper.spell -BINDIR?= /usr/share/doc -BINGRP?= bin -BINOWN?= bin -BINMODE?= 444 - .include + +.if !empty(DOCOWN) +DOC_INSTALL_OWN?= -o ${DOCOWN} -g ${DOGGRP} +.endif + .endif diff --git a/mk/gendirdeps.mk b/mk/gendirdeps.mk index 614a20e3d451..2497f853c3b6 100644 --- a/mk/gendirdeps.mk +++ b/mk/gendirdeps.mk @@ -1,4 +1,4 @@ -# $Id: gendirdeps.mk,v 1.27 2015/06/08 20:55:11 sjg Exp $ +# $Id: gendirdeps.mk,v 1.29 2015/10/03 05:00:46 sjg Exp $ # Copyright (c) 2010-2013, Juniper Networks, Inc. # All rights reserved. @@ -157,7 +157,7 @@ M2D_OBJROOTS += ${SB_BACKING_SB}/${SB_OBJPREFIX} .endif # we are only interested in the dirs -# sepecifically those we read something from. +# specifically those we read something from. # we canonicalize them to keep things simple # if we are using a split-fs sandbox, it gets a little messier. _objtop := ${_OBJTOP:tA} @@ -310,7 +310,7 @@ CAT_DEPEND ?= .depend # The sed command at the end of the stream, allows for the filters # to output _{VAR} tokens which we will turn into proper ${VAR} references. ${_DEPENDFILE}: ${CAT_DEPEND:M.depend} ${META_FILES:O:u:@m@${exists($m):?$m:}@} ${_this} ${META2DEPS} - @(echo '# Autogenerated - do NOT edit!'; echo; \ + @(${GENDIRDEPS_HEADER} echo '# Autogenerated - do NOT edit!'; echo; \ echo 'DIRDEPS = \'; \ echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \ ${_include_src_dirdeps} \ @@ -330,7 +330,7 @@ DIRDEPS := ${SUBDIR:S,^,${RELDIR}/,:O:u} all: ${_DEPENDFILE} ${_DEPENDFILE}: ${MAKEFILE} ${_this} - @(echo '# Autogenerated - do NOT edit!'; echo; \ + @(${GENDIRDEPS_HEADER} echo '# Autogenerated - do NOT edit!'; echo; \ echo 'DIRDEPS = \'; \ echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \ echo '.include '; \ diff --git a/mk/host-target.mk b/mk/host-target.mk index eacdf1d95111..b67c34d2523c 100644 --- a/mk/host-target.mk +++ b/mk/host-target.mk @@ -1,5 +1,5 @@ # RCSid: -# $Id: host-target.mk,v 1.7 2014/05/16 17:54:52 sjg Exp $ +# $Id: host-target.mk,v 1.9 2015/09/10 18:42:57 sjg Exp $ # Host platform information; may be overridden .if !defined(_HOST_OSNAME) @@ -10,16 +10,25 @@ _HOST_OSNAME != uname -s _HOST_OSREL != uname -r .export _HOST_OSREL .endif +.if !defined(_HOST_MACHINE) +_HOST_MACHINE != uname -m +.export _HOST_MACHINE +.endif .if !defined(_HOST_ARCH) -_HOST_ARCH != uname -p 2>/dev/null || uname -m +# for NetBSD prefer $MACHINE (amd64 rather than x86_64) +.if ${_HOST_OSNAME:NNetBSD} == "" +_HOST_ARCH := ${_HOST_MACHINE} +.else +_HOST_ARCH != uname -p 2> /dev/null || uname -m # uname -p may produce garbage on linux .if ${_HOST_ARCH:[\#]} > 1 -_HOST_ARCH != uname -m +_HOST_ARCH := ${_HOST_MACHINE} +.endif .endif .export _HOST_ARCH .endif .if !defined(HOST_MACHINE) -HOST_MACHINE != uname -m +HOST_MACHINE := ${_HOST_MACHINE} .export HOST_MACHINE .endif diff --git a/mk/install-mk b/mk/install-mk index 05facd549ee9..eca75e00df66 100644 --- a/mk/install-mk +++ b/mk/install-mk @@ -55,7 +55,7 @@ # Simon J. Gerraty # RCSid: -# $Id: install-mk,v 1.112 2015/06/08 20:55:11 sjg Exp $ +# $Id: install-mk,v 1.115 2015/10/20 22:04:53 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -70,7 +70,7 @@ # sjg@crufty.net # -MK_VERSION=20150606 +MK_VERSION=20151020 OWNER= GROUP= MODE=444 diff --git a/mk/meta.autodep.mk b/mk/meta.autodep.mk index 64bc30bd4757..a062e47f92c8 100644 --- a/mk/meta.autodep.mk +++ b/mk/meta.autodep.mk @@ -1,4 +1,4 @@ -# $Id: meta.autodep.mk,v 1.36 2014/08/02 23:10:29 sjg Exp $ +# $Id: meta.autodep.mk,v 1.37 2015/06/16 06:29:17 sjg Exp $ # # @(#) Copyright (c) 2010, Simon J. Gerraty @@ -97,6 +97,8 @@ UPDATE_DEPENDFILE = no # for example the result of running configure # just make sure this is not empty META_FILE_FILTER ?= N.meta +# never consider these +META_FILE_FILTER += Ndirdeps.cache* .if !empty(DPADD) # if we have any non-libs in DPADD, diff --git a/mk/meta.stage.mk b/mk/meta.stage.mk index 588f50e98204..4337c0eff5d7 100644 --- a/mk/meta.stage.mk +++ b/mk/meta.stage.mk @@ -1,4 +1,4 @@ -# $Id: meta.stage.mk,v 1.35 2015/05/20 06:40:33 sjg Exp $ +# $Id: meta.stage.mk,v 1.40 2015/10/04 17:36:54 sjg Exp $ # # @(#) Copyright (c) 2011, Simon J. Gerraty # @@ -23,6 +23,8 @@ _dirdep = ${RELDIR}.${MACHINE} _dirdep = ${RELDIR} .endif +CLEANFILES+= .dirdep + # this allows us to trace dependencies back to their src dir .dirdep: @echo '${_dirdep}' > $@ @@ -59,14 +61,23 @@ LN_CP_SCRIPT = LnCp() { \ ln $$1 $$2 2> /dev/null || \ cp -p $$1 $$2; } +# a staging conflict should cause an error +# a warning is handy when bootstapping different options. +STAGE_CONFLICT?= ERROR +.if ${STAGE_CONFLICT:tl} == "error" +STAGE_CONFLICT_ACTION= exit 1; +.else +STAGE_CONFLICT_ACTION= +.endif + # it is an error for more than one src dir to try and stage # the same file STAGE_DIRDEP_SCRIPT = ${LN_CP_SCRIPT}; StageDirdep() { \ t=$$1; \ if [ -s $$t.dirdep ]; then \ cmp -s .dirdep $$t.dirdep && return; \ - echo "ERROR: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \ - exit 1; \ + echo "${STAGE_CONFLICT}: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \ + ${STAGE_CONFLICT_ACTION} \ fi; \ LnCp .dirdep $$t.dirdep || exit 1; } @@ -124,7 +135,7 @@ _STAGE_AS_BASENAME_USE: .USE ${.TARGET:T} .if !empty(STAGE_INCSDIR) STAGE_TARGETS += stage_incs -STAGE_INCS ?= ${.ALLSRC:N.dirdep} +STAGE_INCS ?= ${.ALLSRC:N.dirdep:Nstage_*} stage_includes: stage_incs stage_incs: .dirdep @@ -135,7 +146,7 @@ stage_incs: .dirdep .if !empty(STAGE_LIBDIR) STAGE_TARGETS += stage_libs -STAGE_LIBS ?= ${.ALLSRC:N.dirdep} +STAGE_LIBS ?= ${.ALLSRC:N.dirdep:Nstage_*} stage_libs: .dirdep @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${STAGE_LIBS} @@ -167,8 +178,8 @@ CLEANFILES += ${STAGE_SETS:@s@stage*$s@} # some makefiles need to populate multiple directories .for s in ${STAGE_SETS:O:u} -STAGE_FILES.$s ?= ${.ALLSRC:N.dirdep} -STAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep} +STAGE_FILES.$s ?= ${.ALLSRC:N.dirdep:Nstage_*} +STAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep:Nstage_*} STAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP} STAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP} @@ -214,7 +225,7 @@ STAGE_TARGETS += stage_as # each ${file} will be staged as ${STAGE_AS_${file:T}} # one could achieve the same with SYMLINKS .for s in ${STAGE_AS_SETS:O:u} -STAGE_AS.$s ?= ${.ALLSRC:N.dirdep} +STAGE_AS.$s ?= ${.ALLSRC:N.dirdep:Nstage_*} stage_as: stage_as.$s stage_as.$s: .dirdep @@ -227,13 +238,15 @@ stage_as.$s: .dirdep CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes # stage_*links usually needs to follow any others. +# for non-jobs mode the order here matters +staging: ${STAGE_TARGETS:N*_links} ${STAGE_TARGETS:M*_links} + +.if ${.MAKE.JOBS:U0} > 0 && ${STAGE_TARGETS:M*_links} != "" +# the above isn't sufficient .for t in ${STAGE_TARGETS:N*links:O:u} .ORDER: $t stage_links -.ORDER: $t stage_symlinks .endfor - -# make sure this exists -staging: +.endif # generally we want staging to wait until everything else is done STAGING_WAIT ?= .WAIT diff --git a/mk/meta.sys.mk b/mk/meta.sys.mk index 1f7ac49dae07..1d1ba5338a10 100644 --- a/mk/meta.sys.mk +++ b/mk/meta.sys.mk @@ -1,4 +1,4 @@ -# $Id: meta.sys.mk,v 1.21 2015/06/01 22:43:49 sjg Exp $ +# $Id: meta.sys.mk,v 1.22 2015/06/16 06:31:05 sjg Exp $ # # @(#) Copyright (c) 2010, Simon J. Gerraty @@ -20,6 +20,10 @@ .if ${MAKE_VERSION:U0} > 20100901 .if !target(.ERROR) +.-include "local.meta.sys.mk" + +# absoulte path to what we are reading. +_PARSEDIR = ${.PARSEDIR:tA} META_MODE += meta verbose .MAKE.MODE ?= ${META_MODE} @@ -69,6 +73,7 @@ MACHINE = host # for example, if using Makefild.depend for multiple machines, # allowing only MACHINE0 to update can keep things simple. MACHINE0 := ${MACHINE} +.export MACHINE0 .if defined(PYTHON) && exists(${PYTHON}) # we prefer the python version of this - it is much faster diff --git a/mk/own.mk b/mk/own.mk index f090bbe8e537..3fdb16bcfc9a 100644 --- a/mk/own.mk +++ b/mk/own.mk @@ -1,4 +1,4 @@ -# $Id: own.mk,v 1.28 2015/04/16 16:59:00 sjg Exp $ +# $Id: own.mk,v 1.29 2015/09/08 06:15:31 sjg Exp $ .if !target(__${.PARSEFILE}__) __${.PARSEFILE}__: @@ -133,7 +133,9 @@ USERGRP!= id -g .for x in BIN CONF DOC INFO KMOD LIB MAN NLS SHARE $xOWN= ${USER} $xGRP= ${USERGRP} +$x_INSTALL_OWN= .endfor +PROG_INSTALL_OWN= .endif .endif @@ -143,6 +145,7 @@ BINGRP?= ${ROOT_GROUP} BINOWN?= root BINMODE?= 555 NONBINMODE?= 444 +DIRMODE?= 755 # Define MANZ to have the man pages compressed (gzip) #MANZ= 1 diff --git a/mk/rst2htm.mk b/mk/rst2htm.mk index 4d4c940b8bc7..296b73c68574 100644 --- a/mk/rst2htm.mk +++ b/mk/rst2htm.mk @@ -1,4 +1,4 @@ -# $Id: rst2htm.mk,v 1.9 2014/02/22 01:52:41 sjg Exp $ +# $Id: rst2htm.mk,v 1.10 2015/09/08 22:17:46 sjg Exp $ # # @(#) Copyright (c) 2009, Simon J. Gerraty # @@ -26,7 +26,12 @@ RST2PDF ?= rst2pdf RST2S5 ?= rst2s5.py # the following will run RST2S5 if the target name contains the word 'slides' # otherwise it uses RST2HTML -RST2HTM = ${"${.TARGET:T:M*slides*}":?${RST2S5} ${RST2S5_FLAGS}:${RST2HTML} ${RST2HTML_FLAGS}} +RST2HTM = ${"${.TARGET:T:M*slides*}":?${RST2S5}:${RST2HTML}} +RST2HTM_SLIDES_FLAGS ?= ${RST2S5_FLAGS} +RST2HTM_DOC_FLAGS ?= ${RST2HTML_FLAGS} +RST2HTM_FLAGS ?= ${"${.TARGET:T:M*slides*}":?${RST2HTM_SLIDES_FLAGS}:${RST2HTM_DOC_FLAGS}} + +RST2PDF_FLAGS ?= ${"${.TARGET:T:M*slides*}":?${RST2PDF_SLIDES_FLAGS}:${RST2PDF_DOC_FLAGS}} RST_SUFFIXES ?= .rst .txt @@ -37,10 +42,10 @@ html: ${HTMFILES} .SUFFIXES: ${RST_SUFFIXES} .htm .pdf ${RST_SUFFIXES:@s@$s.htm@}: - ${RST2HTM} ${.IMPSRC} ${.TARGET} + ${RST2HTM} ${RST2HTM_FLAGS} ${FLAGS.${.TARGET}} ${.IMPSRC} ${.TARGET} ${RST_SUFFIXES:@s@$s.pdf@}: - ${RST2PDF} ${.IMPSRC} ${.TARGET} + ${RST2PDF} ${RST2PDF_FLAGS} ${FLAGS.${.TARGET}} ${.IMPSRC} ${.TARGET} .for s in ${RSTSRCS:O:u} ${s:R:T}.htm: $s diff --git a/nonints.h b/nonints.h index 9eaebc2e9b4b..2332858c25cc 100644 --- a/nonints.h +++ b/nonints.h @@ -1,4 +1,4 @@ -/* $NetBSD: nonints.h,v 1.68 2015/05/05 21:51:09 sjg Exp $ */ +/* $NetBSD: nonints.h,v 1.69 2015/10/11 04:51:24 sjg Exp $ */ /*- * Copyright (c) 1988, 1989, 1990, 1993 @@ -184,8 +184,8 @@ void Var_Set(const char *, const char *, GNode *, int); void Var_Append(const char *, const char *, GNode *); Boolean Var_Exists(const char *, GNode *); char *Var_Value(const char *, GNode *, char **); -char *Var_Parse(const char *, GNode *, Boolean, int *, void **); -char *Var_Subst(const char *, const char *, GNode *, Boolean); +char *Var_Parse(const char *, GNode *, Boolean, Boolean, int *, void **); +char *Var_Subst(const char *, const char *, GNode *, Boolean, Boolean); char *Var_GetTail(const char *); char *Var_GetHead(const char *); void Var_Init(void); diff --git a/os.sh b/os.sh index b714eb782cec..1df67b8cd7c3 100755 --- a/os.sh +++ b/os.sh @@ -17,7 +17,7 @@ # Simon J. Gerraty # RCSid: -# $Id: os.sh,v 1.46 2014/05/19 16:38:09 sjg Exp $ +# $Id: os.sh,v 1.47 2015/09/10 05:53:10 sjg Exp $ # # @(#) Copyright (c) 1994 Simon J. Gerraty # @@ -137,7 +137,10 @@ SunOS) # NetBSD at least has good backward compatibility # so NetBSD/i386 is good enough case $OS in - NetBSD) SHARE_ARCH=$OS/${MACHINE_ARCH:-$MACHINE};; + NetBSD) + HOST_ARCH=$MACHINE + SHARE_ARCH=$OS/$HOST + ;; OpenBSD) arch=`Which arch /usr/bin:/usr/ucb:$PATH` MACHINE_ARCH=`$arch -s` @@ -203,13 +206,14 @@ esac TMP_DIRS=${TMP_DIRS:-"/tmp /var/tmp"} MACHINE_ARCH=${MACHINE_ARCH:-$MACHINE} +HOST_ARCH=${HOST_ARCH:-$MACHINE_ARCH} # we mount server:/share/arch/$SHARE_ARCH as /usr/local -SHARE_ARCH=${SHARE_ARCH:-$OS/$OSMAJOR.X/$MACHINE_ARCH} +SHARE_ARCH=${SHARE_ARCH:-$OS/$OSMAJOR.X/$HOST_ARCH} LN=${LN:-ln} TR=${TR:-tr} # Some people like have /share/$HOST_TARGET/bin etc. -HOST_TARGET=`echo ${OS}${OSMAJOR}-${MACHINE_ARCH} | toLower` +HOST_TARGET=`echo ${OS}${OSMAJOR}-$HOST_ARCH | toLower` export HOST_TARGET case `echo -n .` in -n*) N=; C="\c";; *) N=-n; C=;; esac diff --git a/parse.c b/parse.c index a55582ec1cd2..171847019acd 100644 --- a/parse.c +++ b/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.204 2014/09/18 08:06:13 dholland Exp $ */ +/* $NetBSD: parse.c,v 1.205 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: parse.c,v 1.204 2014/09/18 08:06:13 dholland Exp $"; +static char rcsid[] = "$NetBSD: parse.c,v 1.205 2015/10/11 04:51:24 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: parse.c,v 1.204 2014/09/18 08:06:13 dholland Exp $"); +__RCSID("$NetBSD: parse.c,v 1.205 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -812,7 +812,7 @@ ParseMessage(char *line) while (isspace((u_char)*line)) line++; - line = Var_Subst(NULL, line, VAR_CMD, 0); + line = Var_Subst(NULL, line, VAR_CMD, FALSE, TRUE); Parse_Error(mtype, "%s", line); free(line); @@ -1229,7 +1229,7 @@ ParseDoDependency(char *line) int length; void *freeIt; - (void)Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt); + (void)Var_Parse(cp, VAR_CMD, TRUE, TRUE, &length, &freeIt); if (freeIt) free(freeIt); cp += length-1; @@ -1944,7 +1944,7 @@ Parse_DoVar(char *line, GNode *ctxt) if (!Var_Exists(line, ctxt)) Var_Set(line, "", ctxt, 0); - cp = Var_Subst(NULL, cp, ctxt, FALSE); + cp = Var_Subst(NULL, cp, ctxt, FALSE, TRUE); oldVars = oldOldVars; freeCp = TRUE; @@ -1959,7 +1959,7 @@ Parse_DoVar(char *line, GNode *ctxt) * expansion on the whole thing. The resulting string will need * freeing when we're done, so set freeCmd to TRUE. */ - cp = Var_Subst(NULL, cp, VAR_CMD, TRUE); + cp = Var_Subst(NULL, cp, VAR_CMD, TRUE, TRUE); freeCp = TRUE; } @@ -2298,7 +2298,7 @@ ParseDoInclude(char *line) * Substitute for any variables in the file name before trying to * find the thing. */ - file = Var_Subst(NULL, file, VAR_CMD, FALSE); + file = Var_Subst(NULL, file, VAR_CMD, FALSE, TRUE); Parse_include_file(file, endc == '>', silent); free(file); @@ -2524,7 +2524,7 @@ ParseTraditionalInclude(char *line) * Substitute for any variables in the file name before trying to * find the thing. */ - all_files = Var_Subst(NULL, file, VAR_CMD, FALSE); + all_files = Var_Subst(NULL, file, VAR_CMD, FALSE, TRUE); if (*file == '\0') { Parse_Error(PARSE_FATAL, @@ -2592,7 +2592,7 @@ ParseGmakeExport(char *line) /* * Expand the value before putting it in the environment. */ - value = Var_Subst(NULL, value, VAR_CMD, FALSE); + value = Var_Subst(NULL, value, VAR_CMD, FALSE, TRUE); setenv(variable, value, 1); } #endif @@ -3141,7 +3141,7 @@ Parse_File(const char *name, int fd) * variables expanded before being parsed. Tell the variable * module to complain if some variable is undefined... */ - line = Var_Subst(NULL, line, VAR_CMD, TRUE); + line = Var_Subst(NULL, line, VAR_CMD, TRUE, TRUE); /* * Need a non-circular list for the target nodes diff --git a/suff.c b/suff.c index c42d2ec57e8f..15a3cc87cbc0 100644 --- a/suff.c +++ b/suff.c @@ -1,4 +1,4 @@ -/* $NetBSD: suff.c,v 1.73 2014/09/07 20:55:34 joerg Exp $ */ +/* $NetBSD: suff.c,v 1.74 2015/10/11 04:51:24 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: suff.c,v 1.73 2014/09/07 20:55:34 joerg Exp $"; +static char rcsid[] = "$NetBSD: suff.c,v 1.74 2015/10/11 04:51:24 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94"; #else -__RCSID("$NetBSD: suff.c,v 1.73 2014/09/07 20:55:34 joerg Exp $"); +__RCSID("$NetBSD: suff.c,v 1.74 2015/10/11 04:51:24 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -1543,7 +1543,7 @@ SuffExpandChildren(LstNode cln, GNode *pgn) if (DEBUG(SUFF)) { fprintf(debug_file, "Expanding \"%s\"...", cgn->name); } - cp = Var_Subst(NULL, cgn->name, pgn, TRUE); + cp = Var_Subst(NULL, cgn->name, pgn, TRUE, TRUE); if (cp != NULL) { Lst members = Lst_Init(FALSE); @@ -1596,7 +1596,7 @@ SuffExpandChildren(LstNode cln, GNode *pgn) int len; void *freeIt; - junk = Var_Parse(cp, pgn, TRUE, &len, &freeIt); + junk = Var_Parse(cp, pgn, TRUE, TRUE, &len, &freeIt); if (junk != var_Error) { cp += len - 1; } diff --git a/unit-tests/varmisc.exp b/unit-tests/varmisc.exp index 1636aafc11e5..e2af496afabe 100644 --- a/unit-tests/varmisc.exp +++ b/unit-tests/varmisc.exp @@ -1,2 +1,20 @@ +:D expanded when var set +true +TRUE +:U expanded when var undef +true +TRUE +:D skipped if var undef + +:U skipped when var set +is set +:? only lhs when value true +true +TRUE +:? only rhs when value false +false +FALSE +do not evaluate or expand :? if discarding +is set exit status 0 diff --git a/unit-tests/varmisc.mk b/unit-tests/varmisc.mk index 4b4a931a37ac..14b52d22c3e6 100644 --- a/unit-tests/varmisc.mk +++ b/unit-tests/varmisc.mk @@ -1,8 +1,42 @@ -# $Id: varmisc.mk,v 1.2 2014/08/30 22:25:14 sjg Exp $ +# $Id: varmisc.mk,v 1.5 2015/10/12 17:10:48 sjg Exp $ # # Miscellaneous variable tests. -all: unmatched_var_paren +all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none unmatched_var_paren: @echo ${foo::=foo-text} + +True = ${echo true >&2:L:sh}TRUE +False= ${echo false >&2:L:sh}FALSE + +VSET= is set +.undef UNDEF + +U_false: + @echo :U skipped when var set + @echo ${VSET:U${False}} + +D_false: + @echo :D skipped if var undef + @echo ${UNDEF:D${False}} + +U_true: + @echo :U expanded when var undef + @echo ${UNDEF:U${True}} + +D_true: + @echo :D expanded when var set + @echo ${VSET:D${True}} + +Q_lhs: + @echo :? only lhs when value true + @echo ${1:L:?${True}:${False}} + +Q_rhs: + @echo :? only rhs when value false + @echo ${0:L:?${True}:${False}} + +NQ_none: + @echo do not evaluate or expand :? if discarding + @echo ${VSET:U${1:L:?${True}:${False}}} diff --git a/var.c b/var.c index 39e357b80d73..ebc25c65ed1d 100644 --- a/var.c +++ b/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $ */ +/* $NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $"; +static char rcsid[] = "$NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $"; #else #include #ifndef lint #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $"); +__RCSID("$NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -138,6 +138,7 @@ __RCSID("$NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $"); #include "buf.h" #include "dir.h" #include "job.h" +#include "metachar.h" extern int makelevel; /* @@ -541,7 +542,7 @@ Var_Delete(const char *name, GNode *ctxt) char *cp; if (strchr(name, '$')) { - cp = Var_Subst(NULL, name, VAR_GLOBAL, 0); + cp = Var_Subst(NULL, name, VAR_GLOBAL, FALSE, TRUE); } else { cp = (char *)name; } @@ -632,7 +633,7 @@ Var_Export1(const char *name, int parent) } n = snprintf(tmp, sizeof(tmp), "${%s}", name); if (n < (int)sizeof(tmp)) { - val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + val = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); setenv(name, val, 1); free(val); } @@ -700,7 +701,7 @@ Var_ExportVars(void) int ac; int i; - val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + val = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); av = brk_string(val, &ac, FALSE, &as); for (i = 0; i < ac; i++) { Var_Export1(av[i], 0); @@ -738,7 +739,7 @@ Var_Export(char *str, int isExport) } else { track = VAR_EXPORT_PARENT; } - val = Var_Subst(NULL, str, VAR_GLOBAL, 0); + val = Var_Subst(NULL, str, VAR_GLOBAL, FALSE, TRUE); av = brk_string(val, &ac, FALSE, &as); for (i = 0; i < ac; i++) { name = av[i]; @@ -826,7 +827,7 @@ Var_UnExport(char *str) /* Using .MAKE.EXPORTED */ n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}"); if (n < (int)sizeof(tmp)) { - vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); } } if (vlist) { @@ -856,7 +857,7 @@ Var_UnExport(char *str) n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":N%s}", v->name); if (n < (int)sizeof(tmp)) { - cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + cp = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0); free(cp); } @@ -911,7 +912,7 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags) * point in searching them all just to save a bit of memory... */ if (strchr(name, '$') != NULL) { - expanded_name = Var_Subst(NULL, name, ctxt, 0); + expanded_name = Var_Subst(NULL, name, ctxt, FALSE, TRUE); if (expanded_name[0] == 0) { if (DEBUG(VAR)) { fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) " @@ -981,8 +982,7 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags) } out: - if (expanded_name != NULL) - free(expanded_name); + free(expanded_name); if (v != NULL) VarFreeEnv(v, TRUE); } @@ -1022,7 +1022,7 @@ Var_Append(const char *name, const char *val, GNode *ctxt) char *expanded_name = NULL; if (strchr(name, '$') != NULL) { - expanded_name = Var_Subst(NULL, name, ctxt, 0); + expanded_name = Var_Subst(NULL, name, ctxt, FALSE, TRUE); if (expanded_name[0] == 0) { if (DEBUG(VAR)) { fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) " @@ -1060,8 +1060,7 @@ Var_Append(const char *name, const char *val, GNode *ctxt) Hash_SetValue(h, v); } } - if (expanded_name != NULL) - free(expanded_name); + free(expanded_name); } /*- @@ -1088,12 +1087,10 @@ Var_Exists(const char *name, GNode *ctxt) char *cp; if ((cp = strchr(name, '$')) != NULL) { - cp = Var_Subst(NULL, name, ctxt, FALSE); + cp = Var_Subst(NULL, name, ctxt, FALSE, TRUE); } v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV); - if (cp != NULL) { - free(cp); - } + free(cp); if (v == NULL) { return(FALSE); } else { @@ -1388,7 +1385,7 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate, addSpace = TRUE; if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) { - varexp = Var_Subst(NULL, pat->rhs, ctx, 0); + varexp = Var_Subst(NULL, pat->rhs, ctx, FALSE, TRUE); Str_SYSVSubst(buf, varexp, ptr, len); free(varexp); } else { @@ -1808,7 +1805,7 @@ VarLoopExpand(GNode *ctx MAKE_ATTR_UNUSED, if (word && *word) { Var_Set(loop->tvar, word, loop->ctxt, VAR_NO_EXPORT); - s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum); + s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum, TRUE); if (s != NULL && *s != '\0') { if (addSpace && *s != '\n') Buf_AddByte(buf, ' '); @@ -2189,10 +2186,9 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED, * delimiter, assume it's a variable * substitution and recurse. */ - cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt); + cp2 = Var_Parse(cp, ctxt, errnum, TRUE, &len, &freeIt); Buf_AddBytes(&buf, strlen(cp2), cp2); - if (freeIt) - free(freeIt); + free(freeIt); cp += len - 1; } else { const char *cp2 = &cp[1]; @@ -2245,7 +2241,7 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED, /*- *----------------------------------------------------------------------- * VarQuote -- - * Quote shell meta-characters in the string + * Quote shell meta-characters and space characters in the string * * Results: * The quoted string @@ -2260,29 +2256,25 @@ VarQuote(char *str) { Buffer buf; - /* This should cover most shells :-( */ - static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~"; const char *newline; - size_t len, nlen; + size_t nlen; if ((newline = Shell_GetNewline()) == NULL) newline = "\\\n"; nlen = strlen(newline); Buf_Init(&buf, 0); - while (*str != '\0') { - if ((len = strcspn(str, meta)) != 0) { - Buf_AddBytes(&buf, len, str); - str += len; - } else if (*str == '\n') { + + for (; *str != '\0'; str++) { + if (*str == '\n') { Buf_AddBytes(&buf, nlen, newline); - ++str; - } else { - Buf_AddByte(&buf, '\\'); - Buf_AddByte(&buf, *str); - ++str; + continue; } + if (isspace((unsigned char)*str) || ismeta((unsigned char)*str)) + Buf_AddByte(&buf, '\\'); + Buf_AddByte(&buf, *str); } + str = Buf_Destroy(&buf, FALSE); if (DEBUG(VAR)) fprintf(debug_file, "QuoteMeta: [%s]\n", str); @@ -2467,7 +2459,7 @@ VarStrftime(const char *fmt, int zulu) static char * ApplyModifiers(char *nstr, const char *tstr, int startc, int endc, - Var *v, GNode *ctxt, Boolean errnum, + Var *v, GNode *ctxt, Boolean errnum, Boolean wantit, int *lengthPtr, void **freePtr) { const char *start; @@ -2498,7 +2490,7 @@ ApplyModifiers(char *nstr, const char *tstr, int rlen; int c; - rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt); + rval = Var_Parse(tstr, ctxt, errnum, wantit, &rlen, &freeIt); /* * If we have not parsed up to endc or ':', @@ -2508,8 +2500,7 @@ ApplyModifiers(char *nstr, const char *tstr, (c = tstr[rlen]) != '\0' && c != ':' && c != endc) { - if (freeIt) - free(freeIt); + free(freeIt); goto apply_mods; } @@ -2525,17 +2516,15 @@ ApplyModifiers(char *nstr, const char *tstr, nstr = ApplyModifiers(nstr, rval, 0, 0, - v, ctxt, errnum, &used, freePtr); + v, ctxt, errnum, wantit, &used, freePtr); if (nstr == var_Error || (nstr == varNoError && errnum == 0) || strlen(rval) != (size_t) used) { - if (freeIt) - free(freeIt); + free(freeIt); goto out; /* error already reported */ } } - if (freeIt) - free(freeIt); + free(freeIt); if (*tstr == ':') tstr++; else if (!*tstr && endc) { @@ -2564,6 +2553,7 @@ ApplyModifiers(char *nstr, const char *tstr, char *sv_name; VarPattern pattern; int how; + int flags; if (v->name[0] == 0) goto bad_modifier; @@ -2599,8 +2589,9 @@ ApplyModifiers(char *nstr, const char *tstr, delim = startc == PROPEN ? PRCLOSE : BRCLOSE; pattern.flags = 0; + flags = (wantit) ? 0 : VAR_NOSUBST; pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, + &cp, delim, &flags, &pattern.rightLen, NULL); if (v->flags & VAR_JUNK) { @@ -2614,26 +2605,27 @@ ApplyModifiers(char *nstr, const char *tstr, termc = *--cp; delim = '\0'; - switch (how) { - case '+': - Var_Append(v->name, pattern.rhs, v_ctxt); - break; - case '!': - newStr = Cmd_Exec(pattern.rhs, &emsg); - if (emsg) - Error(emsg, nstr); - else - Var_Set(v->name, newStr, v_ctxt, 0); - if (newStr) - free(newStr); - break; - case '?': - if ((v->flags & VAR_JUNK) == 0) + if (wantit) { + switch (how) { + case '+': + Var_Append(v->name, pattern.rhs, v_ctxt); break; - /* FALLTHROUGH */ - default: - Var_Set(v->name, pattern.rhs, v_ctxt, 0); - break; + case '!': + newStr = Cmd_Exec(pattern.rhs, &emsg); + if (emsg) + Error(emsg, nstr); + else + Var_Set(v->name, newStr, v_ctxt, 0); + free(newStr); + break; + case '?': + if ((v->flags & VAR_JUNK) == 0) + break; + /* FALLTHROUGH */ + default: + Var_Set(v->name, pattern.rhs, v_ctxt, 0); + break; + } } free(UNCONST(pattern.rhs)); newStr = varNoError; @@ -2675,8 +2667,15 @@ ApplyModifiers(char *nstr, const char *tstr, case 'U': { Buffer buf; /* Buffer for patterns */ - int wantit; /* want data in buffer */ + int wantit_; /* want data in buffer */ + if (wantit) { + if (*tstr == 'U') + wantit_ = ((v->flags & VAR_JUNK) != 0); + else + wantit_ = ((v->flags & VAR_JUNK) == 0); + } else + wantit_ = wantit; /* * Pass through tstr looking for 1) escaped delimiters, * '$'s and backslashes (place the escaped character in @@ -2705,10 +2704,9 @@ ApplyModifiers(char *nstr, const char *tstr, int len; void *freeIt; - cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt); + cp2 = Var_Parse(cp, ctxt, errnum, wantit_, &len, &freeIt); Buf_AddBytes(&buf, strlen(cp2), cp2); - if (freeIt) - free(freeIt); + free(freeIt); cp += len - 1; } else { Buf_AddByte(&buf, *cp); @@ -2717,13 +2715,9 @@ ApplyModifiers(char *nstr, const char *tstr, termc = *cp; - if (*tstr == 'U') - wantit = ((v->flags & VAR_JUNK) != 0); - else - wantit = ((v->flags & VAR_JUNK) == 0); if ((v->flags & VAR_JUNK) != 0) v->flags |= VAR_KEEP; - if (wantit) { + if (wantit_) { newStr = Buf_Destroy(&buf, FALSE); } else { newStr = nstr; @@ -2768,14 +2762,17 @@ ApplyModifiers(char *nstr, const char *tstr, pattern.flags = 0; delim = '!'; - + emsg = NULL; cp = ++tstr; if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, &cp, delim, NULL, &pattern.rightLen, NULL)) == NULL) goto cleanup; - newStr = Cmd_Exec(pattern.rhs, &emsg); + if (wantit) + newStr = Cmd_Exec(pattern.rhs, &emsg); + else + newStr = varNoError; free(UNCONST(pattern.rhs)); if (emsg) Error(emsg, nstr); @@ -3151,7 +3148,7 @@ ApplyModifiers(char *nstr, const char *tstr, * expand it. */ cp2 = pattern; - pattern = Var_Subst(NULL, cp2, ctxt, errnum); + pattern = Var_Subst(NULL, cp2, ctxt, errnum, TRUE); free(cp2); } if (DEBUG(VAR)) @@ -3237,15 +3234,32 @@ ApplyModifiers(char *nstr, const char *tstr, { VarPattern pattern; Boolean value; - + int cond_rc; + int lhs_flags, rhs_flags; + /* find ':', and then substitute accordingly */ - + if (wantit) { + cond_rc = Cond_EvalExpression(NULL, v->name, &value, 0, FALSE); + if (cond_rc == COND_INVALID) { + lhs_flags = rhs_flags = VAR_NOSUBST; + } else if (value) { + lhs_flags = 0; + rhs_flags = VAR_NOSUBST; + } else { + lhs_flags = VAR_NOSUBST; + rhs_flags = 0; + } + } else { + /* we are just consuming and discarding */ + cond_rc = value = 0; + lhs_flags = rhs_flags = VAR_NOSUBST; + } pattern.flags = 0; cp = ++tstr; delim = ':'; if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, + &cp, delim, &lhs_flags, &pattern.leftLen, NULL)) == NULL) goto cleanup; @@ -3253,15 +3267,14 @@ ApplyModifiers(char *nstr, const char *tstr, /* BROPEN or PROPEN */ delim = endc; if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, + &cp, delim, &rhs_flags, &pattern.rightLen, NULL)) == NULL) goto cleanup; termc = *--cp; delim = '\0'; - if (Cond_EvalExpression(NULL, v->name, &value, 0, FALSE) - == COND_INVALID) { + if (cond_rc == COND_INVALID) { Error("Bad conditional expression `%s' in %s?%s:%s", v->name, v->name, pattern.lhs, pattern.rhs); goto cleanup; @@ -3423,9 +3436,12 @@ ApplyModifiers(char *nstr, const char *tstr, case 's': if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) { const char *emsg; - newStr = Cmd_Exec(nstr, &emsg); - if (emsg) - Error(emsg, nstr); + if (wantit) { + newStr = Cmd_Exec(nstr, &emsg); + if (emsg) + Error(emsg, nstr); + } else + newStr = varNoError; cp = tstr + 2; termc = *cp; break; @@ -3546,10 +3562,8 @@ ApplyModifiers(char *nstr, const char *tstr, if (delim != '\0') Error("Unclosed substitution for %s (%c missing)", v->name, delim); - if (*freePtr) { - free(*freePtr); - *freePtr = NULL; - } + free(*freePtr); + *freePtr = NULL; return (var_Error); } @@ -3564,6 +3578,7 @@ ApplyModifiers(char *nstr, const char *tstr, * str The string to parse * ctxt The context for the variable * errnum TRUE if undefined variables are an error + * wantit TRUE if we actually want the result * lengthPtr OUT: The length of the specification * freePtr OUT: Non-NULL if caller should free *freePtr * @@ -3582,8 +3597,9 @@ ApplyModifiers(char *nstr, const char *tstr, */ /* coverity[+alloc : arg-*4] */ char * -Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, - void **freePtr) +Var_Parse(const char *str, GNode *ctxt, + Boolean errnum, Boolean wantit, + int *lengthPtr, void **freePtr) { const char *tstr; /* Pointer into str */ Var *v; /* Variable in invocation */ @@ -3688,12 +3704,11 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, if (*tstr == '$') { int rlen; void *freeIt; - char *rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt); + char *rval = Var_Parse(tstr, ctxt, errnum, wantit, &rlen, &freeIt); if (rval != NULL) { Buf_AddBytes(&buf, strlen(rval), rval); } - if (freeIt) - free(freeIt); + free(freeIt); tstr += rlen - 1; } else @@ -3836,7 +3851,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, */ nstr = Buf_GetAll(&v->val, NULL); if (strchr(nstr, '$') != NULL) { - nstr = Var_Subst(NULL, nstr, ctxt, errnum); + nstr = Var_Subst(NULL, nstr, ctxt, errnum, wantit); *freePtr = nstr; } @@ -3849,7 +3864,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, extraFree = NULL; if (extramodifiers != NULL) { nstr = ApplyModifiers(nstr, extramodifiers, '(', ')', - v, ctxt, errnum, &used, &extraFree); + v, ctxt, errnum, wantit, &used, &extraFree); } if (haveModifier) { @@ -3857,11 +3872,9 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, tstr++; nstr = ApplyModifiers(nstr, tstr, startc, endc, - v, ctxt, errnum, &used, freePtr); + v, ctxt, errnum, wantit, &used, freePtr); tstr += used; - if (extraFree) { - free(extraFree); - } + free(extraFree); } else { *freePtr = extraFree; } @@ -3923,6 +3936,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, * str the string which to substitute * ctxt the context wherein to find variables * undefErr TRUE if undefineds are an error + * wantit TRUE if we actually want the result * * Results: * The resulting string. @@ -3932,7 +3946,8 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, *----------------------------------------------------------------------- */ char * -Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr) +Var_Subst(const char *var, const char *str, GNode *ctxt, + Boolean undefErr, Boolean wantit) { Buffer buf; /* Buffer for forming things */ char *val; /* Value to substitute for a variable */ @@ -4030,7 +4045,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr) continue; } - val = Var_Parse(str, ctxt, undefErr, &length, &freeIt); + val = Var_Parse(str, ctxt, undefErr, wantit, &length, &freeIt); /* * When we come down here, val should either point to the @@ -4078,10 +4093,8 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr) Buf_AddBytes(&buf, length, val); trailingBslash = length > 0 && val[length - 1] == '\\'; } - if (freeIt) { - free(freeIt); - freeIt = NULL; - } + free(freeIt); + freeIt = NULL; } }