aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2016-03-11 00:37:02 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2016-03-11 00:37:02 +0000
commitd58aa1959ce6eb99db9e15b1f59db03cfd79069b (patch)
tree3fccce67c0a1c2882f96019d55f172fb8c0976fd
parent6c770d664f0700039a4eaf3d79f672ffb99204b6 (diff)
downloadsrc-d58aa1959ce6eb99db9e15b1f59db03cfd79069b.tar.gz
src-d58aa1959ce6eb99db9e15b1f59db03cfd79069b.zip
Import bmake-20160307vendor/NetBSD/bmake/20160307
Notes
Notes: svn path=/vendor/NetBSD/bmake/dist/; revision=296635 svn path=/vendor/NetBSD/bmake/20160307/; revision=296636; tag=vendor/NetBSD/bmake/20160307
-rw-r--r--ChangeLog38
-rw-r--r--Makefile4
-rw-r--r--arch.c48
-rw-r--r--bmake.147
-rw-r--r--bmake.cat161
-rw-r--r--compat.c26
-rw-r--r--cond.c38
-rw-r--r--dirname.c89
-rw-r--r--for.c8
-rw-r--r--getopt.c89
-rw-r--r--job.c35
-rw-r--r--main.c114
-rw-r--r--make.147
-rw-r--r--make.c26
-rw-r--r--make.h11
-rw-r--r--meta.c82
-rw-r--r--meta.h3
-rw-r--r--mk/ChangeLog39
-rw-r--r--mk/auto.dep.mk12
-rw-r--r--mk/dirdeps.mk64
-rw-r--r--mk/gendirdeps.mk6
-rw-r--r--mk/install-mk4
-rw-r--r--mk/meta.autodep.mk4
-rw-r--r--mk/meta.stage.mk6
-rw-r--r--mk/meta.sys.mk4
-rwxr-xr-xmk/meta2deps.sh4
-rw-r--r--mk/sys.clean-env.mk15
-rw-r--r--mk/sys.dependfile.mk4
-rw-r--r--mk/warnings.mk4
-rw-r--r--nonints.h7
-rw-r--r--parse.c46
-rw-r--r--suff.c17
-rw-r--r--targ.c12
-rw-r--r--unit-tests/export-env.exp2
-rw-r--r--unit-tests/export-env.mk9
-rw-r--r--unit-tests/modts.exp10
-rw-r--r--unit-tests/modts.mk3
-rw-r--r--var.c223
38 files changed, 778 insertions, 483 deletions
diff --git a/ChangeLog b/ChangeLog
index c3a4241f0604..78b5a7eedfdd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2016-03-07 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20160307
+ Merge with NetBSD make, pick up
+ o var.c: fix :ts\nnn to be octal by default.
+ o meta.c: meta_finish() to cleanup memory.
+
+2016-02-26 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20160226
+ Merge with NetBSD make, pick up
+ o meta.c: allow meta file for makeDepend if makefiles want it.
+
+2016-02-19 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * var.c: default .MAKE.SAVE_DOLLARS to FALSE
+ for backwards compatability.
+
+ * Makefile (MAKE_VERSION): 20160220
+ Merge with NetBSD make, pick up
+ o var.c: add knob to control handling of '$$' in :=
+
+2016-02-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20160218
+ Merge with NetBSD make, pick up
+ o var.c: add .export-literal allows us to fix sys.clean-env.mk
+ post the changes to Var_Subst.
+ Var_Subst now takes flags, and does not consume '$$' in :=
+
+2016-02-17 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * Makefile (MAKE_VERSION): 20160217
+ Merge with NetBSD make, pick up
+ o var.c: preserve '$$' in :=
+ o parse.c: add .dinclude for handling included
+ makefile like .depend
+
2015-12-20 Simon J. Gerraty <sjg@bad.crufty.net>
* Makefile (MAKE_VERSION): 20151220
diff --git a/Makefile b/Makefile
index 625c254afcdd..730e15d27c51 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
-# $Id: Makefile,v 1.49 2015/12/20 22:54:40 sjg Exp $
+# $Id: Makefile,v 1.55 2016/03/07 22:02:47 sjg Exp $
# Base version on src date
-MAKE_VERSION= 20151220
+MAKE_VERSION= 20160307
PROG= bmake
diff --git a/arch.c b/arch.c
index 9ceee10cddb7..f613a663e394 100644
--- a/arch.c
+++ b/arch.c
@@ -1,4 +1,4 @@
-/* $NetBSD: arch.c,v 1.64 2015/10/11 04:51:24 sjg Exp $ */
+/* $NetBSD: arch.c,v 1.68 2016/02/18 18:29:14 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: arch.c,v 1.64 2015/10/11 04:51:24 sjg Exp $";
+static char rcsid[] = "$NetBSD: arch.c,v 1.68 2016/02/18 18:29:14 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: arch.c,v 1.64 2015/10/11 04:51:24 sjg Exp $");
+__RCSID("$NetBSD: arch.c,v 1.68 2016/02/18 18:29:14 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -136,7 +136,6 @@ __RCSID("$NetBSD: arch.c,v 1.64 2015/10/11 04:51:24 sjg Exp $");
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/param.h>
-#include <ctype.h>
#ifdef HAVE_AR_H
#include <ar.h>
#else
@@ -156,7 +155,6 @@ struct ar_hdr {
#if defined(HAVE_RANLIB_H) && !(defined(__ELF__) || defined(NO_RANLIB))
#include <ranlib.h>
#endif
-#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UTIME_H
@@ -254,8 +252,7 @@ ArchFree(void *ap)
free(Hash_GetValue(entry));
free(a->name);
- if (a->fnametab)
- free(a->fnametab);
+ free(a->fnametab);
Hash_DeleteTable(&a->members);
free(a);
}
@@ -310,9 +307,10 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
void *freeIt;
char *result;
- result = Var_Parse(cp, ctxt, TRUE, TRUE, &length, &freeIt);
- if (freeIt)
- free(freeIt);
+ result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
+ &length, &freeIt);
+ free(freeIt);
+
if (result == var_Error) {
return(FAILURE);
} else {
@@ -325,7 +323,7 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
*cp++ = '\0';
if (subLibName) {
- libName = Var_Subst(NULL, libName, ctxt, TRUE, TRUE);
+ libName = Var_Subst(NULL, libName, ctxt, VARF_UNDEFERR|VARF_WANTRES);
}
@@ -351,9 +349,10 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
void *freeIt;
char *result;
- result = Var_Parse(cp, ctxt, TRUE, TRUE, &length, &freeIt);
- if (freeIt)
- free(freeIt);
+ result = Var_Parse(cp, ctxt, VARF_UNDEFERR|VARF_WANTRES,
+ &length, &freeIt);
+ free(freeIt);
+
if (result == var_Error) {
return(FAILURE);
} else {
@@ -404,7 +403,8 @@ Arch_ParseArchive(char **linePtr, Lst nodeLst, GNode *ctxt)
char *oldMemName = memName;
size_t sz;
- memName = Var_Subst(NULL, memName, ctxt, TRUE, TRUE);
+ memName = Var_Subst(NULL, memName, ctxt,
+ VARF_UNDEFERR|VARF_WANTRES);
/*
* Now form an archive spec and recurse to deal with nested
@@ -759,8 +759,7 @@ ArchStatMember(char *archive, char *member, Boolean hash)
badarch:
fclose(arch);
Hash_DeleteTable(&ar->members);
- if (ar->fnametab)
- free(ar->fnametab);
+ free(ar->fnametab);
free(ar);
return NULL;
}
@@ -1045,10 +1044,10 @@ Arch_Touch(GNode *gn)
arch = ArchFindMember(Var_Value(ARCHIVE, gn, &p1),
Var_Value(MEMBER, gn, &p2),
&arh, "r+");
- if (p1)
- free(p1);
- if (p2)
- free(p2);
+
+ free(p1);
+ free(p2);
+
snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now);
if (arch != NULL) {
@@ -1127,10 +1126,9 @@ Arch_MTime(GNode *gn)
arhPtr = ArchStatMember(Var_Value(ARCHIVE, gn, &p1),
Var_Value(MEMBER, gn, &p2),
TRUE);
- if (p1)
- free(p1);
- if (p2)
- free(p2);
+
+ free(p1);
+ free(p2);
if (arhPtr != NULL) {
modTime = (time_t)strtol(arhPtr->AR_DATE, NULL, 10);
diff --git a/bmake.1 b/bmake.1
index 39d28c4e1ee3..603481e9d08c 100644
--- a/bmake.1
+++ b/bmake.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.249 2015/06/05 07:33:40 wiz Exp $
+.\" $NetBSD: make.1,v 1.254 2016/02/20 01:43:28 wiz Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd June 4, 2015
+.Dd February 19, 2016
.Dt MAKE 1
.Os
.Sh NAME
@@ -293,7 +293,7 @@ then
will search for the specified file or directory named in the remaining part
of the argument string.
The search starts with the current directory of
-the Makefile and then works upward towards the root of the filesystem.
+the Makefile and then works upward towards the root of the file system.
If the search is successful, then the resulting directory replaces the
.Qq \&.../
specification in the
@@ -868,7 +868,7 @@ This can be overridden by setting
.Va bf
to a value which represents True.
.It Pa env
-For debugging, it can be useful to inlcude the environment
+For debugging, it can be useful to include the environment
in the .meta file.
.It Pa verbose
If in "meta" mode, print a clue about the target being built.
@@ -918,7 +918,7 @@ The default value is:
This variable is used to record the names of variables assigned to
on the command line, so that they may be exported as part of
.Ql Ev MAKEFLAGS .
-This behaviour can be disabled by assigning an empty value to
+This behavior can be disabled by assigning an empty value to
.Ql Va .MAKEOVERRIDES
within a makefile.
Extra variables can be exported from a makefile
@@ -941,6 +941,19 @@ The process-id of
.It Va .MAKE.PPID
The parent process-id of
.Nm .
+.It Va .MAKE.SAVE_DOLLARS
+value should be a boolean that controls whether
+.Ql $$
+are preserved when doing
+.Ql :=
+assignments.
+The default is false, for backwards compatibility.
+Set to true for compatability with other makes.
+If set to false,
+.Ql $$
+becomes
+.Ql $
+per normal evaluation rules.
.It Va MAKE_PRINT_VAR_ON_ERROR
When
.Nm
@@ -1044,7 +1057,7 @@ sets
to the value of
.Ql Ev PWD
instead.
-This behaviour is disabled if
+This behavior is disabled if
.Ql Ev MAKEOBJDIRPREFIX
is set or
.Ql Ev MAKEOBJDIR
@@ -1114,7 +1127,7 @@ The wildcard characters may be escaped with a backslash
As a consequence of the way values are split into words, matched,
and then joined, a construct like
.Dl ${VAR:M*}
-will normalise the inter-word spacing, removing all leading and
+will normalize the inter-word spacing, removing all leading and
trailing space, and converting multiple consecutive spaces
to single spaces.
.
@@ -1134,7 +1147,7 @@ Randomize words in variable.
The results will be different each time you are referring to the
modified variable; use the assignment with expansion
.Pq Ql Cm \&:=
-to prevent such behaviour.
+to prevent such behavior.
For example,
.Bd -literal -offset indent
LIST= uno due tre quattro
@@ -1166,7 +1179,7 @@ The value is a format string for
using the current
.Xr gmtime 3 .
.It Cm \&:hash
-Compute a 32bit hash of the value and encode it as hex digits.
+Compute a 32-bit hash of the value and encode it as hex digits.
.It Cm \&:localtime
The value is a format string for
.Xr strftime 3 ,
@@ -1444,7 +1457,7 @@ value is divided into words.
.Pp
Ordinarily, a value is treated as a sequence of words
delimited by white space.
-Some modifiers suppress this behaviour,
+Some modifiers suppress this behavior,
causing a value to be treated as a single word
(possibly containing embedded white space).
An empty value, or a value that consists entirely of white-space,
@@ -1530,12 +1543,20 @@ For compatibility with other versions of
.Nm
.Ql include file ...
is also accepted.
+.Pp
If the include statement is written as
.Cm .-include
or as
.Cm .sinclude
then errors locating and/or opening include files are ignored.
.Pp
+If the include statement is written as
+.Cm .dinclude
+not only are errors locating and/or opening include files ignored,
+but stale dependencies within the included file will be ignored
+just like
+.Va .MAKE.DEPENDFILE .
+.Pp
Conditional expressions are also preceded by a single dot as the first
character of a line.
The possible conditionals are as follows:
@@ -1571,6 +1592,10 @@ This allows exporting a value to the environment which is different from that
used by
.Nm
internally.
+.It Ic .export-literal Ar variable ...
+The same as
+.Ql .export-env ,
+except that variables in the value are not expanded.
.It Ic .info Ar message
The message is printed along with the name of the makefile and line number.
.It Ic .undef Ar variable
@@ -2068,7 +2093,7 @@ The sources are a set of
pairs.
.Bl -tag -width hasErrCtls
.It Ar name
-This is the minimal specification, used to select one of the builtin
+This is the minimal specification, used to select one of the built-in
shell specs;
.Ar sh ,
.Ar ksh ,
diff --git a/bmake.cat1 b/bmake.cat1
index 4d43e2de00c9..b6159a8dcfe8 100644
--- a/bmake.cat1
+++ b/bmake.cat1
@@ -178,11 +178,11 @@ DDEESSCCRRIIPPTTIIOONN
then bbmmaakkee will search for the specified file or directory named
in the remaining part of the argument string. The search starts
with the current directory of the Makefile and then works upward
- towards the root of the filesystem. If the search is successful,
- then the resulting directory replaces the ".../" specification in
- the --mm argument. If used, this feature allows bbmmaakkee to easily
- search in the current source tree for customized sys.mk files
- (e.g., by using ".../mk/sys.mk" as an argument).
+ towards the root of the file system. If the search is success-
+ ful, then the resulting directory replaces the ".../" specifica-
+ tion in the --mm argument. If used, this feature allows bbmmaakkee to
+ easily search in the current source tree for customized sys.mk
+ files (e.g., by using ".../mk/sys.mk" as an argument).
--nn Display the commands that would have been executed, but do not
actually execute them unless the target depends on the .MAKE spe-
@@ -543,7 +543,7 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
in `_._C_U_R_D_I_R'. This can be overridden by set-
ting _b_f to a value which represents True.
- _e_n_v For debugging, it can be useful to inlcude
+ _e_n_v For debugging, it can be useful to include
the environment in the .meta file.
_v_e_r_b_o_s_e If in "meta" mode, print a clue about the
@@ -591,7 +591,7 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
_._M_A_K_E_O_V_E_R_R_I_D_E_S This variable is used to record the names of variables
assigned to on the command line, so that they may be
- exported as part of `MAKEFLAGS'. This behaviour can be
+ exported as part of `MAKEFLAGS'. This behavior can be
disabled by assigning an empty value to `_._M_A_K_E_O_V_E_R_R_I_D_E_S'
within a makefile. Extra variables can be exported from
a makefile by appending their names to `_._M_A_K_E_O_V_E_R_R_I_D_E_S'.
@@ -607,6 +607,13 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
_._M_A_K_E_._P_P_I_D The parent process-id of bbmmaakkee.
+ _._M_A_K_E_._S_A_V_E___D_O_L_L_A_R_S
+ value should be a boolean that controls whether `$$' are
+ preserved when doing `:=' assignments. The default is
+ false, for backwards compatibility. Set to true for com-
+ patability with other makes. If set to false, `$$'
+ becomes `$' per normal evaluation rules.
+
_M_A_K_E___P_R_I_N_T___V_A_R___O_N___E_R_R_O_R
When bbmmaakkee stops due to an error, it prints its name and
the value of `_._C_U_R_D_I_R' as well as the value of any vari-
@@ -670,7 +677,7 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
sets `_._C_U_R_D_I_R' to the canonical path given by getcwd(3).
However, if the environment variable `PWD' is set and
gives a path to the current directory, then bbmmaakkee sets
- `_._C_U_R_D_I_R' to the value of `PWD' instead. This behaviour
+ `_._C_U_R_D_I_R' to the value of `PWD' instead. This behavior
is disabled if `MAKEOBJDIRPREFIX' is set or `MAKEOBJDIR'
contains a variable transform. `PWD' is set to the value
of `_._O_B_J_D_I_R' for all programs which bbmmaakkee executes.
@@ -717,7 +724,7 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
of the way values are split into words, matched, and then joined, a
construct like
${VAR:M*}
- will normalise the inter-word spacing, removing all leading and
+ will normalize the inter-word spacing, removing all leading and
trailing space, and converting multiple consecutive spaces to single
spaces.
@@ -730,7 +737,7 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
::OOxx Randomize words in variable. The results will be different each
time you are referring to the modified variable; use the assignment
- with expansion (`::==') to prevent such behaviour. For example,
+ with expansion (`::==') to prevent such behavior. For example,
LIST= uno due tre quattro
RANDOM_LIST= ${LIST:Ox}
@@ -758,7 +765,7 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
gmtime(3).
::hhaasshh
- Compute a 32bit hash of the value and encode it as hex digits.
+ Compute a 32-bit hash of the value and encode it as hex digits.
::llooccaallttiimmee
The value is a format string for strftime(3), using the current
@@ -914,13 +921,13 @@ VVAARRIIAABBLLEE AASSSSIIGGNNMMEENNTTSS
tions related to the way in which the value is divided into words.
Ordinarily, a value is treated as a sequence of words delimited by
- white space. Some modifiers suppress this behaviour, causing a
- value to be treated as a single word (possibly containing embedded
- white space). An empty value, or a value that consists entirely of
- white-space, is treated as a single word. For the purposes of the
- `::[[]]' modifier, the words are indexed both forwards using positive
- integers (where index 1 represents the first word), and backwards
- using negative integers (where index -1 represents the last word).
+ white space. Some modifiers suppress this behavior, causing a value
+ to be treated as a single word (possibly containing embedded white
+ space). An empty value, or a value that consists entirely of white-
+ space, is treated as a single word. For the purposes of the `::[[]]'
+ modifier, the words are indexed both forwards using positive inte-
+ gers (where index 1 represents the first word), and backwards using
+ negative integers (where index -1 represents the last word).
The _r_a_n_g_e is subjected to variable expansion, and the expanded
result is then interpreted as follows:
@@ -957,8 +964,14 @@ IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOO
used, the including makefile's directory and any directories specified
using the --II option are searched before the system makefile directory.
For compatibility with other versions of bbmmaakkee `include file ...' is also
- accepted. If the include statement is written as ..--iinncclluuddee or as
- ..ssiinncclluuddee then errors locating and/or opening include files are ignored.
+ accepted.
+
+ If the include statement is written as ..--iinncclluuddee or as ..ssiinncclluuddee then
+ errors locating and/or opening include files are ignored.
+
+ If the include statement is written as ..ddiinncclluuddee not only are errors
+ locating and/or opening include files ignored, but stale dependencies
+ within the included file will be ignored just like _._M_A_K_E_._D_E_P_E_N_D_F_I_L_E.
Conditional expressions are also preceded by a single dot as the first
character of a line. The possible conditionals are as follows:
@@ -982,6 +995,10 @@ IINNCCLLUUDDEE SSTTAATTEEMMEENNTTSS,, CCOONNDDIITTIIOO
to _._M_A_K_E_._E_X_P_O_R_T_E_D. This allows exporting a value to the environ-
ment which is different from that used by bbmmaakkee internally.
+ ..eexxppoorrtt--lliitteerraall _v_a_r_i_a_b_l_e _._._.
+ The same as `.export-env', except that variables in the value are
+ not expanded.
+
..iinnffoo _m_e_s_s_a_g_e
The message is printed along with the name of the makefile and
line number.
@@ -1307,7 +1324,7 @@ SSPPEECCIIAALL TTAARRGGEETTSS
sources are a set of _f_i_e_l_d_=_v_a_l_u_e pairs.
_n_a_m_e This is the minimal specification, used to select
- one of the builtin shell specs; _s_h, _k_s_h, and _c_s_h.
+ one of the built-in shell specs; _s_h, _k_s_h, and _c_s_h.
_p_a_t_h Specifies the path to the shell.
@@ -1452,4 +1469,4 @@ BBUUGGSS
There is no way of escaping a space character in a filename.
-NetBSD 5.1 June 4, 2015 NetBSD 5.1
+NetBSD 5.1 February 19, 2016 NetBSD 5.1
diff --git a/compat.c b/compat.c
index 6cf963ffb2da..475c59d51118 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: compat.c,v 1.101 2015/10/11 04:51:24 sjg Exp $ */
+/* $NetBSD: compat.c,v 1.104 2016/02/18 18:29:14 christos 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.101 2015/10/11 04:51:24 sjg Exp $";
+static char rcsid[] = "$NetBSD: compat.c,v 1.104 2016/02/18 18:29:14 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: compat.c,v 1.101 2015/10/11 04:51:24 sjg Exp $");
+__RCSID("$NetBSD: compat.c,v 1.104 2016/02/18 18:29:14 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -146,8 +146,8 @@ CompatInterrupt(int signo)
if (!noExecute && eunlink(file) != -1) {
Error("*** %s removed", file);
}
- if (p1)
- free(p1);
+
+ free(p1);
/*
* Run .INTERRUPT only if hit with interrupt signal
@@ -213,7 +213,7 @@ CompatRunCommand(void *cmdp, void *gnp)
doIt = FALSE;
cmdNode = Lst_Member(gn->commands, cmd);
- cmdStart = Var_Subst(NULL, cmd, gn, FALSE, TRUE);
+ cmdStart = Var_Subst(NULL, cmd, gn, VARF_WANTRES);
/*
* brk_string will return an argv with a NULL in av[0], thus causing
@@ -374,10 +374,10 @@ again:
execError("exec", av[0]);
_exit(1);
}
- if (mav)
- free(mav);
- if (bp)
- free(bp);
+
+ free(mav);
+ free(bp);
+
Lst_Replace(cmdNode, NULL);
#ifdef USE_META
@@ -516,8 +516,7 @@ Compat_Make(void *gnp, void *pgnp)
if (Lst_Member(gn->iParents, pgn) != NULL) {
char *p1;
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
- if (p1)
- free(p1);
+ free(p1);
}
/*
@@ -620,8 +619,7 @@ Compat_Make(void *gnp, void *pgnp)
if (Lst_Member(gn->iParents, pgn) != NULL) {
char *p1;
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
- if (p1)
- free(p1);
+ free(p1);
}
switch(gn->made) {
case BEINGMADE:
diff --git a/cond.c b/cond.c
index 19163008250f..cf0107bc2edd 100644
--- a/cond.c
+++ b/cond.c
@@ -1,4 +1,4 @@
-/* $NetBSD: cond.c,v 1.71 2015/12/02 00:28:24 sjg Exp $ */
+/* $NetBSD: cond.c,v 1.74 2016/02/18 18:29:14 christos 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.71 2015/12/02 00:28:24 sjg Exp $";
+static char rcsid[] = "$NetBSD: cond.c,v 1.74 2016/02/18 18:29:14 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94";
#else
-__RCSID("$NetBSD: cond.c,v 1.71 2015/12/02 00:28:24 sjg Exp $");
+__RCSID("$NetBSD: cond.c,v 1.74 2016/02/18 18:29:14 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -289,10 +289,10 @@ CondGetArg(char **linePtr, char **argPtr, const char *func)
int len;
void *freeIt;
- cp2 = Var_Parse(cp, VAR_CMD, TRUE, TRUE, &len, &freeIt);
+ cp2 = Var_Parse(cp, VAR_CMD, VARF_UNDEFERR|VARF_WANTRES,
+ &len, &freeIt);
Buf_AddBytes(&buf, strlen(cp2), cp2);
- if (freeIt)
- free(freeIt);
+ free(freeIt);
cp += len;
continue;
}
@@ -346,8 +346,8 @@ CondDoDefined(int argLen MAKE_ATTR_UNUSED, const char *arg)
} else {
result = FALSE;
}
- if (p1)
- free(p1);
+
+ free(p1);
return (result);
}
@@ -574,8 +574,9 @@ CondGetString(Boolean doEval, Boolean *quoted, void **freeIt, Boolean strictLHS)
break;
case '$':
/* if we are in quotes, then an undefined variable is ok */
- str = Var_Parse(condExpr, VAR_CMD, (qt ? 0 : doEval),
- TRUE, &len, freeIt);
+ str = Var_Parse(condExpr, VAR_CMD,
+ ((!qt && doEval) ? VARF_UNDEFERR : 0) |
+ VARF_WANTRES, &len, freeIt);
if (str == var_Error) {
if (*freeIt) {
free(*freeIt);
@@ -805,10 +806,8 @@ do_string_compare:
}
done:
- if (lhsFree)
- free(lhsFree);
- if (rhsFree)
- free(rhsFree);
+ free(lhsFree);
+ free(rhsFree);
return t;
}
@@ -827,7 +826,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, TRUE, &length, &freeIt);
+ val = Var_Parse(cp - 1, VAR_CMD, VARF_WANTRES, &length, &freeIt);
/*
* Advance *linePtr to beyond the closing ). Note that
* we subtract one because 'length' is calculated from 'cp - 1'.
@@ -848,8 +847,7 @@ get_mpt_arg(char **linePtr, char **argPtr, const char *func MAKE_ATTR_UNUSED)
* true/false here.
*/
length = *val ? 2 : 1;
- if (freeIt)
- free(freeIt);
+ free(freeIt);
return length;
}
@@ -900,8 +898,7 @@ compare_function(Boolean doEval)
}
/* Evaluate the argument using the required function. */
t = !doEval || fn_def->fn_proc(arglen, arg);
- if (arg)
- free(arg);
+ free(arg);
condExpr = cp;
return t;
}
@@ -933,8 +930,7 @@ compare_function(Boolean doEval)
* be empty - even if it contained a variable expansion.
*/
t = !doEval || if_info->defProc(arglen, arg) != if_info->doNot;
- if (arg)
- free(arg);
+ free(arg);
return t;
}
diff --git a/dirname.c b/dirname.c
index 8b6b6c3d44de..154593b1d523 100644
--- a/dirname.c
+++ b/dirname.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dirname.c,v 1.11 2009/11/24 13:34:20 tnozaki Exp $ */
+/* $NetBSD: dirname.c,v 1.13 2014/07/16 10:52:26 christos Exp $ */
/*-
* Copyright (c) 1997, 2002 The NetBSD Foundation, Inc.
@@ -35,7 +35,10 @@
#ifndef HAVE_DIRNAME
#include <sys/cdefs.h>
-
+#include <sys/param.h>
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
@@ -45,51 +48,73 @@
#ifndef PATH_MAX
# define PATH_MAX 1024
#endif
+#ifndef MIN
+# define MIN(a, b) ((a < b) ? a : b)
+#endif
-char *
-dirname(char *path)
+
+static size_t
+xdirname_r(const char *path, char *buf, size_t buflen)
{
- static char result[PATH_MAX];
- const char *lastp;
+ const char *endp;
size_t len;
/*
* If `path' is a null pointer or points to an empty string,
* return a pointer to the string ".".
*/
- if ((path == NULL) || (*path == '\0'))
- goto singledot;
-
+ if (path == NULL || *path == '\0') {
+ path = ".";
+ len = 1;
+ goto out;
+ }
/* Strip trailing slashes, if any. */
- lastp = path + strlen(path) - 1;
- while (lastp != path && *lastp == '/')
- lastp--;
+ endp = path + strlen(path) - 1;
+ while (endp != path && *endp == '/')
+ endp--;
- /* Terminate path at the last occurence of '/'. */
- do {
- if (*lastp == '/') {
- /* Strip trailing slashes, if any. */
- while (lastp != path && *lastp == '/')
- lastp--;
+ /* Find the start of the dir */
+ while (endp > path && *endp != '/')
+ endp--;
- /* ...and copy the result into the result buffer. */
- len = (lastp - path) + 1 /* last char */;
- if (len > (PATH_MAX - 1))
- len = PATH_MAX - 1;
+ if (endp == path) {
+ path = *endp == '/' ? "/" : ".";
+ len = 1;
+ goto out;
+ }
- memcpy(result, path, len);
- result[len] = '\0';
+ do
+ endp--;
+ while (endp > path && *endp == '/');
- return (result);
- }
- } while (--lastp >= path);
+ len = endp - path + 1;
+out:
+ if (buf != NULL && buflen != 0) {
+ buflen = MIN(len, buflen - 1);
+ memcpy(buf, path, buflen);
+ buf[buflen] = '\0';
+ }
+ return len;
+}
- /* No /'s found, return a pointer to the string ".". */
-singledot:
- result[0] = '.';
- result[1] = '\0';
+char *
+dirname(char *path)
+{
+ static char result[PATH_MAX];
+ (void)xdirname_r(path, result, sizeof(result));
+ return result;
+}
+
+#ifdef MAIN
+#include <stdlib.h>
+#include <stdio.h>
- return (result);
+int
+main(int argc, char *argv[])
+{
+ printf("%s\n", dirname(argv[1]));
+ exit(0);
}
#endif
+#endif
diff --git a/for.c b/for.c
index 7f10e5626f9a..ec00a456a268 100644
--- a/for.c
+++ b/for.c
@@ -1,4 +1,4 @@
-/* $NetBSD: for.c,v 1.50 2015/10/11 04:51:24 sjg Exp $ */
+/* $NetBSD: for.c,v 1.52 2016/02/18 18:29:14 christos 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.50 2015/10/11 04:51:24 sjg Exp $";
+static char rcsid[] = "$NetBSD: for.c,v 1.52 2016/02/18 18:29:14 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: for.c,v 1.50 2015/10/11 04:51:24 sjg Exp $");
+__RCSID("$NetBSD: for.c,v 1.52 2016/02/18 18:29:14 christos 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, TRUE);
+ sub = Var_Subst(NULL, ptr, VAR_GLOBAL, VARF_WANTRES);
/*
* Split into words allowing for quoted strings.
diff --git a/getopt.c b/getopt.c
index c40bc1356d8c..da29daed2ca8 100644
--- a/getopt.c
+++ b/getopt.c
@@ -1,3 +1,5 @@
+/* $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $ */
+
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
@@ -10,11 +12,7 @@
* 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.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -35,11 +33,7 @@
# include "config.h"
#endif
#if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT)
-
-#if defined(LIBC_SCCS) && !defined(lint)
-/* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */
-static char *rcsid = "$Id: getopt.c,v 1.3 1999/01/08 02:14:18 sjg Exp $";
-#endif /* LIBC_SCCS and not lint */
+#include <sys/cdefs.h>
#include <stdio.h>
#include <stdlib.h>
@@ -61,13 +55,10 @@ char *optarg; /* argument associated with option */
* Parse argc/argv argument vector.
*/
int
-getopt(nargc, nargv, ostr)
- int nargc;
- char * const *nargv;
- const char *ostr;
+getopt(int nargc, char * const nargv[], const char *ostr)
{
extern char *__progname;
- static char *place = EMSG; /* option letter processing */
+ static const char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
#ifndef BSD4_4
@@ -79,43 +70,63 @@ getopt(nargc, nargv, ostr)
}
#endif
- if (optreset || !*place) { /* update scanning pointer */
+ if (optreset || *place == 0) { /* update scanning pointer */
optreset = 0;
- if (optind >= nargc || *(place = nargv[optind]) != '-') {
+ place = nargv[optind];
+ if (optind >= nargc || *place++ != '-') {
+ /* Argument is absent or is not an option */
place = EMSG;
return (-1);
}
- if (place[1] && *++place == '-' /* found "--" */
- && !place[1]) { /* and not "--foo" */
+ optopt = *place++;
+ if (optopt == '-' && *place == 0) {
+ /* "--" => end of options */
++optind;
place = EMSG;
return (-1);
}
- } /* option letter okay? */
- if ((optopt = (int)*place++) == (int)':' ||
- !(oli = strchr(ostr, optopt))) {
- /*
- * if the user didn't specify '-' as an option,
- * assume it means -1.
- */
- if (optopt == (int)'-')
- return (-1);
- if (!*place)
+ if (optopt == 0) {
+ /* Solitary '-', treat as a '-' option
+ if the program (eg su) is looking for it. */
+ place = EMSG;
+ if (strchr(ostr, '-') == NULL)
+ return -1;
+ optopt = '-';
+ }
+ } else
+ optopt = *place++;
+
+ /* See if option letter is one the caller wanted... */
+ if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
+ if (*place == 0)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
- "%s: illegal option -- %c\n", __progname, optopt);
+ "%s: unknown option -- %c\n", __progname, optopt);
return (BADCH);
}
- if (*++oli != ':') { /* don't need argument */
+
+ /* Does this option need an argument? */
+ if (oli[1] != ':') {
+ /* don't need argument */
optarg = NULL;
- if (!*place)
+ if (*place == 0)
++optind;
- }
- else { /* need an argument */
- if (*place) /* no white space */
- optarg = place;
- else if (nargc <= ++optind) { /* no arg */
+ } else {
+ /* Option-argument is either the rest of this argument or the
+ entire next argument. */
+ if (*place)
+ optarg = __UNCONST(place);
+ else if (oli[2] == ':')
+ /*
+ * GNU Extension, for optional arguments if the rest of
+ * the argument is empty, we return NULL
+ */
+ optarg = NULL;
+ else if (nargc > ++optind)
+ optarg = nargv[optind];
+ else {
+ /* option-argument absent */
place = EMSG;
if (*ostr == ':')
return (BADARG);
@@ -125,12 +136,10 @@ getopt(nargc, nargv, ostr)
__progname, optopt);
return (BADCH);
}
- else /* white space */
- optarg = nargv[optind];
place = EMSG;
++optind;
}
- return (optopt); /* dump back option letter */
+ return (optopt); /* return option letter */
}
#endif
#ifdef MAIN
diff --git a/job.c b/job.c
index cc209e6c136f..93e7430bc667 100644
--- a/job.c
+++ b/job.c
@@ -1,4 +1,4 @@
-/* $NetBSD: job.c,v 1.181 2015/10/11 04:51:24 sjg Exp $ */
+/* $NetBSD: job.c,v 1.186 2016/02/18 18:29:14 christos 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.181 2015/10/11 04:51:24 sjg Exp $";
+static char rcsid[] = "$NetBSD: job.c,v 1.186 2016/02/18 18:29:14 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: job.c,v 1.181 2015/10/11 04:51:24 sjg Exp $");
+__RCSID("$NetBSD: job.c,v 1.186 2016/02/18 18:29:14 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -144,7 +144,6 @@ __RCSID("$NetBSD: job.c,v 1.181 2015/10/11 04:51:24 sjg Exp $");
#include <assert.h>
#include <errno.h>
-#include <fcntl.h>
#if !defined(USE_SELECT) && defined(HAVE_POLL_H)
#include <poll.h>
#else
@@ -425,8 +424,8 @@ JobCreatePipe(Job *job, int minfd)
}
/* Set close-on-exec flag for both */
- (void)fcntl(job->jobPipe[0], F_SETFD, 1);
- (void)fcntl(job->jobPipe[1], F_SETFD, 1);
+ (void)fcntl(job->jobPipe[0], F_SETFD, FD_CLOEXEC);
+ (void)fcntl(job->jobPipe[1], F_SETFD, FD_CLOEXEC);
/*
* We mark the input side of the pipe non-blocking; we poll(2) the
@@ -715,7 +714,7 @@ JobPrintCommand(void *cmdp, void *jobp)
numCommands += 1;
- cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE, TRUE);
+ cmdStart = cmd = Var_Subst(NULL, cmd, job->node, VARF_WANTRES);
cmdTemplate = "%s\n";
@@ -866,8 +865,7 @@ JobPrintCommand(void *cmdp, void *jobp)
DBPRINTF(cmdTemplate, cmd);
free(cmdStart);
- if (escCmd)
- free(escCmd);
+ free(escCmd);
if (errOff) {
/*
* If echoing is already off, there's no point in issuing the
@@ -903,7 +901,7 @@ JobPrintCommand(void *cmdp, void *jobp)
static int
JobSaveCommand(void *cmd, void *gn)
{
- cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, FALSE, TRUE);
+ cmd = Var_Subst(NULL, (char *)cmd, (GNode *)gn, VARF_WANTRES);
(void)Lst_AtEnd(postCommands->commands, cmd);
return(0);
}
@@ -1234,8 +1232,7 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
*/
Make_HandleUse(DEFAULT, gn);
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn, 0);
- if (p1)
- free(p1);
+ free(p1);
} else if (Dir_MTime(gn, 0) == 0 && (gn->type & OP_SPECIAL) == 0) {
/*
* The node wasn't the target of an operator we have no .DEFAULT
@@ -1598,7 +1595,7 @@ JobStart(GNode *gn, int flags)
if (job->cmdFILE == NULL) {
Punt("Could not fdopen %s", tfile);
}
- (void)fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
+ (void)fcntl(FILENO(job->cmdFILE), F_SETFD, FD_CLOEXEC);
/*
* Send the commands to the command file, flush all its buffers then
* rewind and remove the thing.
@@ -2195,7 +2192,7 @@ Job_SetPrefix(void)
}
targPrefix = Var_Subst(NULL, "${" MAKE_JOB_PREFIX "}",
- VAR_GLOBAL, FALSE, TRUE);
+ VAR_GLOBAL, VARF_WANTRES);
}
/*-
@@ -2402,8 +2399,7 @@ Job_ParseShell(char *line)
line++;
}
- if (shellArgv)
- free(UNCONST(shellArgv));
+ free(UNCONST(shellArgv));
memset(&newShell, 0, sizeof(newShell));
@@ -2651,8 +2647,7 @@ void
Job_End(void)
{
#ifdef CLEANUP
- if (shellArgv)
- free(shellArgv);
+ free(shellArgv);
#endif
}
@@ -2851,8 +2846,8 @@ Job_ServerStart(int max_tokens, int jp_0, int jp_1)
/* Pipe passed in from parent */
tokenWaitJob.inPipe = jp_0;
tokenWaitJob.outPipe = jp_1;
- (void)fcntl(jp_0, F_SETFD, 1);
- (void)fcntl(jp_1, F_SETFD, 1);
+ (void)fcntl(jp_0, F_SETFD, FD_CLOEXEC);
+ (void)fcntl(jp_1, F_SETFD, FD_CLOEXEC);
return;
}
diff --git a/main.c b/main.c
index fcae4961543f..be6039e7dea8 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.235 2015/10/25 05:24:44 sjg Exp $ */
+/* $NetBSD: main.c,v 1.242 2016/03/07 21:45:43 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: main.c,v 1.235 2015/10/25 05:24:44 sjg Exp $";
+static char rcsid[] = "$NetBSD: main.c,v 1.242 2016/03/07 21:45:43 christos 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.235 2015/10/25 05:24:44 sjg Exp $");
+__RCSID("$NetBSD: main.c,v 1.242 2016/03/07 21:45:43 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -125,7 +125,6 @@ __RCSID("$NetBSD: main.c,v 1.235 2015/10/25 05:24:44 sjg Exp $");
#include "wait.h"
#include <errno.h>
-#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
@@ -696,8 +695,7 @@ Main_ParseArgLine(const char *line)
#endif
buf = bmake_malloc(len = strlen(line) + strlen(argv0) + 2);
(void)snprintf(buf, len, "%s %s", argv0, line);
- if (p1)
- free(p1);
+ free(p1);
argv = brk_string(buf, &argc, TRUE, &args);
if (argv == NULL) {
@@ -723,7 +721,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, FALSE, TRUE);
+ path = p = Var_Subst(NULL, buf, VAR_GLOBAL, VARF_WANTRES);
}
if (path[0] != '/') {
@@ -747,8 +745,7 @@ Main_SetObjdir(const char *path)
}
}
- if (p)
- free(p);
+ free(p);
return rc;
}
@@ -807,7 +804,7 @@ MakeMode(const char *mode)
if (!mode)
mode = mp = Var_Subst(NULL, "${" MAKE_MODE ":tl}",
- VAR_GLOBAL, FALSE, TRUE);
+ VAR_GLOBAL, VARF_WANTRES);
if (mode && *mode) {
if (strstr(mode, "compat")) {
@@ -819,8 +816,8 @@ MakeMode(const char *mode)
meta_mode_init(mode);
#endif
}
- if (mp)
- free(mp);
+
+ free(mp);
}
/*-
@@ -1253,7 +1250,7 @@ main(int argc, char **argv)
(char *)Lst_Datum(ln));
} else {
p1 = Var_Subst(NULL, "${" MAKEFILE_PREFERENCE "}",
- VAR_CMD, FALSE, TRUE);
+ VAR_CMD, VARF_WANTRES);
if (p1) {
(void)str2Lst_Append(makefiles, p1, NULL);
(void)Lst_Find(makefiles, NULL, ReadMakefile);
@@ -1264,7 +1261,7 @@ 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, FALSE, TRUE);
+ VAR_CMD, VARF_WANTRES);
doing_depend = TRUE;
(void)ReadMakefile(makeDependfile, NULL);
doing_depend = FALSE;
@@ -1276,8 +1273,7 @@ main(int argc, char **argv)
MakeMode(NULL);
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
- if (p1)
- free(p1);
+ free(p1);
if (!compatMake)
Job_ServerStart(maxJobTokens, jp_0, jp_1);
@@ -1302,7 +1298,7 @@ main(int argc, char **argv)
*/
static char VPATH[] = "${VPATH}";
- vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE, TRUE);
+ vpath = Var_Subst(NULL, VPATH, VAR_CMD, VARF_WANTRES);
path = vpath;
do {
/* skip to end of directory */
@@ -1350,7 +1346,7 @@ main(int argc, char **argv)
if (strchr(var, '$')) {
value = p1 = Var_Subst(NULL, var, VAR_GLOBAL,
- FALSE, TRUE);
+ VARF_WANTRES);
} else if (expandVars) {
char tmp[128];
@@ -1358,13 +1354,12 @@ main(int argc, char **argv)
Fatal("%s: variable name too big: %s",
progname, var);
value = p1 = Var_Subst(NULL, tmp, VAR_GLOBAL,
- FALSE, TRUE);
+ VARF_WANTRES);
} else {
value = Var_Value(var, VAR_GLOBAL, &p1);
}
printf("%s\n", value ? value : "");
- if (p1)
- free(p1);
+ free(p1);
}
} else {
/*
@@ -1420,6 +1415,9 @@ main(int argc, char **argv)
if (enterFlag)
printf("%s: Leaving directory `%s'\n", progname, curdir);
+#ifdef USE_META
+ meta_finish();
+#endif
Suff_End();
Targ_End();
Arch_End();
@@ -1488,8 +1486,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
name = Dir_FindFile(fname,
Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
if (!name || (fd = open(name, O_RDONLY)) == -1) {
- if (name)
- free(name);
+ free(name);
free(path);
return(-1);
}
@@ -1896,7 +1893,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, FALSE, TRUE);
+ cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
if (cp) {
if (*cp)
printf("%s", cp);
@@ -1927,7 +1924,7 @@ Main_ExportMAKEFLAGS(Boolean first)
strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}",
sizeof(tmp));
- s = Var_Subst(NULL, tmp, VAR_CMD, FALSE, TRUE);
+ s = Var_Subst(NULL, tmp, VAR_CMD, VARF_WANTRES);
if (s && *s) {
#ifdef POSIX
setenv("MAKEFLAGS", s, 1);
@@ -1950,7 +1947,7 @@ getTmpdir(void)
* Ensure it ends with /.
*/
tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
- FALSE, TRUE);
+ VARF_WANTRES);
if (stat(tmpdir, &st) < 0 || !S_ISDIR(st.st_mode)) {
free(tmpdir);
tmpdir = bmake_strdup(_PATH_TMP);
@@ -1990,6 +1987,44 @@ mkTempFile(const char *pattern, char **fnamep)
return fd;
}
+/*
+ * Convert a string representation of a boolean.
+ * Anything that looks like "No", "False", "Off", "0" etc,
+ * is FALSE, otherwise TRUE.
+ */
+Boolean
+s2Boolean(const char *s, Boolean bf)
+{
+ if (s) {
+ switch(*s) {
+ case '\0': /* not set - the default wins */
+ break;
+ case '0':
+ case 'F':
+ case 'f':
+ case 'N':
+ case 'n':
+ bf = FALSE;
+ break;
+ case 'O':
+ case 'o':
+ switch (s[1]) {
+ case 'F':
+ case 'f':
+ bf = FALSE;
+ break;
+ default:
+ bf = TRUE;
+ break;
+ }
+ break;
+ default:
+ bf = TRUE;
+ break;
+ }
+ }
+ return (bf);
+}
/*
* Return a Boolean based on setting of a knob.
@@ -2004,32 +2039,11 @@ getBoolean(const char *name, Boolean bf)
char tmp[64];
char *cp;
- if (snprintf(tmp, sizeof(tmp), "${%s:tl}", name) < (int)(sizeof(tmp))) {
- cp = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE);
+ if (snprintf(tmp, sizeof(tmp), "${%s:U:tl}", name) < (int)(sizeof(tmp))) {
+ cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
if (cp) {
- switch(*cp) {
- case '\0': /* not set - the default wins */
- break;
- case '0':
- case 'f':
- case 'n':
- bf = FALSE;
- break;
- case 'o':
- switch (cp[1]) {
- case 'f':
- bf = FALSE;
- break;
- default:
- bf = TRUE;
- break;
- }
- break;
- default:
- bf = TRUE;
- break;
- }
+ bf = s2Boolean(cp, bf);
free(cp);
}
}
diff --git a/make.1 b/make.1
index 14725498a094..6a54694d26c0 100644
--- a/make.1
+++ b/make.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: make.1,v 1.249 2015/06/05 07:33:40 wiz Exp $
+.\" $NetBSD: make.1,v 1.254 2016/02/20 01:43:28 wiz Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd June 4, 2015
+.Dd February 19, 2016
.Dt MAKE 1
.Os
.Sh NAME
@@ -293,7 +293,7 @@ then
will search for the specified file or directory named in the remaining part
of the argument string.
The search starts with the current directory of
-the Makefile and then works upward towards the root of the filesystem.
+the Makefile and then works upward towards the root of the file system.
If the search is successful, then the resulting directory replaces the
.Qq \&.../
specification in the
@@ -868,7 +868,7 @@ This can be overridden by setting
.Va bf
to a value which represents True.
.It Pa env
-For debugging, it can be useful to inlcude the environment
+For debugging, it can be useful to include the environment
in the .meta file.
.It Pa verbose
If in "meta" mode, print a clue about the target being built.
@@ -918,7 +918,7 @@ The default value is:
This variable is used to record the names of variables assigned to
on the command line, so that they may be exported as part of
.Ql Ev MAKEFLAGS .
-This behaviour can be disabled by assigning an empty value to
+This behavior can be disabled by assigning an empty value to
.Ql Va .MAKEOVERRIDES
within a makefile.
Extra variables can be exported from a makefile
@@ -941,6 +941,19 @@ The process-id of
.It Va .MAKE.PPID
The parent process-id of
.Nm .
+.It Va .MAKE.SAVE_DOLLARS
+value should be a boolean that controls whether
+.Ql $$
+are preserved when doing
+.Ql :=
+assignments.
+The default is false, for backwards compatibility.
+Set to true for compatability with other makes.
+If set to false,
+.Ql $$
+becomes
+.Ql $
+per normal evaluation rules.
.It Va MAKE_PRINT_VAR_ON_ERROR
When
.Nm
@@ -1044,7 +1057,7 @@ sets
to the value of
.Ql Ev PWD
instead.
-This behaviour is disabled if
+This behavior is disabled if
.Ql Ev MAKEOBJDIRPREFIX
is set or
.Ql Ev MAKEOBJDIR
@@ -1114,7 +1127,7 @@ The wildcard characters may be escaped with a backslash
As a consequence of the way values are split into words, matched,
and then joined, a construct like
.Dl ${VAR:M*}
-will normalise the inter-word spacing, removing all leading and
+will normalize the inter-word spacing, removing all leading and
trailing space, and converting multiple consecutive spaces
to single spaces.
.
@@ -1134,7 +1147,7 @@ Randomize words in variable.
The results will be different each time you are referring to the
modified variable; use the assignment with expansion
.Pq Ql Cm \&:=
-to prevent such behaviour.
+to prevent such behavior.
For example,
.Bd -literal -offset indent
LIST= uno due tre quattro
@@ -1166,7 +1179,7 @@ The value is a format string for
using the current
.Xr gmtime 3 .
.It Cm \&:hash
-Compute a 32bit hash of the value and encode it as hex digits.
+Compute a 32-bit hash of the value and encode it as hex digits.
.It Cm \&:localtime
The value is a format string for
.Xr strftime 3 ,
@@ -1444,7 +1457,7 @@ value is divided into words.
.Pp
Ordinarily, a value is treated as a sequence of words
delimited by white space.
-Some modifiers suppress this behaviour,
+Some modifiers suppress this behavior,
causing a value to be treated as a single word
(possibly containing embedded white space).
An empty value, or a value that consists entirely of white-space,
@@ -1530,12 +1543,20 @@ For compatibility with other versions of
.Nm
.Ql include file ...
is also accepted.
+.Pp
If the include statement is written as
.Cm .-include
or as
.Cm .sinclude
then errors locating and/or opening include files are ignored.
.Pp
+If the include statement is written as
+.Cm .dinclude
+not only are errors locating and/or opening include files ignored,
+but stale dependencies within the included file will be ignored
+just like
+.Va .MAKE.DEPENDFILE .
+.Pp
Conditional expressions are also preceded by a single dot as the first
character of a line.
The possible conditionals are as follows:
@@ -1571,6 +1592,10 @@ This allows exporting a value to the environment which is different from that
used by
.Nm
internally.
+.It Ic .export-literal Ar variable ...
+The same as
+.Ql .export-env ,
+except that variables in the value are not expanded.
.It Ic .info Ar message
The message is printed along with the name of the makefile and line number.
.It Ic .undef Ar variable
@@ -2068,7 +2093,7 @@ The sources are a set of
pairs.
.Bl -tag -width hasErrCtls
.It Ar name
-This is the minimal specification, used to select one of the builtin
+This is the minimal specification, used to select one of the built-in
shell specs;
.Ar sh ,
.Ar ksh ,
diff --git a/make.c b/make.c
index b43bfd578cf0..5ea04fc0a8bc 100644
--- a/make.c
+++ b/make.c
@@ -1,4 +1,4 @@
-/* $NetBSD: make.c,v 1.92 2015/10/11 04:51:24 sjg Exp $ */
+/* $NetBSD: make.c,v 1.95 2016/02/18 18:29:14 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: make.c,v 1.92 2015/10/11 04:51:24 sjg Exp $";
+static char rcsid[] = "$NetBSD: make.c,v 1.95 2016/02/18 18:29:14 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
#else
-__RCSID("$NetBSD: make.c,v 1.92 2015/10/11 04:51:24 sjg Exp $");
+__RCSID("$NetBSD: make.c,v 1.95 2016/02/18 18:29:14 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -482,10 +482,9 @@ Make_HandleUse(GNode *cgn, GNode *pgn)
if (gn->uname == NULL) {
gn->uname = gn->name;
} else {
- if (gn->name)
- free(gn->name);
+ free(gn->name);
}
- gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE, TRUE);
+ gn->name = Var_Subst(NULL, gn->uname, pgn, VARF_WANTRES);
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);
@@ -692,8 +691,7 @@ Make_Update(GNode *cgn)
checked++;
cname = Var_Value(TARGET, cgn, &p1);
- if (p1)
- free(p1);
+ free(p1);
if (DEBUG(MAKE))
fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num);
@@ -838,8 +836,7 @@ Make_Update(GNode *cgn)
Var_Set(PREFIX, cpref, pgn, 0);
}
}
- if (p1)
- free(p1);
+ free(p1);
Lst_Close(cgn->iParents);
}
}
@@ -907,8 +904,7 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
}
if (allsrc != NULL)
Var_Append(ALLSRC, allsrc, pgn);
- if (p2)
- free(p2);
+ free(p2);
if (pgn->type & OP_JOIN) {
if (cgn->made == MADE) {
Var_Append(OODATE, child, pgn);
@@ -934,8 +930,7 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
*/
Var_Append(OODATE, child, pgn);
}
- if (p1)
- free(p1);
+ free(p1);
}
return (0);
}
@@ -981,8 +976,7 @@ Make_DoAllVar(GNode *gn)
if (gn->type & OP_JOIN) {
char *p1;
Var_Set(TARGET, Var_Value(ALLSRC, gn, &p1), gn, 0);
- if (p1)
- free(p1);
+ free(p1);
}
gn->flags |= DONE_ALLSRC;
}
diff --git a/make.h b/make.h
index 7cf34d82e0a6..444850544206 100644
--- a/make.h
+++ b/make.h
@@ -1,4 +1,4 @@
-/* $NetBSD: make.h,v 1.96 2015/09/21 21:50:16 pooka Exp $ */
+/* $NetBSD: make.h,v 1.98 2016/02/18 18:29:14 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -88,6 +88,7 @@
#include <sys/param.h>
#include <ctype.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
@@ -98,6 +99,10 @@
#include <unistd.h>
#include <sys/cdefs.h>
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 1
+#endif
+
#if defined(__GNUC__)
#define MAKE_GNUC_PREREQ(x, y) \
((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
@@ -501,6 +506,10 @@ Boolean Main_SetObjdir(const char *);
int mkTempFile(const char *, char **);
int str2Lst_Append(Lst, char *, const char *);
+#define VARF_UNDEFERR 1
+#define VARF_WANTRES 2
+#define VARF_ASSIGN 4
+
#ifdef __GNUC__
#define UNCONST(ptr) ({ \
union __unconst { \
diff --git a/meta.c b/meta.c
index a7a4b1962908..f4acbde937ee 100644
--- a/meta.c
+++ b/meta.c
@@ -1,4 +1,4 @@
-/* $NetBSD: meta.c,v 1.41 2015/11/30 23:37:56 sjg Exp $ */
+/* $NetBSD: meta.c,v 1.53 2016/03/07 21:45:43 christos Exp $ */
/*
* Implement 'meta' mode.
@@ -6,7 +6,7 @@
* --sjg
*/
/*
- * Copyright (c) 2009-2010, Juniper Networks, Inc.
+ * Copyright (c) 2009-2016, Juniper Networks, Inc.
* Portions Copyright (c) 2009, John Birrell.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,7 +37,6 @@
#endif
#include <sys/stat.h>
#include <sys/ioctl.h>
-#include <fcntl.h>
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
#elif !defined(HAVE_DIRNAME)
@@ -60,7 +59,9 @@ char * dirname(char *);
static BuildMon Mybm; /* for compat */
static Lst metaBailiwick; /* our scope of control */
+static char *metaBailiwickStr; /* string storage for the list */
static Lst metaIgnorePaths; /* paths we deliberately ignore */
+static char *metaIgnorePathsStr; /* string storage for the list */
#ifndef MAKE_META_IGNORE_PATHS
#define MAKE_META_IGNORE_PATHS ".MAKE.META.IGNORE_PATHS"
@@ -148,8 +149,8 @@ filemon_open(BuildMon *pbm)
err(1, "Could not set filemon file descriptor!");
}
/* we don't need these once we exec */
- (void)fcntl(pbm->mon_fd, F_SETFD, 1);
- (void)fcntl(pbm->filemon_fd, F_SETFD, 1);
+ (void)fcntl(pbm->mon_fd, F_SETFD, FD_CLOEXEC);
+ (void)fcntl(pbm->filemon_fd, F_SETFD, FD_CLOEXEC);
}
/*
@@ -300,8 +301,7 @@ meta_name(struct GNode *gn, char *mname, size_t mnamelen,
}
free(tp);
for (i--; i >= 0; i--) {
- if (p[i])
- free(p[i]);
+ free(p[i]);
}
return (mname);
}
@@ -328,7 +328,7 @@ is_submake(void *cmdp, void *gnp)
}
cp = strchr(cmd, '$');
if ((cp)) {
- mp = Var_Subst(NULL, cmd, gn, FALSE, TRUE);
+ mp = Var_Subst(NULL, cmd, gn, VARF_WANTRES);
cmd = mp;
}
cp2 = strstr(cmd, p_make);
@@ -353,8 +353,7 @@ is_submake(void *cmdp, void *gnp)
}
}
}
- if (mp)
- free(mp);
+ free(mp);
return (rc);
}
@@ -371,11 +370,10 @@ printCMD(void *cmdp, void *mfpp)
char *cp = NULL;
if (strchr(cmd, '$')) {
- cmd = cp = Var_Subst(NULL, cmd, mfp->gn, FALSE, TRUE);
+ cmd = cp = Var_Subst(NULL, cmd, mfp->gn, VARF_WANTRES);
}
fprintf(mfp->fp, "CMD %s\n", cmd);
- if (cp)
- free(cp);
+ free(cp);
return 0;
}
@@ -466,7 +464,7 @@ meta_create(BuildMon *pbm, GNode *gn)
char *mp;
/* Describe the target we are building */
- mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, FALSE, TRUE);
+ mp = Var_Subst(NULL, "${" MAKE_META_PREFIX "}", gn, VARF_WANTRES);
if (*mp)
fprintf(stdout, "%s\n", mp);
free(mp);
@@ -480,9 +478,6 @@ meta_create(BuildMon *pbm, GNode *gn)
fflush(stdout);
- if (strcmp(cp, makeDependfile) == 0)
- goto out;
-
if (!writeMeta)
/* Don't create meta data. */
goto out;
@@ -524,8 +519,7 @@ meta_create(BuildMon *pbm, GNode *gn)
}
out:
for (i--; i >= 0; i--) {
- if (p[i])
- free(p[i]);
+ free(p[i]);
}
return (mf.fp);
@@ -609,10 +603,10 @@ 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,
- FALSE, TRUE);
- if (cp) {
- str2Lst_Append(metaBailiwick, cp, NULL);
+ metaBailiwickStr = Var_Subst(NULL, "${.MAKE.META.BAILIWICK:O:u:tA}",
+ VAR_GLOBAL, VARF_WANTRES);
+ if (metaBailiwickStr) {
+ str2Lst_Append(metaBailiwick, metaBailiwickStr, NULL);
}
/*
* We ignore any paths that start with ${.MAKE.META.IGNORE_PATHS}
@@ -620,11 +614,11 @@ meta_mode_init(const char *make_mode)
metaIgnorePaths = Lst_Init(FALSE);
Var_Append(MAKE_META_IGNORE_PATHS,
"/dev /etc /proc /tmp /var/run /var/tmp ${TMPDIR}", VAR_GLOBAL);
- cp = Var_Subst(NULL,
+ metaIgnorePathsStr = Var_Subst(NULL,
"${" MAKE_META_IGNORE_PATHS ":O:u:tA}", VAR_GLOBAL,
- FALSE, TRUE);
- if (cp) {
- str2Lst_Append(metaIgnorePaths, cp, NULL);
+ VARF_WANTRES);
+ if (metaIgnorePathsStr) {
+ str2Lst_Append(metaIgnorePaths, metaIgnorePathsStr, NULL);
}
}
@@ -693,9 +687,9 @@ meta_job_error(Job *job, GNode *gn, int flags, int status)
if (job != NULL) {
pbm = &job->bm;
- } else {
if (!gn)
gn = job->node;
+ } else {
pbm = &Mybm;
}
if (pbm->mfp != NULL) {
@@ -709,7 +703,7 @@ meta_job_error(Job *job, GNode *gn, int flags, int status)
}
getcwd(cwd, sizeof(cwd));
Var_Set(".ERROR_CWD", cwd, VAR_GLOBAL, 0);
- if (pbm && pbm->meta_fname[0]) {
+ if (pbm->meta_fname[0]) {
Var_Set(".ERROR_META_FILE", pbm->meta_fname, VAR_GLOBAL, 0);
}
meta_job_finish(job);
@@ -734,7 +728,7 @@ meta_job_output(Job *job, char *cp, const char *nl)
char *cp2;
meta_prefix = Var_Subst(NULL, "${" MAKE_META_PREFIX "}",
- VAR_GLOBAL, FALSE, TRUE);
+ VAR_GLOBAL, VARF_WANTRES);
if ((cp2 = strchr(meta_prefix, '$')))
meta_prefix_len = cp2 - meta_prefix;
else
@@ -785,6 +779,15 @@ meta_job_finish(Job *job)
}
}
+void
+meta_finish(void)
+{
+ Lst_Destroy(metaBailiwick, NULL);
+ free(metaBailiwickStr);
+ Lst_Destroy(metaIgnorePaths, NULL);
+ free(metaIgnorePathsStr);
+}
+
/*
* Fetch a full line from fp - growing bufp if needed
* Return length in bufp.
@@ -1035,14 +1038,12 @@ meta_oodate(GNode *gn, Boolean oodate)
ldir = Var_Value(ldir_vname, VAR_GLOBAL, &tp);
if (ldir) {
strlcpy(latestdir, ldir, sizeof(latestdir));
- if (tp)
- free(tp);
+ free(tp);
}
ldir = Var_Value(lcwd_vname, VAR_GLOBAL, &tp);
if (ldir) {
strlcpy(lcwd, ldir, sizeof(lcwd));
- if (tp)
- free(tp);
+ free(tp);
}
}
/* Skip past the pid. */
@@ -1320,7 +1321,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, TRUE);
+ cmd = Var_Subst(NULL, cmd, gn, VARF_WANTRES|VARF_UNDEFERR);
if ((cp = strchr(cmd, '\n'))) {
int n;
@@ -1382,7 +1383,6 @@ meta_oodate(GNode *gn, Boolean oodate)
fprintf(debug_file, "%s: missing files: %s...\n",
fname, (char *)Lst_Datum(Lst_First(missingFiles)));
oodate = TRUE;
- Lst_Destroy(missingFiles, (FreeProc *)free);
}
} else {
if ((gn->type & OP_META)) {
@@ -1391,6 +1391,9 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
}
}
+
+ Lst_Destroy(missingFiles, (FreeProc *)free);
+
if (oodate && needOODATE) {
/*
* Target uses .OODATE which is empty; or we wouldn't be here.
@@ -1399,8 +1402,7 @@ meta_oodate(GNode *gn, Boolean oodate)
*/
Var_Delete(OODATE, gn);
Var_Set(OODATE, Var_Value(ALLSRC, gn, &cp), gn, 0);
- if (cp)
- free(cp);
+ free(cp);
}
return oodate;
}
@@ -1427,8 +1429,8 @@ meta_compat_start(void)
if (pipe(childPipe) < 0)
Punt("Cannot create pipe: %s", strerror(errno));
/* Set close-on-exec flag for both */
- (void)fcntl(childPipe[0], F_SETFD, 1);
- (void)fcntl(childPipe[1], F_SETFD, 1);
+ (void)fcntl(childPipe[0], F_SETFD, FD_CLOEXEC);
+ (void)fcntl(childPipe[1], F_SETFD, FD_CLOEXEC);
}
void
diff --git a/meta.h b/meta.h
index 57c73ca9b5f1..e9f5ed362969 100644
--- a/meta.h
+++ b/meta.h
@@ -1,4 +1,4 @@
-/* $NetBSD: meta.h,v 1.3 2013/03/23 05:31:29 sjg Exp $ */
+/* $NetBSD: meta.h,v 1.4 2016/03/07 21:45:43 christos Exp $ */
/*
* Things needed for 'meta' mode.
@@ -42,6 +42,7 @@ extern Boolean useMeta;
struct Job; /* not defined yet */
void meta_init(void);
+void meta_finish(void);
void meta_mode_init(const char *);
void meta_job_start(struct Job *, GNode *);
void meta_job_child(struct Job *);
diff --git a/mk/ChangeLog b/mk/ChangeLog
index 3c728c8fa7c4..f84b5c5040e9 100644
--- a/mk/ChangeLog
+++ b/mk/ChangeLog
@@ -1,3 +1,42 @@
+2016-03-02 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * meta2deps.sh: don't ignore subdirs.
+ patch from Bryan Drewery
+
+2016-02-26 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * install-mk (MK_VERSION): 20160226
+
+ * gendirdeps.mk: mark _DEPENDFILE .NOMETA
+
+2016-02-20 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * dirdeps.mk: we shouldn't normally include .depend but if we do
+ use .dinclude if we can.
+
+2016-02-18 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * install-mk (MK_VERSION): 20160218
+ * sys.clean-env.mk: with recent change to Var_Subst()
+ we cannot use the '$$' trick, but .export-literal does the job
+ we need.
+ * auto.dep.mk: make use .dinclude if we can.
+
+
+2016-02-05 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * dirdeps.mk:
+ Add _build_all_dirs such that local.dirdeps.mk can
+ add fully qualified dirs to it.
+ These will be built normally but the current
+ DEP_RELDIR will not depend on then (to avoid cycles).
+ This makes it easy to hook things like unit-tests into build.
+
+
+2016-01-21 Simon J. Gerraty <sjg@bad.crufty.net>
+
+ * dirdeps.mk: add bootstrap-empty
+
2015-12-12 Simon J. Gerraty <sjg@bad.crufty.net>
* install-mk (MK_VERSION): 20151212
diff --git a/mk/auto.dep.mk b/mk/auto.dep.mk
index 33137248d450..6bc53e528ac1 100644
--- a/mk/auto.dep.mk
+++ b/mk/auto.dep.mk
@@ -1,6 +1,6 @@
#
# RCSid:
-# $Id: auto.dep.mk,v 1.3 2014/08/04 05:19:10 sjg Exp $
+# $Id: auto.dep.mk,v 1.4 2016/02/18 21:16:39 sjg Exp $
#
# @(#) Copyright (c) 2010, Simon J. Gerraty
#
@@ -45,6 +45,7 @@ CXXFLAGS += ${CFLAGS_MD} ${CFLAGS_MF}
CLEANFILES += .depend ${.MAKE.DEPENDFILE} *.d
+.if ${MAKE_VERSION} < 20160218
# skip generating dependfile for misc targets
.if ${.TARGETS:Uall:M*all} != ""
.END: ${.MAKE.DEPENDFILE}
@@ -60,5 +61,14 @@ ${.MAKE.DEPENDFILE}: ${OBJS} ${POBJS} ${SOBJS}
-@for f in ${.ALLSRC:M*o:T:O:u:%=%.d}; do \
echo ".-include \"$$f\""; \
done > $@
+.else
+# we have .dinclude
+.if empty(_SKIP_BUILD)
+_all_objs = ${OBJS} ${POBJS} ${SOBJS}
+.for d in ${_all_objs:M*o:T:O:u:%=%.d}
+.dinclude "$d"
+.endfor
+.endif
.endif
+.endif
diff --git a/mk/dirdeps.mk b/mk/dirdeps.mk
index 823115d7a8ce..ec37e35dfa54 100644
--- a/mk/dirdeps.mk
+++ b/mk/dirdeps.mk
@@ -1,4 +1,4 @@
-# $Id: dirdeps.mk,v 1.55 2015/10/20 22:04:53 sjg Exp $
+# $Id: dirdeps.mk,v 1.59 2016/02/26 23:32:29 sjg Exp $
# Copyright (c) 2010-2013, Juniper Networks, Inc.
# All rights reserved.
@@ -121,6 +121,9 @@ _DIRDEP_USE_LEVEL?= 0
# and non-specific Makefile.depend*
.if !target(_DIRDEP_USE)
+# make sure we get the behavior we expect
+.MAKE.SAVE_DOLLARS = no
+
# do some setup we only need once
_CURDIR ?= ${.CURDIR}
_OBJDIR ?= ${.OBJDIR}
@@ -256,11 +259,8 @@ DEP_RELDIR := ${DIRDEPS:R:[1]}
MK_DIRDEPS_CACHE = no
.endif
-
-# pickup customizations
-# as below you can use !target(_DIRDEP_USE) to protect things
-# which should only be done once.
-.-include "local.dirdeps.mk"
+# reset each time through
+_build_all_dirs =
# the first time we are included the _DIRDEP_USE target will not be defined
# we can use this as a clue to do initialization and other one time things.
@@ -280,6 +280,14 @@ DEBUG_DIRDEPS ?= no
# remember the initial value of DEP_RELDIR - we test for it below.
_DEP_RELDIR := ${DEP_RELDIR}
+.endif
+
+# pickup customizations
+# as below you can use !target(_DIRDEP_USE) to protect things
+# which should only be done once.
+.-include "local.dirdeps.mk"
+
+.if !target(_DIRDEP_USE)
# things we skip for host tools
SKIP_HOSTDIR ?=
@@ -399,6 +407,7 @@ ${DIRDEPS_CACHE}: .META .NOMETA_CMP
MAKEFLAGS= ${.MAKE} -C ${_CURDIR} -f ${BUILD_DIRDEPS_MAKEFILE} \
${BUILD_DIRDEPS_TARGETS} BUILD_DIRDEPS_CACHE=yes \
.MAKE.DEPENDFILE=.none \
+ ${.MAKEFLAGS:tW:S,-D ,-D,g:tw:M*WITH*} \
3>&1 1>&2 | sed 's,${SRCTOP},$${SRCTOP},g' >> ${.TARGET}.new && \
mv ${.TARGET}.new ${.TARGET}
@@ -479,7 +488,11 @@ _build_dirs += ${_machines:@m@${_CURDIR}.$m@}
_build_dirs += ${_machines:N${DEP_TARGET_SPEC}:@m@${_CURDIR}.$m@}
.if ${DEP_TARGET_SPEC} == ${TARGET_SPEC}
# pickup local dependencies now
+.if ${MAKE_VERSION} < 20160220
.-include <.depend>
+.else
+.dinclude <.depend>
+.endif
.endif
.endif
.endif
@@ -531,22 +544,25 @@ _build_dirs += \
# qualify everything now
_build_dirs := ${_build_dirs:${M_dep_qual_fixes:ts:}:O:u}
+_build_all_dirs += ${_build_dirs}
+_build_all_dirs := ${_build_all_dirs:O:u}
+
.endif # empty DIRDEPS
# Normally if doing make -V something,
# we do not want to waste time chasing DIRDEPS
# but if we want to count the number of Makefile.depend* read, we do.
.if ${.MAKEFLAGS:M-V${_V_READ_DIRDEPS}} == ""
-.if !empty(_build_dirs)
+.if !empty(_build_all_dirs)
.if ${BUILD_DIRDEPS_CACHE} == "yes"
x!= { echo; echo '\# ${DEP_RELDIR}.${DEP_TARGET_SPEC}'; \
- echo 'dirdeps: ${_build_dirs:${M_oneperline}}'; echo; } >&3; echo
-x!= { ${_build_dirs:@x@${target($x):?:echo '$x: _DIRDEP_USE';}@} echo; } >&3; echo
+ echo 'dirdeps: ${_build_all_dirs:${M_oneperline}}'; echo; } >&3; echo
+x!= { ${_build_all_dirs:@x@${target($x):?:echo '$x: _DIRDEP_USE';}@} echo; } >&3; echo
.else
# this makes it all happen
-dirdeps: ${_build_dirs}
+dirdeps: ${_build_all_dirs}
.endif
-${_build_dirs}: _DIRDEP_USE
+${_build_all_dirs}: _DIRDEP_USE
.if ${_debug_reldir}
.info ${DEP_RELDIR}.${DEP_TARGET_SPEC}: needs: ${_build_dirs}
@@ -580,14 +596,14 @@ ${_this_dir}.$m: ${_build_dirs:M*.$m:N${_this_dir}.$m}
.endif
# Now find more dependencies - and recurse.
-.for d in ${_build_dirs}
+.for d in ${_build_all_dirs}
.if ${_DIRDEP_CHECKED:M$d} == ""
# once only
_DIRDEP_CHECKED += $d
.if ${_debug_search}
.info checking $d
.endif
-# Note: _build_dirs is fully qualifed so d:R is always the directory
+# Note: _build_all_dirs is fully qualifed so d:R is always the directory
.if exists(${d:R})
# Warning: there is an assumption here that MACHINE is always
# the first entry in TARGET_SPEC_VARS.
@@ -627,28 +643,37 @@ DIRDEPS =
DEP_RELDIR := ${RELDIR}
_DEP_RELDIR := ${RELDIR}
# pickup local dependencies
+.if ${MAKE_VERSION} < 20160220
.-include <.depend>
+.else
+.dinclude <.depend>
+.endif
.endif
# bootstrapping new dependencies made easy?
-.if (make(bootstrap) || make(bootstrap-recurse)) && !target(bootstrap)
+.if !target(bootstrap) && (make(bootstrap) || \
+ make(bootstrap-this) || \
+ make(bootstrap-recurse) || \
+ make(bootstrap-empty))
.if exists(${.CURDIR}/${.MAKE.DEPENDFILE:T})
# stop here
${.TARGETS:Mboot*}:
-.else
+.elif !make(bootstrap-empty)
# find a Makefile.depend to use as _src
_src != cd ${.CURDIR} && for m in ${.MAKE.DEPENDFILE_PREFERENCE:T:S,${MACHINE},*,}; do test -s $$m || continue; echo $$m; break; done; echo
.if empty(_src)
-.error cannot find any of ${.MAKE.DEPENDFILE_PREFERENCE:T}
+.error cannot find any of ${.MAKE.DEPENDFILE_PREFERENCE:T}${.newline}Use: bootstrap-empty
.endif
_src?= ${.MAKE.DEPENDFILE:T}
+# just create Makefile.depend* for this dir
bootstrap-this: .NOTMAIN
@echo Bootstrapping ${RELDIR}/${.MAKE.DEPENDFILE:T} from ${_src:T}
(cd ${.CURDIR} && sed 's,${_src:E},${MACHINE},g' ${_src} > ${.MAKE.DEPENDFILE:T})
+# create Makefile.depend* for this dir and its dependencies
bootstrap: bootstrap-recurse
bootstrap-recurse: bootstrap-this
@@ -663,4 +688,11 @@ bootstrap-recurse: .NOTMAIN .MAKE
done
.endif
+
+# create an empty Makefile.depend* to get the ball rolling.
+bootstrap-empty: .NOTMAIN .NOMETA
+ @echo Creating empty ${RELDIR}/${.MAKE.DEPENDFILE:T}; \
+ echo You need to build ${RELDIR} to correctly populate it.
+ @{ echo DIRDEPS=; echo ".include <dirdeps.mk>"; } > ${.CURDIR}/${.MAKE.DEPENDFILE:T}
+
.endif
diff --git a/mk/gendirdeps.mk b/mk/gendirdeps.mk
index 2497f853c3b6..8b803385c54b 100644
--- a/mk/gendirdeps.mk
+++ b/mk/gendirdeps.mk
@@ -1,4 +1,4 @@
-# $Id: gendirdeps.mk,v 1.29 2015/10/03 05:00:46 sjg Exp $
+# $Id: gendirdeps.mk,v 1.30 2016/02/27 00:20:39 sjg Exp $
# Copyright (c) 2010-2013, Juniper Networks, Inc.
# All rights reserved.
@@ -309,7 +309,7 @@ CAT_DEPEND ?= .depend
# .depend may contain things we don't want.
# 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}
+${_DEPENDFILE}: .NOMETA ${CAT_DEPEND:M.depend} ${META_FILES:O:u:@m@${exists($m):?$m:}@} ${_this} ${META2DEPS}
@(${GENDIRDEPS_HEADER} echo '# Autogenerated - do NOT edit!'; echo; \
echo 'DIRDEPS = \'; \
echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
@@ -329,7 +329,7 @@ DIRDEPS := ${SUBDIR:S,^,${RELDIR}/,:O:u}
all: ${_DEPENDFILE}
-${_DEPENDFILE}: ${MAKEFILE} ${_this}
+${_DEPENDFILE}: .NOMETA ${MAKEFILE} ${_this}
@(${GENDIRDEPS_HEADER} echo '# Autogenerated - do NOT edit!'; echo; \
echo 'DIRDEPS = \'; \
echo '${DIRDEPS:@d@ $d \\${.newline}@}'; echo; \
diff --git a/mk/install-mk b/mk/install-mk
index 0c3db00ba9db..64b238fd8356 100644
--- a/mk/install-mk
+++ b/mk/install-mk
@@ -55,7 +55,7 @@
# Simon J. Gerraty <sjg@crufty.net>
# RCSid:
-# $Id: install-mk,v 1.118 2015/12/16 01:57:06 sjg Exp $
+# $Id: install-mk,v 1.121 2016/02/27 00:23:02 sjg Exp $
#
# @(#) Copyright (c) 1994 Simon J. Gerraty
#
@@ -70,7 +70,7 @@
# sjg@crufty.net
#
-MK_VERSION=20151212
+MK_VERSION=20160226
OWNER=
GROUP=
MODE=444
diff --git a/mk/meta.autodep.mk b/mk/meta.autodep.mk
index c9fdb0ef2221..5f705647efe1 100644
--- a/mk/meta.autodep.mk
+++ b/mk/meta.autodep.mk
@@ -1,4 +1,4 @@
-# $Id: meta.autodep.mk,v 1.39 2015/12/07 04:35:32 sjg Exp $
+# $Id: meta.autodep.mk,v 1.40 2016/02/22 22:44:58 sjg Exp $
#
# @(#) Copyright (c) 2010, Simon J. Gerraty
@@ -86,7 +86,7 @@ WANT_UPDATE_DEPENDFILE ?= yes
.endif
.if ${WANT_UPDATE_DEPENDFILE:Uno:tl} != "no"
-.if ${.MAKE.MODE:Mmeta*} == "" || ${.MAKE.MODE:M*read*} != ""
+.if ${.MAKE.MODE:Uno:Mmeta*} == "" || ${.MAKE.MODE:Uno:M*read*} != ""
UPDATE_DEPENDFILE = no
.endif
diff --git a/mk/meta.stage.mk b/mk/meta.stage.mk
index b77b27a9fea1..0355d66af041 100644
--- a/mk/meta.stage.mk
+++ b/mk/meta.stage.mk
@@ -1,4 +1,4 @@
-# $Id: meta.stage.mk,v 1.41 2015/11/13 17:34:04 sjg Exp $
+# $Id: meta.stage.mk,v 1.43 2016/02/24 18:46:32 sjg Exp $
#
# @(#) Copyright (c) 2011, Simon J. Gerraty
#
@@ -26,7 +26,7 @@ _dirdep = ${RELDIR}
CLEANFILES+= .dirdep
# this allows us to trace dependencies back to their src dir
-.dirdep:
+.dirdep: .NOPATH
@echo '${_dirdep}' > $@
.if defined(NO_POSIX_SHELL) || ${type printf:L:sh:Mbuiltin} == ""
@@ -241,7 +241,7 @@ CLEANFILES += ${STAGE_TARGETS} stage_incs stage_includes
# 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} != ""
+.if ${.MAKE.JOBS:U0} > 0 && ${STAGE_TARGETS:U:M*_links} != ""
# the above isn't sufficient
.for t in ${STAGE_TARGETS:N*links:O:u}
.ORDER: $t stage_links
diff --git a/mk/meta.sys.mk b/mk/meta.sys.mk
index 8e55878b628b..764f2d1570ef 100644
--- a/mk/meta.sys.mk
+++ b/mk/meta.sys.mk
@@ -1,4 +1,4 @@
-# $Id: meta.sys.mk,v 1.26 2015/11/14 21:16:13 sjg Exp $
+# $Id: meta.sys.mk,v 1.27 2016/02/22 22:44:58 sjg Exp $
#
# @(#) Copyright (c) 2010, Simon J. Gerraty
@@ -102,7 +102,7 @@ META_COOKIE_TOUCH=
# some targets need to be .PHONY in non-meta mode
META_NOPHONY= .PHONY
# Are we, after all, in meta mode?
-.if ${.MAKE.MODE:Mmeta*} != ""
+.if ${.MAKE.MODE:Uno:Mmeta*} != ""
MKDEP_MK = meta.autodep.mk
.if ${.MAKE.MAKEFILES:M*sys.dependfile.mk} == ""
diff --git a/mk/meta2deps.sh b/mk/meta2deps.sh
index 2a79be17a331..8fb5ec6670e3 100755
--- a/mk/meta2deps.sh
+++ b/mk/meta2deps.sh
@@ -77,7 +77,7 @@
# RCSid:
-# $Id: meta2deps.sh,v 1.9 2015/04/03 18:23:25 sjg Exp $
+# $Id: meta2deps.sh,v 1.10 2016/03/02 18:53:36 sjg Exp $
# Copyright (c) 2010-2013, Juniper Networks, Inc.
# All rights reserved.
@@ -309,7 +309,7 @@ meta2deps() {
*) seen=$dir;;
esac
case "$dir" in
- ${CURDIR:-.}|${CURDIR:-.}/*|"") continue;;
+ ${CURDIR:-.}|"") continue;;
$src_re)
# avoid repeating ourselves...
case "$DPDEPS,$seensrc," in
diff --git a/mk/sys.clean-env.mk b/mk/sys.clean-env.mk
index b1867c3804bc..396599bd7832 100644
--- a/mk/sys.clean-env.mk
+++ b/mk/sys.clean-env.mk
@@ -1,4 +1,4 @@
-# $Id: sys.clean-env.mk,v 1.20 2012/11/12 06:56:04 sjg Exp $
+# $Id: sys.clean-env.mk,v 1.21 2016/02/18 21:16:40 sjg Exp $
#
# @(#) Copyright (c) 2009, Simon J. Gerraty
#
@@ -94,6 +94,7 @@ _tricky_env_vars = MAKEOBJDIR OBJTOP
# MAKEOBJDIR='${.CURDIR:S,${SRCTOP},${OBJTOP},}'
_srctop := ${SRCTOP:U${SB_SRC:U${SB}/src}}
_objroot := ${OBJROOT:U${SB_OBJROOT:U${SB}/${SB_OBJPREFIX}}}
+.if ${MAKE_VERSION} < 20160218
_objtop := ${OBJTOP:U${_objroot}${MACHINE}}
# Take care of ${MACHINE}
.if ${MACHINE} == "host" || ${OBJTOP} == ${HOST_OBJTOP:Uno}
@@ -113,7 +114,17 @@ MAKEOBJDIR = $${.CURDIR:S,${_srctop},$${OBJTOP},}
.for v in ${_tricky_env_vars}
$v := ${$v}
.endfor
+.else
+# we cannot use the '$$' trick, anymore
+# but we can export a literal (unexpanded) value
+SRCTOP := ${_srctop}
+OBJROOT := ${_objroot}
+OBJTOP = ${OBJROOT}${MACHINE}
+MAKEOBJDIR = ${.CURDIR:S,${SRCTOP},${OBJTOP},}
+.export-literal SRCTOP OBJROOT ${_tricky_env_vars}
+.endif
#.info ${_tricky_env_vars:@v@${.newline}$v=${$v}@}
-
+#showenv:
+# @env | egrep 'OBJ|SRC'
.endif # MAKEOBJDIR
.endif # level 0
diff --git a/mk/sys.dependfile.mk b/mk/sys.dependfile.mk
index e915082e778c..b4d79f7e11e8 100644
--- a/mk/sys.dependfile.mk
+++ b/mk/sys.dependfile.mk
@@ -1,4 +1,4 @@
-# $Id: sys.dependfile.mk,v 1.6 2014/08/02 18:02:06 sjg Exp $
+# $Id: sys.dependfile.mk,v 1.7 2016/02/20 01:57:39 sjg Exp $
#
# @(#) Copyright (c) 2012, Simon J. Gerraty
#
@@ -49,7 +49,9 @@ _e := ${.MAKE.DEPENDFILE_PREFERENCE:@m@${exists($m):?$m:}@}
# If any already exist, we should follow suit.
_aml = ${ALL_MACHINE_LIST:Uarm amd64 i386 powerpc:N${MACHINE}} ${MACHINE}
# MACHINE must be the last entry in _aml ;-)
+_m := ${MACHINE}
_e := ${_aml:@MACHINE@${.MAKE.DEPENDFILE_PREFERENCE:@m@${exists($m):?$m:}@}@}
+MACHINE := ${_m}
.if !empty(_e)
.MAKE.DEPENDFILE ?= ${.MAKE.DEPENDFILE_PREFERENCE:M*${MACHINE}:[1]}
.endif
diff --git a/mk/warnings.mk b/mk/warnings.mk
index bacbefb2b837..dc230bc83280 100644
--- a/mk/warnings.mk
+++ b/mk/warnings.mk
@@ -1,5 +1,5 @@
# RCSid:
-# $Id: warnings.mk,v 1.8 2014/04/02 19:20:23 sjg Exp $
+# $Id: warnings.mk,v 1.9 2016/02/20 02:00:58 sjg Exp $
#
# @(#) Copyright (c) 2002, Simon J. Gerraty
#
@@ -15,6 +15,8 @@
#
.ifndef _w_cflags
+# make sure we get the behavior we expect
+.MAKE.SAVE_DOLLARS = no
# Any number of warnings sets can be added.
.-include "warnings-sets.mk"
diff --git a/nonints.h b/nonints.h
index 2332858c25cc..5a5c613566f7 100644
--- a/nonints.h
+++ b/nonints.h
@@ -1,4 +1,4 @@
-/* $NetBSD: nonints.h,v 1.69 2015/10/11 04:51:24 sjg Exp $ */
+/* $NetBSD: nonints.h,v 1.72 2016/02/18 20:25:08 sjg Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -120,6 +120,7 @@ void Finish(int) MAKE_ATTR_DEAD;
int eunlink(const char *);
void execError(const char *, const char *);
char *getTmpdir(void);
+Boolean s2Boolean(const char *, Boolean);
Boolean getBoolean(const char *, Boolean);
/* parse.c */
@@ -184,8 +185,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, Boolean, int *, void **);
-char *Var_Subst(const char *, const char *, GNode *, Boolean, Boolean);
+char *Var_Parse(const char *, GNode *, int, int *, void **);
+char *Var_Subst(const char *, const char *, GNode *, int);
char *Var_GetTail(const char *);
char *Var_GetHead(const char *);
void Var_Init(void);
diff --git a/parse.c b/parse.c
index 7f3afbde7bf0..2a22c0b60695 100644
--- a/parse.c
+++ b/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.206 2015/11/26 00:23:04 sjg Exp $ */
+/* $NetBSD: parse.c,v 1.212 2016/02/19 06:19:06 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: parse.c,v 1.206 2015/11/26 00:23:04 sjg Exp $";
+static char rcsid[] = "$NetBSD: parse.c,v 1.212 2016/02/19 06:19:06 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: parse.c,v 1.206 2015/11/26 00:23:04 sjg Exp $");
+__RCSID("$NetBSD: parse.c,v 1.212 2016/02/19 06:19:06 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -128,7 +128,6 @@ __RCSID("$NetBSD: parse.c,v 1.206 2015/11/26 00:23:04 sjg Exp $");
#include <assert.h>
#include <ctype.h>
#include <errno.h>
-#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
@@ -161,6 +160,7 @@ typedef struct IFile {
int lineno; /* current line number in file */
int first_lineno; /* line number of start of text */
int cond_depth; /* 'if' nesting when file opened */
+ Boolean depending; /* state of doing_depend on EOF */
char *P_str; /* point to base of string buffer */
char *P_ptr; /* point to next char of string buffer */
char *P_end; /* point to the end of string buffer */
@@ -816,7 +816,7 @@ ParseMessage(char *line)
while (isspace((u_char)*line))
line++;
- line = Var_Subst(NULL, line, VAR_CMD, FALSE, TRUE);
+ line = Var_Subst(NULL, line, VAR_CMD, VARF_WANTRES);
Parse_Error(mtype, "%s", line);
free(line);
@@ -1233,9 +1233,9 @@ ParseDoDependency(char *line)
int length;
void *freeIt;
- (void)Var_Parse(cp, VAR_CMD, TRUE, TRUE, &length, &freeIt);
- if (freeIt)
- free(freeIt);
+ (void)Var_Parse(cp, VAR_CMD, VARF_UNDEFERR|VARF_WANTRES,
+ &length, &freeIt);
+ free(freeIt);
cp += length-1;
}
}
@@ -1948,7 +1948,7 @@ Parse_DoVar(char *line, GNode *ctxt)
if (!Var_Exists(line, ctxt))
Var_Set(line, "", ctxt, 0);
- cp = Var_Subst(NULL, cp, ctxt, FALSE, TRUE);
+ cp = Var_Subst(NULL, cp, ctxt, VARF_WANTRES|VARF_ASSIGN);
oldVars = oldOldVars;
freeCp = TRUE;
@@ -1963,7 +1963,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, TRUE);
+ cp = Var_Subst(NULL, cp, VAR_CMD, VARF_UNDEFERR|VARF_WANTRES);
freeCp = TRUE;
}
@@ -2155,7 +2155,7 @@ Parse_AddIncludeDir(char *dir)
*/
static void
-Parse_include_file(char *file, Boolean isSystem, int silent)
+Parse_include_file(char *file, Boolean isSystem, Boolean depinc, int silent)
{
struct loadedfile *lf;
char *fullname; /* full pathname of file */
@@ -2255,6 +2255,8 @@ Parse_include_file(char *file, Boolean isSystem, int silent)
/* Start reading from this file next */
Parse_SetInput(fullname, 0, -1, loadedfile_nextbuf, lf);
curFile->lf = lf;
+ if (depinc)
+ doing_depend = depinc; /* only turn it on */
}
static void
@@ -2302,9 +2304,9 @@ 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, TRUE);
+ file = Var_Subst(NULL, file, VAR_CMD, VARF_WANTRES);
- Parse_include_file(file, endc == '>', silent);
+ Parse_include_file(file, endc == '>', (*line == 'd'), silent);
free(file);
}
@@ -2339,10 +2341,8 @@ ParseSetIncludedFile(void)
fprintf(debug_file, "%s: ${.INCLUDEDFROMDIR} = `%s' "
"${.INCLUDEDFROMFILE} = `%s'\n", __func__, pd, pf);
- if (fp)
- free(fp);
- if (dp)
- free(dp);
+ free(fp);
+ free(dp);
}
/*-
*---------------------------------------------------------------------
@@ -2472,6 +2472,7 @@ Parse_SetInput(const char *name, int line, int fd,
curFile->nextbuf = nextbuf;
curFile->nextbuf_arg = arg;
curFile->lf = NULL;
+ curFile->depending = doing_depend; /* restore this on EOF */
assert(nextbuf != NULL);
@@ -2532,7 +2533,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, TRUE);
+ all_files = Var_Subst(NULL, file, VAR_CMD, VARF_WANTRES);
if (*file == '\0') {
Parse_Error(PARSE_FATAL,
@@ -2550,7 +2551,7 @@ ParseTraditionalInclude(char *line)
else
done = 1;
- Parse_include_file(file, FALSE, silent);
+ Parse_include_file(file, FALSE, FALSE, silent);
}
free(all_files);
}
@@ -2600,7 +2601,7 @@ ParseGmakeExport(char *line)
/*
* Expand the value before putting it in the environment.
*/
- value = Var_Subst(NULL, value, VAR_CMD, FALSE, TRUE);
+ value = Var_Subst(NULL, value, VAR_CMD, VARF_WANTRES);
setenv(variable, value, 1);
}
#endif
@@ -2628,6 +2629,7 @@ ParseEOF(void)
assert(curFile->nextbuf != NULL);
+ doing_depend = curFile->depending; /* restore this */
/* get next input buffer, if any */
ptr = curFile->nextbuf(curFile->nextbuf_arg, &len);
curFile->P_ptr = ptr;
@@ -2990,7 +2992,7 @@ Parse_File(const char *name, int fd)
continue;
}
if (strncmp(cp, "include", 7) == 0 ||
- ((cp[0] == 's' || cp[0] == '-') &&
+ ((cp[0] == 'd' || cp[0] == 's' || cp[0] == '-') &&
strncmp(&cp[1], "include", 7) == 0)) {
ParseDoInclude(cp);
continue;
@@ -3149,7 +3151,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, TRUE);
+ line = Var_Subst(NULL, line, VAR_CMD, VARF_UNDEFERR|VARF_WANTRES);
/*
* Need a non-circular list for the target nodes
diff --git a/suff.c b/suff.c
index db69643f4ce4..98bd44734872 100644
--- a/suff.c
+++ b/suff.c
@@ -1,4 +1,4 @@
-/* $NetBSD: suff.c,v 1.75 2015/12/20 22:44:10 sjg Exp $ */
+/* $NetBSD: suff.c,v 1.78 2016/02/18 18:29:14 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: suff.c,v 1.75 2015/12/20 22:44:10 sjg Exp $";
+static char rcsid[] = "$NetBSD: suff.c,v 1.78 2016/02/18 18:29:14 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94";
#else
-__RCSID("$NetBSD: suff.c,v 1.75 2015/12/20 22:44:10 sjg Exp $");
+__RCSID("$NetBSD: suff.c,v 1.78 2016/02/18 18:29:14 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -1556,7 +1556,7 @@ SuffExpandChildren(LstNode cln, GNode *pgn)
if (DEBUG(SUFF)) {
fprintf(debug_file, "Expanding \"%s\"...", cgn->name);
}
- cp = Var_Subst(NULL, cgn->name, pgn, TRUE, TRUE);
+ cp = Var_Subst(NULL, cgn->name, pgn, VARF_UNDEFERR|VARF_WANTRES);
if (cp != NULL) {
Lst members = Lst_Init(FALSE);
@@ -1609,13 +1609,13 @@ SuffExpandChildren(LstNode cln, GNode *pgn)
int len;
void *freeIt;
- junk = Var_Parse(cp, pgn, TRUE, TRUE, &len, &freeIt);
+ junk = Var_Parse(cp, pgn, VARF_UNDEFERR|VARF_WANTRES,
+ &len, &freeIt);
if (junk != var_Error) {
cp += len - 1;
}
- if (freeIt)
- free(freeIt);
+ free(freeIt);
} else if (*cp == '\\' && *cp != '\0') {
/*
* Escaped something -- skip over it
@@ -1933,8 +1933,7 @@ SuffFindArchiveDeps(GNode *gn, Lst slst)
for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) {
char *p1;
Var_Set(copy[i], Var_Value(copy[i], mem, &p1), gn, 0);
- if (p1)
- free(p1);
+ free(p1);
}
diff --git a/targ.c b/targ.c
index 5db5477ca546..dd52b296ff3a 100644
--- a/targ.c
+++ b/targ.c
@@ -1,4 +1,4 @@
-/* $NetBSD: targ.c,v 1.60 2015/05/25 09:01:06 manu Exp $ */
+/* $NetBSD: targ.c,v 1.61 2016/01/17 17:45:21 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: targ.c,v 1.60 2015/05/25 09:01:06 manu Exp $";
+static char rcsid[] = "$NetBSD: targ.c,v 1.61 2016/01/17 17:45:21 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: targ.c,v 1.60 2015/05/25 09:01:06 manu Exp $");
+__RCSID("$NetBSD: targ.c,v 1.61 2016/01/17 17:45:21 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -292,10 +292,8 @@ TargFreeGN(void *gnp)
free(gn->name);
- if (gn->uname)
- free(gn->uname);
- if (gn->path)
- free(gn->path);
+ free(gn->uname);
+ free(gn->path);
/* gn->fname points to name allocated when file was opened, don't free */
Lst_Destroy(gn->iParents, NULL);
diff --git a/unit-tests/export-env.exp b/unit-tests/export-env.exp
index 6221232a2a1b..8a779e6aff0a 100644
--- a/unit-tests/export-env.exp
+++ b/unit-tests/export-env.exp
@@ -2,8 +2,10 @@ make:
UT_TEST=export-env.mk
UT_ENV=not-exported
UT_EXP=not-exported
+UT_LIT=literal export-env.mk
env:
UT_TEST=export-env.mk
UT_ENV=exported
UT_EXP=exported
+UT_LIT=literal ${UT_TEST}
exit status 0
diff --git a/unit-tests/export-env.mk b/unit-tests/export-env.mk
index 6b7cd4c3060c..93aa6721a23e 100644
--- a/unit-tests/export-env.mk
+++ b/unit-tests/export-env.mk
@@ -1,4 +1,4 @@
-# $Id: export-env.mk,v 1.1.1.1 2014/08/30 18:57:18 sjg Exp $
+# $Id: export-env.mk,v 1.1.1.2 2016/02/18 20:35:24 sjg Exp $
# our normal .export, subsequent changes affect the environment
UT_TEST=this
@@ -15,9 +15,12 @@ UT_EXP=before-export
export UT_EXP=exported
UT_EXP=not-exported
+UT_LIT= literal ${UT_TEST}
+.export-literal UT_LIT
+
all:
- @echo make:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=${$v};@}
- @echo env:; ${UT_TEST UT_ENV UT_EXP:L:@v@echo $v=$${$v};@}
+ @echo make:; ${UT_TEST UT_ENV UT_EXP UT_LIT:L:@v@echo $v=${$v};@}
+ @echo env:; ${UT_TEST UT_ENV UT_EXP UT_LIT:L:@v@echo $v=$${$v};@}
diff --git a/unit-tests/modts.exp b/unit-tests/modts.exp
index cf3c91d43c0c..338964963a86 100644
--- a/unit-tests/modts.exp
+++ b/unit-tests/modts.exp
@@ -23,10 +23,16 @@ THREE
FOUR
FIVE
SIX"
+LIST:ts/xa:tu="ONE
+TWO
+THREE
+FOUR
+FIVE
+SIX"
make: Bad modifier `:tx' for LIST
LIST:tx="}"
-make: Bad modifier `:ts\x' for LIST
-LIST:ts/x:tu="\x:tu}"
+make: Bad modifier `:ts\X' for LIST
+LIST:ts/x:tu="\X:tu}"
FU_mod-ts="a/b/cool"
FU_mod-ts:ts:T="cool" == cool?
B.${AAA:ts}="Baaa" == Baaa?
diff --git a/unit-tests/modts.mk b/unit-tests/modts.mk
index 54b3d3d2ffa1..e66dc25a2a02 100644
--- a/unit-tests/modts.mk
+++ b/unit-tests/modts.mk
@@ -36,8 +36,9 @@ mod-ts:
@${PRINT} 'LIST:ts/n="${LIST:ts\n}"'
@${PRINT} 'LIST:ts/t="${LIST:ts\t}"'
@${PRINT} 'LIST:ts/012:tu="${LIST:ts\012:tu}"'
+ @${PRINT} 'LIST:ts/xa:tu="${LIST:ts\xa:tu}"'
@${PRINT} 'LIST:tx="${LIST:tx}"'
- @${PRINT} 'LIST:ts/x:tu="${LIST:ts\x:tu}"'
+ @${PRINT} 'LIST:ts/x:tu="${LIST:ts\X:tu}"'
@${PRINT} 'FU_$@="${FU_${@:ts}:ts}"'
@${PRINT} 'FU_$@:ts:T="${FU_${@:ts}:ts:T}" == cool?'
@${PRINT} 'B.$${AAA:ts}="${B.${AAA:ts}}" == Baaa?'
diff --git a/var.c b/var.c
index 4e7a38d590a0..36ba6de678db 100644
--- a/var.c
+++ b/var.c
@@ -1,4 +1,4 @@
-/* $NetBSD: var.c,v 1.200 2015/12/01 07:26:08 sjg Exp $ */
+/* $NetBSD: var.c,v 1.206 2016/03/07 20:20:35 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
-static char rcsid[] = "$NetBSD: var.c,v 1.200 2015/12/01 07:26:08 sjg Exp $";
+static char rcsid[] = "$NetBSD: var.c,v 1.206 2016/03/07 20:20:35 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
#else
-__RCSID("$NetBSD: var.c,v 1.200 2015/12/01 07:26:08 sjg Exp $");
+__RCSID("$NetBSD: var.c,v 1.206 2016/03/07 20:20:35 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -154,13 +154,23 @@ char **savedEnv = NULL;
char var_Error[] = "";
/*
- * Similar to var_Error, but returned when the 'errnum' flag for Var_Parse is
- * set false. Why not just use a constant? Well, gcc likes to condense
- * identical string instances...
+ * Similar to var_Error, but returned when the 'VARF_UNDEFERR' flag for
+ * Var_Parse is not set. Why not just use a constant? Well, gcc likes
+ * to condense identical string instances...
*/
static char varNoError[] = "";
/*
+ * Traditionally we consume $$ during := like any other expansion.
+ * Other make's do not.
+ * This knob allows controlling the behavior.
+ * FALSE for old behavior.
+ * TRUE for new compatible.
+ */
+#define SAVE_DOLLARS ".MAKE.SAVE_DOLLARS"
+static Boolean save_dollars = FALSE;
+
+/*
* Internally, variables are contained in four different contexts.
* 1) the environment. They may not be changed. If an environment
* variable is appended-to, the result is placed in the global
@@ -216,7 +226,11 @@ static int var_exportedVars = VAR_EXPORTED_NONE;
* We pass this to Var_Export when doing the initial export
* or after updating an exported var.
*/
-#define VAR_EXPORT_PARENT 1
+#define VAR_EXPORT_PARENT 1
+/*
+ * We pass this to Var_Export1 to tell it to leave the value alone.
+ */
+#define VAR_EXPORT_LITERAL 2
/* Var*Pattern flags */
#define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */
@@ -541,7 +555,7 @@ Var_Delete(const char *name, GNode *ctxt)
char *cp;
if (strchr(name, '$')) {
- cp = Var_Subst(NULL, name, VAR_GLOBAL, FALSE, TRUE);
+ cp = Var_Subst(NULL, name, VAR_GLOBAL, VARF_WANTRES);
} else {
cp = (char *)name;
}
@@ -580,12 +594,13 @@ Var_Delete(const char *name, GNode *ctxt)
* We only manipulate flags of vars if 'parent' is set.
*/
static int
-Var_Export1(const char *name, int parent)
+Var_Export1(const char *name, int flags)
{
char tmp[BUFSIZ];
Var *v;
char *val = NULL;
int n;
+ int parent = (flags & VAR_EXPORT_PARENT);
if (*name == '.')
return 0; /* skip internals */
@@ -613,7 +628,7 @@ Var_Export1(const char *name, int parent)
return 0; /* nothing to do */
}
val = Buf_GetAll(&v->val, NULL);
- if (strchr(val, '$')) {
+ if ((flags & VAR_EXPORT_LITERAL) == 0 && strchr(val, '$')) {
if (parent) {
/*
* Flag this as something we need to re-export.
@@ -632,7 +647,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, FALSE, TRUE);
+ val = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
setenv(name, val, 1);
free(val);
}
@@ -700,7 +715,7 @@ Var_ExportVars(void)
int ac;
int i;
- val = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE);
+ val = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
if (*val) {
av = brk_string(val, &ac, FALSE, &as);
for (i = 0; i < ac; i++) {
@@ -725,7 +740,7 @@ Var_Export(char *str, int isExport)
char *val;
char **av;
char *as;
- int track;
+ int flags;
int ac;
int i;
@@ -734,13 +749,16 @@ Var_Export(char *str, int isExport)
return;
}
+ flags = 0;
if (strncmp(str, "-env", 4) == 0) {
- track = 0;
str += 4;
+ } else if (strncmp(str, "-literal", 8) == 0) {
+ str += 8;
+ flags |= VAR_EXPORT_LITERAL;
} else {
- track = VAR_EXPORT_PARENT;
+ flags |= VAR_EXPORT_PARENT;
}
- val = Var_Subst(NULL, str, VAR_GLOBAL, FALSE, TRUE);
+ val = Var_Subst(NULL, str, VAR_GLOBAL, VARF_WANTRES);
if (*val) {
av = brk_string(val, &ac, FALSE, &as);
for (i = 0; i < ac; i++) {
@@ -760,10 +778,10 @@ Var_Export(char *str, int isExport)
continue;
}
}
- if (Var_Export1(name, track)) {
+ if (Var_Export1(name, flags)) {
if (VAR_EXPORTED_ALL != var_exportedVars)
var_exportedVars = VAR_EXPORTED_YES;
- if (isExport && track) {
+ if (isExport && (flags & VAR_EXPORT_PARENT)) {
Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
}
}
@@ -830,7 +848,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, FALSE, TRUE);
+ vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
}
}
if (vlist) {
@@ -860,7 +878,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, FALSE, TRUE);
+ cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0);
free(cp);
}
@@ -915,7 +933,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, FALSE, TRUE);
+ expanded_name = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
if (expanded_name[0] == 0) {
if (DEBUG(VAR)) {
fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) "
@@ -983,7 +1001,11 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
}
-
+ if (*name == '.') {
+ if (strcmp(name, SAVE_DOLLARS) == 0)
+ save_dollars = s2Boolean(val, save_dollars);
+ }
+
out:
free(expanded_name);
if (v != NULL)
@@ -1025,7 +1047,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, FALSE, TRUE);
+ expanded_name = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
if (expanded_name[0] == 0) {
if (DEBUG(VAR)) {
fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) "
@@ -1090,7 +1112,7 @@ Var_Exists(const char *name, GNode *ctxt)
char *cp;
if ((cp = strchr(name, '$')) != NULL) {
- cp = Var_Subst(NULL, name, ctxt, FALSE, TRUE);
+ cp = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
}
v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
free(cp);
@@ -1388,7 +1410,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, FALSE, TRUE);
+ varexp = Var_Subst(NULL, pat->rhs, ctx, VARF_WANTRES);
Str_SYSVSubst(buf, varexp, ptr, len);
free(varexp);
} else {
@@ -1628,14 +1650,14 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
*-----------------------------------------------------------------------
*/
static void
-VarREError(int errnum, regex_t *pat, const char *str)
+VarREError(int reerr, regex_t *pat, const char *str)
{
char *errbuf;
int errlen;
- errlen = regerror(errnum, pat, 0, 0);
+ errlen = regerror(reerr, pat, 0, 0);
errbuf = bmake_malloc(errlen);
- regerror(errnum, pat, errbuf, errlen);
+ regerror(reerr, pat, errbuf, errlen);
Error("%s: %s", str, errbuf);
free(errbuf);
}
@@ -1808,7 +1830,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, TRUE);
+ s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum | VARF_WANTRES);
if (s != NULL && *s != '\0') {
if (addSpace && *s != '\n')
Buf_AddByte(buf, ' ');
@@ -2142,13 +2164,14 @@ VarUniq(const char *str)
*/
static char *
VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
- int errnum, const char **tstr, int delim, int *flags,
+ int flags, const char **tstr, int delim, int *vflags,
int *length, VarPattern *pattern)
{
const char *cp;
char *rstr;
Buffer buf;
int junk;
+ int errnum = flags & VARF_UNDEFERR;
Buf_Init(&buf, 0);
if (length == NULL)
@@ -2170,16 +2193,16 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
cp++;
} else if (*cp == '$') {
if (cp[1] == delim) {
- if (flags == NULL)
+ if (vflags == NULL)
Buf_AddByte(&buf, *cp);
else
/*
* Unescaped $ at end of pattern => anchor
* pattern at end.
*/
- *flags |= VAR_MATCH_END;
+ *vflags |= VAR_MATCH_END;
} else {
- if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
+ if (vflags == NULL || (*vflags & VAR_NOSUBST) == 0) {
char *cp2;
int len;
void *freeIt;
@@ -2189,7 +2212,8 @@ 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, TRUE, &len, &freeIt);
+ cp2 = Var_Parse(cp, ctxt, errnum | VARF_WANTRES, &len,
+ &freeIt);
Buf_AddBytes(&buf, strlen(cp2), cp2);
free(freeIt);
cp += len - 1;
@@ -2462,7 +2486,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, Boolean wantit,
+ Var *v, GNode *ctxt, int flags,
int *lengthPtr, void **freePtr)
{
const char *start;
@@ -2493,7 +2517,7 @@ ApplyModifiers(char *nstr, const char *tstr,
int rlen;
int c;
- rval = Var_Parse(tstr, ctxt, errnum, wantit, &rlen, &freeIt);
+ rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt);
/*
* If we have not parsed up to endc or ':',
@@ -2518,10 +2542,9 @@ ApplyModifiers(char *nstr, const char *tstr,
int used;
nstr = ApplyModifiers(nstr, rval,
- 0, 0,
- v, ctxt, errnum, wantit, &used, freePtr);
+ 0, 0, v, ctxt, flags, &used, freePtr);
if (nstr == var_Error
- || (nstr == varNoError && errnum == 0)
+ || (nstr == varNoError && (flags & VARF_UNDEFERR) == 0)
|| strlen(rval) != (size_t) used) {
free(freeIt);
goto out; /* error already reported */
@@ -2556,7 +2579,7 @@ ApplyModifiers(char *nstr, const char *tstr,
char *sv_name;
VarPattern pattern;
int how;
- int flags;
+ int vflags;
if (v->name[0] == 0)
goto bad_modifier;
@@ -2592,9 +2615,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, &flags,
+ vflags = (flags & VARF_WANTRES) ? 0 : VAR_NOSUBST;
+ pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
+ &cp, delim, &vflags,
&pattern.rightLen,
NULL);
if (v->flags & VAR_JUNK) {
@@ -2608,7 +2631,7 @@ ApplyModifiers(char *nstr, const char *tstr,
termc = *--cp;
delim = '\0';
- if (wantit) {
+ if (flags & VARF_WANTRES) {
switch (how) {
case '+':
Var_Append(v->name, pattern.rhs, v_ctxt);
@@ -2639,29 +2662,30 @@ ApplyModifiers(char *nstr, const char *tstr,
case '@':
{
VarLoop_t loop;
- int flags = VAR_NOSUBST;
+ int vflags = VAR_NOSUBST;
cp = ++tstr;
delim = '@';
- if ((loop.tvar = VarGetPattern(ctxt, &parsestate, errnum,
+ if ((loop.tvar = VarGetPattern(ctxt, &parsestate, flags,
&cp, delim,
- &flags, &loop.tvarLen,
+ &vflags, &loop.tvarLen,
NULL)) == NULL)
goto cleanup;
- if ((loop.str = VarGetPattern(ctxt, &parsestate, errnum,
+ if ((loop.str = VarGetPattern(ctxt, &parsestate, flags,
&cp, delim,
- &flags, &loop.strLen,
+ &vflags, &loop.strLen,
NULL)) == NULL)
goto cleanup;
termc = *cp;
delim = '\0';
- loop.errnum = errnum;
+ loop.errnum = flags & VARF_UNDEFERR;
loop.ctxt = ctxt;
newStr = VarModify(ctxt, &parsestate, nstr, VarLoopExpand,
&loop);
+ Var_Delete(loop.tvar, ctxt);
free(loop.tvar);
free(loop.str);
break;
@@ -2670,15 +2694,19 @@ ApplyModifiers(char *nstr, const char *tstr,
case 'U':
{
Buffer buf; /* Buffer for patterns */
- int wantit_; /* want data in buffer */
+ int nflags;
- if (wantit) {
+ if (flags & VARF_WANTRES) {
+ int wantres;
if (*tstr == 'U')
- wantit_ = ((v->flags & VAR_JUNK) != 0);
+ wantres = ((v->flags & VAR_JUNK) != 0);
else
- wantit_ = ((v->flags & VAR_JUNK) == 0);
+ wantres = ((v->flags & VAR_JUNK) == 0);
+ nflags = flags & ~VARF_WANTRES;
+ if (wantres)
+ nflags |= VARF_WANTRES;
} else
- wantit_ = wantit;
+ nflags = flags;
/*
* Pass through tstr looking for 1) escaped delimiters,
* '$'s and backslashes (place the escaped character in
@@ -2707,7 +2735,7 @@ ApplyModifiers(char *nstr, const char *tstr,
int len;
void *freeIt;
- cp2 = Var_Parse(cp, ctxt, errnum, wantit_, &len, &freeIt);
+ cp2 = Var_Parse(cp, ctxt, nflags, &len, &freeIt);
Buf_AddBytes(&buf, strlen(cp2), cp2);
free(freeIt);
cp += len - 1;
@@ -2720,7 +2748,7 @@ ApplyModifiers(char *nstr, const char *tstr,
if ((v->flags & VAR_JUNK) != 0)
v->flags |= VAR_KEEP;
- if (wantit_) {
+ if (nflags & VARF_WANTRES) {
newStr = Buf_Destroy(&buf, FALSE);
} else {
newStr = nstr;
@@ -2767,12 +2795,12 @@ ApplyModifiers(char *nstr, const char *tstr,
delim = '!';
emsg = NULL;
cp = ++tstr;
- if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
+ if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
&cp, delim,
NULL, &pattern.rightLen,
NULL)) == NULL)
goto cleanup;
- if (wantit)
+ if (flags & VARF_WANTRES)
newStr = Cmd_Exec(pattern.rhs, &emsg);
else
newStr = varNoError;
@@ -2800,7 +2828,7 @@ ApplyModifiers(char *nstr, const char *tstr,
cp = tstr+1; /* point to char after '[' */
delim = ']'; /* look for closing ']' */
estr = VarGetPattern(ctxt, &parsestate,
- errnum, &cp, delim,
+ flags, &cp, delim,
NULL, NULL, NULL);
if (estr == NULL)
goto cleanup; /* report missing ']' */
@@ -2977,6 +3005,9 @@ ApplyModifiers(char *nstr, const char *tstr,
parsestate.varSpace = 0; /* no separator */
cp = tstr + 2;
} else if (tstr[2] == '\\') {
+ const char *xp = &tstr[3];
+ int base = 8; /* assume octal */
+
switch (tstr[3]) {
case 'n':
parsestate.varSpace = '\n';
@@ -2986,12 +3017,20 @@ ApplyModifiers(char *nstr, const char *tstr,
parsestate.varSpace = '\t';
cp = tstr + 4;
break;
+ case 'x':
+ base = 16;
+ xp++;
+ goto get_numeric;
+ case '0':
+ base = 0;
+ goto get_numeric;
default:
if (isdigit((unsigned char)tstr[3])) {
char *ep;
+ get_numeric:
parsestate.varSpace =
- strtoul(&tstr[3], &ep, 0);
+ strtoul(xp, &ep, base);
if (*ep != ':' && *ep != endc)
goto bad_modifier;
cp = ep;
@@ -3151,7 +3190,7 @@ ApplyModifiers(char *nstr, const char *tstr,
* expand it.
*/
cp2 = pattern;
- pattern = Var_Subst(NULL, cp2, ctxt, errnum, TRUE);
+ pattern = Var_Subst(NULL, cp2, ctxt, flags | VARF_WANTRES);
free(cp2);
}
if (DEBUG(VAR))
@@ -3187,14 +3226,14 @@ ApplyModifiers(char *nstr, const char *tstr,
}
cp = tstr;
- if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum,
+ if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, flags,
&cp, delim,
&pattern.flags,
&pattern.leftLen,
NULL)) == NULL)
goto cleanup;
- if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
+ if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
&cp, delim, NULL,
&pattern.rightLen,
&pattern)) == NULL)
@@ -3241,7 +3280,7 @@ ApplyModifiers(char *nstr, const char *tstr,
int lhs_flags, rhs_flags;
/* find ':', and then substitute accordingly */
- if (wantit) {
+ if (flags & VARF_WANTRES) {
cond_rc = Cond_EvalExpression(NULL, v->name, &value, 0, FALSE);
if (cond_rc == COND_INVALID) {
lhs_flags = rhs_flags = VAR_NOSUBST;
@@ -3261,7 +3300,7 @@ ApplyModifiers(char *nstr, const char *tstr,
cp = ++tstr;
delim = ':';
- if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum,
+ if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, flags,
&cp, delim, &lhs_flags,
&pattern.leftLen,
NULL)) == NULL)
@@ -3269,7 +3308,7 @@ ApplyModifiers(char *nstr, const char *tstr,
/* BROPEN or PROPEN */
delim = endc;
- if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum,
+ if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
&cp, delim, &rhs_flags,
&pattern.rightLen,
NULL)) == NULL)
@@ -3310,12 +3349,12 @@ ApplyModifiers(char *nstr, const char *tstr,
cp = tstr;
- if ((re = VarGetPattern(ctxt, &parsestate, errnum, &cp, delim,
+ if ((re = VarGetPattern(ctxt, &parsestate, flags, &cp, delim,
NULL, NULL, NULL)) == NULL)
goto cleanup;
if ((pattern.replace = VarGetPattern(ctxt, &parsestate,
- errnum, &cp, delim, NULL,
+ flags, &cp, delim, NULL,
NULL, NULL)) == NULL){
free(re);
goto cleanup;
@@ -3439,7 +3478,7 @@ ApplyModifiers(char *nstr, const char *tstr,
case 's':
if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
const char *emsg;
- if (wantit) {
+ if (flags & VARF_WANTRES) {
newStr = Cmd_Exec(nstr, &emsg);
if (emsg)
Error(emsg, nstr);
@@ -3492,12 +3531,12 @@ ApplyModifiers(char *nstr, const char *tstr,
delim='=';
cp = tstr;
if ((pattern.lhs = VarGetPattern(ctxt, &parsestate,
- errnum, &cp, delim, &pattern.flags,
+ flags, &cp, delim, &pattern.flags,
&pattern.leftLen, NULL)) == NULL)
goto cleanup;
delim = endc;
if ((pattern.rhs = VarGetPattern(ctxt, &parsestate,
- errnum, &cp, delim, NULL, &pattern.rightLen,
+ flags, &cp, delim, NULL, &pattern.rightLen,
&pattern)) == NULL)
goto cleanup;
@@ -3580,8 +3619,9 @@ ApplyModifiers(char *nstr, const char *tstr,
* Input:
* 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
+ * flags VARF_UNDEFERR if undefineds are an error
+ * VARF_WANTRES if we actually want the result
+ * VARF_ASSIGN if we are in a := assignment
* lengthPtr OUT: The length of the specification
* freePtr OUT: Non-NULL if caller should free *freePtr
*
@@ -3600,9 +3640,8 @@ ApplyModifiers(char *nstr, const char *tstr,
*/
/* coverity[+alloc : arg-*4] */
char *
-Var_Parse(const char *str, GNode *ctxt,
- Boolean errnum, Boolean wantit,
- int *lengthPtr, void **freePtr)
+Var_Parse(const char *str, GNode *ctxt, int flags,
+ int *lengthPtr, void **freePtr)
{
const char *tstr; /* Pointer into str */
Var *v; /* Variable in invocation */
@@ -3670,7 +3709,7 @@ Var_Parse(const char *str, GNode *ctxt,
/*
* Error
*/
- return (errnum ? var_Error : varNoError);
+ return (flags & VARF_UNDEFERR) ? var_Error : varNoError;
} else {
haveModifier = FALSE;
tstr = &str[1];
@@ -3707,7 +3746,7 @@ Var_Parse(const char *str, GNode *ctxt,
if (*tstr == '$') {
int rlen;
void *freeIt;
- char *rval = Var_Parse(tstr, ctxt, errnum, wantit, &rlen, &freeIt);
+ char *rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt);
if (rval != NULL) {
Buf_AddBytes(&buf, strlen(rval), rval);
}
@@ -3820,7 +3859,7 @@ Var_Parse(const char *str, GNode *ctxt,
return(pstr);
} else {
Buf_Destroy(&buf, TRUE);
- return (errnum ? var_Error : varNoError);
+ return (flags & VARF_UNDEFERR) ? var_Error : varNoError;
}
} else {
/*
@@ -3854,7 +3893,7 @@ Var_Parse(const char *str, GNode *ctxt,
*/
nstr = Buf_GetAll(&v->val, NULL);
if (strchr(nstr, '$') != NULL) {
- nstr = Var_Subst(NULL, nstr, ctxt, errnum, wantit);
+ nstr = Var_Subst(NULL, nstr, ctxt, flags);
*freePtr = nstr;
}
@@ -3867,7 +3906,7 @@ Var_Parse(const char *str, GNode *ctxt,
extraFree = NULL;
if (extramodifiers != NULL) {
nstr = ApplyModifiers(nstr, extramodifiers, '(', ')',
- v, ctxt, errnum, wantit, &used, &extraFree);
+ v, ctxt, flags, &used, &extraFree);
}
if (haveModifier) {
@@ -3875,7 +3914,7 @@ Var_Parse(const char *str, GNode *ctxt,
tstr++;
nstr = ApplyModifiers(nstr, tstr, startc, endc,
- v, ctxt, errnum, wantit, &used, freePtr);
+ v, ctxt, flags, &used, freePtr);
tstr += used;
free(extraFree);
} else {
@@ -3916,7 +3955,7 @@ Var_Parse(const char *str, GNode *ctxt,
nstr = bmake_strndup(start, *lengthPtr);
*freePtr = nstr;
} else {
- nstr = errnum ? var_Error : varNoError;
+ nstr = (flags & VARF_UNDEFERR) ? var_Error : varNoError;
}
}
if (nstr != Buf_GetAll(&v->val, NULL))
@@ -3931,15 +3970,16 @@ Var_Parse(const char *str, GNode *ctxt,
*-----------------------------------------------------------------------
* Var_Subst --
* Substitute for all variables in the given string in the given context
- * If undefErr is TRUE, Parse_Error will be called when an undefined
+ * If flags & VARF_UNDEFERR, Parse_Error will be called when an undefined
* variable is encountered.
*
* Input:
* var Named variable || NULL for all
* 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
+ * flags VARF_UNDEFERR if undefineds are an error
+ * VARF_WANTRES if we actually want the result
+ * VARF_ASSIGN if we are in a := assignment
*
* Results:
* The resulting string.
@@ -3949,8 +3989,7 @@ Var_Parse(const char *str, GNode *ctxt,
*-----------------------------------------------------------------------
*/
char *
-Var_Subst(const char *var, const char *str, GNode *ctxt,
- Boolean undefErr, Boolean wantit)
+Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
{
Buffer buf; /* Buffer for forming things */
char *val; /* Value to substitute for a variable */
@@ -3974,6 +4013,8 @@ Var_Subst(const char *var, const char *str, GNode *ctxt,
* In such a case, we skip over the escape character and store the
* dollar sign into the buffer directly.
*/
+ if (save_dollars && (flags & VARF_ASSIGN))
+ Buf_AddByte(&buf, *str);
str++;
Buf_AddByte(&buf, *str);
str++;
@@ -4048,7 +4089,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt,
continue;
}
- val = Var_Parse(str, ctxt, undefErr, wantit, &length, &freeIt);
+ val = Var_Parse(str, ctxt, flags, &length, &freeIt);
/*
* When we come down here, val should either point to the
@@ -4065,7 +4106,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt,
*/
if (oldVars) {
str += length;
- } else if (undefErr || val == var_Error) {
+ } else if ((flags & VARF_UNDEFERR) || val == var_Error) {
/*
* If variable is undefined, complain and skip the
* variable. The complaint will stop us from doing anything