Synchronize on NetBSD-CVS (2013/12/1 12:00:00 UTC)

- Fix for possible unset uid/gid in toproto
 - Fix for default mtree style
 - Update libelf
 - Importing libexecinfo
 - Resynchronize GCC, mpc, gmp, mpfr
 - build.sh: Replace params with show-params.
     This has been done as the make target has been renamed in the same
     way, while a new target named params has been added. This new
     target generates a file containing all the parameters, instead of
     printing it on the console.
 - Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org)
     get getservbyport() out of the inner loop

Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
This commit is contained in:
2013-12-06 12:04:52 +01:00
parent ff10274392
commit 84d9c625bf
4655 changed files with 379317 additions and 151059 deletions

View File

@@ -1,71 +0,0 @@
# $NetBSD: Makefile,v 1.55 2011/08/14 13:06:09 christos Exp $
# @(#)Makefile 5.2 (Berkeley) 12/28/90
PROG= make
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
make.c parse.c str.c suff.c targ.c trace.c var.c util.c
SRCS+= strlist.c
SRCS+= make_malloc.c
SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \
lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \
lstInit.c lstInsert.c lstIsAtEnd.c lstIsEmpty.c lstLast.c \
lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c
SRCS += lstPrev.c
# let people experiment for a bit
USE_META ?= no
.if ${USE_META:tl} != "no"
SRCS+= meta.c
CPPFLAGS+= -DUSE_META
FILEMON_H ?= ${.CURDIR:H:H}/sys/dev/filemon/filemon.h
.if exists(${FILEMON_H}) && ${FILEMON_H:T} == "filemon.h"
COPTS.meta.c += -DHAVE_FILEMON_H -I${FILEMON_H:H}
.endif
.endif
# For MINIX
CPPFLAGS+= -DHAVE_SETENV -DHAVE_STRERROR -DHAVE_STRDUP \
-DHAVE_STRFTIME -DHAVE_VSNPRINTF -DUSE_SELECT
# Gross hack, but we assume i386 everywhere
.if ${MACHINE_ARCH} == "i686"
MACHINE_ARCH=i386
.endif
.if $(MACHINE) == "i686"
MACHINE=i386
.endif
CPPFLAGS+= -DTARGET_MACHINE=\"${MACHINE}\" \
-DTARGET_MACHINE_ARCH=\"${MACHINE_ARCH}\" \
-DMAKE_MACHINE=\"${MACHINE}\" \
-DMAKE_MACHINE_ARCH=\"${MACHINE_ARCH}\"
.PATH: ${.CURDIR}/lst.lib
.if make(install)
SUBDIR= PSD.doc
.endif
.if make(obj) || make(clean)
SUBDIR+= unit-tests
.endif
.include <bsd.prog.mk>
.include <bsd.subdir.mk>
.ifdef TOOLDIR
CPPFLAGS+= -DMAKE_NATIVE
COPTS.var.c += -Wno-cast-qual
COPTS.job.c += -Wno-format-nonliteral
COPTS.parse.c += -Wno-format-nonliteral
COPTS.var.c += -Wno-format-nonliteral
# this is a native netbsd build,
# use libutil rather than the local emalloc etc.
CPPFLAGS+= -DUSE_EMALLOC
LDADD+=-lutil
DPADD+=${LIBUTIL}
.endif
# A simple unit-test driver to help catch regressions
accept test:
cd ${.CURDIR}/unit-tests && ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: compat.c,v 1.90 2012/10/07 19:17:31 sjg Exp $ */
/* $NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: compat.c,v 1.90 2012/10/07 19:17:31 sjg Exp $";
static char rcsid[] = "$NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg 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.90 2012/10/07 19:17:31 sjg Exp $");
__RCSID("$NetBSD: compat.c,v 1.93 2013/09/02 19:26:42 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -329,18 +329,23 @@ again:
* We need to pass the command off to the shell, typically
* because the command contains a "meta" character.
*/
static const char *shargv[4];
static const char *shargv[5];
int shargc;
shargv[0] = shellPath;
shargc = 0;
shargv[shargc++] = shellPath;
/*
* The following work for any of the builtin shell specs.
*/
if (errCheck && shellErrFlag) {
shargv[shargc++] = shellErrFlag;
}
if (DEBUG(SHELL))
shargv[1] = "-xc";
shargv[shargc++] = "-xc";
else
shargv[1] = "-c";
shargv[2] = cmd;
shargv[3] = NULL;
shargv[shargc++] = "-c";
shargv[shargc++] = cmd;
shargv[shargc++] = NULL;
av = shargv;
argc = 0;
bp = NULL;
@@ -374,7 +379,6 @@ again:
Fatal("Could not fork");
}
if (cpid == 0) {
Check_Cwd(av);
Var_ExportVars();
#ifdef USE_META
if (useMeta) {

View File

@@ -1,4 +1,4 @@
/* $NetBSD: cond.c,v 1.64 2012/06/12 19:21:50 joerg Exp $ */
/* $NetBSD: cond.c,v 1.67 2012/11/03 13:59:27 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.64 2012/06/12 19:21:50 joerg Exp $";
static char rcsid[] = "$NetBSD: cond.c,v 1.67 2012/11/03 13:59:27 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.64 2012/06/12 19:21:50 joerg Exp $");
__RCSID("$NetBSD: cond.c,v 1.67 2012/11/03 13:59:27 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -1227,7 +1227,8 @@ do_Cond_EvalExpression(Boolean *value)
int
Cond_Eval(char *line)
{
#define MAXIF 128 /* maximum depth of .if'ing */
#define MAXIF 128 /* maximum depth of .if'ing */
#define MAXIF_BUMP 32 /* how much to grow by */
enum if_states {
IF_ACTIVE, /* .if or .elif part active */
ELSE_ACTIVE, /* .else part active */
@@ -1235,7 +1236,8 @@ Cond_Eval(char *line)
SKIP_TO_ELSE, /* has been true, but not seen '.else' */
SKIP_TO_ENDIF /* nothing else to execute */
};
static enum if_states cond_state[MAXIF + 1] = { IF_ACTIVE };
static enum if_states *cond_state = NULL;
static unsigned int max_if_depth = MAXIF;
const struct If *ifp;
Boolean isElif;
@@ -1244,7 +1246,10 @@ Cond_Eval(char *line)
enum if_states state;
level = PARSE_FATAL;
if (!cond_state) {
cond_state = bmake_malloc(max_if_depth * sizeof(*cond_state));
cond_state[0] = IF_ACTIVE;
}
/* skip leading character (the '.') and any whitespace */
for (line++; *line == ' ' || *line == '\t'; line++)
continue;
@@ -1261,8 +1266,6 @@ Cond_Eval(char *line)
}
/* Return state for previous conditional */
cond_depth--;
if (cond_depth > MAXIF)
return COND_SKIP;
return cond_state[cond_depth] <= ELSE_ACTIVE ? COND_PARSE : COND_SKIP;
}
@@ -1275,8 +1278,6 @@ Cond_Eval(char *line)
return COND_PARSE;
}
if (cond_depth > MAXIF)
return COND_SKIP;
state = cond_state[cond_depth];
switch (state) {
case SEARCH_FOR_ELIF:
@@ -1325,9 +1326,6 @@ Cond_Eval(char *line)
Parse_Error(level, "if-less elif");
return COND_PARSE;
}
if (cond_depth > MAXIF)
/* Error reported when we saw the .if ... */
return COND_SKIP;
state = cond_state[cond_depth];
if (state == SKIP_TO_ENDIF || state == ELSE_ACTIVE) {
Parse_Error(PARSE_WARNING, "extra elif");
@@ -1341,10 +1339,15 @@ Cond_Eval(char *line)
}
} else {
/* Normal .if */
if (cond_depth >= MAXIF) {
cond_depth++;
Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", MAXIF);
return COND_SKIP;
if (cond_depth + 1 >= max_if_depth) {
/*
* This is rare, but not impossible.
* In meta mode, dirdeps.mk (only runs at level 0)
* can need more than the default.
*/
max_if_depth += MAXIF_BUMP;
cond_state = bmake_realloc(cond_state, max_if_depth *
sizeof(*cond_state));
}
state = cond_state[cond_depth];
cond_depth++;

View File

@@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $ */
/* $NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 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: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $";
static char rcsid[] = "$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
#else
__RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $");
__RCSID("$NetBSD: dir.c,v 1.67 2013/03/05 22:01:43 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -145,6 +145,7 @@ __RCSID("$NetBSD: dir.c,v 1.65 2012/06/12 19:21:50 joerg Exp $");
#include "make.h"
#include "hash.h"
#include "dir.h"
#include "job.h"
/*
* A search path consists of a Lst of Path structures. A Path structure
@@ -1463,9 +1464,11 @@ Dir_MTime(GNode *gn, Boolean recheck)
* so that we give that to the compiler.
*/
gn->path = bmake_strdup(fullName);
fprintf(stdout,
"%s: ignoring stale %s for %s, found %s\n",
progname, makeDependfile, gn->name, fullName);
if (!Job_RunTarget(".STALE", gn->fname))
fprintf(stdout,
"%s: %s, %d: ignoring stale %s for %s, "
"found %s\n", progname, gn->fname, gn->lineno,
makeDependfile, gn->name, fullName);
}
}
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $ */
/* $NetBSD: hash.c,v 1.20 2013/11/14 00:27:05 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $";
static char rcsid[] = "$NetBSD: hash.c,v 1.20 2013/11/14 00:27:05 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $");
__RCSID("$NetBSD: hash.c,v 1.20 2013/11/14 00:27:05 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -221,6 +221,9 @@ Hash_FindEntry(Hash_Table *t, const char *key)
unsigned h;
const char *p;
if (t == NULL || t->bucketPtr == NULL) {
return NULL;
}
for (h = 0, p = key; *p;)
h = (h << 5) - h + *p++;
p = key;

View File

@@ -1,4 +1,4 @@
/* $NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $ */
/* $NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -70,14 +70,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $";
static char rcsid[] = "$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg 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.163 2012/07/03 21:03:40 sjg Exp $");
__RCSID("$NetBSD: job.c,v 1.176 2013/08/04 16:48:15 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -139,6 +139,7 @@ __RCSID("$NetBSD: job.c,v 1.163 2012/07/03 21:03:40 sjg Exp $");
#include <sys/time.h>
#include <sys/wait.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#ifndef USE_SELECT
@@ -299,6 +300,7 @@ static Shell *commandShell = &shells[DEFSHELL_INDEX]; /* this is the shell to
const char *shellPath = NULL, /* full pathname of
* executable image */
*shellName = NULL; /* last component of shell */
char *shellErrFlag = NULL;
static const char *shellArgv = NULL; /* Custom shell args */
@@ -330,7 +332,7 @@ static Job childExitJob; /* child exit pseudo-job */
#define TARG_FMT "%s %s ---\n" /* Default format */
#define MESSAGE(fp, gn) \
if (maxJobs != 1) \
if (maxJobs != 1 && targPrefix && *targPrefix) \
(void)fprintf(fp, TARG_FMT, targPrefix, gn->name)
static sigset_t caught_signals; /* Set of signals we handle */
@@ -400,6 +402,15 @@ JobCreatePipe(Job *job, int minfd)
if (pipe(job->jobPipe) == -1)
Punt("Cannot create pipe: %s", strerror(errno));
for (i = 0; i < 2; i++) {
/* Avoid using low numbered fds */
fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
if (fd != -1) {
close(job->jobPipe[i]);
job->jobPipe[i] = fd;
}
}
/* Set close-on-exec flag for both */
(void)fcntl(job->jobPipe[0], F_SETFD, 1);
(void)fcntl(job->jobPipe[1], F_SETFD, 1);
@@ -412,15 +423,6 @@ JobCreatePipe(Job *job, int minfd)
*/
fcntl(job->jobPipe[0], F_SETFL,
fcntl(job->jobPipe[0], F_GETFL, 0) | O_NONBLOCK);
for (i = 0; i < 2; i++) {
/* Avoid using low numbered fds */
fd = fcntl(job->jobPipe[i], F_DUPFD, minfd);
if (fd != -1) {
close(job->jobPipe[i]);
job->jobPipe[i] = fd;
}
}
}
/*-
@@ -477,7 +479,8 @@ JobCondPassSig(int signo)
static void
JobChildSig(int signo MAKE_ATTR_UNUSED)
{
write(childExitJob.outPipe, CHILD_EXIT, 1);
while (write(childExitJob.outPipe, CHILD_EXIT, 1) == -1 && errno == EAGAIN)
continue;
}
@@ -504,7 +507,9 @@ JobContinueSig(int signo MAKE_ATTR_UNUSED)
* Defer sending to SIGCONT to our stopped children until we return
* from the signal handler.
*/
write(childExitJob.outPipe, DO_JOB_RESUME, 1);
while (write(childExitJob.outPipe, DO_JOB_RESUME, 1) == -1 &&
errno == EAGAIN)
continue;
}
/*-
@@ -675,7 +680,6 @@ JobPrintCommand(void *cmdp, void *jobp)
char *escCmd = NULL; /* Command with quotes/backticks escaped */
char *cmd = (char *)cmdp;
Job *job = (Job *)jobp;
char *cp, *tmp;
int i, j;
noSpecials = NoExecute(job->node);
@@ -847,11 +851,6 @@ JobPrintCommand(void *cmdp, void *jobp)
job->flags |= JOB_TRACED;
}
if ((cp = Check_Cwd_Cmd(cmd)) != NULL) {
DBPRINTF("test -d %s && ", cp);
DBPRINTF("cd %s\n", cp);
}
DBPRINTF(cmdTemplate, cmd);
free(cmdStart);
if (escCmd)
@@ -871,10 +870,6 @@ JobPrintCommand(void *cmdp, void *jobp)
if (shutUp && commandShell->hasEchoCtl) {
DBPRINTF("%s\n", commandShell->echoOn);
}
if (cp != NULL) {
DBPRINTF("test -d %s && ", cp);
DBPRINTF("cd %s\n", Var_Value(".OBJDIR", VAR_GLOBAL, &tmp));
}
return 0;
}
@@ -1171,7 +1166,8 @@ Job_Touch(GNode *gn, Boolean silent)
*/
if (read(streamID, &c, 1) == 1) {
(void)lseek(streamID, (off_t)0, SEEK_SET);
(void)write(streamID, &c, 1);
while (write(streamID, &c, 1) == -1 && errno == EAGAIN)
continue;
}
(void)close(streamID);
@@ -1237,8 +1233,10 @@ Job_CheckCommands(GNode *gn, void (*abortProc)(const char *, ...))
static const char msg[] = ": don't know how to make";
if (gn->flags & FROM_DEPEND) {
fprintf(stdout, "%s: ignoring stale %s for %s\n",
progname, makeDependfile, gn->name);
if (!Job_RunTarget(".STALE", gn->fname))
fprintf(stdout, "%s: %s, %d: ignoring stale %s for %s\n",
progname, gn->fname, gn->lineno, makeDependfile,
gn->name);
return TRUE;
}
@@ -1381,11 +1379,13 @@ JobExec(Job *job, char **argv)
* we can kill it and all its descendants in one fell swoop,
* by killing its process family, but not commit suicide.
*/
#if defined(MAKE_NATIVE) || defined(HAVE_SETPGID)
#if defined(SYSV) || defined(__minix)
/* XXX: dsl - I'm sure this should be setpgrp()... */
(void)setsid();
#else
(void)setpgid(0, getpid());
#endif
#endif
Var_ExportVars();
@@ -2051,31 +2051,45 @@ Job_CatchOutput(void)
(void)fflush(stdout);
/* The first fd in the list is the job token pipe */
nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
do {
nready = poll(fds + 1 - wantToken, nfds - 1 + wantToken, POLL_MSEC);
} while (nready < 0 && errno == EINTR);
if (nready < 0 || readyfd(&childExitJob)) {
if (nready < 0)
Punt("poll: %s", strerror(errno));
if (nready > 0 && readyfd(&childExitJob)) {
char token = 0;
nready -= 1;
(void)read(childExitJob.inPipe, &token, 1);
if (token == DO_JOB_RESUME[0])
/* Complete relay requested from our SIGCONT handler */
JobRestartJobs();
Job_CatchChildren();
ssize_t count;
count = read(childExitJob.inPipe, &token, 1);
switch (count) {
case 0:
Punt("unexpected eof on token pipe");
case -1:
Punt("token pipe read: %s", strerror(errno));
case 1:
if (token == DO_JOB_RESUME[0])
/* Complete relay requested from our SIGCONT handler */
JobRestartJobs();
break;
default:
abort();
}
--nready;
}
if (nready <= 0)
return;
if (wantToken && readyfd(&tokenWaitJob))
nready--;
Job_CatchChildren();
if (nready == 0)
return;
for (i = 2; i < nfds; i++) {
if (!fds[i].revents)
continue;
job = jobfds[i];
if (job->job_state != JOB_ST_RUNNING)
continue;
JobDoOutput(job, FALSE);
if (job->job_state == JOB_ST_RUNNING)
JobDoOutput(job, FALSE);
if (--nready == 0)
return;
}
}
@@ -2123,6 +2137,24 @@ Shell_Init(void)
if (commandShell->echo == NULL) {
commandShell->echo = "";
}
if (commandShell->hasErrCtl && *commandShell->exit) {
if (shellErrFlag &&
strcmp(commandShell->exit, &shellErrFlag[1]) != 0) {
free(shellErrFlag);
shellErrFlag = NULL;
}
if (!shellErrFlag) {
int n = strlen(commandShell->exit) + 2;
shellErrFlag = bmake_malloc(n);
if (shellErrFlag) {
snprintf(shellErrFlag, n, "-%s", commandShell->exit);
}
}
} else if (shellErrFlag) {
free(shellErrFlag);
shellErrFlag = NULL;
}
}
/*-
@@ -2166,8 +2198,7 @@ Job_SetPrefix(void)
void
Job_Init(void)
{
GNode *begin; /* node for commands to do at the very start */
Job_SetPrefix();
/* Allocate space for all the job info */
job_table = bmake_malloc(maxJobs * sizeof *job_table);
memset(job_table, 0, maxJobs * sizeof *job_table);
@@ -2243,15 +2274,7 @@ Job_Init(void)
ADDSIG(SIGCONT, JobContinueSig)
#undef ADDSIG
begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
if (begin != NULL) {
JobRun(begin);
if (begin->made == ERROR) {
PrintOnError(begin, "\n\nStop.");
exit(1);
}
}
(void)Job_RunTarget(".BEGIN", NULL);
postCommands = Targ_FindNode(".END", TARG_CREATE);
}
@@ -2477,6 +2500,8 @@ Job_ParseShell(char *line)
commandShell = bmake_malloc(sizeof(Shell));
*commandShell = newShell;
}
/* this will take care of shellErrFlag */
Shell_Init();
}
if (commandShell->echoOn && commandShell->echoOff) {
@@ -2787,7 +2812,8 @@ JobTokenAdd(void)
if (DEBUG(JOB))
fprintf(debug_file, "(%d) aborting %d, deposit token %c\n",
getpid(), aborting, JOB_TOKENS[aborting]);
write(tokenWaitJob.outPipe, &tok, 1);
while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
continue;
}
/*-
@@ -2808,6 +2834,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);
return;
}
@@ -2900,13 +2928,15 @@ Job_TokenWithdraw(void)
while (read(tokenWaitJob.inPipe, &tok1, 1) == 1)
continue;
/* And put the stopper back */
write(tokenWaitJob.outPipe, &tok, 1);
while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
continue;
Fatal("A failure has been detected in another branch of the parallel make");
}
if (count == 1 && jobTokensRunning == 0)
/* We didn't want the token really */
write(tokenWaitJob.outPipe, &tok, 1);
while (write(tokenWaitJob.outPipe, &tok, 1) == -1 && errno == EAGAIN)
continue;
jobTokensRunning++;
if (DEBUG(JOB))
@@ -2914,6 +2944,38 @@ Job_TokenWithdraw(void)
return TRUE;
}
/*-
*-----------------------------------------------------------------------
* Job_RunTarget --
* Run the named target if found. If a filename is specified, then
* set that to the sources.
*
* Results:
* None
*
* Side Effects:
* exits if the target fails.
*
*-----------------------------------------------------------------------
*/
Boolean
Job_RunTarget(const char *target, const char *fname) {
GNode *gn = Targ_FindNode(target, TARG_NOCREATE);
if (gn == NULL)
return FALSE;
if (fname)
Var_Set(ALLSRC, fname, gn, 0);
JobRun(gn);
if (gn->made == ERROR) {
PrintOnError(gn, "\n\nStop.");
exit(1);
}
return TRUE;
}
#ifdef USE_SELECT
int
emul_poll(struct pollfd *fd, int nfd, int timeout)

