Remove old fmake. It wasn't built by default for some time. Users that

really need it can find it in the devel/fmake port or pkg install fmake.
Note: This commit is orthogonal to the question 'can we fmake buildworld'.

Differential Revision: https://reviews.freebsd.org/D2840
This commit is contained in:
Warner Losh 2015-06-16 20:58:33 +00:00
parent 708694f704
commit 32c88b5252
48 changed files with 4 additions and 23953 deletions

View File

@ -31,6 +31,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20150616:
FreeBSD's old make (fmake) has been removed from the system. It is
available as the devel/fmake port or via pkg install fmake.
20150615:
The fix for the issue described in the 20150614 sendmail entry
below has been been committed in revision 284436. The work

View File

@ -179,7 +179,6 @@ __DEFAULT_NO_OPTIONS = \
BSD_GREP \
CLANG_EXTRAS \
EISA \
FMAKE \
HESIOD \
LLDB \
NAND \

View File

@ -253,10 +253,6 @@ SUBDIR+= file
SUBDIR+= finger
.endif
.if ${MK_FMAKE} != "no"
SUBDIR+= make
.endif
.if ${MK_FTP} != "no"
SUBDIR+= ftp
.endif

View File

@ -1,224 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef GNode_h_39503bf2
#define GNode_h_39503bf2
#include "lst.h"
#include "util.h"
struct Suff;
/*
* The structure for an individual graph node. Each node has several
* pieces of data associated with it.
*/
typedef struct GNode {
char *name; /* The target's name */
char *path; /* The full pathname of the target file */
/*
* The type of operator used to define the sources (qv. parse.c)
*
* 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...
*/
int type;
#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 recurrsive 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_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 */
/* 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 */
/*
* 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)
int order; /* Its wait weight */
Boolean make; /* TRUE if this target needs to be remade */
/* Set to reflect the state of processing on this node */
enum {
UNMADE, /* Not examined yet */
/*
* Target is already being made. Indicates a cycle in the graph.
* (compat mode only)
*/
BEINGMADE,
MADE, /* Was out-of-date and has been made */
UPTODATE, /* Was already up-to-date */
/*
* An error occurred while it was being
* made (used only in compat mode)
*/
ERROR,
/*
* The target was aborted due to an
* error making an inferior (compat).
*/
ABORTED,
/*
* Marked as potentially being part of a graph cycle. If we
* come back to a node marked this way, it is printed and
* 'made' is changed to ENDCYCLE.
*/
CYCLE,
/*
* The cycle has been completely printed. Go back and
* unmark all its members.
*/
ENDCYCLE
} made;
/* TRUE if one of this target's children was made */
Boolean childMade;
int unmade; /* The number of unmade children */
int mtime; /* Its modification time */
int cmtime; /* Modification time of its youngest child */
struct GNode *cmtime_gn;/* Youngest child */
/*
* Links to parents for which this is an implied source, if any. (nodes
* that depend on this, as gleaned from the transformation rules.
*/
Lst iParents;
/* List of nodes of the same name created by the :: operator */
Lst cohorts;
/* Lst of nodes for which this is a source (that depend on this one) */
Lst parents;
/* List of nodes on which this depends */
Lst children;
/*
* 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.
*/
Lst successors;
/*
* List of nodes that must be made (if they're made) before this node
* can be, but that do no enter into the datedness of this node.
*/
Lst preds;
/*
* List of ``local'' variables that are specific to this target
* and this target only (qv. var.c [$@ $< $?, etc.])
*/
Lst context;
/*
* List of strings that are commands to be given to a shell
* to create this target.
*/
Lst commands;
/* current command executing in compat mode */
LstNode *compat_command;
/*
* Suffix for the node (determined by Suff_FindDeps and opaque to
* everyone but the Suff module)
*/
struct Suff *suffix;
} GNode;
#endif /* GNode_h_39503bf2 */

View File

@ -1,120 +0,0 @@
# @(#)Makefile 5.2 (Berkeley) 12/28/90
# $Id: Makefile,v 1.6 1994/06/30 05:33:39 cgd Exp $
# $FreeBSD$
.include <src.opts.mk>
PROG= make
CFLAGS+=-I${.CURDIR}
SRCS= arch.c buf.c cond.c dir.c for.c hash.c hash_tables.c job.c \
lst.c main.c make.c parse.c proc.c shell.c str.c suff.c targ.c \
util.c var.c
.if !defined(MK_SHARED_TOOLCHAIN) || ${MK_SHARED_TOOLCHAIN} == "no"
NO_SHARED?= YES
.endif
# Version has the RYYYYMMDDX format, where R is from RELENG_<R>
CFLAGS+=-DMAKE_VERSION=\"10201205300\"
# There is no obvious performance improvement currently.
# CFLAGS+=-DUSE_KQUEUE
# Make object files which depend on preprocessor symbols defined in
# the Makefile which are not compilation options but rather configuration
# options dependend on the Makefile. main.c needs MAKE_VERSION while
# shell.c uses DEFSHELLNAME. This will cause recompilation in the case
# the definition is changed in the makefile. It will of course not cause
# recompilation if one does 'make MAKE_SHELL=csh'.
main.o shell.o: ${MAKEFILE}
# Directive and keyword tables. We use hash tables. These hash tables have been
# generated with mph (ports/devel/mph)
# If you change the directives or keywords (adding, deleting, reordering) you
# need to create new tables and hash functions (directive_hash, keyword_hash).
#
# The following changes have been made to the generated code:
#
# o prefix the names of the g, T0 and T1 arrays with 'directive_'
# resp. 'keyword_'.
#
# o make the type of the tables 'const [un]signed char' (if you change
# anything make sure that the numbers fit into a char).
#
# o make the hash function use the length for termination,
# not the trailing '\0', via the -l flag in emitc and some editing
# (only for directive_hash).
LOCALBASE ?= /usr/local
MPH ?= ${LOCALBASE}/bin/mph
EMITC ?= ${LOCALBASE}/bin/emitc
.PRECIOUS: hash
hash:
( echo '/*' ; \
echo ' * DO NOT EDIT' ; \
echo ' * $$''FreeBSD$$' ; \
echo -n ' * auto-generated from ' ; \
sed -nEe '/\$$FreeBSD/s/^.*\$$(.*)\$$.*$$/\1/p' \
${.CURDIR}/parse.c ; \
echo ' * DO NOT EDIT' ; \
echo ' */' ; \
echo '#include <sys/types.h>' ; \
echo ; \
echo '#include "hash_tables.h"' ; \
echo ; \
cat ${.CURDIR}/parse.c | sed \
-e '1,/DIRECTIVES-START-TAG/d' \
-e '/DIRECTIVES-END-TAG/,$$d' \
-e 's/^[^"]*"\([^"]*\)".*$$/\1/' | \
${MPH} -d2 -m1 | ${EMITC} -l -s | \
sed \
-e 's/^static int g\[\]/static const signed char directive_g[]/' \
-e 's/^static int T0\[\]/static const u_char directive_T0[]/' \
-e 's/^static int T1\[\]/static const u_char directive_T1[]/' \
-e '/^#define uchar unsigned char/d' \
-e 's/uchar/u_char/g' \
-e 's/^hash(/directive_hash(/' \
-e 's/; \*kp;/; kp < key + len;/' \
-e 's/int len)/size_t len)/' \
-e 's/= T0\[/= directive_T0\[/' \
-e 's/= T1\[/= directive_T1\[/' \
-e 's/g\[f/directive_g[f/g' ; \
cat ${.CURDIR}/parse.c | sed \
-e '1,/KEYWORD-START-TAG/d' \
-e '/KEYWORD-END-TAG/,$$d' \
-e 's/^[^"]*"\([^"]*\)".*$$/\1/' | \
${MPH} -d2 -m1 | ${EMITC} -l -s | \
sed \
-e 's/^static int g\[\]/static const signed char keyword_g[]/' \
-e 's/^static int T0\[\]/static const u_char keyword_T0[]/' \
-e 's/^static int T1\[\]/static const u_char keyword_T1[]/' \
-e '/^#define uchar unsigned char/d' \
-e 's/uchar/u_char/g' \
-e 's/^hash(/keyword_hash(/' \
-e 's/int len)/size_t len)/' \
-e 's/= T0\[/= keyword_T0\[/' \
-e 's/= T1\[/= keyword_T1\[/' \
-e 's/g\[f/keyword_g[f/g' \
) > ${.CURDIR}/hash_tables.c
# Set the shell which make(1) uses. Bourne is the default, but a decent
# Korn shell works fine, and much faster. Using the C shell for this
# will almost certainly break everything, but it's Unix tradition to
# allow you to shoot yourself in the foot if you want to :-)
MAKE_SHELL?= sh
.if ${MAKE_SHELL} == "csh" || ${MAKE_SHELL} == "sh" || ${MAKE_SHELL} == "ksh"
CFLAGS+= -DDEFSHELLNAME=\"${MAKE_SHELL}\"
.else
.error "MAKE_SHELL must be set to one of \"csh\", \"sh\" or \"ksh\"."
.endif
# if we are here we don't want this called 'make'
PROG= fmake
CLEANFILES+= fmake.1
fmake.1: make.1
${CP} ${.ALLSRC} ${.TARGET}
.include <bsd.prog.mk>

View File

@ -1,19 +0,0 @@
# $FreeBSD$
# Autogenerated - do NOT edit!
DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
DEP_MACHINE := ${.PARSEFILE:E}
DIRDEPS = \
include \
include/xlocale \
lib/${CSU_DIR} \
lib/libc \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif

View File

@ -1,10 +0,0 @@
# $FreeBSD$
# a simple makefile to help builds on !FreeBSD systems
pmake:
@echo 'make started.'
cc -D__dead2="" -D__unused="" -Darc4random=random -D__FBSDID="static const char *id=" -DDEFSHELLNAME=\"sh\" -I. -c *.c
cc *.o -o pmake
@echo 'make completed.'
clean:
@rm -f *.o pmake

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef arch_h_488adf7a
#define arch_h_488adf7a
#include "util.h"
struct GNode;
struct Lst;
struct Path;
/* archive errors are fatal */
extern Boolean arch_fatal;
Boolean Arch_ParseArchive(char **, struct Lst *, struct GNode *);
void Arch_Touch(struct GNode *);
void Arch_TouchLib(struct GNode *);
int Arch_MTime(struct GNode *);
int Arch_MemMTime(struct GNode *);
void Arch_FindLib(struct GNode *, struct Path *);
Boolean Arch_LibOODate(struct GNode *);
#endif /* arch_h_488adf7a */

View File

@ -1,291 +0,0 @@
/*-
* Copyright (c) 2005 Max Okumoto
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)buf.c 8.1 (Berkeley) 6/6/93
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* buf.c
* Functions for automatically-expanded buffers.
*/
#include <string.h>
#include <stdlib.h>
#include "buf.h"
#include "util.h"
/**
* Returns the number of bytes in the buffer. Doesn't include the
* null-terminating byte.
*/
size_t
Buf_Size(const Buffer *buf)
{
return (buf->end - buf->buf);
}
/**
* Returns a reference to the data contained in the buffer.
*
* @note Adding data to the Buffer object may invalidate the reference.
*/
char *
Buf_Data(const Buffer *bp)
{
return (bp->buf);
}
/**
* Expand the buffer to hold the number of additional bytes, plus
* space to store a terminating NULL byte.
*/
static inline void
BufExpand(Buffer *bp, size_t nb)
{
size_t len = Buf_Size(bp);
size_t size;
if (bp->size < len + nb + 1) {
size = bp->size + MAX(nb + 1, BUF_ADD_INC);
bp->size = size;
bp->buf = erealloc(bp->buf, size);
bp->end = bp->buf + len;
}
}
/**
* Add a single byte to the buffer.
*/
void
Buf_AddByte(Buffer *bp, Byte byte)
{
BufExpand(bp, 1);
*bp->end = byte;
bp->end++;
*bp->end = '\0';
}
/**
* Add bytes to the buffer.
*/
void
Buf_AddBytes(Buffer *bp, size_t len, const Byte *bytes)
{
BufExpand(bp, len);
memcpy(bp->end, bytes, len);
bp->end += len;
*bp->end = '\0';
}
/**
* Get a reference to the internal buffer.
*
* len:
* Pointer to where we return the number of bytes in the internal buffer.
*
* Returns:
* return A pointer to the data.
*/
Byte *
Buf_GetAll(Buffer *bp, size_t *len)
{
if (len != NULL)
*len = Buf_Size(bp);
return (bp->buf);
}
/**
* Get the contents of a buffer and destroy the buffer. If the buffer
* is NULL, return NULL.
*
* Returns:
* the pointer to the data.
*/
char *
Buf_Peel(Buffer *bp)
{
char *ret;
if (bp == NULL)
return (NULL);
ret = bp->buf;
free(bp);
return (ret);
}
/**
* Initialize a buffer. If no initial size is given, a reasonable
* default is used.
*
* Returns:
* A buffer object to be given to other functions in this library.
*
* Side Effects:
* Space is allocated for the Buffer object and a internal buffer.
*/
Buffer *
Buf_Init(size_t size)
{
Buffer *bp; /* New Buffer */
if (size <= 0)
size = BUF_DEF_SIZE;
bp = emalloc(sizeof(*bp));
bp->size = size;
bp->buf = emalloc(size);
bp->end = bp->buf;
*bp->end = '\0';
return (bp);
}
/**
* Destroy a buffer, and optionally free its data, too.
*
* Side Effects:
* Space for the Buffer object and possibly the internal buffer
* is de-allocated.
*/
void
Buf_Destroy(Buffer *buf, Boolean freeData)
{
if (freeData)
free(buf->buf);
free(buf);
}
/**
* Replace the last byte in a buffer. If the buffer was empty
* initially, then a new byte will be added.
*/
void
Buf_ReplaceLastByte(Buffer *bp, Byte byte)
{
if (bp->end == bp->buf) {
Buf_AddByte(bp, byte);
} else {
*(bp->end - 1) = byte;
}
}
/**
* Append characters in str to Buffer object
*/
void
Buf_Append(Buffer *bp, const char str[])
{
Buf_AddBytes(bp, strlen(str), str);
}
/**
* Append characters in buf to Buffer object
*/
void
Buf_AppendBuf(Buffer *bp, const Buffer *buf)
{
Buf_AddBytes(bp, Buf_Size(buf), buf->buf);
}
/**
* Append characters between str and end to Buffer object.
*/
void
Buf_AppendRange(Buffer *bp, const char str[], const char *end)
{
Buf_AddBytes(bp, end - str, str);
}
/**
* Convert newlines in buffer to spaces. The trailing newline is
* removed.
*/
void
Buf_StripNewlines(Buffer *bp)
{
char *ptr = bp->end;
/*
* If there is anything in the buffer, remove the last
* newline character.
*/
if (ptr != bp->buf) {
if (*(ptr - 1) == '\n') {
/* shorten buffer */
*(ptr - 1) = '\0';
--bp->end;
}
--ptr;
}
/* Convert newline characters to a space characters. */
while (ptr != bp->buf) {
if (*ptr == '\n') {
*ptr = ' ';
}
--ptr;
}
}
/**
* Clear the contents of the buffer.
*/
void
Buf_Clear(Buffer *bp)
{
bp->end = bp->buf;
*bp->end = '\0';
}

