Import NetBSD's make

This commit is contained in:
Arun Thomas 2010-02-04 16:52:54 +00:00
parent 8f82633fa2
commit 4b02d003db
90 changed files with 36049 additions and 2 deletions

40
commands/bmake/Makefile Normal file
View File

@ -0,0 +1,40 @@
# $NetBSD: Makefile,v 1.49 2009/04/14 22:15:23 lukem Exp $
# @(#)Makefile 5.2 (Berkeley) 12/28/90
PROG= make
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
make.c parse.c str.c suff.c targ.c trace.c var.c util.c
SRCS+= strlist.c
SRCS+= make_malloc.c
SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \
lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \
lstInit.c lstInsert.c lstIsAtEnd.c lstIsEmpty.c lstLast.c \
lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c
SRCS += lstPrev.c
.PATH: ${.CURDIR}/lst.lib
.if make(install)
SUBDIR= PSD.doc
.endif
.if make(obj) || make(clean)
SUBDIR+= unit-tests
.endif
.include <bsd.prog.mk>
.include <bsd.subdir.mk>
CPPFLAGS+= -DMAKE_NATIVE
COPTS.var.c+= -Wno-cast-qual
.ifdef TOOLDIR
# this is a native netbsd build,
# use libutil rather than the local emalloc etc.
CPPFLAGS+= -DUSE_EMALLOC
LDADD+=-lutil
DPADD+=${LIBUTIL}
.endif
# A simple unit-test driver to help catch regressions
accept test:
cd ${.CURDIR}/unit-tests && ${.MAKE:S,^./,${.CURDIR}/,} TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}

View File

@ -0,0 +1,47 @@
# $NetBSD: Makefile.boot,v 1.19 2009/01/24 11:59:39 dsl 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
#
#CC=gcc -O -g
CC=cc
CFLAGS=-g -Wall -DHAVE_SETENV -DHAVE_STRERROR -DHAVE_STRDUP -DHAVE_STRFTIME -DHAVE_VSNPRINTF -DUSE_SELECT -D_POSIX_SOURCE
.c.o:
${CC} ${CFLAGS} -c $< -o $@
MACHINE=i386
MACHINE_ARCH=i386
# tested on HP-UX 10.20
#MAKE_MACHINE=hp700
#MAKE_MACHINE_ARCH=hppa
CFLAGS+= -DTARGET_MACHINE=\"${MACHINE}\" \
-DTARGET_MACHINE_ARCH=\"${MACHINE_ARCH}\" \
-DMAKE_MACHINE=\"${MACHINE}\"
LIBS=
OBJ=arch.o buf.o compat.o cond.o dir.o for.o hash.o job.o main.o make.o \
make_malloc.o parse.o str.o strlist.o suff.o targ.o trace.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 lst.lib/lstPrev.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

View File

@ -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>

File diff suppressed because it is too large Load Diff

1354
commands/bmake/arch.c Normal file

File diff suppressed because it is too large Load Diff

250
commands/bmake/buf.c Normal file
View File

@ -0,0 +1,250 @@
/* $NetBSD: buf.c,v 1.24 2009/01/17 13:29:37 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: buf.c,v 1.24 2009/01/17 13:29:37 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: buf.c,v 1.24 2009/01/17 13:29:37 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* buf.c --
* Functions for automatically-expanded buffers.
*/
#include "make.h"
#include "buf.h"
#ifndef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#define BUF_DEF_SIZE 256 /* Default buffer size */
/*-
*-----------------------------------------------------------------------
* Buf_Expand_1 --
* Extend buffer for single byte add.
*
*-----------------------------------------------------------------------
*/
void
Buf_Expand_1(Buffer *bp)
{
bp->size += max(bp->size, 16);
bp->buffer = bmake_realloc(bp->buffer, bp->size);
}
/*-
*-----------------------------------------------------------------------
* Buf_AddBytes --
* Add a number of bytes to the buffer.
*
* Results:
* None.
*
* Side Effects:
* Guess what?
*
*-----------------------------------------------------------------------
*/
void
Buf_AddBytes(Buffer *bp, int numBytes, const Byte *bytesPtr)
{
int count = bp->count;
Byte *ptr;
if (__predict_false(count + numBytes >= bp->size)) {
bp->size += max(bp->size, numBytes + 16);
bp->buffer = bmake_realloc(bp->buffer, bp->size);
}
ptr = bp->buffer + count;
bp->count = count + numBytes;
ptr[numBytes] = 0;
memcpy(ptr, bytesPtr, numBytes);
}
/*-
*-----------------------------------------------------------------------
* Buf_GetAll --
* Get all the available data at once.
*
* Results:
* A pointer to the data and the number of bytes available.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
Byte *
Buf_GetAll(Buffer *bp, int *numBytesPtr)
{
if (numBytesPtr != NULL)
*numBytesPtr = bp->count;
return (bp->buffer);
}
/*-
*-----------------------------------------------------------------------
* Buf_Empty --
* Throw away bytes in a buffer.
*
* Results:
* None.
*
* Side Effects:
* The bytes are discarded.
*
*-----------------------------------------------------------------------
*/
void
Buf_Empty(Buffer *bp)
{
bp->count = 0;
*bp->buffer = 0;
}
/*-
*-----------------------------------------------------------------------
* Buf_Init --
* Initialize a buffer. If no initial size is given, a reasonable
* default is used.
*
* Input:
* size Initial size for the buffer
*
* Results:
* A buffer to be given to other functions in this library.
*
* Side Effects:
* The buffer is created, the space allocated and pointers
* initialized.
*
*-----------------------------------------------------------------------
*/
void
Buf_Init(Buffer *bp, int size)
{
if (size <= 0) {
size = BUF_DEF_SIZE;
}
bp->size = size;
bp->count = 0;
bp->buffer = bmake_malloc(size);
*bp->buffer = 0;
}
/*-
*-----------------------------------------------------------------------
* Buf_Destroy --
* Nuke a buffer and all its resources.
*
* Input:
* buf Buffer to destroy
* freeData TRUE if the data should be destroyed
*
* Results:
* Data buffer, NULL if freed
*
* Side Effects:
* The buffer is freed.
*
*-----------------------------------------------------------------------
*/
Byte *
Buf_Destroy(Buffer *buf, Boolean freeData)
{
Byte *data;
data = buf->buffer;
if (freeData) {
free(data);
data = NULL;
}
buf->size = 0;
buf->count = 0;
buf->buffer = NULL;
return data;
}

118
commands/bmake/buf.h Normal file
View File

@ -0,0 +1,118 @@
/* $NetBSD: buf.h,v 1.16 2009/01/17 13:55:42 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)buf.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)buf.h 8.1 (Berkeley) 6/6/93
*/
/*-
* buf.h --
* Header for users of the buf library.
*/
#ifndef _BUF_H
#define _BUF_H
typedef char Byte;
typedef struct Buffer {
int size; /* Current size of the buffer */
int count; /* Number of bytes in buffer */
Byte *buffer; /* The buffer itself (zero terminated) */
} Buffer;
/* If we aren't on netbsd, __predict_false() might not be defined. */
#ifndef __predict_false
#define __predict_false(x) (x)
#endif
/* Buf_AddByte adds a single byte to a buffer. */
#define Buf_AddByte(bp, byte) do { \
int _count = ++(bp)->count; \
char *_ptr; \
if (__predict_false(_count >= (bp)->size)) \
Buf_Expand_1(bp); \
_ptr = (bp)->buffer + _count; \
_ptr[-1] = (byte); \
_ptr[0] = 0; \
} while (0)
#define BUF_ERROR 256
#define Buf_Size(bp) ((bp)->count)
void Buf_Expand_1(Buffer *);
void Buf_AddBytes(Buffer *, int, const Byte *);
Byte *Buf_GetAll(Buffer *, int *);
void Buf_Empty(Buffer *);
void Buf_Init(Buffer *, int);
Byte *Buf_Destroy(Buffer *, Boolean);
#endif /* _BUF_H */

6
commands/bmake/build.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
export PATH=$PATH:/usr/gnu/bin
make -f Makefile.boot clean
make -f Makefile.boot CFLAGS="-g -Wall -DHAVE_SETENV -DHAVE_STRERROR -DHAVE_STRDUP -DHAVE_STRFTIME -DHAVE_VSNPRINTF -D_GNU_SOURCE -DUSE_SELECT -DSYSV -D_POSIX_SOURCE"
#make -f Makefile.boot

717
commands/bmake/compat.c Normal file
View File

@ -0,0 +1,717 @@
/* $NetBSD: compat.c,v 1.76 2009/02/22 07:33:00 dholland Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: compat.c,v 1.76 2009/02/22 07:33:00 dholland Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94";
#else
__RCSID("$NetBSD: compat.c,v 1.76 2009/02/22 07:33:00 dholland Exp $");
#endif
#endif /* not lint */
#endif
/*-
* compat.c --
* The routines in this file implement the full-compatibility
* mode of PMake. Most of the special functionality of PMake
* is available in this mode. Things not supported:
* - different shells.
* - friendly variable substitution.
*
* Interface:
* Compat_Run Initialize things for this module and recreate
* thems as need creatin'
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
#include "job.h"
#include "pathnames.h"
/*
* The following array is used to make a fast determination of which
* characters are interpreted specially by the shell. If a command
* contains any of these characters, it is executed by the shell, not
* directly by us.
*/
static char meta[256];
static GNode *curTarg = NULL;
static GNode *ENDNode;
static void CompatInterrupt(int);
static void
Compat_Init(void)
{
const char *cp;
Shell_Init(); /* setup default shell */
for (cp = "#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) {
meta[(unsigned char) *cp] = 1;
}
/*
* The null character serves as a sentinel in the string.
*/
meta[0] = 1;
}
/*-
*-----------------------------------------------------------------------
* CompatInterrupt --
* Interrupt the creation of the current target and remove it if
* it ain't precious.
*
* Results:
* None.
*
* Side Effects:
* The target is removed and the process exits. If .INTERRUPT exists,
* its commands are run first WITH INTERRUPTS IGNORED..
*
*-----------------------------------------------------------------------
*/
static void
CompatInterrupt(int signo)
{
GNode *gn;
if ((curTarg != NULL) && !Targ_Precious (curTarg)) {
char *p1;
char *file = Var_Value(TARGET, curTarg, &p1);
if (!noExecute && eunlink(file) != -1) {
Error("*** %s removed", file);
}
if (p1)
free(p1);
/*
* Run .INTERRUPT only if hit with interrupt signal
*/
if (signo == SIGINT) {
gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
if (gn != NULL) {
Compat_Make(gn, gn);
}
}
}
exit(signo);
}
/*-
*-----------------------------------------------------------------------
* CompatRunCommand --
* Execute the next command for a target. If the command returns an
* error, the node's made field is set to ERROR and creation stops.
*
* Input:
* cmdp Command to execute
* gnp Node from which the command came
*
* Results:
* 0 if the command succeeded, 1 if an error occurred.
*
* Side Effects:
* The node's 'made' field may be set to ERROR.
*
*-----------------------------------------------------------------------
*/
int
CompatRunCommand(void *cmdp, void *gnp)
{
char *cmdStart; /* Start of expanded command */
char *cp, *bp;
Boolean silent, /* Don't print command */
doIt; /* Execute even if -n */
volatile Boolean errCheck; /* Check errors */
int reason; /* Reason for child's death */
int status; /* Description of child's death */
pid_t cpid; /* Child actually found */
pid_t retstat; /* Result of wait */
LstNode cmdNode; /* Node where current command is located */
const char ** volatile av; /* Argument vector for thing to exec */
char ** volatile mav;/* Copy of the argument vector for freeing */
int argc; /* Number of arguments in av or 0 if not
* dynamically allocated */
Boolean local; /* TRUE if command should be executed
* locally */
Boolean useShell; /* TRUE if command should be executed
* using a shell */
char * volatile cmd = (char *)cmdp;
GNode *gn = (GNode *)gnp;
silent = gn->type & OP_SILENT;
errCheck = !(gn->type & OP_IGNORE);
doIt = FALSE;
cmdNode = Lst_Member(gn->commands, cmd);
cmdStart = Var_Subst(NULL, cmd, gn, FALSE);
/*
* brk_string will return an argv with a NULL in av[0], thus causing
* execvp to choke and die horribly. Besides, how can we execute a null
* 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);
return(0);
}
cmd = cmdStart;
Lst_Replace(cmdNode, cmdStart);
if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) {
(void)Lst_AtEnd(ENDNode->commands, cmdStart);
return(0);
}
if (strcmp(cmdStart, "...") == 0) {
gn->type |= OP_SAVE_CMDS;
return(0);
}
while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) {
switch (*cmd) {
case '@':
silent = DEBUG(LOUD) ? FALSE : TRUE;
break;
case '-':
errCheck = FALSE;
break;
case '+':
doIt = TRUE;
if (!meta[0]) /* we came here from jobs */
Compat_Init();
break;
}
cmd++;
}
while (isspace((unsigned char)*cmd))
cmd++;
#if !defined(MAKE_NATIVE)
/*
* In a non-native build, the host environment might be weird enough
* that it's necessary to go through a shell to get the correct
* behaviour. Or perhaps the shell has been replaced with something
* that does extra logging, and that should not be bypassed.
*/
useShell = TRUE;
#else
/*
* Search for meta characters in the command. If there are no meta
* characters, there's no need to execute a shell to execute the
* command.
*/
for (cp = cmd; !meta[(unsigned char)*cp]; cp++) {
continue;
}
useShell = (*cp != '\0');
#endif
/*
* Print the command before echoing if we're not supposed to be quiet for
* this one. We also print the command if -n given.
*/
if (!silent || NoExecute(gn)) {
printf("%s\n", cmd);
fflush(stdout);
}
/*
* If we're not supposed to execute any commands, this is as far as
* we go...
*/
if (!doIt && NoExecute(gn)) {
return (0);
}
if (DEBUG(JOB))
fprintf(debug_file, "Execute: '%s'\n", cmd);
again:
if (useShell) {
/*
* We need to pass the command off to the shell, typically
* because the command contains a "meta" character.
*/
static const char *shargv[4];
shargv[0] = shellPath;
/*
* The following work for any of the builtin shell specs.
*/
if (DEBUG(SHELL))
shargv[1] = "-xc";
else
shargv[1] = "-c";
shargv[2] = cmd;
shargv[3] = NULL;
av = shargv;
argc = 0;
bp = NULL;
mav = NULL;
} else {
/*
* No meta-characters, so no need to exec a shell. Break the command
* into words to form an argument vector we can execute.
*/
mav = brk_string(cmd, &argc, TRUE, &bp);
if (mav == NULL) {
useShell = 1;
goto again;
}
av = (const char **)mav;
}
local = TRUE;
/*
* Fork and execute the single command. If the fork fails, we abort.
*/
#if defined(__minix)
cpid = fork();
#else
cpid = vfork();
#endif
if (cpid < 0) {
Fatal("Could not fork");
}
if (cpid == 0) {
Check_Cwd(av);
Var_ExportVars();
if (local)
(void)execvp(av[0], (char *const *)UNCONST(av));
else
(void)execv(av[0], (char *const *)UNCONST(av));
execError("exec", av[0]);
_exit(1);
}
if (mav)
free(mav);
if (bp)
free(bp);
Lst_Replace(cmdNode, NULL);
/*
* The child is off and running. Now all we can do is wait...
*/
while (1) {
while ((retstat = wait(&reason)) != cpid) {
if (retstat == -1 && errno != EINTR) {
break;
}
}
if (retstat > -1) {
if (WIFSTOPPED(reason)) {
status = WSTOPSIG(reason); /* stopped */
} else if (WIFEXITED(reason)) {
status = WEXITSTATUS(reason); /* exited */
if (status != 0) {
if (DEBUG(ERROR)) {
fprintf(debug_file, "\n*** Failed target: %s\n*** Failed command: ",
gn->name);
for (cp = cmd; *cp; ) {
if (isspace((unsigned char)*cp)) {
fprintf(debug_file, " ");
while (isspace((unsigned char)*cp))
cp++;
} else {
fprintf(debug_file, "%c", *cp);
cp++;
}
}
fprintf(debug_file, "\n");
}
fprintf(debug_file, "*** Error code %d", status);
}
} else {
status = WTERMSIG(reason); /* signaled */
printf("*** Signal %d", status);
}
if (!WIFEXITED(reason) || (status != 0)) {
if (errCheck) {
gn->made = ERROR;
if (keepgoing) {
/*
* Abort the current target, but let others
* continue.
*/
printf(" (continuing)\n");
}
} else {
/*
* Continue executing commands for this target.
* If we return 0, this will happen...
*/
printf(" (ignored)\n");
status = 0;
}
}
break;
} else {
Fatal("error in wait: %d: %s", retstat, strerror(errno));
/*NOTREACHED*/
}
}
free(cmdStart);
return (status);
}
/*-
*-----------------------------------------------------------------------
* Compat_Make --
* Make a target.
*
* Input:
* gnp The node to make
* pgnp Parent to abort if necessary
*
* Results:
* 0
*
* Side Effects:
* If an error is detected and not being ignored, the process exits.
*
*-----------------------------------------------------------------------
*/
int
Compat_Make(void *gnp, void *pgnp)
{
GNode *gn = (GNode *)gnp;
GNode *pgn = (GNode *)pgnp;
if (!meta[0]) /* we came here from jobs */
Compat_Init();
if (gn->made == UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) {
/*
* First mark ourselves to be made, then apply whatever transformations
* the suffix module thinks are necessary. Once that's done, we can
* descend and make all our children. If any of them has an error
* but the -k flag was given, our 'make' field will be set FALSE again.
* This is our signal to not attempt to do anything but abort our
* parent as well.
*/
gn->flags |= REMAKE;
gn->made = BEINGMADE;
if ((gn->type & OP_MADE) == 0)
Suff_FindDeps(gn);
Lst_ForEach(gn->children, Compat_Make, gn);
if ((gn->flags & REMAKE) == 0) {
gn->made = ABORTED;
pgn->flags &= ~REMAKE;
goto cohorts;
}
if (Lst_Member(gn->iParents, pgn) != NULL) {
char *p1;
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
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
* we were modified last. The criteria for datedness are defined by the
* Make_OODate function.
*/
if (DEBUG(MAKE)) {
fprintf(debug_file, "Examining %s...", gn->name);
}
if (! Make_OODate(gn)) {
gn->made = UPTODATE;
if (DEBUG(MAKE)) {
fprintf(debug_file, "up-to-date.\n");
}
goto cohorts;
} else if (DEBUG(MAKE)) {
fprintf(debug_file, "out-of-date.\n");
}
/*
* If the user is just seeing if something is out-of-date, exit now
* to tell him/her "yes".
*/
if (queryFlag) {
exit(1);
}
/*
* We need to be re-made. We also have to make sure we've got a $?
* variable. To be nice, we also define the $> variable using
* 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.
*/
if (Targ_Ignore(gn)) {
gn->type |= OP_IGNORE;
}
if (Targ_Silent(gn)) {
gn->type |= OP_SILENT;
}
if (Job_CheckCommands(gn, Fatal)) {
/*
* Our commands are ok, but we still have to worry about the -t
* flag...
*/
if (!touchFlag || (gn->type & OP_MAKE)) {
curTarg = gn;
Lst_ForEach(gn->commands, CompatRunCommand, gn);
curTarg = NULL;
} else {
Job_Touch(gn, gn->type & OP_SILENT);
}
} else {
gn->made = ERROR;
}
if (gn->made != ERROR) {
/*
* If the node was made successfully, mark it so, update
* its modification time and timestamp all its parents. Note
* that for .ZEROTIME targets, the timestamping isn't done.
* This is to keep its state from affecting that of its parent.
*/
gn->made = MADE;
pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0;
if (!(gn->type & OP_EXEC)) {
pgn->flags |= CHILDMADE;
Make_TimeStamp(pgn, gn);
}
} else if (keepgoing) {
pgn->flags &= ~REMAKE;
} else {
PrintOnError("\n\nStop.");
exit(1);
}
} else if (gn->made == ERROR) {
/*
* Already had an error when making this beastie. Tell the parent
* to abort.
*/
pgn->flags &= ~REMAKE;
} else {
if (Lst_Member(gn->iParents, pgn) != NULL) {
char *p1;
Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
if (p1)
free(p1);
}
switch(gn->made) {
case BEINGMADE:
Error("Graph cycles through %s", gn->name);
gn->made = ERROR;
pgn->flags &= ~REMAKE;
break;
case MADE:
if ((gn->type & OP_EXEC) == 0) {
pgn->flags |= CHILDMADE;
Make_TimeStamp(pgn, gn);
}
break;
case UPTODATE:
if ((gn->type & OP_EXEC) == 0) {
Make_TimeStamp(pgn, gn);
}
break;
default:
break;
}
}
cohorts:
Lst_ForEach(gn->cohorts, Compat_Make, pgnp);
return (0);
}
/*-
*-----------------------------------------------------------------------
* Compat_Run --
* Initialize this mode and start making.
*
* Input:
* targs List of target nodes to re-create
*
* Results:
* None.
*
* Side Effects:
* Guess what?
*
*-----------------------------------------------------------------------
*/
void
Compat_Run(Lst targs)
{
GNode *gn = NULL;/* Current root target */
int errors; /* Number of targets not remade due to errors */
Compat_Init();
if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
signal(SIGINT, CompatInterrupt);
}
if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
signal(SIGTERM, CompatInterrupt);
}
if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
signal(SIGHUP, CompatInterrupt);
}
if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
signal(SIGQUIT, CompatInterrupt);
}
ENDNode = Targ_FindNode(".END", TARG_CREATE);
ENDNode->type = OP_SPECIAL;
/*
* If the user has defined a .BEGIN target, execute the commands attached
* to it.
*/
if (!queryFlag) {
gn = Targ_FindNode(".BEGIN", TARG_NOCREATE);
if (gn != NULL) {
Compat_Make(gn, gn);
if (gn->made == ERROR) {
PrintOnError("\n\nStop.");
exit(1);
}
}
}
/*
* Expand .USE nodes right now, because they can modify the structure
* of the tree.
*/
Make_ExpandUse(targs);
/*
* For each entry in the list of targets to create, call Compat_Make on
* it to create the thing. Compat_Make will leave the 'made' field of gn
* in one of several states:
* UPTODATE gn was already up-to-date
* MADE gn was recreated successfully
* ERROR An error occurred while gn was being created
* ABORTED gn was not remade because one of its inferiors
* could not be made due to errors.
*/
errors = 0;
while (!Lst_IsEmpty (targs)) {
gn = (GNode *)Lst_DeQueue(targs);
Compat_Make(gn, gn);
if (gn->made == UPTODATE) {
printf("`%s' is up to date.\n", gn->name);
} else if (gn->made == ABORTED) {
printf("`%s' not remade because of errors.\n", gn->name);
errors += 1;
}
}
/*
* If the user has defined a .END target, run its commands.
*/
if (errors == 0) {
Compat_Make(ENDNode, ENDNode);
if (gn->made == ERROR) {
PrintOnError("\n\nStop.");
exit(1);
}
}
}

1410
commands/bmake/cond.c Normal file

File diff suppressed because it is too large Load Diff

154
commands/bmake/config.h Normal file
View File

@ -0,0 +1,154 @@
/* $NetBSD: config.h,v 1.20 2007/10/14 20:22:53 apb Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)config.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)config.h 8.1 (Berkeley) 6/6/93
*/
/*
* DEFMAXJOBS
* DEFMAXLOCAL
* These control the default concurrency. On no occasion will more
* than DEFMAXJOBS targets be created at once (locally or remotely)
* DEFMAXLOCAL is the highest number of targets which will be
* created on the local machine at once. Note that if you set this
* to 0, nothing will ever happen...
*/
#define DEFMAXJOBS 4
#define DEFMAXLOCAL 1
/*
* INCLUDES
* LIBRARIES
* These control the handling of the .INCLUDES and .LIBS variables.
* If INCLUDES is defined, the .INCLUDES variable will be filled
* from the search paths of those suffixes which are marked by
* .INCLUDES dependency lines. Similarly for LIBRARIES and .LIBS
* See suff.c for more details.
*/
#define INCLUDES
#define LIBRARIES
/*
* LIBSUFF
* Is the suffix used to denote libraries and is used by the Suff module
* to find the search path on which to seek any -l<xx> targets.
*
* RECHECK
* If defined, Make_Update will check a target for its current
* modification time after it has been re-made, setting it to the
* starting time of the make only if the target still doesn't exist.
* Unfortunately, under NFS the modification time often doesn't
* get updated in time, so a target will appear to not have been
* 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.
*/
#define LIBSUFF ".a"
#define RECHECK
/*
* 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
/*
* USE_IOVEC
* We have writev(2)
*/
#define USE_IOVEC
#if defined(MAKE_NATIVE) && !defined(__ELF__)
# ifndef RANLIBMAG
# define RANLIBMAG "__.SYMDEF"
# endif
#endif

1766
commands/bmake/dir.c Normal file

File diff suppressed because it is too large Load Diff

108
commands/bmake/dir.h Normal file
View File

@ -0,0 +1,108 @@
/* $NetBSD: dir.h,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)dir.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)dir.h 8.1 (Berkeley) 6/6/93
*/
/* dir.h --
*/
#ifndef _DIR
#define _DIR
typedef struct Path {
char *name; /* Name of directory */
int refCount; /* Number of paths with this directory */
int hits; /* the number of times a file in this
* directory has been found */
Hash_Table files; /* Hash table of files in directory */
} Path;
void Dir_Init(const char *);
void Dir_InitCur(const char *);
void Dir_InitDot(void);
void Dir_End(void);
void Dir_SetPATH(void);
Boolean Dir_HasWildcards(char *);
void Dir_Expand(const char *, Lst, Lst);
char *Dir_FindFile(const char *, Lst);
int Dir_FindHereOrAbove(char *, char *, char *, int);
int Dir_MTime(GNode *);
Path *Dir_AddDir(Lst, const char *);
char *Dir_MakeFlags(const char *, Lst);
void Dir_ClearPath(Lst);
void Dir_Concat(Lst, Lst);
void Dir_PrintDirectories(void);
void Dir_PrintPath(Lst);
void Dir_Destroy(void *);
void * Dir_CopyDir(void *);
#endif /* _DIR */