View File

@@ -1,4 +1,4 @@
/* $NetBSD: job.h,v 1.40 2010/09/13 15:36:57 sjg Exp $ */
/* $NetBSD: job.h,v 1.42 2013/07/05 22:14:56 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -243,6 +243,7 @@ typedef struct Shell {
extern const char *shellPath;
extern const char *shellName;
extern char *shellErrFlag;
extern int jobTokensRunning; /* tokens currently "out" */
extern int maxJobs; /* Max jobs we can run */
@@ -268,5 +269,6 @@ void Job_TokenReturn(void);
Boolean Job_TokenWithdraw(void);
void Job_ServerStart(int, int, int);
void Job_SetPrefix(void);
Boolean Job_RunTarget(const char *, const char *);
#endif /* _JOB_H_ */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/* $NetBSD: lstMember.c,v 1.14 2013/11/14 00:01:28 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -33,14 +33,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
static char rcsid[] = "$NetBSD: lstMember.c,v 1.14 2013/11/14 00:01:28 sjg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
__RCSID("$NetBSD: lstMember.c,v 1.14 2013/11/14 00:01:28 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -58,6 +58,9 @@ Lst_Member(Lst l, void *d)
List list = l;
ListNode lNode;
if (list == NULL) {
return NULL;
}
lNode = list->firstPtr;
if (lNode == NULL) {
return NULL;

View File

@@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.203 2012/08/31 07:00:36 sjg Exp $ */
/* $NetBSD: main.c,v 1.225 2013/09/14 15:09:34 matt Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,7 +69,7 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: main.c,v 1.203 2012/08/31 07:00:36 sjg Exp $";
static char rcsid[] = "$NetBSD: main.c,v 1.225 2013/09/14 15:09:34 matt 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.203 2012/08/31 07:00:36 sjg Exp $");
__RCSID("$NetBSD: main.c,v 1.225 2013/09/14 15:09:34 matt Exp $");
#endif
#endif /* not lint */
#endif
@@ -117,19 +117,21 @@ __RCSID("$NetBSD: main.c,v 1.203 2012/08/31 07:00:36 sjg Exp $");
#include <sys/time.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/signal.h>
#include <sys/stat.h>
#ifdef MAKE_NATIVE
#include <sys/utsname.h>
#include <sys/sysctl.h>
#endif
#include <sys/utsname.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include "make.h"
#include "hash.h"
@@ -165,6 +167,7 @@ Boolean noRecursiveExecute; /* -N flag */
Boolean keepgoing; /* -k flag */
Boolean queryFlag; /* -q flag */
Boolean touchFlag; /* -t flag */
Boolean enterFlag; /* -w flag */
Boolean ignoreErrors; /* -i flag */
Boolean beSilent; /* -s flag */
Boolean oldVars; /* variable substitution style */
@@ -176,7 +179,6 @@ Boolean varNoExportEnv; /* -X flag */
Boolean doing_depend; /* Set while reading .depend */
static Boolean jobsRunning; /* TRUE if the jobs might be running */
static const char * tracefile;
static char * Check_Cwd_av(int, char **, int);
static void MainParseArgs(int, char **);
static int ReadMakefile(const void *, const void *);
static void usage(void) MAKE_ATTR_DEAD;
@@ -187,11 +189,44 @@ char curdir[MAXPATHLEN + 1]; /* Startup directory */
char *progname; /* the program name */
char *makeDependfile;
pid_t myPid;
int makelevel;
Boolean forceJobs = FALSE;
extern Lst parseIncPath;
/*
* For compatibility with the POSIX version of MAKEFLAGS that includes
* all the options with out -, convert flags to -f -l -a -g -s.
*/
static char *
explode(const char *flags)
{
size_t len;
char *nf, *st;
const char *f;
if (flags == NULL)
return NULL;
for (f = flags; *f; f++)
if (!isalpha((unsigned char)*f))
break;
if (*f)
return bmake_strdup(flags);
len = strlen(flags);
st = nf = bmake_malloc(len * 3 + 1);
while (*flags) {
*nf++ = '-';
*nf++ = *flags++;
*nf++ = ' ';
}
*nf = '\0';
return st;
}
static void
parse_debug_options(const char *argvalue)
{
@@ -344,7 +379,7 @@ MainParseArgs(int argc, char **argv)
Boolean inOption, dashDash = FALSE;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrst"
#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstw"
/* Can't actually use getopt(3) because rescanning is not portable */
getopt_def = OPTFLAGS;
@@ -552,6 +587,10 @@ rearg:
touchFlag = TRUE;
Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
break;
case 'w':
enterFlag = TRUE;
Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
break;
case '-':
dashDash = TRUE;
break;
@@ -742,7 +781,7 @@ MakeMode(const char *mode)
}
#if USE_META
if (strstr(mode, "meta"))
meta_init(mode);
meta_mode_init(mode);
#endif
}
if (mp)
@@ -772,7 +811,7 @@ main(int argc, char **argv)
Lst targs; /* target nodes to create -- passed to Make_Init */
Boolean outOfDate = FALSE; /* FALSE if all targets up to date */
struct stat sb, sa;
char *p1, *path, *pwd;
char *p1, *path;
char mdpath[MAXPATHLEN];
const char *machine = getenv("MACHINE");
const char *machine_arch = getenv("MACHINE_ARCH");
@@ -783,9 +822,7 @@ main(int argc, char **argv)
static char defsyspath[] = _PATH_DEFSYSPATH;
char found_path[MAXPATHLEN + 1]; /* for searching for sys.mk */
struct timeval rightnow; /* to initialize random seed */
#ifdef MAKE_NATIVE
struct utsname utsname;
#endif
/* default to writing debug to stderr */
debug_file = stderr;
@@ -804,7 +841,7 @@ main(int argc, char **argv)
progname++;
else
progname = argv[0];
#if defined(RLIMIT_NOFILE) && !defined(__minix)
#if !defined(__minix) && (defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)))
/*
* get rid of resource limit on file descriptors
*/
@@ -818,6 +855,12 @@ main(int argc, char **argv)
}
#endif
if (uname(&utsname) == -1) {
(void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
strerror(errno));
exit(2);
}
/*
* Get the name of this type of MACHINE from utsname
* so we can share an executable for similar machines.
@@ -828,11 +871,6 @@ main(int argc, char **argv)
*/
if (!machine) {
#ifdef MAKE_NATIVE
if (uname(&utsname) == -1) {
(void)fprintf(stderr, "%s: uname failed (%s).\n", progname,
strerror(errno));
exit(2);
}
machine = utsname.machine;
#else
#ifdef MAKE_MACHINE
@@ -844,6 +882,20 @@ main(int argc, char **argv)
}
if (!machine_arch) {
#if defined(MAKE_NATIVE) && !defined(__minix)
static char machine_arch_buf[sizeof(utsname.machine)];
const int mib[2] = { CTL_HW, HW_MACHINE_ARCH };
size_t len = sizeof(machine_arch_buf);
if (sysctl(mib, __arraycount(mib), machine_arch_buf,
&len, NULL, 0) < 0) {
(void)fprintf(stderr, "%s: sysctl failed (%s).\n", progname,
strerror(errno));
exit(2);
}
machine_arch = machine_arch_buf;
#else
#ifndef MACHINE_ARCH
#ifdef MAKE_MACHINE_ARCH
machine_arch = MAKE_MACHINE_ARCH;
@@ -852,6 +904,7 @@ main(int argc, char **argv)
#endif
#else
machine_arch = MACHINE_ARCH;
#endif
#endif
}
@@ -862,6 +915,7 @@ main(int argc, char **argv)
*/
Var_Init(); /* Initialize the lists of variables for
* parsing arguments */
Var_Set(".MAKE.OS", utsname.sysname, VAR_GLOBAL, 0);
Var_Set("MACHINE", machine, VAR_GLOBAL, 0);
Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0);
#ifdef MAKE_VERSION
@@ -935,32 +989,43 @@ main(int argc, char **argv)
Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0);
Var_Set("MFLAGS", "", VAR_GLOBAL, 0);
Var_Set(".ALLTARGETS", "", VAR_GLOBAL, 0);
/* some makefiles need to know this */
Var_Set(MAKE_LEVEL ".ENV", MAKE_LEVEL_ENV, VAR_CMD, 0);
/*
* Set some other useful macros
*/
{
char tmp[64];
const char *ep;
char tmp[64], *ep;
if (!(ep = getenv(MAKE_LEVEL))) {
ep = "0";
}
Var_Set(MAKE_LEVEL, ep, VAR_GLOBAL, 0);
makelevel = ((ep = getenv(MAKE_LEVEL_ENV)) && *ep) ? atoi(ep) : 0;
if (makelevel < 0)
makelevel = 0;
snprintf(tmp, sizeof(tmp), "%d", makelevel);
Var_Set(MAKE_LEVEL, tmp, VAR_GLOBAL, 0);
snprintf(tmp, sizeof(tmp), "%u", myPid);
Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
snprintf(tmp, sizeof(tmp), "%u", getppid());
Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
}
Job_SetPrefix();
if (makelevel > 0) {
char pn[1024];
snprintf(pn, sizeof(pn), "%s[%d]", progname, makelevel);
progname = bmake_strdup(pn);
}
#ifdef USE_META
meta_init();
#endif
/*
* First snag any flags out of the MAKE environment variable.
* (Note this is *not* MAKEFLAGS since /bin/make uses that and it's
* in a different format).
*/
#ifdef POSIX
Main_ParseArgLine(getenv("MAKEFLAGS"));
p1 = explode(getenv("MAKEFLAGS"));
Main_ParseArgLine(p1);
free(p1);
#else
Main_ParseArgLine(getenv("MAKE"));
#endif
@@ -977,6 +1042,9 @@ main(int argc, char **argv)
MainParseArgs(argc, argv);
if (enterFlag)
printf("%s: Entering directory `%s'\n", progname, curdir);
/*
* Verify that cwd is sane.
*/
@@ -997,17 +1065,23 @@ main(int argc, char **argv)
* So, to stop it breaking this case only, we ignore PWD if
* MAKEOBJDIRPREFIX is set or MAKEOBJDIR contains a transform.
*/
if (!ignorePWD &&
(pwd = getenv("PWD")) != NULL &&
getenv("MAKEOBJDIRPREFIX") == NULL) {
const char *makeobjdir = getenv("MAKEOBJDIR");
#ifndef NO_PWD_OVERRIDE
if (!ignorePWD) {
char *pwd;
if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
sa.st_dev == sb.st_dev)
(void)strncpy(curdir, pwd, MAXPATHLEN);
if ((pwd = getenv("PWD")) != NULL &&
getenv("MAKEOBJDIRPREFIX") == NULL) {
const char *makeobjdir = getenv("MAKEOBJDIR");
if (makeobjdir == NULL || !strchr(makeobjdir, '$')) {
if (stat(pwd, &sb) == 0 &&
sa.st_ino == sb.st_ino &&
sa.st_dev == sb.st_dev)
(void)strncpy(curdir, pwd, MAXPATHLEN);
}
}
}
#endif
Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
/*
@@ -1165,8 +1239,6 @@ main(int argc, char **argv)
jp_0, jp_1, maxJobs, maxJobTokens, compatMake);
Main_ExportMAKEFLAGS(TRUE); /* initial export */
Check_Cwd_av(0, NULL, 0); /* initialize it */
/*
@@ -1295,6 +1367,9 @@ main(int argc, char **argv)
Trace_Log(MAKEEND, 0);
if (enterFlag)
printf("%s: Leaving directory `%s'\n", progname, curdir);
Suff_End();
Targ_End();
Arch_End();
@@ -1327,7 +1402,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
if (!strcmp(fname, "-")) {
Parse_File(NULL /*stdin*/, -1);
Var_Set("MAKEFILE", "", VAR_GLOBAL, 0);
Var_Set("MAKEFILE", "", VAR_INTERNAL, 0);
} else {
/* if we've chdir'd, rebuild the path name */
if (strcmp(curdir, objdir) && *fname != '/') {
@@ -1376,7 +1451,7 @@ ReadMakefile(const void *p, const void *q MAKE_ATTR_UNUSED)
*/
found:
if (!doing_depend)
Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0);
Var_Set("MAKEFILE", fname, VAR_INTERNAL, 0);
Parse_File(fname, fd);
}
free(path);
@@ -1384,190 +1459,6 @@ found:
}
/*
* If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR
* in situations that would not arrise with ./obj (links or not).
* This tends to break things like:
*
* build:
* ${MAKE} includes
*
* This function spots when ${.MAKE:T} or ${.MAKE} is a command (as
* opposed to an argument) in a command line and if so returns
* ${.CURDIR} so caller can chdir() so that the assumptions made by
* the Makefile hold true.
*
* If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped.
*
* The chdir() only happens in the child process, and does nothing if
* MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it
* should not break anything. Also if NOCHECKMAKECHDIR is set we
* do nothing - to ensure historic semantics can be retained.
*/
static int Check_Cwd_Off = 0;
static char *
Check_Cwd_av(int ac, char **av, int copy)
{
static char *make[4];
static char *cur_dir = NULL;
char **mp;
char *cp;
int is_cmd, next_cmd;
int i;
int n;
if (Check_Cwd_Off) {
if (DEBUG(CWD))
fprintf(debug_file, "check_cwd: check is off.\n");
return NULL;
}
if (make[0] == NULL) {
if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) {
Check_Cwd_Off = 1;
if (DEBUG(CWD))
fprintf(debug_file, "check_cwd: turning check off.\n");
return NULL;
}
make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp);
if ((make[0] = strrchr(make[1], '/')) == NULL) {
make[0] = make[1];
make[1] = NULL;
} else
++make[0];
make[2] = NULL;
cur_dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
}
if (ac == 0 || av == NULL) {
if (DEBUG(CWD))
fprintf(debug_file, "check_cwd: empty command.\n");
return NULL; /* initialization only */
}
if (getenv("MAKEOBJDIR") == NULL &&
getenv("MAKEOBJDIRPREFIX") == NULL) {
if (DEBUG(CWD))
fprintf(debug_file, "check_cwd: no obj dirs.\n");
return NULL;
}
next_cmd = 1;
for (i = 0; i < ac; ++i) {
is_cmd = next_cmd;
n = strlen(av[i]);
cp = &(av[i])[n - 1];
if (strspn(av[i], "|&;") == (size_t)n) {
next_cmd = 1;
continue;
} else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') {
next_cmd = 1;
if (copy) {
do {
*cp-- = '\0';
} while (*cp == ';' || *cp == '&' || *cp == '|' ||
*cp == ')' || *cp == '}') ;
} else {
/*
* XXX this should not happen.
*/
fprintf(stderr, "%s: WARNING: raw arg ends in shell meta '%s'\n",
progname, av[i]);
}
} else
next_cmd = 0;
cp = av[i];
if (*cp == ';' || *cp == '&' || *cp == '|')
is_cmd = 1;
if (DEBUG(CWD))
fprintf(debug_file, "av[%d] == %s '%s'",
i, (is_cmd) ? "cmd" : "arg", av[i]);
if (is_cmd != 0) {
if (*cp == '(' || *cp == '{' ||
*cp == ';' || *cp == '&' || *cp == '|') {
do {
++cp;
} while (*cp == '(' || *cp == '{' ||
*cp == ';' || *cp == '&' || *cp == '|');
if (*cp == '\0') {
next_cmd = 1;
continue;
}
}
if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) {
if (DEBUG(CWD))
fprintf(debug_file, " == cd, done.\n");
return NULL;
}
for (mp = make; *mp != NULL; ++mp) {
n = strlen(*mp);
if (strcmp(cp, *mp) == 0) {
if (DEBUG(CWD))
fprintf(debug_file, " %s == '%s', chdir(%s)\n",
cp, *mp, cur_dir);
return cur_dir;
}
}
}
if (DEBUG(CWD))
fprintf(debug_file, "\n");
}
return NULL;
}
char *
Check_Cwd_Cmd(const char *cmd)
{
char *cp, *bp;
char **av;
int ac;
if (Check_Cwd_Off)
return NULL;
if (cmd) {
av = brk_string(cmd, &ac, TRUE, &bp);
if (DEBUG(CWD))
fprintf(debug_file, "splitting: '%s' -> %d words\n",
cmd, ac);
} else {
ac = 0;
av = NULL;
bp = NULL;
}
cp = Check_Cwd_av(ac, av, 1);
if (bp)
free(bp);
if (av)
free(av);
return cp;
}
void
Check_Cwd(const char **argv)
{
char *cp;
int ac;
if (Check_Cwd_Off)
return;
for (ac = 0; argv[ac] != NULL; ++ac)
/* NOTHING */;
if (ac == 3 && *argv[1] == '-') {
cp = Check_Cwd_Cmd(argv[2]);
} else {
cp = Check_Cwd_av(ac, UNCONST(argv), 0);
}
if (cp) {
chdir(cp);
}
}
/*-
* Cmd_Exec --
@@ -1849,7 +1740,7 @@ Finish(int errors)
}
/*
* enunlink --
* eunlink --
* Remove a file carefully, avoiding directories.
*/
int
@@ -1895,7 +1786,8 @@ execError(const char *af, const char *av)
IOADD(")\n");
#ifdef USE_IOVEC
(void)writev(2, iov, 8);
while (writev(2, iov, 8) == -1 && errno == EAGAIN)
continue;
#endif
}
@@ -1906,8 +1798,12 @@ execError(const char *af, const char *av)
static void
usage(void)
{
char *p;
if ((p = strchr(progname, '[')) != NULL)
*p = '\0';
(void)fprintf(stderr,
"usage: %s [-BeikNnqrstWX] \n\
"usage: %s [-BeikNnqrstWwX] \n\
[-C directory] [-D variable] [-d flags] [-f makefile]\n\
[-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]\n\
[-V variable] [variable=value] [target ...]\n", progname);

View File

@@ -1,4 +1,4 @@
.\" $NetBSD: make.1,v 1.209 2012/10/08 15:09:48 christos Exp $
.\" $NetBSD: make.1,v 1.226 2013/11/07 18:50:46 dholland 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 October 8, 2012
.Dd October 25, 2013
.Dt MAKE 1
.Os
.Sh NAME
@@ -37,7 +37,7 @@
.Nd maintain program dependencies
.Sh SYNOPSIS
.Nm
.Op Fl BeikNnqrstWX
.Op Fl BeikNnqrstWwX
.Op Fl C Ar directory
.Op Fl D Ar variable
.Op Fl d Ar flags
@@ -209,6 +209,8 @@ Force the
option to print raw values of variables.
.It Ar v
Print debugging information about variable assignment.
.It Ar w
Print entering and leaving directory messages, pre and post processing.
.It Ar x
Run shell commands with
.Fl x
@@ -468,6 +470,50 @@ except that the effect can be limited to a single line of a script.
A
.Ql Ic \-
causes any non-zero exit status of the command line to be ignored.
.Pp
When
.Nm
is run in jobs mode with
.Fl j Ar max_jobs ,
the entire script for the target is fed to a
single instance of the shell.
.Pp
In compatibility (non-jobs) mode, each command is run in a separate process.
If the command contains any shell meta characters
.Pq Ql #=|^(){};&<>*?[]:$`\e\en
it will be passed to the shell, otherwise
.Nm
will attempt direct execution.
.Pp
Since
.Nm
will
.Xr chdir 2
to
.Ql Va .OBJDIR
before executing any targets, each child process
starts with that as its current working directory.
.Pp
Makefiles should be written so that the mode of
.Nm
operation does not change their behavior.
For example, any command which needs to use
.Dq cd
or
.Dq chdir ,
without side-effect should be put in parenthesis:
.Bd -literal -offset indent
avoid-chdir-side-effects:
@echo Building $@ in `pwd`
@(cd ${.CURDIR} && ${.MAKE} $@)
@echo Back in `pwd`
ensure-one-shell-regardless-of-mode:
@echo Building $@ in `pwd`; \\
(cd ${.CURDIR} && ${.MAKE} $@); \\
echo Back in `pwd`
.Ed
.Sh VARIABLE ASSIGNMENTS
Variables in make are much like variables in the shell, and, by tradition,
consist of all upper-case letters.
@@ -699,6 +745,9 @@ then output for each target is prefixed with a token
.Ql --- target ---
the first part of which can be controlled via
.Va .MAKE.JOB.PREFIX .
If
.Va .MAKE.JOB.PREFIX
is empty, no token is printed.
.br
For example:
.Li .MAKE.JOB.PREFIX=${.newline}---${.MAKE:T}[${.MAKE.PID}]
@@ -812,6 +861,11 @@ In "meta" mode, this variable contains a list of all the meta files
used (updated or not).
This list can be used to process the meta files to extract dependency
information.
.It Va .MAKE.META.IGNORE_PATHS
Provides a list of path prefixes that should be ignored;
because the contents are expected to change over time.
The default list includes:
.Ql Pa /dev /etc /proc /tmp /var/run /var/tmp
.It Va .MAKE.META.PREFIX
Defines the message printed for each meta file updated in "meta verbose" mode.
The default value is:
@@ -830,6 +884,13 @@ by appending their names to
is re-exported whenever
.Ql Va .MAKEOVERRIDES
is modified.
.It Va .MAKE.PATH_FILEMON
If
.Nm
was built with
.Xr filemon 4
support, this is set to the path of the device node.
This allows makefiles to test for this support.
.It Va .MAKE.PID
The process-id of
.Nm .
@@ -1005,6 +1066,13 @@ may
be used.
The wildcard characters may be escaped with a backslash
.Pq Ql \e .
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
trailing space, and converting multiple consecutive spaces
to single spaces.
.
.It Cm \&:N Ns Ar pattern
This is identical to
.Ql Cm \&:M ,
@@ -1148,7 +1216,7 @@ The
modifier is just like the
.Cm \&:S
modifier except that the old and new strings, instead of being
simple strings, are a regular expression (see
simple strings, are an extended regular expression (see
.Xr regex 3 )
string
.Ar pattern
@@ -1247,7 +1315,7 @@ should start and end with a period.
For example.
.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
.Pp
However a single character varaiable is often more readable:
However a single character variable is often more readable:
.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
.It Cm \&:U Ns Ar newval
If the variable is undefined
@@ -1270,7 +1338,7 @@ The path of the node which has the same name as the variable
is the value.
If no such node exists or its path is null, then the
name of the variable is used.
In order for this modifier to work, the name (node) must at least have
In order for this modifier to work, the name (node) must at least have
appeared on the rhs of a dependency.
.Sm off
.It Cm \&:\&! Ar cmd Cm \&!
@@ -1690,7 +1758,7 @@ or
.Fl t
options were specified.
Normally used to mark recursive
.Nm Ns 's .
.Nm Ns s .
.It Ic .META
Create a meta file for the target, even if it is flagged as
.Ic .PHONY ,
@@ -1713,6 +1781,20 @@ targets.
Ignore differences in commands when deciding if target is out of date.
This is useful if the command contains a value which always changes.
If the number of commands change, though, the target will still be out of date.
The same effect applies to any command line that uses the variable
.Va .OODATE ,
which can be used for that purpose even when not otherwise needed or desired:
.Bd -literal -offset indent
skip-compare-for-some:
@echo this will be compared
@echo this will not ${.OODATE:M.NOMETA_CMP}
@echo this will also be compared
.Ed
The
.Cm \&:M
pattern suppresses any expansion of the unwanted variable.
.It Ic .NOPATH
Do not search for the target in the directories specified by
.Ic .PATH .
@@ -1896,6 +1978,12 @@ If the source is the special
.Ic .DOTLAST
target, then the current working
directory is searched last.
.It Ic .PATH. Ns Va suffix
Like
.Ic .PATH
but applies only to files with a particular suffix.
The suffix must have been previously declared with
.Ic .SUFFIXES .
.It Ic .PHONY
Apply the
.Ic .PHONY
@@ -1964,6 +2052,10 @@ If no sources are specified, the
.Ic .SILENT
attribute is applied to every
command in the file.
.It Ic .STALE
This target gets run when a dependency file contains stale entries, having
.Va .ALLSRC
set to the name of that dependency file.
.It Ic .SUFFIXES
Each source specifies a suffix to
.Nm .
@@ -2027,28 +2119,6 @@ The way that .for loop variables are substituted changed after
so that they still appear to be variable expansions.
In particular this stops them being treated as syntax, and removes some
obscure problems using them in .if statements.
.Pp
Unlike other
.Nm
programs, this implementation by default executes all commands for a given
target using a single shell invocation.
This is done for both efficiency and to simplify error handling in remote
command invocations.
Typically this is transparent to the user, unless the target commands change
the current working directory using
.Dq cd
or
.Dq chdir .
To be compatible with Makefiles that do this, one can use
.Fl B
to disable this behavior.
.Pp
In compatibility mode, each command is run in a separate process.
If the command contains any shell meta characters
.Pq Ql #=|^(){};&<>*?[]:$`\e\en
it will be passed to the shell, otherwise
.Nm
will attempt direct execution.
.Sh SEE ALSO
.Xr mkdep 1
.Sh HISTORY
@@ -2063,6 +2133,13 @@ for Sprite at Berkeley.
It was designed to be a parallel distributed make running jobs on different
machines using a daemon called
.Dq customs .
.Pp
Historically the target/dependency
.Dq FRC
has been used to FoRCe rebuilding (since the target/dependency
does not exist... unless someone creates an
.Dq FRC
file).
.Sh BUGS
The
.Nm

View File

@@ -1,4 +1,4 @@
/* $NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $ */
/* $NetBSD: make.c,v 1.88 2012/11/09 18:53:05 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: make.c,v 1.87 2012/06/12 19:21:51 joerg Exp $";
static char rcsid[] = "$NetBSD: make.c,v 1.88 2012/11/09 18:53:05 sjg 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.87 2012/06/12 19:21:51 joerg Exp $");
__RCSID("$NetBSD: make.c,v 1.88 2012/11/09 18:53:05 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -1032,7 +1032,7 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
if (cn->order_pred && Lst_ForEach(cn->order_pred, MakeCheckOrder, 0)) {
/* Can't build this (or anything else in this child list) yet */
cn->made = DEFERRED;
return 1;
return 0; /* but keep looking */
}
if (DEBUG(MAKE))
@@ -1055,7 +1055,7 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
return cn->type & OP_WAIT && cn->unmade > 0;
}
/* When a .ORDER RHS node completes we do this on each LHS */
/* When a .ORDER LHS node completes we do this on each RHS */
static int
MakeBuildParent(void *v_pn, void *toBeMade_next)
{

View File

@@ -1,4 +1,4 @@
/* $NetBSD: make.h,v 1.89 2012/06/12 19:21:51 joerg Exp $ */
/* $NetBSD: make.h,v 1.92 2013/09/04 15:38:26 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -388,6 +388,10 @@ extern Boolean varNoExportEnv; /* TRUE if we should not export variables
extern GNode *DEFAULT; /* .DEFAULT rule */
extern GNode *VAR_INTERNAL; /* Variables defined internally by make
* which should not override those set by
* makefiles.
*/
extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
* in the Makefile itself */
extern GNode *VAR_CMD; /* Variables defined on the command line */
@@ -426,6 +430,9 @@ extern pid_t myPid;
#define MAKEFILE_PREFERENCE ".MAKE.MAKEFILE_PREFERENCE"
#define MAKE_DEPENDFILE ".MAKE.DEPENDFILE" /* .depend */
#define MAKE_MODE ".MAKE.MODE"
#ifndef MAKE_LEVEL_ENV
# define MAKE_LEVEL_ENV "MAKELEVEL"
#endif
/*
* debug control:

View File

@@ -1,4 +1,4 @@
/* $NetBSD: meta.c,v 1.25 2012/06/27 17:22:58 sjg Exp $ */
/* $NetBSD: meta.c,v 1.33 2013/10/01 05:37:17 sjg Exp $ */
/*
* Implement 'meta' mode.
@@ -55,7 +55,12 @@
#endif
static BuildMon Mybm; /* for compat */
static Lst metaBailiwick; /* our scope of control */
static Lst metaBailiwick; /* our scope of control */
static Lst metaIgnorePaths; /* paths we deliberately ignore */
#ifndef MAKE_META_IGNORE_PATHS
#define MAKE_META_IGNORE_PATHS ".MAKE.META.IGNORE_PATHS"
#endif
Boolean useMeta = FALSE;
static Boolean useFilemon = FALSE;
@@ -539,8 +544,24 @@ boolValue(char *s)
return TRUE;
}
/*
* Initialization we need before reading makefiles.
*/
void
meta_init(const char *make_mode)
meta_init(void)
{
#ifdef USE_FILEMON
/* this allows makefiles to test if we have filemon support */
Var_Set(".MAKE.PATH_FILEMON", _PATH_FILEMON, VAR_GLOBAL, 0);
#endif
}
/*
* Initialization we need after reading makefiles.
*/
void
meta_mode_init(const char *make_mode)
{
static int once = 0;
char *cp;
@@ -591,6 +612,17 @@ meta_init(const char *make_mode)
if (cp) {
str2Lst_Append(metaBailiwick, cp, NULL);
}
/*
* We ignore any paths that start with ${.MAKE.META.IGNORE_PATHS}
*/
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,
"${" MAKE_META_IGNORE_PATHS ":O:u:tA}", VAR_GLOBAL, 0);
if (cp) {
str2Lst_Append(metaIgnorePaths, cp, NULL);
}
}
/*
@@ -828,6 +860,13 @@ string_match(const void *p, const void *q)
continue; \
}
#define DEQUOTE(p) if (*p == '\'') { \
char *ep; \
p++; \
if ((ep = strchr(p, '\''))) \
*ep = '\0'; \
}
Boolean
meta_oodate(GNode *gn, Boolean oodate)
{
@@ -840,10 +879,12 @@ meta_oodate(GNode *gn, Boolean oodate)
char fname2[MAXPATHLEN];
char *p;
char *cp;
char *link_src;
char *move_target;
static size_t cwdlen = 0;
static size_t tmplen = 0;
FILE *fp;
Boolean ignoreOODATE = FALSE;
Boolean needOODATE = FALSE;
Lst missingFiles;
if (oodate)
@@ -906,6 +947,8 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
break;
}
link_src = NULL;
move_target = NULL;
/* Find the start of the build monitor section. */
if (!f) {
if (strncmp(buf, "-- filemon", 10) == 0) {
@@ -1019,16 +1062,21 @@ meta_oodate(GNode *gn, Boolean oodate)
break;
case 'M': /* renaMe */
if (Lst_IsEmpty(missingFiles))
break;
/*
* For 'M'oves we want to check
* the src as for 'R'ead
* and the target as for 'W'rite.
*/
cp = p; /* save this for a second */
/* now get target */
if (strsep(&p, " ") == NULL)
continue;
CHECK_VALID_META(p);
move_target = p;
p = cp;
/* 'L' and 'M' put single quotes around the args */
if (*p == '\'') {
char *ep;
p++;
if ((ep = strchr(p, '\'')))
*ep = '\0';
}
DEQUOTE(p);
DEQUOTE(move_target);
/* FALLTHROUGH */
case 'D': /* unlink */
if (*p == '/' && !Lst_IsEmpty(missingFiles)) {
@@ -1037,24 +1085,42 @@ meta_oodate(GNode *gn, Boolean oodate)
char *tp = Lst_Datum(ln);
Lst_Remove(missingFiles, ln);
free(tp);
ln = NULL; /* we're done with it */
}
}
if (buf[0] == 'M') {
/* the target of the mv is a file 'W'ritten */
#ifdef DEBUG_META_MODE
if (DEBUG(META))
fprintf(debug_file, "meta_oodate: M %s -> %s\n",
p, move_target);
#endif
p = move_target;
goto check_write;
}
break;
case 'L': /* Link */
/* we want the target */
/*
* For 'L'inks check
* the src as for 'R'ead
* and the target as for 'W'rite.
*/
link_src = p;
/* now get target */
if (strsep(&p, " ") == NULL)
continue;
CHECK_VALID_META(p);
/* 'L' and 'M' put single quotes around the args */
if (*p == '\'') {
char *ep;
p++;
if ((ep = strchr(p, '\'')))
*ep = '\0';
}
DEQUOTE(p);
DEQUOTE(link_src);
#ifdef DEBUG_META_MODE
if (DEBUG(META))
fprintf(debug_file, "meta_oodate: L %s -> %s\n",
link_src, p);
#endif
/* FALLTHROUGH */
case 'W': /* Write */
check_write:
/*
* If a file we generated within our bailiwick
* but outside of .OBJDIR is missing,
@@ -1086,6 +1152,14 @@ meta_oodate(GNode *gn, Boolean oodate)
Lst_AtEnd(missingFiles, bmake_strdup(p));
}
break;
check_link_src:
p = link_src;
link_src = NULL;
#ifdef DEBUG_META_MODE
if (DEBUG(META))
fprintf(debug_file, "meta_oodate: L src %s\n", p);
#endif
/* FALLTHROUGH */
case 'R': /* Read */
case 'E': /* Exec */
/*
@@ -1093,20 +1167,15 @@ meta_oodate(GNode *gn, Boolean oodate)
* be part of the dependencies because
* they are _expected_ to change.
*/
if (strncmp(p, "/tmp/", 5) == 0 ||
(tmplen > 0 && strncmp(p, tmpdir, tmplen) == 0))
break;
if (strncmp(p, "/var/", 5) == 0)
break;
/* Ignore device files. */
if (strncmp(p, "/dev/", 5) == 0)
break;
/* Ignore /etc/ files. */
if (strncmp(p, "/etc/", 5) == 0)
if (*p == '/' &&
Lst_ForEach(metaIgnorePaths, prefix_match, p)) {
#ifdef DEBUG_META_MODE
if (DEBUG(META))
fprintf(debug_file, "meta_oodate: ignoring: %s\n",
p);
#endif
break;
}
if ((cp = strrchr(p, '/'))) {
cp++;
@@ -1185,6 +1254,8 @@ meta_oodate(GNode *gn, Boolean oodate)
default:
break;
}
if (!oodate && buf[0] == 'L' && link_src != NULL)
goto check_link_src;
} else if (strcmp(buf, "CMD") == 0) {
/*
* Compare the current command with the one in the
@@ -1196,17 +1267,19 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
} else {
char *cmd = (char *)Lst_Datum(ln);
Boolean hasOODATE = FALSE;
if (!ignoreOODATE) {
if (strstr(cmd, "$?"))
ignoreOODATE = TRUE;
else if ((cp = strstr(cmd, ".OODATE"))) {
/* check for $[{(].OODATE[)}] */
if (cp > cmd + 2 && cp[-2] == '$')
ignoreOODATE = TRUE;
}
if (ignoreOODATE && DEBUG(META))
fprintf(debug_file, "%s: %d: cannot compare commands using .OODATE\n", fname, lineno);
if (strstr(cmd, "$?"))
hasOODATE = TRUE;
else if ((cp = strstr(cmd, ".OODATE"))) {
/* check for $[{(].OODATE[:)}] */
if (cp > cmd + 2 && cp[-2] == '$')
hasOODATE = TRUE;
}
if (hasOODATE) {
needOODATE = TRUE;
if (DEBUG(META))
fprintf(debug_file, "%s: %d: cannot compare command using .OODATE\n", fname, lineno);
}
cmd = Var_Subst(NULL, cmd, gn, TRUE);
@@ -1235,7 +1308,7 @@ meta_oodate(GNode *gn, Boolean oodate)
if (buf[x - 1] == '\n')
buf[x - 1] = '\0';
}
if (!ignoreOODATE &&
if (!hasOODATE &&
!(gn->type & OP_NOMETA_CMP) &&
strcmp(p, cmd) != 0) {
if (DEBUG(META))
@@ -1279,14 +1352,16 @@ meta_oodate(GNode *gn, Boolean oodate)
oodate = TRUE;
}
}
if (oodate && ignoreOODATE) {
if (oodate && needOODATE) {
/*
* Target uses .OODATE, so we need to re-compute it.
* We need to clean up what Make_DoAllVar() did.
* Target uses .OODATE which is empty; or we wouldn't be here.
* We have decided it is oodate, so .OODATE needs to be set.
* All we can sanely do is set it to .ALLSRC.
*/
Var_Delete(ALLSRC, gn);
Var_Delete(OODATE, gn);
gn->flags &= ~DONE_ALLSRC;
Var_Set(OODATE, Var_Value(ALLSRC, gn, &cp), gn, 0);
if (cp)
free(cp);
}
return oodate;
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: meta.h,v 1.2 2011/03/30 22:03:49 sjg Exp $ */
/* $NetBSD: meta.h,v 1.3 2013/03/23 05:31:29 sjg Exp $ */
/*
* Things needed for 'meta' mode.
@@ -41,7 +41,8 @@ typedef struct BuildMon {
extern Boolean useMeta;
struct Job; /* not defined yet */
void meta_init(const char *);
void meta_init(void);
void meta_mode_init(const char *);
void meta_job_start(struct Job *, GNode *);
void meta_job_child(struct Job *);
void meta_job_error(struct Job *, GNode *, int, int);

View File

@@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $ */
/* $NetBSD: parse.c,v 1.192 2013/10/18 20:47:06 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -68,22 +68,15 @@
* SUCH DAMAGE.
*/
#ifdef __minix
#ifndef MAP_COPY
#define MAP_COPY MAP_PRIVATE
#endif
#endif
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $";
static char rcsid[] = "$NetBSD: parse.c,v 1.192 2013/10/18 20:47:06 christos 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.185 2012/06/12 19:21:51 joerg Exp $");
__RCSID("$NetBSD: parse.c,v 1.192 2013/10/18 20:47:06 christos Exp $");
#endif
#endif /* not lint */
#endif
@@ -140,6 +133,9 @@ __RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $");
#include <stdarg.h>
#include <stdio.h>
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
#ifndef MAP_COPY
#define MAP_COPY MAP_PRIVATE
#endif
@@ -158,7 +154,7 @@ __RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $");
* Structure for a file being read ("included file")
*/
typedef struct IFile {
const char *fname; /* name of file */
char *fname; /* name of file */
int lineno; /* current line number in file */
int first_lineno; /* line number of start of text */
int cond_depth; /* 'if' nesting when file opened */
@@ -214,6 +210,7 @@ typedef enum {
ExShell, /* .SHELL */
Silent, /* .SILENT */
SingleShell, /* .SINGLESHELL */
Stale, /* .STALE */
Suffixes, /* .SUFFIXES */
Wait, /* .WAIT */
Attribute /* Generic attribute */
@@ -337,6 +334,7 @@ static const struct {
{ ".SHELL", ExShell, 0 },
{ ".SILENT", Silent, OP_SILENT },
{ ".SINGLESHELL", SingleShell, 0 },
{ ".STALE", Stale, 0 },
{ ".SUFFIXES", Suffixes, 0 },
{ ".USE", Attribute, OP_USE },
{ ".USEBEFORE", Attribute, OP_USEBEFORE },
@@ -521,7 +519,6 @@ loadfile(const char *path, int fd)
* FUTURE: remove PROT_WRITE when the parser no longer
* needs to scribble on the input.
*/
lf->buf = mmap(NULL, lf->maplen, PROT_READ|PROT_WRITE,
MAP_FILE|MAP_COPY, fd, 0);
if (lf->buf != MAP_FAILED) {
@@ -910,6 +907,8 @@ ParseDoOp(void *gnp, void *opp)
gn->type |= op & ~OP_OPMASK;
cohort = Targ_FindNode(gn->name, TARG_NOHASH);
if (doing_depend)
ParseMark(cohort);
/*
* Make the cohort invisible as well to avoid duplicating it into
* other variables. True, parents of this target won't tend to do
@@ -982,6 +981,8 @@ ParseDoSrc(int tOp, const char *src)
*/
snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
gn = Targ_FindNode(wait_src, TARG_NOHASH);
if (doing_depend)
ParseMark(gn);
gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
Lst_ForEach(targets, ParseLinkSrc, gn);
return;
@@ -1013,6 +1014,8 @@ ParseDoSrc(int tOp, const char *src)
* source and the current one.
*/
gn = Targ_FindNode(src, TARG_CREATE);
if (doing_depend)
ParseMark(gn);
if (predecessor != NULL) {
(void)Lst_AtEnd(predecessor->order_succ, gn);
(void)Lst_AtEnd(gn->order_pred, predecessor);
@@ -1044,6 +1047,8 @@ ParseDoSrc(int tOp, const char *src)
/* Find/create the 'src' node and attach to all targets */
gn = Targ_FindNode(src, TARG_CREATE);
if (doing_depend)
ParseMark(gn);
if (tOp) {
gn->type |= tOp;
} else {
@@ -1201,9 +1206,8 @@ ParseDoDependency(char *line)
*/
int length;
void *freeIt;
char *result;
result = Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
(void)Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
if (freeIt)
free(freeIt);
cp += length-1;
@@ -1289,6 +1293,7 @@ ParseDoDependency(char *line)
* apply the .DEFAULT commands.
* .PHONY The list of targets
* .NOPATH Don't search for file in the path
* .STALE
* .BEGIN
* .END
* .ERROR
@@ -1299,42 +1304,45 @@ ParseDoDependency(char *line)
* .ORDER Must set initial predecessor to NULL
*/
switch (specType) {
case ExPath:
if (paths == NULL) {
paths = Lst_Init(FALSE);
}
(void)Lst_AtEnd(paths, dirSearchPath);
break;
case Main:
if (!Lst_IsEmpty(create)) {
specType = Not;
}
break;
case Begin:
case End:
case dotError:
case Interrupt:
gn = Targ_FindNode(line, TARG_CREATE);
gn->type |= OP_NOTMAIN|OP_SPECIAL;
(void)Lst_AtEnd(targets, gn);
break;
case Default:
gn = Targ_NewGN(".DEFAULT");
gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
(void)Lst_AtEnd(targets, gn);
DEFAULT = gn;
break;
case NotParallel:
maxJobs = 1;
break;
case SingleShell:
compatMake = TRUE;
break;
case Order:
predecessor = NULL;
break;
default:
break;
case ExPath:
if (paths == NULL) {
paths = Lst_Init(FALSE);
}
(void)Lst_AtEnd(paths, dirSearchPath);
break;
case Main:
if (!Lst_IsEmpty(create)) {
specType = Not;
}
break;
case Begin:
case End:
case Stale:
case dotError:
case Interrupt:
gn = Targ_FindNode(line, TARG_CREATE);
if (doing_depend)
ParseMark(gn);
gn->type |= OP_NOTMAIN|OP_SPECIAL;
(void)Lst_AtEnd(targets, gn);
break;
case Default:
gn = Targ_NewGN(".DEFAULT");
gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
(void)Lst_AtEnd(targets, gn);
DEFAULT = gn;
break;
case NotParallel:
maxJobs = 1;
break;
case SingleShell:
compatMake = TRUE;
break;
case Order:
predecessor = NULL;
break;
default:
break;
}
} else if (strncmp(line, ".PATH", 5) == 0) {
/*
@@ -1393,6 +1401,8 @@ ParseDoDependency(char *line)
} else {
gn = Suff_AddTransform(targName);
}
if (doing_depend)
ParseMark(gn);
(void)Lst_AtEnd(targets, gn);
}
@@ -1440,6 +1450,7 @@ ParseDoDependency(char *line)
Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
break;
case Default:
case Stale:
case Begin:
case End:
case dotError:
@@ -1729,6 +1740,12 @@ Parse_IsVar(char *line)
ch = *line++;
wasSpace = TRUE;
}
#ifdef SUNSHCMD
if (ch == ':' && strncmp(line, "sh", 2) == 0) {
line += 2;
continue;
}
#endif
if (ch == '=')
return TRUE;
if (*line == '=' && ISEQOPERATOR(ch))
@@ -2322,7 +2339,7 @@ Parse_SetInput(const char *name, int line, int fd,
* name of the include file so error messages refer to the right
* place.
*/
curFile->fname = name;
curFile->fname = bmake_strdup(name);
curFile->lineno = line;
curFile->first_lineno = line;
curFile->nextbuf = nextbuf;
@@ -2335,6 +2352,8 @@ Parse_SetInput(const char *name, int line, int fd,
buf = curFile->nextbuf(curFile->nextbuf_arg, &len);
if (buf == NULL) {
/* Was all a waste of time ... */
if (curFile->fname)
free(curFile->fname);
free(curFile);
return;
}
@@ -2449,6 +2468,7 @@ ParseGmakeExport(char *line)
"Variable/Value missing from \"export\"");
return;
}
*value++ = '\0'; /* terminate variable */
/*
* Expand the value before putting it in the environment.
@@ -2557,6 +2577,16 @@ ParseGetLine(int flags, int *length)
if (cf->P_end == NULL)
/* End of string (aka for loop) data */
break;
/* see if there is more we can parse */
while (ptr++ < cf->P_end) {
if ((ch = *ptr) == '\n') {
if (ptr > line && ptr[-1] == '\\')
continue;
Parse_Error(PARSE_WARNING,
"Zero byte read from file, skipping rest of line.");
break;
}
}
if (cf->nextbuf != NULL) {
/*
* End of this buffer; return EOF and outer logic

View File

@@ -1,4 +1,4 @@
/* $NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $ */
/* $NetBSD: suff.c,v 1.70 2013/05/18 13:13:34 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: suff.c,v 1.69 2011/09/29 23:38:04 sjg Exp $";
static char rcsid[] = "$NetBSD: suff.c,v 1.70 2013/05/18 13:13:34 sjg 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.69 2011/09/29 23:38:04 sjg Exp $");
__RCSID("$NetBSD: suff.c,v 1.70 2013/05/18 13:13:34 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -684,8 +684,8 @@ GNode *
Suff_AddTransform(char *line)
{
GNode *gn; /* GNode of transformation rule */
Suff *s = NULL, /* source suffix */
*t = NULL; /* target suffix */
Suff *s, /* source suffix */
*t; /* target suffix */
LstNode ln; /* Node for existing transformation */
ln = Lst_Find(transforms, line, SuffGNHasNameP);
@@ -2058,118 +2058,124 @@ SuffFindNormalDeps(GNode *gn, Lst slst)
* children, then look for any overriding transformations they imply.
* Should we find one, we discard the one we found before.
*/
bottom = NULL;
targ = NULL;
while (ln != NULL) {
/*
* Look for next possible suffix...
*/
ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP);
if (ln != NULL) {
int prefLen; /* Length of the prefix */
if (!(gn->type & OP_PHONY)) {
while (ln != NULL) {
/*
* Allocate a Src structure to which things can be transformed
* Look for next possible suffix...
*/
ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP);
if (ln != NULL) {
int prefLen; /* Length of the prefix */
/*
* Allocate a Src structure to which things can be transformed
*/
targ = bmake_malloc(sizeof(Src));
targ->file = bmake_strdup(gn->name);
targ->suff = (Suff *)Lst_Datum(ln);
targ->suff->refCount++;
targ->node = gn;
targ->parent = NULL;
targ->children = 0;
#ifdef DEBUG_SRC
targ->cp = Lst_Init(FALSE);
#endif
/*
* Allocate room for the prefix, whose end is found by
* subtracting the length of the suffix from
* the end of the name.
*/
prefLen = (eoname - targ->suff->nameLen) - sopref;
targ->pref = bmake_malloc(prefLen + 1);
memcpy(targ->pref, sopref, prefLen);
targ->pref[prefLen] = '\0';
/*
* Add nodes from which the target can be made
*/
SuffAddLevel(srcs, targ);
/*
* Record the target so we can nuke it
*/
(void)Lst_AtEnd(targs, targ);
/*
* Search from this suffix's successor...
*/
ln = Lst_Succ(ln);
}
}
/*
* Handle target of unknown suffix...
*/
if (Lst_IsEmpty(targs) && suffNull != NULL) {
if (DEBUG(SUFF)) {
fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
}
targ = bmake_malloc(sizeof(Src));
targ->file = bmake_strdup(gn->name);
targ->suff = (Suff *)Lst_Datum(ln);
targ->suff = suffNull;
targ->suff->refCount++;
targ->node = gn;
targ->parent = NULL;
targ->children = 0;
targ->pref = bmake_strdup(sopref);
#ifdef DEBUG_SRC
targ->cp = Lst_Init(FALSE);
#endif
/*
* Allocate room for the prefix, whose end is found by subtracting
* the length of the suffix from the end of the name.
* Only use the default suffix rules if we don't have commands
* defined for this gnode; traditional make programs used to
* not define suffix rules if the gnode had children but we
* don't do this anymore.
*/
prefLen = (eoname - targ->suff->nameLen) - sopref;
targ->pref = bmake_malloc(prefLen + 1);
memcpy(targ->pref, sopref, prefLen);
targ->pref[prefLen] = '\0';
if (Lst_IsEmpty(gn->commands))
SuffAddLevel(srcs, targ);
else {
if (DEBUG(SUFF))
fprintf(debug_file, "not ");
}
/*
* Add nodes from which the target can be made
*/
SuffAddLevel(srcs, targ);
/*
* Record the target so we can nuke it
*/
(void)Lst_AtEnd(targs, targ);
/*
* Search from this suffix's successor...
*/
ln = Lst_Succ(ln);
}
}
/*
* Handle target of unknown suffix...
*/
if (Lst_IsEmpty(targs) && suffNull != NULL) {
if (DEBUG(SUFF)) {
fprintf(debug_file, "\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
}
targ = bmake_malloc(sizeof(Src));
targ->file = bmake_strdup(gn->name);
targ->suff = suffNull;
targ->suff->refCount++;
targ->node = gn;
targ->parent = NULL;
targ->children = 0;
targ->pref = bmake_strdup(sopref);
#ifdef DEBUG_SRC
targ->cp = Lst_Init(FALSE);
#endif
/*
* Only use the default suffix rules if we don't have commands
* defined for this gnode; traditional make programs used to
* not define suffix rules if the gnode had children but we
* don't do this anymore.
*/
if (Lst_IsEmpty(gn->commands))
SuffAddLevel(srcs, targ);
else {
if (DEBUG(SUFF))
fprintf(debug_file, "not ");
fprintf(debug_file, "adding suffix rules\n");
(void)Lst_AtEnd(targs, targ);
}
if (DEBUG(SUFF))
fprintf(debug_file, "adding suffix rules\n");
(void)Lst_AtEnd(targs, targ);
}
/*
* Using the list of possible sources built up from the target suffix(es),
* try and find an existing file/target that matches.
*/
bottom = SuffFindThem(srcs, slst);
if (bottom == NULL) {
/*
* No known transformations -- use the first suffix found for setting
* the local variables.
* Using the list of possible sources built up from the target
* suffix(es), try and find an existing file/target that matches.
*/
if (!Lst_IsEmpty(targs)) {
targ = (Src *)Lst_Datum(Lst_First(targs));
bottom = SuffFindThem(srcs, slst);
if (bottom == NULL) {
/*
* No known transformations -- use the first suffix found
* for setting the local variables.
*/
if (!Lst_IsEmpty(targs)) {
targ = (Src *)Lst_Datum(Lst_First(targs));
} else {
targ = NULL;
}
} else {
targ = NULL;
/*
* Work up the transformation path to find the suffix of the
* target to which the transformation was made.
*/
for (targ = bottom; targ->parent != NULL; targ = targ->parent)
continue;
}
} else {
/*
* Work up the transformation path to find the suffix of the
* target to which the transformation was made.
*/
for (targ = bottom; targ->parent != NULL; targ = targ->parent)
continue;
}
Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
@@ -2419,12 +2425,7 @@ SuffFindDeps(GNode *gn, Lst slst)
*/
Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0);
Var_Set(PREFIX, gn->name, gn, 0);
if (gn->type & OP_PHONY) {
/*
* If this is a .PHONY target, we do not apply suffix rules.
*/
return;
}
if (DEBUG(SUFF)) {
fprintf(debug_file, "SuffFindDeps (%s)\n", gn->name);
}

View File

@@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.34 2012/06/19 23:25:53 sjg Exp $
# $NetBSD: Makefile,v 1.38 2013/08/28 21:56:50 sjg Exp $
#
# Unit tests for make(1)
# The main targets are:
@@ -24,6 +24,7 @@ SUBFILES= \
error \
export \
export-all \
export-env \
doterror \
dotwait \
forloop \
@@ -36,9 +37,11 @@ SUBFILES= \
modorder \
modts \
modword \
order \
phony-end \
posix \
qequals \
sunshcmd \
sysv \
ternary \
unexport \
@@ -48,6 +51,7 @@ SUBFILES= \
all: ${SUBFILES}
flags.doterror=
flags.order=-j1
# the tests are actually done with sub-makes.
.PHONY: ${SUBFILES}
@@ -76,7 +80,7 @@ LANG= C
test:
@echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1"
@cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \
${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}:,make:,' \
${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}[^:]*:,make:,' \
-e '/stopped/s, /.*, unit-tests,' \
-e 's,${.CURDIR:C/\./\\\./g}/,,g' \
-e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' > ${.TARGET}.out || { \

View File

@@ -0,0 +1,24 @@
# $Id: export-env,v 1.1 2013/03/22 16:36:46 sjg Exp $
# our normal .export, subsequent changes affect the environment
UT_TEST=this
.export UT_TEST
UT_TEST:= ${.PARSEFILE}
# not so with .export-env
UT_ENV=exported
.export-env UT_ENV
UT_ENV=not-exported
# gmake style export goes further; affects nothing but the environment
UT_EXP=before-export
export UT_EXP=exported
UT_EXP=not-exported
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};@}

View File

@@ -0,0 +1,20 @@
# $NetBSD: order,v 1.1 2012/11/09 19:08:28 sjg Exp $
# Test that .ORDER is handled correctly.
# The explicit dependency the.o: the.h will make us examine the.h
# the .ORDER will prevent us building it immediately,
# we should then examine the.c rather than stop.
all: the.o
.ORDER: the.c the.h
the.c the.h:
@echo Making $@
.SUFFIXES: .o .c
.c.o:
@echo Making $@ from $?
the.o: the.h

View File

@@ -0,0 +1,10 @@
BYECMD = echo bye
LATERCMD = echo later
TEST1 :sh = echo hello
TEST2 :sh = ${BYECMD}
TEST3 = ${LATERCMD:sh}
all:
@echo "TEST1=${TEST1}"
@echo "TEST2=${TEST2}"
@echo "TEST3=${TEST3}"

View File

@@ -43,6 +43,14 @@ UT_OK=good
UT_OKDIR=unit-tests
UT_TEST=export-all
UT_ZOO=hoopie
make:
UT_TEST=export-env
UT_ENV=not-exported
UT_EXP=not-exported
env:
UT_TEST=export-env
UT_ENV=exported
UT_EXP=exported
At first, I am
happy
and now: sad
@@ -310,6 +318,9 @@ LIST:tw:C/ /,/g="one two three four five six"
LIST:tw:C/ /,/1g="one two three four five six"
LIST:tw:tW:C/ /,/="one,two three four five six"
LIST:tW:tw:C/ /,/="one two three four five six"
Making the.c
Making the.h
Making the.o from the.h the.c
.TARGET="phony" .PREFIX="phony" .IMPSRC=""
.TARGET="all" .PREFIX="all" .IMPSRC=""
.TARGET="ok" .PREFIX="ok" .IMPSRC=""
@@ -338,6 +349,9 @@ Now we expect an error...
*** Error code 1 (continuing)
`all' not remade because of errors.
V.i386 ?= OK
TEST1=hello
TEST2=bye
TEST3=later
FOOBAR =
FOOBAR = foobar fubar
fun

View File

@@ -1,15 +1,18 @@
/* $NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $ */
/* $NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $ */
/*
* Missing stuff from OS's
*/
#if defined(__MINT__) || defined(__linux__)
#include <signal.h>
#endif
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $";
static char rcsid[] = "$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: util.c,v 1.53 2012/06/04 22:45:05 sjg Exp $");
__RCSID("$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $");
#endif
#endif

View File

@@ -1,4 +1,4 @@
/* $NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $ */
/* $NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -69,14 +69,14 @@
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $";
static char rcsid[] = "$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 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.171 2012/06/12 19:21:51 joerg Exp $");
__RCSID("$NetBSD: var.c,v 1.184 2013/09/04 15:38:26 sjg Exp $");
#endif
#endif /* not lint */
#endif
@@ -139,6 +139,7 @@ __RCSID("$NetBSD: var.c,v 1.171 2012/06/12 19:21:51 joerg Exp $");
#include "dir.h"
#include "job.h"
extern int makelevel;
/*
* This lets us tell if we have replaced the original environ
* (which we cannot free).
@@ -175,6 +176,7 @@ static char varNoError[] = "";
* The four contexts are searched in the reverse order from which they are
* listed.
*/
GNode *VAR_INTERNAL; /* variables from make itself */
GNode *VAR_GLOBAL; /* variables from the makefile */
GNode *VAR_CMD; /* variables defined on the command-line */
@@ -309,7 +311,6 @@ static char *VarGetPattern(GNode *, Var_Parse_State *,
int, const char **, int, int *, int *,
VarPattern *);
static char *VarQuote(char *);
static char *VarChangeCase(char *, int);
static char *VarHash(char *);
static char *VarModify(GNode *, Var_Parse_State *,
const char *,
@@ -408,6 +409,10 @@ VarFind(const char *name, GNode *ctxt, int flags)
(ctxt != VAR_GLOBAL))
{
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
/* VAR_INTERNAL is subordinate to VAR_GLOBAL */
var = Hash_FindEntry(&VAR_INTERNAL->context, name);
}
}
if ((var == NULL) && (flags & FIND_ENV)) {
char *env;
@@ -429,6 +434,9 @@ VarFind(const char *name, GNode *ctxt, int flags)
(ctxt != VAR_GLOBAL))
{
var = Hash_FindEntry(&VAR_GLOBAL->context, name);
if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
var = Hash_FindEntry(&VAR_INTERNAL->context, name);
}
if (var == NULL) {
return NULL;
} else {
@@ -530,11 +538,20 @@ void
Var_Delete(const char *name, GNode *ctxt)
{
Hash_Entry *ln;
ln = Hash_FindEntry(&ctxt->context, name);
char *cp;
if (strchr(name, '$')) {
cp = Var_Subst(NULL, name, VAR_GLOBAL, 0);
} else {
cp = (char *)name;
}
ln = Hash_FindEntry(&ctxt->context, cp);
if (DEBUG(VAR)) {
fprintf(debug_file, "%s:delete %s%s\n",
ctxt->name, name, ln ? "" : " (not found)");
ctxt->name, cp, ln ? "" : " (not found)");
}
if (cp != name) {
free(cp);
}
if (ln != NULL) {
Var *v;
@@ -649,6 +666,15 @@ Var_ExportVars(void)
char *val;
int n;
/*
* Several make's support this sort of mechanism for tracking
* recursion - but each uses a different name.
* We allow the makefiles to update MAKELEVEL and ensure
* children see a correctly incremented value.
*/
snprintf(tmp, sizeof(tmp), "%d", makelevel + 1);
setenv(MAKE_LEVEL_ENV, tmp, 1);
if (VAR_EXPORTED_NONE == var_exportedVars)
return;
@@ -770,7 +796,7 @@ Var_UnExport(char *str)
if (unexport_env) {
char **newenv;
cp = getenv(MAKE_LEVEL); /* we should preserve this */
cp = getenv(MAKE_LEVEL_ENV); /* we should preserve this */
if (environ == savedEnv) {
/* we have been here before! */
newenv = bmake_realloc(environ, 2 * sizeof(char *));
@@ -787,7 +813,7 @@ Var_UnExport(char *str)
environ = savedEnv = newenv;
newenv[0] = NULL;
newenv[1] = NULL;
setenv(MAKE_LEVEL, cp, 1);
setenv(MAKE_LEVEL_ENV, cp, 1);
} else {
for (; *str != '\n' && isspace((unsigned char) *str); str++)
continue;
@@ -911,6 +937,14 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
}
v = VarFind(name, ctxt, 0);
if (v == NULL) {
if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
/*
* This var would normally prevent the same name being added
* to VAR_GLOBAL, so delete it from there if needed.
* Otherwise -V name may show the wrong value.
*/
Var_Delete(name, VAR_GLOBAL);
}
VarAdd(name, val, ctxt);
} else {
Buf_Empty(&v->val);
@@ -945,22 +979,6 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
}
/*
* Another special case.
* Several make's support this sort of mechanism for tracking
* recursion - but each uses a different name.
* We allow the makefiles to update .MAKE.LEVEL and ensure
* children see a correctly incremented value.
*/
if (ctxt == VAR_GLOBAL && strcmp(MAKE_LEVEL, name) == 0) {
char tmp[64];
int level;
level = atoi(val);
snprintf(tmp, sizeof(tmp), "%u", level + 1);
setenv(MAKE_LEVEL, tmp, 1);
}
out:
if (expanded_name != NULL)
@@ -2296,9 +2314,7 @@ VarHash(char *str)
size_t len, len2;
unsigned char *ustr = (unsigned char *)str;
uint32_t h, k, c1, c2;
int done;
done = 1;
h = 0x971e137bU;
c1 = 0x95543787U;
c2 = 0x2ad7eb25U;
@@ -2328,7 +2344,7 @@ VarHash(char *str)
h = (h << 13) ^ (h >> 19);
h = h * 5 + 0x52dce729U;
h ^= k;
} while (!done);
}
h ^= len2;
h *= 0x85ebca6b;
h ^= h >> 13;
@@ -2344,37 +2360,6 @@ VarHash(char *str)
return Buf_Destroy(&buf, FALSE);
}
/*-
*-----------------------------------------------------------------------
* VarChangeCase --
* Change the string to all uppercase or all lowercase
*
* Input:
* str String to modify
* upper TRUE -> uppercase, else lowercase
*
* Results:
* The string with case changed
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
static char *
VarChangeCase(char *str, int upper)
{
Buffer buf;
int (*modProc)(int);
modProc = (upper ? toupper : tolower);
Buf_Init(&buf, 0);
for (; *str ; str++) {
Buf_AddByte(&buf, modProc(*str));
}
return Buf_Destroy(&buf, FALSE);
}
static char *
VarStrftime(const char *fmt, int zulu)
{
@@ -2561,7 +2546,8 @@ ApplyModifiers(char *nstr, const char *tstr,
}
apply_mods:
if (DEBUG(VAR)) {
fprintf(debug_file, "Applying :%c to \"%s\"\n", *tstr, nstr);
fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", v->name,
*tstr, nstr);
}
newStr = var_Error;
switch ((modifier = *tstr)) {
@@ -3050,8 +3036,16 @@ ApplyModifiers(char *nstr, const char *tstr,
VarRealpath, NULL);
cp = tstr + 2;
termc = *cp;
} else if (tstr[1] == 'u' || tstr[1] == 'l') {
newStr = VarChangeCase(nstr, (tstr[1] == 'u'));
} else if (tstr[1] == 'u') {
char *dp = bmake_strdup(nstr);
for (newStr = dp; *dp; dp++)
*dp = toupper((unsigned char)*dp);
cp = tstr + 2;
termc = *cp;
} else if (tstr[1] == 'l') {
char *dp = bmake_strdup(nstr);
for (newStr = dp; *dp; dp++)
*dp = tolower((unsigned char)*dp);
cp = tstr + 2;
termc = *cp;
} else if (tstr[1] == 'W' || tstr[1] == 'w') {
@@ -3161,8 +3155,8 @@ ApplyModifiers(char *nstr, const char *tstr,
free(cp2);
}
if (DEBUG(VAR))
fprintf(debug_file, "Pattern for [%s] is [%s]\n", nstr,
pattern);
fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n",
v->name, nstr, pattern);
if (*tstr == 'M') {
newStr = VarModify(ctxt, &parsestate, nstr, VarMatch,
pattern);
@@ -3517,7 +3511,8 @@ ApplyModifiers(char *nstr, const char *tstr,
}
}
if (DEBUG(VAR)) {
fprintf(debug_file, "Result of :%c is \"%s\"\n", modifier, newStr);
fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n",
v->name, modifier, newStr);
}
if (newStr != nstr) {
@@ -4150,6 +4145,7 @@ Var_GetHead(char *file)
void
Var_Init(void)
{
VAR_INTERNAL = Targ_NewGN("Internal");
VAR_GLOBAL = Targ_NewGN("Global");
VAR_CMD = Targ_NewGN("Command");