View File

@ -1,92 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)buf.h 8.2 (Berkeley) 4/28/95
* $FreeBSD$
*/
#ifndef buf_h_a61a6812
#define buf_h_a61a6812
/*-
* buf.h --
* Header for users of the buf library.
*/
#include <sys/types.h>
#include "util.h"
/*
* There are several places where expandable buffers are used (parse.c and
* var.c). This constant is merely the starting point for those buffers. If
* lines tend to be much shorter than this, it would be best to reduce BSIZE.
* If longer, it should be increased. Reducing it will cause more copying to
* be done for longer lines, but will save space for shorter ones. In any
* case, it ought to be a power of two simply because most storage allocation
* schemes allocate in powers of two.
*/
#define MAKE_BSIZE 256 /* starting size for expandable buffers */
#define BUF_DEF_SIZE 256 /* Default buffer size */
#define BUF_ADD_INC 256 /* Expansion increment when Adding */
typedef char Byte;
typedef struct Buffer {
size_t size; /* Current size of the buffer */
Byte *buf; /* The buffer itself */
Byte *end; /* Place to write to */
} Buffer;
void Buf_AddByte(Buffer *, Byte);
void Buf_AddBytes(Buffer *, size_t, const Byte *);
void Buf_Append(Buffer *, const char []);
void Buf_AppendBuf(Buffer *, const Buffer *);
void Buf_AppendRange(Buffer *, const char [], const char *);
void Buf_Clear(Buffer *);
char *Buf_Data(const Buffer *);
void Buf_Destroy(Buffer *, Boolean);
Byte *Buf_GetAll(Buffer *, size_t *);
Buffer *Buf_Init(size_t);
char *Buf_Peel(Buffer *);
void Buf_ReplaceLastByte(Buffer *, Byte);
size_t Buf_Size(const Buffer *);
void Buf_StripNewlines(Buffer *);
#endif /* buf_h_a61a6812 */

File diff suppressed because it is too large Load Diff

View File

@ -1,73 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef cond_h_6e96ad7c
#define cond_h_6e96ad7c
/*
* 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 */
enum {
COND_IF,
COND_IFDEF,
COND_IFNDEF,
COND_IFMAKE,
COND_IFNMAKE,
COND_ELSE,
COND_ELIF,
COND_ELIFDEF,
COND_ELIFNDEF,
COND_ELIFMAKE,
COND_ELIFNMAKE,
COND_ENDIF,
};
void Cond_If(char *, int, int);
void Cond_Else(char *, int, int);
void Cond_Endif(char *, int, int);
void Cond_End(void);
extern Boolean skipLine;
#endif /* cond_h_6e96ad7c */

View File

@ -1,111 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)config.h 8.2 (Berkeley) 4/28/95
* $FreeBSD$
*/
#ifndef config_h_efe0765e
#define config_h_efe0765e
/*
* DEFMAXJOBS
* This control the default concurrency. On no occasion will more
* than DEFMAXJOBS targets be created at once.
*/
#define DEFMAXJOBS 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
/*
* SYSVINCLUDE
* Recognize system V like include directives [include "filename"]
* SYSVVARSUB
* Recognize system V like ${VAR:x=y} variable substitutions
*/
#define SYSVINCLUDE
#define SYSVVARSUB
/*
* SUNSHCMD
* Recognize SunOS and Solaris:
* VAR :sh= CMD # Assign VAR to the command substitution of CMD
* ${VAR:sh} # Return the command substitution of the value
* # of ${VAR}
*/
#define SUNSHCMD
#if !defined(__svr4__) && !defined(__SVR4) && !defined(__ELF__)
# ifndef RANLIBMAG
# define RANLIBMAG "__.SYMDEF"
# endif
#else
# ifndef RANLIBMAG
# define RANLIBMAG "/"
# endif
#endif
#endif /* config_h_efe0765e */

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)dir.h 8.2 (Berkeley) 4/28/95
* $FreeBSD$
*/
#ifndef dir_h_6002e3b8
#define dir_h_6002e3b8
#include <sys/queue.h>
#include "hash.h"
struct GNode;
struct Lst;
struct Dir;
struct PathElement;
TAILQ_HEAD(Path, PathElement);
void Dir_Init(void);
void Dir_InitDot(void);
Boolean Dir_HasWildcards(const char *);
int Dir_FindHereOrAbove(char *, char *, char *, int);
int Dir_MTime(struct GNode *);
void Dir_PrintDirectories(void);
struct Dir *Path_AddDir(struct Path *, const char *);
void Path_Clear(struct Path *);
void Path_Concat(struct Path *, const struct Path *);
void Path_Duplicate(struct Path *, const struct Path *);
void Path_Expand(char *, struct Path *, struct Lst *);
char *Path_FindFile(char *, struct Path *);
char *Path_MakeFlags(const char *, const struct Path *);
void Path_Print(const struct Path *);
#endif /* dir_h_6002e3b8 */

View File

@ -1,267 +0,0 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Christos Zoulas.
*
* 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.
*
* @(#)for.c 8.1 (Berkeley) 6/6/93
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*-
* 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 <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "buf.h"
#include "for.h"
#include "globals.h"
#include "lst.h"
#include "parse.h"
#include "str.h"
#include "util.h"
#include "var.h"
/*
* 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.
*/
static int forLevel = 0; /* Nesting level */
static char *forVar; /* Iteration variable */
static Buffer *forBuf; /* Commands in loop */
static Lst forLst; /* List of items */
/**
* For_For
* Evaluate the for loop in the passed line. The line
* looks like this:
* .for <variable> in <varlist>
* The line pointer points just behind the for.
*
* Results:
* TRUE: Syntax ok.
* FALSE: Syntax error.
*/
Boolean
For_For(char *line)
{
char *ptr;
char *wrd;
char *sub;
Buffer *buf;
size_t varlen;
int i;
ArgArray words;
ptr = line;
/*
* Skip space between for and the variable.
*/
for (ptr++; *ptr && isspace((u_char)*ptr); ptr++)
;
/*
* Grab the variable
*/
for (wrd = ptr; *ptr && !isspace((u_char)*ptr); ptr++)
;
buf = Buf_Init(0);
Buf_AppendRange(buf, wrd, ptr);
forVar = Buf_GetAll(buf, &varlen);
if (varlen == 0) {
Buf_Destroy(buf, TRUE);
Parse_Error(PARSE_FATAL, "missing variable in for");
return (FALSE);
}
Buf_Destroy(buf, FALSE);
/*
* Skip to 'in'.
*/
while (*ptr && isspace((u_char)*ptr))
ptr++;
/*
* Grab the `in'
*/
if (ptr[0] != 'i' || ptr[1] != 'n' || !isspace((u_char)ptr[2])) {
free(forVar);
Parse_Error(PARSE_FATAL, "missing `in' in for");
fprintf(stderr, "%s\n", ptr);
return (FALSE);
}
ptr += 3;
/*
* Skip to values
*/
while (*ptr && isspace((u_char)*ptr))
ptr++;
/*
* Make a list with the remaining words
*/
sub = Buf_Peel(Var_Subst(ptr, VAR_CMD, FALSE));
brk_string(&words, sub, FALSE);
Lst_Init(&forLst);
for (i = 1; i < words.argc; i++) {
if (words.argv[i][0] != '\0')
Lst_AtFront(&forLst, estrdup(words.argv[i]));
}
ArgArray_Done(&words);
DEBUGF(FOR, ("For: Iterator %s List %s\n", forVar, sub));
free(sub);
forBuf = Buf_Init(0);
forLevel++;
return (TRUE);
}
/**
* For_Eval
* Eat a line of the .for body looking for embedded .for loops
* and the .endfor
*/
Boolean
For_Eval(char *line)
{
char *ptr;
ptr = line;
if (*ptr == '.') {
/*
* Need to check for 'endfor' and 'for' to find the end
* of our loop or to find embedded for loops.
*/
for (ptr++; *ptr != '\0' && isspace((u_char)*ptr); ptr++)
;
/* XXX the isspace is wrong */
if (strncmp(ptr, "endfor", 6) == 0 &&
(isspace((u_char)ptr[6]) || ptr[6] == '\0')) {
DEBUGF(FOR, ("For: end for %d\n", forLevel));
if (forLevel == 0) {
/* should not be here */
abort();
}
forLevel--;
} else if (strncmp(ptr, "for", 3) == 0 &&
isspace((u_char)ptr[3])) {
forLevel++;
DEBUGF(FOR, ("For: new loop %d\n", forLevel));
}
}
if (forLevel != 0) {
/*
* Still in loop - append the line
*/
Buf_Append(forBuf, line);
Buf_AddByte(forBuf, (Byte)'\n');
return (TRUE);
}
return (FALSE);
}
/*-
*-----------------------------------------------------------------------
* For_Run --
* Run the for loop, imitating the actions of an include file
*
* Results:
* None.
*
* Side Effects:
* The values of the variables forLst, forVar and forBuf are freed.
*
*-----------------------------------------------------------------------
*/
void
For_Run(int lineno)
{
Lst values; /* list of values for the variable */
char *var; /* the variable's name */
Buffer *buf; /* the contents of the for loop */
const char *val; /* current value of loop variable */
LstNode *ln;
char *str;
if (forVar == NULL || forBuf == NULL)
return;
/* copy the global variables to have them free for embedded fors */
var = forVar;
buf = forBuf;
Lst_Init(&values);
Lst_Concat(&values, &forLst, LST_CONCLINK);
forVar = NULL;
forBuf = NULL;
LST_FOREACH(ln, &values) {
val = Lst_Datum(ln);
Var_SetGlobal(var, val);
DEBUGF(FOR, ("--- %s = %s\n", var, val));
str = Buf_Peel(Var_SubstOnly(var, Buf_Data(buf), FALSE));
Parse_FromString(str, lineno);
Var_Delete(var, VAR_GLOBAL);
}
free(var);
Lst_Destroy(&values, free);
Buf_Destroy(buf, TRUE);
}

View File

@ -1,50 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef for_h_9d770f33
#define for_h_9d770f33
#include "util.h"
Boolean For_For(char *);
Boolean For_Eval(char *);
void For_Run(int);
#endif /* for_h_9d770f33 */

View File

@ -1,116 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef globals_h_1c1edb96
#define globals_h_1c1edb96
/*
* Global Variables
*/
#include "lst.h"
#include "util.h"
struct GNode;
struct Path;
/*
* The list of target names specified on the command line.
* Used to resolve #if make(...) statements
*/
extern Lst create;
/* The list of directories to search when looking for targets */
extern struct Path dirSearchPath;
/* The list of directories to search when looking for includes */
extern struct Path parseIncPath;
/* The system include path. */
extern struct Path sysIncPath;
extern int jobLimit; /* -j argument: maximum number of jobs */
extern int makeErrors; /* Number of targets not remade due to errors */
extern Boolean jobsRunning; /* True if jobs are running */
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 beVerbose; /* True if should print extra cruft */
extern Boolean beQuiet; /* True if want quiet headers with -j */
extern Boolean noExecute; /* True if should execute nothing */
extern Boolean printGraphOnly; /* -p flag */
extern Boolean allPrecious; /* True if every target is precious */
extern Boolean is_posix; /* .POSIX target seen */
extern Boolean mfAutoDeps; /* .MAKEFILEDEPS target seen */
extern Boolean remakingMakefiles; /* True if remaking makefiles is in progress */
/* True if should continue on unaffected portions of the graph
* when have an error in one portion */
extern Boolean keepgoing;
/* TRUE if targets should just be 'touched'if out of date. Set by the -t flag */
extern Boolean touchFlag;
/* TRUE if should capture the output of subshells by means of pipes.
* Otherwise it is routed to temporary files from which it is retrieved
* when the shell exits */
extern Boolean usePipes;
/* TRUE if we aren't supposed to really make anything, just see if the
* targets are out-of-date */
extern Boolean queryFlag;
/* List of specific variables for which the environment should be
* searched before the global context */
extern Lst envFirstVars;
extern struct GNode *DEFAULT; /* .DEFAULT rule */
/* The time at the start of this whole process */
extern time_t now;
extern int debug;
/* warning flags */
extern uint32_t warn_cmd; /* positive warning flags on command line */
extern uint32_t warn_nocmd; /* negative warning flags on command line */
extern uint32_t warn_flags; /* current warning flags */
#endif /* globals_h_1c1edb96 */

View File

@ -1,398 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)hash.c 8.1 (Berkeley) 6/6/93
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/* 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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "hash.h"
#include "util.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 8
/*
*---------------------------------------------------------
*
* Hash_InitTable --
*
* Set up the hash table t with a given number of buckets, or a
* reasonable default if the number requested is less than or
* equal to zero. Hash tables will grow in size 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 = emalloc(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.
*
* 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(const 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.
*
* 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 int 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 = emalloc(sizeof(*e) + keylen);
hp = &t->bucketPtr[h & t->mask];
e->next = *hp;
*hp = e;
e->clientData = NULL;
e->namehash = h;
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;
}
}
write(STDERR_FILENO, "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.
*
* 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(const 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.
*
* 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;
const Hash_Table *t = searchPtr->tablePtr;
/*
* The hashEntryPtr field points to the most recently returned
* entry, or is NULL if we are starting up. If not NULL, 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 = emalloc(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);
}

View File

@ -1,103 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)hash.h 8.1 (Berkeley) 6/6/93
* $FreeBSD$
*/
#ifndef hash_h_f6312f46
#define hash_h_f6312f46
/* hash.h --
*
* This file contains definitions used by the hash module,
* which maintains hash tables.
*/
#include "util.h"
/*
* The following defines one entry in the hash table.
*/
typedef struct Hash_Entry {
struct Hash_Entry *next; /* Link entries within same bucket. */
void *clientData; /* Data associated with key. */
unsigned namehash; /* hash value of key */
char name[1]; /* key string */
} Hash_Entry;
typedef struct Hash_Table {
struct Hash_Entry **bucketPtr; /* Buckets 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 {
const Hash_Table *tablePtr; /* Table being searched. */
int nextIndex; /* Next bucket to check */
Hash_Entry *hashEntryPtr; /* Next entry in current bucket */
} Hash_Search;
/*
* Macros.
*/
/*
* void *Hash_GetValue(const Hash_Entry *h)
*/
#define Hash_GetValue(h) ((h)->clientData)
/*
* Hash_SetValue(Hash_Entry *h, void *val);
*/
#define Hash_SetValue(h, val) ((h)->clientData = (val))
void Hash_InitTable(Hash_Table *, int);
void Hash_DeleteTable(Hash_Table *);
Hash_Entry *Hash_FindEntry(const Hash_Table *, const char *);
Hash_Entry *Hash_CreateEntry(Hash_Table *, const char *, Boolean *);
void Hash_DeleteEntry(Hash_Table *, Hash_Entry *);
Hash_Entry *Hash_EnumFirst(const Hash_Table *, Hash_Search *);
Hash_Entry *Hash_EnumNext(Hash_Search *);
#endif /* hash_h_f6312f46 */

