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:
parent
708694f704
commit
32c88b5252
4
UPDATING
4
UPDATING
@ -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
|
||||
|
@ -179,7 +179,6 @@ __DEFAULT_NO_OPTIONS = \
|
||||
BSD_GREP \
|
||||
CLANG_EXTRAS \
|
||||
EISA \
|
||||
FMAKE \
|
||||
HESIOD \
|
||||
LLDB \
|
||||
NAND \
|
||||
|
@ -253,10 +253,6 @@ SUBDIR+= file
|
||||
SUBDIR+= finger
|
||||
.endif
|
||||
|
||||
.if ${MK_FMAKE} != "no"
|
||||
SUBDIR+= make
|
||||
.endif
|
||||
|
||||
.if ${MK_FTP} != "no"
|
||||
SUBDIR+= ftp
|
||||
.endif
|
||||
|
@ -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 */
|
@ -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>
|
@ -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
|
@ -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
|
1224
usr.bin/make/arch.c
1224
usr.bin/make/arch.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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';
|
||||
}
|
@ -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 */
|
1221
usr.bin/make/cond.c
1221
usr.bin/make/cond.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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 */
|
1217
usr.bin/make/dir.c
1217
usr.bin/make/dir.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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);
|
||||
}
|
@ -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 */
|
@ -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 */
|
@ -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);
|
||||
}
|
@ -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 */
|
@ -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;
|
||||
}
|
@ -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
|
3391
usr.bin/make/job.c
3391
usr.bin/make/job.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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);
|
||||
}
|
@ -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 */
|
1339
usr.bin/make/main.c
1339
usr.bin/make/main.c
File diff suppressed because it is too large
Load Diff
1843
usr.bin/make/make.1
1843
usr.bin/make/make.1
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
@ -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 */
|
2545
usr.bin/make/parse.c
2545
usr.bin/make/parse.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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 */
|
@ -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);
|
||||
}
|
@ -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 */
|
@ -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);
|
||||
}
|
@ -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 */
|
@ -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);
|
||||
}
|
@ -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 */
|
2205
usr.bin/make/suff.c
2205
usr.bin/make/suff.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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();
|
||||
}
|
@ -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 */
|
@ -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, ")");
|
||||
}
|
@ -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 */
|
2623
usr.bin/make/var.c
2623
usr.bin/make/var.c
File diff suppressed because it is too large
Load Diff
@ -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 */
|
Loading…
Reference in New Issue
Block a user