471
commands/bmake/for.c Normal file
View File

@ -0,0 +1,471 @@
/* $NetBSD: for.c,v 1.46 2009/01/17 13:29:37 dsl Exp $ */
/*
* 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
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: for.c,v 1.46 2009/01/17 13:29:37 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: for.c,v 1.46 2009/01/17 13:29:37 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* for.c --
* Functions to handle loops in a makefile.
*
* Interface:
* For_Eval Evaluate the loop in the passed line.
* For_Run Run accumulated loop
*
*/
#include <assert.h>
#include <ctype.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
#include "buf.h"
#include "strlist.h"
#define FOR_SUB_ESCAPE_CHAR 1
#define FOR_SUB_ESCAPE_BRACE 2
#define FOR_SUB_ESCAPE_PAREN 4
/*
* For statements are of the form:
*
* .for <variable> in <varlist>
* ...
* .endfor
*
* 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;
* then we evaluate the for loop for each variable in the varlist.
*
* Note that any nested fors are just passed through; they get handled
* recursively in For_Eval when we're expanding the enclosing for in
* For_Run.
*/
static int forLevel = 0; /* Nesting level */
/*
* State of a for loop.
*/
typedef struct _For {
Buffer buf; /* Body of loop */
strlist_t vars; /* Iteration variables */
strlist_t items; /* Substitution items */
char *parse_buf;
int short_var;
int sub_next;
} For;
static For *accumFor; /* Loop being accumulated */
static char *
make_str(const char *ptr, int len)
{
char *new_ptr;
new_ptr = bmake_malloc(len + 1);
memcpy(new_ptr, ptr, len);
new_ptr[len] = 0;
return new_ptr;
}
static void
For_Free(For *arg)
{
Buf_Destroy(&arg->buf, TRUE);
strlist_clean(&arg->vars);
strlist_clean(&arg->items);
free(arg->parse_buf);
free(arg);
}
/*-
*-----------------------------------------------------------------------
* For_Eval --
* Evaluate the for loop in the passed line. The line
* looks like this:
* .for <variable> in <varlist>
*
* Input:
* line Line to parse
*
* Results:
* 0: Not a .for statement, parse the line
* 1: We found a for loop
* -1: A .for statement with a bad syntax error, discard.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
int
For_Eval(char *line)
{
For *new_for;
char *ptr = line, *sub;
int len;
int escapes;
unsigned char ch;
/* Skip the '.' and any following whitespace */
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
continue;
/*
* If we are not in a for loop quickly determine if the statement is
* a for.
*/
if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' ||
!isspace((unsigned char) ptr[3])) {
if (ptr[0] == 'e' && strncmp(ptr+1, "ndfor", 5) == 0) {
Parse_Error(PARSE_FATAL, "for-less endfor");
return -1;
}
return 0;
}
ptr += 3;
/*
* we found a for loop, and now we are going to parse it.
*/
new_for = bmake_malloc(sizeof *new_for);
memset(new_for, 0, sizeof *new_for);
/* Grab the variables. Terminate on "in". */
for (;; ptr += len) {
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
if (*ptr == '\0') {
Parse_Error(PARSE_FATAL, "missing `in' in for");
For_Free(new_for);
return -1;
}
for (len = 1; ptr[len] && !isspace((unsigned char)ptr[len]); len++)
continue;
if (len == 2 && ptr[0] == 'i' && ptr[1] == 'n') {
ptr += 2;
break;
}
if (len == 1)
new_for->short_var = 1;
strlist_add_str(&new_for->vars, make_str(ptr, len), len);
}
if (strlist_num(&new_for->vars) == 0) {
Parse_Error(PARSE_FATAL, "no iteration variables in for");
For_Free(new_for);
return -1;
}
while (*ptr && isspace((unsigned char) *ptr))
ptr++;
/*
* Make a list with the remaining words
* The values are substituted as ${:U<value>...} so we must \ escape
* characters that break that syntax.
* Variables are fully expanded - so it is safe for escape $.
* We can't do the escapes here - because we don't know whether
* we are substuting into ${...} or $(...).
*/
sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE);
for (ptr = sub;; ptr += len) {
while (*ptr && isspace((unsigned char)*ptr))
ptr++;
if (*ptr == 0)
break;
escapes = 0;
for (len = 0; (ch = ptr[len]) != 0 && !isspace(ch); len++) {
if (ch == ':' || ch == '$' || ch == '\\')
escapes |= FOR_SUB_ESCAPE_CHAR;
else if (ch == ')')
escapes |= FOR_SUB_ESCAPE_PAREN;
else if (ch == /*{*/ '}')
escapes |= FOR_SUB_ESCAPE_BRACE;
}
strlist_add_str(&new_for->items, make_str(ptr, len), escapes);
}
free(sub);
if (strlist_num(&new_for->items) % strlist_num(&new_for->vars)) {
Parse_Error(PARSE_FATAL,
"Wrong number of words in .for substitution list %d %d",
strlist_num(&new_for->items), strlist_num(&new_for->vars));
/*
* Return 'success' so that the body of the .for loop is accumulated.
* Remove all items so that the loop doesn't iterate.
*/
strlist_clean(&new_for->items);
}
Buf_Init(&new_for->buf, 0);
accumFor = new_for;
forLevel = 1;
return 1;
}
/*
* Add another line to a .for loop.
* Returns 0 when the matching .endfor is reached.
*/
int
For_Accum(char *line)
{
char *ptr = line;
if (*ptr == '.') {
for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++)
continue;
if (strncmp(ptr, "endfor", 6) == 0 &&
(isspace((unsigned char) ptr[6]) || !ptr[6])) {
if (DEBUG(FOR))
(void)fprintf(debug_file, "For: end for %d\n", forLevel);
if (--forLevel <= 0)
return 0;
} else if (strncmp(ptr, "for", 3) == 0 &&
isspace((unsigned char) ptr[3])) {
forLevel++;
if (DEBUG(FOR))
(void)fprintf(debug_file, "For: new loop %d\n", forLevel);
}
}
Buf_AddBytes(&accumFor->buf, strlen(line), line);
Buf_AddByte(&accumFor->buf, '\n');
return 1;
}
/*-
*-----------------------------------------------------------------------
* For_Run --
* Run the for loop, imitating the actions of an include file
*
* Results:
* None.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
static int
for_var_len(const char *var)
{
char ch, var_start, var_end;
int depth;
int len;
var_start = *var;
if (var_start == 0)
/* just escape the $ */
return 0;
if (var_start == '(')
var_end = ')';
else if (var_start == '{')
var_end = '}';
else
/* Single char variable */
return 1;
depth = 1;
for (len = 1; (ch = var[len++]) != 0;) {
if (ch == var_start)
depth++;
else if (ch == var_end && --depth == 0)
return len;
}
/* Variable end not found, escape the $ */
return 0;
}
static void
for_substitute(Buffer *cmds, strlist_t *items, unsigned int item_no, char ech)
{
const char *item = strlist_str(items, item_no);
int len;
char ch;
/* If there were no escapes, or the only escape is the other variable
* terminator, then just substitute the full string */
if (!(strlist_info(items, item_no) &
(ech == ')' ? ~FOR_SUB_ESCAPE_BRACE : ~FOR_SUB_ESCAPE_PAREN))) {
Buf_AddBytes(cmds, strlen(item), item);
return;
}
/* Escape ':', '$', '\\' and 'ech' - removed by :U processing */
while ((ch = *item++) != 0) {
if (ch == '$') {
len = for_var_len(item);
if (len != 0) {
Buf_AddBytes(cmds, len + 1, item - 1);
item += len;
continue;
}
Buf_AddByte(cmds, '\\');
} else if (ch == ':' || ch == '\\' || ch == ech)
Buf_AddByte(cmds, '\\');
Buf_AddByte(cmds, ch);
}
}
static char *
For_Iterate(void *v_arg)
{
For *arg = v_arg;
int i, len;
char *var;
char *cp;
char *cmd_cp;
char *body_end;
char ch;
Buffer cmds;
if (arg->sub_next + strlist_num(&arg->vars) > strlist_num(&arg->items)) {
/* No more iterations */
For_Free(arg);
return NULL;
}
free(arg->parse_buf);
arg->parse_buf = NULL;
/*
* Scan the for loop body and replace references to the loop variables
* with variable references that expand to the required text.
* Using variable expansions ensures that the .for loop can't generate
* syntax, and that the later parsing will still see a variable.
* We assume that the null variable will never be defined.
*
* The detection of substitions of the loop control variable is naive.
* Many of the modifiers use \ to escape $ (not $) so it is possible
* to contrive a makefile where an unwanted substitution happens.
*/
cmd_cp = Buf_GetAll(&arg->buf, &len);
body_end = cmd_cp + len;
Buf_Init(&cmds, len + 256);
for (cp = cmd_cp; (cp = strchr(cp, '$')) != NULL;) {
char ech;
ch = *++cp;
if ((ch == '(' && (ech = ')')) || (ch == '{' && (ech = '}'))) {
cp++;
/* Check variable name against the .for loop variables */
STRLIST_FOREACH(var, &arg->vars, i) {
len = strlist_info(&arg->vars, i);
if (memcmp(cp, var, len) != 0)
continue;
if (cp[len] != ':' && cp[len] != ech && cp[len] != '\\')
continue;
/* Found a variable match. Replace with :U<value> */
Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
Buf_AddBytes(&cmds, 2, ":U");
cp += len;
cmd_cp = cp;
for_substitute(&cmds, &arg->items, arg->sub_next + i, ech);
break;
}
continue;
}
if (ch == 0)
break;
/* Probably a single character name, ignore $$ and stupid ones. {*/
if (!arg->short_var || strchr("}):$", ch) != NULL) {
cp++;
continue;
}
STRLIST_FOREACH(var, &arg->vars, i) {
if (var[0] != ch || var[1] != 0)
continue;
/* Found a variable match. Replace with ${:U<value>} */
Buf_AddBytes(&cmds, cp - cmd_cp, cmd_cp);
Buf_AddBytes(&cmds, 3, "{:U");
cmd_cp = ++cp;
for_substitute(&cmds, &arg->items, arg->sub_next + i, /*{*/ '}');
Buf_AddBytes(&cmds, 1, "}");
break;
}
}
Buf_AddBytes(&cmds, body_end - cmd_cp, cmd_cp);
cp = Buf_Destroy(&cmds, FALSE);
if (DEBUG(FOR))
(void)fprintf(debug_file, "For: loop body:\n%s", cp);
arg->sub_next += strlist_num(&arg->vars);
arg->parse_buf = cp;
return cp;
}
void
For_Run(int lineno)
{
For *arg;
arg = accumFor;
accumFor = NULL;
if (strlist_num(&arg->items) == 0) {
/* Nothing to expand - possibly due to an earlier syntax error. */
For_Free(arg);
return;
}
Parse_SetInput(NULL, lineno, -1, For_Iterate, arg);
}

463
commands/bmake/hash.c Normal file
View File

@ -0,0 +1,463 @@
/* $NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: hash.c,v 1.19 2009/01/24 10:59:09 dsl Exp $");
#endif
#endif /* not lint */
#endif
/* hash.c --
*
* This module contains routines to manipulate a hash table.
* See hash.h for a definition of the structure of the hash
* table. Hash tables grow automatically as the amount of
* information increases.
*/
#include "sprite.h"
#include "make.h"
#include "hash.h"
/*
* Forward references to local procedures that are used before they're
* defined:
*/
static void RebuildTable(Hash_Table *);
/*
* The following defines the ratio of # entries to # buckets
* at which we rebuild the table to make it larger.
*/
#define rebuildLimit 3
/*
*---------------------------------------------------------
*
* Hash_InitTable --
*
* This routine just sets up the hash table.
*
* Input:
* t Structure to to hold table.
* numBuckets How many buckets to create for starters. This
* number is rounded up to a power of two. If
* <= 0, a reasonable default is chosen. The
* table will grow in size later as needed.
*
* Results:
* None.
*
* Side Effects:
* Memory is allocated for the initial bucket area.
*
*---------------------------------------------------------
*/
void
Hash_InitTable(Hash_Table *t, int numBuckets)
{
int i;
struct Hash_Entry **hp;
/*
* Round up the size to a power of two.
*/
if (numBuckets <= 0)
i = 16;
else {
for (i = 2; i < numBuckets; i <<= 1)
continue;
}
t->numEntries = 0;
t->size = i;
t->mask = i - 1;
t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
while (--i >= 0)
*hp++ = NULL;
}
/*
*---------------------------------------------------------
*
* Hash_DeleteTable --
*
* This routine removes everything from a hash table
* and frees up the memory space it occupied (except for
* the space in the Hash_Table structure).
*
* Results:
* None.
*
* Side Effects:
* Lots of memory is freed up.
*
*---------------------------------------------------------
*/
void
Hash_DeleteTable(Hash_Table *t)
{
struct Hash_Entry **hp, *h, *nexth = NULL;
int i;
for (hp = t->bucketPtr, i = t->size; --i >= 0;) {
for (h = *hp++; h != NULL; h = nexth) {
nexth = h->next;
free(h);
}
}
free(t->bucketPtr);
/*
* Set up the hash table to cause memory faults on any future access
* attempts until re-initialization.
*/
t->bucketPtr = NULL;
}
/*
*---------------------------------------------------------
*
* Hash_FindEntry --
*
* Searches a hash table for an entry corresponding to key.
*
* Input:
* t Hash table to search.
* key A hash key.
*
* Results:
* The return value is a pointer to the entry for key,
* if key was present in the table. If key was not
* present, NULL is returned.
*
* Side Effects:
* None.
*
*---------------------------------------------------------
*/
Hash_Entry *
Hash_FindEntry(Hash_Table *t, const char *key)
{
Hash_Entry *e;
unsigned h;
const char *p;
for (h = 0, p = key; *p;)
h = (h << 5) - h + *p++;
p = key;
for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next)
if (e->namehash == h && strcmp(e->name, p) == 0)
return (e);
return NULL;
}
/*
*---------------------------------------------------------
*
* Hash_CreateEntry --
*
* Searches a hash table for an entry corresponding to
* key. If no entry is found, then one is created.
*
* Input:
* t Hash table to search.
* key A hash key.
* newPtr Filled in with TRUE if new entry created,
* FALSE otherwise.
*
* Results:
* The return value is a pointer to the entry. If *newPtr
* isn't NULL, then *newPtr is filled in with TRUE if a
* new entry was created, and FALSE if an entry already existed
* with the given key.
*
* Side Effects:
* Memory may be allocated, and the hash buckets may be modified.
*---------------------------------------------------------
*/
Hash_Entry *
Hash_CreateEntry(Hash_Table *t, const char *key, Boolean *newPtr)
{
Hash_Entry *e;
unsigned h;
const char *p;
int keylen;
struct Hash_Entry **hp;
/*
* Hash the key. As a side effect, save the length (strlen) of the
* key in case we need to create the entry.
*/
for (h = 0, p = key; *p;)
h = (h << 5) - h + *p++;
keylen = p - key;
p = key;
for (e = t->bucketPtr[h & t->mask]; e != NULL; e = e->next) {
if (e->namehash == h && strcmp(e->name, p) == 0) {
if (newPtr != NULL)
*newPtr = FALSE;
return (e);
}
}
/*
* The desired entry isn't there. Before allocating a new entry,
* expand the table if necessary (and this changes the resulting
* bucket chain).
*/
if (t->numEntries >= rebuildLimit * t->size)
RebuildTable(t);
e = bmake_malloc(sizeof(*e) + keylen);
hp = &t->bucketPtr[h & t->mask];
e->next = *hp;
*hp = e;
Hash_SetValue(e, NULL);
e->namehash = h;
(void)strcpy(e->name, p);
t->numEntries++;
if (newPtr != NULL)
*newPtr = TRUE;
return (e);
}
/*
*---------------------------------------------------------
*
* Hash_DeleteEntry --
*
* Delete the given hash table entry and free memory associated with
* it.
*
* Results:
* None.
*
* Side Effects:
* Hash chain that entry lives in is modified and memory is freed.
*
*---------------------------------------------------------
*/
void
Hash_DeleteEntry(Hash_Table *t, Hash_Entry *e)
{
Hash_Entry **hp, *p;
if (e == NULL)
return;
for (hp = &t->bucketPtr[e->namehash & t->mask];
(p = *hp) != NULL; hp = &p->next) {
if (p == e) {
*hp = p->next;
free(p);
t->numEntries--;
return;
}
}
(void)write(2, "bad call to Hash_DeleteEntry\n", 29);
abort();
}
/*
*---------------------------------------------------------
*
* Hash_EnumFirst --
* This procedure sets things up for a complete search
* of all entries recorded in the hash table.
*
* Input:
* t Table to be searched.
* searchPtr Area in which to keep state about search.
*
* Results:
* The return value is the address of the first entry in
* the hash table, or NULL if the table is empty.
*
* Side Effects:
* The information in searchPtr is initialized so that successive
* calls to Hash_Next will return successive HashEntry's
* from the table.
*
*---------------------------------------------------------
*/
Hash_Entry *
Hash_EnumFirst(Hash_Table *t, Hash_Search *searchPtr)
{
searchPtr->tablePtr = t;
searchPtr->nextIndex = 0;
searchPtr->hashEntryPtr = NULL;
return Hash_EnumNext(searchPtr);
}
/*
*---------------------------------------------------------
*
* Hash_EnumNext --
* This procedure returns successive entries in the hash table.
*
* Input:
* searchPtr Area used to keep state about search.
*
* Results:
* The return value is a pointer to the next HashEntry
* in the table, or NULL when the end of the table is
* reached.
*
* Side Effects:
* The information in searchPtr is modified to advance to the
* next entry.
*
*---------------------------------------------------------
*/
Hash_Entry *
Hash_EnumNext(Hash_Search *searchPtr)
{
Hash_Entry *e;
Hash_Table *t = searchPtr->tablePtr;
/*
* The hashEntryPtr field points to the most recently returned
* entry, or is nil if we are starting up. If not nil, we have
* to start at the next one in the chain.
*/
e = searchPtr->hashEntryPtr;
if (e != NULL)
e = e->next;
/*
* If the chain ran out, or if we are starting up, we need to
* find the next nonempty chain.
*/
while (e == NULL) {
if (searchPtr->nextIndex >= t->size)
return NULL;
e = t->bucketPtr[searchPtr->nextIndex++];
}
searchPtr->hashEntryPtr = e;
return (e);
}
/*
*---------------------------------------------------------
*
* RebuildTable --
* This local routine makes a new hash table that
* is larger than the old one.
*
* Results:
* None.
*
* Side Effects:
* The entire hash table is moved, so any bucket numbers
* from the old table are invalid.
*
*---------------------------------------------------------
*/
static void
RebuildTable(Hash_Table *t)
{
Hash_Entry *e, *next = NULL, **hp, **xp;
int i, mask;
Hash_Entry **oldhp;
int oldsize;
oldhp = t->bucketPtr;
oldsize = i = t->size;
i <<= 1;
t->size = i;
t->mask = mask = i - 1;
t->bucketPtr = hp = bmake_malloc(sizeof(*hp) * i);
while (--i >= 0)
*hp++ = NULL;
for (hp = oldhp, i = oldsize; --i >= 0;) {
for (e = *hp++; e != NULL; e = next) {
next = e->next;
xp = &t->bucketPtr[e->namehash & mask];
e->next = *xp;
*xp = e;
}
}
free(oldhp);
}

154
commands/bmake/hash.h Normal file
View File