View File

@ -1,130 +0,0 @@
/*
* DO NOT EDIT
* $FreeBSD$
* auto-generated from FreeBSD: src/usr.bin/make/parse.c,v 1.114 2008/03/12 14:50:58 obrien Exp
* DO NOT EDIT
*/
#include <sys/types.h>
#include "hash_tables.h"
/*
* d=2
* n=40
* m=19
* c=2.09
* maxlen=1
* minklen=2
* maxklen=9
* minchar=97
* maxchar=119
* loop=0
* numiter=1
* seed=
*/
static const signed char directive_g[] = {
8, 0, 0, 5, 6, -1, 17, 15, 10, 6,
-1, -1, 10, 0, 0, -1, 18, 2, 3, 0,
7, -1, -1, -1, 0, 14, -1, -1, 11, 16,
-1, -1, 0, -1, 0, 0, 17, 0, -1, 1,
};
static const u_char directive_T0[] = {
26, 14, 19, 35, 10, 34, 18, 27, 1, 17,
22, 37, 12, 12, 36, 21, 0, 6, 1, 25,
9, 4, 19,
};
static const u_char directive_T1[] = {
25, 22, 19, 0, 2, 18, 33, 18, 30, 4,
30, 9, 21, 19, 16, 12, 35, 34, 4, 19,
9, 33, 16,
};
int
directive_hash(const u_char *key, size_t len)
{
unsigned f0, f1;
const u_char *kp = key;
if (len < 2 || len > 9)
return -1;
for (f0=f1=0; kp < key + len; ++kp) {
if (*kp < 97 || *kp > 119)
return -1;
f0 += directive_T0[-97 + *kp];
f1 += directive_T1[-97 + *kp];
}
f0 %= 40;
f1 %= 40;
return (directive_g[f0] + directive_g[f1]) % 19;
}
/*
* d=2
* n=74
* m=35
* c=2.09
* maxlen=1
* minklen=4
* maxklen=13
* minchar=46
* maxchar=95
* loop=0
* numiter=4
* seed=
*/
static const signed char keyword_g[] = {
12, 18, 7, 25, 30, 5, -1, -1, -1, 7,
-1, 0, 33, 0, 4, -1, -1, 13, 29, 0,
-1, 28, -1, 28, -1, 0, -1, 27, 4, 34,
-1, -1, -1, 30, 13, 10, -1, -1, 0, 10,
24, -1, -1, -1, 0, 6, 0, 0, -1, 23,
-1, -1, -1, 0, -1, 23, -1, -1, 19, 4,
-1, 31, 12, 16, -1, 20, 22, 9, 0, -1,
-1, 9, 4, 0,
};
static const u_char keyword_T0[] = {
34, 28, 50, 61, 14, 57, 48, 60, 20, 67,
60, 63, 0, 24, 28, 2, 49, 64, 18, 23,
36, 33, 40, 14, 38, 42, 71, 49, 2, 53,
53, 37, 7, 29, 24, 21, 12, 50, 59, 10,
43, 23, 0, 44, 47, 6, 46, 22, 48, 64,
};
static const u_char keyword_T1[] = {
18, 67, 39, 60, 7, 70, 2, 26, 31, 18,
73, 47, 61, 17, 38, 50, 22, 52, 13, 55,
56, 32, 63, 4, 64, 55, 49, 21, 47, 67,
33, 66, 60, 73, 30, 68, 69, 32, 72, 4,
28, 49, 51, 15, 66, 68, 43, 67, 46, 56,
};
int
keyword_hash(const u_char *key, size_t len)
{
unsigned f0, f1;
const u_char *kp = key;
if (len < 4 || len > 13)
return -1;
for (f0=f1=0; *kp; ++kp) {
if (*kp < 46 || *kp > 95)
return -1;
f0 += keyword_T0[-46 + *kp];
f1 += keyword_T1[-46 + *kp];
}
f0 %= 74;
f1 %= 74;
return (keyword_g[f0] + keyword_g[f1]) % 35;
}

View File

@ -1,36 +0,0 @@
/*
* Copyright (C) 2005 Max Okumoto.
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD$
*/
#ifndef hash_tables_h_
#define hash_tables_h_
#include <sys/types.h>
int directive_hash(const u_char *, size_t);
int keyword_hash(const u_char *, size_t);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)job.h 8.1 (Berkeley) 6/6/93
* $FreeBSD$
*/
#ifndef job_h_4678dfd1
#define job_h_4678dfd1
/*-
* job.h --
* Definitions pertaining to the running of jobs in parallel mode.
*/
#include <stdio.h>
#include "util.h"
struct Buffer;
struct GNode;
struct Lst;
void Job_Touch(struct GNode *, Boolean);
Boolean Job_CheckCommands(struct GNode *, void (*abortProc)(const char *, ...));
void Job_CatchChildren(Boolean);
void Job_CatchOutput(int flag);
void Job_Make(struct GNode *);
void Job_Init(int);
Boolean Job_Full(void);
Boolean Job_Empty(void);
void Job_Finish(void);
void Job_Wait(void);
void Job_AbortAll(void);
void Job_SetPrefix(void);
void Proc_Init(void);
struct Buffer *Cmd_Exec(const char *, const char **);
int Compat_Make(struct GNode *gn, struct GNode *pgn);
void Compat_InstallSignalHandlers(void);
void Compat_Run(struct Lst *);
#endif /* job_h_4678dfd1 */

View File

@ -1,344 +0,0 @@
/*-
* 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.
*
* $FreeBSD$
*/
/*-
* lst.c --
* Routines to maintain a linked list of objects.
*/
#include <stdio.h>
#include <stdlib.h>
#include "lst.h"
#include "util.h"
/**
* Lst_Append
* Create a new node and add it to the given list after the given node.
*
* Arguments:
* l affected list
* ln node after which to append the datum
* d said datum
*
* Side Effects:
* A new LstNode 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.
*/
void
Lst_Append(Lst *list, LstNode *ln, void *d)
{
LstNode *nLNode;
nLNode = emalloc(sizeof(*nLNode));
nLNode->datum = d;
if (ln == NULL) {
nLNode->nextPtr = nLNode->prevPtr = NULL;
list->firstPtr = list->lastPtr = nLNode;
} else {
nLNode->prevPtr = ln;
nLNode->nextPtr = ln->nextPtr;
ln->nextPtr = nLNode;
if (nLNode->nextPtr != NULL) {
nLNode->nextPtr->prevPtr = nLNode;
}
if (ln == list->lastPtr) {
list->lastPtr = nLNode;
}
}
}
/**
* 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.
*
* Arguments:
* list1 The list to which list2 is to be appended
* list2 The list to append to list1
* flags LST_CONCNEW if LstNode's should be duplicated
* LST_CONCLINK if should just be relinked
*
* Side Effects:
* New elements are created and appended the first list.
*/
void
Lst_Concat(Lst *list1, Lst *list2, int flags)
{
LstNode *ln; /* original LstNode */
LstNode *nln; /* new LstNode */
LstNode *last; /* the last element in the list. Keeps
* bookkeeping until the end */
if (list2->firstPtr == NULL)
return;
if (flags == LST_CONCLINK) {
/*
* 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;
Lst_Init(list2);
} else {
/*
* The loop simply goes through the entire second list creating
* new LstNodes and filling in the nextPtr, and prevPtr to fit
* into list1 and its datum field from the datum field of the
* corresponding element in list2. The 'last' node follows the
* last of the new nodes along until the entire list2 has been
* appended. Only then does the bookkeeping catch up with the
* changes. During the first iteration of the loop, if 'last'
* is NULL, the first list must have been empty so the
* newly-created node is made the first node of the list.
*/
for (last = list1->lastPtr, ln = list2->firstPtr;
ln != NULL;
ln = ln->nextPtr) {
nln = emalloc(sizeof(*nln));
nln->datum = ln->datum;
if (last != NULL) {
last->nextPtr = nln;
} else {
list1->firstPtr = nln;
}
nln->prevPtr = last;
last = nln;
}
/*
* Finish bookkeeping. The last new element becomes the last
* element of list one.
*/
list1->lastPtr = last;
last->nextPtr = NULL;
}
}
/**
* Lst_DeQueue
* Remove and return the datum at the head of the given list.
*
* Results:
* The datum in the node at the head or (ick) NULL if the list
* is empty.
*
* Side Effects:
* The head node is removed from the list.
*/
void *
Lst_DeQueue(Lst *l)
{
void *rd;
LstNode *tln;
tln = Lst_First(l);
if (tln == NULL) {
return (NULL);
}
rd = tln->datum;
Lst_Remove(l, tln);
return (rd);
}
/**
* 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.
*
* Side Effects:
* The given list is freed in its entirety.
*/
void
Lst_Destroy(Lst *list, FreeProc *freeProc)
{
LstNode *ln;
if (list->firstPtr == NULL)
return;
if (freeProc != NOFREE) {
while ((ln = list->firstPtr) != NULL) {
list->firstPtr = ln->nextPtr;
(*freeProc)(ln->datum);
free(ln);
}
} else {
while ((ln = list->firstPtr) != NULL) {
list->firstPtr = ln->nextPtr;
free(ln);
}
}
list->lastPtr = NULL;
}
/**
* Lst_Duplicate
* Duplicate an entire list. If a function to copy a void * is
* given, the individual client elements will be duplicated as well.
*
* Arguments:
* dst the destination list (initialized)
* src the list to duplicate
* copyProc A function to duplicate each void
*/
void
Lst_Duplicate(Lst *dst, Lst *src, DuplicateProc *copyProc)
{
LstNode *ln;
ln = src->firstPtr;
while (ln != NULL) {
if (copyProc != NOCOPY)
Lst_AtEnd(dst, (*copyProc)(ln->datum));
else
Lst_AtEnd(dst, ln->datum);
ln = ln->nextPtr;
}
}
/**
* Lst_Insert
* Insert a new node with the given piece of data before the given
* node in the given list.
*
* Parameters:
* l list to manipulate
* ln node before which to insert d
* d datum to be inserted
*
* Side Effects:
* the firstPtr field will be changed if ln is the first node in the
* list.
*/
void
Lst_Insert(Lst *list, LstNode *ln, void *d)
{
LstNode *nLNode; /* new lnode for d */
nLNode = emalloc(sizeof(*nLNode));
nLNode->datum = d;
if (ln == NULL) {
nLNode->prevPtr = nLNode->nextPtr = NULL;
list->firstPtr = list->lastPtr = nLNode;
} else {
nLNode->prevPtr = ln->prevPtr;
nLNode->nextPtr = ln;
if (nLNode->prevPtr != NULL) {
nLNode->prevPtr->nextPtr = nLNode;
}
ln->prevPtr = nLNode;
if (ln == list->firstPtr) {
list->firstPtr = nLNode;
}
}
}
LstNode *
Lst_Member(Lst *list, void *d)
{
LstNode *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);
}
/**
* Lst_Remove
* Remove the given node from the given list.
*
* 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.
*/
void
Lst_Remove(Lst *list, LstNode *ln)
{
/*
* unlink it from the list
*/
if (ln->nextPtr != NULL)
/* unlink from the backward chain */
ln->nextPtr->prevPtr = ln->prevPtr;
else
/* this was the last element */
list->lastPtr = ln->prevPtr;
if (ln->prevPtr != NULL)
/* unlink from the forward chain */
ln->prevPtr->nextPtr = ln->nextPtr;
else
/* this was the first element */
list->firstPtr = ln->nextPtr;
/*
* note that the datum is unmolested. The caller must free it as
* necessary and as expected.
*/
free(ln);
}

View File

