aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Price <steve@FreeBSD.org>1996-10-06 16:45:32 +0000
committerSteve Price <steve@FreeBSD.org>1996-10-06 16:45:32 +0000
commitea09f5e44d046037109ca9ba434e0135c27b392c (patch)
treebe2e28496871fb3f31307f3dda3b9d11045f9f74
parent6c7089bce55654cffa6258d1dcb973d642d95728 (diff)
downloadsrc-ea09f5e44d046037109ca9ba434e0135c27b392c.tar.gz
src-ea09f5e44d046037109ca9ba434e0135c27b392c.zip
Import Christos Zoulas' version of NetBSD's make onto the
vendor branch for reference. Obtained from: Christos Zoulas <christos@netbsd.org>
Notes
Notes: svn path=/cvs2svn/branches/CHRISTOS/; revision=18764
-rw-r--r--usr.bin/make/Makefile8
-rw-r--r--usr.bin/make/Makefile.boot36
-rw-r--r--usr.bin/make/PSD.doc/Makefile8
-rw-r--r--usr.bin/make/PSD.doc/tutorial.ms22
-rw-r--r--usr.bin/make/arch.c255
-rw-r--r--usr.bin/make/buf.c47
-rw-r--r--usr.bin/make/buf.h9
-rw-r--r--usr.bin/make/compat.c62
-rw-r--r--usr.bin/make/cond.c58
-rw-r--r--usr.bin/make/config.h46
-rw-r--r--usr.bin/make/dir.c112
-rw-r--r--usr.bin/make/dir.h8
-rw-r--r--usr.bin/make/for.c33
-rw-r--r--usr.bin/make/hash.c34
-rw-r--r--usr.bin/make/hash.h28
-rw-r--r--usr.bin/make/job.c1661
-rw-r--r--usr.bin/make/job.h20
-rw-r--r--usr.bin/make/list.h40
-rw-r--r--usr.bin/make/lst.h13
-rw-r--r--usr.bin/make/lst.lib/Makefile10
-rw-r--r--usr.bin/make/lst.lib/lstAppend.c22
-rw-r--r--usr.bin/make/lst.lib/lstAtEnd.c12
-rw-r--r--usr.bin/make/lst.lib/lstAtFront.c10
-rw-r--r--usr.bin/make/lst.lib/lstClose.c10
-rw-r--r--usr.bin/make/lst.lib/lstConcat.c12
-rw-r--r--usr.bin/make/lst.lib/lstDatum.c8
-rw-r--r--usr.bin/make/lst.lib/lstDeQueue.c12
-rw-r--r--usr.bin/make/lst.lib/lstDestroy.c12
-rw-r--r--usr.bin/make/lst.lib/lstDupl.c12
-rw-r--r--usr.bin/make/lst.lib/lstEnQueue.c10
-rw-r--r--usr.bin/make/lst.lib/lstFind.c8
-rw-r--r--usr.bin/make/lst.lib/lstFindFrom.c16
-rw-r--r--usr.bin/make/lst.lib/lstFirst.c8
-rw-r--r--usr.bin/make/lst.lib/lstForEach.c8
-rw-r--r--usr.bin/make/lst.lib/lstForEachFrom.c25
-rw-r--r--usr.bin/make/lst.lib/lstInit.c14
-rw-r--r--usr.bin/make/lst.lib/lstInsert.c24
-rw-r--r--usr.bin/make/lst.lib/lstInt.h7
-rw-r--r--usr.bin/make/lst.lib/lstIsAtEnd.c8
-rw-r--r--usr.bin/make/lst.lib/lstIsEmpty.c8
-rw-r--r--usr.bin/make/lst.lib/lstLast.c8
-rw-r--r--usr.bin/make/lst.lib/lstMember.c10
-rw-r--r--usr.bin/make/lst.lib/lstNext.c16
-rw-r--r--usr.bin/make/lst.lib/lstOpen.c8
-rw-r--r--usr.bin/make/lst.lib/lstRemove.c16
-rw-r--r--usr.bin/make/lst.lib/lstReplace.c8
-rw-r--r--usr.bin/make/lst.lib/lstSucc.c8
-rw-r--r--usr.bin/make/main.c477
-rw-r--r--usr.bin/make/make.1127
-rw-r--r--usr.bin/make/make.c70
-rw-r--r--usr.bin/make/make.h27
-rw-r--r--usr.bin/make/nonints.h10
-rw-r--r--usr.bin/make/parse.c651
-rw-r--r--usr.bin/make/pathnames.h5
-rw-r--r--usr.bin/make/sprite.h8
-rw-r--r--usr.bin/make/str.c43
-rw-r--r--usr.bin/make/suff.c126
-rw-r--r--usr.bin/make/targ.c27
-rw-r--r--usr.bin/make/util.c2
-rw-r--r--usr.bin/make/var.c147
60 files changed, 2921 insertions, 1629 deletions
diff --git a/usr.bin/make/Makefile b/usr.bin/make/Makefile
index b6ae9fc12691..eb1f43f9d5f4 100644
--- a/usr.bin/make/Makefile
+++ b/usr.bin/make/Makefile
@@ -1,10 +1,10 @@
-# from: @(#)Makefile 5.2 (Berkeley) 12/28/90
-# $Id: Makefile,v 1.6 1994/06/30 05:33:39 cgd Exp $
+# $NetBSD: Makefile,v 1.11 1996/05/28 23:34:35 christos Exp $
+# @(#)Makefile 5.2 (Berkeley) 12/28/90
PROG= make
-CFLAGS+= -I${.CURDIR} -DPOSIX
+CFLAGS+= -I${.CURDIR} -Wall -Wno-unused #-Wmissing-prototypes -Wstrict-prototypes
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 var.c
+ make.c parse.c str.c suff.c targ.c var.c util.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 \
diff --git a/usr.bin/make/Makefile.boot b/usr.bin/make/Makefile.boot
new file mode 100644
index 000000000000..b8e8001096bf
--- /dev/null
+++ b/usr.bin/make/Makefile.boot
@@ -0,0 +1,36 @@
+# $NetBSD: Makefile.boot,v 1.7 1996/08/30 17:59:37 thorpej Exp $
+#
+# a very simple makefile...
+#
+# You only want to use this if you aren't running NetBSD.
+#
+# modify MACHINE and MACHINE_ARCH as appropriate for your target architecture
+#
+MACHINE=sun
+MACHINE_ARCH=sparc
+CFLAGS= -I. -DMACHINE=\"${MACHINE}\" -DMACHINE_ARCH=\"${MACHINE_ARCH}\" \
+ -DMAKE_BOOTSTRAP
+LIBS=
+
+OBJ=arch.o buf.o compat.o cond.o dir.o for.o hash.o job.o main.o make.o \
+ parse.o str.o suff.o targ.o var.o util.o
+
+LIBOBJ= lst.lib/lstAppend.o lst.lib/lstAtEnd.o lst.lib/lstAtFront.o \
+ lst.lib/lstClose.o lst.lib/lstConcat.o lst.lib/lstDatum.o \
+ lst.lib/lstDeQueue.o lst.lib/lstDestroy.o lst.lib/lstDupl.o \
+ lst.lib/lstEnQueue.o lst.lib/lstFind.o lst.lib/lstFindFrom.o \
+ lst.lib/lstFirst.o lst.lib/lstForEach.o lst.lib/lstForEachFrom.o \
+ lst.lib/lstInit.o lst.lib/lstInsert.o lst.lib/lstIsAtEnd.o \
+ lst.lib/lstIsEmpty.o lst.lib/lstLast.o lst.lib/lstMember.o \
+ lst.lib/lstNext.o lst.lib/lstOpen.o lst.lib/lstRemove.o \
+ lst.lib/lstReplace.o lst.lib/lstSucc.o
+
+bmake: ${OBJ} ${LIBOBJ}
+# @echo 'make of make and make.0 started.'
+ ${CC} ${CFLAGS} ${OBJ} ${LIBOBJ} -o bmake ${LIBS}
+ @ls -l $@
+# nroff -h -man make.1 > make.0
+# @echo 'make of make and make.0 completed.'
+
+clean:
+ rm -f ${OBJ} ${LIBOBJ} ${PORTOBJ} bmake
diff --git a/usr.bin/make/PSD.doc/Makefile b/usr.bin/make/PSD.doc/Makefile
new file mode 100644
index 000000000000..8e1f1fa0705b
--- /dev/null
+++ b/usr.bin/make/PSD.doc/Makefile
@@ -0,0 +1,8 @@
+# $NetBSD: Makefile,v 1.2 1995/06/14 15:20:23 christos Exp $
+# @(#)Makefile 8.1 (Berkeley) 8/14/93
+
+DIR= psd/12.make
+SRCS= tutorial.ms
+MACROS= -ms
+
+.include <bsd.doc.mk>
diff --git a/usr.bin/make/PSD.doc/tutorial.ms b/usr.bin/make/PSD.doc/tutorial.ms
index 3cd869d05289..f66fd909be7b 100644
--- a/usr.bin/make/PSD.doc/tutorial.ms
+++ b/usr.bin/make/PSD.doc/tutorial.ms
@@ -1,3 +1,4 @@
+.\" $NetBSD: tutorial.ms,v 1.3 1996/03/06 00:15:31 christos Exp $
.\" Copyright (c) 1988, 1989 by Adam de Boor
.\" Copyright (c) 1989 by Berkeley Softworks
.\" Copyright (c) 1988, 1989, 1993
@@ -34,7 +35,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)tutorial.ms 8.4 (Berkeley) 4/28/95
+.\" @(#)tutorial.ms 8.1 (Berkeley) 8/18/93
.\"
.EH 'PSD:12-%''PMake \*- A Tutorial'
.OH 'PMake \*- A Tutorial''PSD:12-%'
@@ -43,8 +44,6 @@
.\" is numeric, it is taken as the depth for numbering (as for .NH), else
.\" the default (1) is assumed.
.\"
-.\" $Id: tutorial.ms,v 1.4 89/01/08 20:20:22 adam Exp Locker: adam $
-.\"
.\" @P The initial paragraph distance.
.\" @Q The piece of section number to increment (or 0 if none given)
.\" @R Section header.
@@ -1272,6 +1271,15 @@ administrator. If locking is on,
will turn it off, and vice versa. Note that this locking will not
prevent \fIyou\fP from invoking PMake twice in the same place \*- if
you own the lock file, PMake will warn you about it but continue to execute.
+.IP "\fB\-m\fP \fIdirectory\fP"
+.Ix 0 def flags -m
+Tells PMake another place to search for included makefiles via the <...>
+style. Several
+.B \-m
+options can be given to form a search path. If this construct is used the
+default system makefile search path is completely overridden.
+To be explained in chapter 3, section 3.2.
+.Rm 2 3.2
.IP \fB\-n\fP
.Ix 0 def flags -n
This flag tells PMake not to execute the commands needed to update the
@@ -1912,11 +1920,15 @@ or this
.DE
The difference between the two is where PMake searches for the file:
the first way, PMake will look for
-the file only in the system makefile directory (to find out what that
-directory is, give PMake the
+the file only in the system makefile directory (or directories)
+(to find out what that directory is, give PMake the
.B \-h
flag).
.Ix 0 ref flags -h
+The system makefile directory search path can be overridden via the
+.B \-m
+option.
+.Ix 0 ref flags -m
For files in double-quotes, the search is more complex:
.RS
.IP 1)
diff --git a/usr.bin/make/arch.c b/usr.bin/make/arch.c
index 64071dc6c535..410580013e01 100644
--- a/usr.bin/make/arch.c
+++ b/usr.bin/make/arch.c
@@ -1,3 +1,5 @@
+/* $NetBSD: arch.c,v 1.16 1996/08/13 16:42:00 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)arch.c 8.3 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94";
+#else
+static char rcsid[] = "$NetBSD: arch.c,v 1.16 1996/08/13 16:42:00 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -94,7 +100,7 @@ static char sccsid[] = "@(#)arch.c 8.3 (Berkeley) 4/28/95";
#include <sys/param.h>
#include <ctype.h>
#include <ar.h>
-#include <ranlib.h>
+#include <utime.h>
#include <stdio.h>
#include <stdlib.h>
#include "make.h"
@@ -108,12 +114,18 @@ typedef struct Arch {
char *name; /* Name of archive */
Hash_Table members; /* All the members of the archive described
* by <name, struct ar_hdr *> key/value pairs */
+ char *fnametab; /* Extended name table strings */
+ size_t fnamesize; /* Size of the string table */
} Arch;
static int ArchFindArchive __P((ClientData, ClientData));
static void ArchFree __P((ClientData));
static struct ar_hdr *ArchStatMember __P((char *, char *, Boolean));
static FILE *ArchFindMember __P((char *, char *, struct ar_hdr *, char *));
+#if defined(__svr4__) || defined(__SVR4)
+#define SVR4ARCHIVES
+static int ArchSVR4Entry __P((Arch *, char *, size_t, FILE *));
+#endif
/*-
*-----------------------------------------------------------------------
@@ -135,18 +147,20 @@ ArchFree(ap)
Arch *a = (Arch *) ap;
Hash_Search search;
Hash_Entry *entry;
-
- /* Free memory from hash entries */
+
+ /* Free memory from hash entries */
for (entry = Hash_EnumFirst(&a->members, &search);
entry != (Hash_Entry *)NULL;
entry = Hash_EnumNext(&search))
free((Address) Hash_GetValue (entry));
free(a->name);
+ if (a->fnametab)
+ free(a->fnametab);
Hash_DeleteTable(&a->members);
free((Address) a);
}
-
+
/*-
@@ -182,7 +196,7 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
* variable substitution performed on it */
libName = *linePtr;
-
+
subLibName = FALSE;
for (cp = libName; *cp != '(' && *cp != '\0'; cp++) {
@@ -194,14 +208,14 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
int length;
Boolean freeIt;
char *result;
-
+
result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt);
if (result == var_Error) {
return(FAILURE);
} else {
subLibName = TRUE;
}
-
+
if (freeIt) {
free(result);
}
@@ -213,7 +227,7 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
if (subLibName) {
libName = Var_Subst(NULL, libName, ctxt, TRUE);
}
-
+
for (;;) {
/*
@@ -289,7 +303,7 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
char *buf;
char *sacrifice;
char *oldMemName = memName;
-
+
memName = Var_Subst(NULL, memName, ctxt, TRUE);
/*
@@ -335,7 +349,7 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
Dir_Expand(memName, dirSearchPath, members);
while (!Lst_IsEmpty(members)) {
member = (char *)Lst_DeQueue(members);
-
+
sprintf(nameBuf, "%s(%s)", libName, member);
free(member);
gn = Targ_FindNode (nameBuf, TARG_CREATE);
@@ -374,7 +388,7 @@ Arch_ParseArchive (linePtr, nodeLst, ctxt)
if (doSubst) {
free(memName);
}
-
+
*cp = saveChar;
}
@@ -486,7 +500,7 @@ ArchStatMember (archive, member, hash)
strncpy(copy, member, AR_MAX_NAME_LEN);
copy[AR_MAX_NAME_LEN] = '\0';
}
- if (he = Hash_FindEntry (&ar->members, copy))
+ if ((he = Hash_FindEntry (&ar->members, copy)) != NULL)
return ((struct ar_hdr *) Hash_GetValue (he));
return ((struct ar_hdr *) NULL);
}
@@ -520,7 +534,7 @@ ArchStatMember (archive, member, hash)
if (arch == (FILE *) NULL) {
return ((struct ar_hdr *) NULL);
}
-
+
/*
* We use the ARMAG string to make sure this is an archive we
* can handle...
@@ -532,27 +546,58 @@ ArchStatMember (archive, member, hash)
}
ar = (Arch *)emalloc (sizeof (Arch));
- ar->name = strdup (archive);
+ ar->name = estrdup (archive);
+ ar->fnametab = NULL;
+ ar->fnamesize = 0;
Hash_InitTable (&ar->members, -1);
memName[AR_MAX_NAME_LEN] = '\0';
-
+
while (fread ((char *)&arh, sizeof (struct ar_hdr), 1, arch) == 1) {
if (strncmp ( arh.ar_fmag, ARFMAG, sizeof (arh.ar_fmag)) != 0) {
- /*
- * The header is bogus, so the archive is bad
- * and there's no way we can recover...
- */
- fclose (arch);
- Hash_DeleteTable (&ar->members);
- free ((Address)ar);
- return ((struct ar_hdr *) NULL);
+ /*
+ * The header is bogus, so the archive is bad
+ * and there's no way we can recover...
+ */
+ goto badarch;
} else {
+ /*
+ * We need to advance the stream's pointer to the start of the
+ * next header. Files are padded with newlines to an even-byte
+ * boundary, so we need to extract the size of the file from the
+ * 'size' field of the header and round it up during the seek.
+ */
+ arh.ar_size[sizeof(arh.ar_size)-1] = '\0';
+ size = (int) strtol(arh.ar_size, NULL, 10);
+
(void) strncpy (memName, arh.ar_name, sizeof(arh.ar_name));
for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
continue;
}
cp[1] = '\0';
+#ifdef SVR4ARCHIVES
+ /*
+ * svr4 names are slash terminated. Also svr4 extended AR format.
+ */
+ if (memName[0] == '/') {
+ /*
+ * svr4 magic mode; handle it
+ */
+ switch (ArchSVR4Entry(ar, memName, size, arch)) {
+ case -1: /* Invalid data */
+ goto badarch;
+ case 0: /* List of files entry */
+ continue;
+ default: /* Got the entry */
+ break;
+ }
+ }
+ else {
+ if (cp[0] == '/')
+ cp[0] = '\0';
+ }
+#endif
+
#ifdef AR_EFMT1
/*
* BSD 4.4 extended AR format: #1/<namelen>, with name as the
@@ -563,18 +608,10 @@ ArchStatMember (archive, member, hash)
unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
- if (elen > MAXPATHLEN) {
- fclose (arch);
- Hash_DeleteTable (&ar->members);
- free ((Address)ar);
- return ((struct ar_hdr *) NULL);
- }
- if (fread (memName, elen, 1, arch) != 1) {
- fclose (arch);
- Hash_DeleteTable (&ar->members);
- free ((Address)ar);
- return ((struct ar_hdr *) NULL);
- }
+ if (elen > MAXPATHLEN)
+ goto badarch;
+ if (fread (memName, elen, 1, arch) != 1)
+ goto badarch;
memName[elen] = '\0';
fseek (arch, -elen, 1);
if (DEBUG(ARCH) || DEBUG(MAKE)) {
@@ -588,14 +625,6 @@ ArchStatMember (archive, member, hash)
memcpy ((Address)Hash_GetValue (he), (Address)&arh,
sizeof (struct ar_hdr));
}
- /*
- * We need to advance the stream's pointer to the start of the
- * next header. Files are padded with newlines to an even-byte
- * boundary, so we need to extract the size of the file from the
- * 'size' field of the header and round it up during the seek.
- */
- arh.ar_size[sizeof(arh.ar_size)-1] = '\0';
- size = (int) strtol(arh.ar_size, NULL, 10);
fseek (arch, (size + 1) & ~1, 1);
}
@@ -614,7 +643,120 @@ ArchStatMember (archive, member, hash)
} else {
return ((struct ar_hdr *) NULL);
}
+
+badarch:
+ fclose (arch);
+ Hash_DeleteTable (&ar->members);
+ if (ar->fnametab)
+ free(ar->fnametab);
+ free ((Address)ar);
+ return ((struct ar_hdr *) NULL);
+}
+
+#ifdef SVR4ARCHIVES
+/*-
+ *-----------------------------------------------------------------------
+ * ArchSVR4Entry --
+ * Parse an SVR4 style entry that begins with a slash.
+ * If it is "//", then load the table of filenames
+ * If it is "/<offset>", then try to substitute the long file name
+ * from offset of a table previously read.
+ *
+ * Results:
+ * -1: Bad data in archive
+ * 0: A table was loaded from the file
+ * 1: Name was successfully substituted from table
+ * 2: Name was not successfully substituted from table
+ *
+ * Side Effects:
+ * If a table is read, the file pointer is moved to the next archive
+ * member
+ *
+ *-----------------------------------------------------------------------
+ */
+static int
+ArchSVR4Entry(ar, name, size, arch)
+ Arch *ar;
+ char *name;
+ size_t size;
+ FILE *arch;
+{
+#define ARLONGNAMES1 "//"
+#define ARLONGNAMES2 "/ARFILENAMES"
+ size_t entry;
+ char *ptr, *eptr;
+
+ if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 ||
+ strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) {
+
+ if (ar->fnametab != NULL) {
+ if (DEBUG(ARCH)) {
+ printf("Attempted to redefine an SVR4 name table\n");
+ }
+ return -1;
+ }
+
+ /*
+ * This is a table of archive names, so we build one for
+ * ourselves
+ */
+ ar->fnametab = emalloc(size);
+ ar->fnamesize = size;
+
+ if (fread(ar->fnametab, size, 1, arch) != 1) {
+ if (DEBUG(ARCH)) {
+ printf("Reading an SVR4 name table failed\n");
+ }
+ return -1;
+ }
+ eptr = ar->fnametab + size;
+ for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++)
+ switch (*ptr) {
+ case '/':
+ entry++;
+ *ptr = '\0';
+ break;
+
+ case '\n':
+ break;
+
+ default:
+ break;
+ }
+ if (DEBUG(ARCH)) {
+ printf("Found svr4 archive name table with %d entries\n", entry);
+ }
+ return 0;
+ }
+
+ if (name[1] == ' ' || name[1] == '\0')
+ return 2;
+
+ entry = (size_t) strtol(&name[1], &eptr, 0);
+ if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) {
+ if (DEBUG(ARCH)) {
+ printf("Could not parse SVR4 name %s\n", name);
+ }
+ return 2;
+ }
+ if (entry >= ar->fnamesize) {
+ if (DEBUG(ARCH)) {
+ printf("SVR4 entry offset %s is greater than %d\n",
+ name, ar->fnamesize);
+ }
+ return 2;
+ }
+
+ if (DEBUG(ARCH)) {
+ printf("Replaced %s with %s\n", name, &ar->fnametab[entry]);
+ }
+
+ (void) strncpy(name, &ar->fnametab[entry], MAXPATHLEN);
+ name[MAXPATHLEN] = '\0';
+ return 1;
}
+#endif
+
/*-
*-----------------------------------------------------------------------
@@ -651,7 +793,7 @@ ArchFindMember (archive, member, arhPtr, mode)
if (arch == (FILE *) NULL) {
return ((FILE *) NULL);
}
-
+
/*
* We use the ARMAG string to make sure this is an archive we
* can handle...
@@ -676,7 +818,7 @@ ArchFindMember (archive, member, arhPtr, mode)
if (len > sizeof (arhPtr->ar_name)) {
tlen = sizeof (arhPtr->ar_name);
}
-
+
while (fread ((char *)arhPtr, sizeof (struct ar_hdr), 1, arch) == 1) {
if (strncmp(arhPtr->ar_fmag, ARFMAG, sizeof (arhPtr->ar_fmag) ) != 0) {
/*
@@ -820,9 +962,10 @@ void
Arch_TouchLib (gn)
GNode *gn; /* The node of the library to touch */
{
+#ifdef RANLIBMAG
FILE * arch; /* Stream open to archive */
struct ar_hdr arh; /* Header describing table of contents */
- struct timeval times[2]; /* Times for utimes() call */
+ struct utimbuf times; /* Times for utime() call */
arch = ArchFindMember (gn->path, RANLIBMAG, &arh, "r+");
sprintf(arh.ar_date, "%-12ld", (long) now);
@@ -831,10 +974,10 @@ Arch_TouchLib (gn)
(void)fwrite ((char *)&arh, sizeof (struct ar_hdr), 1, arch);
fclose (arch);
- times[0].tv_sec = times[1].tv_sec = now;
- times[0].tv_usec = times[1].tv_usec = 0;
- utimes(gn->path, times);
+ times.actime = times.modtime = now;
+ utime(gn->path, &times);
}
+#endif
}
/*-
@@ -940,7 +1083,7 @@ Arch_MemMTime (gn)
/*-
*-----------------------------------------------------------------------
* Arch_FindLib --
- * Search for a library along the given search path.
+ * Search for a library along the given search path.
*
* Results:
* None.
@@ -975,7 +1118,7 @@ Arch_FindLib (gn, path)
Var_Set (TARGET, gn->name, gn);
#else
Var_Set (TARGET, gn->path == (char *) NULL ? gn->name : gn->path, gn);
-#endif LIBRARIES
+#endif /* LIBRARIES */
}
/*-
@@ -1004,7 +1147,7 @@ Arch_FindLib (gn, path)
* opinion we should not bother with the TOC at all since
* this is used by 'ar' rules that affect the data contents
* of the archive, not by ranlib rules, which affect the
- * TOC.
+ * TOC.
*
* Results:
* TRUE if the library is out-of-date. FALSE otherwise.
@@ -1019,12 +1162,13 @@ Arch_LibOODate (gn)
GNode *gn; /* The library's graph node */
{
Boolean oodate;
-
+
if (OP_NOP(gn->type) && Lst_IsEmpty(gn->children)) {
oodate = FALSE;
} else if ((gn->mtime > now) || (gn->mtime < gn->cmtime)) {
oodate = TRUE;
} else {
+#ifdef RANLIBMAG
struct ar_hdr *arhPtr; /* Header for __.SYMDEF */
int modTimeTOC; /* The table-of-contents's mod time */
@@ -1046,6 +1190,9 @@ Arch_LibOODate (gn)
}
oodate = TRUE;
}
+#else
+ oodate = FALSE;
+#endif
}
return (oodate);
}
diff --git a/usr.bin/make/buf.c b/usr.bin/make/buf.c
index 68a534db14bc..e3b6afe176fe 100644
--- a/usr.bin/make/buf.c
+++ b/usr.bin/make/buf.c
@@ -1,6 +1,8 @@
+/* $NetBSD: buf.c,v 1.7 1996/03/29 02:17:13 jtc Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)buf.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: buf.c,v 1.7 1996/03/29 02:17:13 jtc Exp $";
+#endif
#endif /* not lint */
/*-
@@ -63,7 +69,7 @@ static char sccsid[] = "@(#)buf.c 8.2 (Berkeley) 4/28/95";
#define BufExpand(bp,nb) \
if (bp->left < (nb)+1) {\
int newSize = (bp)->size + max((nb)+1,BUF_ADD_INC); \
- Byte *newBuf = (Byte *) realloc((bp)->buffer, newSize); \
+ Byte *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \
\
(bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \
(bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\
@@ -286,7 +292,7 @@ Buf_GetBytes (bp, numBytes, bytesPtr)
int numBytes;
Byte *bytesPtr;
{
-
+
if (bp->inPtr - bp->outPtr < numBytes) {
numBytes = bp->inPtr - bp->outPtr;
}
@@ -323,7 +329,7 @@ Buf_GetAll (bp, numBytesPtr)
if (numBytesPtr != (int *)NULL) {
*numBytesPtr = bp->inPtr - bp->outPtr;
}
-
+
return (bp->outPtr);
}
@@ -336,7 +342,7 @@ Buf_GetAll (bp, numBytesPtr)
* None.
*
* Side Effects:
- * The bytes are discarded.
+ * The bytes are discarded.
*
*-----------------------------------------------------------------------
*/
@@ -428,9 +434,34 @@ Buf_Destroy (buf, freeData)
Buffer buf; /* Buffer to destroy */
Boolean freeData; /* TRUE if the data should be destroyed as well */
{
-
+
if (freeData) {
free ((char *)buf->buffer);
}
free ((char *)buf);
}
+
+/*-
+ *-----------------------------------------------------------------------
+ * Buf_ReplaceLastByte --
+ * Replace the last byte in a buffer.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * If the buffer was empty intially, then a new byte will be added.
+ * Otherwise, the last byte is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+Buf_ReplaceLastByte (buf, byte)
+ Buffer buf; /* buffer to augment */
+ Byte byte; /* byte to be written */
+{
+ if (buf->inPtr == buf->outPtr)
+ Buf_AddByte(buf, byte);
+ else
+ *(buf->inPtr - 1) = byte;
+}
diff --git a/usr.bin/make/buf.h b/usr.bin/make/buf.h
index 33313b8ff0ea..1295ff63dfd7 100644
--- a/usr.bin/make/buf.h
+++ b/usr.bin/make/buf.h
@@ -1,6 +1,8 @@
+/* $NetBSD: buf.h,v 1.5 1995/06/14 15:18:53 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)buf.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)buf.h 8.1 (Berkeley) 6/6/93
*/
/*-
@@ -76,5 +78,6 @@ void Buf_Discard __P((Buffer, int));
int Buf_Size __P((Buffer));
Buffer Buf_Init __P((int));
void Buf_Destroy __P((Buffer, Boolean));
+void Buf_ReplaceLastByte __P((Buffer, Byte));
#endif /* _BUF_H */
diff --git a/usr.bin/make/compat.c b/usr.bin/make/compat.c
index 9cab63c07345..0ebdcc089a01 100644
--- a/usr.bin/make/compat.c
+++ b/usr.bin/make/compat.c
@@ -1,6 +1,8 @@
+/* $NetBSD: compat.c,v 1.13 1995/11/22 17:40:00 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)compat.c 8.3 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
+#else
+static char rcsid[] = "$NetBSD: compat.c,v 1.13 1995/11/22 17:40:00 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -55,11 +61,11 @@ static char sccsid[] = "@(#)compat.c 8.3 (Berkeley) 4/28/95";
#include <stdio.h>
#include <sys/types.h>
-#include <sys/signal.h>
-#include <sys/wait.h>
-#include <sys/errno.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
@@ -101,14 +107,12 @@ CompatInterrupt (signo)
int signo;
{
GNode *gn;
-
+
if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) {
char *p1;
char *file = Var_Value (TARGET, curTarg, &p1);
- struct stat st;
- if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) &&
- unlink(file) != -1) {
+ if (!noExecute && eunlink(file) != -1) {
printf ("*** %s removed\n", file);
}
if (p1)
@@ -151,7 +155,7 @@ CompatRunCommand (cmdp, gnp)
register char *cp;
Boolean silent, /* Don't print command */
errCheck; /* Check errors */
- union wait reason; /* Reason for child's death */
+ int reason; /* Reason for child's death */
int status; /* Description of child's death */
int cpid; /* Child actually found */
ReturnStatus stat; /* Status of fork */
@@ -164,7 +168,7 @@ CompatRunCommand (cmdp, gnp)
char *cmd = (char *) cmdp;
GNode *gn = (GNode *) gnp;
- /*
+ /*
* Avoid clobbered variable warnings by forcing the compiler
* to ``unregister'' variables
*/
@@ -184,7 +188,7 @@ CompatRunCommand (cmdp, gnp)
* command? In any case, we warn the user that the command expanded to
* nothing (is this the right thing to do?).
*/
-
+
if (*cmdStart == '\0') {
free(cmdStart);
Error("%s expands to empty string", cmd);
@@ -213,7 +217,7 @@ CompatRunCommand (cmdp, gnp)
while (isspace((unsigned char)*cmd))
cmd++;
-
+
/*
* Search for meta characters in the command. If there are no meta
* characters, there's no need to execute a shell to execute the
@@ -239,7 +243,7 @@ CompatRunCommand (cmdp, gnp)
if (noExecute) {
return (0);
}
-
+
if (*cp != '\0') {
/*
* If *cp isn't the null character, we hit a "meta" character and
@@ -264,7 +268,7 @@ CompatRunCommand (cmdp, gnp)
av = brk_string(cmd, &argc, TRUE);
av += 1;
}
-
+
local = TRUE;
/*
@@ -286,32 +290,32 @@ CompatRunCommand (cmdp, gnp)
}
free(cmdStart);
Lst_Replace (cmdNode, (ClientData) NULL);
-
+
/*
* The child is off and running. Now all we can do is wait...
*/
while (1) {
- while ((stat = wait((int *)&reason)) != cpid) {
+ while ((stat = wait(&reason)) != cpid) {
if (stat == -1 && errno != EINTR) {
break;
}
}
-
+
if (stat > -1) {
if (WIFSTOPPED(reason)) {
- status = reason.w_stopval; /* stopped */
+ status = WSTOPSIG(reason); /* stopped */
} else if (WIFEXITED(reason)) {
- status = reason.w_retcode; /* exited */
+ status = WEXITSTATUS(reason); /* exited */
if (status != 0) {
printf ("*** Error code %d", status);
}
} else {
- status = reason.w_termsig; /* signaled */
+ status = WTERMSIG(reason); /* signaled */
printf ("*** Signal %d", status);
- }
+ }
+
-
if (!WIFEXITED(reason) || (status != 0)) {
if (errCheck) {
gn->made = ERROR;
@@ -388,7 +392,7 @@ CompatMake (gnp, pgnp)
if (p1)
free(p1);
}
-
+
/*
* All the children were made ok. Now cmtime contains the modification
* time of the newest child, we need to find out if we exist and when
@@ -422,7 +426,7 @@ CompatMake (gnp, pgnp)
* Make_DoAllVar().
*/
Make_DoAllVar(gn);
-
+
/*
* Alter our type to tell if errors should be ignored or things
* should not be printed so CompatRunCommand knows what to do.
@@ -563,7 +567,7 @@ CompatMake (gnp, pgnp)
return (0);
}
-
+
/*-
*-----------------------------------------------------------------------
* Compat_Run --
@@ -615,6 +619,10 @@ Compat_Run(targs)
gn = Targ_FindNode(".BEGIN", TARG_NOCREATE);
if (gn != NILGNODE) {
Lst_ForEach(gn->commands, CompatRunCommand, (ClientData)gn);
+ if (gn->made == ERROR) {
+ printf("\n\nStop.\n");
+ exit(1);
+ }
}
}
diff --git a/usr.bin/make/cond.c b/usr.bin/make/cond.c
index 6ea0d6a3d476..6515ec006789 100644
--- a/usr.bin/make/cond.c
+++ b/usr.bin/make/cond.c
@@ -1,6 +1,8 @@
+/* $NetBSD: cond.c,v 1.6 1995/06/14 15:18:58 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)cond.c 8.3 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94";
+#else
+static char rcsid[] = "$NetBSD: cond.c,v 1.6 1995/06/14 15:18:58 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -94,6 +100,7 @@ typedef enum {
* Structures to handle elegantly the different forms of #if's. The
* last two fields are stored in condInvert and condDefProc, respectively.
*/
+static void CondPushBack __P((Token));
static int CondGetArg __P((char **, char **, char *, Boolean));
static Boolean CondDoDefined __P((int, char *));
static int CondStrMatch __P((ClientData, ClientData));
@@ -110,18 +117,19 @@ static struct If {
char *form; /* Form of if */
int formlen; /* Length of form */
Boolean doNot; /* TRUE if default function should be negated */
- Boolean (*defProc)(); /* Default function to apply */
+ Boolean (*defProc) __P((int, char *)); /* Default function to apply */
} ifs[] = {
{ "ifdef", 5, FALSE, CondDoDefined },
{ "ifndef", 6, TRUE, CondDoDefined },
{ "ifmake", 6, FALSE, CondDoMake },
{ "ifnmake", 7, TRUE, CondDoMake },
{ "if", 2, FALSE, CondDoDefined },
- { (char *)0, 0, FALSE, (Boolean (*)())0 }
+ { NULL, 0, FALSE, NULL }
};
static Boolean condInvert; /* Invert the default function */
-static Boolean (*condDefProc)(); /* Default function to apply */
+static Boolean (*condDefProc) /* Default function to apply */
+ __P((int, char *));
static char *condExpr; /* The expression to parse */
static Token condPushBack=None; /* Single push-back token used in
* parsing */
@@ -210,7 +218,7 @@ CondGetArg (linePtr, argPtr, func, parens)
* long. Why 16? Why not?
*/
buf = Buf_Init(16);
-
+
while ((strchr(" \t)&|", *cp) == (char *)NULL) && (*cp != '\0')) {
if (*cp == '$') {
/*
@@ -253,7 +261,7 @@ CondGetArg (linePtr, argPtr, func, parens)
*/
cp++;
}
-
+
*linePtr = cp;
return (argLen);
}
@@ -427,7 +435,7 @@ CondDoTarget (argLen, arg)
*
* Side Effects:
* Can change 'value' even if string is not a valid number.
- *
+ *
*
*-----------------------------------------------------------------------
*/
@@ -617,10 +625,10 @@ do_string_compare:
buf = Buf_Init(0);
qt = *rhs == '"' ? 1 : 0;
-
- for (cp = &rhs[qt];
- ((qt && (*cp != '"')) ||
- (!qt && strchr(" \t)", *cp) == NULL)) &&
+
+ for (cp = &rhs[qt];
+ ((qt && (*cp != '"')) ||
+ (!qt && strchr(" \t)", *cp) == NULL)) &&
(*cp != '\0'); cp++) {
if ((*cp == '\\') && (cp[1] != '\0')) {
/*
@@ -632,7 +640,7 @@ do_string_compare:
} else if (*cp == '$') {
int len;
Boolean freeIt;
-
+
cp2 = Var_Parse(cp, VAR_CMD, doEval,&len, &freeIt);
if (cp2 != var_Error) {
Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
@@ -686,7 +694,7 @@ do_string_compare:
if (*rhs == '$') {
int len;
Boolean freeIt;
-
+
string = Var_Parse(rhs, VAR_CMD, doEval,&len,&freeIt);
if (string == var_Error) {
right = 0.0;
@@ -714,7 +722,7 @@ do_string_compare:
}
}
}
-
+
if (DEBUG(COND)) {
printf("left = %f, right = %f, op = %.2s\n", left,
right, op);
@@ -758,11 +766,11 @@ error:
break;
}
default: {
- Boolean (*evalProc)();
+ Boolean (*evalProc) __P((int, char *));
Boolean invert = FALSE;
char *arg;
int arglen;
-
+
if (strncmp (condExpr, "defined", 7) == 0) {
/*
* Use CondDoDefined to evaluate the argument and
@@ -824,8 +832,8 @@ error:
if (val == var_Error) {
t = Err;
} else {
- /*
- * A variable is empty when it just contains
+ /*
+ * A variable is empty when it just contains
* spaces... 4/15/92, christos
*/
char *p;
@@ -1107,7 +1115,7 @@ Cond_Eval (line)
} else {
isElse = FALSE;
}
-
+
/*
* Figure out what sort of conditional it is -- what its default
* function is, etc. -- by looking in the table of valid "ifs"
@@ -1167,16 +1175,16 @@ Cond_Eval (line)
*/
condDefProc = ifp->defProc;
condInvert = ifp->doNot;
-
+
line += ifp->formlen;
-
+
while (*line == ' ' || *line == '\t') {
line++;
}
-
+
condExpr = line;
condPushBack = None;
-
+
switch (CondE(TRUE)) {
case True:
if (CondToken(TRUE) == EndOfFile) {
diff --git a/usr.bin/make/config.h b/usr.bin/make/config.h
index 1f70f3768aa3..eaf960c85653 100644
--- a/usr.bin/make/config.h
+++ b/usr.bin/make/config.h
@@ -1,6 +1,8 @@
+/* $NetBSD: config.h,v 1.6 1996/05/28 23:34:39 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)config.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)config.h 8.1 (Berkeley) 6/6/93
*/
#define DEFSHELL 1 /* Bourne shell */
@@ -78,15 +80,39 @@
* re-made, causing later targets to appear up-to-date. On systems
* that don't have this problem, you should defined this. Under
* NFS you probably should not, unless you aren't exporting jobs.
- *
- * POSIX
- * If the POSIX standard for Make is to be followed. There are
- * several areas that I dislike, hence this constant.
*/
#define LIBSUFF ".a"
#define RECHECK
-#ifndef RANLIBMAG
-#define RANLIBMAG "__.SYMDEF"
+/*
+ * POSIX
+ * Adhere to the POSIX 1003.2 draft for the make(1) program.
+ * - Use MAKEFLAGS instead of MAKE to pick arguments from the
+ * environment.
+ * - Allow empty command lines if starting with tab.
+ */
+#define POSIX
+
+/*
+ * SYSVINCLUDE
+ * Recognize system V like include directives [include "filename"]
+ * SYSVVARSUB
+ * Recognize system V like ${VAR:x=y} variable substitutions
+ */
+#define SYSVINCLUDE
+#define SYSVVARSUB
+
+/*
+ * SUNSHCMD
+ * Recognize SunOS and Solaris:
+ * VAR :sh= CMD # Assign VAR to the command substitution of CMD
+ * ${VAR:sh} # Return the command substitution of the value
+ * # of ${VAR}
+ */
+#define SUNSHCMD
+
+#if !defined(__svr4__) && !defined(__SVR4)
+# ifndef RANLIBMAG
+# define RANLIBMAG "__.SYMDEF"
+# endif
#endif
-/*#define POSIX*/
diff --git a/usr.bin/make/dir.c b/usr.bin/make/dir.c
index e515fbb731e1..56d78afbbe90 100644
--- a/usr.bin/make/dir.c
+++ b/usr.bin/make/dir.c
@@ -1,6 +1,8 @@
+/* $NetBSD: dir.c,v 1.11 1996/08/13 16:42:02 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)dir.c 8.3 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94";
+#else
+static char rcsid[] = "$NetBSD: dir.c,v 1.11 1996/08/13 16:42:02 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -211,7 +217,7 @@ Dir_Init ()
dirSearchPath = Lst_Init (FALSE);
openDirectories = Lst_Init (FALSE);
Hash_InitTable(&mtimes, 0);
-
+
/*
* Since the Path structure is placed on both openDirectories and
* the path we give Dir_AddDir (which in this case is openDirectories),
@@ -291,7 +297,7 @@ Dir_HasWildcards (name)
char *name; /* name to check */
{
register char *cp;
-
+
for (cp = name; *cp; cp++) {
switch(*cp) {
case '{':
@@ -327,12 +333,12 @@ DirMatchFiles (pattern, p, expansions)
Path *p; /* Directory to search */
Lst expansions; /* Place to store the results */
{
- Hash_Search search; /* Index into the directory's table */
+ Hash_Search search; /* Index into the directory's table */
Hash_Entry *entry; /* Current entry in the table */
Boolean isDot; /* TRUE if the directory being searched is . */
-
+
isDot = (*p->name == '.' && p->name[1] == '\0');
-
+
for (entry = Hash_EnumFirst(&p->files, &search);
entry != (Hash_Entry *)NULL;
entry = Hash_EnumNext(&search))
@@ -348,7 +354,7 @@ DirMatchFiles (pattern, p, expansions)
(pattern[0] == '.')))
{
(void)Lst_AtEnd(expansions,
- (isDot ? strdup(entry->name) :
+ (isDot ? estrdup(entry->name) :
str_concat(p->name, entry->name,
STR_ADDSLASH)));
}
@@ -551,7 +557,7 @@ Dir_Expand (word, path, expansions)
if (DEBUG(DIR)) {
printf("expanding \"%s\"...", word);
}
-
+
cp = strchr(word, '{');
if (cp) {
DirExpandCurly(word, cp, path, expansions);
@@ -625,7 +631,7 @@ Dir_Expand (word, path, expansions)
* First the files in dot
*/
DirMatchFiles(word, dot, expansions);
-
+
/*
* Then the files in every other directory on the path.
*/
@@ -670,7 +676,7 @@ Dir_FindFile (name, path)
Boolean hasSlash; /* true if 'name' contains a / */
struct stat stb; /* Buffer for stat, if necessary */
Hash_Entry *entry; /* Entry for mtimes table */
-
+
/*
* Find the final component of the name and note whether it has a
* slash in it (the name, I mean)
@@ -683,7 +689,7 @@ Dir_FindFile (name, path)
hasSlash = FALSE;
cp = name;
}
-
+
if (DEBUG(DIR)) {
printf("Searching for %s...", name);
}
@@ -700,9 +706,9 @@ Dir_FindFile (name, path)
}
hits += 1;
dot->hits += 1;
- return (strdup (name));
+ return (estrdup (name));
}
-
+
if (Lst_Open (path) == FAILURE) {
if (DEBUG(DIR)) {
printf("couldn't open path, file not found\n");
@@ -710,7 +716,7 @@ Dir_FindFile (name, path)
misses += 1;
return ((char *) NULL);
}
-
+
/*
* We look through all the directories on the path seeking one which
* contains the final component of the given name and whose final
@@ -775,7 +781,7 @@ Dir_FindFile (name, path)
}
}
}
-
+
/*
* We didn't find the file on any existing members of the directory.
* If the name doesn't contain a slash, that means it doesn't exist.
@@ -795,10 +801,10 @@ Dir_FindFile (name, path)
misses += 1;
return ((char *) NULL);
}
-
+
if (*name != '/') {
Boolean checkedDot = FALSE;
-
+
if (DEBUG(DIR)) {
printf("failed. Trying subdirectories...");
}
@@ -811,21 +817,21 @@ Dir_FindFile (name, path)
/*
* Checking in dot -- DON'T put a leading ./ on the thing.
*/
- file = strdup(name);
+ file = estrdup(name);
checkedDot = TRUE;
}
if (DEBUG(DIR)) {
printf("checking %s...", file);
}
-
-
+
+
if (stat (file, &stb) == 0) {
if (DEBUG(DIR)) {
printf("got it.\n");
}
-
+
Lst_Close (path);
-
+
/*
* We've found another directory to search. We know there's
* a slash in 'file' because we put one there. We nuke it after
@@ -840,7 +846,7 @@ Dir_FindFile (name, path)
*cp = '\0';
Dir_AddDir (path, file);
*cp = '/';
-
+
/*
* Save the modification time so if it's needed, we don't have
* to fetch it again.
@@ -858,7 +864,7 @@ Dir_FindFile (name, path)
free (file);
}
}
-
+
if (DEBUG(DIR)) {
printf("failed. ");
}
@@ -875,7 +881,7 @@ Dir_FindFile (name, path)
return(NULL);
}
}
-
+
/*
* Didn't find it that way, either. Sigh. Phase 3. Add its directory
* onto the search path in any case, just in case, then look for the
@@ -897,7 +903,7 @@ Dir_FindFile (name, path)
cp[-1] = '\0';
Dir_AddDir (path, name);
cp[-1] = '/';
-
+
bigmisses += 1;
ln = Lst_Last (path);
if (ln == NILLNODE) {
@@ -905,9 +911,9 @@ Dir_FindFile (name, path)
} else {
p = (Path *) Lst_Datum (ln);
}
-
+
if (Hash_FindEntry (&p->files, cp) != (Hash_Entry *)NULL) {
- return (strdup (name));
+ return (estrdup (name));
} else {
return ((char *) NULL);
}
@@ -915,14 +921,14 @@ Dir_FindFile (name, path)
if (DEBUG(DIR)) {
printf("Looking for \"%s\"...", name);
}
-
+
bigmisses += 1;
entry = Hash_FindEntry(&mtimes, name);
if (entry != (Hash_Entry *)NULL) {
if (DEBUG(DIR)) {
printf("got it (in mtime cache)\n");
}
- return(strdup(name));
+ return(estrdup(name));
} else if (stat (name, &stb) == 0) {
entry = Hash_CreateEntry(&mtimes, name, (Boolean *)NULL);
if (DEBUG(DIR)) {
@@ -930,7 +936,7 @@ Dir_FindFile (name, path)
name);
}
Hash_SetValue(entry, (long)stb.st_mtime);
- return (strdup (name));
+ return (estrdup (name));
} else {
if (DEBUG(DIR)) {
printf("failed. Returning NULL\n");
@@ -945,7 +951,7 @@ Dir_FindFile (name, path)
* Dir_MTime --
* Find the modification time of the file described by gn along the
* search path dirSearchPath.
- *
+ *
* Results:
* The modification time or 0 if it doesn't exist
*
@@ -963,7 +969,7 @@ Dir_MTime (gn)
char *fullName; /* the full pathname of name */
struct stat stb; /* buffer for finding the mod time */
Hash_Entry *entry;
-
+
if (gn->type & OP_ARCHV) {
return Arch_MTime (gn);
} else if (gn->path == (char *)NULL) {
@@ -971,9 +977,9 @@ Dir_MTime (gn)
} else {
fullName = gn->path;
}
-
+
if (fullName == (char *)NULL) {
- fullName = strdup(gn->name);
+ fullName = estrdup(gn->name);
}
entry = Hash_FindEntry(&mtimes, fullName);
@@ -1001,7 +1007,7 @@ Dir_MTime (gn)
if (fullName && gn->path == (char *)NULL) {
gn->path = fullName;
}
-
+
gn->mtime = stb.st_mtime;
return (gn->mtime);
}
@@ -1017,7 +1023,7 @@ Dir_MTime (gn)
* none
*
* Side Effects:
- * A structure is added to the list and the directory is
+ * A structure is added to the list and the directory is
* read and hashed.
*-----------------------------------------------------------------------
*/
@@ -1031,7 +1037,7 @@ Dir_AddDir (path, name)
register Path *p; /* pointer to new Path structure */
DIR *d; /* for reading directory */
register struct dirent *dp; /* entry in directory */
-
+
ln = Lst_Find (openDirectories, (ClientData)name, DirFindName);
if (ln != NILLNODE) {
p = (Path *)Lst_Datum (ln);
@@ -1044,22 +1050,22 @@ Dir_AddDir (path, name)
printf("Caching %s...", name);
fflush(stdout);
}
-
+
if ((d = opendir (name)) != (DIR *) NULL) {
p = (Path *) emalloc (sizeof (Path));
- p->name = strdup (name);
+ p->name = estrdup (name);
p->hits = 0;
p->refCount = 1;
Hash_InitTable (&p->files, -1);
-
+
/*
* Skip the first two entries -- these will *always* be . and ..
*/
(void)readdir(d);
(void)readdir(d);
-
+
while ((dp = readdir (d)) != (struct dirent *) NULL) {
-#ifdef sun
+#if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */
/*
* The sun directory library doesn't check for a 0 inode
* (0-inode slots just take up space), so we have to do
@@ -1068,7 +1074,7 @@ Dir_AddDir (path, name)
if (dp->d_fileno == 0) {
continue;
}
-#endif /* sun */
+#endif /* sun && d_ino */
(void)Hash_CreateEntry(&p->files, dp->d_name, (Boolean *)NULL);
}
(void) closedir (d);
@@ -1130,9 +1136,9 @@ Dir_MakeFlags (flag, path)
char *tstr; /* the current directory preceded by 'flag' */
LstNode ln; /* the node of the current directory */
Path *p; /* the structure describing the current directory */
-
- str = strdup ("");
-
+
+ str = estrdup ("");
+
if (Lst_Open (path) == SUCCESS) {
while ((ln = Lst_Next (path)) != NILLNODE) {
p = (Path *) Lst_Datum (ln);
@@ -1141,7 +1147,7 @@ Dir_MakeFlags (flag, path)
}
Lst_Close (path);
}
-
+
return (str);
}
@@ -1203,7 +1209,7 @@ Dir_ClearPath(path)
Dir_Destroy((ClientData) p);
}
}
-
+
/*-
*-----------------------------------------------------------------------
@@ -1242,7 +1248,7 @@ Dir_PrintDirectories()
{
LstNode ln;
Path *p;
-
+
printf ("#*** Directory Cache:\n");
printf ("# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n",
hits, misses, nearmisses, bigmisses,
@@ -1261,7 +1267,7 @@ Dir_PrintDirectories()
static int DirPrintDir (p, dummy)
ClientData p;
ClientData dummy;
-{
+{
printf ("%s ", ((Path *) p)->name);
return (dummy ? 0 : 0);
}
diff --git a/usr.bin/make/dir.h b/usr.bin/make/dir.h
index 81d76d11504d..ac43ab0092ac 100644
--- a/usr.bin/make/dir.h
+++ b/usr.bin/make/dir.h
@@ -1,6 +1,8 @@
+/* $NetBSD: dir.h,v 1.3 1995/06/14 15:19:11 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)dir.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)dir.h 8.1 (Berkeley) 6/6/93
*/
/* dir.h --
diff --git a/usr.bin/make/for.c b/usr.bin/make/for.c
index 3ab3cba33dce..47d42af282c0 100644
--- a/usr.bin/make/for.c
+++ b/usr.bin/make/for.c
@@ -1,9 +1,8 @@
+/* $NetBSD: for.c,v 1.3 1995/06/14 15:19:13 christos Exp $ */
+
/*
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Christos Zoulas.
+ * Copyright (c) 1992, The Regents of the University of California.
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,7 +34,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)for.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: for.c,v 1.3 1995/06/14 15:19:13 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -64,7 +67,7 @@ static char sccsid[] = "@(#)for.c 8.2 (Berkeley) 4/28/95";
* The trick is to look for the matching end inside for for loop
* To do that, we count the current nesting level of the for loops.
* and the .endfor statements, accumulating all the statements between
- * the initial .for loop and the matching .endfor;
+ * the initial .for loop and the matching .endfor;
* then we evaluate the for loop for each variable in the varlist.
*/
@@ -128,18 +131,18 @@ For_Eval (line)
!isspace((unsigned char) ptr[3]))
return FALSE;
ptr += 3;
-
+
/*
* we found a for loop, and now we are going to parse it.
*/
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
-
+
/*
* Grab the variable
*/
buf = Buf_Init(0);
- for (wrd = ptr; *ptr && !isspace((unsigned char) *ptr); ptr++)
+ for (wrd = ptr; *ptr && !isspace((unsigned char) *ptr); ptr++)
continue;
Buf_AddBytes(buf, ptr - wrd, (Byte *) wrd);
@@ -172,12 +175,12 @@ For_Eval (line)
*/
forLst = Lst_Init(FALSE);
buf = Buf_Init(0);
- sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
+ sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
#define ADDWORD() \
Buf_AddBytes(buf, ptr - wrd, (Byte *) wrd), \
Buf_AddByte(buf, (Byte) '\0'), \
- Lst_AtEnd(forLst, (ClientData) Buf_GetAll(buf, &varlen)), \
+ Lst_AtFront(forLst, (ClientData) Buf_GetAll(buf, &varlen)), \
Buf_Destroy(buf, FALSE)
for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++)
@@ -193,12 +196,12 @@ For_Eval (line)
}
if (DEBUG(FOR))
(void) fprintf(stderr, "For: Iterator %s List %s\n", forVar, sub);
- if (ptr - wrd > 0)
+ if (ptr - wrd > 0)
ADDWORD();
else
Buf_Destroy(buf, TRUE);
free((Address) sub);
-
+
forBuf = Buf_Init(0);
forLevel++;
return 1;
@@ -259,7 +262,7 @@ ForExec(namep, argp)
Var_Set(arg->var, name, VAR_GLOBAL);
if (DEBUG(FOR))
(void) fprintf(stderr, "--- %s = %s\n", arg->var, name);
- Parse_FromString(Var_Subst(arg->var, (char *) Buf_GetAll(arg->buf, &len),
+ Parse_FromString(Var_Subst(arg->var, (char *) Buf_GetAll(arg->buf, &len),
VAR_GLOBAL, FALSE));
Var_Delete(arg->var, VAR_GLOBAL);
diff --git a/usr.bin/make/hash.c b/usr.bin/make/hash.c
index 37e839862b56..a4b730964a99 100644
--- a/usr.bin/make/hash.c
+++ b/usr.bin/make/hash.c
@@ -1,6 +1,8 @@
+/* $NetBSD: hash.c,v 1.5 1995/06/14 15:19:15 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)hash.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: hash.c,v 1.5 1995/06/14 15:19:15 christos Exp $";
+#endif
#endif /* not lint */
/* hash.c --
@@ -58,7 +64,7 @@ static char sccsid[] = "@(#)hash.c 8.2 (Berkeley) 4/28/95";
static void RebuildTable __P((Hash_Table *));
-/*
+/*
* The following defines the ratio of # entries to # buckets
* at which we rebuild the table to make it larger.
*/
@@ -67,12 +73,12 @@ static void RebuildTable __P((Hash_Table *));
/*
*---------------------------------------------------------
- *
+ *
* Hash_InitTable --
*
* This routine just sets up the hash table.
*
- * Results:
+ * Results:
* None.
*
* Side Effects:
@@ -94,7 +100,7 @@ Hash_InitTable(t, numBuckets)
register struct Hash_Entry **hp;
/*
- * Round up the size to a power of two.
+ * Round up the size to a power of two.
*/
if (numBuckets <= 0)
i = 16;
@@ -119,7 +125,7 @@ Hash_InitTable(t, numBuckets)
* and frees up the memory space it occupied (except for
* the space in the Hash_Table structure).
*
- * Results:
+ * Results:
* None.
*
* Side Effects:
@@ -145,7 +151,7 @@ Hash_DeleteTable(t)
/*
* Set up the hash table to cause memory faults on any future access
- * attempts until re-initialization.
+ * attempts until re-initialization.
*/
t->bucketPtr = NULL;
}
@@ -237,7 +243,7 @@ Hash_CreateEntry(t, key, newPtr)
/*
* The desired entry isn't there. Before allocating a new entry,
* expand the table if necessary (and this changes the resulting
- * bucket chain).
+ * bucket chain).
*/
if (t->numEntries >= rebuildLimit * t->size)
RebuildTable(t);
@@ -301,7 +307,7 @@ Hash_DeleteEntry(t, e)
* This procedure sets things up for a complete search
* of all entries recorded in the hash table.
*
- * Results:
+ * Results:
* The return value is the address of the first entry in
* the hash table, or NULL if the table is empty.
*
@@ -316,7 +322,7 @@ Hash_DeleteEntry(t, e)
Hash_Entry *
Hash_EnumFirst(t, searchPtr)
Hash_Table *t; /* Table to be searched. */
- register Hash_Search *searchPtr;/* Area in which to keep state
+ register Hash_Search *searchPtr;/* Area in which to keep state
* about search.*/
{
searchPtr->tablePtr = t;
@@ -345,7 +351,7 @@ Hash_EnumFirst(t, searchPtr)
Hash_Entry *
Hash_EnumNext(searchPtr)
- register Hash_Search *searchPtr; /* Area used to keep state about
+ register Hash_Search *searchPtr; /* Area used to keep state about
search. */
{
register Hash_Entry *e;
@@ -379,7 +385,7 @@ Hash_EnumNext(searchPtr)
* This local routine makes a new hash table that
* is larger than the old one.
*
- * Results:
+ * Results:
* None.
*
* Side Effects:
diff --git a/usr.bin/make/hash.h b/usr.bin/make/hash.h
index 63e8783726ce..179b2cded713 100644
--- a/usr.bin/make/hash.h
+++ b/usr.bin/make/hash.h
@@ -1,6 +1,8 @@
+/* $NetBSD: hash.h,v 1.4 1995/06/14 15:19:18 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)hash.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)hash.h 8.1 (Berkeley) 6/6/93
*/
/* hash.h --
@@ -47,7 +49,7 @@
#ifndef _HASH
#define _HASH
-/*
+/*
* The following defines one entry in the hash table.
*/
@@ -69,7 +71,7 @@ typedef struct Hash_Table {
int mask; /* Used to select bits for hashing. */
} Hash_Table;
-/*
+/*
* The following structure is used by the searching routines
* to record where we are in the search.
*/
@@ -85,22 +87,22 @@ typedef struct Hash_Search {
*/
/*
- * ClientData Hash_GetValue(h)
- * Hash_Entry *h;
+ * ClientData Hash_GetValue(h)
+ * Hash_Entry *h;
*/
#define Hash_GetValue(h) ((h)->clientData)
-/*
- * Hash_SetValue(h, val);
- * Hash_Entry *h;
- * char *val;
+/*
+ * Hash_SetValue(h, val);
+ * Hash_Entry *h;
+ * char *val;
*/
#define Hash_SetValue(h, val) ((h)->clientData = (ClientData) (val))
-/*
- * Hash_Size(n) returns the number of words in an object of n bytes
+/*
+ * Hash_Size(n) returns the number of words in an object of n bytes
*/
#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int))
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index 166fd974797a..89a7e1b8bd65 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -1,6 +1,8 @@
+/* $NetBSD: job.c,v 1.15 1996/05/29 15:28:05 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)job.c 8.3 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94";
+#else
+static char rcsid[] = "$NetBSD: job.c,v 1.15 1996/05/29 15:28:05 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -97,13 +103,13 @@ static char sccsid[] = "@(#)job.c 8.3 (Berkeley) 4/28/95";
*/
#include <sys/types.h>
-#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
+#include <utime.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
@@ -112,11 +118,17 @@ static char sccsid[] = "@(#)job.c 8.3 (Berkeley) 4/28/95";
#include "dir.h"
#include "job.h"
#include "pathnames.h"
+#ifdef REMOTE
+#include "rmt.h"
+# define STATIC
+#else
+# define STATIC static
+#endif
extern int errno;
/*
- * error handling variables
+ * error handling variables
*/
static int errors = 0; /* number of errors reported */
static int aborting = 0; /* why is the make aborting? */
@@ -124,6 +136,11 @@ static int aborting = 0; /* why is the make aborting? */
#define ABORT_INTERRUPT 2 /* Because it was interrupted */
#define ABORT_WAIT 3 /* Waiting for jobs to finish */
+/*
+ * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file
+ * is a char! So when we go above 127 we turn negative!
+ */
+#define FILENO(a) ((unsigned) fileno(a))
/*
* post-make command processing. The node postCommands is really just the
@@ -136,7 +153,6 @@ static int numCommands; /* The number of commands actually printed
* for a target. Should this number be
* 0, no shell will be executed. */
-
/*
* Return values from JobStart.
*/
@@ -149,7 +165,7 @@ static int numCommands; /* The number of commands actually printed
* tfile is the name of a file into which all shell commands are put. It is
* used over by removing it before the child shell is executed. The XXXXX in
* the string are replaced by the pid of the make process in a 5-character
- * field with leading zeroes.
+ * field with leading zeroes.
*/
static char tfile[] = TMPPAT;
@@ -176,17 +192,20 @@ static Shell shells[] = {
{
"sh",
TRUE, "set -", "set -v", "set -", 5,
+ TRUE, "set -e", "set +e",
+#ifdef OLDBOURNESHELL
FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n",
+#endif
"v", "e",
},
/*
* UNKNOWN.
*/
{
- (char *)0,
- FALSE, (char *)0, (char *)0, (char *)0, 0,
- FALSE, (char *)0, (char *)0,
- (char *)0, (char *)0,
+ (char *) 0,
+ FALSE, (char *) 0, (char *) 0, (char *) 0, 0,
+ FALSE, (char *) 0, (char *) 0,
+ (char *) 0, (char *) 0,
}
};
static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to
@@ -194,17 +213,17 @@ static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to
* commands in the Makefile.
* It is set by the
* Job_ParseShell function */
-static char *shellPath = (char *) NULL, /* full pathname of
+static char *shellPath = NULL, /* full pathname of
* executable image */
*shellName; /* last component of shell */
static int maxJobs; /* The most children we can run at once */
static int maxLocal; /* The most local ones we can have */
-int nJobs; /* The number of children currently running */
-int nLocal; /* The number of local children */
-Lst jobs; /* The structures that describe them */
-Boolean jobFull; /* Flag to tell when the job table is full. It
+STATIC int nJobs; /* The number of children currently running */
+STATIC int nLocal; /* The number of local children */
+STATIC Lst jobs; /* The structures that describe them */
+STATIC Boolean jobFull; /* Flag to tell when the job table is full. It
* is set TRUE when (1) the total number of
* running jobs equals the maximum allowed or
* (2) a job can only be run locally, but
@@ -214,47 +233,86 @@ static fd_set outputs; /* Set of descriptors of pipes connected to
* the output channels of children */
#endif
-GNode *lastNode; /* The node for which output was most recently
+STATIC GNode *lastNode; /* The node for which output was most recently
* produced. */
-char *targFmt; /* Format string to use to head output from a
+STATIC char *targFmt; /* Format string to use to head output from a
* job when it's not the most-recent job heard
* from */
-#define TARG_FMT "--- %s ---\n" /* Default format */
+
+#ifdef REMOTE
+# define TARG_FMT "--- %s at %s ---\n" /* Default format */
+# define MESSAGE(fp, gn) \
+ (void) fprintf(fp, targFmt, gn->name, gn->rem.hname);
+#else
+# define TARG_FMT "--- %s ---\n" /* Default format */
+# define MESSAGE(fp, gn) \
+ (void) fprintf(fp, targFmt, gn->name);
+#endif
/*
* When JobStart attempts to run a job remotely but can't, and isn't allowed
* to run the job locally, or when Job_CatchChildren detects a job that has
* been migrated home, the job is placed on the stoppedJobs queue to be run
- * when the next job finishes.
+ * when the next job finishes.
*/
-Lst stoppedJobs; /* Lst of Job structures describing
+STATIC Lst stoppedJobs; /* Lst of Job structures describing
* jobs that were stopped due to concurrency
* limits or migration home */
#if defined(USE_PGRP) && defined(SYSV)
-#define KILL(pid,sig) killpg (-(pid),(sig))
+# define KILL(pid, sig) killpg(-(pid), (sig))
#else
# if defined(USE_PGRP)
-#define KILL(pid,sig) killpg ((pid),(sig))
+# define KILL(pid, sig) killpg((pid), (sig))
# else
-#define KILL(pid,sig) kill ((pid),(sig))
+# define KILL(pid, sig) kill((pid), (sig))
# endif
#endif
+/*
+ * Grmpf... There is no way to set bits of the wait structure
+ * anymore with the stupid W*() macros. I liked the union wait
+ * stuff much more. So, we devise our own macros... This is
+ * really ugly, use dramamine sparingly. You have been warned.
+ */
+#define W_SETMASKED(st, val, fun) \
+ { \
+ int sh = (int) ~0; \
+ int mask = fun(sh); \
+ \
+ for (sh = 0; ((mask >> sh) & 1) == 0; sh++) \
+ continue; \
+ *(st) = (*(st) & ~mask) | ((val) << sh); \
+ }
+
+#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG)
+#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS)
+
+
static int JobCondPassSig __P((ClientData, ClientData));
static void JobPassSig __P((int));
static int JobCmpPid __P((ClientData, ClientData));
static int JobPrintCommand __P((ClientData, ClientData));
static int JobSaveCommand __P((ClientData, ClientData));
-static void JobFinish __P((Job *, union wait));
+static void JobClose __P((Job *));
+#ifdef REMOTE
+static int JobCmpRmtID __P((Job *, int));
+# ifdef RMT_WILL_WATCH
+static void JobLocalInput __P((int, Job *));
+# endif
+#else
+static void JobFinish __P((Job *, int *));
static void JobExec __P((Job *, char **));
+#endif
static void JobMakeArgv __P((Job *, char **));
static void JobRestart __P((Job *));
static int JobStart __P((GNode *, int, Job *));
+static char *JobOutput __P((Job *, char *, char *, int));
static void JobDoOutput __P((Job *, Boolean));
static Shell *JobMatchShell __P((char *));
-static void JobInterrupt __P((int));
+static void JobInterrupt __P((int, int));
+static void JobRestartJobs __P((void));
/*-
*-----------------------------------------------------------------------
@@ -279,7 +337,7 @@ JobCondPassSig(jobp, signop)
int signo = *(int *) signop;
#ifdef RMT_WANTS_SIGNALS
if (job->flags & JOB_REMOTE) {
- (void)Rmt_Signal(job, signo);
+ (void) Rmt_Signal(job, signo);
} else {
KILL(job->pid, signo);
}
@@ -288,9 +346,15 @@ JobCondPassSig(jobp, signop)
* Assume that sending the signal to job->pid will signal any remote
* job as well.
*/
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "JobCondPassSig passing signal %d to child %d.\n",
+ signo, job->pid);
+ (void) fflush(stdout);
+ }
KILL(job->pid, signo);
#endif
- return(0);
+ return 0;
}
/*-
@@ -304,16 +368,21 @@ JobCondPassSig(jobp, signop)
*
* Side Effects:
* We die by the same signal.
- *
+ *
*-----------------------------------------------------------------------
*/
static void
JobPassSig(signo)
int signo; /* The signal number we've received */
{
- int mask;
-
- Lst_ForEach(jobs, JobCondPassSig, (ClientData)(long)signo);
+ sigset_t nmask, omask;
+ struct sigaction act;
+
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout, "JobPassSig(%d) called.\n", signo);
+ (void) fflush(stdout);
+ }
+ Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
/*
* Deal with proper cleanup based on the signal received. We only run
@@ -321,36 +390,49 @@ JobPassSig(signo)
* three termination signals are more of a "get out *now*" command.
*/
if (signo == SIGINT) {
- JobInterrupt(TRUE);
+ JobInterrupt(TRUE, signo);
} else if ((signo == SIGHUP) || (signo == SIGTERM) || (signo == SIGQUIT)) {
- JobInterrupt(FALSE);
+ JobInterrupt(FALSE, signo);
}
-
+
/*
* Leave gracefully if SIGQUIT, rather than core dumping.
*/
if (signo == SIGQUIT) {
Finish(0);
}
-
+
/*
* Send ourselves the signal now we've given the message to everyone else.
* Note we block everything else possible while we're getting the signal.
* This ensures that all our jobs get continued when we wake up before
* we take any other signal.
*/
- mask = sigblock(0);
- (void) sigsetmask(~0 & ~(1 << (signo-1)));
- signal(signo, SIG_DFL);
+ sigemptyset(&nmask);
+ sigaddset(&nmask, signo);
+ sigprocmask(SIG_SETMASK, &nmask, &omask);
+ act.sa_handler = SIG_DFL;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ sigaction(signo, &act, NULL);
+
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "JobPassSig passing signal to self, mask = %x.\n",
+ ~0 & ~(1 << (signo-1)));
+ (void) fflush(stdout);
+ }
+ (void) signal(signo, SIG_DFL);
- kill(getpid(), signo);
+ (void) KILL(getpid(), signo);
signo = SIGCONT;
Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo);
- sigsetmask(mask);
- signal(signo, JobPassSig);
-
+ (void) sigprocmask(SIG_SETMASK, &omask, NULL);
+ sigprocmask(SIG_SETMASK, &omask, NULL);
+ act.sa_handler = JobPassSig;
+ sigaction(signo, &act, NULL);
}
/*-
@@ -368,13 +450,36 @@ JobPassSig(signo)
*-----------------------------------------------------------------------
*/
static int
-JobCmpPid (job, pid)
+JobCmpPid(job, pid)
ClientData job; /* job to examine */
ClientData pid; /* process id desired */
{
- return ( *(int *) pid - ((Job *) job)->pid);
+ return *(int *) pid - ((Job *) job)->pid;
}
+#ifdef REMOTE
+/*-
+ *-----------------------------------------------------------------------
+ * JobCmpRmtID --
+ * Compare the rmtID of the job with the given rmtID and return 0 if they
+ * are equal.
+ *
+ * Results:
+ * 0 if the rmtID's match
+ *
+ * Side Effects:
+ * None.
+ *-----------------------------------------------------------------------
+ */
+static int
+JobCmpRmtID(job, rmtID)
+ ClientData job; /* job to examine */
+ ClientData rmtID; /* remote id desired */
+{
+ return(*(int *) rmtID - *(int *) job->rmtID);
+}
+#endif
+
/*-
*-----------------------------------------------------------------------
* JobPrintCommand --
@@ -403,7 +508,7 @@ JobCmpPid (job, pid)
*-----------------------------------------------------------------------
*/
static int
-JobPrintCommand (cmdp, jobp)
+JobPrintCommand(cmdp, jobp)
ClientData cmdp; /* command string to print */
ClientData jobp; /* job for which to print it */
{
@@ -420,21 +525,26 @@ JobPrintCommand (cmdp, jobp)
char *cmdStart; /* Start of expanded command */
LstNode cmdNode; /* Node for replacing the command */
char *cmd = (char *) cmdp;
- Job *job = (Job *) jobp;
+ Job *job = (Job *) jobp;
- noSpecials = (noExecute && ! (job->node->type & OP_MAKE));
+ noSpecials = (noExecute && !(job->node->type & OP_MAKE));
- if (strcmp (cmd, "...") == 0) {
- job->node->type |= OP_SAVE_CMDS;
+ if (strcmp(cmd, "...") == 0) {
+ job->node->type |= OP_SAVE_CMDS;
if ((job->flags & JOB_IGNDOTS) == 0) {
- job->tailCmds = Lst_Succ (Lst_Member (job->node->commands,
- (ClientData)cmd));
- return (1);
+ job->tailCmds = Lst_Succ(Lst_Member(job->node->commands,
+ (ClientData)cmd));
+ return 1;
}
- return (0);
+ return 0;
}
-#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) printf (fmt, arg); fprintf (job->cmdFILE, fmt, arg)
+#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \
+ (void) fprintf(stdout, fmt, arg); \
+ (void) fflush(stdout); \
+ } \
+ (void) fprintf(job->cmdFILE, fmt, arg); \
+ (void) fflush(job->cmdFILE);
numCommands += 1;
@@ -442,9 +552,9 @@ JobPrintCommand (cmdp, jobp)
* For debugging, we replace each command with the result of expanding
* the variables in the command.
*/
- cmdNode = Lst_Member (job->node->commands, (ClientData)cmd);
- cmdStart = cmd = Var_Subst (NULL, cmd, job->node, FALSE);
- Lst_Replace (cmdNode, (ClientData)cmdStart);
+ cmdNode = Lst_Member(job->node->commands, (ClientData)cmd);
+ cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE);
+ Lst_Replace(cmdNode, (ClientData)cmdStart);
cmdTemplate = "%s\n";
@@ -464,16 +574,16 @@ JobPrintCommand (cmdp, jobp)
cmd++;
if (shutUp) {
- if (! (job->flags & JOB_SILENT) && !noSpecials &&
+ if (!(job->flags & JOB_SILENT) && !noSpecials &&
commandShell->hasEchoCtl) {
- DBPRINTF ("%s\n", commandShell->echoOff);
+ DBPRINTF("%s\n", commandShell->echoOff);
} else {
shutUp = FALSE;
}
}
if (errOff) {
- if ( ! (job->flags & JOB_IGNERR) && !noSpecials) {
+ if ( !(job->flags & JOB_IGNERR) && !noSpecials) {
if (commandShell->hasErrCtl) {
/*
* we don't want the error-control commands showing
@@ -483,16 +593,16 @@ JobPrintCommand (cmdp, jobp)
* string too, but why make it any more complex than
* it already is?
*/
- if (! (job->flags & JOB_SILENT) && !shutUp &&
+ if (!(job->flags & JOB_SILENT) && !shutUp &&
commandShell->hasEchoCtl) {
- DBPRINTF ("%s\n", commandShell->echoOff);
- DBPRINTF ("%s\n", commandShell->ignErr);
- DBPRINTF ("%s\n", commandShell->echoOn);
+ DBPRINTF("%s\n", commandShell->echoOff);
+ DBPRINTF("%s\n", commandShell->ignErr);
+ DBPRINTF("%s\n", commandShell->echoOn);
} else {
- DBPRINTF ("%s\n", commandShell->ignErr);
+ DBPRINTF("%s\n", commandShell->ignErr);
}
} else if (commandShell->ignErr &&
- (*commandShell->ignErr != '\0'))
+ (*commandShell->ignErr != '\0'))
{
/*
* The shell has no error control, so we need to be
@@ -503,10 +613,10 @@ JobPrintCommand (cmdp, jobp)
* to ignore errors. Set cmdTemplate to use the weirdness
* instead of the simple "%s\n" template.
*/
- if (! (job->flags & JOB_SILENT) && !shutUp &&
+ if (!(job->flags & JOB_SILENT) && !shutUp &&
commandShell->hasEchoCtl) {
- DBPRINTF ("%s\n", commandShell->echoOff);
- DBPRINTF (commandShell->errCheck, cmd);
+ DBPRINTF("%s\n", commandShell->echoOff);
+ DBPRINTF(commandShell->errCheck, cmd);
shutUp = TRUE;
}
cmdTemplate = commandShell->ignErr;
@@ -523,9 +633,9 @@ JobPrintCommand (cmdp, jobp)
errOff = FALSE;
}
}
-
- DBPRINTF (cmdTemplate, cmd);
-
+
+ DBPRINTF(cmdTemplate, cmd);
+
if (errOff) {
/*
* If echoing is already off, there's no point in issuing the
@@ -533,15 +643,15 @@ JobPrintCommand (cmdp, jobp)
* for the whole command...
*/
if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){
- DBPRINTF ("%s\n", commandShell->echoOff);
+ DBPRINTF("%s\n", commandShell->echoOff);
shutUp = TRUE;
}
- DBPRINTF ("%s\n", commandShell->errCheck);
+ DBPRINTF("%s\n", commandShell->errCheck);
}
if (shutUp) {
- DBPRINTF ("%s\n", commandShell->echoOn);
+ DBPRINTF("%s\n", commandShell->echoOn);
}
- return (0);
+ return 0;
}
/*-
@@ -559,13 +669,48 @@ JobPrintCommand (cmdp, jobp)
*-----------------------------------------------------------------------
*/
static int
-JobSaveCommand (cmd, gn)
+JobSaveCommand(cmd, gn)
ClientData cmd;
ClientData gn;
{
- cmd = (ClientData) Var_Subst (NULL, (char *) cmd, (GNode *) gn, FALSE);
- (void)Lst_AtEnd (postCommands->commands, cmd);
- return (0);
+ cmd = (ClientData) Var_Subst(NULL, (char *) cmd, (GNode *) gn, FALSE);
+ (void) Lst_AtEnd(postCommands->commands, cmd);
+ return(0);
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobClose --
+ * Called to close both input and output pipes when a job is finished.
+ *
+ * Results:
+ * Nada
+ *
+ * Side Effects:
+ * The file descriptors associated with the job are closed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobClose(job)
+ Job *job;
+{
+ if (usePipes) {
+#ifdef RMT_WILL_WATCH
+ Rmt_Ignore(job->inPipe);
+#else
+ FD_CLR(job->inPipe, &outputs);
+#endif
+ if (job->outPipe != job->inPipe) {
+ (void) close(job->outPipe);
+ }
+ JobDoOutput(job, TRUE);
+ (void) close(job->inPipe);
+ } else {
+ (void) close(job->outFd);
+ JobDoOutput(job, TRUE);
+ }
}
/*-
@@ -593,15 +738,15 @@ JobSaveCommand (cmd, gn)
*/
/*ARGSUSED*/
static void
-JobFinish (job, status)
- Job *job; /* job to finish */
- union wait status; /* sub-why job went away */
+JobFinish(job, status)
+ Job *job; /* job to finish */
+ int *status; /* sub-why job went away */
{
- Boolean done;
+ Boolean done;
- if ((WIFEXITED(status) &&
- (((status.w_retcode != 0) && !(job->flags & JOB_IGNERR)))) ||
- (WIFSIGNALED(status) && (status.w_termsig != SIGCONT)))
+ if ((WIFEXITED(*status) &&
+ (((WEXITSTATUS(*status) != 0) && !(job->flags & JOB_IGNERR)))) ||
+ (WIFSIGNALED(*status) && (WTERMSIG(*status) != SIGCONT)))
{
/*
* If it exited non-zero and either we're doing things our
@@ -611,93 +756,109 @@ JobFinish (job, status)
* cases, finish out the job's output before printing the exit
* status...
*/
- if (usePipes) {
-#ifdef RMT_WILL_WATCH
- Rmt_Ignore(job->inPipe);
-#else
- FD_CLR(job->inPipe, &outputs);
-#endif /* RMT_WILL_WATCH */
- if (job->outPipe != job->inPipe) {
- (void)close (job->outPipe);
- }
- JobDoOutput (job, TRUE);
- (void)close (job->inPipe);
- } else {
- (void)close (job->outFd);
- JobDoOutput (job, TRUE);
- }
-
+#ifdef REMOTE
+ KILL(job->pid, SIGCONT);
+#endif
+ JobClose(job);
if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
- fclose(job->cmdFILE);
+ (void) fclose(job->cmdFILE);
}
done = TRUE;
- } else if (WIFEXITED(status) && status.w_retcode != 0) {
+#ifdef REMOTE
+ if (job->flags & JOB_REMOTE)
+ Rmt_Done(job->rmtID, job->node);
+#endif
+ } else if (WIFEXITED(*status)) {
/*
* Deal with ignored errors in -B mode. We need to print a message
* telling of the ignored error as well as setting status.w_status
* to 0 so the next command gets run. To do this, we set done to be
- * TRUE if in -B mode and the job exited non-zero. Note we don't
+ * TRUE if in -B mode and the job exited non-zero.
+ */
+ done = WEXITSTATUS(*status) != 0;
+ /*
+ * Old comment said: "Note we don't
* want to close down any of the streams until we know we're at the
- * end.
+ * end."
+ * But we do. Otherwise when are we going to print the rest of the
+ * stuff?
*/
- done = TRUE;
+ JobClose(job);
+#ifdef REMOTE
+ if (job->flags & JOB_REMOTE)
+ Rmt_Done(job->rmtID, job->node);
+#endif /* REMOTE */
} else {
/*
* No need to close things down or anything.
*/
done = FALSE;
}
-
+
if (done ||
- WIFSTOPPED(status) ||
- (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) ||
+ WIFSTOPPED(*status) ||
+ (WIFSIGNALED(*status) && (WTERMSIG(*status) == SIGCONT)) ||
DEBUG(JOB))
{
FILE *out;
-
- if (!usePipes && (job->flags & JOB_IGNERR)) {
+
+ if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) {
/*
* If output is going to a file and this job is ignoring
* errors, arrange to have the exit status sent to the
* output file as well.
*/
- out = fdopen (job->outFd, "w");
+ out = fdopen(job->outFd, "w");
} else {
out = stdout;
}
- if (WIFEXITED(status)) {
- if (status.w_retcode != 0) {
+ if (WIFEXITED(*status)) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout, "Process %d exited.\n", job->pid);
+ (void) fflush(stdout);
+ }
+ if (WEXITSTATUS(*status) != 0) {
if (usePipes && job->node != lastNode) {
- fprintf (out, targFmt, job->node->name);
+ MESSAGE(out, job->node);
lastNode = job->node;
}
- fprintf (out, "*** Error code %d%s\n", status.w_retcode,
- (job->flags & JOB_IGNERR) ? " (ignored)" : "");
+ (void) fprintf(out, "*** Error code %d%s\n",
+ WEXITSTATUS(*status),
+ (job->flags & JOB_IGNERR) ? "(ignored)" : "");
if (job->flags & JOB_IGNERR) {
- status.w_status = 0;
+ *status = 0;
}
} else if (DEBUG(JOB)) {
if (usePipes && job->node != lastNode) {
- fprintf (out, targFmt, job->node->name);
+ MESSAGE(out, job->node);
lastNode = job->node;
}
- fprintf (out, "*** Completed successfully\n");
+ (void) fprintf(out, "*** Completed successfully\n");
+ }
+ } else if (WIFSTOPPED(*status)) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout, "Process %d stopped.\n", job->pid);
+ (void) fflush(stdout);
}
- } else if (WIFSTOPPED(status)) {
if (usePipes && job->node != lastNode) {
- fprintf (out, targFmt, job->node->name);
+ MESSAGE(out, job->node);
lastNode = job->node;
}
- if (! (job->flags & JOB_REMIGRATE)) {
- fprintf (out, "*** Stopped -- signal %d\n", status.w_stopsig);
+ if (!(job->flags & JOB_REMIGRATE)) {
+ (void) fprintf(out, "*** Stopped -- signal %d\n",
+ WSTOPSIG(*status));
}
job->flags |= JOB_RESUME;
(void)Lst_AtEnd(stoppedJobs, (ClientData)job);
- fflush(out);
+#ifdef REMOTE
+ if (job->flags & JOB_REMIGRATE)
+ JobRestart(job);
+#endif
+ (void) fflush(out);
return;
- } else if (status.w_termsig == SIGCONT) {
+ } else if (WTERMSIG(*status) == SIGCONT) {
/*
* If the beastie has continued, shift the Job from the stopped
* list to the running one (or re-stop it if concurrency is
@@ -705,37 +866,58 @@ JobFinish (job, status)
*/
if (job->flags & (JOB_RESUME|JOB_REMIGRATE|JOB_RESTART)) {
if (usePipes && job->node != lastNode) {
- fprintf (out, targFmt, job->node->name);
+ MESSAGE(out, job->node);
lastNode = job->node;
}
- fprintf (out, "*** Continued\n");
+ (void) fprintf(out, "*** Continued\n");
}
- if (! (job->flags & JOB_CONTINUING)) {
- JobRestart(job);
- } else {
- Lst_AtEnd(jobs, (ClientData)job);
- nJobs += 1;
- if (! (job->flags & JOB_REMOTE)) {
- nLocal += 1;
- }
- if (nJobs == maxJobs) {
- jobFull = TRUE;
- if (DEBUG(JOB)) {
- printf("Job queue is full.\n");
- }
+ if (!(job->flags & JOB_CONTINUING)) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "Warning: process %d was not continuing.\n",
+ job->pid);
+ (void) fflush(stdout);
}
+#ifdef notdef
+ /*
+ * We don't really want to restart a job from scratch just
+ * because it continued, especially not without killing the
+ * continuing process! That's why this is ifdef'ed out.
+ * FD - 9/17/90
+ */
+ JobRestart(job);
+#endif
}
- fflush(out);
- return;
+ job->flags &= ~JOB_CONTINUING;
+ Lst_AtEnd(jobs, (ClientData)job);
+ nJobs += 1;
+ if (!(job->flags & JOB_REMOTE)) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "Process %d is continuing locally.\n",
+ job->pid);
+ (void) fflush(stdout);
+ }
+ nLocal += 1;
+ }
+ if (nJobs == maxJobs) {
+ jobFull = TRUE;
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout, "Job queue is full.\n");
+ (void) fflush(stdout);
+ }
+ }
+ (void) fflush(out);
+ return;
} else {
if (usePipes && job->node != lastNode) {
- fprintf (out, targFmt, job->node->name);
+ MESSAGE(out, job->node);
lastNode = job->node;
}
- fprintf (out, "*** Signal %d\n", status.w_termsig);
+ (void) fprintf(out, "*** Signal %d\n", WTERMSIG(*status));
}
- fflush (out);
+ (void) fflush(out);
}
/*
@@ -743,40 +925,36 @@ JobFinish (job, status)
* try and restart the job on the next command. If JobStart says it's
* ok, it's ok. If there's an error, this puppy is done.
*/
- if ((status.w_status == 0) &&
- !Lst_IsAtEnd (job->node->commands))
- {
- switch (JobStart (job->node,
- job->flags & JOB_IGNDOTS,
- job))
- {
- case JOB_RUNNING:
- done = FALSE;
- break;
- case JOB_ERROR:
- done = TRUE;
- status.w_retcode = 1;
- break;
- case JOB_FINISHED:
- /*
- * If we got back a JOB_FINISHED code, JobStart has already
- * called Make_Update and freed the job descriptor. We set
- * done to false here to avoid fake cycles and double frees.
- * JobStart needs to do the update so we can proceed up the
- * graph when given the -n flag..
- */
- done = FALSE;
- break;
+ if (compatMake && (WIFEXITED(*status) &&
+ !Lst_IsAtEnd(job->node->commands))) {
+ switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) {
+ case JOB_RUNNING:
+ done = FALSE;
+ break;
+ case JOB_ERROR:
+ done = TRUE;
+ W_SETEXITSTATUS(status, 1);
+ break;
+ case JOB_FINISHED:
+ /*
+ * If we got back a JOB_FINISHED code, JobStart has already
+ * called Make_Update and freed the job descriptor. We set
+ * done to false here to avoid fake cycles and double frees.
+ * JobStart needs to do the update so we can proceed up the
+ * graph when given the -n flag..
+ */
+ done = FALSE;
+ break;
}
} else {
done = TRUE;
}
-
+
if (done &&
(aborting != ABORT_ERROR) &&
(aborting != ABORT_INTERRUPT) &&
- (status.w_status == 0))
+ (*status == 0))
{
/*
* As long as we aren't aborting and the job didn't return a non-zero
@@ -785,21 +963,19 @@ JobFinish (job, status)
* on the .END target.
*/
if (job->tailCmds != NILLNODE) {
- Lst_ForEachFrom (job->node->commands, job->tailCmds,
+ Lst_ForEachFrom(job->node->commands, job->tailCmds,
JobSaveCommand,
- (ClientData)job->node);
+ (ClientData)job->node);
}
job->node->made = MADE;
- Make_Update (job->node);
+ Make_Update(job->node);
free((Address)job);
- } else if (status.w_status) {
+ } else if (*status != 0) {
errors += 1;
free((Address)job);
}
- while (!errors && !jobFull && !Lst_IsEmpty(stoppedJobs)) {
- JobRestart((Job *)Lst_DeQueue(stoppedJobs));
- }
+ JobRestartJobs();
/*
* Set aborting if any error.
@@ -812,13 +988,13 @@ JobFinish (job, status)
*/
aborting = ABORT_ERROR;
}
-
+
if ((aborting == ABORT_ERROR) && Job_Empty()) {
/*
* If we are aborting and the job table is now empty, we finish.
*/
- (void) unlink (tfile);
- Finish (errors);
+ (void) eunlink(tfile);
+ Finish(errors);
}
}
@@ -837,12 +1013,12 @@ JobFinish (job, status)
*-----------------------------------------------------------------------
*/
void
-Job_Touch (gn, silent)
+Job_Touch(gn, silent)
GNode *gn; /* the node of the file to touch */
Boolean silent; /* TRUE if should not print messages */
{
int streamID; /* ID of stream opened to do the touch */
- struct timeval times[2]; /* Times for utimes() call */
+ struct utimbuf times; /* Times for utime() call */
if (gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_OPTIONAL)) {
/*
@@ -851,9 +1027,10 @@ Job_Touch (gn, silent)
*/
return;
}
-
+
if (!silent) {
- printf ("touch %s\n", gn->name);
+ (void) fprintf(stdout, "touch %s\n", gn->name);
+ (void) fflush(stdout);
}
if (noExecute) {
@@ -861,16 +1038,15 @@ Job_Touch (gn, silent)
}
if (gn->type & OP_ARCHV) {
- Arch_Touch (gn);
+ Arch_Touch(gn);
} else if (gn->type & OP_LIB) {
- Arch_TouchLib (gn);
+ Arch_TouchLib(gn);
} else {
char *file = gn->path ? gn->path : gn->name;
- times[0].tv_sec = times[1].tv_sec = now;
- times[0].tv_usec = times[1].tv_usec = 0;
- if (utimes(file, times) < 0){
- streamID = open (file, O_RDWR | O_CREAT, 0666);
+ times.actime = times.modtime = now;
+ if (utime(file, &times) < 0){
+ streamID = open(file, O_RDWR | O_CREAT, 0666);
if (streamID >= 0) {
char c;
@@ -880,13 +1056,16 @@ Job_Touch (gn, silent)
* modification time, then close the file.
*/
if (read(streamID, &c, 1) == 1) {
- lseek(streamID, 0L, L_SET);
- write(streamID, &c, 1);
+ (void) lseek(streamID, 0L, L_SET);
+ (void) write(streamID, &c, 1);
}
-
- (void)close (streamID);
- } else
- printf("*** couldn't touch %s: %s", file, strerror(errno));
+
+ (void) close(streamID);
+ } else {
+ (void) fprintf(stdout, "*** couldn't touch %s: %s",
+ file, strerror(errno));
+ (void) fflush(stdout);
+ }
}
}
}
@@ -894,7 +1073,7 @@ Job_Touch (gn, silent)
/*-
*-----------------------------------------------------------------------
* Job_CheckCommands --
- * Make sure the given node has all the commands it needs.
+ * Make sure the given node has all the commands it needs.
*
* Results:
* TRUE if the commands list is/was ok.
@@ -905,17 +1084,17 @@ Job_Touch (gn, silent)
*-----------------------------------------------------------------------
*/
Boolean
-Job_CheckCommands (gn, abortProc)
+Job_CheckCommands(gn, abortProc)
GNode *gn; /* The target whose commands need
* verifying */
- void (*abortProc) __P((char *, ...));
+ void (*abortProc) __P((char *, ...));
/* Function to abort with message */
{
- if (OP_NOP(gn->type) && Lst_IsEmpty (gn->commands) &&
+ if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands) &&
(gn->type & OP_LIB) == 0) {
/*
* No commands. Look for .DEFAULT rule from which we might infer
- * commands
+ * commands
*/
if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) {
char *p1;
@@ -929,32 +1108,33 @@ Job_CheckCommands (gn, abortProc)
* .DEFAULT itself.
*/
Make_HandleUse(DEFAULT, gn);
- Var_Set (IMPSRC, Var_Value (TARGET, gn, &p1), gn);
+ Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn);
if (p1)
free(p1);
- } else if (Dir_MTime (gn) == 0) {
+ } else if (Dir_MTime(gn) == 0) {
/*
* The node wasn't the target of an operator we have no .DEFAULT
* rule to go on and the target doesn't already exist. There's
* nothing more we can do for this branch. If the -k flag wasn't
* given, we stop in our tracks, otherwise we just don't update
- * this node's parents so they never get examined.
+ * this node's parents so they never get examined.
*/
+ static const char msg[] = "make: don't know how to make";
+
if (gn->type & OP_OPTIONAL) {
- printf ("make: don't know how to make %s (ignored)\n",
- gn->name);
+ (void) fprintf(stdout, "%s %s(ignored)\n", msg, gn->name);
+ (void) fflush(stdout);
} else if (keepgoing) {
- printf ("make: don't know how to make %s (continuing)\n",
- gn->name);
- return (FALSE);
+ (void) fprintf(stdout, "%s %s(continuing)\n", msg, gn->name);
+ (void) fflush(stdout);
+ return FALSE;
} else {
- (*abortProc) ("make: don't know how to make %s. Stop",
- gn->name);
- return(FALSE);
+ (*abortProc)("%s %s. Stop", msg, gn->name);
+ return FALSE;
}
}
}
- return (TRUE);
+ return TRUE;
}
#ifdef RMT_WILL_WATCH
/*-
@@ -967,7 +1147,7 @@ Job_CheckCommands (gn, abortProc)
*
* Side Effects:
* JobDoOutput is called.
- *
+ *
*-----------------------------------------------------------------------
*/
/*ARGSUSED*/
@@ -1001,19 +1181,20 @@ JobExec(job, argv)
char **argv;
{
int cpid; /* ID of new child */
-
+
if (DEBUG(JOB)) {
int i;
-
- printf("Running %s %sly\n", job->node->name,
- job->flags&JOB_REMOTE?"remote":"local");
- printf("\tCommand: ");
- for (i = 0; argv[i] != (char *)NULL; i++) {
- printf("%s ", argv[i]);
+
+ (void) fprintf(stdout, "Running %s %sly\n", job->node->name,
+ job->flags&JOB_REMOTE?"remote":"local");
+ (void) fprintf(stdout, "\tCommand: ");
+ for (i = 0; argv[i] != NULL; i++) {
+ (void) fprintf(stdout, "%s ", argv[i]);
}
- printf("\n");
+ (void) fprintf(stdout, "\n");
+ (void) fflush(stdout);
}
-
+
/*
* Some jobs produce no output and it's disconcerting to have
* no feedback of their running (since they produce no output, the
@@ -1021,20 +1202,19 @@ JobExec(job, argv)
* provide that feedback, even if nothing follows it.
*/
if ((lastNode != job->node) && (job->flags & JOB_FIRST) &&
- !(job->flags & JOB_SILENT))
- {
- printf(targFmt, job->node->name);
+ !(job->flags & JOB_SILENT)) {
+ MESSAGE(stdout, job->node);
lastNode = job->node;
}
-
+
#ifdef RMT_NO_EXEC
if (job->flags & JOB_REMOTE) {
goto jobExecFinish;
}
#endif /* RMT_NO_EXEC */
- if ((cpid = vfork()) == -1) {
- Punt ("Cannot fork");
+ if ((cpid = vfork()) == -1) {
+ Punt("Cannot fork");
} else if (cpid == 0) {
/*
@@ -1042,23 +1222,26 @@ JobExec(job, argv)
* reset it to the beginning (again). Since the stream was marked
* close-on-exec, we must clear that bit in the new input.
*/
- (void) dup2(fileno(job->cmdFILE), 0);
- fcntl(0, F_SETFD, 0);
- lseek(0, 0, L_SET);
-
+ if (dup2(FILENO(job->cmdFILE), 0) == -1)
+ Punt("Cannot dup2: %s", strerror(errno));
+ (void) fcntl(0, F_SETFD, 0);
+ (void) lseek(0, 0, L_SET);
+
if (usePipes) {
/*
* Set up the child's output to be routed through the pipe
* we've created for it.
*/
- (void) dup2 (job->outPipe, 1);
+ if (dup2(job->outPipe, 1) == -1)
+ Punt("Cannot dup2: %s", strerror(errno));
} else {
/*
* We're capturing output in a file, so we duplicate the
* descriptor to the temporary file into the standard
* output.
*/
- (void) dup2 (job->outFd, 1);
+ if (dup2(job->outFd, 1) == -1)
+ Punt("Cannot dup2: %s", strerror(errno));
}
/*
* The output channels are marked close on exec. This bit was
@@ -1066,8 +1249,9 @@ JobExec(job, argv)
* it before routing the shell's error output to the same place as
* its standard output.
*/
- fcntl(1, F_SETFD, 0);
- (void) dup2 (1, 2);
+ (void) fcntl(1, F_SETFD, 0);
+ if (dup2(1, 2) == -1)
+ Punt("Cannot dup2: %s", strerror(errno));
#ifdef USE_PGRP
/*
@@ -1075,15 +1259,27 @@ JobExec(job, argv)
* we can kill it and all its descendants in one fell swoop,
* by killing its process family, but not commit suicide.
*/
-
- (void) setpgrp(0, getpid());
-#endif USE_PGRP
-
- (void) execv (shellPath, argv);
- (void) write (2, "Could not execute shell\n",
- sizeof ("Could not execute shell"));
- _exit (1);
+# if defined(SYSV)
+ (void) setsid();
+# else
+ (void) setpgid(0, getpid());
+# endif
+#endif /* USE_PGRP */
+
+#ifdef REMOTE
+ if (job->flags & JOB_REMOTE) {
+ Rmt_Exec(shellPath, argv, FALSE);
+ } else
+#endif /* REMOTE */
+ (void) execv(shellPath, argv);
+
+ (void) write(2, "Could not execute shell\n",
+ sizeof("Could not execute shell"));
+ _exit(1);
} else {
+#ifdef REMOTE
+ long omask = sigblock(sigmask(SIGCHLD));
+#endif
job->pid = cpid;
if (usePipes && (job->flags & JOB_FIRST) ) {
@@ -1093,7 +1289,7 @@ JobExec(job, argv)
* stream to watch in the outputs mask
*/
job->curPos = 0;
-
+
#ifdef RMT_WILL_WATCH
Rmt_Watch(job->inPipe, JobLocalInput, job);
#else
@@ -1102,27 +1298,34 @@ JobExec(job, argv)
}
if (job->flags & JOB_REMOTE) {
+#ifndef REMOTE
job->rmtID = 0;
+#else
+ job->rmtID = Rmt_LastID(job->pid);
+#endif /* REMOTE */
} else {
nLocal += 1;
/*
- * XXX: Used to not happen if CUSTOMS. Why?
+ * XXX: Used to not happen if REMOTE. Why?
*/
- if (job->cmdFILE != stdout) {
- fclose(job->cmdFILE);
+ if (job->cmdFILE != NULL && job->cmdFILE != stdout) {
+ (void) fclose(job->cmdFILE);
job->cmdFILE = NULL;
}
}
+#ifdef REMOTE
+ (void) sigsetmask(omask);
+#endif
}
#ifdef RMT_NO_EXEC
-jobExecFinish:
+jobExecFinish:
#endif
/*
* Now the job is actually running, add it to the table.
*/
nJobs += 1;
- (void)Lst_AtEnd (jobs, (ClientData)job);
+ (void) Lst_AtEnd(jobs, (ClientData)job);
if (nJobs == maxJobs) {
jobFull = TRUE;
}
@@ -1132,7 +1335,7 @@ jobExecFinish:
*-----------------------------------------------------------------------
* JobMakeArgv --
* Create the argv needed to execute the shell for a given job.
- *
+ *
*
* Results:
*
@@ -1147,7 +1350,7 @@ JobMakeArgv(job, argv)
{
int argc;
static char args[10]; /* For merged arguments */
-
+
argv[0] = shellName;
argc = 1;
@@ -1180,13 +1383,13 @@ JobMakeArgv(job, argv)
argc++;
}
}
- argv[argc] = (char *)NULL;
+ argv[argc] = NULL;
}
/*-
*-----------------------------------------------------------------------
* JobRestart --
- * Restart a job that stopped for some reason.
+ * Restart a job that stopped for some reason.
*
* Results:
* None.
@@ -1200,44 +1403,91 @@ static void
JobRestart(job)
Job *job; /* Job to restart */
{
+#ifdef REMOTE
+ int host;
+#endif
+
if (job->flags & JOB_REMIGRATE) {
- if (DEBUG(JOB)) {
- printf("Remigrating %x\n", job->pid);
+ if (
+#ifdef REMOTE
+ verboseRemigrates ||
+#endif
+ DEBUG(JOB)) {
+ (void) fprintf(stdout, "*** remigrating %x(%s)\n",
+ job->pid, job->node->name);
+ (void) fflush(stdout);
}
- if (nLocal != maxLocal) {
+
+#ifdef REMOTE
+ if (!Rmt_ReExport(job->pid, job->node, &host)) {
+ if (verboseRemigrates || DEBUG(JOB)) {
+ (void) fprintf(stdout, "*** couldn't migrate...\n");
+ (void) fflush(stdout);
+ }
+#endif
+ if (nLocal != maxLocal) {
/*
* Job cannot be remigrated, but there's room on the local
* machine, so resume the job and note that another
* local job has started.
*/
- if (DEBUG(JOB)) {
- printf("resuming on local machine\n");
- }
+ if (
+#ifdef REMOTE
+ verboseRemigrates ||
+#endif
+ DEBUG(JOB)) {
+ (void) fprintf(stdout, "*** resuming on local machine\n");
+ (void) fflush(stdout);
+ }
KILL(job->pid, SIGCONT);
nLocal +=1;
+#ifdef REMOTE
+ job->flags &= ~(JOB_REMIGRATE|JOB_RESUME|JOB_REMOTE);
+ job->flags |= JOB_CONTINUING;
+#else
job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
+#endif
} else {
/*
* Job cannot be restarted. Mark the table as full and
* place the job back on the list of stopped jobs.
*/
- if (DEBUG(JOB)) {
- printf("holding\n");
- }
+ if (
+#ifdef REMOTE
+ verboseRemigrates ||
+#endif
+ DEBUG(JOB)) {
+ (void) fprintf(stdout, "*** holding\n");
+ (void) fflush(stdout);
+ }
(void)Lst_AtFront(stoppedJobs, (ClientData)job);
jobFull = TRUE;
if (DEBUG(JOB)) {
- printf("Job queue is full.\n");
+ (void) fprintf(stdout, "Job queue is full.\n");
+ (void) fflush(stdout);
}
return;
+ }
+#ifdef REMOTE
+ } else {
+ /*
+ * Clear out the remigrate and resume flags. Set the continuing
+ * flag so we know later on that the process isn't exiting just
+ * because of a signal.
+ */
+ job->flags &= ~(JOB_REMIGRATE|JOB_RESUME);
+ job->flags |= JOB_CONTINUING;
+ job->rmtID = host;
}
-
+#endif
+
(void)Lst_AtEnd(jobs, (ClientData)job);
nJobs += 1;
if (nJobs == maxJobs) {
jobFull = TRUE;
if (DEBUG(JOB)) {
- printf("Job queue is full.\n");
+ (void) fprintf(stdout, "Job queue is full.\n");
+ (void) fflush(stdout);
}
}
} else if (job->flags & JOB_RESTART) {
@@ -1247,38 +1497,65 @@ JobRestart(job)
* the 'exit' flag of the commandShell is used to cause it to exit
* upon receiving an error. If the JOB_SILENT flag is clear, the
* 'echo' flag of the commandShell is used to get it to start echoing
- * as soon as it starts processing commands.
+ * as soon as it starts processing commands.
*/
char *argv[4];
-
+
JobMakeArgv(job, argv);
-
+
if (DEBUG(JOB)) {
- printf("Restarting %s...", job->node->name);
+ (void) fprintf(stdout, "Restarting %s...", job->node->name);
+ (void) fflush(stdout);
}
- if (((nLocal >= maxLocal) && ! (job->flags & JOB_SPECIAL))) {
+#ifdef REMOTE
+ if ((job->node->type&OP_NOEXPORT) ||
+ (nLocal < maxLocal && runLocalFirst)
+# ifdef RMT_NO_EXEC
+ || !Rmt_Export(shellPath, argv, job)
+# else
+ || !Rmt_Begin(shellPath, argv, job->node)
+# endif
+#endif
+ {
+ if (((nLocal >= maxLocal) && !(job->flags & JOB_SPECIAL))) {
/*
* Can't be exported and not allowed to run locally -- put it
* back on the hold queue and mark the table full
*/
if (DEBUG(JOB)) {
- printf("holding\n");
+ (void) fprintf(stdout, "holding\n");
+ (void) fflush(stdout);
}
(void)Lst_AtFront(stoppedJobs, (ClientData)job);
jobFull = TRUE;
if (DEBUG(JOB)) {
- printf("Job queue is full.\n");
+ (void) fprintf(stdout, "Job queue is full.\n");
+ (void) fflush(stdout);
}
return;
- } else {
+ } else {
/*
* Job may be run locally.
*/
if (DEBUG(JOB)) {
- printf("running locally\n");
+ (void) fprintf(stdout, "running locally\n");
+ (void) fflush(stdout);
}
job->flags &= ~JOB_REMOTE;
+ }
}
+#ifdef REMOTE
+ else {
+ /*
+ * Can be exported. Hooray!
+ */
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout, "exporting\n");
+ (void) fflush(stdout);
+ }
+ job->flags |= JOB_REMOTE;
+ }
+#endif
JobExec(job, argv);
} else {
/*
@@ -1286,13 +1563,20 @@ JobRestart(job)
* we don't know...
*/
if (DEBUG(JOB)) {
- printf("Resuming %s...", job->node->name);
+ (void) fprintf(stdout, "Resuming %s...", job->node->name);
+ (void) fflush(stdout);
}
if (((job->flags & JOB_REMOTE) ||
- (nLocal < maxLocal) ||
- (((job->flags & JOB_SPECIAL)) &&
- (maxLocal == 0))) &&
- (nJobs != maxJobs))
+ (nLocal < maxLocal) ||
+#ifdef REMOTE
+ (((job->flags & JOB_SPECIAL) &&
+ (job->node->type & OP_NOEXPORT)) &&
+ (maxLocal == 0))) &&
+#else
+ ((job->flags & JOB_SPECIAL) &&
+ (maxLocal == 0))) &&
+#endif
+ (nJobs != maxJobs))
{
/*
* If the job is remote, it's ok to resume it as long as the
@@ -1303,8 +1587,8 @@ JobRestart(job)
*/
Boolean error;
extern int errno;
- union wait status;
-
+ int status;
+
#ifdef RMT_WANTS_SIGNALS
if (job->flags & JOB_REMOTE) {
error = !Rmt_Signal(job, SIGCONT);
@@ -1318,19 +1602,20 @@ JobRestart(job)
* actually put the thing in the job table.
*/
job->flags |= JOB_CONTINUING;
- status.w_termsig = SIGCONT;
- JobFinish(job, status);
-
+ W_SETTERMSIG(&status, SIGCONT);
+ JobFinish(job, &status);
+
job->flags &= ~(JOB_RESUME|JOB_CONTINUING);
if (DEBUG(JOB)) {
- printf("done\n");
+ (void) fprintf(stdout, "done\n");
+ (void) fflush(stdout);
}
} else {
Error("couldn't resume %s: %s",
job->node->name, strerror(errno));
- status.w_status = 0;
- status.w_retcode = 1;
- JobFinish(job, status);
+ status = 0;
+ W_SETEXITSTATUS(&status, 1);
+ JobFinish(job, &status);
}
} else {
/*
@@ -1338,12 +1623,14 @@ JobRestart(job)
* place the job back on the list of stopped jobs.
*/
if (DEBUG(JOB)) {
- printf("table full\n");
+ (void) fprintf(stdout, "table full\n");
+ (void) fflush(stdout);
}
- (void)Lst_AtFront(stoppedJobs, (ClientData)job);
+ (void) Lst_AtFront(stoppedJobs, (ClientData)job);
jobFull = TRUE;
if (DEBUG(JOB)) {
- printf("Job queue is full.\n");
+ (void) fprintf(stdout, "Job queue is full.\n");
+ (void) fflush(stdout);
}
}
}
@@ -1353,7 +1640,7 @@ JobRestart(job)
*-----------------------------------------------------------------------
* JobStart --
* Start a target-creation process going for the target described
- * by the graph node gn.
+ * by the graph node gn.
*
* Results:
* JOB_ERROR if there was an error in the commands, JOB_FINISHED
@@ -1366,7 +1653,7 @@ JobRestart(job)
*-----------------------------------------------------------------------
*/
static int
-JobStart (gn, flags, previous)
+JobStart(gn, flags, previous)
GNode *gn; /* target to create */
int flags; /* flags for the job to override normal ones.
* e.g. JOB_SPECIAL or JOB_IGNDOTS */
@@ -1380,12 +1667,12 @@ JobStart (gn, flags, previous)
Boolean local; /* Set true if the job was run locally */
Boolean noExec; /* Set true if we decide not to run the job */
- if (previous != (Job *)NULL) {
- previous->flags &= ~ (JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE);
+ if (previous != NULL) {
+ previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE);
job = previous;
} else {
- job = (Job *) emalloc (sizeof (Job));
- if (job == (Job *)NULL) {
+ job = (Job *) emalloc(sizeof(Job));
+ if (job == NULL) {
Punt("JobStart out of memory");
}
flags |= JOB_FIRST;
@@ -1400,10 +1687,10 @@ JobStart (gn, flags, previous)
* are also added to the field.
*/
job->flags = 0;
- if (Targ_Ignore (gn)) {
+ if (Targ_Ignore(gn)) {
job->flags |= JOB_IGNERR;
}
- if (Targ_Silent (gn)) {
+ if (Targ_Silent(gn)) {
job->flags |= JOB_SILENT;
}
job->flags |= flags;
@@ -1412,12 +1699,12 @@ JobStart (gn, flags, previous)
* Check the commands now so any attributes from .DEFAULT have a chance
* to migrate to the node
*/
- if (job->flags & JOB_FIRST) {
+ if (!compatMake && job->flags & JOB_FIRST) {
cmdsOK = Job_CheckCommands(gn, Error);
} else {
cmdsOK = TRUE;
}
-
+
/*
* If the -n flag wasn't given, we open up OUR (not the child's)
* temporary file to stuff commands in it. The thing is rd/wr so we don't
@@ -1432,12 +1719,12 @@ JobStart (gn, flags, previous)
if (!cmdsOK) {
DieHorribly();
}
-
- job->cmdFILE = fopen (tfile, "w+");
- if (job->cmdFILE == (FILE *) NULL) {
- Punt ("Could not open %s", tfile);
+
+ job->cmdFILE = fopen(tfile, "w+");
+ if (job->cmdFILE == NULL) {
+ Punt("Could not open %s", tfile);
}
- fcntl(fileno(job->cmdFILE), F_SETFD, 1);
+ (void) fcntl(FILENO(job->cmdFILE), F_SETFD, 1);
/*
* Send the commands to the command file, flush all its buffers then
* rewind and remove the thing.
@@ -1460,13 +1747,14 @@ JobStart (gn, flags, previous)
if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){
cmdsOK = FALSE;
} else {
- LstNode ln = Lst_Next (gn->commands);
-
+ LstNode ln = Lst_Next(gn->commands);
+
if ((ln == NILLNODE) ||
- JobPrintCommand ((char *)Lst_Datum (ln), job))
+ JobPrintCommand((ClientData) Lst_Datum(ln),
+ (ClientData) job))
{
noExec = TRUE;
- Lst_Close (gn->commands);
+ Lst_Close(gn->commands);
}
if (noExec && !(job->flags & JOB_FIRST)) {
/*
@@ -1480,21 +1768,7 @@ JobStart (gn, flags, previous)
* Job_CatchChildren b/c it wasn't clear if there were
* more commands to execute or not...
*/
- if (usePipes) {
-#ifdef RMT_WILL_WATCH
- Rmt_Ignore(job->inPipe);
-#else
- FD_CLR(job->inPipe, &outputs);
-#endif
- if (job->outPipe != job->inPipe) {
- (void)close (job->outPipe);
- }
- JobDoOutput (job, TRUE);
- (void)close (job->inPipe);
- } else {
- (void)close (job->outFd);
- JobDoOutput (job, TRUE);
- }
+ JobClose(job);
}
}
} else {
@@ -1502,8 +1776,8 @@ JobStart (gn, flags, previous)
* We can do all the commands at once. hooray for sanity
*/
numCommands = 0;
- Lst_ForEach (gn->commands, JobPrintCommand, (ClientData)job);
-
+ Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job);
+
/*
* If we didn't print out any commands to the shell script,
* there's not much point in executing the shell, is there?
@@ -1518,7 +1792,7 @@ JobStart (gn, flags, previous)
* in one fell swoop. This will still set up job->tailCmds correctly.
*/
if (lastNode != gn) {
- printf (targFmt, gn->name);
+ MESSAGE(stdout, gn);
lastNode = gn;
}
job->cmdFILE = stdout;
@@ -1542,22 +1816,23 @@ JobStart (gn, flags, previous)
* up the graph.
*/
job->cmdFILE = stdout;
- Job_Touch (gn, job->flags&JOB_SILENT);
+ Job_Touch(gn, job->flags&JOB_SILENT);
noExec = TRUE;
}
/*
- * If we're not supposed to execute a shell, don't.
+ * If we're not supposed to execute a shell, don't.
*/
if (noExec) {
/*
* Unlink and close the command file if we opened one
*/
if (job->cmdFILE != stdout) {
- (void) unlink (tfile);
- fclose(job->cmdFILE);
+ (void) eunlink(tfile);
+ if (job->cmdFILE != NULL)
+ (void) fclose(job->cmdFILE);
} else {
- fflush (stdout);
+ (void) fflush(stdout);
}
/*
@@ -1569,7 +1844,7 @@ JobStart (gn, flags, previous)
if (job->tailCmds != NILLNODE) {
Lst_ForEachFrom(job->node->commands, job->tailCmds,
JobSaveCommand,
- (ClientData)job->node);
+ (ClientData)job->node);
}
Make_Update(job->node);
}
@@ -1580,8 +1855,8 @@ JobStart (gn, flags, previous)
return(JOB_ERROR);
}
} else {
- fflush (job->cmdFILE);
- (void) unlink (tfile);
+ (void) fflush(job->cmdFILE);
+ (void) eunlink(tfile);
}
/*
@@ -1596,29 +1871,47 @@ JobStart (gn, flags, previous)
* starting a job and then set up its temporary-file name. This is just
* tfile with two extra digits tacked on -- jobno.
*/
- if (job->flags & JOB_FIRST) {
+ if (!compatMake || (job->flags & JOB_FIRST)) {
if (usePipes) {
int fd[2];
- (void) pipe(fd);
+ if (pipe(fd) == -1)
+ Punt("Cannot create pipe: %s", strerror(errno));
job->inPipe = fd[0];
job->outPipe = fd[1];
- (void)fcntl (job->inPipe, F_SETFD, 1);
- (void)fcntl (job->outPipe, F_SETFD, 1);
+ (void) fcntl(job->inPipe, F_SETFD, 1);
+ (void) fcntl(job->outPipe, F_SETFD, 1);
} else {
- printf ("Remaking `%s'\n", gn->name);
- fflush (stdout);
- sprintf (job->outFile, "%s%02d", tfile, jobno);
+ (void) fprintf(stdout, "Remaking `%s'\n", gn->name);
+ (void) fflush(stdout);
+ sprintf(job->outFile, "%s%02d", tfile, jobno);
jobno = (jobno + 1) % 100;
job->outFd = open(job->outFile,O_WRONLY|O_CREAT|O_APPEND,0600);
- (void)fcntl (job->outFd, F_SETFD, 1);
+ (void) fcntl(job->outFd, F_SETFD, 1);
}
}
- local = TRUE;
+#ifdef REMOTE
+ if (!(gn->type & OP_NOEXPORT) && !(runLocalFirst && nLocal < maxLocal)) {
+#ifdef RMT_NO_EXEC
+ local = !Rmt_Export(shellPath, argv, job);
+#else
+ local = !Rmt_Begin(shellPath, argv, job->node);
+#endif /* RMT_NO_EXEC */
+ if (!local) {
+ job->flags |= JOB_REMOTE;
+ }
+ } else
+#endif
+ local = TRUE;
if (local && (((nLocal >= maxLocal) &&
- !(job->flags & JOB_SPECIAL) &&
- (maxLocal != 0))))
+ !(job->flags & JOB_SPECIAL) &&
+#ifdef REMOTE
+ (!(gn->type & OP_NOEXPORT) || (maxLocal != 0))
+#else
+ (maxLocal != 0)
+#endif
+ )))
{
/*
* The job can only be run locally, but we've hit the limit of
@@ -1626,15 +1919,17 @@ JobStart (gn, flags, previous)
* finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END)
* may be run locally even when the local limit has been reached
* (e.g. when maxLocal == 0), though they will be exported if at
- * all possible.
+ * all possible. In addition, any target marked with .NOEXPORT will
+ * be run locally if maxLocal is 0.
*/
jobFull = TRUE;
-
+
if (DEBUG(JOB)) {
- printf("Can only run job locally.\n");
+ (void) fprintf(stdout, "Can only run job locally.\n");
+ (void) fflush(stdout);
}
job->flags |= JOB_RESTART;
- (void)Lst_AtEnd(stoppedJobs, (ClientData)job);
+ (void) Lst_AtEnd(stoppedJobs, (ClientData)job);
} else {
if ((nLocal >= maxLocal) && local) {
/*
@@ -1643,7 +1938,8 @@ JobStart (gn, flags, previous)
*/
jobFull = TRUE;
if (DEBUG(JOB)) {
- printf("Local job queue is full.\n");
+ (void) fprintf(stdout, "Local job queue is full.\n");
+ (void) fflush(stdout);
}
}
JobExec(job, argv);
@@ -1651,6 +1947,52 @@ JobStart (gn, flags, previous)
return(JOB_RUNNING);
}
+static char *
+JobOutput(job, cp, endp, msg)
+ register Job *job;
+ register char *cp, *endp;
+ int msg;
+{
+ register char *ecp;
+
+ if (commandShell->noPrint) {
+ ecp = Str_FindSubstring(cp, commandShell->noPrint);
+ while (ecp != NULL) {
+ if (cp != ecp) {
+ *ecp = '\0';
+ if (msg && job->node != lastNode) {
+ MESSAGE(stdout, job->node);
+ lastNode = job->node;
+ }
+ /*
+ * The only way there wouldn't be a newline after
+ * this line is if it were the last in the buffer.
+ * however, since the non-printable comes after it,
+ * there must be a newline, so we don't print one.
+ */
+ (void) fprintf(stdout, "%s", cp);
+ (void) fflush(stdout);
+ }
+ cp = ecp + commandShell->noPLen;
+ if (cp != endp) {
+ /*
+ * Still more to print, look again after skipping
+ * the whitespace following the non-printable
+ * command....
+ */
+ cp++;
+ while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
+ cp++;
+ }
+ ecp = Str_FindSubstring(cp, commandShell->noPrint);
+ } else {
+ return cp;
+ }
+ }
+ }
+ return cp;
+}
+
/*-
*-----------------------------------------------------------------------
* JobDoOutput --
@@ -1678,13 +2020,14 @@ JobStart (gn, flags, previous)
* curPos may be shifted as may the contents of outBuf.
*-----------------------------------------------------------------------
*/
-static void
-JobDoOutput (job, finish)
+STATIC void
+JobDoOutput(job, finish)
register Job *job; /* the job whose output needs printing */
Boolean finish; /* TRUE if this is the last time we'll be
* called for this job */
{
Boolean gotNL = FALSE; /* true if got a newline */
+ Boolean fbuf; /* true if our buffer filled up */
register int nr; /* number of bytes read */
register int i; /* auxiliary index into outBuf */
register int max; /* limit for i (end of current data) */
@@ -1693,14 +2036,16 @@ JobDoOutput (job, finish)
FILE *oFILE; /* Stream pointer to shell's output file */
char inLine[132];
-
+
if (usePipes) {
/*
* Read as many bytes as will fit in the buffer.
*/
end_loop:
-
- nRead = read (job->inPipe, &job->outBuf[job->curPos],
+ gotNL = FALSE;
+ fbuf = FALSE;
+
+ nRead = read(job->inPipe, &job->outBuf[job->curPos],
JOB_BUFSIZE - job->curPos);
if (nRead < 0) {
if (DEBUG(JOB)) {
@@ -1724,11 +2069,11 @@ end_loop:
} else if (nr == 0) {
finish = FALSE;
}
-
+
/*
* Look for the last newline in the bytes we just got. If there is
* one, break out of the loop with 'i' as its index and gotNL set
- * TRUE.
+ * TRUE.
*/
max = job->curPos + nr;
for (i = job->curPos + nr - 1; i >= job->curPos; i--) {
@@ -1742,19 +2087,19 @@ end_loop:
job->outBuf[i] = ' ';
}
}
-
+
if (!gotNL) {
job->curPos += nr;
if (job->curPos == JOB_BUFSIZE) {
/*
* If we've run out of buffer space, we have no choice
- * but to print the stuff. sigh.
+ * but to print the stuff. sigh.
*/
- gotNL = TRUE;
+ fbuf = TRUE;
i = job->curPos;
}
}
- if (gotNL) {
+ if (gotNL || fbuf) {
/*
* Need to send the output to the screen. Null terminate it
* first, overwriting the newline character if there was one.
@@ -1763,49 +2108,13 @@ end_loop:
* by a target banner if this target isn't the same as the
* one for which we last printed something.
* The rest of the data in the buffer are then shifted down
- * to the start of the buffer and curPos is set accordingly.
+ * to the start of the buffer and curPos is set accordingly.
*/
job->outBuf[i] = '\0';
if (i >= job->curPos) {
- register char *cp, *ecp;
-
- cp = job->outBuf;
- if (commandShell->noPrint) {
- ecp = Str_FindSubstring(job->outBuf,
- commandShell->noPrint);
- while (ecp != (char *)NULL) {
- if (cp != ecp) {
- *ecp = '\0';
- if (job->node != lastNode) {
- printf (targFmt, job->node->name);
- lastNode = job->node;
- }
- /*
- * The only way there wouldn't be a newline after
- * this line is if it were the last in the buffer.
- * however, since the non-printable comes after it,
- * there must be a newline, so we don't print one.
- */
- printf ("%s", cp);
- }
- cp = ecp + commandShell->noPLen;
- if (cp != &job->outBuf[i]) {
- /*
- * Still more to print, look again after skipping
- * the whitespace following the non-printable
- * command....
- */
- cp++;
- while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
- cp++;
- }
- ecp = Str_FindSubstring (cp,
- commandShell->noPrint);
- } else {
- break;
- }
- }
- }
+ char *cp;
+
+ cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE);
/*
* There's still more in that thar buffer. This time, though,
@@ -1814,19 +2123,18 @@ end_loop:
*/
if (*cp != '\0') {
if (job->node != lastNode) {
- printf (targFmt, job->node->name);
+ MESSAGE(stdout, job->node);
lastNode = job->node;
}
- printf ("%s\n", cp);
+ (void) fprintf(stdout, "%s%s", cp, gotNL ? "\n" : "");
+ (void) fflush(stdout);
}
-
- fflush (stdout);
}
if (i < max - 1) {
/* shift the remaining characters down */
- memcpy ( job->outBuf, &job->outBuf[i + 1], max - (i + 1));
+ (void) memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1));
job->curPos = max - (i + 1);
-
+
} else {
/*
* We have written everything out, so we just start over
@@ -1838,10 +2146,11 @@ end_loop:
if (finish) {
/*
* If the finish flag is true, we must loop until we hit
- * end-of-file on the pipe. This is guaranteed to happen eventually
- * since the other end of the pipe is now closed (we closed it
- * explicitly and the child has exited). When we do get an EOF,
- * finish will be set FALSE and we'll fall through and out.
+ * end-of-file on the pipe. This is guaranteed to happen
+ * eventually since the other end of the pipe is now closed
+ * (we closed it explicitly and the child has exited). When
+ * we do get an EOF, finish will be set FALSE and we'll fall
+ * through and out.
*/
goto end_loop;
}
@@ -1856,62 +2165,36 @@ end_loop:
* Change to read in blocks and do FindSubString type things as for
* pipes? That would allow for "@echo -n..."
*/
- oFILE = fopen (job->outFile, "r");
- if (oFILE != (FILE *) NULL) {
- printf ("Results of making %s:\n", job->node->name);
- while (fgets (inLine, sizeof(inLine), oFILE) != NULL) {
- register char *cp, *ecp, *endp;
+ oFILE = fopen(job->outFile, "r");
+ if (oFILE != NULL) {
+ (void) fprintf(stdout, "Results of making %s:\n", job->node->name);
+ (void) fflush(stdout);
+ while (fgets(inLine, sizeof(inLine), oFILE) != NULL) {
+ register char *cp, *endp, *oendp;
cp = inLine;
- endp = inLine + strlen(inLine);
+ oendp = endp = inLine + strlen(inLine);
if (endp[-1] == '\n') {
*--endp = '\0';
}
- if (commandShell->noPrint) {
- ecp = Str_FindSubstring(cp, commandShell->noPrint);
- while (ecp != (char *)NULL) {
- if (cp != ecp) {
- *ecp = '\0';
- /*
- * The only way there wouldn't be a newline after
- * this line is if it were the last in the buffer.
- * however, since the non-printable comes after it,
- * there must be a newline, so we don't print one.
- */
- printf ("%s", cp);
- }
- cp = ecp + commandShell->noPLen;
- if (cp != endp) {
- /*
- * Still more to print, look again after skipping
- * the whitespace following the non-printable
- * command....
- */
- cp++;
- while (*cp == ' ' || *cp == '\t' || *cp == '\n') {
- cp++;
- }
- ecp = Str_FindSubstring(cp, commandShell->noPrint);
- } else {
- break;
- }
- }
- }
+ cp = JobOutput(job, inLine, endp, FALSE);
/*
* There's still more in that thar buffer. This time, though,
* we know there's no newline at the end, so we add one of
* our own free will.
*/
- if (*cp != '\0') {
- printf ("%s\n", cp);
+ (void) fprintf(stdout, "%s", cp);
+ (void) fflush(stdout);
+ if (endp != oendp) {
+ (void) fprintf(stdout, "\n");
+ (void) fflush(stdout);
}
}
- fclose (oFILE);
- (void) unlink (job->outFile);
+ (void) fclose(oFILE);
+ (void) eunlink(job->outFile);
}
}
- fflush(stdout);
}
/*-
@@ -1934,13 +2217,13 @@ end_loop:
*-----------------------------------------------------------------------
*/
void
-Job_CatchChildren (block)
+Job_CatchChildren(block)
Boolean block; /* TRUE if should block on the wait. */
{
int pid; /* pid of dead child */
register Job *job; /* job descriptor for dead child */
LstNode jnode; /* list element for finding job */
- union wait status; /* Exit/termination status */
+ int status; /* Exit/termination status */
/*
* Don't even bother if we know there's no one around.
@@ -1948,41 +2231,55 @@ Job_CatchChildren (block)
if (nLocal == 0) {
return;
}
-
- while ((pid = wait3((int *)&status, (block?0:WNOHANG)|WUNTRACED,
- (struct rusage *)0)) > 0)
+
+ while ((pid = waitpid((pid_t) -1, &status,
+ (block?0:WNOHANG)|WUNTRACED)) > 0)
{
- if (DEBUG(JOB))
- printf("Process %d exited or stopped.\n", pid);
-
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout, "Process %d exited or stopped.\n", pid);
+ (void) fflush(stdout);
+ }
- jnode = Lst_Find (jobs, (ClientData)&pid, JobCmpPid);
+
+ jnode = Lst_Find(jobs, (ClientData)&pid, JobCmpPid);
if (jnode == NILLNODE) {
- if (WIFSIGNALED(status) && (status.w_termsig == SIGCONT)) {
+ if (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT)) {
jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid);
if (jnode == NILLNODE) {
Error("Resumed child (%d) not in table", pid);
continue;
}
job = (Job *)Lst_Datum(jnode);
- (void)Lst_Remove(stoppedJobs, jnode);
+ (void) Lst_Remove(stoppedJobs, jnode);
} else {
- Error ("Child (%d) not in table?", pid);
+ Error("Child (%d) not in table?", pid);
continue;
}
} else {
- job = (Job *) Lst_Datum (jnode);
- (void)Lst_Remove (jobs, jnode);
+ job = (Job *) Lst_Datum(jnode);
+ (void) Lst_Remove(jobs, jnode);
nJobs -= 1;
if (jobFull && DEBUG(JOB)) {
- printf("Job queue is no longer full.\n");
+ (void) fprintf(stdout, "Job queue is no longer full.\n");
+ (void) fflush(stdout);
}
jobFull = FALSE;
+#ifdef REMOTE
+ if (!(job->flags & JOB_REMOTE)) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "Job queue has one fewer local process.\n");
+ (void) fflush(stdout);
+ }
+ nLocal -= 1;
+ }
+#else
nLocal -= 1;
+#endif
}
- JobFinish (job, status);
+ JobFinish(job, &status);
}
}
@@ -1993,17 +2290,17 @@ Job_CatchChildren (block)
* pipes do so. Otherwise just block time until we get a
* signal (most likely a SIGCHLD) since there's no point in
* just spinning when there's nothing to do and the reaping
- * of a child can wait for a while.
+ * of a child can wait for a while.
*
* Results:
- * None
+ * None
*
* Side Effects:
* Output is read from pipes if we're piping.
* -----------------------------------------------------------------------
*/
void
-Job_CatchOutput ()
+Job_CatchOutput()
{
int nfds;
struct timeval timeout;
@@ -2014,7 +2311,7 @@ Job_CatchOutput ()
int pnJobs; /* Previous nJobs */
#endif
- fflush(stdout);
+ (void) fflush(stdout);
#ifdef RMT_WILL_WATCH
pnJobs = nJobs;
@@ -2043,21 +2340,21 @@ Job_CatchOutput ()
timeout.tv_sec = SEL_SEC;
timeout.tv_usec = SEL_USEC;
- if ((nfds = select (FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0)
- {
+ if ((nfds = select(FD_SETSIZE, &readfds, (fd_set *) 0,
+ (fd_set *) 0, &timeout)) <= 0)
return;
- } else {
- if (Lst_Open (jobs) == FAILURE) {
- Punt ("Cannot open job table");
+ else {
+ if (Lst_Open(jobs) == FAILURE) {
+ Punt("Cannot open job table");
}
- while (nfds && (ln = Lst_Next (jobs)) != NILLNODE) {
- job = (Job *) Lst_Datum (ln);
+ while (nfds && (ln = Lst_Next(jobs)) != NILLNODE) {
+ job = (Job *) Lst_Datum(ln);
if (FD_ISSET(job->inPipe, &readfds)) {
- JobDoOutput (job, FALSE);
+ JobDoOutput(job, FALSE);
nfds -= 1;
}
}
- Lst_Close (jobs);
+ Lst_Close(jobs);
}
}
#endif /* RMT_WILL_WATCH */
@@ -2078,10 +2375,10 @@ Job_CatchOutput ()
*-----------------------------------------------------------------------
*/
void
-Job_Make (gn)
+Job_Make(gn)
GNode *gn;
{
- (void)JobStart (gn, 0, (Job *)NULL);
+ (void) JobStart(gn, 0, NULL);
}
/*-
@@ -2097,7 +2394,7 @@ Job_Make (gn)
*-----------------------------------------------------------------------
*/
void
-Job_Init (maxproc, maxlocal)
+Job_Init(maxproc, maxlocal)
int maxproc; /* the greatest number of jobs which may be
* running at one time */
int maxlocal; /* the greatest number of local jobs which may
@@ -2105,9 +2402,9 @@ Job_Init (maxproc, maxlocal)
{
GNode *begin; /* node for commands to do at the very start */
- sprintf (tfile, "/tmp/make%05d", getpid());
+ (void) sprintf(tfile, "/tmp/make%05d", getpid());
- jobs = Lst_Init (FALSE);
+ jobs = Lst_Init(FALSE);
stoppedJobs = Lst_Init(FALSE);
maxJobs = maxproc;
maxLocal = maxlocal;
@@ -2120,7 +2417,11 @@ Job_Init (maxproc, maxlocal)
lastNode = NILGNODE;
- if (maxJobs == 1) {
+ if (maxJobs == 1
+#ifdef REMOTE
+ || noMessages
+#endif
+ ) {
/*
* If only one job can run at a time, there's no need for a banner,
* no is there?
@@ -2129,8 +2430,8 @@ Job_Init (maxproc, maxlocal)
} else {
targFmt = TARG_FMT;
}
-
- if (shellPath == (char *) NULL) {
+
+ if (shellPath == NULL) {
/*
* The user didn't specify a shell to use, so we are using the
* default one... Both the absolute path and the last component
@@ -2139,13 +2440,13 @@ Job_Init (maxproc, maxlocal)
* All default shells are located in _PATH_DEFSHELLDIR.
*/
shellName = commandShell->name;
- shellPath = str_concat (_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
+ shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH);
}
- if (commandShell->exit == (char *)NULL) {
+ if (commandShell->exit == NULL) {
commandShell->exit = "";
}
- if (commandShell->echo == (char *)NULL) {
+ if (commandShell->echo == NULL) {
commandShell->echo = "";
}
@@ -2153,17 +2454,17 @@ Job_Init (maxproc, maxlocal)
* Catch the four signals that POSIX specifies if they aren't ignored.
* JobPassSig will take care of calling JobInterrupt if appropriate.
*/
- if (signal (SIGINT, SIG_IGN) != SIG_IGN) {
- signal (SIGINT, JobPassSig);
+ if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
+ (void) signal(SIGINT, JobPassSig);
}
- if (signal (SIGHUP, SIG_IGN) != SIG_IGN) {
- signal (SIGHUP, JobPassSig);
+ if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
+ (void) signal(SIGHUP, JobPassSig);
}
- if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) {
- signal (SIGQUIT, JobPassSig);
+ if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
+ (void) signal(SIGQUIT, JobPassSig);
}
- if (signal (SIGTERM, SIG_IGN) != SIG_IGN) {
- signal (SIGTERM, JobPassSig);
+ if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
+ (void) signal(SIGTERM, JobPassSig);
}
/*
* There are additional signals that need to be caught and passed if
@@ -2172,32 +2473,32 @@ Job_Init (maxproc, maxlocal)
* signals from the terminal driver as we own the terminal)
*/
#if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP)
- if (signal (SIGTSTP, SIG_IGN) != SIG_IGN) {
- signal (SIGTSTP, JobPassSig);
+ if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) {
+ (void) signal(SIGTSTP, JobPassSig);
}
- if (signal (SIGTTOU, SIG_IGN) != SIG_IGN) {
- signal (SIGTTOU, JobPassSig);
+ if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) {
+ (void) signal(SIGTTOU, JobPassSig);
}
- if (signal (SIGTTIN, SIG_IGN) != SIG_IGN) {
- signal (SIGTTIN, JobPassSig);
+ if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) {
+ (void) signal(SIGTTIN, JobPassSig);
}
- if (signal (SIGWINCH, SIG_IGN) != SIG_IGN) {
- signal (SIGWINCH, JobPassSig);
+ if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) {
+ (void) signal(SIGWINCH, JobPassSig);
}
#endif
-
- begin = Targ_FindNode (".BEGIN", TARG_NOCREATE);
+
+ begin = Targ_FindNode(".BEGIN", TARG_NOCREATE);
if (begin != NILGNODE) {
- JobStart (begin, JOB_SPECIAL, (Job *)0);
+ JobStart(begin, JOB_SPECIAL, (Job *)0);
while (nJobs) {
Job_CatchOutput();
#ifndef RMT_WILL_WATCH
- Job_CatchChildren (!usePipes);
+ Job_CatchChildren(!usePipes);
#endif /* RMT_WILL_WATCH */
}
}
- postCommands = Targ_FindNode (".END", TARG_CREATE);
+ postCommands = Targ_FindNode(".END", TARG_CREATE);
}
/*-
@@ -2215,9 +2516,9 @@ Job_Init (maxproc, maxlocal)
*-----------------------------------------------------------------------
*/
Boolean
-Job_Full ()
+Job_Full()
{
- return (aborting || jobFull);
+ return(aborting || jobFull);
}
/*-
@@ -2237,7 +2538,7 @@ Job_Full ()
* -----------------------------------------------------------------------
*/
Boolean
-Job_Empty ()
+Job_Empty()
{
if (nJobs == 0) {
if (!Lst_IsEmpty(stoppedJobs) && !aborting) {
@@ -2246,9 +2547,7 @@ Job_Empty ()
* it...Try and restart the stopped jobs.
*/
jobFull = FALSE;
- while (!jobFull && !Lst_IsEmpty(stoppedJobs)) {
- JobRestart((Job *)Lst_DeQueue(stoppedJobs));
- }
+ JobRestartJobs();
return(FALSE);
} else {
return(TRUE);
@@ -2272,7 +2571,7 @@ Job_Empty ()
*-----------------------------------------------------------------------
*/
static Shell *
-JobMatchShell (name)
+JobMatchShell(name)
char *name; /* Final component of shell path */
{
register Shell *sh; /* Pointer into shells table */
@@ -2281,24 +2580,23 @@ JobMatchShell (name)
*cp2;
char *eoname;
- eoname = name + strlen (name);
+ eoname = name + strlen(name);
- match = (Shell *) NULL;
+ match = NULL;
for (sh = shells; sh->name != NULL; sh++) {
- for (cp1 = eoname - strlen (sh->name), cp2 = sh->name;
+ for (cp1 = eoname - strlen(sh->name), cp2 = sh->name;
*cp1 != '\0' && *cp1 == *cp2;
cp1++, cp2++) {
continue;
}
if (*cp1 != *cp2) {
continue;
- } else if (match == (Shell *) NULL ||
- strlen (match->name) < strlen (sh->name)) {
- match = sh;
+ } else if (match == NULL || strlen(match->name) < strlen(sh->name)) {
+ match = sh;
}
}
- return (match == (Shell *) NULL ? sh : match);
+ return(match == NULL ? sh : match);
}
/*-
@@ -2345,7 +2643,7 @@ JobMatchShell (name)
*-----------------------------------------------------------------------
*/
ReturnStatus
-Job_ParseShell (line)
+Job_ParseShell(line)
char *line; /* The shell spec */
{
char **words;
@@ -2356,64 +2654,64 @@ Job_ParseShell (line)
Shell newShell;
Boolean fullSpec = FALSE;
- while (isspace (*line)) {
+ while (isspace(*line)) {
line++;
}
- words = brk_string (line, &wordCount, TRUE);
+ words = brk_string(line, &wordCount, TRUE);
+
+ memset((Address)&newShell, 0, sizeof(newShell));
- memset ((Address)&newShell, 0, sizeof(newShell));
-
/*
* Parse the specification by keyword
*/
- for (path = (char *)NULL, argc = wordCount - 1, argv = words + 1;
+ for (path = NULL, argc = wordCount - 1, argv = words + 1;
argc != 0;
argc--, argv++) {
- if (strncmp (*argv, "path=", 5) == 0) {
+ if (strncmp(*argv, "path=", 5) == 0) {
path = &argv[0][5];
- } else if (strncmp (*argv, "name=", 5) == 0) {
+ } else if (strncmp(*argv, "name=", 5) == 0) {
newShell.name = &argv[0][5];
} else {
- if (strncmp (*argv, "quiet=", 6) == 0) {
+ if (strncmp(*argv, "quiet=", 6) == 0) {
newShell.echoOff = &argv[0][6];
- } else if (strncmp (*argv, "echo=", 5) == 0) {
+ } else if (strncmp(*argv, "echo=", 5) == 0) {
newShell.echoOn = &argv[0][5];
- } else if (strncmp (*argv, "filter=", 7) == 0) {
+ } else if (strncmp(*argv, "filter=", 7) == 0) {
newShell.noPrint = &argv[0][7];
newShell.noPLen = strlen(newShell.noPrint);
- } else if (strncmp (*argv, "echoFlag=", 9) == 0) {
+ } else if (strncmp(*argv, "echoFlag=", 9) == 0) {
newShell.echo = &argv[0][9];
- } else if (strncmp (*argv, "errFlag=", 8) == 0) {
+ } else if (strncmp(*argv, "errFlag=", 8) == 0) {
newShell.exit = &argv[0][8];
- } else if (strncmp (*argv, "hasErrCtl=", 10) == 0) {
+ } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) {
char c = argv[0][10];
newShell.hasErrCtl = !((c != 'Y') && (c != 'y') &&
- (c != 'T') && (c != 't'));
- } else if (strncmp (*argv, "check=", 6) == 0) {
+ (c != 'T') && (c != 't'));
+ } else if (strncmp(*argv, "check=", 6) == 0) {
newShell.errCheck = &argv[0][6];
- } else if (strncmp (*argv, "ignore=", 7) == 0) {
+ } else if (strncmp(*argv, "ignore=", 7) == 0) {
newShell.ignErr = &argv[0][7];
} else {
- Parse_Error (PARSE_FATAL, "Unknown keyword \"%s\"",
+ Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"",
*argv);
- return (FAILURE);
+ return(FAILURE);
}
fullSpec = TRUE;
}
}
- if (path == (char *)NULL) {
+ if (path == NULL) {
/*
* If no path was given, the user wants one of the pre-defined shells,
* yes? So we find the one s/he wants with the help of JobMatchShell
* and set things up the right way. shellPath will be set up by
* Job_Init.
*/
- if (newShell.name == (char *)NULL) {
- Parse_Error (PARSE_FATAL, "Neither path nor name specified");
- return (FAILURE);
+ if (newShell.name == NULL) {
+ Parse_Error(PARSE_FATAL, "Neither path nor name specified");
+ return(FAILURE);
} else {
- commandShell = JobMatchShell (newShell.name);
+ commandShell = JobMatchShell(newShell.name);
shellName = newShell.name;
}
} else {
@@ -2425,19 +2723,19 @@ Job_ParseShell (line)
* path the user gave for the shell.
*/
shellPath = path;
- path = strrchr (path, '/');
- if (path == (char *)NULL) {
+ path = strrchr(path, '/');
+ if (path == NULL) {
path = shellPath;
} else {
path += 1;
}
- if (newShell.name != (char *)NULL) {
+ if (newShell.name != NULL) {
shellName = newShell.name;
} else {
shellName = path;
}
if (!fullSpec) {
- commandShell = JobMatchShell (shellName);
+ commandShell = JobMatchShell(shellName);
} else {
commandShell = (Shell *) emalloc(sizeof(Shell));
*commandShell = newShell;
@@ -2447,21 +2745,21 @@ Job_ParseShell (line)
if (commandShell->echoOn && commandShell->echoOff) {
commandShell->hasEchoCtl = TRUE;
}
-
+
if (!commandShell->hasErrCtl) {
- if (commandShell->errCheck == (char *)NULL) {
+ if (commandShell->errCheck == NULL) {
commandShell->errCheck = "";
}
- if (commandShell->ignErr == (char *)NULL) {
+ if (commandShell->ignErr == NULL) {
commandShell->ignErr = "%s\n";
}
}
-
+
/*
* Do not free up the words themselves, since they might be in use by the
* shell specification...
*/
- free (words);
+ free(words);
return SUCCESS;
}
@@ -2479,28 +2777,27 @@ Job_ParseShell (line)
*-----------------------------------------------------------------------
*/
static void
-JobInterrupt (runINTERRUPT)
+JobInterrupt(runINTERRUPT, signo)
int runINTERRUPT; /* Non-zero if commands for the .INTERRUPT
* target should be executed */
+ int signo; /* signal received */
{
LstNode ln; /* element in job table */
Job *job; /* job descriptor in that element */
GNode *interrupt; /* the node describing the .INTERRUPT target */
-
+
aborting = ABORT_INTERRUPT;
- (void)Lst_Open (jobs);
- while ((ln = Lst_Next (jobs)) != NILLNODE) {
- job = (Job *) Lst_Datum (ln);
+ (void) Lst_Open(jobs);
+ while ((ln = Lst_Next(jobs)) != NILLNODE) {
+ job = (Job *) Lst_Datum(ln);
- if (!Targ_Precious (job->node)) {
- char *file = (job->node->path == (char *)NULL ?
+ if (!Targ_Precious(job->node)) {
+ char *file = (job->node->path == NULL ?
job->node->name :
job->node->path);
- struct stat st;
- if (!noExecute && lstat(file, &st) != -1 && !S_ISDIR(st.st_mode) &&
- unlink(file) != -1) {
- Error ("*** %s removed", file);
+ if (!noExecute && eunlink(file) != -1) {
+ Error("*** %s removed", file);
}
}
#ifdef RMT_WANTS_SIGNALS
@@ -2508,51 +2805,117 @@ JobInterrupt (runINTERRUPT)
/*
* If job is remote, let the Rmt module do the killing.
*/
- if (!Rmt_Signal(job, SIGINT)) {
+ if (!Rmt_Signal(job, signo)) {
/*
* If couldn't kill the thing, finish it out now with an
* error code, since no exit report will come in likely.
*/
- union wait status;
+ int status;
status.w_status = 0;
status.w_retcode = 1;
- JobFinish(job, status);
+ JobFinish(job, &status);
}
} else if (job->pid) {
- KILL(job->pid, SIGINT);
+ KILL(job->pid, signo);
}
#else
if (job->pid) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "JobInterrupt passing signal to child %d.\n",
+ job->pid);
+ (void) fflush(stdout);
+ }
+ KILL(job->pid, signo);
+ }
+#endif /* RMT_WANTS_SIGNALS */
+ }
+
+#ifdef REMOTE
+ (void)Lst_Open(stoppedJobs);
+ while ((ln = Lst_Next(stoppedJobs)) != NILLNODE) {
+ job = (Job *) Lst_Datum(ln);
+
+ if (job->flags & JOB_RESTART) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout, "%s%s",
+ "JobInterrupt skipping job on stopped queue",
+ "-- it was waiting to be restarted.\n");
+ (void) fflush(stdout);
+ }
+ continue;
+ }
+ if (!Targ_Precious(job->node)) {
+ char *file = (job->node->path == NULL ?
+ job->node->name :
+ job->node->path);
+ if (eunlink(file) == 0) {
+ Error("*** %s removed", file);
+ }
+ }
+ /*
+ * Resume the thing so it will take the signal.
+ */
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "JobInterrupt passing CONT to stopped child %d.\n",
+ job->pid);
+ (void) fflush(stdout);
+ }
+ KILL(job->pid, SIGCONT);
+#ifdef RMT_WANTS_SIGNALS
+ if (job->flags & JOB_REMOTE) {
+ /*
+ * If job is remote, let the Rmt module do the killing.
+ */
+ if (!Rmt_Signal(job, SIGINT)) {
+ /*
+ * If couldn't kill the thing, finish it out now with an
+ * error code, since no exit report will come in likely.
+ */
+ int status;
+ status.w_status = 0;
+ status.w_retcode = 1;
+ JobFinish(job, &status);
+ }
+ } else if (job->pid) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "JobInterrupt passing interrupt to stopped child %d.\n",
+ job->pid);
+ (void) fflush(stdout);
+ }
KILL(job->pid, SIGINT);
}
#endif /* RMT_WANTS_SIGNALS */
}
- Lst_Close (jobs);
+#endif
+ Lst_Close(stoppedJobs);
if (runINTERRUPT && !touchFlag) {
- interrupt = Targ_FindNode (".INTERRUPT", TARG_NOCREATE);
+ interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
if (interrupt != NILGNODE) {
ignoreErrors = FALSE;
- JobStart (interrupt, JOB_IGNDOTS, (Job *)0);
+ JobStart(interrupt, JOB_IGNDOTS, (Job *)0);
while (nJobs) {
Job_CatchOutput();
#ifndef RMT_WILL_WATCH
- Job_CatchChildren (!usePipes);
+ Job_CatchChildren(!usePipes);
#endif /* RMT_WILL_WATCH */
}
}
}
- (void) unlink (tfile);
- exit (0);
+ (void) eunlink(tfile);
+ exit(signo);
}
/*
*-----------------------------------------------------------------------
* Job_End --
* Do final processing such as the running of the commands
- * attached to the .END target.
+ * attached to the .END target.
*
* Results:
* Number of errors reported.
@@ -2563,24 +2926,23 @@ JobInterrupt (runINTERRUPT)
*-----------------------------------------------------------------------
*/
int
-Job_End ()
+Job_End()
{
- if (postCommands != NILGNODE && !Lst_IsEmpty (postCommands->commands)) {
+ if (postCommands != NILGNODE && !Lst_IsEmpty(postCommands->commands)) {
if (errors) {
- Error ("Errors reported so .END ignored");
+ Error("Errors reported so .END ignored");
} else {
- JobStart (postCommands, JOB_SPECIAL | JOB_IGNDOTS,
- (Job *)0);
+ JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL);
while (nJobs) {
Job_CatchOutput();
#ifndef RMT_WILL_WATCH
- Job_CatchChildren (!usePipes);
+ Job_CatchChildren(!usePipes);
#endif /* RMT_WILL_WATCH */
}
}
}
- (void) unlink (tfile);
+ (void) eunlink(tfile);
return(errors);
}
@@ -2626,23 +2988,23 @@ Job_Wait()
*-----------------------------------------------------------------------
*/
void
-Job_AbortAll ()
+Job_AbortAll()
{
- LstNode ln; /* element in job table */
+ LstNode ln; /* element in job table */
Job *job; /* the job descriptor in that element */
int foo;
-
+
aborting = ABORT_ERROR;
-
+
if (nJobs) {
- (void)Lst_Open (jobs);
- while ((ln = Lst_Next (jobs)) != NILLNODE) {
- job = (Job *) Lst_Datum (ln);
+ (void) Lst_Open(jobs);
+ while ((ln = Lst_Next(jobs)) != NILLNODE) {
+ job = (Job *) Lst_Datum(ln);
/*
* kill the child process with increasingly drastic signals to make
- * darn sure it's dead.
+ * darn sure it's dead.
*/
#ifdef RMT_WANTS_SIGNALS
if (job->flags & JOB_REMOTE) {
@@ -2658,11 +3020,92 @@ Job_AbortAll ()
#endif /* RMT_WANTS_SIGNALS */
}
}
-
+
/*
* Catch as many children as want to report in at first, then give up
*/
- while (wait3(&foo, WNOHANG, (struct rusage *)0) > 0)
+ while (waitpid((pid_t) -1, &foo, WNOHANG) > 0)
continue;
- (void) unlink (tfile);
+ (void) eunlink(tfile);
+}
+
+#ifdef REMOTE
+/*-
+ *-----------------------------------------------------------------------
+ * JobFlagForMigration --
+ * Handle the eviction of a child. Called from RmtStatusChange.
+ * Flags the child as remigratable and then suspends it.
+ *
+ * Results:
+ * none.
+ *
+ * Side Effects:
+ * The job descriptor is flagged for remigration.
+ *
+ *-----------------------------------------------------------------------
+ */
+void
+JobFlagForMigration(hostID)
+ int hostID; /* ID of host we used, for matching children. */
+{
+ register Job *job; /* job descriptor for dead child */
+ LstNode jnode; /* list element for finding job */
+
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout, "JobFlagForMigration(%d) called.\n", hostID);
+ (void) fflush(stdout);
+ }
+ jnode = Lst_Find(jobs, (ClientData)hostID, JobCmpRmtID);
+
+ if (jnode == NILLNODE) {
+ jnode = Lst_Find(stoppedJobs, (ClientData)hostID, JobCmpRmtID);
+ if (jnode == NILLNODE) {
+ if (DEBUG(JOB)) {
+ Error("Evicting host(%d) not in table", hostID);
+ }
+ return;
+ }
+ }
+ job = (Job *) Lst_Datum(jnode);
+
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "JobFlagForMigration(%d) found job '%s'.\n", hostID,
+ job->node->name);
+ (void) fflush(stdout);
+ }
+
+ KILL(job->pid, SIGSTOP);
+
+ job->flags |= JOB_REMIGRATE;
+}
+
+#endif
+
+/*-
+ *-----------------------------------------------------------------------
+ * JobRestartJobs --
+ * Tries to restart stopped jobs if there are slots available.
+ * Note that this tries to restart them regardless of pending errors.
+ * It's not good to leave stopped jobs lying around!
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Resumes(and possibly migrates) jobs.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+JobRestartJobs()
+{
+ while (!jobFull && !Lst_IsEmpty(stoppedJobs)) {
+ if (DEBUG(JOB)) {
+ (void) fprintf(stdout,
+ "Job queue is not full. Restarting a stopped job.\n");
+ (void) fflush(stdout);
+ }
+ JobRestart((Job *)Lst_DeQueue(stoppedJobs));
+ }
}
diff --git a/usr.bin/make/job.h b/usr.bin/make/job.h
index 5feb43fb6e43..d9cdcc02efa0 100644
--- a/usr.bin/make/job.h
+++ b/usr.bin/make/job.h
@@ -1,6 +1,8 @@
+/* $NetBSD: job.h,v 1.4 1995/06/14 15:19:26 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)job.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)job.h 8.1 (Berkeley) 6/6/93
*/
/*-
@@ -51,14 +53,14 @@
/*
* The SEL_ constants determine the maximum amount of time spent in select
* before coming out to see if a child has finished. SEL_SEC is the number of
- * seconds and SEL_USEC is the number of micro-seconds
+ * seconds and SEL_USEC is the number of micro-seconds
*/
#define SEL_SEC 0
#define SEL_USEC 500000
/*-
- * Job Table definitions.
+ * Job Table definitions.
*
* Each job has several things associated with it:
* 1) The process id of the child shell
@@ -79,11 +81,11 @@
* 6) An identifier provided by and for the exclusive use of the
* Rmt module.
* 7) A word of flags which determine how the module handles errors,
- * echoing, etc. for the job
+ * echoing, etc. for the job
*
* The job "table" is kept as a linked Lst in 'jobs', with the number of
* active jobs maintained in the 'nJobs' variable. At no time will this
- * exceed the value of 'maxJobs', initialized by the Job_Init function.
+ * exceed the value of 'maxJobs', initialized by the Job_Init function.
*
* When a job is finished, the Make_Update function is called on each of the
* parents of the node which was just remade. This takes care of the upward
@@ -105,7 +107,7 @@ typedef struct Job {
* if we can't export it and maxLocal is 0 */
#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing
* commands */
-#define JOB_REMOTE 0x010 /* Job is running remotely */
+#define JOB_REMOTE 0x010 /* Job is running remotely */
#define JOB_FIRST 0x020 /* Job is first job for the node */
#define JOB_REMIGRATE 0x040 /* Job needs to be remigrated */
#define JOB_RESTART 0x080 /* Job needs to be completely restarted */
@@ -193,7 +195,7 @@ typedef struct Shell {
char *errCheck; /* string to turn error checking on */
char *ignErr; /* string to turn off error checking */
/*
- * command-line flags
+ * command-line flags
*/
char *echo; /* echo commands */
char *exit; /* exit on error */
diff --git a/usr.bin/make/list.h b/usr.bin/make/list.h
index 41b9a1930293..e150d2e4c64e 100644
--- a/usr.bin/make/list.h
+++ b/usr.bin/make/list.h
@@ -1,6 +1,8 @@
+/* $NetBSD: list.h,v 1.4 1995/06/14 15:19:28 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)list.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)list.h 8.1 (Berkeley) 6/6/93
*/
/*
@@ -60,39 +62,39 @@
* to a list as a whole, the user keeps a pointer to the header; that
* header is initialized by a call to List_Init(), which creates an empty
* list given a pointer to a List_Links structure (described below).
- *
+ *
* The links are contained in a two-element structure called List_Links.
* A list joins List_Links records (that is, each List_Links structure
* points to other List_Links structures), but if the List_Links is the
* first field within a larger structure, then the larger structures are
* effectively linked together as follows:
- *
+ *
* header
* (List_Links) first elt. second elt.
- * ----------------- ----------------- -----------------
+ * ----------------- ----------------- -----------------
* ..-> | nextPtr | ----> | List_Links | ----> | List_Links |----..
- * | - - - - - - - | | | | |
+ * | - - - - - - - | | | | |
* ..-- | prevPtr | <---- | | <---- | |<---..
* ----------------- - --- --- --- - - --- --- --- -
- * | rest of | | rest of |
- * | structure | | structure |
+ * | rest of | | rest of |
+ * | structure | | structure |
* | | | |
- * | ... | | ... |
- * ----------------- -----------------
- *
+ * | ... | | ... |
+ * ----------------- -----------------
+ *
* It is possible to link structures through List_Links fields that are
* not at the beginning of the larger structure, but it is then necessary
* to perform pointer arithmetic to find the beginning of the larger
* structure, given a pointer to some point within it.
- *
+ *
* A typical structure might be something like:
- *
+ *
* typedef struct {
* List_Links links;
* char ch;
* integer flags;
* } EditChar;
- *
+ *
* Before an element is inserted in a list for the first time, it must
* be initialized by calling the macro List_InitElement().
*/
@@ -129,7 +131,7 @@ void List_Move(); /* move an element elsewhere in a list */
#define List_InitElement(elementPtr) \
(elementPtr)->prevPtr = (List_Links *) NIL; \
(elementPtr)->nextPtr = (List_Links *) NIL;
-
+
/*
* Macros for stepping through or selecting parts of lists
*/
@@ -142,10 +144,10 @@ void List_Move(); /* move an element elsewhere in a list */
* Macro to loop through a list and perform an operation on each member.
*
* Usage: LIST_FORALL(headerPtr, itemPtr) {
- * / *
+ * / *
* * operation on itemPtr, which points to successive members
* * of the list
- * *
+ * *
* * It may be appropriate to first assign
* * foobarPtr = (Foobar *) itemPtr;
* * to refer to the entire Foobar structure.
@@ -279,7 +281,7 @@ void List_Move(); /* move an element elsewhere in a list */
* LIST_ATFRONT(headerPtr) -- insert at front of list
* LIST_ATREAR(headerPtr) -- insert at end of list
*
- * For example,
+ * For example,
*
* List_Insert(itemPtr, LIST_AFTER(otherPtr));
*
diff --git a/usr.bin/make/lst.h b/usr.bin/make/lst.h
index 8d8abe04c814..ff4a40c9afe8 100644
--- a/usr.bin/make/lst.h
+++ b/usr.bin/make/lst.h
@@ -1,6 +1,8 @@
+/* $NetBSD: lst.h,v 1.6 1996/02/04 22:20:46 christos Exp $ */
+
/*
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
+ * Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)lst.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)lst.h 8.1 (Berkeley) 6/6/93
*/
/*-
@@ -46,6 +48,7 @@
#define _LST_H_
#include <sprite.h>
+#include <sys/param.h>
#if __STDC__
#include <stdlib.h>
#endif
@@ -117,12 +120,12 @@ ClientData Lst_Datum __P((LstNode));
* Functions for entire lists
*/
/* Find an element in a list */
-LstNode Lst_Find __P((Lst, ClientData,
+LstNode Lst_Find __P((Lst, ClientData,
int (*)(ClientData, ClientData)));
/* Find an element starting from somewhere */
LstNode Lst_FindFrom __P((Lst, LstNode, ClientData,
int (*cProc)(ClientData, ClientData)));
-/*
+/*
* See if the given datum is on the list. Returns the LstNode containing
* the datum
*/
diff --git a/usr.bin/make/lst.lib/Makefile b/usr.bin/make/lst.lib/Makefile
new file mode 100644
index 000000000000..1e73eca40479
--- /dev/null
+++ b/usr.bin/make/lst.lib/Makefile
@@ -0,0 +1,10 @@
+# $NetBSD: Makefile,v 1.3 1995/06/14 15:20:42 christos Exp $
+
+OBJ=lstAppend.o lstDupl.o lstInit.o lstOpen.o lstAtEnd.o lstEnQueue.o \
+ lstInsert.o lstAtFront.o lstIsAtEnd.o lstClose.o lstFind.o lstIsEmpty.o \
+ lstRemove.o lstConcat.o lstFindFrom.o lstLast.o lstReplace.o lstFirst.o \
+ lstDatum.o lstForEach.o lstMember.o lstSucc.o lstDeQueue.o \
+ lstForEachFrom.o lstDestroy.o lstNext.o
+
+CFLAGS=-I..
+all: ${OBJ}
diff --git a/usr.bin/make/lst.lib/lstAppend.c b/usr.bin/make/lst.lib/lstAppend.c
index 93800db01a0b..b6f15d371536 100644
--- a/usr.bin/make/lst.lib/lstAppend.c
+++ b/usr.bin/make/lst.lib/lstAppend.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstAppend.c,v 1.4 1995/06/14 15:20:44 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstAppend.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstAppend.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstAppend.c,v 1.4 1995/06/14 15:20:44 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -70,23 +76,23 @@ Lst_Append (l, ln, d)
register List list;
register ListNode lNode;
register ListNode nLNode;
-
+
if (LstValid (l) && (ln == NILLNODE && LstIsEmpty (l))) {
goto ok;
}
-
+
if (!LstValid (l) || LstIsEmpty (l) || ! LstNodeValid (ln, l)) {
return (FAILURE);
}
ok:
-
+
list = (List)l;
lNode = (ListNode)ln;
PAlloc (nLNode, ListNode);
nLNode->datum = d;
nLNode->useCount = nLNode->flags = 0;
-
+
if (lNode == NilListNode) {
if (list->isCirc) {
nLNode->nextPtr = nLNode->prevPtr = nLNode;
@@ -97,17 +103,17 @@ Lst_Append (l, ln, d)
} else {
nLNode->prevPtr = lNode;
nLNode->nextPtr = lNode->nextPtr;
-
+
lNode->nextPtr = nLNode;
if (nLNode->nextPtr != NilListNode) {
nLNode->nextPtr->prevPtr = nLNode;
}
-
+
if (lNode == list->lastPtr) {
list->lastPtr = nLNode;
}
}
-
+
return (SUCCESS);
}
diff --git a/usr.bin/make/lst.lib/lstAtEnd.c b/usr.bin/make/lst.lib/lstAtEnd.c
index e61a28c0673f..a4ed0d7b0181 100644
--- a/usr.bin/make/lst.lib/lstAtEnd.c
+++ b/usr.bin/make/lst.lib/lstAtEnd.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstAtEnd.c,v 1.4 1995/06/14 15:20:46 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstAtEnd.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstAtEnd.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.4 1995/06/14 15:20:46 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -44,7 +50,7 @@ static char sccsid[] = "@(#)lstAtEnd.c 8.2 (Berkeley) 4/28/95";
*/
#include "lstInt.h"
-
+
/*-
*-----------------------------------------------------------------------
* Lst_AtEnd --
@@ -64,7 +70,7 @@ Lst_AtEnd (l, d)
ClientData d; /* Datum to add */
{
register LstNode end;
-
+
end = Lst_Last (l);
return (Lst_Append (l, end, d));
}
diff --git a/usr.bin/make/lst.lib/lstAtFront.c b/usr.bin/make/lst.lib/lstAtFront.c
index 5e8b7f1ab4c2..ef694d345d4e 100644
--- a/usr.bin/make/lst.lib/lstAtFront.c
+++ b/usr.bin/make/lst.lib/lstAtFront.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstAtFront.c,v 1.4 1995/06/14 15:20:48 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstAtFront.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstAtFront.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.4 1995/06/14 15:20:48 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -65,7 +71,7 @@ Lst_AtFront (l, d)
ClientData d;
{
register LstNode front;
-
+
front = Lst_First (l);
return (Lst_Insert (l, front, d));
}
diff --git a/usr.bin/make/lst.lib/lstClose.c b/usr.bin/make/lst.lib/lstClose.c
index 6f9174f3db8a..e07ed4a81c81 100644
--- a/usr.bin/make/lst.lib/lstClose.c
+++ b/usr.bin/make/lst.lib/lstClose.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstClose.c,v 1.4 1995/06/14 15:20:50 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstClose.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstClose.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstClose.c,v 1.4 1995/06/14 15:20:50 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -68,7 +74,7 @@ Lst_Close (l)
Lst l; /* The list to close */
{
register List list = (List) l;
-
+
if (LstValid(l) == TRUE) {
list->isOpen = FALSE;
list->atEnd = Unknown;
diff --git a/usr.bin/make/lst.lib/lstConcat.c b/usr.bin/make/lst.lib/lstConcat.c
index e7726a862b60..74baa86b2096 100644
--- a/usr.bin/make/lst.lib/lstConcat.c
+++ b/usr.bin/make/lst.lib/lstConcat.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstConcat.c,v 1.5 1995/06/14 15:20:53 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstConcat.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstConcat.c,v 1.5 1995/06/14 15:20:53 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -149,7 +155,7 @@ Lst_Concat (l1, l2, flags)
/*
* Finish bookkeeping. The last new element becomes the last element
- * of list one.
+ * of list one.
*/
list1->lastPtr = last;
@@ -173,4 +179,4 @@ Lst_Concat (l1, l2, flags)
return (SUCCESS);
}
-
+
diff --git a/usr.bin/make/lst.lib/lstDatum.c b/usr.bin/make/lst.lib/lstDatum.c
index 6b0988e0fa2b..6125b665174b 100644
--- a/usr.bin/make/lst.lib/lstDatum.c
+++ b/usr.bin/make/lst.lib/lstDatum.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstDatum.c,v 1.4 1995/06/14 15:20:54 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstDatum.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstDatum.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstDatum.c,v 1.4 1995/06/14 15:20:54 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstDeQueue.c b/usr.bin/make/lst.lib/lstDeQueue.c
index 4b901257b001..b4c5f8bb805a 100644
--- a/usr.bin/make/lst.lib/lstDeQueue.c
+++ b/usr.bin/make/lst.lib/lstDeQueue.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstDeQueue.c,v 1.4 1995/06/14 15:20:56 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstDeQueue.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstDeQueue.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.4 1995/06/14 15:20:56 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -65,12 +71,12 @@ Lst_DeQueue (l)
{
ClientData rd;
register ListNode tln;
-
+
tln = (ListNode) Lst_First (l);
if (tln == NilListNode) {
return ((ClientData) NIL);
}
-
+
rd = tln->datum;
if (Lst_Remove (l, (LstNode)tln) == FAILURE) {
return ((ClientData) NIL);
diff --git a/usr.bin/make/lst.lib/lstDestroy.c b/usr.bin/make/lst.lib/lstDestroy.c
index 56ea5c528fe6..23e0ecd6b7d7 100644
--- a/usr.bin/make/lst.lib/lstDestroy.c
+++ b/usr.bin/make/lst.lib/lstDestroy.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstDestroy.c,v 1.5 1995/06/14 15:20:58 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstDestroy.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstDestroy.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstDestroy.c,v 1.5 1995/06/14 15:20:58 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -68,7 +74,7 @@ Lst_Destroy (l, freeProc)
register ListNode ln;
register ListNode tln = NilListNode;
register List list = (List)l;
-
+
if (l == NILLST || ! l) {
/*
* Note the check for l == (Lst)0 to catch uninitialized static Lst's.
@@ -97,6 +103,6 @@ Lst_Destroy (l, freeProc)
free ((Address)ln);
}
}
-
+
free ((Address)l);
}
diff --git a/usr.bin/make/lst.lib/lstDupl.c b/usr.bin/make/lst.lib/lstDupl.c
index 184b386228d3..b0d36f83a0e5 100644
--- a/usr.bin/make/lst.lib/lstDupl.c
+++ b/usr.bin/make/lst.lib/lstDupl.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstDupl.c,v 1.5 1995/06/14 15:21:02 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstDupl.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstDupl.c,v 1.5 1995/06/14 15:21:02 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -68,7 +74,7 @@ Lst_Duplicate (l, copyProc)
register Lst nl;
register ListNode ln;
register List list = (List)l;
-
+
if (!LstValid (l)) {
return (NILLST);
}
@@ -94,6 +100,6 @@ Lst_Duplicate (l, copyProc)
ln = ln->nextPtr;
}
}
-
+
return (nl);
}
diff --git a/usr.bin/make/lst.lib/lstEnQueue.c b/usr.bin/make/lst.lib/lstEnQueue.c
index 1016c88d2834..cdd865cfad05 100644
--- a/usr.bin/make/lst.lib/lstEnQueue.c
+++ b/usr.bin/make/lst.lib/lstEnQueue.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstEnQueue.c,v 1.4 1995/06/14 15:21:04 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstEnQueue.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstEnQueue.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.4 1995/06/14 15:21:04 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -67,7 +73,7 @@ Lst_EnQueue (l, d)
if (LstValid (l) == FALSE) {
return (FAILURE);
}
-
+
return (Lst_Append (l, Lst_Last(l), d));
}
diff --git a/usr.bin/make/lst.lib/lstFind.c b/usr.bin/make/lst.lib/lstFind.c
index bab85ccd173c..41b9e1cf4b9d 100644
--- a/usr.bin/make/lst.lib/lstFind.c
+++ b/usr.bin/make/lst.lib/lstFind.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstFind.c,v 1.5 1995/06/14 15:21:07 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstFind.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstFind.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstFind.c,v 1.5 1995/06/14 15:21:07 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstFindFrom.c b/usr.bin/make/lst.lib/lstFindFrom.c
index 08de990afe5c..19cd4e04867e 100644
--- a/usr.bin/make/lst.lib/lstFindFrom.c
+++ b/usr.bin/make/lst.lib/lstFindFrom.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstFindFrom.c,v 1.5 1995/06/14 15:21:09 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstFindFrom.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstFindFrom.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.5 1995/06/14 15:21:09 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -69,13 +75,13 @@ Lst_FindFrom (l, ln, d, cProc)
{
register ListNode tln;
Boolean found = FALSE;
-
+
if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
return (NILLNODE);
}
-
+
tln = (ListNode)ln;
-
+
do {
if ((*cProc) (tln->datum, d) == 0) {
found = TRUE;
@@ -84,7 +90,7 @@ Lst_FindFrom (l, ln, d, cProc)
tln = tln->nextPtr;
}
} while (tln != (ListNode)ln && tln != NilListNode);
-
+
if (found) {
return ((LstNode)tln);
} else {
diff --git a/usr.bin/make/lst.lib/lstFirst.c b/usr.bin/make/lst.lib/lstFirst.c
index 9a95018777ab..f97c12c1f624 100644
--- a/usr.bin/make/lst.lib/lstFirst.c
+++ b/usr.bin/make/lst.lib/lstFirst.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstFirst.c,v 1.4 1995/06/14 15:21:12 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstFirst.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstFirst.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstFirst.c,v 1.4 1995/06/14 15:21:12 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstForEach.c b/usr.bin/make/lst.lib/lstForEach.c
index 1d6ba9396dc6..00c1fa91dc64 100644
--- a/usr.bin/make/lst.lib/lstForEach.c
+++ b/usr.bin/make/lst.lib/lstForEach.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstForEach.c,v 1.5 1995/06/14 15:21:14 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstForEach.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstForEach.c,v 1.5 1995/06/14 15:21:14 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstForEachFrom.c b/usr.bin/make/lst.lib/lstForEachFrom.c
index 7c9e51e749f0..a5efc640d299 100644
--- a/usr.bin/make/lst.lib/lstForEachFrom.c
+++ b/usr.bin/make/lst.lib/lstForEachFrom.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstForEachFrom.c,v 1.4 1995/06/14 15:21:16 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstForEachFrom.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstForEachFrom.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.4 1995/06/14 15:21:16 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -51,7 +57,7 @@ static char sccsid[] = "@(#)lstForEachFrom.c 8.2 (Berkeley) 4/28/95";
* Lst_ForEachFrom --
* Apply the given function to each element of the given list. The
* function should return 0 if traversal should continue and non-
- * zero if it should abort.
+ * zero if it should abort.
*
* Results:
* None.
@@ -66,7 +72,7 @@ void
Lst_ForEachFrom (l, ln, proc, d)
Lst l;
LstNode ln;
- register int (*proc)();
+ register int (*proc) __P((ClientData, ClientData));
register ClientData d;
{
register ListNode tln = (ListNode)ln;
@@ -74,19 +80,19 @@ Lst_ForEachFrom (l, ln, proc, d)
register ListNode next;
Boolean done;
int result;
-
+
if (!LstValid (list) || LstIsEmpty (list)) {
return;
}
-
+
do {
/*
* Take care of having the current element deleted out from under
* us.
*/
-
+
next = tln->nextPtr;
-
+
(void) tln->useCount++;
result = (*proc) (tln->datum, d);
(void) tln->useCount--;
@@ -99,7 +105,7 @@ Lst_ForEachFrom (l, ln, proc, d)
*/
done = (next == tln->nextPtr &&
(next == NilListNode || next == list->firstPtr));
-
+
next = tln->nextPtr;
if (tln->flags & LN_DELETED) {
@@ -107,5 +113,6 @@ Lst_ForEachFrom (l, ln, proc, d)
}
tln = next;
} while (!result && !LstIsEmpty(list) && !done);
-
+
}
+
diff --git a/usr.bin/make/lst.lib/lstInit.c b/usr.bin/make/lst.lib/lstInit.c
index 17276be6f1e7..dfcb873971af 100644
--- a/usr.bin/make/lst.lib/lstInit.c
+++ b/usr.bin/make/lst.lib/lstInit.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstInit.c,v 1.4 1995/06/14 15:21:18 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstInit.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstInit.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstInit.c,v 1.4 1995/06/14 15:21:18 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -63,14 +69,14 @@ Lst_Init(circ)
Boolean circ; /* TRUE if the list should be made circular */
{
register List nList;
-
+
PAlloc (nList, List);
-
+
nList->firstPtr = NilListNode;
nList->lastPtr = NilListNode;
nList->isOpen = FALSE;
nList->isCirc = circ;
nList->atEnd = Unknown;
-
+
return ((Lst)nList);
}
diff --git a/usr.bin/make/lst.lib/lstInsert.c b/usr.bin/make/lst.lib/lstInsert.c
index 724924adf071..07070202e470 100644
--- a/usr.bin/make/lst.lib/lstInsert.c
+++ b/usr.bin/make/lst.lib/lstInsert.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstInsert.c,v 1.4 1995/06/14 15:21:21 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstInsert.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstInsert.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstInsert.c,v 1.4 1995/06/14 15:21:21 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -76,17 +82,17 @@ Lst_Insert (l, ln, d)
*/
if (LstValid (l) && (LstIsEmpty (l) && ln == NILLNODE))
goto ok;
-
+
if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
return (FAILURE);
}
-
+
ok:
PAlloc (nLNode, ListNode);
-
+
nLNode->datum = d;
nLNode->useCount = nLNode->flags = 0;
-
+
if (ln == NILLNODE) {
if (list->isCirc) {
nLNode->prevPtr = nLNode->nextPtr = nLNode;
@@ -97,17 +103,17 @@ Lst_Insert (l, ln, d)
} else {
nLNode->prevPtr = lNode->prevPtr;
nLNode->nextPtr = lNode;
-
+
if (nLNode->prevPtr != NilListNode) {
nLNode->prevPtr->nextPtr = nLNode;
}
lNode->prevPtr = nLNode;
-
+
if (lNode == list->firstPtr) {
list->firstPtr = nLNode;
}
}
-
+
return (SUCCESS);
}
-
+
diff --git a/usr.bin/make/lst.lib/lstInt.h b/usr.bin/make/lst.lib/lstInt.h
index 1253660f8e81..975d5dc5fe89 100644
--- a/usr.bin/make/lst.lib/lstInt.h
+++ b/usr.bin/make/lst.lib/lstInt.h
@@ -1,3 +1,5 @@
+/* $NetBSD: lstInt.h,v 1.6 1995/11/10 21:27:27 cgd Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -33,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)lstInt.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)lstInt.h 8.1 (Berkeley) 6/6/93
*/
/*-
@@ -43,6 +45,7 @@
#ifndef _LSTINT_H_
#define _LSTINT_H_
+#include "make.h"
#include "lst.h"
typedef struct ListNode {
@@ -87,7 +90,7 @@ typedef struct {
* PAlloc (var, ptype) --
* Allocate a pointer-typedef structure 'ptype' into the variable 'var'
*/
-#define PAlloc(var,ptype) var = (ptype) malloc (sizeof (*var))
+#define PAlloc(var,ptype) var = (ptype) emalloc (sizeof (*var))
/*
* LstValid (l) --
diff --git a/usr.bin/make/lst.lib/lstIsAtEnd.c b/usr.bin/make/lst.lib/lstIsAtEnd.c
index 7fdf68dca49c..be17403b43bc 100644
--- a/usr.bin/make/lst.lib/lstIsAtEnd.c
+++ b/usr.bin/make/lst.lib/lstIsAtEnd.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstIsAtEnd.c,v 1.4 1995/06/14 15:21:25 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstIsAtEnd.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstIsAtEnd.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.4 1995/06/14 15:21:25 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstIsEmpty.c b/usr.bin/make/lst.lib/lstIsEmpty.c
index da475611bfa8..6fc9b908f758 100644
--- a/usr.bin/make/lst.lib/lstIsEmpty.c
+++ b/usr.bin/make/lst.lib/lstIsEmpty.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstIsEmpty.c,v 1.4 1995/06/14 15:21:27 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstIsEmpty.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstIsEmpty.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstIsEmpty.c,v 1.4 1995/06/14 15:21:27 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstLast.c b/usr.bin/make/lst.lib/lstLast.c
index a87c50c0f837..1c28fd7c7e77 100644
--- a/usr.bin/make/lst.lib/lstLast.c
+++ b/usr.bin/make/lst.lib/lstLast.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstLast.c,v 1.4 1995/06/14 15:21:29 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstLast.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstLast.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstLast.c,v 1.4 1995/06/14 15:21:29 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstMember.c b/usr.bin/make/lst.lib/lstMember.c
index a6145ee64fd3..fc9b1bbc03ac 100644
--- a/usr.bin/make/lst.lib/lstMember.c
+++ b/usr.bin/make/lst.lib/lstMember.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstMember.c,v 1.4 1995/06/14 15:21:32 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstMember.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstMember.c,v 1.4 1995/06/14 15:21:32 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -57,7 +63,7 @@ Lst_Member (l, d)
if (lNode == NilListNode) {
return NILLNODE;
}
-
+
do {
if (lNode->datum == d) {
return (LstNode)lNode;
diff --git a/usr.bin/make/lst.lib/lstNext.c b/usr.bin/make/lst.lib/lstNext.c
index b6986d866d59..d36e5065ee00 100644
--- a/usr.bin/make/lst.lib/lstNext.c
+++ b/usr.bin/make/lst.lib/lstNext.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstNext.c,v 1.4 1995/06/14 15:21:35 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstNext.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstNext.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstNext.c,v 1.4 1995/06/14 15:21:35 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -71,14 +77,14 @@ Lst_Next (l)
{
register ListNode tln;
register List list = (List)l;
-
+
if ((LstValid (l) == FALSE) ||
(list->isOpen == FALSE)) {
return (NILLNODE);
}
-
+
list->prevPtr = list->curPtr;
-
+
if (list->curPtr == NilListNode) {
if (list->atEnd == Unknown) {
/*
@@ -108,7 +114,7 @@ Lst_Next (l)
list->atEnd = Middle;
}
}
-
+
return ((LstNode)tln);
}
diff --git a/usr.bin/make/lst.lib/lstOpen.c b/usr.bin/make/lst.lib/lstOpen.c
index 9da8cfab5769..ae492b17e3bd 100644
--- a/usr.bin/make/lst.lib/lstOpen.c
+++ b/usr.bin/make/lst.lib/lstOpen.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstOpen.c,v 1.4 1995/06/14 15:21:37 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstOpen.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstOpen.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstOpen.c,v 1.4 1995/06/14 15:21:37 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstRemove.c b/usr.bin/make/lst.lib/lstRemove.c
index 98eb3ce53493..7d13cae0e6ca 100644
--- a/usr.bin/make/lst.lib/lstRemove.c
+++ b/usr.bin/make/lst.lib/lstRemove.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstRemove.c,v 1.4 1995/06/14 15:21:39 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstRemove.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstRemove.c,v 1.4 1995/06/14 15:21:39 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -72,7 +78,7 @@ Lst_Remove (l, ln)
!LstNodeValid (ln, l)) {
return (FAILURE);
}
-
+
/*
* unlink it from the list
*/
@@ -82,7 +88,7 @@ Lst_Remove (l, ln)
if (lNode->prevPtr != NilListNode) {
lNode->prevPtr->nextPtr = lNode->nextPtr;
}
-
+
/*
* if either the firstPtr or lastPtr of the list point to this node,
* adjust them accordingly
@@ -115,7 +121,7 @@ Lst_Remove (l, ln)
if (list->firstPtr == lNode) {
list->firstPtr = NilListNode;
}
-
+
/*
* note that the datum is unmolested. The caller must free it as
* necessary and as expected.
@@ -125,7 +131,7 @@ Lst_Remove (l, ln)
} else {
lNode->flags |= LN_DELETED;
}
-
+
return (SUCCESS);
}
diff --git a/usr.bin/make/lst.lib/lstReplace.c b/usr.bin/make/lst.lib/lstReplace.c
index 8adb6895aec1..635e2c86a403 100644
--- a/usr.bin/make/lst.lib/lstReplace.c
+++ b/usr.bin/make/lst.lib/lstReplace.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstReplace.c,v 1.4 1995/06/14 15:21:41 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstReplace.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstReplace.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstReplace.c,v 1.4 1995/06/14 15:21:41 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/lst.lib/lstSucc.c b/usr.bin/make/lst.lib/lstSucc.c
index a5875f686874..971e540ad9e9 100644
--- a/usr.bin/make/lst.lib/lstSucc.c
+++ b/usr.bin/make/lst.lib/lstSucc.c
@@ -1,3 +1,5 @@
+/* $NetBSD: lstSucc.c,v 1.4 1995/06/14 15:21:42 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)lstSucc.c 8.2 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: lstSucc.c,v 1.4 1995/06/14 15:21:42 christos Exp $";
+#endif
#endif /* not lint */
/*-
diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c
index 8607fbb08bb6..d8b1708fd65a 100644
--- a/usr.bin/make/main.c
+++ b/usr.bin/make/main.c
@@ -1,3 +1,5 @@
+/* $NetBSD: main.c,v 1.30 1996/08/13 16:42:08 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -43,7 +45,11 @@ static char copyright[] =
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94";
+#else
+static char rcsid[] = "$NetBSD: main.c,v 1.30 1996/08/13 16:42:08 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -79,7 +85,10 @@ static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 4/28/95";
#include <sys/resource.h>
#include <sys/signal.h>
#include <sys/stat.h>
+#ifndef MACHINE
#include <sys/utsname.h>
+#endif
+#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -96,7 +105,7 @@ static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 4/28/95";
#ifndef DEFMAXLOCAL
#define DEFMAXLOCAL DEFMAXJOBS
-#endif DEFMAXLOCAL
+#endif /* DEFMAXLOCAL */
#define MAKEFLAGS ".MAKEFLAGS"
@@ -107,7 +116,9 @@ Boolean allPrecious; /* .PRECIOUS given on line by itself */
static Boolean noBuiltins; /* -r flag */
static Lst makefiles; /* ordered list of makefiles to read */
-int maxJobs; /* -J argument */
+static Boolean printVars; /* print value of one or more vars */
+static Lst variables; /* list of variables to print */
+int maxJobs; /* -j argument */
static int maxLocal; /* -L argument */
Boolean compatMake; /* -B argument */
Boolean debug; /* -d flag */
@@ -122,8 +133,10 @@ Boolean oldVars; /* variable substitution style */
Boolean checkEnvFirst; /* -e flag */
static Boolean jobsRunning; /* TRUE if the jobs might be running */
-static Boolean ReadMakefile();
-static void usage();
+static void MainParseArgs __P((int, char **));
+char * chdir_verify_path __P((char *, char *));
+static int ReadMakefile __P((ClientData, ClientData));
+static void usage __P((void));
static char *curdir; /* startup directory */
static char *objdir; /* where we chdir'ed to */
@@ -150,12 +163,13 @@ MainParseArgs(argc, argv)
extern int optind;
extern char *optarg;
int c;
+ int forceJobs = 0;
optind = 1; /* since we're called more than once */
-#ifdef notyet
-# define OPTFLAGS "BD:I:L:PSd:ef:ij:knqrst"
+#ifdef REMOTE
+# define OPTFLAGS "BD:I:L:PSV:d:ef:ij:km:nqrst"
#else
-# define OPTFLAGS "D:I:d:ef:ij:knqrst"
+# define OPTFLAGS "BD:I:PSV:d:ef:ij:km:nqrst"
#endif
rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
switch(c) {
@@ -169,15 +183,22 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
break;
-#ifdef notyet
+ case 'V':
+ printVars = TRUE;
+ (void)Lst_AtEnd(variables, (ClientData)optarg);
+ Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
+ break;
case 'B':
compatMake = TRUE;
break;
+#ifdef REMOTE
case 'L':
maxLocal = atoi(optarg);
Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
break;
+#endif
case 'P':
usePipes = FALSE;
Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
@@ -186,7 +207,6 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
keepgoing = FALSE;
Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
break;
-#endif
case 'd': {
char *modules = optarg;
@@ -254,7 +274,11 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
break;
case 'j':
+ forceJobs = TRUE;
maxJobs = atoi(optarg);
+#ifndef REMOTE
+ maxLocal = maxJobs;
+#endif
Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
break;
@@ -262,6 +286,11 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
keepgoing = TRUE;
Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
break;
+ case 'm':
+ Dir_AddDir(sysIncPath, optarg);
+ Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
+ Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
+ break;
case 'n':
noExecute = TRUE;
Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
@@ -289,6 +318,13 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
}
}
+ /*
+ * Be compatible if user did not specify -j and did not explicitly
+ * turned compatibility on
+ */
+ if (!compatMake && !forceJobs)
+ compatMake = TRUE;
+
oldVars = TRUE;
/*
@@ -309,7 +345,7 @@ rearg: while((c = getopt(argc, argv, OPTFLAGS)) != EOF) {
optind = 1; /* - */
goto rearg;
}
- (void)Lst_AtEnd(create, (ClientData)strdup(*argv));
+ (void)Lst_AtEnd(create, (ClientData)estrdup(*argv));
}
}
@@ -346,6 +382,34 @@ Main_ParseArgLine(line)
MainParseArgs(argc, argv);
}
+char *
+chdir_verify_path(path, obpath)
+ char *path;
+ char *obpath;
+{
+ struct stat sb;
+
+ if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
+ if (chdir(path)) {
+ (void)fprintf(stderr, "make warning: %s: %s.\n",
+ path, strerror(errno));
+ return 0;
+ }
+ else {
+ if (path[0] != '/') {
+ (void) snprintf(obpath, MAXPATHLEN, "%s/%s",
+ curdir, path);
+ return obpath;
+ }
+ else
+ return path;
+ }
+ }
+
+ return 0;
+}
+
+
/*-
* main --
* The main function, for obvious reasons. Initializes variables
@@ -371,13 +435,29 @@ main(argc, argv)
Lst targs; /* target nodes to create -- passed to Make_Init */
Boolean outOfDate = TRUE; /* FALSE if all targets up to date */
struct stat sb, sa;
- char *p, *p1, *path, *pwd, *getenv(), *getwd();
+ char *p, *p1, *path, *pathp, *pwd;
char mdpath[MAXPATHLEN + 1];
char obpath[MAXPATHLEN + 1];
char cdpath[MAXPATHLEN + 1];
- struct utsname utsname;
char *machine = getenv("MACHINE");
+ Lst sysMkPath; /* Path of sys.mk */
+ char *cp = NULL, *start;
+ /* avoid faults on read-only strings */
+ static char syspath[] = _PATH_DEFSYSPATH;
+#ifdef RLIMIT_NOFILE
+ /*
+ * get rid of resource limit on file descriptors
+ */
+ {
+ struct rlimit rl;
+ if (getrlimit(RLIMIT_NOFILE, &rl) != -1 &&
+ rl.rlim_cur != rl.rlim_max) {
+ rl.rlim_cur = rl.rlim_max;
+ (void) setrlimit(RLIMIT_NOFILE, &rl);
+ }
+ }
+#endif
/*
* Find where we are and take care of PWD for the automounter...
* All this code is so that we know where we are when we start up
@@ -397,7 +477,7 @@ main(argc, argv)
if ((pwd = getenv("PWD")) != NULL) {
if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino &&
- sa.st_dev == sb.st_dev)
+ sa.st_dev == sb.st_dev)
(void) strcpy(curdir, pwd);
}
@@ -410,62 +490,53 @@ main(argc, argv)
* MACHINE_ARCH is always known at compile time.
*/
if (!machine) {
- if (uname(&utsname)) {
+#ifndef MACHINE
+ struct utsname utsname;
+
+ if (uname(&utsname) == -1) {
perror("make: uname");
exit(2);
}
machine = utsname.machine;
+#else
+ machine = MACHINE;
+#endif
}
/*
- * if the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
- * exists, change into it and build there. Once things are
- * initted, have to add the original directory to the search path,
+ * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory
+ * exists, change into it and build there. (If a .${MACHINE} suffix
+ * exists, use that directory instead).
+ * Otherwise check MAKEOBJDIRPREFIX`cwd` (or by default,
+ * _PATH_OBJDIRPREFIX`cwd`) and build there if it exists.
+ * If all fails, use the current directory to build.
+ *
+ * Once things are initted,
+ * have to add the original directory to the search path,
* and modify the paths for the Makefiles apropriately. The
* current directory is also placed as a variable for make scripts.
*/
- if (!(path = getenv("MAKEOBJDIR"))) {
- path = _PATH_OBJDIR;
- (void) sprintf(mdpath, "%s.%s", path, machine);
- }
- else
- (void) strncpy(mdpath, path, MAXPATHLEN + 1);
-
- if (stat(mdpath, &sb) == 0 && S_ISDIR(sb.st_mode)) {
-
- if (chdir(mdpath)) {
- (void)fprintf(stderr, "make warning: %s: %s.\n",
- mdpath, strerror(errno));
- objdir = curdir;
- }
- else {
- if (mdpath[0] != '/') {
- (void) sprintf(obpath, "%s/%s", curdir, mdpath);
- objdir = obpath;
- }
- else
- objdir = mdpath;
+ if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
+ if (!(path = getenv("MAKEOBJDIR"))) {
+ path = _PATH_OBJDIR;
+ pathp = _PATH_OBJDIRPREFIX;
+ (void) snprintf(mdpath, MAXPATHLEN, "%s.%s",
+ path, machine);
+ if (!(objdir = chdir_verify_path(mdpath, obpath)))
+ if (!(objdir=chdir_verify_path(path, obpath))) {
+ (void) snprintf(mdpath, MAXPATHLEN,
+ "%s%s", pathp, curdir);
+ if (!(objdir=chdir_verify_path(mdpath,
+ obpath)))
+ objdir = curdir;
+ }
}
+ else if (!(objdir = chdir_verify_path(path, obpath)))
+ objdir = curdir;
}
else {
- if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
-
- if (chdir(path)) {
- (void)fprintf(stderr, "make warning: %s: %s.\n",
- path, strerror(errno));
- objdir = curdir;
- }
- else {
- if (path[0] != '/') {
- (void) sprintf(obpath, "%s/%s", curdir,
- path);
- objdir = obpath;
- }
- else
- objdir = obpath;
- }
- }
- else
+ (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
+ if (!(objdir = chdir_verify_path(mdpath, obpath)))
objdir = curdir;
}
@@ -473,6 +544,8 @@ main(argc, argv)
create = Lst_Init(FALSE);
makefiles = Lst_Init(FALSE);
+ printVars = FALSE;
+ variables = Lst_Init(FALSE);
beSilent = FALSE; /* Print commands as executed */
ignoreErrors = FALSE; /* Pay attention to non-zero returns */
noExecute = FALSE; /* Execute all commands */
@@ -485,14 +558,14 @@ main(argc, argv)
debug = 0; /* No debug verbosity, please. */
jobsRunning = FALSE;
- maxJobs = DEFMAXJOBS; /* Set default max concurrency */
maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */
-#ifdef notyet
- compatMake = FALSE; /* No compat mode */
+#ifdef REMOTE
+ maxJobs = DEFMAXJOBS; /* Set default max concurrency */
#else
- compatMake = TRUE; /* No compat mode */
+ maxJobs = maxLocal;
#endif
-
+ compatMake = FALSE; /* No compat mode */
+
/*
* Initialize the parsing, directory and variable modules to prepare
@@ -535,7 +608,7 @@ main(argc, argv)
#else
Main_ParseArgLine(getenv("MAKE"));
#endif
-
+
MainParseArgs(argc, argv);
/*
@@ -566,13 +639,41 @@ main(argc, argv)
} else
Var_Set(".TARGETS", "", VAR_GLOBAL);
+
+ /*
+ * If no user-supplied system path was given (through the -m option)
+ * add the directories from the DEFSYSPATH (more than one may be given
+ * as dir1:...:dirn) to the system include path.
+ */
+ if (Lst_IsEmpty(sysIncPath)) {
+ for (start = syspath; *start != '\0'; start = cp) {
+ for (cp = start; *cp != '\0' && *cp != ':'; cp++)
+ continue;
+ if (*cp == '\0') {
+ Dir_AddDir(sysIncPath, start);
+ } else {
+ *cp++ = '\0';
+ Dir_AddDir(sysIncPath, start);
+ }
+ }
+ }
+
/*
- * Read in the built-in rules first, followed by the specified makefile,
- * if it was (makefile != (char *) NULL), or the default Makefile and
- * makefile, in that order, if it wasn't.
+ * Read in the built-in rules first, followed by the specified
+ * makefile, if it was (makefile != (char *) NULL), or the default
+ * Makefile and makefile, in that order, if it wasn't.
*/
- if (!noBuiltins && !ReadMakefile(_PATH_DEFSYSMK))
- Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
+ if (!noBuiltins) {
+ LstNode ln;
+
+ sysMkPath = Lst_Init (FALSE);
+ Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath);
+ if (Lst_IsEmpty(sysMkPath))
+ Fatal("make: no system rules (%s).", _PATH_DEFSYSMK);
+ ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile);
+ if (ln != NILLNODE)
+ Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
+ }
if (!Lst_IsEmpty(makefiles)) {
LstNode ln;
@@ -580,10 +681,10 @@ main(argc, argv)
ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile);
if (ln != NILLNODE)
Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
- } else if (!ReadMakefile("makefile"))
- (void)ReadMakefile("Makefile");
+ } else if (!ReadMakefile("makefile", NULL))
+ (void)ReadMakefile("Makefile", NULL);
- (void)ReadMakefile(".depend");
+ (void)ReadMakefile(".depend", NULL);
Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL);
if (p1)
@@ -641,6 +742,21 @@ main(argc, argv)
if (DEBUG(GRAPH1))
Targ_PrintGraph(1);
+ /* print the values of any variables requested by the user */
+ if (printVars) {
+ LstNode ln;
+
+ for (ln = Lst_First(variables); ln != NILLNODE;
+ ln = Lst_Succ(ln)) {
+ char *value = Var_Value((char *)Lst_Datum(ln),
+ VAR_GLOBAL, &p1);
+
+ printf("%s\n", value ? value : "");
+ if (p1)
+ free(p1);
+ }
+ }
+
/*
* Have now read the entire graph and need to make a list of targets
* to create. If none was given on the command line, we consult the
@@ -651,11 +767,7 @@ main(argc, argv)
else
targs = Targ_FindList(create, TARG_CREATE);
-/*
- * this was original amMake -- want to allow parallelism, so put this
- * back in, eventually.
- */
- if (!compatMake) {
+ if (!compatMake && !printVars) {
/*
* Initialize job module before traversing the graph, now that
* any .BEGIN and .END targets have been read. This is done
@@ -671,14 +783,16 @@ main(argc, argv)
/* Traverse the graph, checking on all the targets */
outOfDate = Make_Run(targs);
- } else
+ } else if (!printVars) {
/*
* Compat_Init will take care of creating all the targets as
* well as initializing the module.
*/
Compat_Run(targs);
-
+ }
+
Lst_Destroy(targs, NOFREE);
+ Lst_Destroy(variables, NOFREE);
Lst_Destroy(makefiles, NOFREE);
Lst_Destroy(create, (void (*) __P((ClientData))) free);
@@ -711,10 +825,11 @@ main(argc, argv)
* lots
*/
static Boolean
-ReadMakefile(fname)
- char *fname; /* makefile to read */
+ReadMakefile(p, q)
+ ClientData p, q;
{
- extern Lst parseIncPath, sysIncPath;
+ char *fname = p; /* makefile to read */
+ extern Lst parseIncPath;
FILE *stream;
char *name, path[MAXPATHLEN + 1];
@@ -752,6 +867,142 @@ found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
}
/*-
+ * Cmd_Exec --
+ * Execute the command in cmd, and return the output of that command
+ * in a string.
+ *
+ * Results:
+ * A string containing the output of the command, or the empty string
+ * If err is not NULL, it contains the reason for the command failure
+ *
+ * Side Effects:
+ * The string must be freed by the caller.
+ */
+char *
+Cmd_Exec(cmd, err)
+ char *cmd;
+ char **err;
+{
+ char *args[4]; /* Args for invoking the shell */
+ int fds[2]; /* Pipe streams */
+ int cpid; /* Child PID */
+ int pid; /* PID from wait() */
+ char *res; /* result */
+ int status; /* command exit status */
+ Buffer buf; /* buffer to store the result */
+ char *cp;
+ int cc;
+
+
+ *err = NULL;
+
+ /*
+ * Set up arguments for shell
+ */
+ args[0] = "sh";
+ args[1] = "-c";
+ args[2] = cmd;
+ args[3] = NULL;
+
+ /*
+ * Open a pipe for fetching its output
+ */
+ if (pipe(fds) == -1) {
+ *err = "Couldn't create pipe for \"%s\"";
+ goto bad;
+ }
+
+ /*
+ * Fork
+ */
+ switch (cpid = vfork()) {
+ case 0:
+ /*
+ * Close input side of pipe
+ */
+ (void) close(fds[0]);
+
+ /*
+ * Duplicate the output stream to the shell's output, then
+ * shut the extra thing down. Note we don't fetch the error
+ * stream...why not? Why?
+ */
+ (void) dup2(fds[1], 1);
+ (void) close(fds[1]);
+
+ (void) execv("/bin/sh", args);
+ _exit(1);
+ /*NOTREACHED*/
+
+ case -1:
+ *err = "Couldn't exec \"%s\"";
+ goto bad;
+
+ default:
+ /*
+ * No need for the writing half
+ */
+ (void) close(fds[1]);
+
+ buf = Buf_Init (MAKE_BSIZE);
+
+ do {
+ char result[BUFSIZ];
+ cc = read(fds[0], result, sizeof(result));
+ if (cc > 0)
+ Buf_AddBytes(buf, cc, (Byte *) result);
+ }
+ while (cc > 0 || (cc == -1 && errno == EINTR));
+
+ /*
+ * Close the input side of the pipe.
+ */
+ (void) close(fds[0]);
+
+ /*
+ * Wait for the process to exit.
+ */
+ while(((pid = wait(&status)) != cpid) && (pid >= 0))
+ continue;
+
+ res = (char *)Buf_GetAll (buf, &cc);
+ Buf_Destroy (buf, FALSE);
+
+ if (cc == 0)
+ *err = "Couldn't read shell's output for \"%s\"";
+
+ if (status)
+ *err = "\"%s\" returned non-zero status";
+
+ /*
+ * Null-terminate the result, convert newlines to spaces and
+ * install it in the variable.
+ */
+ res[cc] = '\0';
+ cp = &res[cc] - 1;
+
+ if (*cp == '\n') {
+ /*
+ * A final newline is just stripped
+ */
+ *cp-- = '\0';
+ }
+ while (cp >= res) {
+ if (*cp == '\n') {
+ *cp = ' ';
+ }
+ cp--;
+ }
+ break;
+ }
+ return res;
+bad:
+ res = emalloc(1);
+ *res = '\0';
+ return res;
+}
+
+/*-
* Error --
* Print an error message given its format.
*
@@ -833,7 +1084,7 @@ Fatal(va_alist)
* a message and exits.
*
* Results:
- * None
+ * None
*
* Side Effects:
* All children are killed indiscriminately and the program Lib_Exits
@@ -889,10 +1140,10 @@ DieHorribly()
/*
* Finish --
* Called when aborting due to errors in child shell to signal
- * abnormal exit.
+ * abnormal exit.
*
* Results:
- * None
+ * None
*
* Side Effects:
* The program exits
@@ -908,18 +1159,47 @@ Finish(errors)
* emalloc --
* malloc, but die on error.
*/
-char *
+void *
emalloc(len)
size_t len;
{
+ void *p;
+
+ if ((p = malloc(len)) == NULL)
+ enomem();
+ return(p);
+}
+
+/*
+ * estrdup --
+ * strdup, but die on error.
+ */
+char *
+estrdup(str)
+ const char *str;
+{
char *p;
- if ((p = (char *) malloc(len)) == NULL)
+ if ((p = strdup(str)) == NULL)
enomem();
return(p);
}
/*
+ * erealloc --
+ * realloc, but die on error.
+ */
+void *
+erealloc(ptr, size)
+ void *ptr;
+ size_t size;
+{
+ if ((ptr = realloc(ptr, size)) == NULL)
+ enomem();
+ return(ptr);
+}
+
+/*
* enomem --
* die when out of memory.
*/
@@ -931,6 +1211,26 @@ enomem()
}
/*
+ * enunlink --
+ * Remove a file carefully, avoiding directories.
+ */
+int
+eunlink(file)
+ const char *file;
+{
+ struct stat st;
+
+ if (lstat(file, &st) == -1)
+ return -1;
+
+ if (S_ISDIR(st.st_mode)) {
+ errno = EISDIR;
+ return -1;
+ }
+ return unlink(file);
+}
+
+/*
* usage --
* exit with usage message
*/
@@ -938,8 +1238,9 @@ static void
usage()
{
(void)fprintf(stderr,
-"usage: make [-eiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
- [-I directory] [-j max_jobs] [variable=value]\n");
+"usage: make [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\
+ [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\
+ [variable=value] [target ...]\n");
exit(2);
}
diff --git a/usr.bin/make/make.1 b/usr.bin/make/make.1
index b1392cc6e944..64efe0a89632 100644
--- a/usr.bin/make/make.1
+++ b/usr.bin/make/make.1
@@ -1,3 +1,5 @@
+.\" $NetBSD: make.1,v 1.15 1996/08/30 17:59:40 thorpej Exp $
+.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
@@ -29,9 +31,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" @(#)make.1 8.8 (Berkeley) 6/13/95
+.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
.\"
-.Dd June 13, 1995
+.Dd March 19, 1994
.Dt MAKE 1
.Os
.Sh NAME
@@ -39,14 +41,16 @@
.Nd maintain program dependencies
.Sh SYNOPSIS
.Nm make
-.Op Fl eiknqrstv
+.Op Fl Beiknqrst
.Op Fl D Ar variable
.Op Fl d Ar flags
.Op Fl f Ar makefile
.Op Fl I Ar directory
.Bk -words
.Op Fl j Ar max_jobs
+.Op Fl m Ar directory
.Ek
+.Op Fl V Ar variable
.Op Ar variable=value
.Op Ar target ...
.Sh DESCRIPTION
@@ -73,6 +77,9 @@ and makefiles, please refer to
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl B
+Try to be backwards compatible by executing a single shell per command and
+by executing the commands to make the sources of a dependency line in sequence.
.It Fl D Ar variable
Define
.Ar variable
@@ -126,8 +133,9 @@ standard input is read.
Multiple makefile's may be specified, and are read in the order specified.
.It Fl I Ar directory
Specify a directory in which to search for makefiles and included makefiles.
-The system makefile directory is automatically included as part of this
-list.
+The system makefile directory (or directories, see the
+.Fl m
+option) is automatically included as part of this list.
.It Fl i
Ignore non-zero exit of shell commands in the makefile.
Equivalent to specifying
@@ -136,10 +144,20 @@ before each command line in the makefile.
.It Fl j Ar max_jobs
Specify the maximum number of jobs that
.Nm make
-may have running at any one time.
+may have running at any one time. Turns compatibility mode off, unless the
+.Ar B
+flag is also specified.
.It Fl k
Continue processing after errors are encountered, but only on those targets
that do not depend on the target whose creation caused the error.
+.It Fl m Ar directory
+Specify a directory in which to search for sys.mk and makefiles included
+via the <...> style. Multiple directories can be added to form a search path.
+This path will override the default system include path: /usr/share/mk.
+Furthermore the system include path will be appended to the search path used
+for "..."-style inclusions (see the
+.Fl I
+option).
.It Fl n
Display the commands that would have been executed, but do not actually
execute them.
@@ -156,6 +174,16 @@ before each command line in the makefile.
.It Fl t
Rather than re-building a target as specified in the makefile, create it
or update its modification time to make it appear up-to-date.
+.It Fl V Ar variable
+Print
+.Nm make Ns 's
+idea of the value of
+.Ar variable ,
+in the global context.
+Do not build any targets.
+Multiple instances of this option may be specified;
+the variables will be printed one per line,
+with a blank line for each null or undefined variable.
.It Ar variable=value
Set the value of the variable
.Ar variable
@@ -400,6 +428,28 @@ variable which is then
entered into the environment for all programs which
.Nm make
executes.
+.It Ev PWD
+Alternate path to the current directory.
+.Nm make
+normally sets
+.Ql Va .CURDIR
+to the canonical path given by
+.Xr getcwd 2 .
+However, if the environment variable
+.Ql Ev PWD
+is set and gives a path to the current directory, then
+.Nm make
+sets
+.Ql Va .CURDIR
+to the value of
+.Ql Ev PWD
+instead.
+.Ql Ev PWD
+is set to the value of
+.Ql Va .OBJDIR
+for all programs which
+.Nm make
+executes.
.El
.Pp
Variable expansion may be modified to select or modify each word of the
@@ -487,23 +537,23 @@ This is the
.At V
style variable substitution.
It must be the last modifier specified.
-If
+If
.Ar old_string
or
.Ar new_string
do not contain the pattern matching character
.Ar %
-then it is assumed that they are
+then it is assumed that they are
anchored at the end of each word, so only suffixes or entire
-words may be replaced. Otherwise
+words may be replaced. Otherwise
.Ar %
-is the substring of
-.Ar old_string
+is the substring of
+.Ar old_string
to be replaced in
.Ar new_string
.El
.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
-Makefile inclusion, conditional structures and for loops reminiscent
+Makefile inclusion, conditional structures and for loops reminiscent
of the C programming language are provided in
.Nm make .
All such structures are identified by a line beginning with a single
@@ -629,7 +679,7 @@ As in C,
.Nm make
will only evaluate a conditional as far as is necessary to determine
its value.
-Parenthesis may be used to change the order of evaluation.
+Parentheses may be used to change the order of evaluation.
The boolean operator
.Ql Ic \&!
may be used to logically negate an entire
@@ -705,14 +755,14 @@ In both cases this continues until a
or
.Ql Ic .endif
is found.
-.Pp
+.Pp
For loops are typically used to apply a set of rules to a list of files.
The syntax of a for loop is:
.Bl -tag -width Ds
.It Xo
.Ic \&.for
-.Ar variable
-.Ic in
+.Ar variable
+.Ic in
.Ar expression
.Xc
.It Xo
@@ -723,12 +773,12 @@ The syntax of a for loop is:
.Xc
.El
After the for
-.Ic expression
-is evaluated, it is split into words. The
+.Ic expression
+is evaluated, it is split into words. The
iteration
.Ic variable
-is successively set to each word, and substituted in the
-.Ic make-rules
+is successively set to each word, and substituted in the
+.Ic make-rules
inside the body of the for loop.
.Sh COMMENTS
Comments begin with a hash
@@ -760,12 +810,6 @@ If a target is marked with this attribute and
.Nm make
can't figure out how to create it, it will ignore this fact and assume
the file isn't needed or already exists.
-.It Ic .PHONY
-If this special target is present in a Makefile, all sources for the
-target will considered to be `phony' targets. I.e. they don't refer
-to real files, and they will always be considered out-of-date. This
-is useful in case one wants to create a target called `install', in
-a directory where a file `install' already exists.
.It Ic .PRECIOUS
When
.Nm make
@@ -788,6 +832,12 @@ If the target already has commands, the
.Ic .USE
target's commands are appended
to them.
+.It Ic .WAIT
+If special
+.Ic .WAIT
+source is appears in a dependency line, the sources that precede it are
+made before the sources that succeed it in the line. Loops are not being
+detected and targets that form loops will be silently ignored.
.El
.Sh "SPECIAL TARGETS"
Special targets may not be included with other targets, i.e. they must be
@@ -836,11 +886,30 @@ The flags are as if typed to the shell, though the
.Fl f
option will have
no effect.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .NOTPARALLEL
+.\" The named targets are executed in non parallel mode. If no targets are
+.\" specified, then all targets are executed in non parallel mode.
+.It Ic .NOTPARALLEL
+Disable parallel mode.
+.It Ic .NO_PARALLEL
+Same as above, for compatibility with other pmake variants.
+.It Ic .ORDER
+The named targets are made in sequence.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .PARALLEL
+.\" The named targets are executed in parallel mode. If no targets are
+.\" specified, then all targets are executed in parallel mode.
.It Ic .PATH
The sources are directories which are to be searched for files not
found in the current directory.
If no sources are specified, any previously specified directories are
deleted.
+.It Ic .PHONY
+Apply the
+.Ic .PHONY
+attribute to any specified sources. Targets with this attribute are always
+considered to be out of date.
.It Ic .PRECIOUS
Apply the
.Ic .PRECIOUS
@@ -864,10 +933,12 @@ If no sources are specified, any previous specified suffices are deleted.
.Sh ENVIRONMENT
.Nm Make
utilizes the following environment variables, if they exist:
+.Ev MACHINE ,
.Ev MAKE ,
-.Ev MAKEFLAGS
+.Ev MAKEFLAGS ,
+.Ev MAKEOBJDIR ,
and
-.Ev MAKEOBJDIR .
+.Ev PWD .
.Sh FILES
.Bl -tag -width /usr/share/mk -compact
.It .depend
diff --git a/usr.bin/make/make.c b/usr.bin/make/make.c
index 6d17b2ed87f3..68a579bf4865 100644
--- a/usr.bin/make/make.c
+++ b/usr.bin/make/make.c
@@ -1,3 +1,5 @@
+/* $NetBSD: make.c,v 1.9 1996/08/30 23:21:10 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)make.c 8.3 (Berkeley) 6/13/95";
+#if 0
+static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93";
+#else
+static char rcsid[] = "$NetBSD: make.c,v 1.9 1996/08/30 23:21:10 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -96,10 +102,10 @@ static int MakePrintStatus __P((ClientData, ClientData));
*-----------------------------------------------------------------------
* Make_TimeStamp --
* Set the cmtime field of a parent node based on the mtime stamp in its
- * child. Called from MakeOODate via Lst_ForEach.
+ * child. Called from MakeOODate via Lst_ForEach.
*
* Results:
- * Always returns 0.
+ * Always returns 0.
*
* Side Effects:
* The cmtime of the parent node will be changed if the mtime
@@ -136,7 +142,7 @@ MakeTimeStamp (pgn, cgn)
* will have been recreated.
*
* Results:
- * TRUE if the node is out of date. FALSE otherwise.
+ * TRUE if the node is out of date. FALSE otherwise.
*
* Side Effects:
* The mtime field of the node and the cmtime field of its parents
@@ -153,7 +159,7 @@ Make_OODate (gn)
* Certain types of targets needn't even be sought as their datedness
* doesn't depend on their modification time...
*/
- if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC|OP_PHONY)) == 0) {
+ if ((gn->type & (OP_JOIN|OP_USE|OP_EXEC)) == 0) {
(void) Dir_MTime (gn);
if (DEBUG(MAKE)) {
if (gn->mtime != 0) {
@@ -178,14 +184,7 @@ Make_OODate (gn)
* These weird rules are brought to you by Backward-Compatability and
* the strange people who wrote 'Make'.
*/
- if (gn->type & OP_PHONY) {
- /*
- * A PHONY node is always out of date
- */
- if (DEBUG(MAKE))
- printf("phony...");
- return TRUE;
- } else if (gn->type & OP_USE) {
+ if (gn->type & OP_USE) {
/*
* If the node is a USE node it is *never* out of date
* no matter *what*.
@@ -214,7 +213,7 @@ Make_OODate (gn)
printf(".JOIN node...");
}
oodate = gn->childMade;
- } else if (gn->type & (OP_FORCE|OP_EXEC)) {
+ } else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
/*
* A node which is the object of the force (!) operator or which has
* the .EXEC attribute is always considered out-of-date.
@@ -222,6 +221,8 @@ Make_OODate (gn)
if (DEBUG(MAKE)) {
if (gn->type & OP_FORCE) {
printf("! operator...");
+ } else if (gn->type & OP_PHONY) {
+ printf(".PHONY node...");
} else {
printf(".EXEC node...");
}
@@ -339,7 +340,7 @@ Make_HandleUse (cgn, pgn)
*/
(void) Lst_Concat (pgn->commands, cgn->commands, LST_CONCNEW);
}
-
+
if (Lst_Open (cgn->children) == SUCCESS) {
while ((ln = Lst_Next (cgn->children)) != NILLNODE) {
gn = (GNode *)Lst_Datum (ln);
@@ -352,7 +353,7 @@ Make_HandleUse (cgn, pgn)
}
Lst_Close (cgn->children);
}
-
+
pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_TRANSFORM);
/*
@@ -381,7 +382,7 @@ MakeHandleUse (pgn, cgn)
* Make_Update --
* Perform update on the parents of a node. Used by JobFinish once
* a node has been dealt with and by MakeStartJobs if it finds an
- * up-to-date node.
+ * up-to-date node.
*
* Results:
* Always returns 0
@@ -480,7 +481,7 @@ Make_Update (cgn)
}
#endif
}
-
+
if (Lst_Open (cgn->parents) == SUCCESS) {
while ((ln = Lst_Next (cgn->parents)) != NILLNODE) {
pgn = (GNode *)Lst_Datum (ln);
@@ -525,7 +526,7 @@ Make_Update (cgn)
(void)Lst_EnQueue(toBeMade, (ClientData)succ);
}
}
-
+
/*
* Set the .PREFIX and .IMPSRC variables for all the implied parents
* of this node.
@@ -577,9 +578,16 @@ MakeAddAllSrc (cgnp, pgnp)
GNode *pgn = (GNode *) pgnp;
if ((cgn->type & (OP_EXEC|OP_USE|OP_INVISIBLE)) == 0) {
char *child;
- char *p1;
+ char *p1 = NULL;
- child = Var_Value(TARGET, cgn, &p1);
+ if (OP_NOP(cgn->type)) {
+ /*
+ * this node is only source; use the specific pathname for it
+ */
+ child = cgn->path ? cgn->path : cgn->name;
+ }
+ else
+ child = Var_Value(TARGET, cgn, &p1);
Var_Append (ALLSRC, child, pgn);
if (pgn->type & OP_JOIN) {
if (cgn->made == MADE) {
@@ -675,7 +683,7 @@ static Boolean
MakeStartJobs ()
{
register GNode *gn;
-
+
while (!Job_Full() && !Lst_IsEmpty (toBeMade)) {
gn = (GNode *) Lst_DeQueue (toBeMade);
if (DEBUG(MAKE)) {
@@ -708,7 +716,7 @@ MakeStartJobs ()
continue;
}
}
-
+
numNodes--;
if (Make_OODate (gn)) {
if (DEBUG(MAKE)) {
@@ -733,7 +741,7 @@ MakeStartJobs ()
*/
Make_DoAllVar (gn);
}
-
+
Make_Update (gn);
}
}
@@ -828,22 +836,22 @@ Make_Run (targs)
examine = Lst_Duplicate(targs, NOCOPY);
numNodes = 0;
-
+
/*
* Make an initial downward pass over the graph, marking nodes to be made
* as we go down. We call Suff_FindDeps to find where a node is and
* to get some children for it if it has none and also has no commands.
* If the node is a leaf, we stick it on the toBeMade queue to
* be looked at in a minute, otherwise we add its children to our queue
- * and go on about our business.
+ * and go on about our business.
*/
while (!Lst_IsEmpty (examine)) {
gn = (GNode *) Lst_DeQueue (examine);
-
+
if (!gn->make) {
gn->make = TRUE;
numNodes++;
-
+
/*
* Apply any .USE rules before looking for implicit dependencies
* to make sure everything has commands that should...
@@ -858,7 +866,7 @@ Make_Run (targs)
}
}
}
-
+
Lst_Destroy (examine, NOFREE);
if (queryFlag) {
@@ -874,7 +882,7 @@ Make_Run (targs)
* get started, nothing will happen since the remaining upward
* traversal of the graph is performed by the routines in job.c upon
* the finishing of a job. So we fill the Job table as much as we can
- * before going into our loop.
+ * before going into our loop.
*/
(void) MakeStartJobs();
}
@@ -903,6 +911,6 @@ Make_Run (targs)
*/
errors = ((errors == 0) && (numNodes != 0));
Lst_ForEach(targs, MakePrintStatus, (ClientData) &errors);
-
+
return (TRUE);
}
diff --git a/usr.bin/make/make.h b/usr.bin/make/make.h
index 3af67f7e4157..c0fe81b68dbf 100644
--- a/usr.bin/make/make.h
+++ b/usr.bin/make/make.h
@@ -1,3 +1,5 @@
+/* $NetBSD: make.h,v 1.10 1996/08/13 16:39:30 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)make.h 8.3 (Berkeley) 6/13/95
+ * from: @(#)make.h 8.3 (Berkeley) 6/13/95
*/
/*-
@@ -50,13 +52,15 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#ifndef MAKE_BOOTSTRAP
+#if !defined(MAKE_BOOTSTRAP) && defined(BSD)
#include <sys/cdefs.h>
#else
+#ifndef __P
#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos) protos /* full-blown ANSI C */
#else
-#define __P(protos) () /* traditional C preprocessor */
+#define __P(protos) () /* traditional C preprocessor */
+#endif
#endif
#endif
#if __STDC__
@@ -94,12 +98,13 @@
* 16) a Lst of ``local'' variables that are specific to this target
* and this target only (qv. var.c [$@ $< $?, etc.])
* 17) a Lst of strings that are commands to be given to a shell
- * to create this target.
+ * to create this target.
*/
typedef struct GNode {
char *name; /* The target's name */
char *path; /* The full pathname of the file */
int type; /* Its type (see the OP flags, below) */
+ int order; /* Its wait weight */
Boolean make; /* TRUE if this target needs to be remade */
enum {
@@ -150,7 +155,7 @@ typedef struct GNode {
} GNode;
/*
- * Manifest constants
+ * Manifest constants
*/
#define NILGNODE ((GNode *) NIL)
@@ -161,7 +166,7 @@ typedef struct GNode {
* placed in the 'type' field of each node. Any node that has
* a 'type' field which satisfies the OP_NOP function was never never on
* the lefthand side of an operator, though it may have been on the
- * righthand side...
+ * righthand side...
*/
#define OP_DEPENDS 0x00000001 /* Execution of commands depends on
* kids (:) */
@@ -216,7 +221,7 @@ typedef struct GNode {
* do if the desired node(s) is (are) not found. If the TARG_CREATE constant
* is given, a new, empty node will be created for the target, placed in the
* table of all targets and its address returned. If TARG_NOCREATE is given,
- * a NIL pointer will be returned.
+ * a NIL pointer will be returned.
*/
#define TARG_CREATE 0x01 /* create node if not found */
#define TARG_NOCREATE 0x00 /* don't create it */
@@ -228,7 +233,7 @@ typedef struct GNode {
* If longer, it should be increased. Reducing it will cause more copying to
* be done for longer lines, but will save space for shorter ones. In any
* case, it ought to be a power of two simply because most storage allocation
- * schemes allocate in powers of two.
+ * schemes allocate in powers of two.
*/
#define MAKE_BSIZE 256 /* starting size for expandable buffers */
@@ -239,7 +244,7 @@ typedef struct GNode {
* be used instead of a space. If neither is given, no intervening characters
* will be placed between the two strings in the final output. If the
* STR_DOFREE bit is set, the two input strings will be freed before
- * Str_Concat returns.
+ * Str_Concat returns.
*/
#define STR_ADDSPACE 0x01 /* add a space when Str_Concat'ing */
#define STR_DOFREE 0x02 /* free source strings after concatenation */
@@ -279,7 +284,7 @@ typedef struct GNode {
#define DPREFIX "*D" /* directory part of PREFIX */
/*
- * Global Variables
+ * Global Variables
*/
extern Lst create; /* The list of target names specified on the
* command line. used to resolve #if
@@ -323,6 +328,8 @@ extern time_t now; /* The time at the start of this whole
extern Boolean oldVars; /* Do old-style variable substitution */
+extern Lst sysIncPath; /* The system include path. */
+
/*
* debug control:
* There is one bit per module. It is up to the module what debug
diff --git a/usr.bin/make/nonints.h b/usr.bin/make/nonints.h
index 039d4b967ed2..705412654fd7 100644
--- a/usr.bin/make/nonints.h
+++ b/usr.bin/make/nonints.h
@@ -1,3 +1,5 @@
+/* $NetBSD: nonints.h,v 1.11 1996/08/13 16:42:11 christos Exp $ */
+
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)nonints.h 8.4 (Berkeley) 4/28/95
+ * from: @(#)nonints.h 8.3 (Berkeley) 3/19/94
*/
/* arch.c */
@@ -63,14 +65,18 @@ void For_Run __P((void));
/* main.c */
void Main_ParseArgLine __P((char *));
int main __P((int, char **));
+char *Cmd_Exec __P((char *, char **));
void Error __P((char *, ...));
void Fatal __P((char *, ...));
void Punt __P((char *, ...));
void DieHorribly __P((void));
int PrintAddr __P((ClientData, ClientData));
void Finish __P((int));
-char *emalloc __P((size_t));
+char *estrdup __P((const char *));
+void *emalloc __P((size_t));
+void *erealloc __P((void *, size_t));
void enomem __P((void));
+int eunlink __P((const char *));
/* parse.c */
void Parse_Error __P((int, char *, ...));
diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c
index e4d8446279bd..669c68a15436 100644
--- a/usr.bin/make/parse.c
+++ b/usr.bin/make/parse.c
@@ -1,3 +1,5 @@
+/* $NetBSD: parse.c,v 1.26 1996/09/27 02:36:58 thorpej Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)parse.c 8.6 (Berkeley) 6/13/95";
+#if 0
+static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94";
+#else
+static char rcsid[] = "$NetBSD: parse.c,v 1.26 1996/09/27 02:36:58 thorpej Exp $";
+#endif
#endif /* not lint */
/*-
@@ -90,7 +96,6 @@ static char sccsid[] = "@(#)parse.c 8.6 (Berkeley) 6/13/95";
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
-#include <sys/wait.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
@@ -162,17 +167,20 @@ typedef enum {
NotParallel, /* .NOTPARALELL */
Null, /* .NULL */
Order, /* .ORDER */
+ Parallel, /* .PARALLEL */
ExPath, /* .PATH */
+ Phony, /* .PHONY */
Precious, /* .PRECIOUS */
- Reserved, /* .RESERVED or .[A-Z]* */
ExShell, /* .SHELL */
Silent, /* .SILENT */
SingleShell, /* .SINGLESHELL */
Suffixes, /* .SUFFIXES */
+ Wait, /* .WAIT */
Attribute /* Generic attribute */
} ParseSpecial;
static ParseSpecial specType;
+static int waiting;
/*
* Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER
@@ -192,70 +200,44 @@ static struct {
ParseSpecial spec; /* Type when used as a target */
int op; /* Operator when used as a source */
} parseKeywords[] = {
-#define DOT_BEGIN 0
{ ".BEGIN", Begin, 0 },
-#define DOT_DEFAULT 1
{ ".DEFAULT", Default, 0 },
-#define DOT_END 2
{ ".END", End, 0 },
-#define DOT_EXEC 3
{ ".EXEC", Attribute, OP_EXEC },
-#define DOT_IGNORE 4
{ ".IGNORE", Ignore, OP_IGNORE },
-#define DOT_INCLUDES 5
{ ".INCLUDES", Includes, 0 },
-#define DOT_INTERRUPT 6
{ ".INTERRUPT", Interrupt, 0 },
-#define DOT_INVISIBLE 7
{ ".INVISIBLE", Attribute, OP_INVISIBLE },
-#define DOT_JOIN 8
{ ".JOIN", Attribute, OP_JOIN },
-#define DOT_LIBS 9
{ ".LIBS", Libs, 0 },
-#define DOT_MAIN 10
{ ".MAIN", Main, 0 },
-#define DOT_MAKE 11
{ ".MAKE", Attribute, OP_MAKE },
-#define DOT_MAKEFLAGS 12
{ ".MAKEFLAGS", MFlags, 0 },
-#define DOT_MFLAGS 13
{ ".MFLAGS", MFlags, 0 },
-#define DOT_NOTMAIN 14
{ ".NOTMAIN", Attribute, OP_NOTMAIN },
-#define DOT_NOTPARALLEL 15
{ ".NOTPARALLEL", NotParallel, 0 },
-#define DOT_NULL 16
+{ ".NO_PARALLEL", NotParallel, 0 },
{ ".NULL", Null, 0 },
-#define DOT_OPTIONAL 17
{ ".OPTIONAL", Attribute, OP_OPTIONAL },
-#define DOT_ORDER 18
{ ".ORDER", Order, 0 },
-#define DOT_PATH 19
+{ ".PARALLEL", Parallel, 0 },
{ ".PATH", ExPath, 0 },
-#define DOT_PHONY 20
-{ ".PHONY", Attribute, OP_PHONY },
-#define DOT_PRECIOUS 21
+{ ".PHONY", Phony, OP_PHONY },
{ ".PRECIOUS", Precious, OP_PRECIOUS },
-#define DOT_RECURSIVE 22
{ ".RECURSIVE", Attribute, OP_MAKE },
-#define DOT_RESERVED 23
-{ ".RESERVED", Reserved, 0 },
-#define DOT_SHELL 24
{ ".SHELL", ExShell, 0 },
-#define DOT_SILENT 25
{ ".SILENT", Silent, OP_SILENT },
-#define DOT_SINGLESHELL 26
{ ".SINGLESHELL", SingleShell, 0 },
-#define DOT_SUFFIXES 27
{ ".SUFFIXES", Suffixes, 0 },
-#define DOT_USE 28
{ ".USE", Attribute, OP_USE },
+{ ".WAIT", Wait, 0 },
};
static int ParseFindKeyword __P((char *));
static int ParseLinkSrc __P((ClientData, ClientData));
static int ParseDoOp __P((ClientData, ClientData));
-static void ParseDoSrc __P((int, char *));
+static int ParseAddDep __P((ClientData, ClientData));
+static void ParseDoSrc __P((int, char *, Lst));
static int ParseFindMain __P((ClientData, ClientData));
static int ParseAddDir __P((ClientData, ClientData));
static int ParseClearPath __P((ClientData, ClientData));
@@ -293,7 +275,7 @@ ParseFindKeyword (str)
end,
cur;
register int diff;
-
+
start = 0;
end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1;
@@ -309,12 +291,7 @@ ParseFindKeyword (str)
start = cur + 1;
}
} while (start <= end);
-
- cur = 0;
- for (++str; *str; str++)
- if (!isupper((unsigned char) *str))
- break;
- return *str ? -1 : DOT_RESERVED;
+ return (-1);
}
/*-
@@ -421,7 +398,7 @@ ParseDoOp (gnp, opp)
/*
* If the dependency mask of the operator and the node don't match and
* the node has actually had an operator applied to it before, and
- * the operator actually has some dependency information in it, complain.
+ * the operator actually has some dependency information in it, complain.
*/
if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&
!OP_NOP(gn->type) && !OP_NOP(op))
@@ -441,7 +418,7 @@ ParseDoOp (gnp, opp)
*/
register GNode *cohort;
LstNode ln;
-
+
cohort = Targ_NewGN(gn->name);
/*
* Duplicate links to parents so graph traversal is simple. Perhaps
@@ -465,7 +442,7 @@ ParseDoOp (gnp, opp)
}
/*
* We don't want to nuke any previous flags (whatever they were) so we
- * just OR the new operator into the old
+ * just OR the new operator into the old
*/
gn->type |= op;
@@ -474,6 +451,45 @@ ParseDoOp (gnp, opp)
/*-
*---------------------------------------------------------------------
+ * ParseAddDep --
+ * Check if the pair of GNodes given needs to be synchronized.
+ * This has to be when two nodes are on different sides of a
+ * .WAIT directive.
+ *
+ * Results:
+ * Returns 1 if the two targets need to be ordered, 0 otherwise.
+ * If it returns 1, the search can stop
+ *
+ * Side Effects:
+ * A dependency can be added between the two nodes.
+ *
+ *---------------------------------------------------------------------
+ */
+int
+ParseAddDep(pp, sp)
+ ClientData pp;
+ ClientData sp;
+{
+ GNode *p = (GNode *) pp;
+ GNode *s = (GNode *) sp;
+
+ if (p->order < s->order) {
+ /*
+ * XXX: This can cause loops, and loops can cause unmade targets,
+ * but checking is tedious, and the debugging output can show the
+ * problem
+ */
+ (void)Lst_AtEnd(p->successors, (ClientData)s);
+ (void)Lst_AtEnd(s->preds, (ClientData)p);
+ return 0;
+ }
+ else
+ return 1;
+}
+
+
+/*-
+ *---------------------------------------------------------------------
* ParseDoSrc --
* Given the name of a source, figure out if it is an attribute
* and apply it to the targets if it is. Else decide if there is
@@ -490,23 +506,31 @@ ParseDoOp (gnp, opp)
*---------------------------------------------------------------------
*/
static void
-ParseDoSrc (tOp, src)
+ParseDoSrc (tOp, src, allsrc)
int tOp; /* operator (if any) from special targets */
char *src; /* name of the source to handle */
+ Lst allsrc; /* List of all sources to wait for */
+
{
- int op; /* operator (if any) from special source */
- GNode *gn;
+ GNode *gn = NULL;
- op = 0;
if (*src == '.' && isupper (src[1])) {
int keywd = ParseFindKeyword(src);
if (keywd != -1) {
- op = parseKeywords[keywd].op;
+ int op = parseKeywords[keywd].op;
+ if (op != 0) {
+ Lst_ForEach (targets, ParseDoOp, (ClientData)&op);
+ return;
+ }
+ if (parseKeywords[keywd].spec == Wait) {
+ waiting++;
+ return;
+ }
}
}
- if (op != 0) {
- Lst_ForEach (targets, ParseDoOp, (ClientData)&op);
- } else if (specType == Main) {
+
+ switch (specType) {
+ case Main:
/*
* If we have noted the existence of a .MAIN, it means we need
* to add the sources of said target to the list of things
@@ -515,13 +539,15 @@ ParseDoSrc (tOp, src)
* invoked if the user didn't specify a target on the command
* line. This is to allow #ifmake's to succeed, or something...
*/
- (void) Lst_AtEnd (create, (ClientData)strdup(src));
+ (void) Lst_AtEnd (create, (ClientData)estrdup(src));
/*
* Add the name to the .TARGETS variable as well, so the user cna
* employ that, if desired.
*/
Var_Append(".TARGETS", src, VAR_GLOBAL);
- } else if (specType == Order) {
+ return;
+
+ case Order:
/*
* Create proper predecessor/successor links between the previous
* source and the current one.
@@ -535,7 +561,9 @@ ParseDoSrc (tOp, src)
* The current source now becomes the predecessor for the next one.
*/
predecessor = gn;
- } else {
+ break;
+
+ default:
/*
* If the source is not an attribute, we need to find/create
* a node for it. After that we can apply any operator to it
@@ -566,6 +594,13 @@ ParseDoSrc (tOp, src)
}
}
}
+ break;
+ }
+
+ gn->order = waiting;
+ (void)Lst_AtEnd(allsrc, (ClientData)gn);
+ if (waiting) {
+ Lst_ForEach(allsrc, ParseAddDep, (ClientData)gn);
}
}
@@ -688,17 +723,21 @@ ParseDoDependency (line)
Lst paths; /* List of search paths to alter when parsing
* a list of .PATH targets */
int tOp; /* operator from special target */
- Lst sources; /* list of source names after expansion */
+ Lst sources; /* list of archive source names after
+ * expansion */
Lst curTargs; /* list of target names to be found and added
* to the targets list */
+ Lst curSrcs; /* list of sources in order */
tOp = 0;
specType = Not;
+ waiting = 0;
paths = (Lst)NULL;
curTargs = Lst_Init(FALSE);
-
+ curSrcs = Lst_Init(FALSE);
+
do {
for (cp = line;
*cp && !isspace (*cp) &&
@@ -746,11 +785,11 @@ ParseDoDependency (line)
}
}
savec = *cp;
-
+
if (!*cp) {
/*
* Ending a dependency line without an operator is a Bozo
- * no-no
+ * no-no
*/
Parse_Error (PARSE_FATAL, "Need an operator");
return;
@@ -763,7 +802,7 @@ ParseDoDependency (line)
if (*line == '.' && isupper (line[1])) {
/*
* See if the target is a special target that must have it
- * or its sources handled specially.
+ * or its sources handled specially.
*/
int keywd = ParseFindKeyword(line);
if (keywd != -1) {
@@ -771,7 +810,7 @@ ParseDoDependency (line)
Parse_Error(PARSE_FATAL, "Mismatched special targets");
return;
}
-
+
specType = parseKeywords[keywd].spec;
tOp = parseKeywords[keywd].op;
@@ -794,6 +833,7 @@ ParseDoDependency (line)
* life easier later, when we'll
* use Make_HandleUse to actually
* apply the .DEFAULT commands.
+ * .PHONY The list of targets
* .BEGIN
* .END
* .INTERRUPT Are not to be considered the
@@ -830,7 +870,7 @@ ParseDoDependency (line)
case NotParallel:
{
extern int maxJobs;
-
+
maxJobs = 1;
break;
}
@@ -840,12 +880,6 @@ ParseDoDependency (line)
case Order:
predecessor = NILGNODE;
break;
- case Reserved:
- /*
- * A posix reserved target that we don't know
- * how to deal with.
- */
- return;
default:
break;
}
@@ -856,7 +890,7 @@ ParseDoDependency (line)
* modify.
*/
Lst path;
-
+
specType = ExPath;
path = Suff_GetPath (&line[5]);
if (path == NILLST) {
@@ -872,10 +906,10 @@ ParseDoDependency (line)
}
}
}
-
+
/*
* Have word in line. Get or create its node and stick it at
- * the end of the targets list
+ * the end of the targets list
*/
if ((specType == Not) && (*line != '\0')) {
if (Dir_HasWildcards(line)) {
@@ -886,9 +920,9 @@ ParseDoDependency (line)
* Dir module could have added a directory to the path...
*/
Lst emptyPath = Lst_Init(FALSE);
-
+
Dir_Expand(line, emptyPath, curTargs);
-
+
Lst_Destroy(emptyPath, Dir_Destroy);
} else {
/*
@@ -897,22 +931,22 @@ ParseDoDependency (line)
*/
(void)Lst_AtEnd(curTargs, (ClientData)line);
}
-
+
while(!Lst_IsEmpty(curTargs)) {
char *targName = (char *)Lst_DeQueue(curTargs);
-
+
if (!Suff_IsTransform (targName)) {
gn = Targ_FindNode (targName, TARG_CREATE);
} else {
gn = Suff_AddTransform (targName);
}
-
+
(void)Lst_AtEnd (targets, (ClientData)gn);
}
} else if (specType == ExPath && *line != '.' && *line != '\0') {
Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
}
-
+
*cp = savec;
/*
* If it is a special type and not .PATH, it's the only target we
@@ -920,7 +954,7 @@ ParseDoDependency (line)
*/
if (specType != Not && specType != ExPath) {
Boolean warn = FALSE;
-
+
while ((*cp != '!') && (*cp != ':') && *cp) {
if (*cp != ' ' && *cp != '\t') {
warn = TRUE;
@@ -987,7 +1021,7 @@ ParseDoDependency (line)
Lst_ForEach (targets, ParseDoOp, (ClientData)&op);
/*
- * Get to the first source
+ * Get to the first source
*/
while (*cp && isspace (*cp)) {
cp++;
@@ -1040,9 +1074,9 @@ ParseDoDependency (line)
} else if ((specType == NotParallel) || (specType == SingleShell)) {
*line = '\0';
}
-
+
/*
- * NOW GO FOR THE SOURCES
+ * NOW GO FOR THE SOURCES
*/
if ((specType == Suffixes) || (specType == ExPath) ||
(specType == Includes) || (specType == Libs) ||
@@ -1143,7 +1177,7 @@ ParseDoDependency (line)
while (!Lst_IsEmpty (sources)) {
gn = (GNode *) Lst_DeQueue (sources);
- ParseDoSrc (tOp, gn->name);
+ ParseDoSrc (tOp, gn->name, curSrcs);
}
Lst_Destroy (sources, NOFREE);
cp = line;
@@ -1153,7 +1187,7 @@ ParseDoDependency (line)
cp += 1;
}
- ParseDoSrc (tOp, line);
+ ParseDoSrc (tOp, line, curSrcs);
}
while (*cp && isspace (*cp)) {
cp++;
@@ -1161,7 +1195,7 @@ ParseDoDependency (line)
line = cp;
}
}
-
+
if (mainNode == NILGNODE) {
/*
* If we have yet to decide on a main target to make, in the
@@ -1172,6 +1206,10 @@ ParseDoDependency (line)
Lst_ForEach (targets, ParseFindMain, (ClientData)0);
}
+ /*
+ * Finally, destroy the list of sources
+ */
+ Lst_Destroy(curSrcs, NOFREE);
}
/*-
@@ -1196,60 +1234,80 @@ Parse_IsVar (line)
{
register Boolean wasSpace = FALSE; /* set TRUE if found a space */
register Boolean haveName = FALSE; /* Set TRUE if have a variable name */
+ int level = 0;
+#define ISEQOPERATOR(c) \
+ (((c) == '+') || ((c) == ':') || ((c) == '?') || ((c) == '!'))
/*
* Skip to variable name
*/
- while ((*line == ' ') || (*line == '\t')) {
- line++;
- }
+ for (;(*line == ' ') || (*line == '\t'); line++)
+ continue;
- while (*line != '=') {
- if (*line == '\0') {
+ for (; *line != '=' || level != 0; line++)
+ switch (*line) {
+ case '\0':
/*
* end-of-line -- can't be a variable assignment.
*/
- return (FALSE);
- } else if ((*line == ' ') || (*line == '\t')) {
+ return FALSE;
+
+ case ' ':
+ case '\t':
/*
* there can be as much white space as desired so long as there is
- * only one word before the operator
+ * only one word before the operator
*/
wasSpace = TRUE;
- } else if (wasSpace && haveName) {
- /*
- * Stop when an = operator is found.
- */
- if ((*line == '+') || (*line == ':') || (*line == '?') ||
- (*line == '!')) {
- break;
- }
+ break;
- /*
- * This is the start of another word, so not assignment.
- */
- return (FALSE);
- } else {
- haveName = TRUE;
- wasSpace = FALSE;
+ case '(':
+ case '{':
+ level++;
+ break;
+
+ case '}':
+ case ')':
+ level--;
+ break;
+
+ default:
+ if (wasSpace && haveName) {
+ if (ISEQOPERATOR(*line)) {
+ /*
+ * We must have a finished word
+ */
+ if (level != 0)
+ return FALSE;
+
+ /*
+ * When an = operator [+?!:] is found, the next
+ * character must be an = or it ain't a valid
+ * assignment.
+ */
+ if (line[1] == '=')
+ return haveName;
+#ifdef SUNSHCMD
+ /*
+ * This is a shell command
+ */
+ if (strncmp(line, ":sh", 3) == 0)
+ return haveName;
+#endif
+ }
+ /*
+ * This is the start of another word, so not assignment.
+ */
+ return FALSE;
+ }
+ else {
+ haveName = TRUE;
+ wasSpace = FALSE;
+ }
+ break;
}
- line++;
- }
- /*
- * A final check: if we stopped on a +, ?, ! or :, the next character must
- * be an = or it ain't a valid assignment
- */
- if (((*line == '+') ||
- (*line == '?') ||
- (*line == ':') ||
- (*line == '!')) &&
- (line[1] != '='))
- {
- return (FALSE);
- } else {
- return (haveName);
- }
+ return haveName;
}
/*-
@@ -1282,9 +1340,9 @@ Parse_DoVar (line, ctxt)
enum {
VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL
} type; /* Type of assignment */
- char *opc; /* ptr to operator character to
+ char *opc; /* ptr to operator character to
* null-terminate the variable name */
- /*
+ /*
* Avoid clobbered variable warnings by forcing the compiler
* to ``unregister'' variables
*/
@@ -1343,6 +1401,17 @@ Parse_DoVar (line, ctxt)
break;
default:
+#ifdef SUNSHCMD
+ while (*opc != ':')
+ if (--opc < line)
+ break;
+
+ if (strncmp(opc, ":sh", 3) == 0) {
+ type = VAR_SHELL;
+ *opc = '\0';
+ break;
+ }
+#endif
type = VAR_NORMAL;
break;
}
@@ -1374,156 +1443,38 @@ Parse_DoVar (line, ctxt)
Var_Set(line, cp, ctxt);
free(cp);
} else if (type == VAR_SHELL) {
- char *args[4]; /* Args for invoking the shell */
- int fds[2]; /* Pipe streams */
- int cpid; /* Child PID */
- int pid; /* PID from wait() */
- Boolean freeCmd; /* TRUE if the command needs to be freed, i.e.
- * if any variable expansion was performed */
-
- /*
- * Avoid clobbered variable warnings by forcing the compiler
- * to ``unregister'' variables
- */
-#if __GNUC__
- (void) &freeCmd;
-#endif
+ Boolean freeCmd = FALSE; /* TRUE if the command needs to be freed, i.e.
+ * if any variable expansion was performed */
+ char *res, *err;
- /*
- * Set up arguments for shell
- */
- args[0] = "sh";
- args[1] = "-c";
- if (strchr(cp, '$') != (char *)NULL) {
+ if (strchr(cp, '$') != NULL) {
/*
* There's a dollar sign in the command, so perform variable
* expansion on the whole thing. The resulting string will need
* freeing when we're done, so set freeCmd to TRUE.
*/
- args[2] = Var_Subst(NULL, cp, VAR_CMD, TRUE);
+ cp = Var_Subst(NULL, cp, VAR_CMD, TRUE);
freeCmd = TRUE;
- } else {
- args[2] = cp;
- freeCmd = FALSE;
}
- args[3] = (char *)NULL;
-
- /*
- * Open a pipe for fetching its output
- */
- pipe(fds);
-
- /*
- * Fork
- */
- cpid = vfork();
- if (cpid == 0) {
- /*
- * Close input side of pipe
- */
- close(fds[0]);
- /*
- * Duplicate the output stream to the shell's output, then
- * shut the extra thing down. Note we don't fetch the error
- * stream...why not? Why?
- */
- dup2(fds[1], 1);
- close(fds[1]);
-
- execv("/bin/sh", args);
- _exit(1);
- } else if (cpid < 0) {
- /*
- * Couldn't fork -- tell the user and make the variable null
- */
- Parse_Error(PARSE_WARNING, "Couldn't exec \"%s\"", cp);
- Var_Set(line, "", ctxt);
- } else {
- int status;
- int cc;
- Buffer buf;
- char *res;
+ res = Cmd_Exec(cp, &err);
+ Var_Set(line, res, ctxt);
+ free(res);
- /*
- * No need for the writing half
- */
- close(fds[1]);
-
- buf = Buf_Init (MAKE_BSIZE);
-
- do {
- char result[BUFSIZ];
- cc = read(fds[0], result, sizeof(result));
- if (cc > 0)
- Buf_AddBytes(buf, cc, (Byte *) result);
- }
- while (cc > 0 || (cc == -1 && errno == EINTR));
-
- /*
- * Close the input side of the pipe.
- */
- close(fds[0]);
+ if (err)
+ Parse_Error(PARSE_WARNING, err, cp);
- /*
- * Wait for the process to exit.
- */
- while(((pid = wait(&status)) != cpid) && (pid >= 0))
- continue;
-
- res = (char *)Buf_GetAll (buf, &cc);
- Buf_Destroy (buf, FALSE);
-
- if (cc == 0) {
- /*
- * Couldn't read the child's output -- tell the user and
- * set the variable to null
- */
- Parse_Error(PARSE_WARNING, "Couldn't read shell's output");
- }
-
- if (status) {
- /*
- * Child returned an error -- tell the user but still use
- * the result.
- */
- Parse_Error(PARSE_WARNING, "\"%s\" returned non-zero", cp);
- }
-
- /*
- * Null-terminate the result, convert newlines to spaces and
- * install it in the variable.
- */
- res[cc] = '\0';
- cp = &res[cc] - 1;
-
- if (*cp == '\n') {
- /*
- * A final newline is just stripped
- */
- *cp-- = '\0';
- }
- while (cp >= res) {
- if (*cp == '\n') {
- *cp = ' ';
- }
- cp--;
- }
- Var_Set(line, res, ctxt);
- free(res);
-
- }
- if (freeCmd) {
- free(args[2]);
- }
+ if (freeCmd)
+ free(cp);
} else {
/*
* Normal assignment -- just do it.
*/
- Var_Set (line, cp, ctxt);
+ Var_Set(line, cp, ctxt);
}
}
+
/*-
* ParseAddCmd --
* Lst_ForEach function to add a command line to all targets
@@ -1597,7 +1548,7 @@ Parse_AddIncludeDir (dir)
*---------------------------------------------------------------------
* ParseDoInclude --
* Push to another file.
- *
+ *
* The input is the line minus the #include. A file spec is a string
* enclosed in <> or "". The former is looked for only in sysIncPath.
* The latter in . and the directories specified by -I command line
@@ -1681,17 +1632,20 @@ ParseDoInclude (file)
* leading path components and call Dir_FindFile to see if
* we can locate the beast.
*/
- char *prefEnd;
+ char *prefEnd, *Fname;
- prefEnd = strrchr (fname, '/');
+ /* Make a temporary copy of this, to be safe. */
+ Fname = estrdup(fname);
+
+ prefEnd = strrchr (Fname, '/');
if (prefEnd != (char *)NULL) {
char *newName;
-
+
*prefEnd = '\0';
if (file[0] == '/')
- newName = strdup(file);
+ newName = estrdup(file);
else
- newName = str_concat (fname, file, STR_ADDSLASH);
+ newName = str_concat (Fname, file, STR_ADDSLASH);
fullname = Dir_FindFile (newName, parseIncPath);
if (fullname == (char *)NULL) {
fullname = Dir_FindFile(newName, dirSearchPath);
@@ -1701,6 +1655,7 @@ ParseDoInclude (file)
} else {
fullname = (char *)NULL;
}
+ free (Fname);
} else {
fullname = (char *)NULL;
}
@@ -1775,7 +1730,7 @@ ParseDoInclude (file)
*---------------------------------------------------------------------
* Parse_FromString --
* Start Parsing from the given string
- *
+ *
* Results:
* None
*
@@ -1798,14 +1753,14 @@ Parse_FromString(str)
oldFile->fname = fname;
oldFile->F = curFILE;
oldFile->p = curPTR;
-
+
(void) Lst_AtFront (includes, (ClientData)oldFile);
curFILE = NULL;
curPTR = (PTR *) emalloc (sizeof (PTR));
curPTR->str = curPTR->ptr = str;
lineno = 0;
- fname = strdup(fname);
+ fname = estrdup(fname);
}
@@ -1814,7 +1769,7 @@ Parse_FromString(str)
*---------------------------------------------------------------------
* ParseTraditionalInclude --
* Push to another file.
- *
+ *
* The input is the line minus the "include". The file name is
* the string following the "include".
*
@@ -1877,7 +1832,7 @@ ParseTraditionalInclude (file)
prefEnd = strrchr (fname, '/');
if (prefEnd != (char *)NULL) {
char *newName;
-
+
*prefEnd = '\0';
newName = str_concat (fname, file, STR_ADDSLASH);
fullname = Dir_FindFile (newName, parseIncPath);
@@ -1997,7 +1952,7 @@ ParseEOF (opened)
/*-
*---------------------------------------------------------------------
* ParseReadc --
- * Read a character from the current file
+ * Read a character from the current file
*
* Results:
* The character that was read
@@ -2010,7 +1965,7 @@ ParseReadc()
{
if (curFILE)
return fgetc(curFILE);
-
+
if (curPTR && *curPTR->ptr)
return *curPTR->ptr++;
return EOF;
@@ -2020,7 +1975,7 @@ ParseReadc()
/*-
*---------------------------------------------------------------------
* ParseUnreadc --
- * Put back a character to the current file
+ * Put back a character to the current file
*
* Results:
* None.
@@ -2051,54 +2006,43 @@ ParseSkipLine(skip)
int skip; /* Skip lines that don't start with . */
{
char *line;
- int c, lastc = '\0', lineLength;
+ int c, lastc, lineLength = 0;
Buffer buf;
- c = ParseReadc();
+ buf = Buf_Init(MAKE_BSIZE);
- if (skip) {
- /*
- * Skip lines until get to one that begins with a
- * special char.
- */
- while ((c != '.') && (c != EOF)) {
- while (((c != '\n') || (lastc == '\\')) && (c != EOF))
- {
- /*
- * Advance to next unescaped newline
- */
- if ((lastc = c) == '\n') {
- lineno++;
- }
- c = ParseReadc();
- }
- lineno++;
-
- lastc = c;
- c = ParseReadc ();
- }
- }
-
- if (c == EOF) {
- Parse_Error (PARSE_FATAL, "Unclosed conditional/for loop");
- return ((char *)NULL);
- }
-
- /*
- * Read the entire line into buf
- */
- buf = Buf_Init (MAKE_BSIZE);
- if (c != '\n') {
- do {
- Buf_AddByte (buf, (Byte)c);
- c = ParseReadc();
- } while ((c != '\n') && (c != EOF));
- }
- lineno++;
-
- Buf_AddByte (buf, (Byte)'\0');
- line = (char *)Buf_GetAll (buf, &lineLength);
- Buf_Destroy (buf, FALSE);
+ do {
+ Buf_Discard(buf, lineLength);
+ lastc = '\0';
+
+ while (((c = ParseReadc()) != '\n' || lastc == '\\')
+ && c != EOF) {
+ if (c == '\n') {
+ Buf_ReplaceLastByte(buf, (Byte)' ');
+ lineno++;
+
+ while ((c = ParseReadc()) == ' ' || c == '\t');
+
+ if (c == EOF)
+ break;
+ }
+
+ Buf_AddByte(buf, (Byte)c);
+ lastc = c;
+ }
+
+ if (c == EOF) {
+ Parse_Error(PARSE_FATAL, "Unclosed conditional/for loop");
+ Buf_Destroy(buf, TRUE);
+ return((char *)NULL);
+ }
+
+ lineno++;
+ Buf_AddByte(buf, (Byte)'\0');
+ line = (char *)Buf_GetAll(buf, &lineLength);
+ } while (skip == 1 && line[0] != '.');
+
+ Buf_Destroy(buf, FALSE);
return line;
}
@@ -2164,11 +2108,11 @@ ParseReadLine ()
break;
}
}
-
+
if (c != EOF) {
lastc = c;
buf = Buf_Init(MAKE_BSIZE);
-
+
while (((c = ParseReadc ()) != '\n' || (lastc == '\\')) &&
(c != EOF))
{
@@ -2216,7 +2160,7 @@ test_char:
*/
ParseUnreadc('\t');
goto line_read;
- }
+ }
break;
case '=':
if (!semiNL) {
@@ -2242,7 +2186,11 @@ test_char:
break;
case '#':
if (!ignComment) {
- if (compatMake && (lastc != '\\')) {
+ if (
+#if 0
+ compatMake &&
+#endif
+ (lastc != '\\')) {
/*
* If the character is a hash mark and it isn't escaped
* (or we're being compatible), the thing is a comment.
@@ -2279,11 +2227,11 @@ test_char:
*/
Buf_AddByte (buf, (Byte)lastc);
lastc = c;
-
+
}
line_read:
lineno++;
-
+
if (lastc != '\0') {
Buf_AddByte (buf, (Byte)lastc);
}
@@ -2299,13 +2247,13 @@ test_char:
ep = line;
while (*ep)
++ep;
- while (ep > line && (ep[-1] == ' ' || ep[-1] == '\t')) {
+ while (ep > line + 1 && (ep[-1] == ' ' || ep[-1] == '\t')) {
if (ep > line + 1 && ep[-2] == '\\')
break;
--ep;
}
*ep = 0;
-
+
if (line[0] == '.') {
/*
* The line might be a conditional. Ask the conditional module
@@ -2337,7 +2285,7 @@ test_char:
*/
line = ParseSkipLine(0);
if (line == NULL) {
- Parse_Error (PARSE_FATAL,
+ Parse_Error (PARSE_FATAL,
"Unexpected end of file in for loop.\n");
break;
}
@@ -2385,7 +2333,7 @@ ParseFinishLine()
inLine = FALSE;
}
}
-
+
/*-
*---------------------------------------------------------------------
@@ -2446,12 +2394,11 @@ Parse_File(name, stream)
goto nextLine;
}
}
- if (*line == '#' || *line == '\0') {
- /* If we're this far, the line must be a comment.
- (Empty lines are ignored as well) */
+ if (*line == '#') {
+ /* If we're this far, the line must be a comment. */
goto nextLine;
}
-
+
if (*line == '\t') {
/*
* If a line starts with a tab, it can only hope to be
@@ -2468,19 +2415,20 @@ Parse_File(name, stream)
/*
* So long as it's not a blank line and we're actually
* in a dependency spec, add the command to the list of
- * commands of all targets in the dependency spec
+ * commands of all targets in the dependency spec
*/
Lst_ForEach (targets, ParseAddCmd, cp);
Lst_AtEnd(targCmds, (ClientData) line);
continue;
} else {
Parse_Error (PARSE_FATAL,
- "Unassociated shell command \"%.20s\"",
+ "Unassociated shell command \"%s\"",
cp);
}
}
#ifdef SYSVINCLUDE
- } else if (strncmp (line, "include", 7) == 0 &&
+ } else if (strncmp (line, "include", 7) == 0 &&
+ isspace((unsigned char) line[7]) &&
strchr(line, ':') == NULL) {
/*
* It's an S3/S5-style "include".
@@ -2505,7 +2453,7 @@ Parse_File(name, stream)
#ifndef POSIX
Boolean nonSpace = FALSE;
#endif
-
+
cp = line;
if (isspace((unsigned char) line[0])) {
while ((*cp != '\0') && isspace((unsigned char) *cp)) {
@@ -2521,7 +2469,7 @@ Parse_File(name, stream)
}
#endif
}
-
+
#ifndef POSIX
if (*cp == '\0') {
if (inLine) {
@@ -2538,16 +2486,16 @@ Parse_File(name, stream)
cp = Var_Subst (NULL, line, VAR_CMD, TRUE);
free (line);
line = cp;
-
+
/*
- * Need a non-circular list for the target nodes
+ * Need a non-circular list for the target nodes
*/
if (targets)
Lst_Destroy(targets, NOFREE);
targets = Lst_Init (FALSE);
inLine = TRUE;
-
+
ParseDoDependency (line);
#ifndef POSIX
}
@@ -2559,7 +2507,7 @@ Parse_File(name, stream)
free (line);
}
/*
- * Reached EOF, but it may be just EOF of an include file...
+ * Reached EOF, but it may be just EOF of an include file...
*/
} while (ParseEOF(1) == CONTINUE);
@@ -2589,30 +2537,11 @@ Parse_File(name, stream)
void
Parse_Init ()
{
- char *cp = NULL, *start;
- /* avoid faults on read-only strings */
- static char syspath[] = _PATH_DEFSYSPATH;
-
mainNode = NILGNODE;
parseIncPath = Lst_Init (FALSE);
sysIncPath = Lst_Init (FALSE);
includes = Lst_Init (FALSE);
targCmds = Lst_Init (FALSE);
-
- /*
- * Add the directories from the DEFSYSPATH (more than one may be given
- * as dir1:...:dirn) to the system include path.
- */
- for (start = syspath; *start != '\0'; start = cp) {
- for (cp = start; *cp != '\0' && *cp != ':'; cp++)
- continue;
- if (*cp == '\0') {
- Dir_AddDir(sysIncPath, start);
- } else {
- *cp++ = '\0';
- Dir_AddDir(sysIncPath, start);
- }
- }
}
void
@@ -2625,7 +2554,7 @@ Parse_End()
Lst_Destroy(parseIncPath, Dir_Destroy);
Lst_Destroy(includes, NOFREE); /* Should be empty now */
}
-
+
/*-
*-----------------------------------------------------------------------
@@ -2649,7 +2578,7 @@ Parse_MainName()
main = Lst_Init (FALSE);
if (mainNode == NILGNODE) {
- Punt ("make: no target to make.\n");
+ Punt ("no target to make.");
/*NOTREACHED*/
} else if (mainNode->type & OP_DOUBLEDEP) {
(void) Lst_AtEnd (main, (ClientData)mainNode);
diff --git a/usr.bin/make/pathnames.h b/usr.bin/make/pathnames.h
index 8cb066148393..9f46b26d0bb0 100644
--- a/usr.bin/make/pathnames.h
+++ b/usr.bin/make/pathnames.h
@@ -1,3 +1,5 @@
+/* $NetBSD: pathnames.h,v 1.5 1996/08/30 17:59:41 thorpej Exp $ */
+
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -30,10 +32,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)pathnames.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)pathnames.h 5.2 (Berkeley) 6/1/90
*/
#define _PATH_OBJDIR "obj"
+#define _PATH_OBJDIRPREFIX "/usr/obj"
#define _PATH_DEFSHELLDIR "/bin"
#define _PATH_DEFSYSMK "sys.mk"
#define _PATH_DEFSYSPATH "/usr/share/mk"
diff --git a/usr.bin/make/sprite.h b/usr.bin/make/sprite.h
index 0da22f180d05..65e732c1bae7 100644
--- a/usr.bin/make/sprite.h
+++ b/usr.bin/make/sprite.h
@@ -1,3 +1,5 @@
+/* $NetBSD: sprite.h,v 1.5 1995/06/14 15:19:54 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -35,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)sprite.h 8.2 (Berkeley) 4/28/95
+ * from: @(#)sprite.h 8.1 (Berkeley) 6/6/93
*/
/*
@@ -69,7 +71,7 @@ typedef int Boolean;
typedef int ReturnStatus;
/*
- * The following statuses overlap with the first 2 generic statuses
+ * The following statuses overlap with the first 2 generic statuses
* defined in status.h:
*
* SUCCESS There was no error.
@@ -81,7 +83,7 @@ typedef int ReturnStatus;
/*
- * A nil pointer must be something that will cause an exception if
+ * A nil pointer must be something that will cause an exception if
* referenced. There are two nils: the kernels nil and the nil used
* by user processes.
*/
diff --git a/usr.bin/make/str.c b/usr.bin/make/str.c
index 7df8e8d2f113..e1e5968922bd 100644
--- a/usr.bin/make/str.c
+++ b/usr.bin/make/str.c
@@ -1,3 +1,5 @@
+/* $NetBSD: str.c,v 1.12 1996/03/29 02:17:34 jtc Exp $ */
+
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,8 +39,12 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)str.c 8.6 (Berkeley) 4/28/95";
-#endif /* not lint */
+#if 0
+static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
+#else
+static char rcsid[] = "$NetBSD: str.c,v 1.12 1996/03/29 02:17:34 jtc Exp $";
+#endif
+#endif /* not lint */
#include "make.h"
@@ -54,7 +60,7 @@ void
str_init()
{
char *p1;
- argv = (char **)emalloc((argmax = 50) * sizeof(char *));
+ argv = (char **)emalloc(((argmax = 50) + 1) * sizeof(char *));
argv[0] = Var_Value(".MAKE", VAR_GLOBAL, &p1);
}
@@ -67,15 +73,15 @@ str_init()
void
str_end()
{
- if (argv[0]) {
- free(argv[0]);
+ if (argv) {
+ if (argv[0])
+ free(argv[0]);
free((Address) argv);
}
if (buffer)
free(buffer);
}
-
/*-
* str_concat --
* concatenate the two strings, inserting a space or slash between them,
@@ -201,9 +207,8 @@ brk_string(str, store_argc, expand)
*t++ = '\0';
if (argc == argmax) {
argmax *= 2; /* ramp up fast */
- if (!(argv = (char **)realloc(argv,
- argmax * sizeof(char *))))
- enomem();
+ argv = (char **)erealloc(argv,
+ (argmax + 1) * sizeof(char *));
}
argv[argc++] = start;
start = (char *)NULL;
@@ -218,7 +223,7 @@ brk_string(str, store_argc, expand)
ch = *++p;
break;
}
-
+
switch (ch = *++p) {
case '\0':
case '\n':
@@ -255,12 +260,12 @@ done: argv[argc] = (char *)NULL;
/*
* Str_FindSubstring -- See if a string contains a particular substring.
- *
+ *
* Results: If string contains substring, the return value is the location of
* the first matching instance of substring in string. If string doesn't
* contain substring, the return value is NULL. Matching is done on an exact
* character-for-character basis with no wildcards or special characters.
- *
+ *
* Side effects: None.
*/
char *
@@ -293,13 +298,13 @@ Str_FindSubstring(string, substring)
/*
* Str_Match --
- *
+ *
* See if a particular string matches a particular pattern.
- *
+ *
* Results: Non-zero is returned if string matches pattern, 0 otherwise. The
* matching operation permits the following special characters in the
* pattern: *?\[] (see the man page for details on what these mean).
- *
+ *
* Side effects: None.
*/
int
@@ -396,8 +401,8 @@ thisCharOK: ++pattern;
/*-
*-----------------------------------------------------------------------
* Str_SYSVMatch --
- * Check word against pattern for a match (% is wild),
- *
+ * Check word against pattern for a match (% is wild),
+ *
* Results:
* Returns the beginning position of a match or null. The number
* of characters matched is returned in len.
@@ -447,7 +452,7 @@ Str_SYSVMatch(word, pattern, len)
return m;
}
while (*w++ != '\0');
-
+
return NULL;
}
@@ -458,7 +463,7 @@ Str_SYSVMatch(word, pattern, len)
* Substitute '%' on the pattern with len characters from src.
* If the pattern does not contain a '%' prepend len characters
* from src.
- *
+ *
* Results:
* None
*
diff --git a/usr.bin/make/suff.c b/usr.bin/make/suff.c
index 1b344d499490..0bbbe170de56 100644
--- a/usr.bin/make/suff.c
+++ b/usr.bin/make/suff.c
@@ -1,3 +1,5 @@
+/* $NetBSD: suff.c,v 1.12 1996/08/13 16:42:16 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)suff.c 8.5 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94";
+#else
+static char rcsid[] = "$NetBSD: suff.c,v 1.12 1996/08/13 16:42:16 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -95,7 +101,6 @@ static char sccsid[] = "@(#)suff.c 8.5 (Berkeley) 4/28/95";
#include "make.h"
#include "hash.h"
#include "dir.h"
-#include "bit.h"
static Lst sufflist; /* Lst of suffixes */
static Lst suffClean; /* Lst of suffixes to be cleaned */
@@ -159,6 +164,7 @@ static int SuffSuffIsSuffixP __P((ClientData, ClientData));
static int SuffSuffHasNameP __P((ClientData, ClientData));
static int SuffSuffIsPrefix __P((ClientData, ClientData));
static int SuffGNHasNameP __P((ClientData, ClientData));
+static void SuffUnRef __P((ClientData, ClientData));
static void SuffFree __P((ClientData));
static void SuffInsert __P((Lst, Suff *));
static void SuffRemove __P((Lst, Suff *));
@@ -505,7 +511,7 @@ SuffParseTransform(str, srcPtr, targPtr)
srcLn = NILLNODE;
singleLn = NILLNODE;
-
+
/*
* Loop looking first for a suffix that matches the start of the
* string and then for one that exactly matches the rest of it. If
@@ -605,7 +611,7 @@ Suff_AddTransform (line)
if (ln == NILLNODE) {
/*
* Make a new graph node for the transformation. It will be filled in
- * by the Parse module.
+ * by the Parse module.
*/
gn = Targ_NewGN (line);
(void)Lst_AtEnd (transforms, (ClientData)gn);
@@ -628,7 +634,7 @@ Suff_AddTransform (line)
(void)SuffParseTransform(line, &s, &t);
/*
- * link the two together in the proper relationship and order
+ * link the two together in the proper relationship and order
*/
if (DEBUG(SUFF)) {
printf("defining transformation from `%s' to `%s'\n",
@@ -663,7 +669,7 @@ Suff_EndTransform(gnp, dummy)
ClientData dummy; /* Node for transformation */
{
GNode *gn = (GNode *) gnp;
-
+
if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) &&
Lst_IsEmpty(gn->children))
{
@@ -796,7 +802,7 @@ Suff_AddSuffix (str)
if (ln == NILLNODE) {
s = (Suff *) emalloc (sizeof (Suff));
- s->name = strdup (str);
+ s->name = estrdup (str);
s->nameLen = strlen (s->name);
s->searchPath = Lst_Init (FALSE);
s->children = Lst_Init (FALSE);
@@ -812,7 +818,7 @@ Suff_AddSuffix (str)
* XXX: Only do this after a Suff_ClearSuffixes?
*/
Lst_ForEach (transforms, SuffRebuildGraph, (ClientData)s);
- }
+ }
}
/*-
@@ -995,7 +1001,7 @@ SuffAddSrc (sp, lsp)
Src *targ; /* Target structure */
targ = ls->s;
-
+
if ((s->flags & SUFF_NULL) && (*s->name != '\0')) {
/*
* If the suffix has been marked as the NULL suffix, also create a Src
@@ -1003,7 +1009,7 @@ SuffAddSrc (sp, lsp)
* that...
*/
s2 = (Src *) emalloc (sizeof (Src));
- s2->file = strdup(targ->pref);
+ s2->file = estrdup(targ->pref);
s2->pref = targ->pref;
s2->parent = targ;
s2->node = NILGNODE;
@@ -1266,7 +1272,7 @@ SuffFindCmds (targ, slst)
* again (ick)), and return the new structure.
*/
ret = (Src *)emalloc (sizeof (Src));
- ret->file = strdup(s->name);
+ ret->file = estrdup(s->name);
ret->pref = targ->pref;
ret->suff = suff;
suff->refCount++;
@@ -1325,7 +1331,7 @@ SuffExpandChildren(cgnp, pgnp)
* after the child
*/
prevLN = Lst_Member(pgn->children, (ClientData)cgn);
-
+
/*
* First do variable expansion -- this takes precedence over
* wildcard expansion. If the result contains wildcards, they'll be gotten
@@ -1340,7 +1346,7 @@ SuffExpandChildren(cgnp, pgnp)
if (cp != (char *)NULL) {
Lst members = Lst_Init(FALSE);
-
+
if (cgn->type & OP_ARCHV) {
/*
* Node was an archive(member) target, so we want to call
@@ -1361,7 +1367,7 @@ SuffExpandChildren(cgnp, pgnp)
char *start;
char *initcp = cp; /* For freeing... */
- for (start = cp; *start == ' ' || *start == '\t'; start++)
+ for (start = cp; *start == ' ' || *start == '\t'; start++)
continue;
for (cp = start; *cp != '\0'; cp++) {
if (*cp == ' ' || *cp == '\t') {
@@ -1468,7 +1474,7 @@ SuffExpandChildren(cgnp, pgnp)
if (DEBUG(SUFF)) {
printf("Wildcard expanding \"%s\"...", cgn->name);
}
-
+
if (ln != NILLNODE) {
Suff *s = (Suff *)Lst_Datum(ln);
@@ -1516,7 +1522,7 @@ SuffExpandChildren(cgnp, pgnp)
* Nuke what's left of the list
*/
Lst_Destroy(exp, NOFREE);
-
+
/*
* Now the source is expanded, remove it from the list of children to
* keep it from being processed.
@@ -1609,7 +1615,7 @@ SuffApplyTransform(tGn, sGn, t, s)
}
gn = (GNode *)Lst_Datum(ln);
-
+
if (DEBUG(SUFF)) {
printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name);
}
@@ -1618,7 +1624,7 @@ SuffApplyTransform(tGn, sGn, t, s)
* Record last child for expansion purposes
*/
ln = Lst_Last(tGn->children);
-
+
/*
* Pass the buck to Make_HandleUse to apply the rule
*/
@@ -1671,7 +1677,7 @@ SuffFindArchiveDeps(gn, slst)
int i; /* Index into copy and vals */
Suff *ms; /* Suffix descriptor for member */
char *name; /* Start of member's name */
-
+
/*
* The node is an archive(member) pair. so we must find a
* suffix for both of them.
@@ -1683,7 +1689,7 @@ SuffFindArchiveDeps(gn, slst)
*eoarch = '\0'; /* So a suffix can be found */
name = eoarch + 1;
-
+
/*
* To simplify things, call Suff_FindDeps recursively on the member now,
* so we can simply compare the member's .PREFIX and .TARGET variables
@@ -1702,7 +1708,7 @@ SuffFindArchiveDeps(gn, slst)
(void)Lst_AtEnd(mem->parents, (ClientData)gn);
gn->unmade += 1;
}
-
+
/*
* Copy in the variables from the member node to this one.
*/
@@ -1815,7 +1821,7 @@ SuffFindNormalDeps(gn, slst)
eoname = gn->name + strlen(gn->name);
sopref = gn->name;
-
+
/*
* Begin at the beginning...
*/
@@ -1841,7 +1847,8 @@ SuffFindNormalDeps(gn, slst)
* children, then look for any overriding transformations they imply.
* Should we find one, we discard the one we found before.
*/
- while(ln != NILLNODE) {
+
+ while (ln != NILLNODE) {
/*
* Look for next possible suffix...
*/
@@ -1850,12 +1857,12 @@ SuffFindNormalDeps(gn, slst)
if (ln != NILLNODE) {
int prefLen; /* Length of the prefix */
Src *targ;
-
+
/*
* Allocate a Src structure to which things can be transformed
*/
targ = (Src *)emalloc(sizeof (Src));
- targ->file = strdup(gn->name);
+ targ->file = estrdup(gn->name);
targ->suff = (Suff *)Lst_Datum(ln);
targ->suff->refCount++;
targ->node = gn;
@@ -1864,7 +1871,7 @@ SuffFindNormalDeps(gn, slst)
#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.
@@ -1896,17 +1903,17 @@ SuffFindNormalDeps(gn, slst)
*/
if (Lst_IsEmpty(targs) && suffNull != NULL) {
if (DEBUG(SUFF)) {
- printf("\tNo known suffix on %s. Using .NULL suffix: ", gn->name);
+ printf("\tNo known suffix on %s. Using .NULL suffix\n", gn->name);
}
-
+
targ = (Src *)emalloc(sizeof (Src));
- targ->file = strdup(gn->name);
+ targ->file = estrdup(gn->name);
targ->suff = suffNull;
targ->suff->refCount++;
targ->node = gn;
targ->parent = (Src *)NULL;
targ->children = 0;
- targ->pref = strdup(sopref);
+ targ->pref = estrdup(sopref);
#ifdef DEBUG_SRC
targ->cp = Lst_Init(FALSE);
#endif
@@ -1918,16 +1925,16 @@ SuffFindNormalDeps(gn, slst)
if (Lst_IsEmpty(gn->commands) && Lst_IsEmpty(gn->children))
SuffAddLevel(srcs, targ);
else {
- if (DEBUG(SUFF))
+ if (DEBUG(SUFF))
printf("not ");
}
- if (DEBUG(SUFF))
+ if (DEBUG(SUFF))
printf("adding suffix rules\n");
(void)Lst_AtEnd(targs, (ClientData)targ);
}
-
+
/*
* Using the list of possible sources built up from the target suffix(es),
* try and find an existing file/target that matches.
@@ -1969,7 +1976,7 @@ SuffFindNormalDeps(gn, slst)
* that still contain variables or wildcards in their names.
*/
Lst_ForEach(gn->children, SuffExpandChildren, (ClientData)gn);
-
+
if (targ == NULL) {
if (DEBUG(SUFF)) {
printf("\tNo valid suffix on %s\n", gn->name);
@@ -1988,6 +1995,7 @@ sfnd_abort:
(targ == NULL ? dirSearchPath :
targ->suff->searchPath));
if (gn->path != NULL) {
+ char *ptr;
Var_Set(TARGET, gn->path, gn);
if (targ != NULL) {
@@ -1995,7 +2003,7 @@ sfnd_abort:
* Suffix known for the thing -- trim the suffix off
* the path to form the proper .PREFIX variable.
*/
- int len = strlen(gn->path);
+ int savep = strlen(gn->path) - targ->suff->nameLen;
char savec;
if (gn->suffix)
@@ -2003,12 +2011,17 @@ sfnd_abort:
gn->suffix = targ->suff;
gn->suffix->refCount++;
- savec = gn->path[len-targ->suff->nameLen];
- gn->path[len-targ->suff->nameLen] = '\0';
+ savec = gn->path[savep];
+ gn->path[savep] = '\0';
- Var_Set(PREFIX, gn->path, gn);
+ if ((ptr = strrchr(gn->path, '/')) != NULL)
+ ptr++;
+ else
+ ptr = gn->path;
- gn->path[len-targ->suff->nameLen] = savec;
+ Var_Set(PREFIX, ptr, gn);
+
+ gn->path[savep] = savec;
} else {
/*
* The .PREFIX gets the full path if the target has
@@ -2018,7 +2031,12 @@ sfnd_abort:
gn->suffix->refCount--;
gn->suffix = NULL;
- Var_Set(PREFIX, gn->path, gn);
+ if ((ptr = strrchr(gn->path, '/')) != NULL)
+ ptr++;
+ else
+ ptr = gn->path;
+
+ Var_Set(PREFIX, ptr, gn);
}
}
} else {
@@ -2034,9 +2052,9 @@ sfnd_abort:
gn->suffix->refCount++;
if (gn->path != NULL)
free(gn->path);
- gn->path = strdup(gn->name);
+ gn->path = estrdup(gn->name);
}
-
+
goto sfnd_return;
}
@@ -2086,12 +2104,12 @@ sfnd_abort:
* suffix. Note that this causes the commands list of the original
* node, gn, to be replaced by the commands of the final
* transformation rule. Also, the unmade field of gn is incremented.
- * Etc.
+ * Etc.
*/
if (bottom->node == NILGNODE) {
bottom->node = Targ_FindNode(bottom->file, TARG_CREATE);
}
-
+
for (src = bottom; src->parent != (Src *)NULL; src = src->parent) {
targ = src->parent;
@@ -2120,7 +2138,7 @@ sfnd_abort:
targ->node->type |= OP_DEPS_FOUND;
Var_Set(PREFIX, targ->pref, targ->node);
-
+
Var_Set(TARGET, targ->node->name, targ->node);
}
}
@@ -2135,7 +2153,7 @@ sfnd_abort:
*/
if (gn->path)
free(gn->path);
- gn->path = strdup(gn->name);
+ gn->path = estrdup(gn->name);
/*
* Nuke the transformation path and the Src structures left over in the
@@ -2152,8 +2170,8 @@ sfnd_return:
Lst_Concat(slst, srcs, LST_CONCLINK);
Lst_Concat(slst, targs, LST_CONCLINK);
}
-
-
+
+
/*-
*-----------------------------------------------------------------------
* Suff_FindDeps --
@@ -2186,7 +2204,7 @@ void
Suff_FindDeps(gn)
GNode *gn;
{
-
+
SuffFindDeps(gn, srclist);
while (SuffRemoveSrc(srclist))
continue;
@@ -2206,11 +2224,11 @@ SuffFindDeps (gn, slst)
} else {
gn->type |= OP_DEPS_FOUND;
}
-
+
if (DEBUG(SUFF)) {
printf ("SuffFindDeps (%s)\n", gn->name);
}
-
+
if (gn->type & OP_ARCHV) {
SuffFindArchiveDeps(gn, slst);
} else if (gn->type & OP_LIB) {
@@ -2224,7 +2242,7 @@ SuffFindDeps (gn, slst)
*/
LstNode ln;
Suff *s;
-
+
ln = Lst_Find (sufflist, (ClientData)LIBSUFF, SuffSuffHasNameP);
if (gn->suffix)
gn->suffix->refCount--;
@@ -2316,7 +2334,7 @@ Suff_Init ()
*/
emptySuff = suffNull = (Suff *) emalloc (sizeof (Suff));
- suffNull->name = strdup ("");
+ suffNull->name = estrdup ("");
suffNull->nameLen = 0;
suffNull->searchPath = Lst_Init (FALSE);
Dir_Concat(suffNull->searchPath, dirSearchPath);
@@ -2375,7 +2393,7 @@ SuffPrintSuff (sp, dummy)
int flag;
printf ("# `%s' [%d] ", s->name, s->refCount);
-
+
flags = s->flags;
if (flags) {
fputs (" (", stdout);
diff --git a/usr.bin/make/targ.c b/usr.bin/make/targ.c
index 49aedbd5d218..0fe96509f9fe 100644
--- a/usr.bin/make/targ.c
+++ b/usr.bin/make/targ.c
@@ -1,3 +1,5 @@
+/* $NetBSD: targ.c,v 1.9 1996/08/30 17:59:43 thorpej Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)targ.c 8.3 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
+#else
+static char *rcsid = "$NetBSD: targ.c,v 1.9 1996/08/30 17:59:43 thorpej Exp $";
+#endif
#endif /* not lint */
/*-
@@ -158,7 +164,7 @@ Targ_NewGN (name)
register GNode *gn;
gn = (GNode *) emalloc (sizeof (GNode));
- gn->name = strdup (name);
+ gn->name = estrdup (name);
gn->path = (char *) 0;
if (name[0] == '-' && name[1] == 'l') {
gn->type = OP_LIB;
@@ -169,6 +175,7 @@ Targ_NewGN (name)
gn->make = FALSE;
gn->made = UNMADE;
gn->childMade = FALSE;
+ gn->order = 0;
gn->mtime = gn->cmtime = 0;
gn->iParents = Lst_Init (FALSE);
gn->cohorts = Lst_Init (FALSE);
@@ -269,11 +276,11 @@ Targ_FindNode (name, flags)
/*-
*-----------------------------------------------------------------------
* Targ_FindList --
- * Make a complete list of GNodes from the given list of names
+ * Make a complete list of GNodes from the given list of names
*
* Results:
* A complete list of graph nodes corresponding to all instances of all
- * the names in names.
+ * the names in names.
*
* Side Effects:
* If flags is TARG_CREATE, nodes will be created for all names in
@@ -390,7 +397,7 @@ Targ_Precious (gn)
/******************* DEBUG INFO PRINTING ****************/
static GNode *mainTarg; /* the main target, as set by Targ_SetMain */
-/*-
+/*-
*-----------------------------------------------------------------------
* Targ_SetMain --
* Set our idea of the main target we'll be creating. Used for
@@ -467,12 +474,12 @@ Targ_FmtTime (time)
parts = localtime(&time);
- sprintf (buf, "%d:%02d:%02d %s %d, 19%d",
+ sprintf (buf, "%d:%02d:%02d %s %d, %d",
parts->tm_hour, parts->tm_min, parts->tm_sec,
- months[parts->tm_mon], parts->tm_mday, parts->tm_year);
+ months[parts->tm_mon], parts->tm_mday, 1900 + parts->tm_year);
return(buf);
}
-
+
/*-
*-----------------------------------------------------------------------
* Targ_PrintType --
@@ -490,7 +497,7 @@ Targ_PrintType (type)
register int type;
{
register int tbit;
-
+
#ifdef __STDC__
#define PRINTBIT(attr) case CONCAT(OP_,attr): printf("." #attr " "); break
#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf("." #attr " "); break
@@ -577,7 +584,7 @@ TargPrintNode (gnp, passp)
Lst_ForEach (gn->parents, TargPrintName, (ClientData)0);
fputc ('\n', stdout);
}
-
+
printf("%-16s", gn->name);
switch (gn->type & OP_OPMASK) {
case OP_DEPENDS:
diff --git a/usr.bin/make/util.c b/usr.bin/make/util.c
index df8347c201ee..07eb6a47e55d 100644
--- a/usr.bin/make/util.c
+++ b/usr.bin/make/util.c
@@ -1,3 +1,5 @@
+/* $NetBSD: util.c,v 1.7 1996/08/30 17:59:44 thorpej Exp $ */
+
/*
* Missing stuff from OS's
*/
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c
index 4d7b2e956878..bc57634f1ac8 100644
--- a/usr.bin/make/var.c
+++ b/usr.bin/make/var.c
@@ -1,3 +1,5 @@
+/* $NetBSD: var.c,v 1.14 1996/08/13 16:42:25 christos Exp $ */
+
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -37,7 +39,11 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)var.c 8.4 (Berkeley) 4/28/95";
+#if 0
+static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
+#else
+static char rcsid[] = "$NetBSD: var.c,v 1.14 1996/08/13 16:42:25 christos Exp $";
+#endif
#endif /* not lint */
/*-
@@ -147,7 +153,6 @@ typedef struct {
#define VAR_SUB_GLOBAL 1 /* Apply substitution globally */
#define VAR_MATCH_START 2 /* Match at start of word */
#define VAR_MATCH_END 4 /* Match at end of word */
-#define VAR_NO_SUB 8 /* Substitution is non-global and already done */
} VarPattern;
static int VarCmp __P((ClientData, ClientData));
@@ -159,7 +164,9 @@ static Boolean VarTail __P((char *, Boolean, Buffer, ClientData));
static Boolean VarSuffix __P((char *, Boolean, Buffer, ClientData));
static Boolean VarRoot __P((char *, Boolean, Buffer, ClientData));
static Boolean VarMatch __P((char *, Boolean, Buffer, ClientData));
+#ifdef SYSVVARSUB
static Boolean VarSYSVMatch __P((char *, Boolean, Buffer, ClientData));
+#endif
static Boolean VarNoMatch __P((char *, Boolean, Buffer, ClientData));
static Boolean VarSubstitute __P((char *, Boolean, Buffer, ClientData));
static char *VarModify __P((char *, Boolean (*)(char *, Boolean, Buffer,
@@ -271,15 +278,15 @@ VarFind (name, ctxt, flags)
if ((env = getenv (name)) != NULL) {
int len;
-
+
v = (Var *) emalloc(sizeof(Var));
- v->name = strdup(name);
+ v->name = estrdup(name);
len = strlen(env);
-
+
v->val = Buf_Init(len);
Buf_AddBytes(v->val, len, (Byte *)env);
-
+
v->flags = VAR_FROM_ENV;
return (v);
} else if (checkEnvFirst && (flags & FIND_GLOBAL) &&
@@ -326,7 +333,7 @@ VarAdd (name, val, ctxt)
v = (Var *) emalloc (sizeof (Var));
- v->name = strdup (name);
+ v->name = estrdup (name);
len = val ? strlen(val) : 0;
v->val = Buf_Init(len+1);
@@ -747,7 +754,7 @@ VarRoot (word, addSpace, buf, dummy)
* VarMatch --
* Place the word in the buffer if it matches the given pattern.
* Callback function for VarModify to implement the :M modifier.
- *
+ *
* Results:
* TRUE if a space should be placed in the buffer before the next
* word.
@@ -776,15 +783,14 @@ VarMatch (word, addSpace, buf, pattern)
return(addSpace);
}
-
-
+#ifdef SYSVVARSUB
/*-
*-----------------------------------------------------------------------
* VarSYSVMatch --
* Place the word in the buffer if it matches the given pattern.
* Callback function for VarModify to implement the System V %
* modifiers.
- *
+ *
* Results:
* TRUE if a space should be placed in the buffer before the next
* word.
@@ -819,6 +825,7 @@ VarSYSVMatch (word, addSpace, buf, patp)
return(addSpace);
}
+#endif
/*-
@@ -826,7 +833,7 @@ VarSYSVMatch (word, addSpace, buf, patp)
* VarNoMatch --
* Place the word in the buffer if it doesn't match the given pattern.
* Callback function for VarModify to implement the :N modifier.
- *
+ *
* Results:
* TRUE if a space should be placed in the buffer before the next
* word.
@@ -883,9 +890,9 @@ VarSubstitute (word, addSpace, buf, patternp)
VarPattern *pattern = (VarPattern *) patternp;
wordLen = strlen(word);
- if ((pattern->flags & VAR_NO_SUB) == 0) {
+ if (1) { /* substitute in each word of the variable */
/*
- * Still substituting -- break it down into simple anchored cases
+ * Break substitution down into simple anchored cases
* and if none of them fits, perform the general substitution case.
*/
if ((pattern->flags & VAR_MATCH_START) &&
@@ -967,7 +974,7 @@ VarSubstitute (word, addSpace, buf, patternp)
* Pattern is unanchored: search for the pattern in the word using
* String_FindSubstring, copying unmatched portions and the
* right-hand-side for each match found, handling non-global
- * subsititutions correctly, etc. When the loop is done, any
+ * substitutions correctly, etc. When the loop is done, any
* remaining part of the word (word and wordLen are adjusted
* accordingly through the loop) is copied straight into the
* buffer.
@@ -990,12 +997,8 @@ VarSubstitute (word, addSpace, buf, patternp)
Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
wordLen -= (cp - word) + pattern->leftLen;
word = cp + pattern->leftLen;
- if (wordLen == 0) {
- done = TRUE;
- }
- if ((pattern->flags & VAR_SUB_GLOBAL) == 0) {
+ if (wordLen == 0 || (pattern->flags & VAR_SUB_GLOBAL) == 0){
done = TRUE;
- pattern->flags |= VAR_NO_SUB;
}
} else {
done = TRUE;
@@ -1015,14 +1018,9 @@ VarSubstitute (word, addSpace, buf, patternp)
return ((Buf_Size(buf) != origSize) || addSpace);
}
/*
- * Common code for anchored substitutions: if performed a substitution
- * and it's not supposed to be global, mark the pattern as requiring
- * no more substitutions. addSpace was set TRUE if characters were
- * added to the buffer.
+ * Common code for anchored substitutions:
+ * addSpace was set TRUE if characters were added to the buffer.
*/
- if ((pattern->flags & VAR_SUB_GLOBAL) == 0) {
- pattern->flags |= VAR_NO_SUB;
- }
return (addSpace);
}
nosub:
@@ -1068,7 +1066,7 @@ VarModify (str, modProc, datum)
for (i = 1; i < ac; i++)
addSpace = (*modProc)(av[i], addSpace, buf, datum);
-
+
Buf_AddByte (buf, '\0');
str = (char *)Buf_GetAll (buf, (int *)NULL);
Buf_Destroy (buf, FALSE);
@@ -1110,7 +1108,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
Boolean haveModifier;/* TRUE if have modifiers for the variable */
register char endc; /* Ending character when variable in parens
* or braces */
- register char startc; /* Starting character when variable in parens
+ register char startc=0; /* Starting character when variable in parens
* or braces */
int cnt; /* Used to count brace pairs when variable in
* in parens or braces */
@@ -1119,11 +1117,11 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
* expanding it in a non-local context. This
* is done to support dynamic sources. The
* result is just the invocation, unaltered */
-
+
*freePtr = FALSE;
dynamic = FALSE;
start = str;
-
+
if (str[1] != '(' && str[1] != '{') {
/*
* If it's not bounded by braces of some sort, life is much simpler.
@@ -1138,7 +1136,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
if (v == (Var *)NIL) {
*lengthPtr = 2;
-
+
if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
/*
* If substituting a local variable in a non-local context,
@@ -1196,7 +1194,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
return (var_Error);
}
*tstr = '\0';
-
+
v = VarFind (str + 2, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
if ((v == (Var *)NIL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
((tstr-str) == 4) && (str[3] == 'F' || str[3] == 'D'))
@@ -1222,7 +1220,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
vname[0] = str[2];
vname[1] = '\0';
v = VarFind(vname, ctxt, 0);
-
+
if (v != (Var *)NIL) {
/*
* No need for nested expansion or anything, as we're
@@ -1230,7 +1228,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
* but nested invocations in them...
*/
val = (char *)Buf_GetAll(v->val, (int *)NULL);
-
+
if (str[3] == 'D') {
val = VarModify(val, VarHead, (ClientData)0);
} else {
@@ -1249,7 +1247,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
}
}
}
-
+
if (v == (Var *)NIL) {
if ((((tstr-str) == 3) ||
((((tstr-str) == 4) && (str[3] == 'F' ||
@@ -1278,7 +1276,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
{
int len;
-
+
len = (tstr-str) - 3;
if ((strncmp(str+2, ".TARGET", len) == 0) ||
(strncmp(str+2, ".ARCHIVE", len) == 0) ||
@@ -1288,7 +1286,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
dynamic = TRUE;
}
}
-
+
if (!haveModifier) {
/*
* No modifiers -- have specification length so we can return
@@ -1338,9 +1336,9 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
str = Var_Subst(NULL, str, ctxt, err);
*freePtr = TRUE;
}
-
+
v->flags &= ~VAR_IN_USE;
-
+
/*
* Now we need to apply any modifiers the user wants applied.
* These are:
@@ -1366,7 +1364,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
while (*tstr != endc) {
char *newStr; /* New value to return */
char termc; /* Character which terminated scan */
-
+
if (DEBUG(VAR)) {
printf("Applying :%c to \"%s\"\n", *tstr, str);
}
@@ -1443,7 +1441,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
}
buf = Buf_Init(0);
-
+
/*
* Pass through the lhs looking for 1) escaped delimiters,
* '$'s and backslashes (place the escaped character in
@@ -1469,7 +1467,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
char *cp2;
int len;
Boolean freeIt;
-
+
cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
if (freeIt) {
@@ -1489,7 +1487,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
}
Buf_AddByte(buf, (Byte)'\0');
-
+
/*
* If lhs didn't end with the delimiter, complain and
* return NULL
@@ -1524,7 +1522,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
* it right here) and 3) expand any variable substitutions.
*/
buf = Buf_Init(0);
-
+
tstr = cp + 1;
for (cp = tstr; *cp != '\0' && *cp != delim; cp++) {
if ((*cp == '\\') &&
@@ -1555,7 +1553,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
}
Buf_AddByte(buf, (Byte)'\0');
-
+
/*
* If didn't end in delimiter character, complain
*/
@@ -1627,14 +1625,29 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
break;
}
/*FALLTHRU*/
- default: {
+#ifdef SUNSHCMD
+ case 's':
+ if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
+ char *err;
+ newStr = Cmd_Exec (str, &err);
+ if (err)
+ Error (err, str);
+ cp = tstr + 2;
+ termc = *cp;
+ break;
+ }
+ /*FALLTHRU*/
+#endif
+ default:
+ {
+#ifdef SYSVVARSUB
/*
* This can either be a bogus modifier or a System-V
* substitution command.
*/
VarPattern pattern;
Boolean eqFound;
-
+
pattern.flags = 0;
eqFound = FALSE;
/*
@@ -1657,7 +1670,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
cp++;
}
if (*cp == endc && eqFound) {
-
+
/*
* Now we break this sucker into the lhs and
* rhs. We must null terminate them of course.
@@ -1667,7 +1680,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
pattern.lhs = tstr;
pattern.leftLen = cp - tstr;
*cp++ = '\0';
-
+
pattern.rhs = cp;
cnt = 1;
while (cnt) {
@@ -1680,7 +1693,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
}
pattern.rightLen = cp - pattern.rhs;
*cp = '\0';
-
+
/*
* SYSV modifications happen through the whole
* string. Note the pattern is anchored at the end.
@@ -1694,11 +1707,13 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
pattern.lhs[pattern.leftLen] = '=';
pattern.rhs[pattern.rightLen] = endc;
termc = endc;
- } else {
+ } else
+#endif
+ {
Error ("Unknown modifier '%c'\n", *tstr);
for (cp = tstr+1;
*cp != ':' && *cp != endc && *cp != '\0';
- cp++)
+ cp++)
continue;
termc = *cp;
newStr = var_Error;
@@ -1708,7 +1723,7 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
if (DEBUG(VAR)) {
printf("Result is \"%s\"\n", newStr);
}
-
+
if (*freePtr) {
free (str);
}
@@ -1732,10 +1747,10 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
*lengthPtr = tstr - start + 1;
*tstr = endc;
}
-
+
if (v->flags & VAR_FROM_ENV) {
Boolean destroy = FALSE;
-
+
if (str != (char *)Buf_GetAll(v->val, (int *)NULL)) {
destroy = TRUE;
} else {
@@ -1842,9 +1857,9 @@ Var_Subst (var, str, ctxt, undefErr)
/*
* Scan up to the end of the variable name.
*/
- for (p = &str[2]; *p &&
+ for (p = &str[2]; *p &&
*p != ':' && *p != ')' && *p != '}'; p++)
- if (*p == '$')
+ if (*p == '$')
break;
/*
* A variable inside the variable. We cannot expand
@@ -1856,14 +1871,14 @@ Var_Subst (var, str, ctxt, undefErr)
str = p;
continue;
}
-
- if (strncmp(var, str + 2, p - str - 2) != 0 ||
+
+ if (strncmp(var, str + 2, p - str - 2) != 0 ||
var[p - str - 2] != '\0') {
/*
* Not the variable we want to expand, scan
* until the next variable
*/
- for (;*p != '$' && *p != '\0'; p++)
+ for (;*p != '$' && *p != '\0'; p++)
continue;
Buf_AddBytes(buf, p - str, (Byte *) str);
str = p;
@@ -1877,7 +1892,7 @@ Var_Subst (var, str, ctxt, undefErr)
if (!expand)
continue;
}
-
+
val = Var_Parse (str, ctxt, undefErr, &length, &doFree);
/*
@@ -1917,7 +1932,7 @@ Var_Subst (var, str, ctxt, undefErr)
* advance the string pointer.
*/
str += length;
-
+
/*
* Copy all the characters from the variable value straight
* into the new string.
@@ -1929,7 +1944,7 @@ Var_Subst (var, str, ctxt, undefErr)
}
}
}
-
+
Buf_AddByte (buf, '\0');
str = (char *)Buf_GetAll (buf, (int *)NULL);
Buf_Destroy (buf, FALSE);
@@ -1988,7 +2003,7 @@ Var_GetHead(file)
* None
*
* Side Effects:
- * The VAR_CMD and VAR_GLOBAL contexts are created
+ * The VAR_CMD and VAR_GLOBAL contexts are created
*-----------------------------------------------------------------------
*/
void
@@ -2006,7 +2021,7 @@ Var_End ()
{
Lst_Destroy(allVars, VarDelete);
}
-
+
/****************** PRINT DEBUGGING INFO *****************/
static int