@ -0,0 +1,154 @@
/* $NetBSD: hash.h,v 1.10 2009/01/24 10:59:09 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)hash.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)hash.h 8.1 (Berkeley) 6/6/93
*/
/* hash.h --
*
* This file contains definitions used by the hash module,
* which maintains hash tables.
*/
#ifndef _HASH
#define _HASH
/*
* The following defines one entry in the hash table.
*/
typedef struct Hash_Entry {
struct Hash_Entry *next; /* Used to link together all the
* entries associated with the same
* bucket. */
union {
void *clientPtr; /* Arbitrary pointer */
time_t clientTime; /* Arbitrary Time */
} clientInfo;
unsigned namehash; /* hash value of key */
char name[1]; /* key string */
} Hash_Entry;
typedef struct Hash_Table {
struct Hash_Entry **bucketPtr;/* Pointers to Hash_Entry, one
* for each bucket in the table. */
int size; /* Actual size of array. */
int numEntries; /* Number of entries in the 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.
*/
typedef struct Hash_Search {
Hash_Table *tablePtr; /* Table being searched. */
int nextIndex; /* Next bucket to check (after current). */
Hash_Entry *hashEntryPtr; /* Next entry to check in current bucket. */
} Hash_Search;
/*
* Macros.
*/
/*
* void * Hash_GetValue(h)
* Hash_Entry *h;
*/
#define Hash_GetValue(h) ((h)->clientInfo.clientPtr)
#define Hash_GetTimeValue(h) ((h)->clientInfo.clientTime)
/*
* Hash_SetValue(h, val);
* Hash_Entry *h;
* char *val;
*/
#define Hash_SetValue(h, val) ((h)->clientInfo.clientPtr = (val))
#define Hash_SetTimeValue(h, val) ((h)->clientInfo.clientTime = (val))
/*
* Hash_Size(n) returns the number of words in an object of n bytes
*/
#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int))
void Hash_InitTable(Hash_Table *, int);
void Hash_DeleteTable(Hash_Table *);
Hash_Entry *Hash_FindEntry(Hash_Table *, const char *);
Hash_Entry *Hash_CreateEntry(Hash_Table *, const char *, Boolean *);
void Hash_DeleteEntry(Hash_Table *, Hash_Entry *);
Hash_Entry *Hash_EnumFirst(Hash_Table *, Hash_Search *);
Hash_Entry *Hash_EnumNext(Hash_Search *);
#endif /* _HASH */

2953
commands/bmake/job.c Normal file

File diff suppressed because it is too large Load Diff

263
commands/bmake/job.h Normal file
View File

@ -0,0 +1,263 @@
/* $NetBSD: job.h,v 1.39 2009/04/11 09:41:18 apb Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)job.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)job.h 8.1 (Berkeley) 6/6/93
*/
/*-
* job.h --
* Definitions pertaining to the running of jobs in parallel mode.
*/
#ifndef _JOB_H_
#define _JOB_H_
#define TMPPAT "makeXXXXXX" /* relative to tmpdir */
#ifdef USE_SELECT
/*
* Emulate poll() in terms of select(). This is not a complete
* emulation but it is sufficient for make's purposes.
*/
#define poll emul_poll
#define pollfd emul_pollfd
struct emul_pollfd {
int fd;
short events;
short revents;
};
#define POLLIN 0x0001
#define POLLOUT 0x0004
int
emul_poll(struct pollfd *fd, int nfd, int timeout);
#endif
/*
* The POLL_MSEC constant determines the maximum number of milliseconds spent
* in poll before coming out to see if a child has finished.
*/
#define POLL_MSEC 5000
/*-
* Job Table definitions.
*
* Each job has several things associated with it:
* 1) The process id of the child shell
* 2) The graph node describing the target being made by this job
* 3) A LstNode for the first command to be saved after the job
* completes. This is NULL if there was no "..." in the job's
* commands.
* 4) An FILE* for writing out the commands. This is only
* used before the job is actually started.
* 5) The output is being caught via a pipe and
* the descriptors of our pipe, an array in which output is line
* buffered and the current position in that buffer are all
* maintained for each job.
* 6) A word of flags which determine how the module handles errors,
* echoing, etc. for the job
*
* 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
* traversal of the dependency graph.
*/
struct pollfd;
#define JOB_BUFSIZE 1024
typedef struct Job {
int pid; /* The child's process ID */
GNode *node; /* The target the child is making */
LstNode tailCmds; /* The node of the first command to be
* saved when the job has been run */
FILE *cmdFILE; /* When creating the shell script, this is
* where the commands go */
int exit_status; /* from wait4() in signal handler */
char job_state; /* status of the job entry */
#define JOB_ST_FREE 0 /* Job is available */
#define JOB_ST_SETUP 1 /* Job is allocated but otherwise invalid */
#define JOB_ST_RUNNING 3 /* Job is running, pid valid */
#define JOB_ST_FINISHED 4 /* Job is done (ie after SIGCHILD) */
char job_suspended;
short flags; /* Flags to control treatment of job */
#define JOB_IGNERR 0x001 /* Ignore non-zero exits */
#define JOB_SILENT 0x002 /* no output */
#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally
* if we can't export it and maxLocal is 0 */
#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing
* commands */
#define JOB_TRACED 0x400 /* we've sent 'set -x' */
int jobPipe[2]; /* Pipe for readind output from job */
struct pollfd *inPollfd; /* pollfd associated with inPipe */
char outBuf[JOB_BUFSIZE + 1];
/* Buffer for storing the output of the
* job, line by line */
int curPos; /* Current position in op_outBuf */
} Job;
#define inPipe jobPipe[0]
#define outPipe jobPipe[1]
/*-
* Shell Specifications:
* Each shell type has associated with it the following information:
* 1) The string which must match the last character of the shell name
* for the shell to be considered of this type. The longest match
* wins.
* 2) A command to issue to turn off echoing of command lines
* 3) A command to issue to turn echoing back on again
* 4) What the shell prints, and its length, when given the echo-off
* command. This line will not be printed when received from the shell
* 5) A boolean to tell if the shell has the ability to control
* error checking for individual commands.
* 6) The string to turn this checking on.
* 7) The string to turn it off.
* 8) The command-flag to give to cause the shell to start echoing
* commands right away.
* 9) The command-flag to cause the shell to Lib_Exit when an error is
* detected in one of the commands.
*
* Some special stuff goes on if a shell doesn't have error control. In such
* a case, errCheck becomes a printf template for echoing the command,
* should echoing be on and ignErr becomes another printf template for
* executing the command while ignoring the return status. Finally errOut
* is a printf template for running the command and causing the shell to
* exit on error. If any of these strings are empty when hasErrCtl is FALSE,
* the command will be executed anyway as is and if it causes an error, so be
* it. Any templates setup to echo the command will escape any '$ ` \ "'i
* characters in the command string to avoid common problems with
* echo "%s\n" as a template.
*/
typedef struct Shell {
const char *name; /* the name of the shell. For Bourne and C
* shells, this is used only to find the
* shell description when used as the single
* source of a .SHELL target. For user-defined
* shells, this is the full path of the shell.
*/
Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */
const char *echoOff; /* command to turn off echo */
const char *echoOn; /* command to turn it back on again */
const char *noPrint; /* command to skip when printing output from
* shell. This is usually the command which
* was executed to turn off echoing */
int noPLen; /* length of noPrint command */
Boolean hasErrCtl; /* set if can control error checking for
* individual commands */
const char *errCheck; /* string to turn error checking on */
const char *ignErr; /* string to turn off error checking */
const char *errOut; /* string to use for testing exit code */
const char *newline; /* string literal that results in a newline
* character when it appears outside of any
* 'quote' or "quote" characters */
char commentChar; /* character used by shell for comment lines */
/*
* command-line flags
*/
const char *echo; /* echo commands */
const char *exit; /* exit on error */
} Shell;
extern const char *shellPath;
extern const char *shellName;
extern int jobTokensRunning; /* tokens currently "out" */
extern int maxJobs; /* Max jobs we can run */
void Shell_Init(void);
const char *Shell_GetNewline(void);
void Job_Touch(GNode *, Boolean);
Boolean Job_CheckCommands(GNode *, void (*abortProc )(const char *, ...));
#define CATCH_BLOCK 1
void Job_CatchChildren(void);
void Job_CatchOutput(void);
void Job_Make(GNode *);
void Job_Init(void);
Boolean Job_Full(void);
Boolean Job_Empty(void);
ReturnStatus Job_ParseShell(char *);
int Job_Finish(void);
void Job_End(void);
void Job_Wait(void);
void Job_AbortAll(void);
void JobFlagForMigration(int);
void Job_TokenReturn(void);
Boolean Job_TokenWithdraw(void);
void Job_ServerStart(int, int, int);
void Job_SetPrefix(void);
#endif /* _JOB_H_ */

189
commands/bmake/lst.h Normal file
View File

@ -0,0 +1,189 @@
/* $NetBSD: lst.h,v 1.18 2009/01/23 21:58:27 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)lst.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1988, 1989 by Adam de Boor
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)lst.h 8.1 (Berkeley) 6/6/93
*/
/*-
* lst.h --
* Header for using the list library
*/
#ifndef _LST_H_
#define _LST_H_
#include <sys/param.h>
#include <stdlib.h>
#include "sprite.h"
/*
* basic typedef. This is what the Lst_ functions handle
*/
typedef struct List *Lst;
typedef struct ListNode *LstNode;
typedef void *DuplicateProc(void *);
typedef void FreeProc(void *);
#define LST_CONCNEW 0 /* create new LstNode's when using Lst_Concat */
#define LST_CONCLINK 1 /* relink LstNode's when using Lst_Concat */
/*
* Creation/destruction functions
*/
/* Create a new list */
Lst Lst_Init(Boolean);
/* Duplicate an existing list */
Lst Lst_Duplicate(Lst, DuplicateProc *);
/* Destroy an old one */
void Lst_Destroy(Lst, FreeProc *);
/* True if list is empty */
Boolean Lst_IsEmpty(Lst);
/*
* Functions to modify a list
*/
/* Insert an element before another */
ReturnStatus Lst_InsertBefore(Lst, LstNode, void *);
/* Insert an element after another */
ReturnStatus Lst_InsertAfter(Lst, LstNode, void *);
/* Place an element at the front of a lst. */
ReturnStatus Lst_AtFront(Lst, void *);
/* Place an element at the end of a lst. */
ReturnStatus Lst_AtEnd(Lst, void *);
/* Remove an element */
ReturnStatus Lst_Remove(Lst, LstNode);
/* Replace a node with a new value */
ReturnStatus Lst_Replace(LstNode, void *);
/* Concatenate two lists */
ReturnStatus Lst_Concat(Lst, Lst, int);
/*
* Node-specific functions
*/
/* Return first element in list */
LstNode Lst_First(Lst);
/* Return last element in list */
LstNode Lst_Last(Lst);
/* Return successor to given element */
LstNode Lst_Succ(LstNode);
/* Return predecessor to given element */
LstNode Lst_Prev(LstNode);
/* Get datum from LstNode */
void *Lst_Datum(LstNode);
/*
* Functions for entire lists
*/
/* Find an element in a list */
LstNode Lst_Find(Lst, const void *, int (*)(const void *, const void *));
/* Find an element starting from somewhere */
LstNode Lst_FindFrom(Lst, LstNode, const void *,
int (*cProc)(const void *, const void *));
/*
* See if the given datum is on the list. Returns the LstNode containing
* the datum
*/
LstNode Lst_Member(Lst, void *);
/* Apply a function to all elements of a lst */
int Lst_ForEach(Lst, int (*)(void *, void *), void *);
/*
* Apply a function to all elements of a lst starting from a certain point.
* If the list is circular, the application will wrap around to the
* beginning of the list again.
*/
int Lst_ForEachFrom(Lst, LstNode, int (*)(void *, void *),
void *);
/*
* these functions are for dealing with a list as a table, of sorts.
* An idea of the "current element" is kept and used by all the functions
* between Lst_Open() and Lst_Close().
*/
/* Open the list */
ReturnStatus Lst_Open(Lst);
/* Next element please */
LstNode Lst_Next(Lst);
/* Done yet? */
Boolean Lst_IsAtEnd(Lst);
/* Finish table access */
void Lst_Close(Lst);
/*
* for using the list as a queue
*/
/* Place an element at tail of queue */
ReturnStatus Lst_EnQueue(Lst, void *);
/* Remove an element from head of queue */
void *Lst_DeQueue(Lst);
#endif /* _LST_H_ */

View File

@ -0,0 +1,10 @@
# $NetBSD: Makefile,v 1.6 2006/11/11 21:23:36 dsl 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 lstPrev.o
CPPFLAGS=-I${.CURDIR}/..
all: ${OBJ}

View File

@ -0,0 +1,122 @@
/* $NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstAppend.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstAppend.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstAppend.c --
* Add a new node with a new datum after an existing node
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_InsertAfter --
* Create a new node and add it to the given list after the given node.
*
* Input:
* l affected list
* ln node after which to append the datum
* d said datum
*
* Results:
* SUCCESS if all went well.
*
* Side Effects:
* A new ListNode is created and linked in to the List. The lastPtr
* field of the List will be altered if ln is the last node in the
* list. lastPtr and firstPtr will alter if the list was empty and
* ln was NULL.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_InsertAfter(Lst l, LstNode ln, void *d)
{
List list;
ListNode lNode;
ListNode nLNode;
if (LstValid (l) && (ln == NULL && LstIsEmpty (l))) {
goto ok;
}
if (!LstValid (l) || LstIsEmpty (l) || ! LstNodeValid (ln, l)) {
return (FAILURE);
}
ok:
list = l;
lNode = ln;
PAlloc (nLNode, ListNode);
nLNode->datum = d;
nLNode->useCount = nLNode->flags = 0;
if (lNode == NULL) {
if (list->isCirc) {
nLNode->nextPtr = nLNode->prevPtr = nLNode;
} else {
nLNode->nextPtr = nLNode->prevPtr = NULL;
}
list->firstPtr = list->lastPtr = nLNode;
} else {
nLNode->prevPtr = lNode;
nLNode->nextPtr = lNode->nextPtr;
lNode->nextPtr = nLNode;
if (nLNode->nextPtr != NULL) {
nLNode->nextPtr->prevPtr = nLNode;
}
if (lNode == list->lastPtr) {
list->lastPtr = nLNode;
}
}
return (SUCCESS);
}

View File

@ -0,0 +1,79 @@
/* $NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstAtEnd.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstAtEnd.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstAtEnd.c --
* Add a node at the end of the list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_AtEnd --
* Add a node to the end of the given list
*
* Input:
* l List to which to add the datum
* d Datum to add
*
* Results:
* SUCCESS if life is good.
*
* Side Effects:
* A new ListNode is created and added to the list.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_AtEnd(Lst l, void *d)
{
LstNode end;
end = Lst_Last(l);
return (Lst_InsertAfter(l, end, d));
}

View File

@ -0,0 +1,76 @@
/* $NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstAtFront.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstAtFront.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstAtFront.c --
* Add a node at the front of the list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_AtFront --
* Place a piece of data at the front of a list
*
* Results:
* SUCCESS or FAILURE
*
* Side Effects:
* A new ListNode is created and stuck at the front of the list.
* hence, firstPtr (and possible lastPtr) in the list are altered.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_AtFront(Lst l, void *d)
{
LstNode front;
front = Lst_First(l);
return (Lst_InsertBefore(l, front, d));
}

View File

@ -0,0 +1,86 @@
/* $NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstClose.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstClose.c,v 1.11 2006/10/27 21:37:25 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstClose.c --
* Close a list for sequential access.
* The sequential functions access the list in a slightly different way.
* CurPtr points to their idea of the current node in the list and they
* access the list based on it. Because the list is circular, Lst_Next
* and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
* used to determine when to stop.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Close --
* Close a list which was opened for sequential access.
*
* Input:
* l The list to close
*
* Results:
* None.
*
* Side Effects:
* The list is closed.
*
*-----------------------------------------------------------------------
*/
void
Lst_Close(Lst l)
{
List list = l;
if (LstValid(l) == TRUE) {
list->isOpen = FALSE;
list->atEnd = Unknown;
}
}

View File

@ -0,0 +1,185 @@
/* $NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstConcat.c,v 1.16 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* listConcat.c --
* Function to concatentate two lists.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Concat --
* Concatenate two lists. New elements are created to hold the data
* elements, if specified, but the elements themselves are not copied.
* If the elements should be duplicated to avoid confusion with another
* list, the Lst_Duplicate function should be called first.
* If LST_CONCLINK is specified, the second list is destroyed since
* its pointers have been corrupted and the list is no longer useable.
*
* Input:
* l1 The list to which l2 is to be appended
* l2 The list to append to l1
* flags LST_CONCNEW if LstNode's should be duplicated
* LST_CONCLINK if should just be relinked
*
* Results:
* SUCCESS if all went well. FAILURE otherwise.
*
* Side Effects:
* New elements are created and appended the first list.
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_Concat(Lst l1, Lst l2, int flags)
{
ListNode ln; /* original LstNode */
ListNode nln; /* new LstNode */
ListNode last; /* the last element in the list. Keeps
* bookkeeping until the end */
List list1 = l1;
List list2 = l2;
if (!LstValid (l1) || !LstValid (l2)) {
return (FAILURE);
}
if (flags == LST_CONCLINK) {
if (list2->firstPtr != NULL) {
/*
* We set the nextPtr of the
* last element of list two to be NIL to make the loop easier and
* so we don't need an extra case should the first list turn
* out to be non-circular -- the final element will already point
* to NIL space and the first element will be untouched if it
* existed before and will also point to NIL space if it didn't.
*/
list2->lastPtr->nextPtr = NULL;
/*
* So long as the second list isn't empty, we just link the
* first element of the second list to the last element of the
* first list. If the first list isn't empty, we then link the
* last element of the list to the first element of the second list
* The last element of the second list, if it exists, then becomes
* the last element of the first list.
*/
list2->firstPtr->prevPtr = list1->lastPtr;
if (list1->lastPtr != NULL) {
list1->lastPtr->nextPtr = list2->firstPtr;
} else {
list1->firstPtr = list2->firstPtr;
}
list1->lastPtr = list2->lastPtr;
}
if (list1->isCirc && list1->firstPtr != NULL) {
/*
* If the first list is supposed to be circular and it is (now)
* non-empty, we must make sure it's circular by linking the
* first element to the last and vice versa
*/
list1->firstPtr->prevPtr = list1->lastPtr;
list1->lastPtr->nextPtr = list1->firstPtr;
}
free(l2);
} else if (list2->firstPtr != NULL) {
/*
* We set the nextPtr of the last element of list 2 to be nil to make
* the loop less difficult. The loop simply goes through the entire
* second list creating new LstNodes and filling in the nextPtr, and
* prevPtr to fit into l1 and its datum field from the
* datum field of the corresponding element in l2. The 'last' node
* follows the last of the new nodes along until the entire l2 has
* been appended. Only then does the bookkeeping catch up with the
* changes. During the first iteration of the loop, if 'last' is nil,
* the first list must have been empty so the newly-created node is
* made the first node of the list.
*/
list2->lastPtr->nextPtr = NULL;
for (last = list1->lastPtr, ln = list2->firstPtr;
ln != NULL;
ln = ln->nextPtr)
{
PAlloc (nln, ListNode);
nln->datum = ln->datum;
if (last != NULL) {
last->nextPtr = nln;
} else {
list1->firstPtr = nln;
}
nln->prevPtr = last;
nln->flags = nln->useCount = 0;
last = nln;
}
/*
* Finish bookkeeping. The last new element becomes the last element
* of list one.
*/
list1->lastPtr = last;
/*
* The circularity of both list one and list two must be corrected
* for -- list one because of the new nodes added to it; list two
* because of the alteration of list2->lastPtr's nextPtr to ease the
* above for loop.
*/
if (list1->isCirc) {
list1->lastPtr->nextPtr = list1->firstPtr;
list1->firstPtr->prevPtr = list1->lastPtr;
} else {
last->nextPtr = NULL;
}
if (list2->isCirc) {
list2->lastPtr->nextPtr = list2->firstPtr;
}
}
return (SUCCESS);
}

View File

@ -0,0 +1,77 @@
/* $NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstDatum.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstDatum.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstDatum.c --
* Return the datum associated with a list node.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Datum --
* Return the datum stored in the given node.
*
* Results:
* The datum or NULL if the node is invalid.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
void *
Lst_Datum(LstNode ln)
{
if (ln != NULL) {
return ((ln)->datum);
} else {
return NULL;
}
}

View File

@ -0,0 +1,87 @@
/* $NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstDeQueue.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstDeQueue.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstDeQueue.c --
* Remove the node and return its datum from the head of the list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_DeQueue --
* Remove and return the datum at the head of the given list.
*
* Results:
* The datum in the node at the head or NULL if the list
* is empty.
*
* Side Effects:
* The head node is removed from the list.
*
*-----------------------------------------------------------------------
*/
void *
Lst_DeQueue(Lst l)
{
void *rd;
ListNode tln;
tln = Lst_First(l);
if (tln == NULL) {
return NULL;
}
rd = tln->datum;
if (Lst_Remove(l, tln) == FAILURE) {
return NULL;
} else {
return (rd);
}
}

View File

@ -0,0 +1,101 @@
/* $NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstDestroy.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstDestroy.c,v 1.16 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstDestroy.c --
* Nuke a list and all its resources
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Destroy --
* Destroy a list and free all its resources. If the freeProc is
* given, it is called with the datum from each node in turn before
* the node is freed.
*
* Results:
* None.
*
* Side Effects:
* The given list is freed in its entirety.
*
*-----------------------------------------------------------------------
*/
void
Lst_Destroy(Lst list, FreeProc *freeProc)
{
ListNode ln;
ListNode tln = NULL;
if (list == NULL)
return;
/* To ease scanning */
if (list->lastPtr != NULL)
list->lastPtr->nextPtr = NULL;
else {
free(list);
return;
}
if (freeProc) {
for (ln = list->firstPtr; ln != NULL; ln = tln) {
tln = ln->nextPtr;
freeProc(ln->datum);
free(ln);
}
} else {
for (ln = list->firstPtr; ln != NULL; ln = tln) {
tln = ln->nextPtr;
free(ln);
}
}
free(list);
}

View File

@ -0,0 +1,107 @@
/* $NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstDupl.c,v 1.16 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* listDupl.c --
* Duplicate a list. This includes duplicating the individual
* elements.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Duplicate --
* Duplicate an entire list. If a function to copy a void *is
* given, the individual client elements will be duplicated as well.
*
* Input:
* l the list to duplicate
* copyProc A function to duplicate each void *
*
* Results:
* The new Lst structure or NULL if failure.
*
* Side Effects:
* A new list is created.
*-----------------------------------------------------------------------
*/
Lst
Lst_Duplicate(Lst l, DuplicateProc *copyProc)
{
Lst nl;
ListNode ln;
List list = l;
if (!LstValid (l)) {
return NULL;
}
nl = Lst_Init(list->isCirc);
if (nl == NULL) {
return NULL;
}
ln = list->firstPtr;
while (ln != NULL) {
if (copyProc != NULL) {
if (Lst_AtEnd(nl, copyProc(ln->datum)) == FAILURE) {
return NULL;
}
} else if (Lst_AtEnd(nl, ln->datum) == FAILURE) {
return NULL;
}
if (list->isCirc && ln == list->lastPtr) {
ln = NULL;
} else {
ln = ln->nextPtr;
}
}
return (nl);
}

View File

@ -0,0 +1,78 @@
/* $NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstEnQueue.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstEnQueue.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstEnQueue.c--
* Treat the list as a queue and place a datum at its end
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_EnQueue --
* Add the datum to the tail of the given list.
*
* Results:
* SUCCESS or FAILURE as returned by Lst_InsertAfter.
*
* Side Effects:
* the lastPtr field is altered all the time and the firstPtr field
* will be altered if the list used to be empty.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_EnQueue(Lst l, void *d)
{
if (LstValid (l) == FALSE) {
return (FAILURE);
}
return (Lst_InsertAfter(l, Lst_Last(l), d));
}

View File

@ -0,0 +1,74 @@
/* $NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstFind.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstFind.c,v 1.15 2009/01/23 21:58:28 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstFind.c --
* Find a node on a list.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Find --
* Find a node on the given list using the given comparison function
* and the given datum.
*
* Results:
* The found node or NULL if none matches.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Find(Lst l, const void *d, int (*cProc)(const void *, const void *))
{
return (Lst_FindFrom(l, Lst_First(l), d, cProc));
}

View File

@ -0,0 +1,90 @@
/* $NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstFindFrom.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstFindFrom.c,v 1.15 2009/01/23 21:58:28 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstFindFrom.c --
* Find a node on a list from a given starting point. Used by Lst_Find.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_FindFrom --
* Search for a node starting and ending with the given one on the
* given list using the passed datum and comparison function to
* determine when it has been found.
*
* Results:
* The found node or NULL
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_FindFrom(Lst l, LstNode ln, const void *d,
int (*cProc)(const void *, const void *))
{
ListNode tln;
if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) {
return NULL;
}
tln = ln;
do {
if ((*cProc)(tln->datum, d) == 0)
return (tln);
tln = tln->nextPtr;
} while (tln != ln && tln != NULL);
return NULL;
}

View File

@ -0,0 +1,77 @@
/* $NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstFirst.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstFirst.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstFirst.c --
* Return the first node of a list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_First --
* Return the first node on the given list.
*
* Results:
* The first node or NULL if the list is empty.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_First(Lst l)
{
if (!LstValid (l) || LstIsEmpty (l)) {
return NULL;
} else {
return (l->firstPtr);
}
}

View File

@ -0,0 +1,76 @@
/* $NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstForEach.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstForeach.c --
* Perform a given function on all elements of a list.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_ForEach --
* Apply the given function to each element of the given list. The
* function should return 0 if Lst_ForEach should continue and non-
* zero if it should abort.
*
* Results:
* None.
*
* Side Effects:
* Only those created by the passed-in function.
*
*-----------------------------------------------------------------------
*/
/*VARARGS2*/
int
Lst_ForEach(Lst l, int (*proc)(void *, void *), void *d)
{
return Lst_ForEachFrom(l, Lst_First(l), proc, d);
}

View File

@ -0,0 +1,125 @@
/* $NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstForEachFrom.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstForEachFrom.c,v 1.17 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* lstForEachFrom.c --
* Perform a given function on all elements of a list starting from
* a given point.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* 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.
*
* Results:
* None.
*
* Side Effects:
* Only those created by the passed-in function.
*
*-----------------------------------------------------------------------
*/
/*VARARGS2*/
int
Lst_ForEachFrom(Lst l, LstNode ln, int (*proc)(void *, void *),
void *d)
{
ListNode tln = ln;
List list = l;
ListNode next;
Boolean done;
int result;
if (!LstValid (list) || LstIsEmpty (list)) {
return 0;
}
do {
/*
* Take care of having the current element deleted out from under
* us.
*/
next = tln->nextPtr;
/*
* We're done with the traversal if
* - the next node to examine is the first in the queue or
* doesn't exist and
* - nothing's been added after the current node (check this
* after proc() has been called).
*/
done = (next == NULL || next == list->firstPtr);
(void) tln->useCount++;
result = (*proc) (tln->datum, d);
(void) tln->useCount--;
/*
* Now check whether a node has been added.
* Note: this doesn't work if this node was deleted before
* the new node was added.
*/
if (next != tln->nextPtr) {
next = tln->nextPtr;
done = 0;
}
if (tln->flags & LN_DELETED) {
free((char *)tln);
}
tln = next;
} while (!result && !LstIsEmpty(list) && !done);
return result;
}

View File

@ -0,0 +1,85 @@
/* $NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstInit.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstInit.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* init.c --
* Initialize a new linked list.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Init --
* Create and initialize a new list.
*
* Input:
* circ TRUE if the list should be made circular
*
* Results:
* The created list.
*
* Side Effects:
* A list is created, what else?
*
*-----------------------------------------------------------------------
*/
Lst
Lst_Init(Boolean circ)
{
List nList;
PAlloc (nList, List);
nList->firstPtr = NULL;
nList->lastPtr = NULL;
nList->isOpen = FALSE;
nList->isCirc = circ;
nList->atEnd = Unknown;
return (nList);
}

View File

@ -0,0 +1,122 @@
/* $NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstInsert.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstInsert.c,v 1.14 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstInsert.c --
* Insert a new datum before an old one
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_InsertBefore --
* Insert a new node with the given piece of data before the given
* node in the given list.
*
* Input:
* l list to manipulate
* ln node before which to insert d
* d datum to be inserted
*
* Results:
* SUCCESS or FAILURE.
*
* Side Effects:
* the firstPtr field will be changed if ln is the first node in the
* list.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_InsertBefore(Lst l, LstNode ln, void *d)
{
ListNode nLNode; /* new lnode for d */
ListNode lNode = ln;
List list = l;
/*
* check validity of arguments
*/
if (LstValid (l) && (LstIsEmpty (l) && ln == NULL))
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 == NULL) {
if (list->isCirc) {
nLNode->prevPtr = nLNode->nextPtr = nLNode;
} else {
nLNode->prevPtr = nLNode->nextPtr = NULL;
}
list->firstPtr = list->lastPtr = nLNode;
} else {
nLNode->prevPtr = lNode->prevPtr;
nLNode->nextPtr = lNode;
if (nLNode->prevPtr != NULL) {
nLNode->prevPtr->nextPtr = nLNode;
}
lNode->prevPtr = nLNode;
if (lNode == list->firstPtr) {
list->firstPtr = nLNode;
}
}
return (SUCCESS);
}

View File

@ -0,0 +1,105 @@
/* $NetBSD: lstInt.h,v 1.20 2009/01/24 14:43:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)lstInt.h 8.1 (Berkeley) 6/6/93
*/
/*-
* lstInt.h --
* Internals for the list library
*/
#ifndef _LSTINT_H_
#define _LSTINT_H_
#include "../lst.h"
#include "../make_malloc.h"
typedef struct ListNode {
struct ListNode *prevPtr; /* previous element in list */
struct ListNode *nextPtr; /* next in list */
unsigned int useCount:8, /* Count of functions using the node.
* node may not be deleted until count
* goes to 0 */
flags:8; /* Node status flags */
void *datum; /* datum associated with this element */
} *ListNode;
/*
* Flags required for synchronization
*/
#define LN_DELETED 0x0001 /* List node should be removed when done */
typedef enum {
Head, Middle, Tail, Unknown
} Where;
typedef struct List {
ListNode firstPtr; /* first node in list */
ListNode lastPtr; /* last node in list */
Boolean isCirc; /* true if the list should be considered
* circular */
/*
* fields for sequential access
*/
Where atEnd; /* Where in the list the last access was */
Boolean isOpen; /* true if list has been Lst_Open'ed */
ListNode curPtr; /* current node, if open. NULL if
* *just* opened */
ListNode prevPtr; /* Previous node, if open. Used by
* Lst_Remove */
} *List;
/*
* PAlloc (var, ptype) --
* Allocate a pointer-typedef structure 'ptype' into the variable 'var'
*/
#define PAlloc(var,ptype) var = (ptype) bmake_malloc(sizeof *(var))
/*
* LstValid (l) --
* Return TRUE if the list l is valid
*/
#define LstValid(l) ((Lst)(l) != NULL)
/*
* LstNodeValid (ln, l) --
* Return TRUE if the LstNode ln is valid with respect to l
*/
#define LstNodeValid(ln, l) ((ln) != NULL)
/*
* LstIsEmpty (l) --
* TRUE if the list l is empty.
*/
#define LstIsEmpty(l) (((List)(l))->firstPtr == NULL)
#endif /* _LSTINT_H_ */