@ -1,175 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)lst.h 8.2 (Berkeley) 4/28/95
* $FreeBSD$
*/
#ifndef lst_h_38f3ead1
#define lst_h_38f3ead1
/*-
* lst.h --
* Header for using the list library
*/
/*
* Structure of a list node.
*/
struct LstNode {
struct LstNode *prevPtr; /* previous element in list */
struct LstNode *nextPtr; /* next in list */
void *datum; /* datum associated with this element */
};
typedef struct LstNode LstNode;
/*
* The list itself
*/
struct Lst {
LstNode *firstPtr; /* first node in list */
LstNode *lastPtr; /* last node in list */
};
typedef struct Lst Lst;
typedef void *DuplicateProc(void *);
typedef void FreeProc(void *);
/*
* NOFREE can be used as the freeProc to Lst_Destroy when the elements are
* not to be freed.
* NOCOPY performs similarly when given as the copyProc to Lst_Duplicate.
*/
#define NOFREE ((FreeProc *)NULL)
#define NOCOPY ((DuplicateProc *)NULL)
#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 */
#define Lst_Init(LST) do { \
(LST)->firstPtr = NULL; \
(LST)->lastPtr = NULL; \
} while (0)
#define Lst_Initializer(NAME) { NULL, NULL }
/* Duplicate an existing list */
void Lst_Duplicate(Lst *, Lst *, DuplicateProc *);
/* Destroy an old one */
void Lst_Destroy(Lst *, FreeProc *);
/*
* Functions to modify a list
*/
/* Insert an element before another */
void Lst_Insert(Lst *, LstNode *, void *);
/* Insert an element after another */
void Lst_Append(Lst *, LstNode *, void *);
/* Place an element at the front of a lst. */
#define Lst_AtFront(LST, D) (Lst_Insert((LST), Lst_First(LST), (D)))
/* Place an element at the end of a lst. */
#define Lst_AtEnd(LST, D) (Lst_Append((LST), Lst_Last(LST), (D)))
/* Remove an element */
void Lst_Remove(Lst *, LstNode *);
/* Replace a node with a new value */
#define Lst_Replace(NODE, D) ((void)((NODE)->datum = (D)))
/* Concatenate two lists */
void Lst_Concat(Lst *, Lst *, int);
/*
* Node-specific functions
*/
/* Return first element in list */
#define Lst_First(LST) ((Lst_Valid(LST) && !Lst_IsEmpty(LST)) \
? (LST)->firstPtr : NULL)
/* Return last element in list */
#define Lst_Last(LST) ((Lst_Valid(LST) && !Lst_IsEmpty(LST)) \
? (LST)->lastPtr : NULL)
/* Return successor to given element */
#define Lst_Succ(NODE) (((NODE) == NULL) ? NULL : (NODE)->nextPtr)
#define LST_NEXT(NODE) ((NODE)->nextPtr)
/* Get datum from LstNode */
#define Lst_Datum(NODE) ((NODE)->datum)
/*
* Functions for entire lists
*/
/*
* See if the given datum is on the list. Returns the LstNode containing
* the datum
*/
LstNode *Lst_Member(Lst *, void *);
/* Loop through a list. Note, that you may not delete the list element. */
#define LST_FOREACH(PTR, LST) \
for ((PTR) = (LST)->firstPtr; (PTR) != NULL; (PTR) = (PTR)->nextPtr)
/*
* for using the list as a queue
*/
/* Place an element at tail of queue */
#define Lst_EnQueue(LST, D) (Lst_Valid(LST) \
? Lst_Append((LST), Lst_Last(LST), (D)) \
: (void)0)
/* Remove an element from head of queue */
void *Lst_DeQueue(Lst *);
/*
* LstValid (L) --
* Return TRUE if the list L is valid
*/
#define Lst_Valid(L) (((L) == NULL) ? FALSE : TRUE)
/*
* LstNodeValid (LN, L) --
* Return TRUE if the LstNode LN is valid with respect to L
*/
#define Lst_NodeValid(LN, L) (((LN) == NULL) ? FALSE : TRUE)
/*
* Lst_IsEmpty(L) --
* TRUE if the list L is empty.
*/
#define Lst_IsEmpty(L) (!Lst_Valid(L) || (L)->firstPtr == NULL)
#endif /* lst_h_38f3ead1 */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,819 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)make.c 8.1 (Berkeley) 6/6/93
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* make.c
* The functions which perform the examination of targets and
* their suitability for creation
*
* Interface:
* Make_Run Initialize things for the module and recreate
* whatever needs recreating. Returns TRUE if
* work was (or would have been) done and FALSE
* otherwise.
*
* Make_Update Update all parents of a given child. Performs
* various bookkeeping chores like the updating
* of the cmtime field of the parent, filling
* of the IMPSRC context variable, etc. It will
* place the parent on the toBeMade queue if it should be.
*
* Make_TimeStamp Function to set the parent's cmtime field
* based on a child's modification time.
*
* Make_DoAllVar Set up the various local variables for a
* target, including the .ALLSRC variable, making
* sure that any variable that needs to exist
* at the very least has the empty value.
*
* Make_OODate Determine if a target is out-of-date.
*
* Make_HandleUse See if a child is a .USE node for a parent
* and perform the .USE actions if so.
*/
#include "arch.h"
#include "config.h"
#include "dir.h"
#include "globals.h"
#include "GNode.h"
#include "job.h"
#include "make.h"
#include "parse.h"
#include "suff.h"
#include "targ.h"
#include "util.h"
#include "var.h"
/* The current fringe of the graph. These are nodes which await examination
* by MakeOODate. It is added to by Make_Update and subtracted from by
* MakeStartJobs */
static Lst toBeMade = Lst_Initializer(toBeMade);
/*
* Number of nodes to be processed. If this is non-zero when Job_Empty()
* returns TRUE, there's a cycle in the graph.
*/
static int numNodes;
static Boolean MakeStartJobs(void);
/**
* Make_TimeStamp
* Set the cmtime field of a parent node based on the mtime stamp in its
* child. Called from MakeOODate via LST_FOREACH.
*
* Results:
* Always returns 0.
*
* Side Effects:
* The cmtime of the parent node will be changed if the mtime
* field of the child is greater than it.
*/
int
Make_TimeStamp(GNode *pgn, GNode *cgn)
{
if (cgn->mtime > pgn->cmtime) {
pgn->cmtime = cgn->mtime;
pgn->cmtime_gn = cgn;
}
return (0);
}
/**
* Make_OODate
* See if a given node is out of date with respect to its sources.
* Used by Make_Run when deciding which nodes to place on the
* toBeMade queue initially and by Make_Update to screen out USE and
* EXEC nodes. In the latter case, however, any other sort of node
* must be considered out-of-date since at least one of its children
* will have been recreated.
*
* Results:
* TRUE if the node is out of date. FALSE otherwise.
*
* Side Effects:
* The mtime field of the node and the cmtime field of its parents
* will/may be changed.
*/
Boolean
Make_OODate(GNode *gn)
{
Boolean oodate;
LstNode *ln;
/*
* Certain types of targets needn't even be sought as their datedness
* doesn't depend on their modification time...
*/
if ((gn->type & (OP_JOIN | OP_USE | OP_EXEC)) == 0) {
Dir_MTime(gn);
if (gn->mtime != 0) {
DEBUGF(MAKE, ("modified %s...",
Targ_FmtTime(gn->mtime)));
} else {
DEBUGF(MAKE, ("non-existent..."));
}
}
/*
* A target is remade in one of the following circumstances:
* its modification time is smaller than that of its youngest child
* and it would actually be run (has commands or type OP_NOP)
* it's the object of a force operator
* it has no children, was on the lhs of an operator and doesn't
* exist already.
*
* Libraries are only considered out-of-date if the archive module says
* they are.
*
* These weird rules are brought to you by Backward-Compatibility and
* the strange people who wrote 'Make'.
*/
if (gn->type & OP_USE) {
/*
* If the node is a USE node it is *never* out of date
* no matter *what*.
*/
DEBUGF(MAKE, (".USE node..."));
oodate = FALSE;
} else if (gn->type & OP_LIB) {
DEBUGF(MAKE, ("library..."));
/*
* always out of date if no children and :: target
*/
oodate = Arch_LibOODate(gn) ||
((gn->cmtime == 0) && (gn->type & OP_DOUBLEDEP));
} else if (gn->type & OP_JOIN) {
/*
* A target with the .JOIN attribute is only considered
* out-of-date if any of its children was out-of-date.
*/
DEBUGF(MAKE, (".JOIN node..."));
oodate = gn->childMade;
} else if (gn->type & (OP_FORCE|OP_EXEC|OP_PHONY)) {
/*
* A node which is the object of the force (!) operator or
* which has the .EXEC attribute is always considered
* out-of-date.
*/
if (gn->type & OP_FORCE) {
DEBUGF(MAKE, ("! operator..."));
} else if (gn->type & OP_PHONY) {
DEBUGF(MAKE, (".PHONY node..."));
} else {
DEBUGF(MAKE, (".EXEC node..."));
}
if (remakingMakefiles) {
DEBUGF(MAKE, ("skipping (remaking makefiles)..."));
oodate = FALSE;
} else {
oodate = TRUE;
}
} else if (gn->mtime < gn->cmtime ||
(gn->cmtime == 0 && (gn->mtime == 0 || (gn->type & OP_DOUBLEDEP)))) {
/*
* A node whose modification time is less than that of its
* youngest child or that has no children (cmtime == 0) and
* either doesn't exist (mtime == 0) or was the object of a
* :: operator is out-of-date. Why? Because that's the way
* Make does it.
*/
if (gn->mtime < gn->cmtime) {
DEBUGF(MAKE, ("modified before source (%s)...",
gn->cmtime_gn ? gn->cmtime_gn->path : "???"));
oodate = TRUE;
} else if (gn->mtime == 0) {
DEBUGF(MAKE, ("non-existent and no sources..."));
if (remakingMakefiles && Lst_IsEmpty(&gn->commands)) {
DEBUGF(MAKE, ("skipping (no commands and remaking makefiles)..."));
oodate = FALSE;
} else {
oodate = TRUE;
}
} else {
DEBUGF(MAKE, (":: operator and no sources..."));
if (remakingMakefiles) {
DEBUGF(MAKE, ("skipping (remaking makefiles)..."));
oodate = FALSE;
} else {
oodate = TRUE;
}
}
} else
oodate = FALSE;
/*
* If the target isn't out-of-date, the parents need to know its
* modification time. Note that targets that appear to be out-of-date
* but aren't, because they have no commands and aren't of type OP_NOP,
* have their mtime stay below their children's mtime to keep parents
* from thinking they're out-of-date.
*/
if (!oodate) {
LST_FOREACH(ln, &gn->parents)
if (Make_TimeStamp(Lst_Datum(ln), gn))
break;
}
return (oodate);
}
/**
* Make_HandleUse
* Function called by Make_Run and SuffApplyTransform on the downward
* pass to handle .USE and transformation nodes. A callback function
* for LST_FOREACH, it implements the .USE and transformation
* functionality by copying the node's commands, type flags
* and children to the parent node. Should be called before the
* children are enqueued to be looked at.
*
* A .USE node is much like an explicit transformation rule, except
* its commands are always added to the target node, even if the
* target already has commands.
*
* Results:
* returns 0.
*
* Side Effects:
* Children and commands may be added to the parent and the parent's
* type may be changed.
*
*-----------------------------------------------------------------------
*/
int
Make_HandleUse(GNode *cgn, GNode *pgn)
{
GNode *gn; /* A child of the .USE node */
LstNode *ln; /* An element in the children list */
if (cgn->type & (OP_USE | OP_TRANSFORM)) {
if ((cgn->type & OP_USE) || Lst_IsEmpty(&pgn->commands)) {
/*
* .USE or transformation and target has no commands --
* append the child's commands to the parent.
*/
Lst_Concat(&pgn->commands, &cgn->commands, LST_CONCNEW);
}
for (ln = Lst_First(&cgn->children); ln != NULL;
ln = Lst_Succ(ln)) {
gn = Lst_Datum(ln);
if (Lst_Member(&pgn->children, gn) == NULL) {
Lst_AtEnd(&pgn->children, gn);
Lst_AtEnd(&gn->parents, pgn);
pgn->unmade += 1;
}
}
pgn->type |= cgn->type & ~(OP_OPMASK | OP_USE | OP_TRANSFORM);
/*
* This child node is now "made", so we decrement the count of
* unmade children in the parent... We also remove the child
* from the parent's list to accurately reflect the number of
* decent children the parent has. This is used by Make_Run to
* decide whether to queue the parent or examine its children...
*/
if (cgn->type & OP_USE) {
pgn->unmade--;
}
}
return (0);
}
/**
* Make_Update
* Perform update on the parents of a node. Used by JobFinish once
* a node has been dealt with and by MakeStartJobs if it finds an
* up-to-date node.
*
* Results:
* Always returns 0
*
* Side Effects:
* The unmade field of pgn is decremented and pgn may be placed on
* the toBeMade queue if this field becomes 0.
*
* If the child was made, the parent's childMade field will be set true
* and its cmtime set to now.
*
* If the child wasn't made, the cmtime field of the parent will be
* altered if the child's mtime is big enough.
*
* Finally, if the child is the implied source for the parent, the
* parent's IMPSRC variable is set appropriately.
*/
void
Make_Update(GNode *cgn)
{
GNode *pgn; /* the parent node */
const char *cname; /* the child's name */
LstNode *ln; /* Element in parents and iParents lists */
const char *cpref;
cname = Var_Value(TARGET, cgn);
/*
* If the child was actually made, see what its modification time is
* now -- some rules won't actually update the file. If the file still
* doesn't exist, make its mtime now.
*/
if (cgn->made != UPTODATE) {
#ifndef RECHECK
/*
* We can't re-stat the thing, but we can at least take care
* of rules where a target depends on a source that actually
* creates the target, but only if it has changed, e.g.
*
* parse.h : parse.o
*
* parse.o : parse.y
* yacc -d parse.y
* cc -c y.tab.c
* mv y.tab.o parse.o
* cmp -s y.tab.h parse.h || mv y.tab.h parse.h
*
* In this case, if the definitions produced by yacc haven't
* changed from before, parse.h won't have been updated and
* cgn->mtime will reflect the current modification time for
* parse.h. This is something of a kludge, I admit, but it's a
* useful one..
* XXX: People like to use a rule like
*
* FRC:
*
* To force things that depend on FRC to be made, so we have to
* check for gn->children being empty as well...
*/
if (!Lst_IsEmpty(&cgn->commands) ||
Lst_IsEmpty(&cgn->children)) {
cgn->mtime = now;
}
#else
/*
* This is what Make does and it's actually a good thing, as it
* allows rules like
*
* cmp -s y.tab.h parse.h || cp y.tab.h parse.h
*
* to function as intended. Unfortunately, thanks to the
* stateless nature of NFS (by which I mean the loose coupling
* of two clients using the same file from a common server),
* there are times when the modification time of a file created
* on a remote machine will not be modified before the local
* stat() implied by the Dir_MTime occurs, thus leading us to
* believe that the file is unchanged, wreaking havoc with
* files that depend on this one.
*
* I have decided it is better to make too much than to make too
* little, so this stuff is commented out unless you're sure
* it's ok.
* -- ardeb 1/12/88
*/
/*
* Christos, 4/9/92: If we are saving commands pretend that
* the target is made now. Otherwise archives with ... rules
* don't work!
*/
if (noExecute || (cgn->type & OP_SAVE_CMDS) ||
Dir_MTime(cgn) == 0) {
cgn->mtime = now;
}
DEBUGF(MAKE, ("update time: %s\n", Targ_FmtTime(cgn->mtime)));
#endif
}
for (ln = Lst_First(&cgn->parents); ln != NULL; ln = Lst_Succ(ln)) {
pgn = Lst_Datum(ln);
if (pgn->make) {
pgn->unmade -= 1;
if (!(cgn->type & (OP_EXEC | OP_USE))) {
if (cgn->made == MADE)
pgn->childMade = TRUE;
Make_TimeStamp(pgn, cgn);
}
if (pgn->unmade == 0) {
/*
* Queue the node up -- any unmade predecessors
* will be dealt with in MakeStartJobs.
*/
Lst_EnQueue(&toBeMade, pgn);
} else if (pgn->unmade < 0) {
Error("Graph cycles through %s", pgn->name);
}
}
}
/*
* Deal with successor nodes. If any is marked for making and has an
* unmade count of 0, has not been made and isn't in the examination
* queue, it means we need to place it in the queue as it restrained
* itself before.
*/
for (ln = Lst_First(&cgn->successors); ln != NULL; ln = Lst_Succ(ln)) {
GNode *succ = Lst_Datum(ln);
if (succ->make && succ->unmade == 0 && succ->made == UNMADE &&
Lst_Member(&toBeMade, succ) == NULL) {
Lst_EnQueue(&toBeMade, succ);
}
}
/*
* Set the .PREFIX and .IMPSRC variables for all the implied parents
* of this node.
*/
cpref = Var_Value(PREFIX, cgn);
for (ln = Lst_First(&cgn->iParents); ln != NULL; ln = Lst_Succ(ln)) {
pgn = Lst_Datum(ln);
if (pgn->make) {
Var_Set(IMPSRC, cname, pgn);
Var_Set(PREFIX, cpref, pgn);
}
}
}
/**
* Make_DoAllVar
* Set up the ALLSRC and OODATE variables. Sad to say, it must be
* done separately, rather than while traversing the graph. This is
* because Make defined OODATE to contain all sources whose modification
* times were later than that of the target, *not* those sources that
* were out-of-date. Since in both compatibility and native modes,
* the modification time of the parent isn't found until the child
* has been dealt with, we have to wait until now to fill in the
* variable. As for ALLSRC, the ordering is important and not
* guaranteed when in native mode, so it must be set here, too.
*
* Side Effects:
* The ALLSRC and OODATE variables of the given node is filled in.
* If the node is a .JOIN node, its TARGET variable will be set to
* match its ALLSRC variable.
*/
void
Make_DoAllVar(GNode *gn)
{
LstNode *ln;
GNode *cgn;
const char *child;
LST_FOREACH(ln, &gn->children) {
/*
* Add the child's name to the ALLSRC and OODATE variables of
* the given node. The child is added only if it has not been
* given the .EXEC, .USE or .INVISIBLE attributes. .EXEC and
* .USE children are very rarely going to be files, so...
*
* A child is added to the OODATE variable if its modification
* time is later than that of its parent, as defined by Make,
* except if the parent is a .JOIN node. In that case, it is
* only added to the OODATE variable if it was actually made
* (since .JOIN nodes don't have modification times, the
* comparison is rather unfair...).
*/
cgn = Lst_Datum(ln);
if ((cgn->type & (OP_EXEC | OP_USE | OP_INVISIBLE)) == 0) {
if (OP_NOP(cgn->type)) {
/*
* this node is only source; use the specific
* pathname for it
*/
child = cgn->path ? cgn->path : cgn->name;
} else
child = Var_Value(TARGET, cgn);
Var_Append(ALLSRC, child, gn);
if (gn->type & OP_JOIN) {
if (cgn->made == MADE) {
Var_Append(OODATE, child, gn);
}
} else if (gn->mtime < cgn->mtime ||
(cgn->mtime >= now && cgn->made == MADE)) {
/*
* It goes in the OODATE variable if the parent
* is younger than the child or if the child has
* been modified more recently than the start of
* the make. This is to keep pmake from getting
* confused if something else updates the parent
* after the make starts (shouldn't happen, I
* know, but sometimes it does). In such a case,
* if we've updated the kid, the parent is
* likely to have a modification time later than
* that of the kid and anything that relies on
* the OODATE variable will be hosed.
*
* XXX: This will cause all made children to
* go in the OODATE variable, even if they're
* not touched, if RECHECK isn't defined, since
* cgn->mtime is set to now in Make_Update.
* According to some people, this is good...
*/
Var_Append(OODATE, child, gn);
}
}
}
if (!Var_Exists (OODATE, gn)) {
Var_Set(OODATE, "", gn);
}
if (!Var_Exists (ALLSRC, gn)) {
Var_Set(ALLSRC, "", gn);
}
if (gn->type & OP_JOIN) {
Var_Set(TARGET, Var_Value(ALLSRC, gn), gn);
}
}
/**
* MakeStartJobs
* Start as many jobs as possible.
*
* Results:
* If the query flag was given to pmake, no job will be started,
* but as soon as an out-of-date target is found, this function
* returns TRUE. At all other times, this function returns FALSE.
*
* Side Effects:
* Nodes are removed from the toBeMade queue and job table slots
* are filled.
*/
static Boolean
MakeStartJobs(void)
{
GNode *gn;
while (!Lst_IsEmpty(&toBeMade) && !Job_Full()) {
gn = Lst_DeQueue(&toBeMade);
DEBUGF(MAKE, ("Examining %s...", gn->name));
/*
* Make sure any and all predecessors that are going to be made,
* have been.
*/
if (!Lst_IsEmpty(&gn->preds)) {
LstNode *ln;
for (ln = Lst_First(&gn->preds); ln != NULL;
ln = Lst_Succ(ln)){
GNode *pgn = Lst_Datum(ln);
if (pgn->make && pgn->made == UNMADE) {
DEBUGF(MAKE, ("predecessor %s not made "
"yet.\n", pgn->name));
break;
}
}
/*
* If ln isn't NULL, there's a predecessor as yet
* unmade, so we just drop this node on the floor.
* When the node in question has been made, it will
* notice this node as being ready to make but as yet
* unmade and will place the node on the queue.
*/
if (ln != NULL) {
continue;
}
}
numNodes--;
if (Make_OODate(gn)) {
DEBUGF(MAKE, ("out-of-date\n"));
if (queryFlag) {
return (TRUE);
}
Make_DoAllVar(gn);
Job_Make(gn);
} else {
DEBUGF(MAKE, ("up-to-date\n"));
gn->made = UPTODATE;
if (gn->type & OP_JOIN) {
/*
* Even for an up-to-date .JOIN node, we need
* it to have its context variables so
* references to it get the correct value for
* .TARGET when building up the context
* variables of its parent(s)...
*/
Make_DoAllVar(gn);
}
Make_Update(gn);
}
}
return (FALSE);
}
/**
* MakePrintStatus
* Print the status of a top-level node, viz. it being up-to-date
* already or not created due to an error in a lower level.
* Callback function for Make_Run via LST_FOREACH. If gn->unmade is
* nonzero and that is meant to imply a cycle in the graph, then
* cycle is TRUE.
*
* Side Effects:
* A message may be printed.
*/
static void
MakePrintStatus(GNode *gn, Boolean cycle)
{
LstNode *ln;
if (gn->made == UPTODATE) {
printf("`%s' is up to date.\n", gn->name);
} else if (gn->unmade != 0) {
if (cycle) {
/*
* If printing cycles and came to one that has unmade
* children, print out the cycle by recursing on its
* children. Note a cycle like:
* a : b
* b : c
* c : b
* will cause this to erroneously complain about a
* being in the cycle, but this is a good approximation.
*/
if (gn->made == CYCLE) {
Error("Graph cycles through `%s'", gn->name);
gn->made = ENDCYCLE;
LST_FOREACH(ln, &gn->children)
MakePrintStatus(Lst_Datum(ln), TRUE);
gn->made = UNMADE;
} else if (gn->made != ENDCYCLE) {
gn->made = CYCLE;
LST_FOREACH(ln, &gn->children)
MakePrintStatus(Lst_Datum(ln), TRUE);
}
} else {
printf("`%s' not remade because of errors.\n",
gn->name);
}
}
}
/**
* Make_Run
* Initialize the nodes to remake and the list of nodes which are
* ready to be made by doing a breadth-first traversal of the graph
* starting from the nodes in the given list. Once this traversal
* is finished, all the 'leaves' of the graph are in the toBeMade
* queue.
* Using this queue and the Job module, work back up the graph,
* calling on MakeStartJobs to keep the job table as full as
* possible.
*
* Results:
* TRUE if work was done. FALSE otherwise.
*
* Side Effects:
* The make field of all nodes involved in the creation of the given
* targets is set to 1. The toBeMade list is set to contain all the
* 'leaves' of these subgraphs.
*/
Boolean
Make_Run(Lst *targs)
{
GNode *gn; /* a temporary pointer */
GNode *cgn;
Lst examine; /* List of targets to examine */
LstNode *ln;
Lst_Init(&examine);
Lst_Duplicate(&examine, targs, NOCOPY);
numNodes = 0;
/*
* Make an initial downward pass over the graph, marking nodes to be
* made as we go down. We call Suff_FindDeps to find where a node is and
* to get some children for it if it has none and also has no commands.
* If the node is a leaf, we stick it on the toBeMade queue to
* be looked at in a minute, otherwise we add its children to our queue
* and go on about our business.
*/
while (!Lst_IsEmpty(&examine)) {
gn = Lst_DeQueue(&examine);
if (!gn->make) {
gn->make = TRUE;
numNodes++;
/*
* Apply any .USE rules before looking for implicit
* dependencies to make sure everything has commands
* that should...
*/
LST_FOREACH(ln, &gn->children)
if (Make_HandleUse(Lst_Datum(ln), gn))
break;
Suff_FindDeps(gn);
if (gn->unmade != 0) {
LST_FOREACH(ln, &gn->children) {
cgn = Lst_Datum(ln);
if (!cgn->make && !(cgn->type & OP_USE))
Lst_EnQueue(&examine, cgn);
}
} else {
Lst_EnQueue(&toBeMade, gn);
}
}
}
if (queryFlag) {
/*
* We wouldn't do any work unless we could start some jobs in
* the next loop... (we won't actually start any, of course,
* this is just to see if any of the targets was out of date)
*/
return (MakeStartJobs());
} else {
/*
* Initialization. At the moment, no jobs are running and
* until some get started, nothing will happen since the
* remaining upward traversal of the graph is performed by the
* routines in job.c upon the finishing of a job. So we fill
* the Job table as much as we can before going into our loop.
*/
MakeStartJobs();
}
/*
* Main Loop: The idea here is that the ending of jobs will take
* care of the maintenance of data structures and the waiting for output
* will cause us to be idle most of the time while our children run as
* much as possible. Because the job table is kept as full as possible,
* the only time when it will be empty is when all the jobs which need
* running have been run, so that is the end condition of this loop.
* Note that the Job module will exit if there were any errors unless
* the keepgoing flag was given.
*/
while (!Job_Empty()) {
Job_CatchOutput(!Lst_IsEmpty(&toBeMade));
Job_CatchChildren(!usePipes);
MakeStartJobs();
}
Job_Finish();
/*
* Print the final status of each target. E.g. if it wasn't made
* because some inferior reported an error.
*/
LST_FOREACH(ln, targs)
MakePrintStatus(Lst_Datum(ln), (makeErrors == 0) && (numNodes != 0));
return (TRUE);
}

View File

@ -1,75 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)make.h 8.3 (Berkeley) 6/13/95
* $FreeBSD$
*/
#ifndef make_h_a91074b9
#define make_h_a91074b9
/**
* make.h
* The global definitions for make
*/
#include "util.h"
#define MAKE_JOB_PREFIX ".MAKE.JOB.PREFIX"
struct GNode;
struct Lst;
struct Buffer;
/*
* Warning flags
*/
enum {
WARN_DIRSYNTAX = 0x0001, /* syntax errors in directives */
};
int Make_TimeStamp(struct GNode *, struct GNode *);
Boolean Make_OODate(struct GNode *);
int Make_HandleUse(struct GNode *, struct GNode *);
void Make_Update(struct GNode *);
void Make_DoAllVar(struct GNode *);
Boolean Make_Run(struct Lst *);
void Main_ParseArgLine(char *, int);
int Main_ParseWarn(const char *, int);
void Main_AddSourceMakefile(const char *);
#endif /* make_h_a91074b9 */

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef parse_h_470eeb9a
#define parse_h_470eeb9a
#include <stdio.h>
#include "util.h"
struct GNode;
struct Lst;
/*
* 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
/*
* 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 */
void Parse_Error(int, const char *, ...);
Boolean Parse_AnyExport(void);
Boolean Parse_IsVar(char *);
void Parse_DoVar(char *, struct GNode *);
void Parse_AddIncludeDir(char *);
void Parse_File(const char *, FILE *);
void Parse_FromString(char *, int);
void Parse_MainName(struct Lst *);
#endif /* parse_h_470eeb9a */

View File

@ -1,56 +0,0 @@
/*-
* 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.
*
* @(#)pathnames.h 8.2 (Berkeley) 4/28/95
* $FreeBSD$
*/
#ifndef pathnames_h_235b888a
#define pathnames_h_235b888a
#ifndef PATH_OBJDIR
#define PATH_OBJDIR "obj"
#endif /* ! PATH_OBJDIR */
#ifndef PATH_OBJDIRPREFIX
#define PATH_OBJDIRPREFIX "/usr/obj"
#endif /* ! PATH_OBJDIRPREFIX */
#ifndef PATH_DEFSHELLDIR
#define PATH_DEFSHELLDIR "/bin"
#endif /* ! PATH_DEFSHELLDIR */
#ifndef PATH_DEFSYSMK
#define PATH_DEFSYSMK "sys.mk"
#endif /* ! PATH_DEFSYSMK */
#ifndef PATH_DEFSYSPATH
#define PATH_DEFSYSPATH "/usr/share/mk"
#endif /* ! PATH_DEFSYSPATH */
#endif /* pathnames_h_235b888a */

View File