View File

@ -0,0 +1,87 @@
/* $NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstIsAtEnd.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstIsAtEnd.c,v 1.13 2008/02/15 21:29:50 christos Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstIsAtEnd.c --
* Tell if the current node is at the end of the list.
* The sequential functions access the list in a slightly different way.
* CurPtr points to their idea of the current node in the list and they
* access the list based on it. Because the list is circular, Lst_Next
* and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
* used to determine when to stop.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_IsAtEnd --
* Return true if have reached the end of the given list.
*
* Results:
* TRUE if at the end of the list (this includes the list not being
* open or being invalid) or FALSE if not. We return TRUE if the list
* is invalid or unopend so as to cause the caller to exit its loop
* asap, the assumption being that the loop is of the form
* while (!Lst_IsAtEnd (l)) {
* ...
* }
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
Boolean
Lst_IsAtEnd(Lst l)
{
List list = l;
return (!LstValid (l) || !list->isOpen ||
(list->atEnd == Head) || (list->atEnd == Tail));
}

View File

@ -0,0 +1,75 @@
/* $NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstIsEmpty.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstIsEmpty.c,v 1.11 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstIsEmpty.c --
* A single function to decide if a list is empty
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_IsEmpty --
* Return TRUE if the given list is empty.
*
* Results:
* TRUE if the list is empty, FALSE otherwise.
*
* Side Effects:
* None.
*
* A list is considered empty if its firstPtr == NULL (or if
* the list itself is NULL).
*-----------------------------------------------------------------------
*/
Boolean
Lst_IsEmpty(Lst l)
{
return ( ! LstValid (l) || LstIsEmpty(l));
}

View File

@ -0,0 +1,77 @@
/* $NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstLast.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstLast.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstLast.c --
* Return the last element of a list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Last --
* Return the last node on the list l.
*
* Results:
* The requested node or NULL if the list is empty.
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Last(Lst l)
{
if (!LstValid(l) || LstIsEmpty (l)) {
return NULL;
} else {
return (l->lastPtr);
}
}

View File

@ -0,0 +1,74 @@
/* $NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstMember.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* lstMember.c --
* See if a given datum is on a given list.
*/
#include "lstInt.h"
LstNode
Lst_Member(Lst l, void *d)
{
List list = l;
ListNode lNode;
lNode = list->firstPtr;
if (lNode == NULL) {
return NULL;
}
do {
if (lNode->datum == d) {
return lNode;
}
lNode = lNode->nextPtr;
} while (lNode != NULL && lNode != list->firstPtr);
return NULL;
}

View File

@ -0,0 +1,120 @@
/* $NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstNext.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstNext.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstNext.c --
* Return the next node for a list.
* The sequential functions access the list in a slightly different way.
* CurPtr points to their idea of the current node in the list and they
* access the list based on it. Because the list is circular, Lst_Next
* and Lst_Prev will go around the list forever. Lst_IsAtEnd must be
* used to determine when to stop.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Next --
* Return the next node for the given list.
*
* Results:
* The next node or NULL if the list has yet to be opened. Also
* if the list is non-circular and the end has been reached, NULL
* is returned.
*
* Side Effects:
* the curPtr field is updated.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Next(Lst l)
{
ListNode tln;
List list = l;
if ((LstValid (l) == FALSE) ||
(list->isOpen == FALSE)) {
return NULL;
}
list->prevPtr = list->curPtr;
if (list->curPtr == NULL) {
if (list->atEnd == Unknown) {
/*
* If we're just starting out, atEnd will be Unknown.
* Then we want to start this thing off in the right
* direction -- at the start with atEnd being Middle.
*/
list->curPtr = tln = list->firstPtr;
list->atEnd = Middle;
} else {
tln = NULL;
list->atEnd = Tail;
}
} else {
tln = list->curPtr->nextPtr;
list->curPtr = tln;
if (tln == list->firstPtr || tln == NULL) {
/*
* If back at the front, then we've hit the end...
*/
list->atEnd = Tail;
} else {
/*
* Reset to Middle if gone past first.
*/
list->atEnd = Middle;
}
}
return (tln);
}

View File

@ -0,0 +1,87 @@
/* $NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstOpen.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstOpen.c,v 1.12 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstOpen.c --
* Open a list for sequential access. The sequential functions access the
* list in a slightly different way. CurPtr points to their idea of the
* current node in the list and they access the list based on it.
* If the list is circular, Lst_Next and Lst_Prev will go around
* the list forever. Lst_IsAtEnd must be used to determine when to stop.
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Open --
* Open a list for sequential access. A list can still be searched,
* etc., without confusing these functions.
*
* Results:
* SUCCESS or FAILURE.
*
* Side Effects:
* isOpen is set TRUE and curPtr is set to NULL so the
* other sequential functions no it was just opened and can choose
* the first element accessed based on this.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_Open(Lst l)
{
if (LstValid (l) == FALSE) {
return (FAILURE);
}
(l)->isOpen = TRUE;
(l)->atEnd = LstIsEmpty (l) ? Head : Unknown;
(l)->curPtr = NULL;
return (SUCCESS);
}

View File

@ -0,0 +1,79 @@
/* $NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstPrev.c,v 1.3 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstPrev.c --
* return the predecessor to a given node
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Prev --
* Return the predecessor to the given node on its list.
*
* Results:
* The predecessor of the node, if it exists (note that on a circular
* list, if the node is the only one in the list, it is its own
* predecessor).
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Prev(LstNode ln)
{
if (ln == NULL) {
return NULL;
} else {
return (ln->prevPtr);
}
}

View File

@ -0,0 +1,136 @@
/* $NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstRemove.c,v 1.14 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstRemove.c --
* Remove an element from a list
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Remove --
* Remove the given node from the given list.
*
* Results:
* SUCCESS or FAILURE.
*
* Side Effects:
* The list's firstPtr will be set to NULL if ln is the last
* node on the list. firsPtr and lastPtr will be altered if ln is
* either the first or last node, respectively, on the list.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_Remove(Lst l, LstNode ln)
{
List list = l;
ListNode lNode = ln;
if (!LstValid (l) ||
!LstNodeValid (ln, l)) {
return (FAILURE);
}
/*
* unlink it from the list
*/
if (lNode->nextPtr != NULL) {
lNode->nextPtr->prevPtr = lNode->prevPtr;
}
if (lNode->prevPtr != NULL) {
lNode->prevPtr->nextPtr = lNode->nextPtr;
}
/*
* if either the firstPtr or lastPtr of the list point to this node,
* adjust them accordingly
*/
if (list->firstPtr == lNode) {
list->firstPtr = lNode->nextPtr;
}
if (list->lastPtr == lNode) {
list->lastPtr = lNode->prevPtr;
}
/*
* Sequential access stuff. If the node we're removing is the current
* node in the list, reset the current node to the previous one. If the
* previous one was non-existent (prevPtr == NULL), we set the
* end to be Unknown, since it is.
*/
if (list->isOpen && (list->curPtr == lNode)) {
list->curPtr = list->prevPtr;
if (list->curPtr == NULL) {
list->atEnd = Unknown;
}
}
/*
* the only way firstPtr can still point to ln is if ln is the last
* node on the list (the list is circular, so lNode->nextptr == lNode in
* this case). The list is, therefore, empty and is marked as such
*/
if (list->firstPtr == lNode) {
list->firstPtr = NULL;
}
/*
* note that the datum is unmolested. The caller must free it as
* necessary and as expected.
*/
if (lNode->useCount == 0) {
free(ln);
} else {
lNode->flags |= LN_DELETED;
}
return (SUCCESS);
}

View File

@ -0,0 +1,78 @@
/* $NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstReplace.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstReplace.c,v 1.13 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstReplace.c --
* Replace the datum in a node with a new datum
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Replace --
* Replace the datum in the given node with the new datum
*
* Results:
* SUCCESS or FAILURE.
*
* Side Effects:
* The datum field fo the node is altered.
*
*-----------------------------------------------------------------------
*/
ReturnStatus
Lst_Replace(LstNode ln, void *d)
{
if (ln == NULL) {
return (FAILURE);
} else {
(ln)->datum = d;
return (SUCCESS);
}
}

View File

@ -0,0 +1,79 @@
/* $NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: lstSucc.c,v 1.13 2008/12/13 15:19:29 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* LstSucc.c --
* return the successor to a given node
*/
#include "lstInt.h"
/*-
*-----------------------------------------------------------------------
* Lst_Succ --
* Return the successor to the given node on its list.
*
* Results:
* The successor of the node, if it exists (note that on a circular
* list, if the node is the only one in the list, it is its own
* successor).
*
* Side Effects:
* None.
*
*-----------------------------------------------------------------------
*/
LstNode
Lst_Succ(LstNode ln)
{
if (ln == NULL) {
return NULL;
} else {
return (ln->nextPtr);
}
}

1859
commands/bmake/main.c Normal file

File diff suppressed because it is too large Load Diff

1846
commands/bmake/make.1 Normal file

File diff suppressed because it is too large Load Diff

1550
commands/bmake/make.c Normal file

File diff suppressed because it is too large Load Diff

467
commands/bmake/make.h Normal file
View File

@ -0,0 +1,467 @@
/* $NetBSD: make.h,v 1.79 2009/09/08 17:29:20 sjg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)make.h 8.3 (Berkeley) 6/13/95
*/
/*
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)make.h 8.3 (Berkeley) 6/13/95
*/
/*-
* make.h --
* The global definitions for pmake
*/
#ifndef _MAKE_H_
#define _MAKE_H_
#include <sys/types.h>
#include <sys/param.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef BSD4_4
# include <sys/cdefs.h>
#endif
#if !defined(__GNUC_PREREQ__)
#if defined(__GNUC__)
#define __GNUC_PREREQ__(x, y) \
((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
(__GNUC__ > (x)))
#else /* defined(__GNUC__) */
#define __GNUC_PREREQ__(x, y) 0
#endif /* defined(__GNUC__) */
#endif /* !defined(__GNUC_PREREQ__) */
#if !defined(__unused)
#if __GNUC_PREREQ__(2, 7)
#define __unused __attribute__((__unused__))
#else
#define __unused /* delete */
#endif
#endif
#include "sprite.h"
#include "lst.h"
#include "hash.h"
#include "config.h"
#include "buf.h"
#include "make_malloc.h"
/*-
* The structure for an individual graph node. Each node has several
* pieces of data associated with it.
* 1) the name of the target it describes
* 2) the location of the target file in the file system.
* 3) the type of operator used to define its sources (qv. parse.c)
* 4) whether it is involved in this invocation of make
* 5) whether the target has been remade
* 6) whether any of its children has been remade
* 7) the number of its children that are, as yet, unmade
* 8) its modification time
* 9) the modification time of its youngest child (qv. make.c)
* 10) a list of nodes for which this is a source (parents)
* 11) a list of nodes on which this depends (children)
* 12) a list of nodes that depend on this, as gleaned from the
* transformation rules (iParents)
* 13) a list of ancestor nodes, which includes parents, iParents,
* and recursive parents of parents
* 14) a list of nodes of the same name created by the :: operator
* 15) a list of nodes that must be made (if they're made) before
* this node can be, but that do not enter into the datedness of
* this node.
* 16) a list of nodes that must be made (if they're made) before
* this node or any child of this node can be, but that do not
* enter into the datedness of this node.
* 17) a list of nodes that must be made (if they're made) after
* this node is, but that do not depend on this node, in the
* normal sense.
* 18) a Lst of ``local'' variables that are specific to this target
* and this target only (qv. var.c [$@ $< $?, etc.])
* 19) a Lst of strings that are commands to be given to a shell
* to create this target.
*/
typedef struct GNode {
char *name; /* The target's name */
char *uname; /* The unexpanded name of a .USE node */
char *path; /* The full pathname of the file */
int type; /* Its type (see the OP flags, below) */
int flags;
#define REMAKE 0x1 /* this target needs to be (re)made */
#define CHILDMADE 0x2 /* children of this target were made */
#define FORCE 0x4 /* children don't exist, and we pretend made */
#define DONE_WAIT 0x8 /* Set by Make_ProcessWait() */
#define DONE_ORDER 0x10 /* Build requested by .ORDER processing */
#define FROM_DEPEND 0x20 /* Node created from .depend */
#define CYCLE 0x1000 /* Used by MakePrintStatus */
#define DONECYCLE 0x2000 /* Used by MakePrintStatus */
enum enum_made {
UNMADE, DEFERRED, REQUESTED, BEINGMADE,
MADE, UPTODATE, ERROR, ABORTED
} made; /* Set to reflect the state of processing
* on this node:
* UNMADE - Not examined yet
* DEFERRED - Examined once (building child)
* REQUESTED - on toBeMade list
* BEINGMADE - Target is already being made.
* Indicates a cycle in the graph.
* MADE - Was out-of-date and has been made
* UPTODATE - Was already up-to-date
* ERROR - An error occurred while it was being
* made (used only in compat mode)
* ABORTED - The target was aborted due to
* an error making an inferior (compat).
*/
int unmade; /* The number of unmade children */
time_t mtime; /* Its modification time */
time_t cmtime; /* The modification time of its youngest
* child */
Lst iParents; /* Links to parents for which this is an
* implied source, if any */
Lst cohorts; /* Other nodes for the :: operator */
Lst parents; /* Nodes that depend on this one */
Lst children; /* Nodes on which this one depends */
Lst order_pred; /* .ORDER nodes we need made */
Lst order_succ; /* .ORDER nodes who need us */
char cohort_num[8]; /* #n for this cohort */
int unmade_cohorts;/* # of unmade instances on the
cohorts list */
struct GNode *centurion; /* Pointer to the first instance of a ::
node; only set when on a cohorts list */
unsigned int checked; /* Last time we tried to makle this node */
Hash_Table context; /* The local variables */
Lst commands; /* Creation commands */
struct _Suff *suffix; /* Suffix for the node (determined by
* Suff_FindDeps and opaque to everyone
* but the Suff module) */
const char *fname; /* filename where the GNode got defined */
int lineno; /* line number where the GNode got defined */
} GNode;
/*
* The OP_ constants are used when parsing a dependency line as a way of
* communicating to other parts of the program the way in which a target
* should be made. These constants are bitwise-OR'ed together and
* 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...
*/
#define OP_DEPENDS 0x00000001 /* Execution of commands depends on
* kids (:) */
#define OP_FORCE 0x00000002 /* Always execute commands (!) */
#define OP_DOUBLEDEP 0x00000004 /* Execution of commands depends on kids
* per line (::) */
#define OP_OPMASK (OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP)
#define OP_OPTIONAL 0x00000008 /* Don't care if the target doesn't
* exist and can't be created */
#define OP_USE 0x00000010 /* Use associated commands for parents */
#define OP_EXEC 0x00000020 /* Target is never out of date, but always
* execute commands anyway. Its time
* doesn't matter, so it has none...sort
* of */
#define OP_IGNORE 0x00000040 /* Ignore errors when creating the node */
#define OP_PRECIOUS 0x00000080 /* Don't remove the target when
* interrupted */
#define OP_SILENT 0x00000100 /* Don't echo commands when executed */
#define OP_MAKE 0x00000200 /* Target is a recursive make so its
* commands should always be executed when
* it is out of date, regardless of the
* state of the -n or -t flags */
#define OP_JOIN 0x00000400 /* Target is out-of-date only if any of its
* children was out-of-date */
#define OP_MADE 0x00000800 /* Assume the children of the node have
* been already made */
#define OP_SPECIAL 0x00001000 /* Special .BEGIN, .END, .INTERRUPT */
#define OP_USEBEFORE 0x00002000 /* Like .USE, only prepend commands */
#define OP_INVISIBLE 0x00004000 /* The node is invisible to its parents.
* I.e. it doesn't show up in the parents's
* local variables. */
#define OP_NOTMAIN 0x00008000 /* The node is exempt from normal 'main
* target' processing in parse.c */
#define OP_PHONY 0x00010000 /* Not a file target; run always */
#define OP_NOPATH 0x00020000 /* Don't search for file in the path */
#define OP_WAIT 0x00040000 /* .WAIT phony node */
/* Attributes applied by PMake */
#define OP_TRANSFORM 0x80000000 /* The node is a transformation rule */
#define OP_MEMBER 0x40000000 /* Target is a member of an archive */
#define OP_LIB 0x20000000 /* Target is a library */
#define OP_ARCHV 0x10000000 /* Target is an archive construct */
#define OP_HAS_COMMANDS 0x08000000 /* Target has all the commands it should.
* Used when parsing to catch multiple
* commands for a target */
#define OP_SAVE_CMDS 0x04000000 /* Saving commands on .END (Compat) */
#define OP_DEPS_FOUND 0x02000000 /* Already processed by Suff_FindDeps */
#define OP_MARK 0x01000000 /* Node found while expanding .ALLSRC */
#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute)
/*
* OP_NOP will return TRUE if the node with the given type was not the
* object of a dependency operator
*/
#define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000)
#define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)
/*
* The TARG_ constants are used when calling the Targ_FindNode and
* Targ_FindList functions in targ.c. They simply tell the functions what to
* 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 NULL pointer will be returned.
*/
#define TARG_NOCREATE 0x00 /* don't create it */
#define TARG_CREATE 0x01 /* create node if not found */
#define TARG_NOHASH 0x02 /* don't look in/add to hash table */
/*
* These constants are all used by the Str_Concat function to decide how the
* final string should look. If STR_ADDSPACE is given, a space will be
* placed between the two strings. If STR_ADDSLASH is given, a '/' will
* 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.
*/
#define STR_ADDSPACE 0x01 /* add a space when Str_Concat'ing */
#define STR_ADDSLASH 0x02 /* add a slash when Str_Concat'ing */
/*
* Error levels for parsing. PARSE_FATAL means the process cannot continue
* once the makefile has been parsed. PARSE_WARNING means it can. Passed
* as the first argument to Parse_Error.
*/
#define PARSE_WARNING 2
#define PARSE_FATAL 1
/*
* Values returned by Cond_Eval.
*/
#define COND_PARSE 0 /* Parse the next lines */
#define COND_SKIP 1 /* Skip the next lines */
#define COND_INVALID 2 /* Not a conditional statement */
/*
* Definitions for the "local" variables. Used only for clarity.
*/
#define TARGET "@" /* Target of dependency */
#define OODATE "?" /* All out-of-date sources */
#define ALLSRC ">" /* All sources */
#define IMPSRC "<" /* Source implied by transformation */
#define PREFIX "*" /* Common prefix */
#define ARCHIVE "!" /* Archive in "archive(member)" syntax */
#define MEMBER "%" /* Member in "archive(member)" syntax */
#define FTARGET "@F" /* file part of TARGET */
#define DTARGET "@D" /* directory part of TARGET */
#define FIMPSRC "<F" /* file part of IMPSRC */
#define DIMPSRC "<D" /* directory part of IMPSRC */
#define FPREFIX "*F" /* file part of PREFIX */
#define DPREFIX "*D" /* directory part of PREFIX */
/*
* Global Variables
*/
extern Lst create; /* The list of target names specified on the
* command line. used to resolve #if
* make(...) statements */
extern Lst dirSearchPath; /* The list of directories to search when
* looking for targets */
extern Boolean compatMake; /* True if we are make compatible */
extern Boolean ignoreErrors; /* True if should ignore all errors */
extern Boolean beSilent; /* True if should print no commands */
extern Boolean noExecute; /* True if should execute nothing */
extern Boolean noRecursiveExecute; /* True if should execute nothing */
extern Boolean allPrecious; /* True if every target is precious */
extern Boolean keepgoing; /* True if should continue on unaffected
* portions of the graph when have an error
* in one portion */
extern Boolean touchFlag; /* TRUE if targets should just be 'touched'
* if out of date. Set by the -t flag */
extern Boolean queryFlag; /* TRUE if we aren't supposed to really make
* anything, just see if the targets are out-
* of-date */
extern Boolean doing_depend; /* TRUE if processing .depend */
extern Boolean checkEnvFirst; /* TRUE if environment should be searched for
* variables before the global context */
extern Boolean jobServer; /* a jobServer already exists */
extern Boolean parseWarnFatal; /* TRUE if makefile parsing warnings are
* treated as errors */
extern Boolean varNoExportEnv; /* TRUE if we should not export variables
* set on the command line to the env. */
extern GNode *DEFAULT; /* .DEFAULT rule */
extern GNode *VAR_GLOBAL; /* Variables defined in a global context, e.g
* in the Makefile itself */
extern GNode *VAR_CMD; /* Variables defined on the command line */
extern GNode *VAR_FOR; /* Iteration variables */
extern char var_Error[]; /* Value returned by Var_Parse when an error
* is encountered. It actually points to
* an empty string, so naive callers needn't
* worry about it. */
extern time_t now; /* The time at the start of this whole
* process */
extern Boolean oldVars; /* Do old-style variable substitution */
extern Lst sysIncPath; /* The system include path. */
extern Lst defIncPath; /* The default include path. */
extern char *progname; /* The program name */
#define MAKEFLAGS ".MAKEFLAGS"
#define MAKEOVERRIDES ".MAKEOVERRIDES"
#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX" /* prefix for job target output */
#define MAKE_EXPORTED ".MAKE.EXPORTED" /* variables we export */
#define MAKE_MAKEFILES ".MAKE.MAKEFILES" /* all the makefiles we read */
#define MAKE_LEVEL ".MAKE.LEVEL" /* recursion level */
/*
* debug control:
* There is one bit per module. It is up to the module what debug
* information to print.
*/
FILE *debug_file; /* Output written here - default stdout */
extern int debug;
#define DEBUG_ARCH 0x00001
#define DEBUG_COND 0x00002
#define DEBUG_DIR 0x00004
#define DEBUG_GRAPH1 0x00008
#define DEBUG_GRAPH2 0x00010
#define DEBUG_JOB 0x00020
#define DEBUG_MAKE 0x00040
#define DEBUG_SUFF 0x00080
#define DEBUG_TARG 0x00100
#define DEBUG_VAR 0x00200
#define DEBUG_FOR 0x00400
#define DEBUG_SHELL 0x00800
#define DEBUG_ERROR 0x01000
#define DEBUG_LOUD 0x02000
#define DEBUG_GRAPH3 0x10000
#define DEBUG_SCRIPT 0x20000
#define DEBUG_PARSE 0x40000
#define DEBUG_CWD 0x80000
#define CONCAT(a,b) a##b
#define DEBUG(module) (debug & CONCAT(DEBUG_,module))
#include "nonints.h"
int Make_TimeStamp(GNode *, GNode *);
Boolean Make_OODate(GNode *);
void Make_ExpandUse(Lst);
time_t Make_Recheck(GNode *);
void Make_HandleUse(GNode *, GNode *);
void Make_Update(GNode *);
void Make_DoAllVar(GNode *);
Boolean Make_Run(Lst);
char * Check_Cwd_Cmd(const char *);
void Check_Cwd(const char **);
void PrintOnError(const char *);
void Main_ExportMAKEFLAGS(Boolean);
Boolean Main_SetObjdir(const char *);
#ifdef __GNUC__
#define UNCONST(ptr) ({ \
union __unconst { \
const void *__cp; \
void *__p; \
} __d; \
__d.__cp = ptr, __d.__p; })
#else
#define UNCONST(ptr) (void *)(ptr)
#endif
#ifndef MIN
#define MIN(a, b) ((a < b) ? a : b)
#endif
#ifndef MAX
#define MAX(a, b) ((a > b) ? a : b)
#endif
#endif /* _MAKE_H_ */

View File