@ -1,134 +0,0 @@
/*-
* Copyright (C) 2005 Max Okumoto.
* 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 AUTHOR 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 AUTHOR 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "proc.h"
#include "shell.h"
#include "util.h"
/**
* Replace the current process.
*/
void
Proc_Exec(const ProcStuff *ps)
{
if (ps->in != STDIN_FILENO) {
/*
* Redirect the child's stdin to the input fd
* and reset it to the beginning (again).
*/
if (dup2(ps->in, STDIN_FILENO) == -1)
Punt("Cannot dup2: %s", strerror(errno));
lseek(STDIN_FILENO, (off_t)0, SEEK_SET);
}
if (ps->out != STDOUT_FILENO) {
/*
* Redirect the child's stdout to the output fd.
*/
if (dup2(ps->out, STDOUT_FILENO) == -1)
Punt("Cannot dup2: %s", strerror(errno));
close(ps->out);
}
if (ps->err != STDERR_FILENO) {
/*
* Redirect the child's stderr to the err fd.
*/
if (dup2(ps->err, STDERR_FILENO) == -1)
Punt("Cannot dup2: %s", strerror(errno));
close(ps->err);
}
if (ps->merge_errors) {
/*
* Send stderr to parent process too.
*/
if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
Punt("Cannot dup2: %s", strerror(errno));
}
if (commandShell->unsetenv) {
/* for the benfit of ksh */
unsetenv("ENV");
}
/*
* The file descriptors for stdin, stdout, or stderr might
* have been marked close-on-exec. Clear the flag on all
* of them.
*/
fcntl(STDIN_FILENO, F_SETFD,
fcntl(STDIN_FILENO, F_GETFD) & (~FD_CLOEXEC));
fcntl(STDOUT_FILENO, F_SETFD,
fcntl(STDOUT_FILENO, F_GETFD) & (~FD_CLOEXEC));
fcntl(STDERR_FILENO, F_SETFD,
fcntl(STDERR_FILENO, F_GETFD) & (~FD_CLOEXEC));
if (ps->pgroup) {
#ifdef USE_PGRP
/*
* Become a process group leader, so we can kill it and all
* its descendants in one fell swoop, by killing its process
* family, but not commit suicide.
*/
#if defined(SYSV)
setsid();
#else
setpgid(0, getpid());
#endif
#endif /* USE_PGRP */
}
if (ps->searchpath) {
execvp(ps->argv[0], ps->argv);
write(STDERR_FILENO, ps->argv[0], strlen(ps->argv[0]));
write(STDERR_FILENO, ": ", 2);
write(STDERR_FILENO, strerror(errno), strlen(strerror(errno)));
write(STDERR_FILENO, "\n", 1);
} else {
execv(commandShell->path, ps->argv);
write(STDERR_FILENO,
"Could not execute shell\n",
sizeof("Could not execute shell"));
}
/*
* Since we are the child process, exit without flushing buffers.
*/
_exit(1);
}

View File

@ -1,53 +0,0 @@
/*-
* Copyright (C) 2005 Max Okumoto.
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD$
*/
#ifndef proc_h_458845848
#define proc_h_458845848
/**
* Information used to create a new process.
*/
typedef struct ProcStuff {
int in; /* stdin for new process */
int out; /* stdout for new process */
int err; /* stderr for new process */
int merge_errors; /* true if stderr is redirected to stdin */
int pgroup; /* true if new process a process leader */
int searchpath; /* true if binary should be found via $PATH */
char **argv;
int argv_free; /* release argv after use */
int errCheck;
pid_t child_pid;
} ProcStuff;
void Proc_Exec(const ProcStuff *) __dead2;
#endif /* proc_h_458845848 */

View File

@ -1,472 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/queue.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parse.h"
#include "pathnames.h"
#include "shell.h"
#include "util.h"
/*
* Descriptions for various shells. What the list of builtins should contain
* is debatable: either all builtins or only those which may specified on
* a single line without use of meta-characters. For correct makefiles that
* contain only correct command lines there is no difference. But if a command
* line, for example, is: 'if -foo bar' and there is an executable named 'if'
* in the path, the first possibility would execute that 'if' while in the
* second case the shell would give an error. Histerically only a small
* subset of the builtins and no reserved words where given in the list which
* corresponds roughly to the first variant. So go with this but add missing
* words.
*/
#define CSH_BUILTINS \
"alias cd eval exec exit read set ulimit unalias " \
"umask unset wait"
#define SH_BUILTINS \
"alias cd eval exec exit read set ulimit unalias " \
"umask unset wait"
#define CSH_META "#=|^(){};&<>*?[]:$`\\@\n"
#define SH_META "#=|^(){};&<>*?[]:$`\\\n"
static const char *const shells_init[] = {
/*
* CSH description. The csh can do echo control by playing
* with the setting of the 'echo' shell variable. Sadly,
* however, it is unable to do error control nicely.
*/
"name=csh path='" PATH_DEFSHELLDIR "/csh' "
"quiet='unset verbose' echo='set verbose' filter='unset verbose' "
"hasErrCtl=N check='echo \"%s\"\n' ignore='csh -c \"%s || exit 0\"' "
"echoFlag=v errFlag=e "
"meta='" CSH_META "' builtins='" CSH_BUILTINS "'",
/*
* SH description. Echo control is also possible and, under
* sun UNIX anyway, one can even control error checking.
*/
"name=sh path='" PATH_DEFSHELLDIR "/sh' "
"quiet='set -' echo='set -v' filter='set -' "
"hasErrCtl=Y check='set -e' ignore='set +e' "
"echoFlag=v errFlag=e "
"meta='" SH_META "' builtins='" SH_BUILTINS "'",
/*
* KSH description. The Korn shell has a superset of
* the Bourne shell's functionality. There are probably builtins
* missing here.
*/
"name=ksh path='" PATH_DEFSHELLDIR "/ksh' "
"quiet='set -' echo='set -v' filter='set -' "
"hasErrCtl=Y check='set -e' ignore='set +e' "
"echoFlag=v errFlag=e "
"meta='" SH_META "' builtins='" SH_BUILTINS "' unsetenv=T",
NULL
};
/*
* This is the shell to which we pass all commands in the Makefile.
* It is set by the Job_ParseShell function.
*/
struct Shell *commandShell;
/*
* This is the list of all known shells.
*/
static struct Shells shells = TAILQ_HEAD_INITIALIZER(shells);
void ShellDump(const struct Shell *) __unused;
/**
* Helper function for sorting the builtin list alphabetically.
*/
static int
sort_builtins(const void *p1, const void *p2)
{
return (strcmp(*(const char* const*)p1, *(const char* const*)p2));
}
/**
* Free a shell structure and all associated strings.
*/
static void
ShellFree(struct Shell *sh)
{
if (sh != NULL) {
free(sh->name);
free(sh->path);
free(sh->echoOff);
free(sh->echoOn);
free(sh->noPrint);
free(sh->errCheck);
free(sh->ignErr);
free(sh->echo);
free(sh->exit);
ArgArray_Done(&sh->builtins);
free(sh->meta);
free(sh);
}
}
/**
* Dump a shell specification to stderr.
*/
void
ShellDump(const struct Shell *sh)
{
int i;
fprintf(stderr, "Shell %p:\n", sh);
fprintf(stderr, " name='%s' path='%s'\n", sh->name, sh->path);
fprintf(stderr, " hasEchoCtl=%d echoOff='%s' echoOn='%s'\n",
sh->hasEchoCtl, sh->echoOff, sh->echoOn);
fprintf(stderr, " noPrint='%s'\n", sh->noPrint);
fprintf(stderr, " hasErrCtl=%d errCheck='%s' ignErr='%s'\n",
sh->hasErrCtl, sh->errCheck, sh->ignErr);
fprintf(stderr, " echo='%s' exit='%s'\n", sh->echo, sh->exit);
fprintf(stderr, " builtins=%d\n", sh->builtins.argc - 1);
for (i = 1; i < sh->builtins.argc; i++)
fprintf(stderr, " '%s'", sh->builtins.argv[i]);
fprintf(stderr, "\n meta='%s'\n", sh->meta);
fprintf(stderr, " unsetenv=%d\n", sh->unsetenv);
}
/**
* Parse a shell specification line and return the new Shell structure.
* In case of an error a message is printed and NULL is returned.
*/
static struct Shell *
ShellParseSpec(const char *spec, Boolean *fullSpec)
{
ArgArray aa;
struct Shell *sh;
char *eq;
char *keyw;
int arg;
*fullSpec = FALSE;
sh = emalloc(sizeof(*sh));
memset(sh, 0, sizeof(*sh));
ArgArray_Init(&sh->builtins);
/*
* Parse the specification by keyword but skip the first word
*/
brk_string(&aa, spec, TRUE);
for (arg = 1; arg < aa.argc; arg++) {
/*
* Split keyword and value
*/
keyw = aa.argv[arg];
if ((eq = strchr(keyw, '=')) == NULL) {
Parse_Error(PARSE_FATAL, "missing '=' in shell "
"specification keyword '%s'", keyw);
ArgArray_Done(&aa);
ShellFree(sh);
return (NULL);
}
*eq++ = '\0';
if (strcmp(keyw, "path") == 0) {
free(sh->path);
sh->path = estrdup(eq);
} else if (strcmp(keyw, "name") == 0) {
free(sh->name);
sh->name = estrdup(eq);
} else if (strcmp(keyw, "quiet") == 0) {
free(sh->echoOff);
sh->echoOff = estrdup(eq);
*fullSpec = TRUE;
} else if (strcmp(keyw, "echo") == 0) {
free(sh->echoOn);
sh->echoOn = estrdup(eq);
*fullSpec = TRUE;
} else if (strcmp(keyw, "filter") == 0) {
free(sh->noPrint);
sh->noPrint = estrdup(eq);
*fullSpec = TRUE;
} else if (strcmp(keyw, "echoFlag") == 0) {
free(sh->echo);
sh->echo = estrdup(eq);
*fullSpec = TRUE;
} else if (strcmp(keyw, "errFlag") == 0) {
free(sh->exit);
sh->exit = estrdup(eq);
*fullSpec = TRUE;
} else if (strcmp(keyw, "hasErrCtl") == 0) {
sh->hasErrCtl = (*eq == 'Y' || *eq == 'y' ||
*eq == 'T' || *eq == 't');
*fullSpec = TRUE;
} else if (strcmp(keyw, "check") == 0) {
free(sh->errCheck);
sh->errCheck = estrdup(eq);
*fullSpec = TRUE;
} else if (strcmp(keyw, "ignore") == 0) {
free(sh->ignErr);
sh->ignErr = estrdup(eq);
*fullSpec = TRUE;
} else if (strcmp(keyw, "builtins") == 0) {
ArgArray_Done(&sh->builtins);
brk_string(&sh->builtins, eq, TRUE);
qsort(sh->builtins.argv + 1, sh->builtins.argc - 1,
sizeof(char *), sort_builtins);
*fullSpec = TRUE;
} else if (strcmp(keyw, "meta") == 0) {
free(sh->meta);
sh->meta = estrdup(eq);
*fullSpec = TRUE;
} else if (strcmp(keyw, "unsetenv") == 0) {
sh->unsetenv = (*eq == 'Y' || *eq == 'y' ||
*eq == 'T' || *eq == 't');
*fullSpec = TRUE;
} else {
Parse_Error(PARSE_FATAL, "unknown keyword in shell "
"specification '%s'", keyw);
ArgArray_Done(&aa);
ShellFree(sh);
return (NULL);
}
}
ArgArray_Done(&aa);
/*
* Some checks (could be more)
*/
if (*fullSpec) {
if ((sh->echoOn != NULL) ^ (sh->echoOff != NULL)) {
Parse_Error(PARSE_FATAL, "Shell must have either both "
"echoOff and echoOn or none of them");
ShellFree(sh);
return (NULL);
}
if (sh->echoOn != NULL && sh->echoOff != NULL)
sh->hasEchoCtl = TRUE;
}
return (sh);
}
/**
* Parse the builtin shell specifications and put them into the shell
* list. Then select the default shell to be the current shell. This
* is called from main() before any parsing (including MAKEFLAGS and
* command line) is done.
*/
void
Shell_Init(void)
{
int i;
struct Shell *sh;
Boolean fullSpec;
for (i = 0; shells_init[i] != NULL; i++) {
sh = ShellParseSpec(shells_init[i], &fullSpec);
TAILQ_INSERT_TAIL(&shells, sh, link);
if (strcmp(sh->name, DEFSHELLNAME) == 0)
commandShell = sh;
}
}
/**
* Find a matching shell in 'shells' given its final component.
*
* Results:
* A pointer to a freshly allocated Shell structure with the contents
* from static description or NULL if no shell with the given name
* is found.
*/
static struct Shell *
ShellMatch(const char *name)
{
struct Shell *sh;
TAILQ_FOREACH(sh, &shells, link)
if (strcmp(sh->name, name) == 0)
return (sh);
return (NULL);
}
/**
* Parse a shell specification and set up commandShell appropriately.
*
* Results:
* TRUE if the specification was correct. FALSE otherwise.
*
* Side Effects:
* commandShell points to a Shell structure.
* created from the shell spec).
*
* Notes:
* A shell specification consists of a .SHELL target, with dependency
* operator, followed by a series of blank-separated words. Double
* quotes can be used to use blanks in words. A backslash escapes
* anything (most notably a double-quote and a space) and
* provides the functionality it does in C. Each word consists of
* keyword and value separated by an equal sign. There should be no
* unnecessary spaces in the word. The keywords are as follows:
* name Name of shell.
* path Location of shell. Overrides "name" if given
* quiet Command to turn off echoing.
* echo Command to turn echoing on
* filter Result of turning off echoing that shouldn't be
* printed.
* echoFlag Flag to turn echoing on at the start
* errFlag Flag to turn error checking on at the start
* hasErrCtl True if shell has error checking control
* check Command to turn on error checking if hasErrCtl
* is TRUE or template of command to echo a command
* for which error checking is off if hasErrCtl is
* FALSE.
* ignore Command to turn off error checking if hasErrCtl
* is TRUE or template of command to execute a
* command so as to ignore any errors it returns if
* hasErrCtl is FALSE.
* builtins A space separated list of builtins. If one
* of these builtins is detected when make wants
* to execute a command line, the command line is
* handed to the shell. Otherwise make may try to
* execute the command directly. If this list is empty
* it is assumed, that the command must always be
* handed over to the shell.
* meta The shell meta characters. If this is not specified
* or empty, commands are alway passed to the shell.
* Otherwise they are not passed when they contain
* neither a meta character nor a builtin command.
* unsetenv Unsetenv("ENV") before executing anything.
*/
Boolean
Shell_Parse(const char line[])
{
Boolean fullSpec;
struct Shell *sh;
struct Shell *match;
/* parse the specification */
if ((sh = ShellParseSpec(line, &fullSpec)) == NULL)
return (FALSE);
if (sh->path == NULL) {
/*
* If no path was given, the user wants one of the pre-defined
* shells, yes? So we find the one s/he wants with the help of
* JobMatchShell and set things up the right way.
*/
if (sh->name == NULL) {
Parse_Error(PARSE_FATAL,
"Neither path nor name specified");
ShellFree(sh);
return (FALSE);
}
if (fullSpec) {
/*
* XXX May want to merge sh into match. But this
* require ShellParseSpec to return information
* which attributes actuall have been specified.
*/
Parse_Error(PARSE_FATAL, "No path specified");
ShellFree(sh);
return (FALSE);
}
if ((match = ShellMatch(sh->name)) == NULL) {
Parse_Error(PARSE_FATAL, "%s: no matching shell",
sh->name);
ShellFree(sh);
return (FALSE);
}
ShellFree(sh);
commandShell = match;
return (TRUE);
}
/*
* The user provided a path. If s/he gave nothing else
* (fullSpec is FALSE), try and find a matching shell in the
* ones we know of. Else we just take the specification at its
* word and copy it to a new location. In either case, we need
* to record the path the user gave for the shell.
*/
if (sh->name == NULL) {
/* get the base name as the name */
if ((sh->name = strrchr(sh->path, '/')) == NULL) {
sh->name = estrdup(sh->path);
} else {
sh->name = estrdup(sh->name + 1);
}
}
if (!fullSpec) {
if ((match = ShellMatch(sh->name)) == NULL) {
Parse_Error(PARSE_FATAL,
"%s: no matching shell", sh->name);
ShellFree(sh);
return (FALSE);
}
/* set the patch on the matching shell */
free(match->path);
match->path = sh->path;
sh->path = NULL;
ShellFree(sh);
commandShell = match;
return (TRUE);
}
TAILQ_INSERT_HEAD(&shells, sh, link);
/* set the new shell */
commandShell = sh;
return (TRUE);
}

View File

@ -1,110 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef shell_h_6002e3b8
#define shell_h_6002e3b8
#include <sys/queue.h>
#include "str.h"
#include "util.h"
/**
* Shell Specifications:
*
* 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. If either of these
* strings is empty when hasErrCtl is FALSE, the command will be executed
* anyway as is and if it causes an error, so be it.
*/
struct Shell {
TAILQ_ENTRY(Shell) link; /* link all shell descriptions */
/*
* 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.
*/
char *name;
char *path; /* full path to the shell */
/* True if both echoOff and echoOn defined */
Boolean hasEchoCtl;
char *echoOff; /* command to turn off echo */
char *echoOn; /* command to turn it back on */
/*
* What the shell prints, and its length, when given the
* echo-off command. This line will not be printed when
* received from the shell. This is usually the command which
* was executed to turn off echoing
*/
char *noPrint;
/* set if can control error checking for individual commands */
Boolean hasErrCtl;
/* string to turn error checking on */
char *errCheck;
/* string to turn off error checking */
char *ignErr;
char *echo; /* command line flag: echo commands */
char *exit; /* command line flag: exit on error */
ArgArray builtins; /* ordered list of shell builtins */
char *meta; /* shell meta characters */
Boolean unsetenv; /* unsetenv("ENV") before exec */
};
TAILQ_HEAD(Shells, Shell);
extern struct Shell *commandShell;
void Shell_Init(void);
Boolean Shell_Parse(const char []);
#endif /* shell_h_6002e3b8 */

View File