@ -0,0 +1,119 @@
/* $NetBSD: make_malloc.c,v 1.5 2009/01/24 23:19:50 dsl Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef MAKE_NATIVE
#include <sys/cdefs.h>
__RCSID("$NetBSD: make_malloc.c,v 1.5 2009/01/24 23:19:50 dsl Exp $");
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "make_malloc.h"
#ifndef USE_EMALLOC
/*
* enomem --
* die when out of memory.
*/
static void
enomem(void)
{
extern char *progname;
(void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
exit(2);
}
/*
* bmake_malloc --
* malloc, but die on error.
*/
void *
bmake_malloc(size_t len)
{
void *p;
if ((p = malloc(len)) == NULL)
enomem();
return(p);
}
/*
* bmake_strdup --
* strdup, but die on error.
*/
char *
bmake_strdup(const char *str)
{
size_t len;
char *p;
len = strlen(str) + 1;
if ((p = malloc(len)) == NULL)
enomem();
return memcpy(p, str, len);
}
/*
* bmake_strndup --
* strndup, but die on error.
*/
char *
bmake_strndup(const char *str, size_t max_len)
{
size_t len;
char *p;
if (str == NULL)
return NULL;
len = strlen(str);
if (len > max_len)
len = max_len;
p = bmake_malloc(len + 1);
memcpy(p, str, len);
p[len] = '\0';
return(p);
}
/*
* bmake_realloc --
* realloc, but die on error.
*/
void *
bmake_realloc(void *ptr, size_t size)
{
if ((ptr = realloc(ptr, size)) == NULL)
enomem();
return(ptr);
}
#endif

View File

@ -0,0 +1,41 @@
/* $NetBSD: make_malloc.h,v 1.4 2009/01/24 14:43:29 dsl Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef USE_EMALLOC
void *bmake_malloc(size_t);
void *bmake_realloc(void *, size_t);
char *bmake_strdup(const char *);
char *bmake_strndup(const char *, size_t);
#else
#include <util.h>
#define bmake_malloc(x) emalloc(x)
#define bmake_realloc(x,y) erealloc(x,y)
#define bmake_strdup(x) estrdup(x)
#define bmake_strndup(x,y) estrndup(x,y)
#endif

196
commands/bmake/nonints.h Normal file
View File

@ -0,0 +1,196 @@
/* $NetBSD: nonints.h,v 1.57 2009/11/19 00:30:24 sjg Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)nonints.h 8.3 (Berkeley) 3/19/94
*/
/*-
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)nonints.h 8.3 (Berkeley) 3/19/94
*/
#ifndef MAKE_NATIVE
#undef __attribute__
#define __attribute__(x)
#endif
/* arch.c */
ReturnStatus Arch_ParseArchive(char **, Lst, GNode *);
void Arch_Touch(GNode *);
void Arch_TouchLib(GNode *);
time_t Arch_MTime(GNode *);
time_t Arch_MemMTime(GNode *);
void Arch_FindLib(GNode *, Lst);
Boolean Arch_LibOODate(GNode *);
void Arch_Init(void);
void Arch_End(void);
int Arch_IsLib(GNode *);
/* compat.c */
int CompatRunCommand(void *, void *);
void Compat_Run(Lst);
int Compat_Make(void *, void *);
/* cond.c */
struct If;
int Cond_EvalExpression(const struct If *, char *, Boolean *, int);
int Cond_Eval(char *);
void Cond_restore_depth(unsigned int);
unsigned int Cond_save_depth(void);
/* for.c */
int For_Eval(char *);
int For_Accum(char *);
void For_Run(int);
/* main.c */
void Main_ParseArgLine(const char *);
int main(int, char **);
char *Cmd_Exec(const char *, const char **);
void Error(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));
void Fatal(const char *, ...)
__attribute__((__format__(__printf__, 1, 2),__noreturn__));
void Punt(const char *, ...)
__attribute__((__format__(__printf__, 1, 2),__noreturn__));
void DieHorribly(void) __attribute__((__noreturn__));
int PrintAddr(void *, void *);
void Finish(int);
int eunlink(const char *);
void execError(const char *, const char *);
/* parse.c */
void Parse_Error(int, const char *, ...)
__attribute__((__format__(__printf__, 2, 3)));
Boolean Parse_AnyExport(void);
Boolean Parse_IsVar(char *);
void Parse_DoVar(char *, GNode *);
void Parse_AddIncludeDir(char *);
void Parse_File(const char *, int);
void Parse_Init(void);
void Parse_End(void);
void Parse_SetInput(const char *, int, int, char *(*)(void *), void *);
Lst Parse_MainName(void);
/* str.c */
char *str_concat(const char *, const char *, int);
char **brk_string(const char *, int *, Boolean, char **);
char *Str_FindSubstring(const char *, const char *);
int Str_Match(const char *, const char *);
char *Str_SYSVMatch(const char *, const char *, int *len);
void Str_SYSVSubst(Buffer *, char *, char *, int);
/* suff.c */
void Suff_ClearSuffixes(void);
Boolean Suff_IsTransform(char *);
GNode *Suff_AddTransform(char *);
int Suff_EndTransform(void *, void *);
void Suff_AddSuffix(char *, GNode **);
Lst Suff_GetPath(char *);
void Suff_DoPaths(void);
void Suff_AddInclude(char *);
void Suff_AddLib(char *);
void Suff_FindDeps(GNode *);
Lst Suff_FindPath(GNode *);
void Suff_SetNull(char *);
void Suff_Init(void);
void Suff_End(void);
void Suff_PrintAll(void);
/* targ.c */
void Targ_Init(void);
void Targ_End(void);
Lst Targ_List(void);
GNode *Targ_NewGN(const char *);
GNode *Targ_FindNode(const char *, int);
Lst Targ_FindList(Lst, int);
Boolean Targ_Ignore(GNode *);
Boolean Targ_Silent(GNode *);
Boolean Targ_Precious(GNode *);
void Targ_SetMain(GNode *);
int Targ_PrintCmd(void *, void *);
int Targ_PrintNode(void *, void *);
char *Targ_FmtTime(time_t);
void Targ_PrintType(int);
void Targ_PrintGraph(int);
void Targ_Propagate(void);
void Targ_Propagate_Wait(void);
/* var.c */
void Var_Delete(const char *, GNode *);
void Var_Set(const char *, const char *, GNode *, int);
void Var_Append(const char *, const char *, GNode *);
Boolean Var_Exists(const char *, GNode *);
char *Var_Value(const char *, GNode *, char **);
char *Var_Parse(const char *, GNode *, Boolean, int *, void **);
char *Var_Subst(const char *, const char *, GNode *, Boolean);
char *Var_GetTail(const char *);
char *Var_GetHead(const char *);
void Var_Init(void);
void Var_End(void);
void Var_Dump(GNode *);
void Var_ExportVars(void);
void Var_Export(char *, int);
void Var_UnExport(char *);

2759
commands/bmake/parse.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
/* $NetBSD: pathnames.h,v 1.17 2009/04/11 09:41:18 apb Exp $ */
/*
* Copyright (c) 1990, 1993
* 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
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)pathnames.h 5.2 (Berkeley) 6/1/90
*/
#ifndef MAKE_NATIVE
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#else
#include <paths.h>
#endif
#define _PATH_OBJDIR "obj"
#define _PATH_OBJDIRPREFIX "/usr/obj"
#ifndef _PATH_DEFSHELLDIR
#define _PATH_DEFSHELLDIR "/bin"
#endif
#define _PATH_DEFSYSMK "sys.mk"
#ifndef _PATH_DEFSYSPATH
#if defined(__minix)
#define _PATH_DEFSYSPATH "/etc/mk"
#else
#define _PATH_DEFSYSPATH "/usr/share/mk"
#endif
#endif
#ifndef _PATH_TMP
#define _PATH_TMP "/tmp/" /* with trailing slash */
#endif

116
commands/bmake/sprite.h Normal file
View File

@ -0,0 +1,116 @@
/* $NetBSD: sprite.h,v 1.11 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)sprite.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)sprite.h 8.1 (Berkeley) 6/6/93
*/
/*
* sprite.h --
*
* Common constants and type declarations for Sprite.
*/
#ifndef _SPRITE
#define _SPRITE
/*
* A boolean type is defined as an integer, not an enum. This allows a
* boolean argument to be an expression that isn't strictly 0 or 1 valued.
*/
typedef int Boolean;
#ifndef TRUE
#define TRUE 1
#endif /* TRUE */
#ifndef FALSE
#define FALSE 0
#endif /* FALSE */
/*
* Functions that must return a status can return a ReturnStatus to
* indicate success or type of failure.
*/
typedef int ReturnStatus;
/*
* The following statuses overlap with the first 2 generic statuses
* defined in status.h:
*
* SUCCESS There was no error.
* FAILURE There was a general error.
*/
#define SUCCESS 0x00000000
#define FAILURE 0x00000001
#endif /* _SPRITE */

506
commands/bmake/str.c Normal file
View File

@ -0,0 +1,506 @@
/* $NetBSD: str.c,v 1.33 2009/02/25 21:17:21 sno Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*-
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: str.c,v 1.33 2009/02/25 21:17:21 sno Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
#else
__RCSID("$NetBSD: str.c,v 1.33 2009/02/25 21:17:21 sno Exp $");
#endif
#endif /* not lint */
#endif
#include "make.h"
/*-
* str_concat --
* concatenate the two strings, inserting a space or slash between them,
* freeing them if requested.
*
* returns --
* the resulting string in allocated space.
*/
char *
str_concat(const char *s1, const char *s2, int flags)
{
int len1, len2;
char *result;
/* get the length of both strings */
len1 = strlen(s1);
len2 = strlen(s2);
/* allocate length plus separator plus EOS */
result = bmake_malloc((u_int)(len1 + len2 + 2));
/* copy first string into place */
memcpy(result, s1, len1);
/* add separator character */
if (flags & STR_ADDSPACE) {
result[len1] = ' ';
++len1;
} else if (flags & STR_ADDSLASH) {
result[len1] = '/';
++len1;
}
/* copy second string plus EOS into place */
memcpy(result + len1, s2, len2 + 1);
return(result);
}
/*-
* brk_string --
* Fracture a string into an array of words (as delineated by tabs or
* spaces) taking quotation marks into account. Leading tabs/spaces
* are ignored.
*
* If expand is TRUE, quotes are removed and escape sequences
* such as \r, \t, etc... are expanded.
*
* returns --
* Pointer to the array of pointers to the words.
* Memory containing the actual words in *buffer.
* Both of these must be free'd by the caller.
* Number of words in *store_argc.
*/
char **
brk_string(const char *str, int *store_argc, Boolean expand, char **buffer)
{
int argc, ch;
char inquote, *start, *t;
const char *p;
int len;
int argmax = 50, curlen = 0;
char **argv = bmake_malloc((argmax + 1) * sizeof(char *));
/* skip leading space chars. */
for (; *str == ' ' || *str == '\t'; ++str)
continue;
/* allocate room for a copy of the string */
if ((len = strlen(str) + 1) > curlen)
*buffer = bmake_malloc(curlen = len);
/*
* copy the string; at the same time, parse backslashes,
* quotes and build the argument list.
*/
argc = 0;
inquote = '\0';
for (p = str, start = t = *buffer;; ++p) {
switch(ch = *p) {
case '"':
case '\'':
if (inquote) {
if (inquote == ch)
inquote = '\0';
else
break;
}
else {
inquote = (char) ch;
/* Don't miss "" or '' */
if (start == NULL && p[1] == inquote) {
if (!expand) {
start = t;
*t++ = ch;
} else
start = t + 1;
p++;
inquote = '\0';
break;
}
}
if (!expand) {
if (!start)
start = t;
*t++ = ch;
}
continue;
case ' ':
case '\t':
case '\n':
if (inquote)
break;
if (!start)
continue;
/* FALLTHROUGH */
case '\0':
/*
* end of a token -- make sure there's enough argv
* space and save off a pointer.
*/
if (!start)
goto done;
*t++ = '\0';
if (argc == argmax) {
argmax *= 2; /* ramp up fast */
argv = (char **)bmake_realloc(argv,
(argmax + 1) * sizeof(char *));
}
argv[argc++] = start;
start = NULL;
if (ch == '\n' || ch == '\0') {
if (expand && inquote) {
free(argv);
free(*buffer);
*buffer = NULL;
return NULL;
}
goto done;
}
continue;
case '\\':
if (!expand) {
if (!start)
start = t;
*t++ = '\\';
if (*(p+1) == '\0') /* catch '\' at end of line */
continue;
ch = *++p;
break;
}
switch (ch = *++p) {
case '\0':
case '\n':
/* hmmm; fix it up as best we can */
ch = '\\';
--p;
break;
case 'b':
ch = '\b';
break;
case 'f':
ch = '\f';
break;
case 'n':
ch = '\n';
break;
case 'r':
ch = '\r';
break;
case 't':
ch = '\t';
break;
}
break;
}
if (!start)
start = t;
*t++ = (char) ch;
}
done: argv[argc] = NULL;
*store_argc = argc;
return(argv);
}
/*
* Str_FindSubstring -- See if a string contains a particular substring.
*
* Input:
* string String to search.
* substring Substring to find in string.
*
* 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 *
Str_FindSubstring(const char *string, const char *substring)
{
const char *a, *b;
/*
* First scan quickly through the two strings looking for a single-
* character match. When it's found, then compare the rest of the
* substring.
*/
for (b = substring; *string != 0; string += 1) {
if (*string != *b)
continue;
a = string;
for (;;) {
if (*b == 0)
return UNCONST(string);
if (*a++ != *b++)
break;
}
b = substring;
}
return NULL;
}
/*
* 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
Str_Match(const char *string, const char *pattern)
{
char c2;
for (;;) {
/*
* See if we're at the end of both the pattern and the
* string. If, we succeeded. If we're at the end of the
* pattern but not at the end of the string, we failed.
*/
if (*pattern == 0)
return(!*string);
if (*string == 0 && *pattern != '*')
return(0);
/*
* Check for a "*" as the next pattern character. It matches
* any substring. We handle this by calling ourselves
* recursively for each postfix of string, until either we
* match or we reach the end of the string.
*/
if (*pattern == '*') {
pattern += 1;
if (*pattern == 0)
return(1);
while (*string != 0) {
if (Str_Match(string, pattern))
return(1);
++string;
}
return(0);
}
/*
* Check for a "?" as the next pattern character. It matches
* any single character.
*/
if (*pattern == '?')
goto thisCharOK;
/*
* Check for a "[" as the next pattern character. It is
* followed by a list of characters that are acceptable, or
* by a range (two characters separated by "-").
*/
if (*pattern == '[') {
++pattern;
for (;;) {
if ((*pattern == ']') || (*pattern == 0))
return(0);
if (*pattern == *string)
break;
if (pattern[1] == '-') {
c2 = pattern[2];
if (c2 == 0)
return(0);
if ((*pattern <= *string) &&
(c2 >= *string))
break;
if ((*pattern >= *string) &&
(c2 <= *string))
break;
pattern += 2;
}
++pattern;
}
while ((*pattern != ']') && (*pattern != 0))
++pattern;
goto thisCharOK;
}
/*
* If the next pattern character is '/', just strip off the
* '/' so we do exact matching on the character that follows.
*/
if (*pattern == '\\') {
++pattern;
if (*pattern == 0)
return(0);
}
/*
* There's no special character. Just make sure that the
* next characters of each string match.
*/
if (*pattern != *string)
return(0);
thisCharOK: ++pattern;
++string;
}
}
/*-
*-----------------------------------------------------------------------
* Str_SYSVMatch --
* Check word against pattern for a match (% is wild),
*
* Input:
* word Word to examine
* pattern Pattern to examine against
* len Number of characters to substitute
*
* Results:
* Returns the beginning position of a match or null. The number
* of characters matched is returned in len.
*
* Side Effects:
* None
*
*-----------------------------------------------------------------------
*/
char *
Str_SYSVMatch(const char *word, const char *pattern, int *len)
{
const char *p = pattern;
const char *w = word;
const char *m;
if (*p == '\0') {
/* Null pattern is the whole string */
*len = strlen(w);
return UNCONST(w);
}
if ((m = strchr(p, '%')) != NULL) {
/* check that the prefix matches */
for (; p != m && *w && *w == *p; w++, p++)
continue;
if (p != m)
return NULL; /* No match */
if (*++p == '\0') {
/* No more pattern, return the rest of the string */
*len = strlen(w);
return UNCONST(w);
}
}
m = w;
/* Find a matching tail */
do
if (strcmp(p, w) == 0) {
*len = w - m;
return UNCONST(m);
}
while (*w++ != '\0');
return NULL;
}
/*-
*-----------------------------------------------------------------------
* Str_SYSVSubst --
* Substitute '%' on the pattern with len characters from src.
* If the pattern does not contain a '%' prepend len characters
* from src.
*
* Results:
* None
*
* Side Effects:
* Places result on buf
*
*-----------------------------------------------------------------------
*/
void
Str_SYSVSubst(Buffer *buf, char *pat, char *src, int len)
{
char *m;
if ((m = strchr(pat, '%')) != NULL) {
/* Copy the prefix */
Buf_AddBytes(buf, m - pat, pat);
/* skip the % */
pat = m + 1;
}
/* Copy the pattern */
Buf_AddBytes(buf, len, src);
/* append the rest */
Buf_AddBytes(buf, strlen(pat), pat);
}

93
commands/bmake/strlist.c Normal file
View File

@ -0,0 +1,93 @@
/* $NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $ */
/*-
* Copyright (c) 2008 - 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: strlist.c,v 1.4 2009/01/24 11:59:39 dsl Exp $");
#endif /* not lint */
#endif
#include <stddef.h>
#include <stdlib.h>
#include "strlist.h"
#include "make_malloc.h"
void
strlist_init(strlist_t *sl)
{
sl->sl_num = 0;
sl->sl_max = 0;
sl->sl_items = NULL;
}
void
strlist_clean(strlist_t *sl)
{
char *str;
int i;
STRLIST_FOREACH(str, sl, i)
free(str);
free(sl->sl_items);
sl->sl_num = 0;
sl->sl_max = 0;
sl->sl_items = NULL;
}
void
strlist_add_str(strlist_t *sl, char *str, unsigned int info)
{
unsigned int n;
strlist_item_t *items;
if (str == NULL)
return;
n = sl->sl_num + 1;
sl->sl_num = n;
items = sl->sl_items;
if (n >= sl->sl_max) {
items = bmake_realloc(items, (n + 7) * sizeof *sl->sl_items);
sl->sl_items = items;
sl->sl_max = n + 6;
}
items += n - 1;
items->si_str = str;
items->si_info = info;
items[1].si_str = NULL; /* STRLIST_FOREACH() terminator */
}

62
commands/bmake/strlist.h Normal file
View File

@ -0,0 +1,62 @@
/* $NetBSD: strlist.h,v 1.3 2009/01/16 21:15:34 dsl Exp $ */
/*-
* Copyright (c) 2008 - 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by David Laight.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STRLIST_H
#define _STRLIST_H
typedef struct {
char *si_str;
unsigned int si_info;
} strlist_item_t;
typedef struct {
unsigned int sl_num;
unsigned int sl_max;
strlist_item_t *sl_items;
} strlist_t;
void strlist_init(strlist_t *);
void strlist_clean(strlist_t *);
void strlist_add_str(strlist_t *, char *, unsigned int);
#define strlist_num(sl) ((sl)->sl_num)
#define strlist_str(sl, n) ((sl)->sl_items[n].si_str)
#define strlist_info(sl, n) ((sl)->sl_items[n].si_info)
#define strlist_set_info(sl, n, v) ((void)((sl)->sl_items[n].si_info = (v)))
#define STRLIST_FOREACH(v, sl, index) \
if ((sl)->sl_items != NULL) \
for (index = 0; (v = strlist_str(sl, index)) != NULL; index++)
#endif /* _STRLIST_H */

2645
commands/bmake/suff.c Normal file

File diff suppressed because it is too large Load Diff

848
commands/bmake/targ.c Normal file
View File