@ -1,559 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)str.c 5.8 (Berkeley) 6/1/90
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include "buf.h"
#include "str.h"
#include "util.h"
/**
* Initialize the argument array object. The array is initially
* eight positions, and will be expanded as necessary. The first
* position is set to NULL since everything ignores it. We allocate
* (size + 1) since we need space for the terminating NULL. The
* buffer is set to NULL, since no common buffer is allocated yet.
*/
void
ArgArray_Init(ArgArray *aa)
{
aa->size = 8;
aa->argv = emalloc((aa->size + 1) * sizeof(char *));
aa->argc = 0;
aa->argv[aa->argc++] = NULL;
aa->len = 0;
aa->buffer = NULL;
}
/**
* Cleanup the memory allocated for in the argument array object.
*/
void
ArgArray_Done(ArgArray *aa)
{
if (aa->buffer == NULL) {
int i;
/* args are individually allocated */
for (i = 0; i < aa->argc; ++i) {
if (aa->argv[i]) {
free(aa->argv[i]);
aa->argv[i] = NULL;
}
}
} else {
/* args are part of a single allocation */
free(aa->buffer);
aa->buffer = NULL;
}
free(aa->argv);
aa->argv = NULL;
aa->argc = 0;
aa->size = 0;
}
/*-
* str_concat --
* concatenate the two strings, inserting a space or slash between them.
*
* 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 = emalloc(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);
}
/**
* Fracture a string into an array of words (as delineated by tabs or
* spaces) taking quotation marks into account. Leading tabs/spaces
* are ignored.
*/
void
brk_string(ArgArray *aa, const char str[], Boolean expand)
{
char inquote;
char *start;
char *arg;
/* skip leading space chars. */
for (; *str == ' ' || *str == '\t'; ++str)
continue;
ArgArray_Init(aa);
aa->buffer = estrdup(str);
arg = aa->buffer;
start = arg;
inquote = '\0';
/*
* copy the string; at the same time, parse backslashes,
* quotes and build the argument list.
*/
for (;;) {
switch (str[0]) {
case '"':
case '\'':
if (inquote == '\0') {
inquote = str[0];
if (expand)
break;
if (start == NULL)
start = arg;
} else if (inquote == str[0]) {
inquote = '\0';
/* Don't miss "" or '' */
if (start == NULL)
start = arg;
if (expand)
break;
} else {
/* other type of quote found */
if (start == NULL)
start = arg;
}
*arg++ = str[0];
break;
case ' ':
case '\t':
case '\n':
if (inquote) {
if (start == NULL)
start = arg;
*arg++ = str[0];
break;
}
if (start == NULL)
break;
/* FALLTHROUGH */
case '\0':
/*
* end of a token -- make sure there's enough argv
* space and save off a pointer.
*/
if (aa->argc == aa->size) {
aa->size *= 2; /* ramp up fast */
aa->argv = erealloc(aa->argv,
(aa->size + 1) * sizeof(char *));
}
*arg++ = '\0';
if (start == NULL) {
aa->argv[aa->argc] = start;
return;
}
if (str[0] == '\n' || str[0] == '\0') {
aa->argv[aa->argc++] = start;
aa->argv[aa->argc] = NULL;
return;
} else {
aa->argv[aa->argc++] = start;
start = NULL;
break;
}
case '\\':
if (start == NULL)
start = arg;
if (expand) {
switch (str[1]) {
case '\0':
case '\n':
/* hmmm; fix it up as best we can */
*arg++ = '\\';
break;
case 'b':
*arg++ = '\b';
++str;
break;
case 'f':
*arg++ = '\f';
++str;
break;
case 'n':
*arg++ = '\n';
++str;
break;
case 'r':
*arg++ = '\r';
++str;
break;
case 't':
*arg++ = '\t';
++str;
break;
default:
*arg++ = str[1];
++str;
break;
}
} else {
*arg++ = str[0];
if (str[1] != '\0') {
++str;
*arg++ = str[0];
}
}
break;
default:
if (start == NULL)
start = arg;
*arg++ = str[0];
break;
}
++str;
}
}
/*
* Quote a string for appending it to MAKEFLAGS. According to Posix the
* kind of quoting here is implementation-defined. This quoting must ensure
* that the parsing of MAKEFLAGS's contents in a sub-shell yields the same
* options, option arguments and macro definitions as in the calling make.
* We simply quote all blanks, which according to Posix are space and tab
* in the POSIX locale. Don't use isblank because in that case makes with
* different locale settings could not communicate. We must also quote
* backslashes obviously.
*/
char *
MAKEFLAGS_quote(const char *str)
{
char *ret, *q;
const char *p;
/* assume worst case - everything has to be quoted */
ret = emalloc(strlen(str) * 2 + 1);
p = str;
q = ret;
while (*p != '\0') {
switch (*p) {
case ' ':
case '\t':
*q++ = '\\';
break;
default:
break;
}
*q++ = *p++;
}
*q++ = '\0';
return (ret);
}
void
MAKEFLAGS_break(ArgArray *aa, const char str[])
{
char *arg;
char *start;
ArgArray_Init(aa);
aa->buffer = strdup(str);
arg = aa->buffer;
start = NULL;
for (;;) {
switch (str[0]) {
case ' ':
case '\t':
/* word separator */
if (start == NULL) {
/* not in a word */
str++;
continue;
}
/* FALLTHRU */
case '\0':
if (aa->argc == aa->size) {
aa->size *= 2;
aa->argv = erealloc(aa->argv,
(aa->size + 1) * sizeof(char *));
}
*arg++ = '\0';
if (start == NULL) {
aa->argv[aa->argc] = start;
return;
}
if (str[0] == '\0') {
aa->argv[aa->argc++] = start;
aa->argv[aa->argc] = NULL;
return;
} else {
aa->argv[aa->argc++] = start;
start = NULL;
str++;
continue;
}
case '\\':
if (str[1] == ' ' || str[1] == '\t')
str++;
break;
default:
break;
}
if (start == NULL)
start = arg;
*arg++ = *str++;
}
}
/*
* 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),
*
* Results:
* Returns the beginning position of a match or null. The number
* of characters matched is returned in len.
*/
const char *
Str_SYSVMatch(const char *word, const char *pattern, int *len)
{
const char *m, *p, *w;
p = pattern;
w = word;
if (*w == '\0') {
/* Zero-length word cannot be matched against */
*len = 0;
return (NULL);
}
if (*p == '\0') {
/* Null pattern is the whole string */
*len = strlen(w);
return (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 (w);
}
}
m = w;
/* Find a matching tail */
do
if (strcmp(p, w) == 0) {
*len = w - m;
return (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.
*
* Side Effects:
* Places result on buf
*/
void
Str_SYSVSubst(Buffer *buf, const char *pat, const char *src, int len)
{
const char *m;
if ((m = strchr(pat, '%')) != NULL) {
/* Copy the prefix */
Buf_AppendRange(buf, pat, m);
/* skip the % */
pat = m + 1;
}
/* Copy the pattern */
Buf_AddBytes(buf, len, (const Byte *)src);
/* append the rest */
Buf_Append(buf, pat);
}

View File

@ -1,81 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef str_h_44db59e6
#define str_h_44db59e6
#include "util.h"
struct Buffer;
/**
* An array of c-strings. The pointers stored in argv, point to
* strings stored in buffer.
*/
typedef struct ArgArray {
int size; /* size of argv array */
int argc; /* strings referenced in argv */
char **argv; /* array of string pointers */
size_t len; /* size of buffer */
char *buffer; /* data buffer */
} ArgArray;
/*
* 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.
*/
#define STR_ADDSPACE 0x01 /* add a space when Str_Concat'ing */
#define STR_ADDSLASH 0x04 /* add a slash when Str_Concat'ing */
void ArgArray_Init(ArgArray *);
void ArgArray_Done(ArgArray *);
char *str_concat(const char *, const char *, int);
void brk_string(ArgArray *, const char [], Boolean);
char *MAKEFLAGS_quote(const char *);
void MAKEFLAGS_break(ArgArray *, const char []);
int Str_Match(const char *, const char *);
const char *Str_SYSVMatch(const char *, const char *, int *);
void Str_SYSVSubst(struct Buffer *, const char *, const char *, int);
#endif /* str_h_44db59e6 */

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef suff_h_2d5a821c
#define suff_h_2d5a821c
struct GNode;
struct Path;
void Suff_ClearSuffixes(void);
Boolean Suff_IsTransform(char *);
struct GNode *Suff_AddTransform(char *);
void Suff_EndTransform(const struct GNode *);
void Suff_AddSuffix(char *);
struct Path *Suff_GetPath(char *);
void Suff_DoPaths(void);
void Suff_AddInclude(char *);
void Suff_AddLib(char *);
void Suff_FindDeps(struct GNode *);
void Suff_SetNull(char *);
void Suff_Init(void);
void Suff_PrintAll(void);
#endif /* suff_h_2d5a821c */

View File

@ -1,472 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)targ.c 8.2 (Berkeley) 3/19/94
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* 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_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.
*
* 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 "dir.h"
#include "globals.h"
#include "GNode.h"
#include "hash.h"
#include "suff.h"
#include "targ.h"
#include "util.h"
#include "var.h"
/* the list of all targets found so far */
static Lst allTargets = Lst_Initializer(allTargets);
static Hash_Table targets; /* a hash table of same */
#define HTSIZE 191 /* initial size of hash table */
/**
* Targ_Init
* Initialize this module
*
* Side Effects:
* The allTargets list and the targets hash table are initialized
*/
void
Targ_Init(void)
{
Hash_InitTable(&targets, HTSIZE);
}
/**
* Targ_NewGN
* Create and initialize a new graph 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 = emalloc(sizeof(GNode));
gn->name = estrdup(name);
gn->path = NULL;
if (name[0] == '-' && name[1] == 'l') {
gn->type = OP_LIB;
} else {
gn->type = 0;
}
gn->unmade = 0;
gn->make = FALSE;
gn->made = UNMADE;
gn->childMade = FALSE;
gn->order = 0;
gn->mtime = gn->cmtime = 0;
gn->cmtime_gn = NULL;
Lst_Init(&gn->iParents);
Lst_Init(&gn->cohorts);
Lst_Init(&gn->parents);
Lst_Init(&gn->children);
Lst_Init(&gn->successors);
Lst_Init(&gn->preds);
Lst_Init(&gn->context);
Lst_Init(&gn->commands);
gn->suffix = NULL;
return (gn);
}
/**
* Targ_FindNode
* Find a node in the list using the given name for matching
*
* 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) {
he = Hash_CreateEntry(&targets, name, &isNew);
if (isNew) {
gn = Targ_NewGN(name);
Hash_SetValue(he, gn);
Lst_AtEnd(&allTargets, gn);
}
} else {
he = Hash_FindEntry(&targets, name);
}
if (he == NULL) {
return (NULL);
} else {
return (Hash_GetValue(he));
}
}
/**
* Targ_FindList
* Make a complete list of GNodes from the given list of names
*
* Results:
* A complete list of graph nodes corresponding to all instances of all
* the names in names.
*
* 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.
*/
void
Targ_FindList(Lst *nodes, Lst *names, int flags)
{
LstNode *ln; /* name list element */
GNode *gn; /* node in tLn */
char *name;
for (ln = Lst_First(names); ln != NULL; ln = Lst_Succ(ln)) {
name = 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.
*/
Lst_AtEnd(nodes, gn);
if (gn->type & OP_DOUBLEDEP) {
Lst_Concat(nodes, &gn->cohorts, LST_CONCNEW);
}
} else if (flags == TARG_NOCREATE) {
Error("\"%s\" -- target unknown.", name);
}
}
}
/**
* Targ_Ignore
* Return true if should ignore errors when creating gn
*
* Results:
* TRUE if should ignore errors
*/
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
*
* Results:
* TRUE if should be silent
*/
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
*
* Results:
* TRUE if it is precious. FALSE otherwise
*/
Boolean
Targ_Precious(GNode *gn)
{
if (allPrecious || (gn->type & (OP_PRECIOUS | OP_DOUBLEDEP))) {
return (TRUE);
} else {
return (FALSE);
}
}
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.
*
* Side Effects:
* "mainTarg" is set to the main target's node.
*/
void
Targ_SetMain(GNode *gn)
{
mainTarg = gn;
}
/**
* 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 modtime)
{
struct tm *parts;
static char buf[128];
parts = localtime(&modtime);
strftime(buf, sizeof(buf), "%H:%M:%S %b %d, %Y", parts);
buf[sizeof(buf) - 1] = '\0';
return (buf);
}
/**
* Targ_PrintType
* Print out a type field giving only those attributes the user can
* set.
*/
void
Targ_PrintType(int type)
{
static const struct flag2str type2str[] = {
{ OP_OPTIONAL, ".OPTIONAL" },
{ OP_USE, ".USE" },
{ OP_EXEC, ".EXEC" },
{ OP_IGNORE, ".IGNORE" },
{ OP_PRECIOUS, ".PRECIOUS" },
{ OP_SILENT, ".SILENT" },
{ OP_MAKE, ".MAKE" },
{ OP_JOIN, ".JOIN" },
{ OP_INVISIBLE, ".INVISIBLE" },
{ OP_NOTMAIN, ".NOTMAIN" },
{ OP_PHONY, ".PHONY" },
{ OP_LIB, ".LIB" },
{ OP_MEMBER, ".MEMBER" },
{ OP_ARCHV, ".ARCHV" },
{ 0, NULL }
};
type &= ~OP_OPMASK;
if (!DEBUG(TARG))
type &= ~(OP_ARCHV | OP_LIB | OP_MEMBER);
print_flags(stdout, type2str, type, 0);
}
/**
* TargPrintNode
* print the contents of a node
*/
static int
TargPrintNode(const GNode *gn, int pass)
{
const LstNode *tln;
if (!OP_NOP(gn->type)) {
printf("#\n");
if (gn == mainTarg) {
printf("# *** MAIN TARGET ***\n");
}
if (pass == 2) {
if (gn->unmade) {
printf("# %d unmade children\n", gn->unmade);
} else {
printf("# No unmade children\n");
}
if (!(gn->type & (OP_JOIN | OP_USE | OP_EXEC))) {
if (gn->mtime != 0) {
printf("# last modified %s: %s\n",
Targ_FmtTime(gn->mtime),
gn->made == UNMADE ? "unmade" :
gn->made == MADE ? "made" :
gn->made == UPTODATE ? "up-to-date":
"error when made");
} else if (gn->made != UNMADE) {
printf("# non-existent (maybe): %s\n",
gn->made == MADE ? "made" :
gn->made == UPTODATE ? "up-to-date":
gn->made == ERROR?"error when made":
"aborted");
} else {
printf("# unmade\n");
}
}
if (!Lst_IsEmpty(&gn->iParents)) {
printf("# implicit parents: ");
LST_FOREACH(tln, &gn->iParents)
printf("%s ", ((const GNode *)
Lst_Datum(tln))->name);
printf("\n");
}
}
if (!Lst_IsEmpty(&gn->parents)) {
printf("# parents: ");
LST_FOREACH(tln, &gn->parents)
printf("%s ", ((const GNode *)
Lst_Datum(tln))->name);
printf("\n");
}
printf("%-16s", gn->name);
switch (gn->type & OP_OPMASK) {
case OP_DEPENDS:
printf(": ");
break;
case OP_FORCE:
printf("! ");
break;
case OP_DOUBLEDEP:
printf(":: ");
break;
default:
break;
}
Targ_PrintType(gn->type);
LST_FOREACH(tln, &gn->children)
printf("%s ", ((const GNode *)Lst_Datum(tln))->name);
printf("\n");
LST_FOREACH(tln, &gn->commands)
printf("\t%s\n", (const char *)Lst_Datum(tln));
printf("\n\n");
if (gn->type & OP_DOUBLEDEP) {
LST_FOREACH(tln, &gn->cohorts)
TargPrintNode((const GNode *)Lst_Datum(tln),
pass);
}
}
return (0);
}
/**
* Targ_PrintGraph
* Print the entire graph.
*/
void
Targ_PrintGraph(int pass)
{
const GNode *gn;
const LstNode *tln;
printf("#*** Input graph:\n");
LST_FOREACH(tln, &allTargets)
TargPrintNode((const GNode *)Lst_Datum(tln), pass);
printf("\n\n");
printf("#\n# Files that are only sources:\n");
LST_FOREACH(tln, &allTargets) {
gn = Lst_Datum(tln);
if (OP_NOP(gn->type))
printf("#\t%s [%s]\n", gn->name,
gn->path ? gn->path : gn->name);
}
Var_Dump();
printf("\n");
Dir_PrintDirectories();
printf("\n");
Suff_PrintAll();
}

View File

@ -1,73 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef targ_h_6ded1830
#define targ_h_6ded1830
#include <time.h>
/*
* 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_CREATE 0x01 /* create node if not found */
#define TARG_NOCREATE 0x00 /* don't create it */
struct GNode;
struct Lst;
void Targ_Init(void);
struct GNode *Targ_NewGN(const char *);
struct GNode *Targ_FindNode(const char *, int);
void Targ_FindList(struct Lst *, struct Lst *, int);
Boolean Targ_Ignore(struct GNode *);
Boolean Targ_Silent(struct GNode *);
Boolean Targ_Precious(struct GNode *);
void Targ_SetMain(struct GNode *);
int Targ_PrintCmd(void *, void *);
char *Targ_FmtTime(time_t);
void Targ_PrintType(int);
void Targ_PrintGraph(int);
#endif /* targ_h_6ded1830 */

View File

@ -1,316 +0,0 @@
/*-
* Copyright (c) 2002 Juli Mallett. All rights reserved.
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* @(#)main.c 8.3 (Berkeley) 3/19/94
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*-
* util.c --
* General utilitarian routines for make(1).
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <err.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "globals.h"
#include "job.h"
#include "targ.h"
#include "util.h"
static void enomem(void) __dead2;
/*-
* Debug --
* Print a debugging message given its format.
*
* Results:
* None.
*
* Side Effects:
* The message is printed.
*/
/* VARARGS */
void
Debug(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fflush(stderr);
}
/*-
* Print a debugging message given its format and append the current
* errno description. Terminate with a newline.
*/
/* VARARGS */
void
DebugM(const char *fmt, ...)
{
va_list ap;
int e = errno;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
fprintf(stderr, ": %s\n", strerror(e));
va_end(ap);
fflush(stderr);
}
/*-
* Error --
* Print an error message given its format.
*
* Results:
* None.
*
* Side Effects:
* The message is printed.
*/
/* VARARGS */
void
Error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
fflush(stderr);
}
/*-
* Fatal --
* Produce a Fatal error message. If jobs are running, waits for them
* to finish.
*
* Results:
* None
*
* Side Effects:
* The program exits
*/
/* VARARGS */
void
Fatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (jobsRunning)
Job_Wait();
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
fflush(stderr);
if (DEBUG(GRAPH2))
Targ_PrintGraph(2);
exit(2); /* Not 1 so -q can distinguish error */
}
/*
* Punt --
* Major exception once jobs are being created. Kills all jobs, prints
* a message and exits.
*
* Results:
* None
*
* Side Effects:
* All children are killed indiscriminately and the program Lib_Exits
*/
/* VARARGS */
void
Punt(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "make: ");
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
fflush(stderr);
DieHorribly();
}
/*-
* DieHorribly --
* Exit without giving a message.
*
* Results:
* None
*
* Side Effects:
* A big one...
*/
void
DieHorribly(void)
{
if (jobsRunning)
Job_AbortAll();
if (DEBUG(GRAPH2))
Targ_PrintGraph(2);
exit(2); /* Not 1, so -q can distinguish error */
}
/*
* Finish --
* Called when aborting due to errors in child shell to signal
* abnormal exit, with the number of errors encountered in Make_Make.
*
* Results:
* None
*
* Side Effects:
* The program exits
*/
void
Finish(int errors)
{
Fatal("%d error%s", errors, errors == 1 ? "" : "s");
}
/*
* emalloc --
* malloc, but die on error.
*/
void *
emalloc(size_t len)
{
void *p;
if ((p = malloc(len)) == NULL)
enomem();
return (p);
}
/*
* estrdup --
* strdup, but die on error.
*/
char *
estrdup(const char *str)
{
char *p;
if ((p = strdup(str)) == NULL)
enomem();
return (p);
}
/*
* erealloc --
* realloc, but die on error.
*/
void *
erealloc(void *ptr, size_t size)
{
if ((ptr = realloc(ptr, size)) == NULL)
enomem();
return (ptr);
}
/*
* enomem --
* die when out of memory.
*/
static void
enomem(void)
{
err(2, NULL);
}
/*
* enunlink --
* Remove a file carefully, avoiding directories.
*/
int
eunlink(const char *file)
{
struct stat st;
if (lstat(file, &st) == -1)
return (-1);
if (S_ISDIR(st.st_mode)) {
errno = EISDIR;
return (-1);
}
return (unlink(file));
}
/*
* Convert a flag word to a printable thing and print it
*/
void
print_flags(FILE *fp, const struct flag2str *tab, u_int flags, int par)
{
int first = 1;
if (par)
fprintf(fp, "(");
while (tab->str != NULL) {
if (flags & tab->flag) {
if (!first)
fprintf(fp, par ? "|" : " ");
first = 0;
fprintf(fp, "%s", tab->str);
}
tab++;
}
if (par)
fprintf(fp, ")");
}

View File

@ -1,116 +0,0 @@
/*-
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef util_h_b7020fdb
#define util_h_b7020fdb
#include <sys/types.h>
#include <stdio.h>
/*
* 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
#define FALSE 0
#endif /* TRUE */
#define CONCAT(a,b) a##b
struct flag2str {
u_int flag;
const char *str;
};
/*
* debug control:
* There is one bit per module. It is up to the module what debug
* information to print.
*/
#define DEBUG_ARCH 0x0001
#define DEBUG_COND 0x0002
#define DEBUG_DIR 0x0004
#define DEBUG_GRAPH1 0x0008
#define DEBUG_GRAPH2 0x0010
#define DEBUG_JOB 0x0020
#define DEBUG_MAKE 0x0040
#define DEBUG_SUFF 0x0080
#define DEBUG_TARG 0x0100
#define DEBUG_VAR 0x0200
#define DEBUG_FOR 0x0400
#define DEBUG_LOUD 0x0800
#define DEBUG(module) (debug & CONCAT(DEBUG_,module))
#define DEBUGF(module,args) \
do { \
if (DEBUG(module)) { \
Debug args ; \
} \
} while (0)
#define DEBUGM(module, args) do { \
if (DEBUG(module)) { \
DebugM args; \
} \
} while (0)
#define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
#define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
#ifndef MAX
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
void Debug(const char *, ...);
void DebugM(const char *, ...);
void Error(const char *, ...);
void Fatal(const char *, ...) __dead2;
void Punt(const char *, ...) __dead2;
void DieHorribly(void) __dead2;
void Finish(int) __dead2;
char *estrdup(const char *);
void *emalloc(size_t);
void *erealloc(void *, size_t);
int eunlink(const char *);
void print_flags(FILE *, const struct flag2str *, u_int, int);
#endif /* util_h_b7020fdb */

File diff suppressed because it is too large Load Diff

View File

@ -1,85 +0,0 @@
/*-
* Copyright (c) 2002 Juli Mallett.
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* 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.
*
* $FreeBSD$
*/
#ifndef var_h_9cccafce
#define var_h_9cccafce
struct Buffer;
struct GNode;
struct List;
/* Variables defined in a global context, e.g in the Makefile itself */
extern struct GNode *VAR_GLOBAL;
/* Variables defined on the command line */
extern struct GNode *VAR_CMD;
/*
* 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 char var_Error[];
/*
* TRUE if environment should be searched for all variables before
* the global context
*/
extern Boolean checkEnvFirst;
/* Do old-style variable substitution */
extern Boolean oldVars;
void Var_Append(const char *, const char *, struct GNode *);
void Var_Delete(const char *, struct GNode *);
void Var_Dump(void);
Boolean Var_Exists(const char *, struct GNode *);
void Var_Init(char **);
size_t Var_Match(const char [], struct GNode *);
char *Var_Parse(const char *, struct GNode *, Boolean, size_t *, Boolean *);
void Var_Print(struct Lst *, Boolean);
void Var_Set(const char *, const char *, struct GNode *);
void Var_SetGlobal(const char *, const char *);
void Var_SetEnv(const char *, struct GNode *);
struct Buffer *Var_Subst(const char *, struct GNode *, Boolean);
struct Buffer *Var_SubstOnly(const char *, const char *, Boolean);
const char *Var_Value(const char [], struct GNode *);
#endif /* var_h_9cccafce */