@ -0,0 +1,848 @@
/* $NetBSD: targ.c,v 1.55 2009/01/23 21:26:30 dsl Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1989 by Berkeley Softworks
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Adam de Boor.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: targ.c,v 1.55 2009/01/23 21:26:30 dsl Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94";
#else
__RCSID("$NetBSD: targ.c,v 1.55 2009/01/23 21:26:30 dsl Exp $");
#endif
#endif /* not lint */
#endif
/*-
* targ.c --
* Functions for maintaining the Lst allTargets. Target nodes are
* kept in two structures: a Lst, maintained by the list library, and a
* hash table, maintained by the hash library.
*
* Interface:
* Targ_Init Initialization procedure.
*
* Targ_End Cleanup the module
*
* Targ_List Return the list of all targets so far.
*
* Targ_NewGN Create a new GNode for the passed target
* (string). The node is *not* placed in the
* hash table, though all its fields are
* initialized.
*
* Targ_FindNode Find the node for a given target, creating
* and storing it if it doesn't exist and the
* flags are right (TARG_CREATE)
*
* Targ_FindList Given a list of names, find nodes for all
* of them. If a name doesn't exist and the
* TARG_NOCREATE flag was given, an error message
* is printed. Else, if a name doesn't exist,
* its node is created.
*
* Targ_Ignore Return TRUE if errors should be ignored when
* creating the given target.
*
* Targ_Silent Return TRUE if we should be silent when
* creating the given target.
*
* Targ_Precious Return TRUE if the target is precious and
* should not be removed if we are interrupted.
*
* Targ_Propagate Propagate information between related
* nodes. Should be called after the
* makefiles are parsed but before any
* action is taken.
*
* Debugging:
* Targ_PrintGraph Print out the entire graphm all variables
* and statistics for the directory cache. Should
* print something for suffixes, too, but...
*/
#include <stdio.h>
#include <strings.h>
#include <time.h>
#include "make.h"
#include "hash.h"
#include "dir.h"
static Lst allTargets; /* the list of all targets found so far */
#ifdef CLEANUP
static Lst allGNs; /* List of all the GNodes */
#endif
static Hash_Table targets; /* a hash table of same */
#define HTSIZE 191 /* initial size of hash table */
static int TargPrintOnlySrc(void *, void *);
static int TargPrintName(void *, void *);
#ifdef CLEANUP
static void TargFreeGN(void *);
#endif
static int TargPropagateCohort(void *, void *);
static int TargPropagateNode(void *, void *);
/*-
*-----------------------------------------------------------------------
* Targ_Init --
* Initialize this module
*
* Results:
* None
*
* Side Effects:
* The allTargets list and the targets hash table are initialized
*-----------------------------------------------------------------------
*/
void
Targ_Init(void)
{
allTargets = Lst_Init(FALSE);
Hash_InitTable(&targets, HTSIZE);
}
/*-
*-----------------------------------------------------------------------
* Targ_End --
* Finalize this module
*
* Results:
* None
*
* Side Effects:
* All lists and gnodes are cleared
*-----------------------------------------------------------------------
*/
void
Targ_End(void)
{
#ifdef CLEANUP
Lst_Destroy(allTargets, NULL);
if (allGNs)
Lst_Destroy(allGNs, TargFreeGN);
Hash_DeleteTable(&targets);
#endif
}
/*-
*-----------------------------------------------------------------------
* Targ_List --
* Return the list of all targets
*
* Results:
* The list of all targets.
*
* Side Effects:
* None
*-----------------------------------------------------------------------
*/
Lst
Targ_List(void)
{
return allTargets;
}
/*-
*-----------------------------------------------------------------------
* Targ_NewGN --
* Create and initialize a new graph node
*
* Input:
* name the name to stick in the new node
*
* Results:
* An initialized graph node with the name field filled with a copy
* of the passed name
*
* Side Effects:
* The gnode is added to the list of all gnodes.
*-----------------------------------------------------------------------
*/
GNode *
Targ_NewGN(const char *name)
{
GNode *gn;
gn = bmake_malloc(sizeof(GNode));
gn->name = bmake_strdup(name);
gn->uname = NULL;
gn->path = NULL;
if (name[0] == '-' && name[1] == 'l') {
gn->type = OP_LIB;
} else {
gn->type = 0;
}
gn->unmade = 0;
gn->unmade_cohorts = 0;
gn->cohort_num[0] = 0;
gn->centurion = NULL;
gn->made = UNMADE;
gn->flags = 0;
gn->checked = 0;
gn->mtime = gn->cmtime = 0;
gn->iParents = Lst_Init(FALSE);
gn->cohorts = Lst_Init(FALSE);
gn->parents = Lst_Init(FALSE);
gn->children = Lst_Init(FALSE);
gn->order_pred = Lst_Init(FALSE);
gn->order_succ = Lst_Init(FALSE);
Hash_InitTable(&gn->context, 0);
gn->commands = Lst_Init(FALSE);
gn->suffix = NULL;
gn->lineno = 0;
gn->fname = NULL;
#ifdef CLEANUP
if (allGNs == NULL)
allGNs = Lst_Init(FALSE);
Lst_AtEnd(allGNs, gn);
#endif
return (gn);
}
#ifdef CLEANUP
/*-
*-----------------------------------------------------------------------
* TargFreeGN --
* Destroy a GNode
*
* Results:
* None.
*
* Side Effects:
* None.
*-----------------------------------------------------------------------
*/
static void
TargFreeGN(void *gnp)
{
GNode *gn = (GNode *)gnp;
free(gn->name);
if (gn->uname)
free(gn->uname);
if (gn->path)
free(gn->path);
/* gn->fname points to name allocated when file was opened, don't free */
Lst_Destroy(gn->iParents, NULL);
Lst_Destroy(gn->cohorts, NULL);
Lst_Destroy(gn->parents, NULL);
Lst_Destroy(gn->children, NULL);
Lst_Destroy(gn->order_succ, NULL);
Lst_Destroy(gn->order_pred, NULL);
Hash_DeleteTable(&gn->context);
Lst_Destroy(gn->commands, NULL);
free(gn);
}
#endif
/*-
*-----------------------------------------------------------------------
* Targ_FindNode --
* Find a node in the list using the given name for matching
*
* Input:
* name the name to find
* flags flags governing events when target not
* found
*
* Results:
* The node in the list if it was. If it wasn't, return NULL of
* flags was TARG_NOCREATE or the newly created and initialized node
* if it was TARG_CREATE
*
* Side Effects:
* Sometimes a node is created and added to the list
*-----------------------------------------------------------------------
*/
GNode *
Targ_FindNode(const char *name, int flags)
{
GNode *gn; /* node in that element */
Hash_Entry *he; /* New or used hash entry for node */
Boolean isNew; /* Set TRUE if Hash_CreateEntry had to create */
/* an entry for the node */
if (!(flags & (TARG_CREATE | TARG_NOHASH))) {
he = Hash_FindEntry(&targets, name);
if (he == NULL)
return NULL;
return (GNode *)Hash_GetValue(he);
}
if (!(flags & TARG_NOHASH)) {
he = Hash_CreateEntry(&targets, name, &isNew);
if (!isNew)
return (GNode *)Hash_GetValue(he);
}
gn = Targ_NewGN(name);
if (!(flags & TARG_NOHASH))
Hash_SetValue(he, gn);
Var_Append(".ALLTARGETS", name, VAR_GLOBAL);
(void)Lst_AtEnd(allTargets, gn);
if (doing_depend)
gn->flags |= FROM_DEPEND;
return gn;
}
/*-
*-----------------------------------------------------------------------
* Targ_FindList --
* Make a complete list of GNodes from the given list of names
*
* Input:
* name list of names to find
* flags flags used if no node is found for a given name
*
* Results:
* A complete list of graph nodes corresponding to all instances of all
* the names in names.
*
* Side Effects:
* If flags is TARG_CREATE, nodes will be created for all names in
* names which do not yet have graph nodes. If flags is TARG_NOCREATE,
* an error message will be printed for each name which can't be found.
* -----------------------------------------------------------------------
*/
Lst
Targ_FindList(Lst names, int flags)
{
Lst nodes; /* result list */
LstNode ln; /* name list element */
GNode *gn; /* node in tLn */
char *name;
nodes = Lst_Init(FALSE);
if (Lst_Open(names) == FAILURE) {
return (nodes);
}
while ((ln = Lst_Next(names)) != NULL) {
name = (char *)Lst_Datum(ln);
gn = Targ_FindNode(name, flags);
if (gn != NULL) {
/*
* Note: Lst_AtEnd must come before the Lst_Concat so the nodes
* are added to the list in the order in which they were
* encountered in the makefile.
*/
(void)Lst_AtEnd(nodes, gn);
} else if (flags == TARG_NOCREATE) {
Error("\"%s\" -- target unknown.", name);
}
}
Lst_Close(names);
return (nodes);
}
/*-
*-----------------------------------------------------------------------
* Targ_Ignore --
* Return true if should ignore errors when creating gn
*
* Input:
* gn node to check for
*
* Results:
* TRUE if should ignore errors
*
* Side Effects:
* None
*-----------------------------------------------------------------------
*/
Boolean
Targ_Ignore(GNode *gn)
{
if (ignoreErrors || gn->type & OP_IGNORE) {
return (TRUE);
} else {
return (FALSE);
}
}
/*-
*-----------------------------------------------------------------------
* Targ_Silent --
* Return true if be silent when creating gn
*
* Input:
* gn node to check for
*
* Results:
* TRUE if should be silent
*
* Side Effects:
* None
*-----------------------------------------------------------------------
*/
Boolean
Targ_Silent(GNode *gn)
{
if (beSilent || gn->type & OP_SILENT) {
return (TRUE);
} else {
return (FALSE);
}
}
/*-
*-----------------------------------------------------------------------
* Targ_Precious --
* See if the given target is precious
*
* Input:
* gn the node to check
*
* Results:
* TRUE if it is precious. FALSE otherwise
*
* Side Effects:
* None
*-----------------------------------------------------------------------
*/
Boolean
Targ_Precious(GNode *gn)
{
if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) {
return (TRUE);
} else {
return (FALSE);
}
}
/******************* 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
* debugging output.
*
* Input:
* gn The main target we'll create
*
* Results:
* None.
*
* Side Effects:
* "mainTarg" is set to the main target's node.
*-----------------------------------------------------------------------
*/
void
Targ_SetMain(GNode *gn)
{
mainTarg = gn;
}
static int
TargPrintName(void *gnp, void *pflags __unused)
{
GNode *gn = (GNode *)gnp;
fprintf(debug_file, "%s%s ", gn->name, gn->cohort_num);
return 0;
}
int
Targ_PrintCmd(void *cmd, void *dummy)
{
fprintf(debug_file, "\t%s\n", (char *)cmd);
return (dummy ? 0 : 0);
}
/*-
*-----------------------------------------------------------------------
* Targ_FmtTime --
* Format a modification time in some reasonable way and return it.
*
* Results:
* The time reformatted.
*
* Side Effects:
* The time is placed in a static area, so it is overwritten
* with each call.
*
*-----------------------------------------------------------------------
*/
char *
Targ_FmtTime(time_t tm)
{
struct tm *parts;
static char buf[128];
parts = localtime(&tm);
(void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts);
return(buf);
}
/*-
*-----------------------------------------------------------------------
* Targ_PrintType --
* Print out a type field giving only those attributes the user can
* set.
*
* Results:
*
* Side Effects:
*
*-----------------------------------------------------------------------
*/
void
Targ_PrintType(int type)
{
int tbit;
#define PRINTBIT(attr) case CONCAT(OP_,attr): fprintf(debug_file, "." #attr " "); break
#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG))fprintf(debug_file, "." #attr " "); break
type &= ~OP_OPMASK;
while (type) {
tbit = 1 << (ffs(type) - 1);
type &= ~tbit;
switch(tbit) {
PRINTBIT(OPTIONAL);
PRINTBIT(USE);
PRINTBIT(EXEC);
PRINTBIT(IGNORE);
PRINTBIT(PRECIOUS);
PRINTBIT(SILENT);
PRINTBIT(MAKE);
PRINTBIT(JOIN);
PRINTBIT(INVISIBLE);
PRINTBIT(NOTMAIN);
PRINTDBIT(LIB);
/*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */
case OP_MEMBER: if (DEBUG(TARG))fprintf(debug_file, ".MEMBER "); break;
PRINTDBIT(ARCHV);
PRINTDBIT(MADE);
PRINTDBIT(PHONY);
}
}
}
static const char *
made_name(enum enum_made made)
{
switch (made) {
case UNMADE: return "unmade";
case DEFERRED: return "deferred";
case REQUESTED: return "requested";
case BEINGMADE: return "being made";
case MADE: return "made";
case UPTODATE: return "up-to-date";
case ERROR: return "error when made";
case ABORTED: return "aborted";
default: return "unknown enum_made value";
}
}
/*-
*-----------------------------------------------------------------------
* TargPrintNode --
* print the contents of a node
*-----------------------------------------------------------------------
*/
int
Targ_PrintNode(void *gnp, void *passp)
{
GNode *gn = (GNode *)gnp;
int pass = passp ? *(int *)passp : 0;
fprintf(debug_file, "# %s%s, flags %x, type %x, made %d\n",
gn->name, gn->cohort_num, gn->flags, gn->type, gn->made);
if (gn->flags == 0)
return 0;
if (!OP_NOP(gn->type)) {
fprintf(debug_file, "#\n");
if (gn == mainTarg) {
fprintf(debug_file, "# *** MAIN TARGET ***\n");
}
if (pass >= 2) {
if (gn->unmade) {
fprintf(debug_file, "# %d unmade children\n", gn->unmade);
} else {
fprintf(debug_file, "# No unmade children\n");
}
if (! (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC))) {
if (gn->mtime != 0) {
fprintf(debug_file, "# last modified %s: %s\n",
Targ_FmtTime(gn->mtime),
made_name(gn->made));
} else if (gn->made != UNMADE) {
fprintf(debug_file, "# non-existent (maybe): %s\n",
made_name(gn->made));
} else {
fprintf(debug_file, "# unmade\n");
}
}
if (!Lst_IsEmpty (gn->iParents)) {
fprintf(debug_file, "# implicit parents: ");
Lst_ForEach(gn->iParents, TargPrintName, NULL);
fprintf(debug_file, "\n");
}
} else {
if (gn->unmade)
fprintf(debug_file, "# %d unmade children\n", gn->unmade);
}
if (!Lst_IsEmpty (gn->parents)) {
fprintf(debug_file, "# parents: ");
Lst_ForEach(gn->parents, TargPrintName, NULL);
fprintf(debug_file, "\n");
}
if (!Lst_IsEmpty (gn->order_pred)) {
fprintf(debug_file, "# order_pred: ");
Lst_ForEach(gn->order_pred, TargPrintName, NULL);
fprintf(debug_file, "\n");
}
if (!Lst_IsEmpty (gn->order_succ)) {
fprintf(debug_file, "# order_succ: ");
Lst_ForEach(gn->order_succ, TargPrintName, NULL);
fprintf(debug_file, "\n");
}
fprintf(debug_file, "%-16s", gn->name);
switch (gn->type & OP_OPMASK) {
case OP_DEPENDS:
fprintf(debug_file, ": "); break;
case OP_FORCE:
fprintf(debug_file, "! "); break;
case OP_DOUBLEDEP:
fprintf(debug_file, ":: "); break;
}
Targ_PrintType(gn->type);
Lst_ForEach(gn->children, TargPrintName, NULL);
fprintf(debug_file, "\n");
Lst_ForEach(gn->commands, Targ_PrintCmd, NULL);
fprintf(debug_file, "\n\n");
if (gn->type & OP_DOUBLEDEP) {
Lst_ForEach(gn->cohorts, Targ_PrintNode, &pass);
}
}
return (0);
}
/*-
*-----------------------------------------------------------------------
* TargPrintOnlySrc --
* Print only those targets that are just a source.
*
* Results:
* 0.
*
* Side Effects:
* The name of each file is printed preceded by #\t
*
*-----------------------------------------------------------------------
*/
static int
TargPrintOnlySrc(void *gnp, void *dummy __unused)
{
GNode *gn = (GNode *)gnp;
if (!OP_NOP(gn->type))
return 0;
fprintf(debug_file, "#\t%s [%s] ",
gn->name, gn->path ? gn->path : gn->name);
Targ_PrintType(gn->type);
fprintf(debug_file, "\n");
return 0;
}
/*-
*-----------------------------------------------------------------------
* Targ_PrintGraph --
* print the entire graph. heh heh
*
* Input:
* pass Which pass this is. 1 => no processing
* 2 => processing done
*
* Results:
* none
*
* Side Effects:
* lots o' output
*-----------------------------------------------------------------------
*/
void
Targ_PrintGraph(int pass)
{
fprintf(debug_file, "#*** Input graph:\n");
Lst_ForEach(allTargets, Targ_PrintNode, &pass);
fprintf(debug_file, "\n\n");
fprintf(debug_file, "#\n# Files that are only sources:\n");
Lst_ForEach(allTargets, TargPrintOnlySrc, NULL);
fprintf(debug_file, "#*** Global Variables:\n");
Var_Dump(VAR_GLOBAL);
fprintf(debug_file, "#*** Command-line Variables:\n");
Var_Dump(VAR_CMD);
fprintf(debug_file, "\n");
Dir_PrintDirectories();
fprintf(debug_file, "\n");
Suff_PrintAll();
}
/*-
*-----------------------------------------------------------------------
* TargPropagateNode --
* Propagate information from a single node to related nodes if
* appropriate.
*
* Input:
* gnp The node that we are processing.
*
* Results:
* Always returns 0, for the benefit of Lst_ForEach().
*
* Side Effects:
* Information is propagated from this node to cohort or child
* nodes.
*
* If the node was defined with "::", then TargPropagateCohort()
* will be called for each cohort node.
*
* If the node has recursive predecessors, then
* TargPropagateRecpred() will be called for each recursive
* predecessor.
*-----------------------------------------------------------------------
*/
static int
TargPropagateNode(void *gnp, void *junk __unused)
{
GNode *gn = (GNode *)gnp;
if (gn->type & OP_DOUBLEDEP)
Lst_ForEach(gn->cohorts, TargPropagateCohort, gnp);
return (0);
}
/*-
*-----------------------------------------------------------------------
* TargPropagateCohort --
* Propagate some bits in the type mask from a node to
* a related cohort node.
*
* Input:
* cnp The node that we are processing.
* gnp Another node that has cnp as a cohort.
*
* Results:
* Always returns 0, for the benefit of Lst_ForEach().
*
* Side Effects:
* cnp's type bitmask is modified to incorporate some of the
* bits from gnp's type bitmask. (XXX need a better explanation.)
*-----------------------------------------------------------------------
*/
static int
TargPropagateCohort(void *cgnp, void *pgnp)
{
GNode *cgn = (GNode *)cgnp;
GNode *pgn = (GNode *)pgnp;
cgn->type |= pgn->type & ~OP_OPMASK;
return (0);
}
/*-
*-----------------------------------------------------------------------
* Targ_Propagate --
* Propagate information between related nodes. Should be called
* after the makefiles are parsed but before any action is taken.
*
* Results:
* none
*
* Side Effects:
* Information is propagated between related nodes throughout the
* graph.
*-----------------------------------------------------------------------
*/
void
Targ_Propagate(void)
{
Lst_ForEach(allTargets, TargPropagateNode, NULL);
}

123
commands/bmake/trace.c Normal file
View File

@ -0,0 +1,123 @@
/* $NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Bill Sommerfeld
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $");
#endif /* not lint */
#endif
/*-
* trace.c --
* handle logging of trace events generated by various parts of make.
*
* Interface:
* Trace_Init Initialize tracing (called once during
* the lifetime of the process)
*
* Trace_End Finalize tracing (called before make exits)
*
* Trace_Log Log an event about a particular make job.
*/
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include "make.h"
#include "job.h"
#include "trace.h"
static FILE *trfile;
static pid_t trpid;
char *trwd;
static const char *evname[] = {
"BEG",
"END",
"ERR",
"JOB",
"DON",
"INT",
};
void
Trace_Init(const char *pathname)
{
char *p1;
if (pathname != NULL) {
trpid = getpid();
trwd = Var_Value(".CURDIR", VAR_GLOBAL, &p1);
trfile = fopen(pathname, "a");
}
}
void
Trace_Log(TrEvent event, Job *job)
{
struct timeval rightnow;
if (trfile == NULL)
return;
gettimeofday(&rightnow, NULL);
#if defined(__minix)
fprintf(trfile, "%ld.%06ld %d %s %d %s",
(long)rightnow.tv_sec, (long)rightnow.tv_usec,
jobTokensRunning,
evname[event], trpid, trwd);
#else
fprintf(trfile, "%lld.%06ld %d %s %d %s",
(long long)rightnow.tv_sec, (long)rightnow.tv_usec,
jobTokensRunning,
evname[event], trpid, trwd);
#endif
if (job != NULL) {
fprintf(trfile, " %s %d %x %x", job->node->name,
job->pid, job->flags, job->node->type);
}
fputc('\n', trfile);
fflush(trfile);
}
void
Trace_End(void)
{
if (trfile != NULL)
fclose(trfile);
}

49
commands/bmake/trace.h Normal file
View File

@ -0,0 +1,49 @@
/* $NetBSD: trace.h,v 1.3 2008/04/28 20:24:14 martin Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Bill Sommerfeld
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*-
* trace.h --
* Definitions pertaining to the tracing of jobs in parallel mode.
*/
typedef enum {
MAKESTART,
MAKEEND,
MAKEERROR,
JOBSTART,
JOBEND,
MAKEINTR
} TrEvent;
void Trace_Init(const char *);
void Trace_Log(TrEvent, Job *);
void Trace_End(void);

View File

@ -0,0 +1,73 @@
# $NetBSD: Makefile,v 1.25 2009/11/19 00:30:25 sjg Exp $
#
# Unit tests for make(1)
# The main targets are:
#
# all: run all the tests
# test: run 'all', capture output and compare to expected results
# accept: move generated output to expected results
#
# Adding a test case.
# Each feature should get its own set of tests in its own suitably
# named makefile which should be added to SUBFILES to hook it in.
#
.MAIN: all
UNIT_TESTS:= ${.PARSEDIR}
# Simple sub-makefiles - we run them as a black box
# keep the list sorted.
SUBFILES= \
comment \
cond1 \
export \
export-all \
dotwait \
forsubst \
moderrs \
modmatch \
modmisc \
modorder \
modts \
modword \
posix \
qequals \
ternary \
unexport \
unexport-env \
varcmd
all: ${SUBFILES}
# the tests are actually done with sub-makes.
.PHONY: ${SUBFILES}
.PRECIOUS: ${SUBFILES}
${SUBFILES}:
-@${.MAKE} -k -f ${UNIT_TESTS}/$@
clean:
rm -f *.out *.fail *.core
.include <bsd.obj.mk>
TEST_MAKE?= ${.MAKE}
# The driver.
# We always pretend .MAKE was called 'make'
# and strip ${.CURDIR}/ from the output
# and replace anything after 'stopped in' with unit-tests
# so the results can be compared.
test:
@echo "${TEST_MAKE} -f ${MAKEFILE} > ${.TARGET}.out 2>&1"
@cd ${.OBJDIR} && ${TEST_MAKE} -f ${MAKEFILE} 2>&1 | \
${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}:,make:,' \
-e '/stopped/s, /.*, unit-tests,' \
-e 's,${.CURDIR:C/\./\\\./g}/,,g' \
-e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' > ${.TARGET}.out || { \
tail ${.TARGET}.out; mv ${.TARGET}.out ${.TARGET}.fail; exit 1; }
diff -u ${UNIT_TESTS}/${.TARGET}.exp ${.TARGET}.out
accept:
mv test.out ${.CURDIR}/test.exp

View File

@ -0,0 +1,31 @@
# This is a comment
.if ${MACHINE_ARCH} == something
FOO=bar
.endif
#\
Multiline comment
BAR=# defined
FOOBAR= # defined
# This is an escaped comment \
that keeps going until the end of this line
# Another escaped comment \
that \
goes \
on
# This is NOT an escaped comment due to the double backslashes \\
all: hi foo bar
@echo comment testing done
hi:
@echo comment testing start
foo:
@echo this is $@
bar:
@echo This is how a comment looks: '# comment'

View File

@ -0,0 +1,104 @@
# $Id: cond1,v 1.4 2008/10/29 15:37:08 sjg Exp $
# hard code these!
TEST_UNAME_S= NetBSD
TEST_UNAME_M= sparc
TEST_MACHINE= i386
.if ${TEST_UNAME_S}
Ok=var,
.endif
.if ("${TEST_UNAME_S}")
Ok+=(\"var\"),
.endif
.if (${TEST_UNAME_M} != ${TEST_MACHINE})
Ok+=(var != var),
.endif
.if ${TEST_UNAME_M} != ${TEST_MACHINE}
Ok+= var != var,
.endif
.if !((${TEST_UNAME_M} != ${TEST_MACHINE}) && defined(X))
Ok+= !((var != var) && defined(name)),
.endif
# from bsd.obj.mk
MKOBJ?=no
.if ${MKOBJ} == "no"
o= no
Ok+= var == "quoted",
.else
.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR)
.if defined(notMAKEOBJDIRPREFIX)
o=${MAKEOBJDIRPREFIX}${__curdir}
.else
o= ${MAKEOBJDIR}
.endif
.endif
o= o
.endif
# repeat the above to check we get the same result
.if ${MKOBJ} == "no"
o2= no
.else
.if defined(notMAKEOBJDIRPREFIX) || defined(norMAKEOBJDIR)
.if defined(notMAKEOBJDIRPREFIX)
o2=${MAKEOBJDIRPREFIX}${__curdir}
.else
o2= ${MAKEOBJDIR}
.endif
.endif
o2= o
.endif
PRIMES=2 3 5 7 11
NUMBERS=1 2 3 4 5
n=2
.if ${PRIMES:M$n} == ""
X=not
.else
X=
.endif
.if ${MACHINE_ARCH} == no-such
A=one
.else
.if ${MACHINE_ARCH} == not-this
.if ${MACHINE_ARCH} == something-else
A=unlikely
.else
A=no
.endif
.endif
A=other
# We expect an extra else warning - we're not skipping here
.else
A=this should be an error
.endif
.if $X != ""
.if $X == not
B=one
.else
B=other
# We expect an extra else warning - we are skipping here
.else
B=this should be an error
.endif
.else
B=unknown
.endif
.if "quoted" == quoted
C=clever
.else
C=dim
.endif
all:
@echo "$n is $X prime"
@echo "A='$A' B='$B' C='$C' o='$o,${o2}'"
@echo "Passed:${.newline} ${Ok:S/,/${.newline}/}"
@echo "${NUMBERS:@n@$n is ${("${PRIMES:M$n}" == ""):?not:} prime${.newline}@}"
@echo "${"${DoNotQuoteHere:U0}" > 0:?OK:No}"
@echo "${${NoSuchNumber:U42} > 0:?OK:No}"

View File

@ -0,0 +1,61 @@
# $NetBSD: dotwait,v 1.1 2006/02/26 22:45:46 apb Exp $
THISMAKEFILE:= ${.PARSEDIR}/${.PARSEFILE}
TESTS= simple recursive shared cycle
PAUSE= sleep 1
# Use a .for loop rather than dependencies here, to ensure
# that the tests are run one by one, with parallelism
# only within tests.
# Ignore "--- target ---" lines printed by parallel make.
all:
.for t in ${TESTS}
@${.MAKE} -f ${THISMAKEFILE} -j4 $t | grep -v "^--- "
.endfor
#
# Within each test, the names of the sub-targets follow these
# conventions:
# * If it's expected that two or more targets may be made in parallel,
# then the target names will differ only in an alphabetic component
# such as ".a" or ".b".
# * If it's expected that two or more targets should be made in sequence
# then the target names will differ in numeric components, such that
# lexical ordering of the target names matches the expected order
# in which the targets should be made.
#
# Targets may echo ${PARALLEL_TARG} to print a modified version
# of their own name, in which alphabetic components like ".a" or ".b"
# are converted to ".*". Two targets that are expected to
# be made in parallel will thus print the same strings, so that the
# output is independent of the order in which these targets are made.
#
PARALLEL_TARG= ${.TARGET:C/\.[a-z]/.*/g:Q}
.DEFAULT:
@echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG}
_ECHOUSE: .USE
@echo ${PARALLEL_TARG}; ${PAUSE}; echo ${PARALLEL_TARG}
# simple: no recursion, no cycles
simple: simple.1 .WAIT simple.2
# recursive: all children of the left hand side of the .WAIT
# must be made before any child of the right hand side.
recursive: recursive.1.99 .WAIT recursive.2.99
recursive.1.99: recursive.1.1.a recursive.1.1.b _ECHOUSE
recursive.2.99: recursive.2.1.a recursive.2.1.b _ECHOUSE
# shared: both shared.1.99 and shared.2.99 depend on shared.0.
# shared.0 must be made first, even though it is a child of
# the right hand side of the .WAIT.
shared: shared.1.99 .WAIT shared.2.99
shared.1.99: shared.0 _ECHOUSE
shared.2.99: shared.2.1 shared.0 _ECHOUSE
# cycle: the cyclic dependency must not cause infinite recursion
# leading to stack overflow and a crash.
cycle: cycle.1.99 .WAIT cycle.2.99
cycle.2.99: cycle.2.98 _ECHOUSE
cycle.2.98: cycle.2.97 _ECHOUSE
cycle.2.97: cycle.2.99 _ECHOUSE

View File

@ -0,0 +1,22 @@
# $Id: export,v 1.1 2007/10/05 15:27:46 sjg Exp $
UT_TEST=export
UT_FOO=foo${BAR}
UT_FU=fubar
UT_ZOO=hoopie
UT_NO=all
# belive it or not, we expect this one to come out with $UT_FU unexpanded.
UT_DOLLAR= This is $$UT_FU
.export UT_FU UT_FOO
.export UT_DOLLAR
# this one will be ignored
.export .MAKE.PID
BAR=bar is ${UT_FU}
.MAKE.EXPORTED+= UT_ZOO UT_TEST
all:
@env | grep '^UT_' | sort

View File

@ -0,0 +1,11 @@
# $Id: export-all,v 1.1 2007/10/05 15:27:46 sjg Exp $
UT_OK=good
UT_F=fine
.export
.include "export"
UT_TEST=export-all
UT_ALL=even this gets exported

View File

@ -0,0 +1,10 @@
# $Id: forsubst,v 1.1 2009/10/07 16:40:30 sjg Exp $
all: for-subst
here := ${.PARSEDIR}
# this should not run foul of the parser
.for file in ${.PARSEFILE}
for-subst: ${file:S;^;${here}/;g}
@echo ".for with :S;... OK"
.endfor

View File

@ -0,0 +1,31 @@
# $Id: moderrs,v 1.2 2006/05/11 18:48:33 sjg Exp $
#
# various modifier error tests
VAR=TheVariable
# incase we have to change it ;-)
MOD_UNKN=Z
MOD_TERM=S,V,v
MOD_S:= ${MOD_TERM},
all: modunkn modunknV varterm vartermV modtermV
modunkn:
@echo "Expect: Unknown modifier 'Z'"
@echo "VAR:Z=${VAR:Z}"
modunknV:
@echo "Expect: Unknown modifier 'Z'"
@echo "VAR:${MOD_UNKN}=${VAR:${MOD_UNKN}}"
varterm:
@echo "Expect: Unclosed variable specification for VAR"
@echo VAR:S,V,v,=${VAR:S,V,v,
vartermV:
@echo "Expect: Unclosed variable specification for VAR"
@echo VAR:${MOD_TERM},=${VAR:${MOD_S}
modtermV:
@echo "Expect: Unclosed substitution for VAR (, missing)"
-@echo "VAR:${MOD_TERM}=${VAR:${MOD_TERM}}"

View File

@ -0,0 +1,25 @@
X=a b c d e
.for x in $X
LIB${x:tu}=/tmp/lib$x.a
.endfor
X_LIBS= ${LIBA} ${LIBD} ${LIBE}
LIB?=a
var = head
res = no
.if !empty(var:M${:Uhead\:tail:C/:.*//})
res = OK
.endif
all:
@for x in $X; do ${.MAKE} -f ${MAKEFILE} show LIB=$$x; done
@echo "Mscanner=${res}"
show:
@echo 'LIB=${LIB} X_LIBS:M$${LIB$${LIB:tu}} is "${X_LIBS:M${LIB${LIB:tu}}}"'
@echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a is "${X_LIBS:M*/lib${LIB}.a}"'
@echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a:tu is "${X_LIBS:M*/lib${LIB}.a:tu}"'

View File

@ -0,0 +1,33 @@
# $Id: modmisc,v 1.4 2006/05/11 15:37:07 sjg Exp $
#
# miscellaneous modifier tests
path=:/bin:/usr/bin::/sbin:/usr/sbin:.:/home/user/bin:.
# strip cwd from path.
MOD_NODOT=S/:/ /g:N.:ts:
# and decorate, note that $'s need to be doubled. Also note that
# the modifier_variable can be used with other modifiers.
MOD_NODOTX=S/:/ /g:N.:@d@'$$d'@
# another mod - pretend it is more interesting
MOD_HOMES=S,/home/,/homes/,
MOD_OPT=@d@$${exists($$d):?$$d:$${d:S,/usr,/opt,}}@
MOD_SEP=S,:, ,g
all: modvar modvarloop
modvar:
@echo "path='${path}'"
@echo "path='${path:${MOD_NODOT}}'"
@echo "path='${path:S,home,homes,:${MOD_NODOT}}'"
@echo "path=${path:${MOD_NODOTX}:ts:}"
@echo "path=${path:${MOD_HOMES}:${MOD_NODOTX}:ts:}"
.for d in ${path:${MOD_SEP}:N.} /usr/xbin
path_$d?= ${d:${MOD_OPT}:${MOD_HOMES}}/
paths+= ${d:${MOD_OPT}:${MOD_HOMES}}
.endfor
modvarloop:
@echo "path_/usr/xbin=${path_/usr/xbin}"
@echo "paths=${paths}"
@echo "PATHS=${paths:tu}"

View File

@ -0,0 +1,22 @@
# $NetBSD: modorder,v 1.2 2007/10/05 15:27:46 sjg Exp $
LIST= one two three four five six seven eight nine ten
LISTX= ${LIST:Ox}
LISTSX:= ${LIST:Ox}
TEST_RESULT= && echo Ok || echo Failed
# unit-tests have to produce the same results on each run
# so we cannot actually include :Ox output.
all:
@echo "LIST = ${LIST}"
@echo "LIST:O = ${LIST:O}"
# Note that 1 in every 10! trials two independently generated
# randomized orderings will be the same. The test framework doesn't
# support checking probabilistic output, so we accept that the test
# will incorrectly fail with probability 2.8E-7.
@echo "LIST:Ox = `test '${LIST:Ox}' != '${LIST:Ox}' ${TEST_RESULT}`"
@echo "LIST:O:Ox = `test '${LIST:O:Ox}' != '${LIST:O:Ox}' ${TEST_RESULT}`"
@echo "LISTX = `test '${LISTX}' != '${LISTX}' ${TEST_RESULT}`"
@echo "LISTSX = `test '${LISTSX}' = '${LISTSX}' ${TEST_RESULT}`"
@echo "BADMOD 1 = ${LIST:OX}"
@echo "BADMOD 2 = ${LIST:OxXX}"

View File

@ -0,0 +1,32 @@
LIST= one two three
LIST+= four five six
FU_mod-ts = a / b / cool
AAA= a a a
B.aaa= Baaa
all: mod-ts
mod-ts:
@echo 'LIST="${LIST}"'
@echo 'LIST:ts,="${LIST:ts,}"'
@echo 'LIST:ts/:tu="${LIST:ts/:tu}"'
@echo 'LIST:ts::tu="${LIST:ts::tu}"'
@echo 'LIST:ts:tu="${LIST:ts:tu}"'
@echo 'LIST:tu:ts/="${LIST:tu:ts/}"'
@echo 'LIST:ts:="${LIST:ts:}"'
@echo 'LIST:ts="${LIST:ts}"'
@echo 'LIST:ts:S/two/2/="${LIST:ts:S/two/2/}"'
@echo 'LIST:S/two/2/:ts="${LIST:S/two/2/:ts}"'
@echo 'LIST:ts/:S/two/2/="${LIST:ts/:S/two/2/}"'
@echo "Pretend the '/' in '/n' etc. below are back-slashes."
@echo 'LIST:ts/n="${LIST:ts\n}"'
@echo 'LIST:ts/t="${LIST:ts\t}"'
@echo 'LIST:ts/012:tu="${LIST:ts\012:tu}"'
@echo 'LIST:tx="${LIST:tx}"'
@echo 'LIST:ts/x:tu="${LIST:ts\x:tu}"'
@echo 'FU_$@="${FU_${@:ts}:ts}"'
@echo 'FU_$@:ts:T="${FU_${@:ts}:ts:T}" == cool?'
@echo 'B.$${AAA:ts}="${B.${AAA:ts}}" == Baaa?'

View File

@ -0,0 +1,151 @@
# $Id: modword,v 1.1 2003/09/27 21:29:37 sjg Exp $
#
# Test behaviour of new :[] modifier
all: mod-squarebrackets mod-S-W mod-C-W mod-tW-tw
LIST= one two three
LIST+= four five six
LONGLIST= 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
EMPTY= # the space should be ignored
ESCAPEDSPACE=\ # escaped space before the '#'
REALLYSPACE:=${EMPTY:C/^/ /W}
HASH= \#
AT= @
STAR= *
ZERO= 0
ONE= 1
MINUSONE= -1
mod-squarebrackets: mod-squarebrackets-0-star-at \
mod-squarebrackets-hash \
mod-squarebrackets-n \
mod-squarebrackets-start-end \
mod-squarebrackets-nested
mod-squarebrackets-0-star-at:
@echo 'LIST:[]="${LIST:[]}" is an error'
@echo 'LIST:[0]="${LIST:[0]}"'
@echo 'LIST:[0x0]="${LIST:[0x0]}"'
@echo 'LIST:[000]="${LIST:[000]}"'
@echo 'LIST:[*]="${LIST:[*]}"'
@echo 'LIST:[@]="${LIST:[@]}"'
@echo 'LIST:[0]:C/ /,/="${LIST:[0]:C/ /,/}"'
@echo 'LIST:[0]:C/ /,/g="${LIST:[0]:C/ /,/g}"'
@echo 'LIST:[0]:C/ /,/1g="${LIST:[0]:C/ /,/1g}"'
@echo 'LIST:[*]:C/ /,/="${LIST:[*]:C/ /,/}"'
@echo 'LIST:[*]:C/ /,/g="${LIST:[*]:C/ /,/g}"'
@echo 'LIST:[*]:C/ /,/1g="${LIST:[*]:C/ /,/1g}"'
@echo 'LIST:[@]:C/ /,/="${LIST:[@]:C/ /,/}"'
@echo 'LIST:[@]:C/ /,/g="${LIST:[@]:C/ /,/g}"'
@echo 'LIST:[@]:C/ /,/1g="${LIST:[@]:C/ /,/1g}"'
@echo 'LIST:[@]:[0]:C/ /,/="${LIST:[@]:[0]:C/ /,/}"'
@echo 'LIST:[0]:[@]:C/ /,/="${LIST:[0]:[@]:C/ /,/}"'
@echo 'LIST:[@]:[*]:C/ /,/="${LIST:[@]:[*]:C/ /,/}"'
@echo 'LIST:[*]:[@]:C/ /,/="${LIST:[*]:[@]:C/ /,/}"'
mod-squarebrackets-hash:
@echo 'EMPTY="${EMPTY}"'
@echo 'EMPTY:[#]="${EMPTY:[#]}" == 1 ?'
@echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
@echo 'ESCAPEDSPACE:[#]="${ESCAPEDSPACE:[#]}" == 1 ?'
@echo 'REALLYSPACE="${REALLYSPACE}"'
@echo 'REALLYSPACE:[#]="${REALLYSPACE:[#]}" == 1 ?'
@echo 'LIST:[#]="${LIST:[#]}"'
@echo 'LIST:[0]:[#]="${LIST:[0]:[#]}" == 1 ?'
@echo 'LIST:[*]:[#]="${LIST:[*]:[#]}" == 1 ?'
@echo 'LIST:[@]:[#]="${LIST:[@]:[#]}"'
@echo 'LIST:[1]:[#]="${LIST:[1]:[#]}"'
@echo 'LIST:[1..3]:[#]="${LIST:[1..3]:[#]}"'
mod-squarebrackets-n:
@echo 'EMPTY:[1]="${EMPTY:[1]}"'
@echo 'ESCAPEDSPACE="${ESCAPEDSPACE}"'
@echo 'ESCAPEDSPACE:[1]="${ESCAPEDSPACE:[1]}"'
@echo 'REALLYSPACE="${REALLYSPACE}"'
@echo 'REALLYSPACE:[1]="${REALLYSPACE:[1]}" == "" ?'
@echo 'REALLYSPACE:[*]:[1]="${REALLYSPACE:[*]:[1]}" == " " ?'
@echo 'LIST:[1]="${LIST:[1]}"'
@echo 'LIST:[1.]="${LIST:[1.]}" is an error'
@echo 'LIST:[1].="${LIST:[1].}" is an error'
@echo 'LIST:[2]="${LIST:[2]}"'
@echo 'LIST:[6]="${LIST:[6]}"'
@echo 'LIST:[7]="${LIST:[7]}"'
@echo 'LIST:[999]="${LIST:[999]}"'
@echo 'LIST:[-]="${LIST:[-]}" is an error'
@echo 'LIST:[--]="${LIST:[--]}" is an error'
@echo 'LIST:[-1]="${LIST:[-1]}"'
@echo 'LIST:[-2]="${LIST:[-2]}"'
@echo 'LIST:[-6]="${LIST:[-6]}"'
@echo 'LIST:[-7]="${LIST:[-7]}"'
@echo 'LIST:[-999]="${LIST:[-999]}"'
@echo 'LONGLIST:[17]="${LONGLIST:[17]}"'
@echo 'LONGLIST:[0x11]="${LONGLIST:[0x11]}"'
@echo 'LONGLIST:[021]="${LONGLIST:[021]}"'
@echo 'LIST:[0]:[1]="${LIST:[0]:[1]}"'
@echo 'LIST:[*]:[1]="${LIST:[*]:[1]}"'
@echo 'LIST:[@]:[1]="${LIST:[@]:[1]}"'
@echo 'LIST:[0]:[2]="${LIST:[0]:[2]}"'
@echo 'LIST:[*]:[2]="${LIST:[*]:[2]}"'
@echo 'LIST:[@]:[2]="${LIST:[@]:[2]}"'
@echo 'LIST:[*]:C/ /,/:[2]="${LIST:[*]:C/ /,/:[2]}"'
@echo 'LIST:[*]:C/ /,/:[*]:[2]="${LIST:[*]:C/ /,/:[*]:[2]}"'
@echo 'LIST:[*]:C/ /,/:[@]:[2]="${LIST:[*]:C/ /,/:[@]:[2]}"'
mod-squarebrackets-start-end:
@echo 'LIST:[1.]="${LIST:[1.]}" is an error'
@echo 'LIST:[1..]="${LIST:[1..]}" is an error'
@echo 'LIST:[1..1]="${LIST:[1..1]}"'
@echo 'LIST:[1..1.]="${LIST:[1..1.]}" is an error'
@echo 'LIST:[1..2]="${LIST:[1..2]}"'
@echo 'LIST:[2..1]="${LIST:[2..1]}"'
@echo 'LIST:[3..-2]="${LIST:[3..-2]}"'
@echo 'LIST:[-4..4]="${LIST:[-4..4]}"'
@echo 'LIST:[0..1]="${LIST:[0..1]}" is an error'
@echo 'LIST:[-1..0]="${LIST:[-1..0]}" is an error'
@echo 'LIST:[-1..1]="${LIST:[-1..1]}"'
@echo 'LIST:[0..0]="${LIST:[0..0]}"'
@echo 'LIST:[3..99]="${LIST:[3..99]}"'
@echo 'LIST:[-3..-99]="${LIST:[-3..-99]}"'
@echo 'LIST:[-99..-3]="${LIST:[-99..-3]}"'
mod-squarebrackets-nested:
@echo 'HASH="${HASH}" == "#" ?'
@echo 'LIST:[$${HASH}]="${LIST:[${HASH}]}"'
@echo 'LIST:[$${ZERO}]="${LIST:[${ZERO}]}"'
@echo 'LIST:[$${ZERO}x$${ONE}]="${LIST:[${ZERO}x${ONE}]}"'
@echo 'LIST:[$${ONE}]="${LIST:[${ONE}]}"'
@echo 'LIST:[$${MINUSONE}]="${LIST:[${MINUSONE}]}"'
@echo 'LIST:[$${STAR}]="${LIST:[${STAR}]}"'
@echo 'LIST:[$${AT}]="${LIST:[${AT}]}"'
@echo 'LIST:[$${EMPTY}]="${LIST:[${EMPTY}]}" is an error'
@echo 'LIST:[$${LONGLIST:[21]:S/2//}]="${LIST:[${LONGLIST:[21]:S/2//}]}"'
@echo 'LIST:[$${LIST:[#]}]="${LIST:[${LIST:[#]}]}"'
@echo 'LIST:[$${LIST:[$${HASH}]}]="${LIST:[${LIST:[${HASH}]}]}"'
mod-C-W:
@echo 'LIST:C/ /,/="${LIST:C/ /,/}"'
@echo 'LIST:C/ /,/W="${LIST:C/ /,/W}"'
@echo 'LIST:C/ /,/gW="${LIST:C/ /,/gW}"'
@echo 'EMPTY:C/^/,/="${EMPTY:C/^/,/}"'
@echo 'EMPTY:C/^/,/W="${EMPTY:C/^/,/W}"'
mod-S-W:
@echo 'LIST:S/ /,/="${LIST:S/ /,/}"'
@echo 'LIST:S/ /,/W="${LIST:S/ /,/W}"'
@echo 'LIST:S/ /,/gW="${LIST:S/ /,/gW}"'
@echo 'EMPTY:S/^/,/="${EMPTY:S/^/,/}"'
@echo 'EMPTY:S/^/,/W="${EMPTY:S/^/,/W}"'
mod-tW-tw:
@echo 'LIST:tW="${LIST:tW}"'
@echo 'LIST:tw="${LIST:tw}"'
@echo 'LIST:tW:C/ /,/="${LIST:tW:C/ /,/}"'
@echo 'LIST:tW:C/ /,/g="${LIST:tW:C/ /,/g}"'
@echo 'LIST:tW:C/ /,/1g="${LIST:tW:C/ /,/1g}"'
@echo 'LIST:tw:C/ /,/="${LIST:tw:C/ /,/}"'
@echo 'LIST:tw:C/ /,/g="${LIST:tw:C/ /,/g}"'
@echo 'LIST:tw:C/ /,/1g="${LIST:tw:C/ /,/1g}"'
@echo 'LIST:tw:tW:C/ /,/="${LIST:tw:tW:C/ /,/}"'
@echo 'LIST:tW:tw:C/ /,/="${LIST:tW:tw:C/ /,/}"'

View File

@ -0,0 +1,24 @@
# $Id: posix,v 1.1 2004/05/07 08:12:16 sjg Exp $
all: x plus subs err
x:
@echo "Posix says we should execute the command as if run by system(3)"
@echo "Expect 'Hello,' and 'World!'"
@echo Hello,; false; echo "World!"
plus:
@echo a command
+@echo "a command prefixed by '+' executes even with -n"
@echo another command
subs:
@echo make -n
@${.MAKE} -f ${MAKEFILE} -n plus
@echo make -n -j1
@${.MAKE} -f ${MAKEFILE} -n -j1 plus
err:
@(echo Now we expect an error...; exit 1)
@echo "Oops! you shouldn't see this!"

View File

@ -0,0 +1,8 @@
# $Id: qequals,v 1.1 2008/03/31 00:12:21 sjg Exp $
M= i386
V.i386= OK
V.$M ?= bug
all:
@echo 'V.$M ?= ${V.$M}'

View File

@ -0,0 +1,8 @@
all:
@for x in "" A= A=42; do ${.MAKE} -f ${MAKEFILE} show $$x; done
show:
@echo "The answer is ${A:?known:unknown}"
@echo "The answer is ${A:?$A:unknown}"
@echo "The answer is ${empty(A):?empty:$A}"

View File

@ -0,0 +1,316 @@
comment testing start
this is foo
This is how a comment looks: # comment
comment testing done
make: "cond1" line 75: warning: extra else
make: "cond1" line 85: warning: extra else
2 is prime
A='other' B='unknown' C='clever' o='no,no'
Passed:
var
("var")
(var != var)
var != var
!((var != var) && defined(name))
var == quoted
1 is not prime
2 is prime
3 is prime
4 is not prime
5 is prime
make: warning: String comparison operator should be either == or !=
make: Bad conditional expression `"0" > 0' in "0" > 0?OK:No
OK
UT_DOLLAR=This is $UT_FU
UT_FOO=foobar is fubar
UT_FU=fubar
UT_TEST=export
UT_ZOO=hoopie
UT_ALL=even this gets exported
UT_DOLLAR=This is $UT_FU
UT_F=fine
UT_FOO=foobar is fubar
UT_FU=fubar
UT_NO=all
UT_OK=good
UT_TEST=export-all
UT_ZOO=hoopie
simple.1
simple.1
simple.2
simple.2
recursive.1.1.*
recursive.1.1.*
recursive.1.1.*
recursive.1.1.*
recursive.1.99
recursive.1.99
recursive.2.1.*
recursive.2.1.*
recursive.2.1.*
recursive.2.1.*
recursive.2.99
recursive.2.99
shared.0
shared.0
shared.1.99
shared.1.99
shared.2.1
shared.2.1
shared.2.99
shared.2.99
make: Graph cycles through `cycle.2.99'
make: Graph cycles through `cycle.2.98'
make: Graph cycles through `cycle.2.97'
cycle.1.99
cycle.1.99
.for with :S;... OK
Expect: Unknown modifier 'Z'
make: Unknown modifier 'Z'
VAR:Z=
Expect: Unknown modifier 'Z'
make: Unknown modifier 'Z'
VAR:Z=
Expect: Unclosed variable specification for VAR
make: Unclosed variable specification (expecting '}') for "VAR" (value "Thevariable") modifier S
VAR:S,V,v,=Thevariable
Expect: Unclosed variable specification for VAR
make: Unclosed variable specification after complex modifier (expecting '}') for VAR
VAR:S,V,v,=Thevariable
Expect: Unclosed substitution for VAR (, missing)
make: Unclosed substitution for VAR (, missing)
VAR:S,V,v=
LIB=a X_LIBS:M${LIB${LIB:tu}} is "/tmp/liba.a"
LIB=a X_LIBS:M*/lib${LIB}.a is "/tmp/liba.a"
LIB=a X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBA.A"
LIB=b X_LIBS:M${LIB${LIB:tu}} is ""
LIB=b X_LIBS:M*/lib${LIB}.a is ""
LIB=b X_LIBS:M*/lib${LIB}.a:tu is ""
LIB=c X_LIBS:M${LIB${LIB:tu}} is ""
LIB=c X_LIBS:M*/lib${LIB}.a is ""
LIB=c X_LIBS:M*/lib${LIB}.a:tu is ""
LIB=d X_LIBS:M${LIB${LIB:tu}} is "/tmp/libd.a"
LIB=d X_LIBS:M*/lib${LIB}.a is "/tmp/libd.a"
LIB=d X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBD.A"
LIB=e X_LIBS:M${LIB${LIB:tu}} is "/tmp/libe.a"
LIB=e X_LIBS:M*/lib${LIB}.a is "/tmp/libe.a"
LIB=e X_LIBS:M*/lib${LIB}.a:tu is "/TMP/LIBE.A"
Mscanner=OK
path=':/bin:/usr/bin::/sbin:/usr/sbin:.:/home/user/bin:.'
path='/bin:/usr/bin:/sbin:/usr/sbin:/home/user/bin'
path='/bin:/usr/bin:/sbin:/usr/sbin:/homes/user/bin'
path='/bin':'/usr/bin':'/sbin':'/usr/sbin':'/home/user/bin'
path='/bin':'/usr/bin':'/sbin':'/usr/sbin':'/homes/user/bin'
path_/usr/xbin=/opt/xbin/
paths=/bin /usr/bin /sbin /usr/sbin /homes/user/bin /opt/xbin
PATHS=/BIN /USR/BIN /SBIN /USR/SBIN /HOMES/USER/BIN /OPT/XBIN
LIST = one two three four five six seven eight nine ten
LIST:O = eight five four nine one seven six ten three two
LIST:Ox = Ok
LIST:O:Ox = Ok
LISTX = Ok
LISTSX = Ok
make: Bad modifier `:OX' for LIST
BADMOD 1 = }
make: Bad modifier `:OxXX' for LIST
BADMOD 2 = XX}
LIST="one two three four five six"
LIST:ts,="one,two,three,four,five,six"
LIST:ts/:tu="ONE/TWO/THREE/FOUR/FIVE/SIX"
LIST:ts::tu="ONE:TWO:THREE:FOUR:FIVE:SIX"
LIST:ts:tu="ONETWOTHREEFOURFIVESIX"
LIST:tu:ts/="ONE/TWO/THREE/FOUR/FIVE/SIX"
LIST:ts:="one:two:three:four:five:six"
LIST:ts="onetwothreefourfivesix"
LIST:ts:S/two/2/="one2threefourfivesix"
LIST:S/two/2/:ts="one2threefourfivesix"
LIST:ts/:S/two/2/="one/2/three/four/five/six"
Pretend the '/' in '/n' etc. below are back-slashes.
LIST:ts/n="one
two
three
four
five
six"
LIST:ts/t="one two three four five six"
LIST:ts/012:tu="ONE
TWO
THREE
FOUR
FIVE
SIX"
make: Bad modifier `:tx' for LIST
LIST:tx="}"
make: Bad modifier `:ts\x' for LIST
LIST:ts/x:tu="\x:tu}"
FU_mod-ts="a/b/cool"
FU_mod-ts:ts:T="cool" == cool?
B.${AAA:ts}="Baaa" == Baaa?
make: Bad modifier `:[]' for LIST
LIST:[]="" is an error
LIST:[0]="one two three four five six"
LIST:[0x0]="one two three four five six"
LIST:[000]="one two three four five six"
LIST:[*]="one two three four five six"
LIST:[@]="one two three four five six"
LIST:[0]:C/ /,/="one,two three four five six"
LIST:[0]:C/ /,/g="one,two,three,four,five,six"
LIST:[0]:C/ /,/1g="one,two,three,four,five,six"
LIST:[*]:C/ /,/="one,two three four five six"
LIST:[*]:C/ /,/g="one,two,three,four,five,six"
LIST:[*]:C/ /,/1g="one,two,three,four,five,six"
LIST:[@]:C/ /,/="one two three four five six"
LIST:[@]:C/ /,/g="one two three four five six"
LIST:[@]:C/ /,/1g="one two three four five six"
LIST:[@]:[0]:C/ /,/="one,two three four five six"
LIST:[0]:[@]:C/ /,/="one two three four five six"
LIST:[@]:[*]:C/ /,/="one,two three four five six"
LIST:[*]:[@]:C/ /,/="one two three four five six"
EMPTY=""
EMPTY:[#]="1" == 1 ?
ESCAPEDSPACE="\ "
ESCAPEDSPACE:[#]="1" == 1 ?
REALLYSPACE=" "
REALLYSPACE:[#]="1" == 1 ?
LIST:[#]="6"
LIST:[0]:[#]="1" == 1 ?
LIST:[*]:[#]="1" == 1 ?
LIST:[@]:[#]="6"
LIST:[1]:[#]="1"
LIST:[1..3]:[#]="3"
EMPTY:[1]=""
ESCAPEDSPACE="\ "
ESCAPEDSPACE:[1]="\ "
REALLYSPACE=" "
REALLYSPACE:[1]="" == "" ?
REALLYSPACE:[*]:[1]=" " == " " ?
LIST:[1]="one"
make: Bad modifier `:[1.]' for LIST
LIST:[1.]="" is an error
make: Bad modifier `:[1].' for LIST
LIST:[1].="}" is an error
LIST:[2]="two"
LIST:[6]="six"
LIST:[7]=""
LIST:[999]=""
make: Bad modifier `:[-]' for LIST
LIST:[-]="" is an error
make: Bad modifier `:[--]' for LIST
LIST:[--]="" is an error
LIST:[-1]="six"
LIST:[-2]="five"
LIST:[-6]="one"
LIST:[-7]=""
LIST:[-999]=""
LONGLIST:[17]="17"
LONGLIST:[0x11]="17"
LONGLIST:[021]="17"
LIST:[0]:[1]="one two three four five six"
LIST:[*]:[1]="one two three four five six"
LIST:[@]:[1]="one"
LIST:[0]:[2]=""
LIST:[*]:[2]=""
LIST:[@]:[2]="two"
LIST:[*]:C/ /,/:[2]=""
LIST:[*]:C/ /,/:[*]:[2]=""
LIST:[*]:C/ /,/:[@]:[2]="three"
make: Bad modifier `:[1.]' for LIST
LIST:[1.]="" is an error
make: Bad modifier `:[1..]' for LIST
LIST:[1..]="" is an error
LIST:[1..1]="one"
make: Bad modifier `:[1..1.]' for LIST
LIST:[1..1.]="" is an error
LIST:[1..2]="one two"
LIST:[2..1]="two one"
LIST:[3..-2]="three four five"
LIST:[-4..4]="three four"
make: Bad modifier `:[0..1]' for LIST
LIST:[0..1]="" is an error
make: Bad modifier `:[-1..0]' for LIST
LIST:[-1..0]="" is an error
LIST:[-1..1]="six five four three two one"
LIST:[0..0]="one two three four five six"
LIST:[3..99]="three four five six"
LIST:[-3..-99]="four three two one"
LIST:[-99..-3]="one two three four"
HASH="#" == "#" ?
LIST:[${HASH}]="6"
LIST:[${ZERO}]="one two three four five six"
LIST:[${ZERO}x${ONE}]="one"
LIST:[${ONE}]="one"
LIST:[${MINUSONE}]="six"
LIST:[${STAR}]="one two three four five six"
LIST:[${AT}]="one two three four five six"
make: Bad modifier `:[${EMPTY' for LIST
LIST:[${EMPTY}]="" is an error
LIST:[${LONGLIST:[21]:S/2//}]="one"
LIST:[${LIST:[#]}]="six"
LIST:[${LIST:[${HASH}]}]="six"
LIST:S/ /,/="one two three four five six"
LIST:S/ /,/W="one,two three four five six"
LIST:S/ /,/gW="one,two,three,four,five,six"
EMPTY:S/^/,/=","
EMPTY:S/^/,/W=","
LIST:C/ /,/="one two three four five six"
LIST:C/ /,/W="one,two three four five six"
LIST:C/ /,/gW="one,two,three,four,five,six"
EMPTY:C/^/,/=","
EMPTY:C/^/,/W=","
LIST:tW="one two three four five six"
LIST:tw="one two three four five six"
LIST:tW:C/ /,/="one,two three four five six"
LIST:tW:C/ /,/g="one,two,three,four,five,six"
LIST:tW:C/ /,/1g="one,two,three,four,five,six"
LIST:tw:C/ /,/="one two three four five six"
LIST:tw:C/ /,/g="one two three four five six"
LIST:tw:C/ /,/1g="one two three four five six"
LIST:tw:tW:C/ /,/="one,two three four five six"
LIST:tW:tw:C/ /,/="one two three four five six"
Posix says we should execute the command as if run by system(3)
Expect 'Hello,' and 'World!'
Hello,
World!
a command
a command prefixed by '+' executes even with -n
another command
make -n
echo a command
echo "a command prefixed by '+' executes even with -n"
a command prefixed by '+' executes even with -n
echo another command
make -n -j1
{ echo a command
} || exit $?
echo "a command prefixed by '+' executes even with -n"
a command prefixed by '+' executes even with -n
{ echo another command
} || exit $?
Now we expect an error...
*** Error code 1 (continuing)
`all' not remade because of errors.
V.i386 ?= OK
The answer is unknown
The answer is unknown
The answer is empty
The answer is known
The answer is
The answer is empty
The answer is known
The answer is 42
The answer is 42
UT_DOLLAR=This is $UT_FU
UT_FU=fubar
UT_TEST=unexport
UT_TEST=unexport-env
default FU=<v>fu</v> FOO=<v>foo</v> VAR=<v></v>
two FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
three FU=<v>bar</v> FOO=<v>goo</v> VAR=<v></v>
four FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v>
five FU=<v>bar</v> FOO=<v>goo</v> VAR=<v>Internal</v>
five v=is x k=is x
six v=is y k=is y
show-v v=override k=override

View File

@ -0,0 +1,8 @@
# $Id: unexport,v 1.1 2009/11/19 00:30:25 sjg Exp $
# pick up a bunch of exported vars
.include "export"
.unexport UT_ZOO UT_FOO
UT_TEST = unexport

View File

@ -0,0 +1,14 @@
# $Id: unexport-env,v 1.1 2009/11/19 00:30:25 sjg Exp $
# pick up a bunch of exported vars
.include "export"
# an example of setting up a minimal environment.
PATH = /bin:/usr/bin:/sbin:/usr/sbin
# now clobber the environment to just PATH and UT_TEST
UT_TEST = unexport-env
# this removes everything
.unexport-env
.export PATH UT_TEST

View File

@ -0,0 +1,49 @@
# $Id: varcmd,v 1.3 2008/05/14 14:27:02 sjg Exp $
#
# Test behaviour of recursive make and vars set on command line.
FU=fu
FOO?=foo
.if !empty(.TARGETS)
TAG=${.TARGETS}
.endif
TAG?=default
all: one
show:
@echo "${TAG} FU=<v>${FU}</v> FOO=<v>${FOO}</v> VAR=<v>${VAR}</v>"
one: show
@${.MAKE} -f ${MAKEFILE} FU=bar FOO=goo two
two: show
@${.MAKE} -f ${MAKEFILE} three
three: show
@${.MAKE} -f ${MAKEFILE} four
.ifmake four
VAR=Internal
.MAKEOVERRIDES+= VAR
.endif
four: show
@${.MAKE} -f ${MAKEFILE} five
M = x
V.y = is y
V.x = is x
V := ${V.$M}
K := ${V}
show-v:
@echo '${TAG} v=${V} k=${K}'
five: show show-v
@${.MAKE} -f ${MAKEFILE} M=y six
six: show-v
@${.MAKE} -f ${MAKEFILE} V=override show-v

504
commands/bmake/util.c Normal file
View File

@ -0,0 +1,504 @@
/* $NetBSD: util.c,v 1.48 2009/01/29 09:03:04 dholland Exp $ */
/*
* Missing stuff from OS's
*/
#ifndef MAKE_NATIVE
static char rcsid[] = "$NetBSD: util.c,v 1.48 2009/01/29 09:03:04 dholland Exp $";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: util.c,v 1.48 2009/01/29 09:03:04 dholland Exp $");
#endif
#endif
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
#include <time.h>
#include "make.h"
#if !defined(MAKE_NATIVE) && !defined(HAVE_STRERROR)
extern int errno, sys_nerr;
extern char *sys_errlist[];
char *
strerror(int e)
{
static char buf[100];
if (e < 0 || e >= sys_nerr) {
snprintf(buf, sizeof(buf), "Unknown error %d", e);
return buf;
}
else
return sys_errlist[e];
}
#endif
#if !defined(MAKE_NATIVE) && !defined(HAVE_SETENV)
extern char **environ;
static char *
findenv(const char *name, int *offset)
{
size_t i, len;
char *p, *q;
for (i = 0; (q = environ[i]); i++) {
char *p = strchr(q, '=');
if (p == NULL)
continue;
if (strncmp(name, q, len = p - q) == 0) {
*offset = i;
return q + len + 1;
}
}
*offset = i;
return NULL;
}
int
unsetenv(const char *name)
{
char **p;
int offset;
if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) {
errno = EINVAL;
return -1;
}
while (findenv(name, &offset)) { /* if set multiple times */
for (p = &environ[offset];; ++p)
if (!(*p = *(p + 1)))
break;
}
return 0;
}
int
setenv(const char *name, const char *value, int rewrite)
{
static char **saveenv; /* copy of previously allocated space */
char *c, **newenv;
const char *cc;
size_t l_value, size;
int offset;
if (name == NULL || value == NULL) {
errno = EINVAL;
return -1;
}
if (*value == '=') /* no `=' in value */
++value;
l_value = strlen(value);
/* find if already exists */
if ((c = findenv(name, &offset))) {
if (!rewrite)
return 0;
if (strlen(c) >= l_value) /* old larger; copy over */
goto copy;
} else { /* create new slot */
size = sizeof(char *) * (offset + 2);
if (saveenv == environ) { /* just increase size */
if ((newenv = realloc(saveenv, size)) == NULL)
return -1;
saveenv = newenv;
} else { /* get new space */
/*
* We don't free here because we don't know if
* the first allocation is valid on all OS's
*/
if ((saveenv = malloc(size)) == NULL)
return -1;
(void)memcpy(saveenv, environ, size - sizeof(char *));
}
environ = saveenv;
environ[offset + 1] = NULL;
}
for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */
continue;
size = cc - name;
/* name + `=' + value */
if ((environ[offset] = malloc(size + l_value + 2)) == NULL)
return -1;
c = environ[offset];
(void)memcpy(c, name, size);
c += size;
*c++ = '=';
copy:
(void)memcpy(c, value, l_value + 1);
return 0;
}
#ifdef TEST
int
main(int argc, char *argv[])
{
setenv(argv[1], argv[2], 0);
printf("%s\n", getenv(argv[1]));
unsetenv(argv[1]);
printf("%s\n", getenv(argv[1]));
return 0;
}
#endif
#endif
#if defined(__hpux__) || defined(__hpux)
/* strrcpy():
* Like strcpy, going backwards and returning the new pointer
*/
static char *
strrcpy(char *ptr, char *str)
{
int len = strlen(str);
while (len)
*--ptr = str[--len];
return (ptr);
} /* end strrcpy */
char *sys_siglist[] = {
"Signal 0",
"Hangup", /* SIGHUP */
"Interrupt", /* SIGINT */
"Quit", /* SIGQUIT */
"Illegal instruction", /* SIGILL */
"Trace/BPT trap", /* SIGTRAP */
"IOT trap", /* SIGIOT */
"EMT trap", /* SIGEMT */
"Floating point exception", /* SIGFPE */
"Killed", /* SIGKILL */
"Bus error", /* SIGBUS */
"Segmentation fault", /* SIGSEGV */
"Bad system call", /* SIGSYS */
"Broken pipe", /* SIGPIPE */
"Alarm clock", /* SIGALRM */
"Terminated", /* SIGTERM */
"User defined signal 1", /* SIGUSR1 */
"User defined signal 2", /* SIGUSR2 */
"Child exited", /* SIGCLD */
"Power-fail restart", /* SIGPWR */
"Virtual timer expired", /* SIGVTALRM */
"Profiling timer expired", /* SIGPROF */
"I/O possible", /* SIGIO */
"Window size changes", /* SIGWINDOW */
"Stopped (signal)", /* SIGSTOP */
"Stopped", /* SIGTSTP */
"Continued", /* SIGCONT */
"Stopped (tty input)", /* SIGTTIN */
"Stopped (tty output)", /* SIGTTOU */
"Urgent I/O condition", /* SIGURG */
"Remote lock lost (NFS)", /* SIGLOST */
"Signal 31", /* reserved */
"DIL signal" /* SIGDIL */
};
#endif /* __hpux__ || __hpux */
#if defined(__hpux__) || defined(__hpux)
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/time.h>
#include <unistd.h>
int
killpg(int pid, int sig)
{
return kill(-pid, sig);
}
#if !defined(__hpux__) && !defined(__hpux)
void
srandom(long seed)
{
srand48(seed);
}
long
random(void)
{
return lrand48();
}
#endif
/* turn into bsd signals */
void (*
signal(int s, void (*a)(int)))(int)
{
struct sigvec osv, sv;
(void)sigvector(s, NULL, &osv);
sv = osv;
sv.sv_handler = a;
#ifdef SV_BSDSIG
sv.sv_flags = SV_BSDSIG;
#endif
if (sigvector(s, &sv, NULL) == -1)
return (BADSIG);
return (osv.sv_handler);
}
#if !defined(__hpux__) && !defined(__hpux)
int
utimes(char *file, struct timeval tvp[2])
{
struct utimbuf t;
t.actime = tvp[0].tv_sec;
t.modtime = tvp[1].tv_sec;
return(utime(file, &t));
}
#endif
#if !defined(BSD) && !defined(d_fileno)
# define d_fileno d_ino
#endif
#ifndef DEV_DEV_COMPARE
# define DEV_DEV_COMPARE(a, b) ((a) == (b))
#endif
#define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
#define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
char *
getwd(char *pathname)
{
DIR *dp;
struct dirent *d;
extern int errno;
struct stat st_root, st_cur, st_next, st_dotdot;
char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
char *pathptr, *nextpathptr, *cur_name_add;
/* find the inode of root */
if (stat("/", &st_root) == -1) {
(void)sprintf(pathname,
"getwd: Cannot stat \"/\" (%s)", strerror(errno));
return NULL;
}
pathbuf[MAXPATHLEN - 1] = '\0';
pathptr = &pathbuf[MAXPATHLEN - 1];
nextpathbuf[MAXPATHLEN - 1] = '\0';
cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
/* find the inode of the current directory */
if (lstat(".", &st_cur) == -1) {
(void)sprintf(pathname,
"getwd: Cannot stat \".\" (%s)", strerror(errno));
return NULL;
}
nextpathptr = strrcpy(nextpathptr, "../");
/* Descend to root */
for (;;) {
/* look if we found root yet */
if (st_cur.st_ino == st_root.st_ino &&
DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
(void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
return (pathname);
}
/* open the parent directory */
if (stat(nextpathptr, &st_dotdot) == -1) {
(void)sprintf(pathname,
"getwd: Cannot stat directory \"%s\" (%s)",
nextpathptr, strerror(errno));
return NULL;
}
if ((dp = opendir(nextpathptr)) == NULL) {
(void)sprintf(pathname,
"getwd: Cannot open directory \"%s\" (%s)",
nextpathptr, strerror(errno));
return NULL;
}
/* look in the parent for the entry with the same inode */
if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
/* Parent has same device. No need to stat every member */
for (d = readdir(dp); d != NULL; d = readdir(dp))
if (d->d_fileno == st_cur.st_ino)
break;
}
else {
/*
* Parent has a different device. This is a mount point so we
* need to stat every member
*/
for (d = readdir(dp); d != NULL; d = readdir(dp)) {
if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
continue;
(void)strcpy(cur_name_add, d->d_name);
if (lstat(nextpathptr, &st_next) == -1) {
(void)sprintf(pathname,
"getwd: Cannot stat \"%s\" (%s)",
d->d_name, strerror(errno));
(void)closedir(dp);
return NULL;
}
/* check if we found it yet */
if (st_next.st_ino == st_cur.st_ino &&
DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
break;
}
}
if (d == NULL) {
(void)sprintf(pathname,
"getwd: Cannot find \".\" in \"..\"");
(void)closedir(dp);
return NULL;
}
st_cur = st_dotdot;
pathptr = strrcpy(pathptr, d->d_name);
pathptr = strrcpy(pathptr, "/");
nextpathptr = strrcpy(nextpathptr, "../");
(void)closedir(dp);
*cur_name_add = '\0';
}
} /* end getwd */
#endif /* __hpux */
#if defined(sun) && defined(__svr4__)
#include <signal.h>
/* turn into bsd signals */
void (*
signal(int s, void (*a)(int)))(int)
{
struct sigaction sa, osa;
sa.sa_handler = a;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(s, &sa, &osa) == -1)
return SIG_ERR;
else
return osa.sa_handler;
}
#endif
#if !defined(MAKE_NATIVE) && !defined(HAVE_VSNPRINTF)
#include <stdarg.h>
#if !defined(__osf__)
#ifdef _IOSTRG
#define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */
#else
#if 0
#define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */
#endif
#endif /* _IOSTRG */
#endif /* __osf__ */
int
vsnprintf(char *s, size_t n, const char *fmt, va_list args)
{
#ifdef STRFLAG
FILE fakebuf;
fakebuf._flag = STRFLAG;
/*
* Some os's are char * _ptr, others are unsigned char *_ptr...
* We cast to void * to make everyone happy.
*/
fakebuf._ptr = (void *)s;
fakebuf._cnt = n-1;
fakebuf._file = -1;
_doprnt(fmt, args, &fakebuf);
fakebuf._cnt++;
putc('\0', &fakebuf);
if (fakebuf._cnt<0)
fakebuf._cnt = 0;
return (n-fakebuf._cnt-1);
#else
(void)vsprintf(s, fmt, args);
return strlen(s);
#endif
}
int
snprintf(char *s, size_t n, const char *fmt, ...)
{
va_list ap;
int rv;
va_start(ap, fmt);
rv = vsnprintf(s, n, fmt, ap);
va_end(ap);
return rv;
}
#if !defined(MAKE_NATIVE) && !defined(HAVE_STRFTIME)
size_t
strftime(char *buf, size_t len, const char *fmt, const struct tm *tm)
{
static char months[][4] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
size_t s;
char *b = buf;
while (*fmt) {
if (len == 0)
return buf - b;
if (*fmt != '%') {
*buf++ = *fmt++;
len--;
continue;
}
switch (*fmt++) {
case '%':
*buf++ = '%';
len--;
if (len == 0) return buf - b;
/*FALLTHROUGH*/
case '\0':
*buf = '%';
s = 1;
break;
case 'k':
s = snprintf(buf, len, "%d", tm->tm_hour);
break;
case 'M':
s = snprintf(buf, len, "%02d", tm->tm_min);
break;
case 'S':
s = snprintf(buf, len, "%02d", tm->tm_sec);
break;
case 'b':
if (tm->tm_mon >= 12)
return buf - b;
s = snprintf(buf, len, "%s", months[tm->tm_mon]);
break;
case 'd':
s = snprintf(buf, len, "%02d", tm->tm_mday);
break;
case 'Y':
s = snprintf(buf, len, "%d", 1900 + tm->tm_year);
break;
default:
s = snprintf(buf, len, "Unsupported format %c",
fmt[-1]);
break;
}
buf += s;
len -= s;
}
}
#endif
#endif

3985
commands/bmake/var.c Normal file

File diff suppressed because it is too large Load Diff

223
etc/mk/sys.mk Normal file
View File

@ -0,0 +1,223 @@
# $NetBSD: sys.mk,v 1.99 2008/09/07 15:54:52 kent Exp $
# @(#)sys.mk 8.2 (Berkeley) 3/21/94
unix?= We run MINIX.
.SUFFIXES: .a .o .ln .s .S .c .cc .cpp .cxx .C .f .F .r .p .l .y #.sh
.LIBS: .a
AR?= ar
ARFLAGS?= rl
RANLIB?= ranlib
AS?= as
AFLAGS?=
COMPILE.s?= ${CC} ${AFLAGS} -c
LINK.s?= ${CC} ${AFLAGS} ${LDFLAGS}
COMPILE.S?= ${CC} ${AFLAGS} ${CPPFLAGS} -c -traditional-cpp
LINK.S?= ${CC} ${AFLAGS} ${CPPFLAGS} ${LDFLAGS}
CC?= cc
.if ${MACHINE_ARCH} == "alpha" || \
${MACHINE_ARCH} == "arm" || \
${MACHINE_ARCH} == "x86_64" || \
${MACHINE_ARCH} == "armeb" || \
${MACHINE_ARCH} == "hppa" || \
${MACHINE_ARCH} == "i386" || \
${MACHINE_ARCH} == "m68k" || \
${MACHINE_ARCH} == "mipsel" || ${MACHINE_ARCH} == "mipseb" || \
${MACHINE_ARCH} == "mips64el" || ${MACHINE_ARCH} == "mips64eb" || \
${MACHINE_ARCH} == "powerpc" || \
${MACHINE_ARCH} == "sparc" || \
${MACHINE_ARCH} == "sparc64"
DBG?= -O2
.elif ${MACHINE_ARCH} == "sh3el" || ${MACHINE_ARCH} == "sh3eb"
# -O2 is too -falign-* zealous for low-memory sh3 machines
DBG?= -Os -freorder-blocks
.elif ${MACHINE_ARCH} == "vax"
DBG?= -O1 -fgcse -fstrength-reduce -fgcse-after-reload
.elif ${MACHINE_ARCH} == "m68000"
# see src/doc/HACKS for details
DBG?= -O1
.else
DBG?= -O
.endif
CFLAGS?= ${DBG}
LDFLAGS?=
COMPILE.c?= ${CC} ${CFLAGS} ${CPPFLAGS} -c
LINK.c?= ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}
CXX?= c++
CXXFLAGS?= ${CFLAGS:N-Wno-traditional:N-Wstrict-prototypes:N-Wmissing-prototypes:N-Wno-pointer-sign:N-ffreestanding:N-std=gnu99}
__ALLSRC1= ${empty(DESTDIR):?${.ALLSRC}:${.ALLSRC:S|^${DESTDIR}|^destdir|}}
__ALLSRC2= ${empty(MAKEOBJDIR):?${__ALLSRC1}:${__ALLSRC1:S|^${MAKEOBJDIR}|^obj|}}
__ALLSRC3= ${empty(NETBSDSRCDIR):?${__ALLSRC2}:${__ALLSRC2:S|^${NETBSDSRCDIR}|^src|}}
_CXXSEED?= ${BUILDSEED:D-frandom-seed=${BUILDSEED:Q}/${__ALLSRC3:O:Q}/${.TARGET:Q}}
COMPILE.cc?= ${CXX} ${_CXXSEED} ${CXXFLAGS} ${CPPFLAGS} -c
LINK.cc?= ${CXX} ${CXXFLAGS} ${CPPFLAGS} ${LDFLAGS}
OBJC?= ${CC}
OBJCFLAGS?= ${CFLAGS}
COMPILE.m?= ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} -c
LINK.m?= ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} ${LDFLAGS}
CPP?= cpp
CPPFLAGS?=
FC?= f77
FFLAGS?= -O
RFLAGS?=
COMPILE.f?= ${FC} ${FFLAGS} -c
LINK.f?= ${FC} ${FFLAGS} ${LDFLAGS}
COMPILE.F?= ${FC} ${FFLAGS} ${CPPFLAGS} -c
LINK.F?= ${FC} ${FFLAGS} ${CPPFLAGS} ${LDFLAGS}
COMPILE.r?= ${FC} ${FFLAGS} ${RFLAGS} -c
LINK.r?= ${FC} ${FFLAGS} ${RFLAGS} ${LDFLAGS}
INSTALL?= install
LD?= ld
LEX?= lex
LFLAGS?=
LEX.l?= ${LEX} ${LFLAGS}
LINT?= lint
LINTFLAGS?= -chapbxzFS
LORDER?= lorder
MAKE?= make
NM?= nm
PC?= pc
PFLAGS?=
COMPILE.p?= ${PC} ${PFLAGS} ${CPPFLAGS} -c
LINK.p?= ${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
SHELL?= sh
SIZE?= size
TSORT?= tsort -q
YACC?= yacc
YFLAGS?=
YACC.y?= ${YACC} ${YFLAGS}
# C
.c:
${LINK.c} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
.c.o:
${COMPILE.c} ${.IMPSRC}
.c.a:
${COMPILE.c} ${.IMPSRC}
${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o
rm -f ${.PREFIX}.o
.c.ln:
${LINT} ${LINTFLAGS} \
${CPPFLAGS:C/-([IDU])[ ]*/-\1/Wg:M-[IDU]*} \
-i ${.IMPSRC}
# C++
.cc .cpp .cxx .C:
${LINK.cc} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
.cc.o .cpp.o .cxx.o .C.o:
${COMPILE.cc} ${.IMPSRC}
.cc.a .cpp.a .cxx.a .C.a:
${COMPILE.cc} ${.IMPSRC}
${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o
rm -f ${.PREFIX}.o
# Fortran/Ratfor
.f:
${LINK.f} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
.f.o:
${COMPILE.f} ${.IMPSRC}
.f.a:
${COMPILE.f} ${.IMPSRC}
${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o
rm -f ${.PREFIX}.o
.F:
${LINK.F} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
.F.o:
${COMPILE.F} ${.IMPSRC}
.F.a:
${COMPILE.F} ${.IMPSRC}
${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o
rm -f ${.PREFIX}.o
.r:
${LINK.r} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
.r.o:
${COMPILE.r} ${.IMPSRC}
.r.a:
${COMPILE.r} ${.IMPSRC}
${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o
rm -f ${.PREFIX}.o
# Pascal
.p:
${LINK.p} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
.p.o:
${COMPILE.p} ${.IMPSRC}
.p.a:
${COMPILE.p} ${.IMPSRC}
${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o
rm -f ${.PREFIX}.o
# Assembly
.s:
${LINK.s} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
.s.o:
${COMPILE.s} ${.IMPSRC}
.s.a:
${COMPILE.s} ${.IMPSRC}
${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o
rm -f ${.PREFIX}.o
.S:
${LINK.S} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
.S.o:
${COMPILE.S} ${.IMPSRC}
.S.a:
${COMPILE.S} ${.IMPSRC}
${AR} ${ARFLAGS} ${.TARGET} ${.PREFIX}.o
rm -f ${.PREFIX}.o
# Lex
.l:
${LEX.l} ${.IMPSRC}
${LINK.c} -o ${.TARGET} lex.yy.c ${LDLIBS} -ll
rm -f lex.yy.c
.l.c:
${LEX.l} ${.IMPSRC}
mv lex.yy.c ${.TARGET}
.l.o:
${LEX.l} ${.IMPSRC}
${COMPILE.c} -o ${.TARGET} lex.yy.c
rm -f lex.yy.c
# Yacc
.y:
${YACC.y} ${.IMPSRC}
${LINK.c} -o ${.TARGET} y.tab.c ${LDLIBS}
rm -f y.tab.c
.y.c:
${YACC.y} ${.IMPSRC}
mv y.tab.c ${.TARGET}
.y.o:
${YACC.y} ${.IMPSRC}
${COMPILE.c} -o ${.TARGET} y.tab.c
rm -f y.tab.c
# Shell
# .sh:
# rm -f ${.TARGET}
# cp ${.IMPSRC} ${.TARGET}
# chmod a+x ${.TARGET}

65
include/ar.h Normal file
View File

@ -0,0 +1,65 @@
/* $NetBSD: ar.h,v 1.5 2003/08/07 09:44:09 agc Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* This code is derived from software contributed to Berkeley by
* Hugh Smith at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ar.h 8.2 (Berkeley) 1/21/94
*/
#ifndef _AR_H_
#define _AR_H_
/* Pre-4BSD archives had these magic numbers in them. */
#define OARMAG1 0177555
#define OARMAG2 0177545
#define ARMAG "!<arch>\n" /* ar "magic number" */
#define SARMAG 8 /* strlen(ARMAG); */
#define AR_EFMT1 "#1/" /* extended format #1 */
struct ar_hdr {
char ar_name[16]; /* name */
char ar_date[12]; /* modification time */
char ar_uid[6]; /* user id */
char ar_gid[6]; /* group id */
char ar_mode[8]; /* octal file permissions */
char ar_size[10]; /* size in bytes */
#define ARFMAG "`\n"
char ar_fmag[2]; /* consistency check */
};
#endif /* !_AR_H_ */

View File

@ -1,10 +1,14 @@
#ifndef __SYS_PARAM_H__
#define __SYS_PARAM_H__
/*
sys/param.h
*/
#ifndef __SYS_PARAM_H__
#define __SYS_PARAM_H__
#include <limits.h>
#define MAXHOSTNAMELEN 256 /* max hostname size */
#define NGROUPS 8 /* max number of supplementary groups */
#define MAXPATHLEN PATH_MAX
#endif /* __SYS_PARAM_H__ */