From 868a3892a6e95948e5a743bfa136fbe8ff2f7bf3 Mon Sep 17 00:00:00 2001 From: reed Date: Tue, 1 Nov 2005 01:06:02 +0000 Subject: bootstrap script uses source files from pkgsrc/devel/bmake/files for "bmake". Remove all of bmake source from this bootstrap. Keep bootstrap/bmake/mk -- copy to files-mk (so the bmake "boot-strap" doesn't notice the mk*). This was tested on DragonFly, NetBSD and some on Linux. Hopefully all the fixes to boostrap's bmake are included in devel/bmake/files. Note that the "mk" files is still not using devel/mk-files. --- bootstrap/bmake/ChangeLog | 219 -- bootstrap/bmake/FILES | 83 - bootstrap/bmake/Makefile.in | 118 - bootstrap/bmake/PSD.doc/Makefile | 8 - bootstrap/bmake/PSD.doc/tutorial.ms | 3744 ------------------------------ bootstrap/bmake/README | 110 - bootstrap/bmake/aclocal.m4 | 77 - bootstrap/bmake/arch.c | 1344 ----------- bootstrap/bmake/bit.h | 102 - bootstrap/bmake/buf.c | 308 --- bootstrap/bmake/buf.h | 79 - bootstrap/bmake/compat.c | 636 ----- bootstrap/bmake/cond.c | 1351 ----------- bootstrap/bmake/config.h.in | 182 -- bootstrap/bmake/configure | 2966 ----------------------- bootstrap/bmake/configure.in | 210 -- bootstrap/bmake/dir.c | 1470 ------------ bootstrap/bmake/dir.h | 72 - bootstrap/bmake/find_lib.sh | 13 - bootstrap/bmake/for.c | 390 ---- bootstrap/bmake/getenv.c | 90 - bootstrap/bmake/getopt.c | 179 -- bootstrap/bmake/hash.c | 429 ---- bootstrap/bmake/hash.h | 118 - bootstrap/bmake/install-sh | 201 -- bootstrap/bmake/job.c | 3483 --------------------------- bootstrap/bmake/job.h | 265 --- bootstrap/bmake/list.h | 300 --- bootstrap/bmake/lst.h | 166 -- bootstrap/bmake/lst.lib/Makefile | 10 - bootstrap/bmake/lst.lib/lstAppend.c | 124 - bootstrap/bmake/lst.lib/lstAtEnd.c | 81 - bootstrap/bmake/lst.lib/lstAtFront.c | 82 - bootstrap/bmake/lst.lib/lstClose.c | 88 - bootstrap/bmake/lst.lib/lstConcat.c | 187 -- bootstrap/bmake/lst.lib/lstDatum.c | 82 - bootstrap/bmake/lst.lib/lstDeQueue.c | 92 - bootstrap/bmake/lst.lib/lstDestroy.c | 113 - bootstrap/bmake/lst.lib/lstDupl.c | 110 - bootstrap/bmake/lst.lib/lstEnQueue.c | 84 - bootstrap/bmake/lst.lib/lstFind.c | 81 - bootstrap/bmake/lst.lib/lstFindFrom.c | 105 - bootstrap/bmake/lst.lib/lstFirst.c | 82 - bootstrap/bmake/lst.lib/lstForEach.c | 83 - bootstrap/bmake/lst.lib/lstForEachFrom.c | 123 - bootstrap/bmake/lst.lib/lstInit.c | 87 - bootstrap/bmake/lst.lib/lstInsert.c | 124 - bootstrap/bmake/lst.lib/lstInt.h | 113 - bootstrap/bmake/lst.lib/lstIsAtEnd.c | 92 - bootstrap/bmake/lst.lib/lstIsEmpty.c | 80 - bootstrap/bmake/lst.lib/lstLast.c | 82 - bootstrap/bmake/lst.lib/lstMember.c | 80 - bootstrap/bmake/lst.lib/lstNext.c | 125 - bootstrap/bmake/lst.lib/lstOpen.c | 92 - bootstrap/bmake/lst.lib/lstRemove.c | 142 -- bootstrap/bmake/lst.lib/lstReplace.c | 84 - bootstrap/bmake/lst.lib/lstSucc.c | 84 - bootstrap/bmake/lst.lib/makefile.boot.in | 45 - bootstrap/bmake/machine.sh | 85 - bootstrap/bmake/main.c | 1795 -------------- bootstrap/bmake/make-conf.h | 133 -- bootstrap/bmake/make.1 | 1265 ---------- bootstrap/bmake/make.c | 1107 --------- bootstrap/bmake/make.h | 438 ---- bootstrap/bmake/makefile.boot.in | 60 - bootstrap/bmake/missing/sys/cdefs.h | 176 -- bootstrap/bmake/mkdeps.sh | 322 --- bootstrap/bmake/nonints.h | 154 -- bootstrap/bmake/parse.c | 2825 ---------------------- bootstrap/bmake/pathnames.h | 52 - bootstrap/bmake/ranlib.h | 30 - bootstrap/bmake/setenv.c | 154 -- bootstrap/bmake/sigcompat.c | 334 --- bootstrap/bmake/sprite.h | 113 - bootstrap/bmake/str.c | 472 ---- bootstrap/bmake/suff.c | 2544 -------------------- bootstrap/bmake/targ.c | 726 ------ bootstrap/bmake/trace.c | 125 - bootstrap/bmake/trace.h | 56 - bootstrap/bmake/util.c | 506 ---- bootstrap/bmake/var.c | 2928 ----------------------- bootstrap/bmake/wait.h | 81 - bootstrap/bootstrap | 15 +- 83 files changed, 9 insertions(+), 37957 deletions(-) delete mode 100644 bootstrap/bmake/ChangeLog delete mode 100644 bootstrap/bmake/FILES delete mode 100644 bootstrap/bmake/Makefile.in delete mode 100644 bootstrap/bmake/PSD.doc/Makefile delete mode 100644 bootstrap/bmake/PSD.doc/tutorial.ms delete mode 100644 bootstrap/bmake/README delete mode 100644 bootstrap/bmake/aclocal.m4 delete mode 100644 bootstrap/bmake/arch.c delete mode 100644 bootstrap/bmake/bit.h delete mode 100644 bootstrap/bmake/buf.c delete mode 100644 bootstrap/bmake/buf.h delete mode 100644 bootstrap/bmake/compat.c delete mode 100644 bootstrap/bmake/cond.c delete mode 100644 bootstrap/bmake/config.h.in delete mode 100755 bootstrap/bmake/configure delete mode 100644 bootstrap/bmake/configure.in delete mode 100644 bootstrap/bmake/dir.c delete mode 100644 bootstrap/bmake/dir.h delete mode 100755 bootstrap/bmake/find_lib.sh delete mode 100644 bootstrap/bmake/for.c delete mode 100644 bootstrap/bmake/getenv.c delete mode 100644 bootstrap/bmake/getopt.c delete mode 100644 bootstrap/bmake/hash.c delete mode 100644 bootstrap/bmake/hash.h delete mode 100755 bootstrap/bmake/install-sh delete mode 100644 bootstrap/bmake/job.c delete mode 100644 bootstrap/bmake/job.h delete mode 100644 bootstrap/bmake/list.h delete mode 100644 bootstrap/bmake/lst.h delete mode 100644 bootstrap/bmake/lst.lib/Makefile delete mode 100644 bootstrap/bmake/lst.lib/lstAppend.c delete mode 100644 bootstrap/bmake/lst.lib/lstAtEnd.c delete mode 100644 bootstrap/bmake/lst.lib/lstAtFront.c delete mode 100644 bootstrap/bmake/lst.lib/lstClose.c delete mode 100644 bootstrap/bmake/lst.lib/lstConcat.c delete mode 100644 bootstrap/bmake/lst.lib/lstDatum.c delete mode 100644 bootstrap/bmake/lst.lib/lstDeQueue.c delete mode 100644 bootstrap/bmake/lst.lib/lstDestroy.c delete mode 100644 bootstrap/bmake/lst.lib/lstDupl.c delete mode 100644 bootstrap/bmake/lst.lib/lstEnQueue.c delete mode 100644 bootstrap/bmake/lst.lib/lstFind.c delete mode 100644 bootstrap/bmake/lst.lib/lstFindFrom.c delete mode 100644 bootstrap/bmake/lst.lib/lstFirst.c delete mode 100644 bootstrap/bmake/lst.lib/lstForEach.c delete mode 100644 bootstrap/bmake/lst.lib/lstForEachFrom.c delete mode 100644 bootstrap/bmake/lst.lib/lstInit.c delete mode 100644 bootstrap/bmake/lst.lib/lstInsert.c delete mode 100644 bootstrap/bmake/lst.lib/lstInt.h delete mode 100644 bootstrap/bmake/lst.lib/lstIsAtEnd.c delete mode 100644 bootstrap/bmake/lst.lib/lstIsEmpty.c delete mode 100644 bootstrap/bmake/lst.lib/lstLast.c delete mode 100644 bootstrap/bmake/lst.lib/lstMember.c delete mode 100644 bootstrap/bmake/lst.lib/lstNext.c delete mode 100644 bootstrap/bmake/lst.lib/lstOpen.c delete mode 100644 bootstrap/bmake/lst.lib/lstRemove.c delete mode 100644 bootstrap/bmake/lst.lib/lstReplace.c delete mode 100644 bootstrap/bmake/lst.lib/lstSucc.c delete mode 100644 bootstrap/bmake/lst.lib/makefile.boot.in delete mode 100755 bootstrap/bmake/machine.sh delete mode 100644 bootstrap/bmake/main.c delete mode 100644 bootstrap/bmake/make-conf.h delete mode 100644 bootstrap/bmake/make.1 delete mode 100644 bootstrap/bmake/make.c delete mode 100644 bootstrap/bmake/make.h delete mode 100644 bootstrap/bmake/makefile.boot.in delete mode 100644 bootstrap/bmake/missing/sys/cdefs.h delete mode 100755 bootstrap/bmake/mkdeps.sh delete mode 100644 bootstrap/bmake/nonints.h delete mode 100644 bootstrap/bmake/parse.c delete mode 100644 bootstrap/bmake/pathnames.h delete mode 100644 bootstrap/bmake/ranlib.h delete mode 100644 bootstrap/bmake/setenv.c delete mode 100644 bootstrap/bmake/sigcompat.c delete mode 100644 bootstrap/bmake/sprite.h delete mode 100644 bootstrap/bmake/str.c delete mode 100644 bootstrap/bmake/suff.c delete mode 100644 bootstrap/bmake/targ.c delete mode 100644 bootstrap/bmake/trace.c delete mode 100644 bootstrap/bmake/trace.h delete mode 100644 bootstrap/bmake/util.c delete mode 100644 bootstrap/bmake/var.c delete mode 100644 bootstrap/bmake/wait.h diff --git a/bootstrap/bmake/ChangeLog b/bootstrap/bmake/ChangeLog deleted file mode 100644 index f0411f16266..00000000000 --- a/bootstrap/bmake/ChangeLog +++ /dev/null @@ -1,219 +0,0 @@ -Tue Oct 16 12:18:42 2001 Simon J. Gerraty - - * Merge with NetBSD make - pick up fix for .END failure in compat mode. - pick up fix for extra va_end() in ParseVErrorInternal. - -Thu Oct 11 13:20:06 2001 Simon J. Gerraty - - * configure.in: for systems that have sys/cdefs.h check if it is - compatible. If not, include the one under missing, but tell it to - include the native one too - necessary on Linux. - - * missing/sys/cdefs.h: if NEED_HOST_CDEFS_H is defined, use - include_next (for gcc) to get the native sys/cdefs.h - -Tue Aug 21 02:29:34 2001 Simon J. Gerraty - - * job.c (JobFinish): Fix an earlier merge bug that resulted in - leaking descriptors when using -jN. - - * job.c (JobPrintCommand): See if "curdir" exists before - attempting to chdir(). Doing the chdir directly in make (when in - compat mode) fails silently, so let the -jN version do the same. - This can happen when building kernels in an object tree and - playing clever games to reset .CURDIR. - - * Merged with NetBSD make - pick up .USEBEFORE - -Tue Jun 26 23:45:11 2001 Simon J. Gerraty - - * makefile.boot.in: Give bmake.boot a MAKESYSPATH that might work. - -Tue Jun 12 16:48:57 2001 Simon J. Gerraty - - * var.c (Var_Set): Add 4th (flags) arg so VarLoopExpand can tell - us not to export the iterator variable when using VAR_CMD context. - -Sun Jun 10 21:55:21 2001 Simon J. Gerraty - - * job.c (Job_CatchChildren): don't call Job_CatchOutput() here, - its the wrong "fix". - -Sat Jun 9 00:11:24 2001 Simon J. Gerraty - - * Redesigned export of VAR_CMD's via MAKEFLAGS. - We now simply append the variable names to .MAKEOVERRIDES, and - handle duplicate suppression and quoting in ExportMAKEFLAGS using: - ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@} - Apart from fixing quoting bugs in previous version, this allows us - to export vars to the environment by simply doing: - .MAKEOVERRIDES+= PATH - Merged again with NetBSD make, but the above is the only change. - - * configure.in: added - --disable-pwd-override disable $PWD overriding getcwd() - --disable-check-make-chdir disable make trying to guess - when it should automatically cd ${.CURDIR} - - * Merge with NetBSD make, changes include: - parse.c (ParseDoDependency): Spot that the syntax error is - caused by an unresolved cvs/rcs conflict and say so. - var.c: most of Var* functions now take a ctxt as 1st arg. - now does variable substituion on rhs of sysv style modifiers. - - * var.c (Var_Set): exporting of command line variables (VAR_CMD) - is now done here. We append the name='value' to .MAKEOVERRIDES - rather than directly into MAKEFLAGS as this allows a Makefile to - use .MAKEOVERRIDES= to disable this behaviour. GNU make uses a - very similar mechanism. Note that in adding name='value' to - .MAKEOVERRIDES we do the moral equivalent of: - .MAKEOVERRIDES:= ${.MAKEOVERRIDES:Nname=*} name='val' - -Fri Jun 1 14:08:02 2001 Simon J. Gerraty - - * make-conf.h (USE_IOVEC): make it conditional on HAVE_SYS_UIO_H - - * Merged with NetBSD make - make -dx can now be used to run commands via sh -x - better error messages on exec failures. - -Thu May 31 01:44:54 2001 Simon J. Gerraty - - * Makefile.in (main.o): depends on ${SRCS} ${MAKEFILE} so that - MAKE_VERSION gets updated. Also don't use ?= for MAKE_VERSION, - MACHINE etc otherwise they propagate from the previous bmake. - - * configure.in (machine): allow --with-machine=generic to make - configure use machine.sh to set MACHINE. - - * job.c (JobInterrupt): convert to using WAIT_T and friends. - - * Makefile.in: mention in bmake.1 that we use autoconf. - - * make.1: mention MAKE_PRINT_VAR_ON_ERROR. - -Wed May 30 23:17:18 2001 Simon J. Gerraty - - * main.c (ReadMakefile): don't set MAKEFILE if reading ".depend" - as that rather defeats the usefulness of ${MAKEFILE}. - - * main.c (MainParseArgs): append command line variable assignments - to MAKEFLAGS so that they get propagated to child make's. - Apparently this is required POSIX behaviour? Its useful anyway. - -Tue May 29 02:20:07 2001 Simon J. Gerraty - - * compat.c (CompatRunCommand): don't use perror() since stdio may - cause problems in child of vfork(). - - * compat.c, main.c: Call PrintOnError() when we are going to bail. - This routine prints out the .curdir where we stopped and will also - display any vars listed in ${MAKE_PRINT_VAR_ON_ERROR}. - - * main.c: add ${.newline} to hold a "\n" - sometimes handy in - :@ expansion. - - * var.c: VarLoopExpand: ignore addSpace if a \n is present. - - * Added RCSid's for the files we've touched. - -Thu May 24 15:41:37 2001 Simon J. Gerraty - - * configure.in: Thanks to some clues from mdb@juniper.net, - added autoconf magic to control setting of MACHINE, MACHINE_ARCH - as well as what ends up in _PATH_DEFSYSPATH. We now have: - - --with-machine=MACHINE explicitly set MACHINE - --with-force-machine=MACHINE set FORCE_MACHINE - --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH - --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH - --with-prefix-sys-path=PATH:DIR:LIST prefix _PATH_PREFIX_SYSPATH - --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX - - If _PATH_OBJDIRPREFIX is set to "no" we won't define it. - - * makefile: added a pathetically simple makefile to drive - bootstrapping. Running configure by hand is more useful. - - * Makefile.in: added MAKE_VERSION, and reworked things to be less - dependent on NetBSD bsd.*.mk - - * pathnames.h: allow NO_PATH_OBJDIRPREFIX to stop us defining - _PATH_OBJDIRPREFIX for those that don't want a default. - construct _PATH_DEFSYSPATH from the info we get from configure. - - * main.c: allow for no _PATH_OBJDIRPREFIX, set ${MAKE_VERSION} - if MAKE_VERSION is defined. - - * compat.c: when we bail, print out the .CURDIR we were in. - -Sat May 12 00:34:12 2001 Simon J. Gerraty - - * Merged with NetBSD make - - * var.c: fixed a bug in the handling of the modifier :P - if the node as found but the path was null, we segfault trying to - duplicate it. - -Mon Mar 5 16:20:33 2001 Simon J. Gerraty - - * Merged with NetBSD make - - * make.c: Make_OODate's test for a library out of date was using - cmtime where it should have used mtime (my bug). - - * compat.c: Use perror() to tell us what really went wrong when we - cannot exec a command. - -Fri Dec 15 10:11:08 2000 Simon J. Gerraty - - * Merged with NetBSD make - -Sat Jun 10 10:11:08 2000 Simon J. Gerraty - - * Merged with NetBSD make - -Thu Jun 1 10:11:08 2000 Simon J. Gerraty - - * Merged with NetBSD make - -Tue May 30 10:11:08 2000 Simon J. Gerraty - - * Merged with NetBSD make - -Thu Apr 27 00:07:47 2000 Simon J. Gerraty - - * util.c: don't provide signal() since we use sigcompat.c - - * Makefile.in: added a build target. - - * var.c (Var_Parse): added ODE modifiers :U, :D, :L, :P, :@ and :! - These allow some quite clever magic. - - * main.c (main): added support for getenv(MAKESYSPATH). - -Mon Apr 2 16:25:13 2000 Simon J. Gerraty - - * Disable $PWD overriding getcwd() if MAKEOBJDIRPREFIX is set. - This avoids objdir having a different value depending on how a - directory was reached (via command line, or subdir.mk). - - * If FORCE_MACHINE is defined, ignore getenv("MACHINE"). - -Mon Apr 2 23:15:31 2000 Simon J. Gerraty - - * Do a chdir(${.CURDIR}) before invoking ${.MAKE} or ${.MAKE:T} if - MAKEOBJDIRPREFIX is set and NOCHECKMAKECHDIR is not. - I've been testing this in NetBSD's make for some weeks. - - * Turn Makefile into Makefile.in and make it useful. - -Tue Feb 29 22:08:00 2000 Simon J. Gerraty - - * Imported NetBSD's -current make(1) and resolve conflicts. - - * Applied autoconf patches from bmake v2 - - * Imported clean code base from NetBSD-1.0 diff --git a/bootstrap/bmake/FILES b/bootstrap/bmake/FILES deleted file mode 100644 index 4ff1226be12..00000000000 --- a/bootstrap/bmake/FILES +++ /dev/null @@ -1,83 +0,0 @@ -FILES -ChangeLog -bmake.cat1 -Makefile.in -PSD.doc/Makefile -PSD.doc/tutorial.ms -README -arch.c -bit.h -buf.c -buf.h -compat.c -cond.c -make-conf.h -config.h.in -configure -aclocal.m4 -configure.in -dir.c -dir.h -find_lib.sh -for.c -getenv.c -getopt.c -hash.c -hash.h -install-sh -job.c -job.h -trace.c -trace.h -list.h -lst.h -lst.lib/Makefile -lst.lib/lstAppend.c -lst.lib/lstAtEnd.c -lst.lib/lstAtFront.c -lst.lib/lstClose.c -lst.lib/lstConcat.c -lst.lib/lstDatum.c -lst.lib/lstDeQueue.c -lst.lib/lstDestroy.c -lst.lib/lstDupl.c -lst.lib/lstEnQueue.c -lst.lib/lstFind.c -lst.lib/lstFindFrom.c -lst.lib/lstFirst.c -lst.lib/lstForEach.c -lst.lib/lstForEachFrom.c -lst.lib/lstInit.c -lst.lib/lstInsert.c -lst.lib/lstInt.h -lst.lib/lstIsAtEnd.c -lst.lib/lstIsEmpty.c -lst.lib/lstLast.c -lst.lib/lstMember.c -lst.lib/lstNext.c -lst.lib/lstOpen.c -lst.lib/lstRemove.c -lst.lib/lstReplace.c -lst.lib/lstSucc.c -lst.lib/makefile.boot.in -machine.sh -main.c -make.1 -make.c -make.h -makefile.boot.in -missing/sys/cdefs.h -mkdeps.sh -nonints.h -parse.c -pathnames.h -ranlib.h -setenv.c -sigcompat.c -sprite.h -str.c -suff.c -targ.c -util.c -var.c -wait.h diff --git a/bootstrap/bmake/Makefile.in b/bootstrap/bmake/Makefile.in deleted file mode 100644 index 22262b9bd05..00000000000 --- a/bootstrap/bmake/Makefile.in +++ /dev/null @@ -1,118 +0,0 @@ -# $NetBSD: Makefile.in,v 1.2 2004/08/23 03:44:34 jlam Exp $ -# @(#)Makefile 5.2 (Berkeley) 12/28/90 - -# $Id: Makefile.in,v 1.2 2004/08/23 03:44:34 jlam Exp $ - -# you can use this Makefile if you have an earlier version of bmake. -prefix= @prefix@ -srcdir= @srcdir@ -CC?= @CC@ -BUILD_DATE!= date +%Y%m%d -MAKE_VERSION:= bmake-3.1.12 ${BUILD_DATE} -MACHINE=@machine@ -MACHINE_ARCH=@machine_arch@ - -CFLAGS+= -I. -I${srcdir} @DEFS@ @CPPFLAGS@ ${XDEFS} ${CFLAGS_${.TARGET:T}} -CFLAGS_main.o= "-DMAKE_VERSION=\"${MAKE_VERSION}\"" -LDFLAGS= @LDFLAGS@ -LIBOBJS= @LIBOBJS@ -LDADD= @LIBS@ - -PROG= bmake -SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \ - make.c parse.c str.c suff.c targ.c trace.c var.c util.c -SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \ - lstDatum.c lstDeQueue.c lstDestroy.c lstDupl.c lstEnQueue.c \ - lstFind.c lstFindFrom.c lstFirst.c lstForEach.c lstForEachFrom.c \ - lstInit.c lstInsert.c lstIsAtEnd.c lstIsEmpty.c lstLast.c \ - lstMember.c lstNext.c lstOpen.c lstRemove.c lstReplace.c lstSucc.c - -.if !empty(LIBOBJS) -SRCS+= ${LIBOBJS:.o=.c} -.endif - -.PATH: ${srcdir} -.PATH: ${srcdir}/lst.lib - -WFORMAT= 1 -OS!= uname -s -ARCH!= uname -m - -.if (${OS} == "NetBSD") && make(install) && exists(${DESTDIR}/usr/share/doc) -SUBDIR= PSD.doc -.endif - -.if (${OS} != "NetBSD" && ${OS} != "FreeBSD" && ${OS} != "OpenBSD") -# XXX not sure if we still want this given that configure -# lets us force or not the definition of MACHINE. -CFLAGS_main.o+= "-DFORCE_MACHINE=\"${MACHINE}\"" -NOMAN=no -SRCS+= getenv.c -INSTALL?=${srcdir}/install-sh -.if (${MACHINE} == "sun386") -# even I don't have one of these anymore :-) -CFLAGS+= -DPORTAR -.elif (${MACHINE} != "sunos") -SRCS+= sigcompat.c -CFLAGS+= -DSIGNAL_FLAGS=SA_RESTART -.endif -.endif - -CFLAGS_main.o+= "-D@force_machine@MACHINE=\"${MACHINE}\"" "-DMACHINE_ARCH=\"${MACHINE_ARCH}\"" - -EXTRACT_MAN=no - -MAN=${PROG}.1 -.if (${PROG} != "make") -${MAN}: make.1 - @echo making ${PROG}.1 - @sed -e '/^.Nm/s/make/${PROG}/' -e '/^.Sh HISTORY/,$$d' ${srcdir}/make.1 > $@ - @(echo ".Sh HISTORY"; echo ".Nm"; echo "is derrived from NetBSD's"; echo ".Xr make 1 ."; echo It uses autoconf to facilitate portability to other platforms.) >> $@ - -.endif - -.if exists(${srcdir}/../Makefile.inc) -.include "${srcdir}/../Makefile.inc" -.endif -.-include "prog.mk" -.ifdef OBJS -# prog.mk likely found. -.include "subdir.mk" -.else -.include "bsd.prog.mk" -.include "bsd.subdir.mk" -.endif - -# Force these -BINDIR= ${prefix}/bin -MANDIR= ${prefix}/man - -.if ${OS} == "FreeBSD" || ${OS} == "OpenBSD" -# freebsd's bsd.man.mk works differently -MAN1=${MAN} -MANDIR= ${prefix}/man/man -MANDEST= ${MANDIR}1 -.endif -MANDEST?= ${MANDIR} - -arch.o: config.h -# make sure that MAKE_VERSION gets updated. -main.o: ${SRCS} ${MAKEFILE} - -MK?=${prefix}/share/mk -MKSRC?=${srcdir}/mk - -beforeinstall: - test -d ${DESTDIR}${BINDIR} || ${INSTALL} -m 775 -d ${DESTDIR}${BINDIR} - test -d ${DESTDIR}${MANDEST} || ${INSTALL} -m 775 -d ${DESTDIR}${MANDEST} - -install-mk: -.if exists(${MKSRC}/bsd.prog.mk) - test -d ${DESTDIR}${MK} || ${INSTALL} -m 775 -d ${DESTDIR}${MK} - ${INSTALL} -m 644 ${MKSRC}/[ac-z]*.mk ${DESTDIR}${MK} - test -s ${DESTDIR}${MK}/bsd.own.mk || ${INSTALL} -m 644 ${MKSRC}/bsd*.mk ${DESTDIR}${MK} - test -s ${DESTDIR}${MK}/sys.mk || ${INSTALL} -m 644 mk/sys.mk ${DESTDIR}${MK} - test -s ${DESTDIR}${MK}/sys.mk || ${INSTALL} -m 644 ${MKSRC}/${MACHINE}.sys.mk ${DESTDIR}${MK}/sys.mk -.else - @echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC; false -.endif diff --git a/bootstrap/bmake/PSD.doc/Makefile b/bootstrap/bmake/PSD.doc/Makefile deleted file mode 100644 index 0500db65228..00000000000 --- a/bootstrap/bmake/PSD.doc/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $NetBSD: Makefile,v 1.1.1.1 2004/03/11 13:04:14 grant Exp $ -# @(#)Makefile 8.1 (Berkeley) 8/14/93 - -DIR= psd/12.make -SRCS= tutorial.ms -MACROS= -ms - -.include diff --git a/bootstrap/bmake/PSD.doc/tutorial.ms b/bootstrap/bmake/PSD.doc/tutorial.ms deleted file mode 100644 index 6546db2fd38..00000000000 --- a/bootstrap/bmake/PSD.doc/tutorial.ms +++ /dev/null @@ -1,3744 +0,0 @@ -.\" $NetBSD: tutorial.ms,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ -.\" Copyright (c) 1988, 1989 by Adam de Boor -.\" Copyright (c) 1989 by Berkeley Softworks -.\" Copyright (c) 1988, 1989, 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. 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. -.\" -.\" @(#)tutorial.ms 8.1 (Berkeley) 8/18/93 -.\" -.EH 'PSD:12-%''PMake \*- A Tutorial' -.OH 'PMake \*- A Tutorial''PSD:12-%' -.\" xH is a macro to provide numbered headers that are automatically stuffed -.\" into a table-of-contents, properly indented, etc. If the first argument -.\" is numeric, it is taken as the depth for numbering (as for .NH), else -.\" the default (1) is assumed. -.\" -.\" @P The initial paragraph distance. -.\" @Q The piece of section number to increment (or 0 if none given) -.\" @R Section header. -.\" @S Indent for toc entry -.\" @T Argument to NH (can't use @Q b/c giving 0 to NH resets the counter) -.de xH -.NH \\$1 -\\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 -.nr PD .1v -.XS \\n% -.ta 0.6i -\\*(SN \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9 -.XE -.nr PD .3v -.. -.\" CW is used to place a string in fixed-width or switch to a -.\" fixed-width font. -.\" C is a typewriter font for a laserwriter. Use something else if -.\" you don't have one... -.de CW -.ie !\\n(.$ .ft C -.el \&\\$3\fC\\$1\fP\\$2 -.. -.\" Anything I put in a display I want to be in fixed-width -.am DS -.CW -.. -.\" The stuff in .No produces a little stop sign in the left margin -.\" that says NOTE in it. Unfortunately, it does cause a break, but -.\" hey. Can't have everything. In case you're wondering how I came -.\" up with such weird commands, they came from running grn on a -.\" gremlin file... -.de No -.br -.ne 0.5i -.po -0.5i -.br -.mk -.nr g3 \\n(.f -.nr g4 \\n(.s -.sp -1 -.\" .st cf -\D's -1u'\D't 5u' -.sp -1 -\h'50u'\D'l 71u 0u'\D'l 50u 50u'\D'l 0u 71u'\D'l -50u 50u'\D'l -71u 0u'\D'l -50u -50u'\D'l 0u -71u'\D'l 50u -50u' -.sp -1 -\D't 3u' -.sp -1 -.sp 7u -\h'53u'\D'p 14 68u 0u 46u 46u 0u 68u -46u 46u -68u 0u -47u -46u 0u -68u 47u -46u' -.sp -1 -.ft R -.ps 6 -.nr g8 \\n(.d -.ds g9 "NOTE -.sp 74u -\h'85u'\v'0.85n'\h-\w\\*(g9u/2u\&\\*(g9 -.sp |\\n(g8u -.sp 166u -\D't 3u'\D's -1u' -.br -.po -.rt -.ft \\n(g3 -.ps \\n(g4 -.. -.de Bp -.ie !\\n(.$ .IP \(bu 2 -.el .IP "\&" 2 -.. -.po +.3i -.TL -PMake \*- A Tutorial -.AU -Adam de Boor -.AI -Berkeley Softworks -2150 Shattuck Ave, Penthouse -Berkeley, CA 94704 -adam@bsw.uu.net -\&...!uunet!bsw!adam -.FS -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appears in all copies. -The University of California, Berkeley Softworks, and Adam de Boor make no -representations about the suitability of this software for any -purpose. It is provided "as is" without express or implied warranty. -.FE -.PP -.xH 1 Introduction -.LP -PMake is a program for creating other programs, or anything else you -can think of for it to do. The basic idea behind PMake is that, for -any given system, be it a program or a document or whatever, there -will be some files that depend on the state of other files (on when -they were last modified). PMake takes these dependencies, which you -must specify, and uses them to build whatever it is you want it to -build. -.LP -PMake is almost fully-compatible with Make, with which you may already -be familiar. PMake's most important feature is its ability to run -several different jobs at once, making the creation of systems -considerably faster. It also has a great deal more functionality than -Make. Throughout the text, whenever something is mentioned that is an -important difference between PMake and Make (i.e. something that will -cause a makefile to fail if you don't do something about it), or is -simply important, it will be flagged with a little sign in the left -margin, like this: -.No -.LP -This tutorial is divided into three main sections corresponding to basic, -intermediate and advanced PMake usage. If you already know Make well, -you will only need to skim chapter 2 (there are some aspects of -PMake that I consider basic to its use that didn't exist in Make). -Things in chapter 3 make life much easier, while those in chapter 4 -are strictly for those who know what they are doing. Chapter 5 has -definitions for the jargon I use and chapter 6 contains possible -solutions to the problems presented throughout the tutorial. -.xH 1 The Basics of PMake -.LP -PMake takes as input a file that tells a) which files depend on which -other files to be complete and b) what to do about files that are -``out-of-date.'' This file is known as a ``makefile'' and is usually -.Ix 0 def makefile -kept in the top-most directory of the system to be built. While you -can call the makefile anything you want, PMake will look for -.CW Makefile -and -.CW makefile -(in that order) in the current directory if you don't tell it -otherwise. -.Ix 0 def makefile default -To specify a different makefile, use the -.B \-f -flag (e.g. -.CW "pmake -f program.mk" ''). `` -.Ix 0 ref flags -f -.Ix 0 ref makefile other -.LP -A makefile has four different types of lines in it: -.RS -.IP \(bu 2 -File dependency specifications -.IP \(bu 2 -Creation commands -.IP \(bu 2 -Variable assignments -.IP \(bu 2 -Comments, include statements and conditional directives -.RE -.LP -Any line may be continued over multiple lines by ending it with a -backslash. -.Ix 0 def "continuation line" -The backslash, following newline and any initial whitespace -on the following line are compressed into a single space before the -input line is examined by PMake. -.xH 2 Dependency Lines -.LP -As mentioned in the introduction, in any system, there are -dependencies between the files that make up the system. For instance, -in a program made up of several C source files and one header file, -the C files will need to be re-compiled should the header file be -changed. For a document of several chapters and one macro file, the -chapters will need to be reprocessed if any of the macros changes. -.Ix 0 def "dependency" -These are dependencies and are specified by means of dependency lines in -the makefile. -.LP -.Ix 0 def "dependency line" -On a dependency line, there are targets and sources, separated by a -one- or two-character operator. -The targets ``depend'' on the sources and are usually created from -them. -.Ix 0 def target -.Ix 0 def source -.Ix 0 ref operator -Any number of targets and sources may be specified on a dependency line. -All the targets in the line are made to depend on all the sources. -Targets and sources need not be actual files, but every source must be -either an actual file or another target in the makefile. -If you run out of room, use a backslash at the end of the line to continue onto -the next one. -.LP -Any file may be a target and any file may be a source, but the -relationship between the two (or however many) is determined by the -``operator'' that separates them. -.Ix 0 def operator -Three types of operators exist: one specifies that the datedness of a -target is determined by the state of its sources, while another -specifies other files (the sources) that need to be dealt with before -the target can be re-created. The third operator is very similar to -the first, with the additional condition that the target is -out-of-date if it has no sources. These operations are represented by -the colon, the exclamation point and the double-colon, respectively, and are -mutually exclusive. Their exact semantics are as follows: -.IP ":" -.Ix 0 def operator colon -.Ix 0 def : -If a colon is used, a target on the line is considered to be -``out-of-date'' (and in need of creation) if -.RS -.IP \(bu 2 -any of the sources has been modified more recently than the target, or -.IP \(bu 2 -the target doesn't exist. -.RE -.Ix 0 def out-of-date -.IP "\&" -Under this operation, steps will be taken to re-create the target only -if it is found to be out-of-date by using these two rules. -.IP "!" -.Ix 0 def operator force -.Ix 0 def ! -If an exclamation point is used, the target will always be re-created, -but this will not happen until all of its sources have been examined -and re-created, if necessary. -.IP "::" -.Ix 0 def operator double-colon -.Ix 0 def :: -If a double-colon is used, a target is out-of-date if: -.RS -.IP \(bu 2 -any of the sources has been modified more recently than the target, or -.IP \(bu 2 -the target doesn't exist, or -.IP \(bu 2 -the target has no sources. -.RE -.IP "\&" -If the target is out-of-date according to these rules, it will be re-created. -This operator also does something else to the targets, but I'll go -into that in the next section (``Shell Commands''). -.LP -Enough words, now for an example. Take that C program I mentioned -earlier. Say there are three C files -.CW a.c , ( -.CW b.c -and -.CW c.c ) -each of which -includes the file -.CW defs.h . -The dependencies between the files could then be expressed as follows: -.DS -program : a.o b.o c.o -a.o b.o c.o : defs.h -a.o : a.c -b.o : b.c -c.o : c.c -.DE -.LP -You may be wondering at this point, where -.CW a.o , -.CW b.o -and -.CW c.o -came in and why -.I they -depend on -.CW defs.h -and the C files don't. The reason is quite simple: -.CW program -cannot be made by linking together .c files \*- it must be -made from .o files. Likewise, if you change -.CW defs.h , -it isn't the .c files that need to be re-created, it's the .o files. -If you think of dependencies in these terms \*- which files (targets) -need to be created from which files (sources) \*- you should have no problems. -.LP -An important thing to notice about the above example, is that all the -\&.o files appear as targets on more than one line. This is perfectly -all right: the target is made to depend on all the sources mentioned -on all the dependency lines. E.g. -.CW a.o -depends on both -.CW defs.h -and -.CW a.c . -.Ix 0 ref dependency -.No -.LP -The order of the dependency lines in the makefile is -important: the first target on the first dependency line in the -makefile will be the one that gets made if you don't say otherwise. -That's why -.CW program -comes first in the example makefile, above. -.LP -Both targets and sources may contain the standard C-Shell wildcard -characters -.CW { , ( -.CW } , -.CW * , -.CW ? , -.CW [ , -and -.CW ] ), -but the non-curly-brace ones may only appear in the final component -(the file portion) of the target or source. The characters mean the -following things: -.IP \fB{}\fP -These enclose a comma-separated list of options and cause the pattern -to be expanded once for each element of the list. Each expansion -contains a different element. For example, -.CW src/{whiffle,beep,fish}.c -expands to the three words -.CW src/whiffle.c , -.CW src/beep.c , -and -.CW src/fish.c . -These braces may be nested and, unlike the other wildcard characters, -the resulting words need not be actual files. All other wildcard -characters are expanded using the files that exist when PMake is -started. -.IP \fB*\fP -This matches zero or more characters of any sort. -.CW src/*.c -will expand to the same three words as above as long as -.CW src -contains those three files (and no other files that end in -.CW .c ). -.IP \fB?\fP -Matches any single character. -.IP \fB[]\fP -This is known as a character class and contains either a list of -single characters, or a series of character ranges -.CW a-z , ( -for example means all characters between a and z), or both. It matches -any single character contained in the list. E.g. -.CW [A-Za-z] -will match all letters, while -.CW [0123456789] -will match all numbers. -.xH 2 Shell Commands -.LP -``Isn't that nice,'' you say to yourself, ``but how are files -actually `re-created,' as he likes to spell it?'' -The re-creation is accomplished by commands you place in the makefile. -These commands are passed to the Bourne shell (better known as -``/bin/sh'') to be executed and are -.Ix 0 ref shell -.Ix 0 ref re-creation -.Ix 0 ref update -expected to do what's necessary to update the target file (PMake -doesn't actually check to see if the target was created. It just -assumes it's there). -.Ix 0 ref target -.LP -Shell commands in a makefile look a lot like shell commands you would -type at a terminal, with one important exception: each command in a -makefile -.I must -be preceded by at least one tab. -.LP -Each target has associated with it a shell script made up of -one or more of these shell commands. The creation script for a target -should immediately follow the dependency line for that target. While -any given target may appear on more than one dependency line, only one -of these dependency lines may be followed by a creation script, unless -the `::' operator was used on the dependency line. -.Ix 0 ref operator double-colon -.Ix 0 ref :: -.No -.LP -If the double-colon was used, each dependency line for the target -may be followed by a shell script. That script will only be executed -if the target on the associated dependency line is out-of-date with -respect to the sources on that line, according to the rules I gave -earlier. -I'll give you a good example of this later on. -.LP -To expand on the earlier makefile, you might add commands as follows: -.DS -program : a.o b.o c.o - cc a.o b.o c.o \-o program -a.o b.o c.o : defs.h -a.o : a.c - cc \-c a.c -b.o : b.c - cc \-c b.c -c.o : c.c - cc \-c c.c -.DE -.LP -Something you should remember when writing a makefile is, the -commands will be executed if the -.I target -on the dependency line is out-of-date, not the sources. -.Ix 0 ref target -.Ix 0 ref source -.Ix 0 ref out-of-date -In this example, the command -.CW "cc \-c a.c" '' `` -will be executed if -.CW a.o -is out-of-date. Because of the `:' operator, -.Ix 0 ref : -.Ix 0 ref operator colon -this means that should -.CW a.c -.I or -.CW defs.h -have been modified more recently than -.CW a.o , -the command will be executed -.CW a.o "\&" ( -will be considered out-of-date). -.Ix 0 ref out-of-date -.LP -Remember how I said the only difference between a makefile shell -command and a regular shell command was the leading tab? I lied. There -is another way in which makefile commands differ from regular ones. -The first two characters after the initial whitespace are treated -specially. -If they are any combination of `@' and `\-', they cause PMake to do -different things. -.LP -In most cases, shell commands are printed before they're -actually executed. This is to keep you informed of what's going on. If -an `@' appears, however, this echoing is suppressed. In the case of an -.CW echo -command, say -.CW "echo Linking index" ,'' `` -it would be -rather silly to see -.DS -echo Linking index -Linking index -.DE -.LP -so PMake allows you to place an `@' before the command -.CW "@echo Linking index" '') (`` -to prevent the command from being printed. -.LP -The other special character is the `\-'. In case you didn't know, -shell commands finish with a certain ``exit status.'' This status is -made available by the operating system to whatever program invoked the -command. Normally this status will be 0 if everything went ok and -non-zero if something went wrong. For this reason, PMake will consider -an error to have occurred if one of the shells it invokes returns a non-zero -status. When it detects an error, PMake's usual action is to abort -whatever it's doing and exit with a non-zero status itself (any other -targets that were being created will continue being made, but nothing -new will be started. PMake will exit after the last job finishes). -This behavior can be altered, however, by placing a `\-' at the front -of a command -.CW "\-mv index index.old" ''), (`` -certain command-line arguments, -or doing other things, to be detailed later. In such -a case, the non-zero status is simply ignored and PMake keeps chugging -along. -.No -.LP -Because all the commands are given to a single shell to execute, such -things as setting shell variables, changing directories, etc., last -beyond the command in which they are found. This also allows shell -compound commands (like -.CW for -loops) to be entered in a natural manner. -Since this could cause problems for some makefiles that depend on -each command being executed by a single shell, PMake has a -.B \-B -.Ix 0 ref compatibility -.Ix 0 ref flags -B -flag (it stands for backwards-compatible) that forces each command to -be given to a separate shell. It also does several other things, all -of which I discourage since they are now old-fashioned.\|.\|.\|. -.No -.LP -A target's shell script is fed to the shell on its (the shell's) input stream. -This means that any commands, such as -.CW ci -that need to get input from the terminal won't work right \*- they'll -get the shell's input, something they probably won't find to their -liking. A simple way around this is to give a command like this: -.DS -ci $(SRCS) < /dev/tty -.DE -This would force the program's input to come from the terminal. If you -can't do this for some reason, your only other alternative is to use -PMake in its fullest compatibility mode. See -.B Compatibility -in chapter 4. -.Ix 0 ref compatibility -.LP -.xH 2 Variables -.LP -PMake, like Make before it, has the ability to save text in variables -to be recalled later at your convenience. Variables in PMake are used -much like variables in the shell and, by tradition, consist of -all upper-case letters (you don't -.I have -to use all upper-case letters. -In fact there's nothing to stop you from calling a variable -.CW @^&$%$ . -Just tradition). Variables are assigned-to using lines of the form -.Ix 0 def variable assignment -.DS -VARIABLE = value -.DE -.Ix 0 def variable assignment -appended-to by -.DS -VARIABLE += value -.DE -.Ix 0 def variable appending -.Ix 0 def variable assignment appended -.Ix 0 def += -conditionally assigned-to (if the variable isn't already defined) by -.DS -VARIABLE ?= value -.DE -.Ix 0 def variable assignment conditional -.Ix 0 def ?= -and assigned-to with expansion (i.e. the value is expanded (see below) -before being assigned to the variable\*-useful for placing a value at -the beginning of a variable, or other things) by -.DS -VARIABLE := value -.DE -.Ix 0 def variable assignment expanded -.Ix 0 def := -.LP -Any whitespace before -.I value -is stripped off. When appending, a space is placed between the old -value and the stuff being appended. -.LP -The final way a variable may be assigned to is using -.DS -VARIABLE != shell-command -.DE -.Ix 0 def variable assignment shell-output -.Ix 0 def != -In this case, -.I shell-command -has all its variables expanded (see below) and is passed off to a -shell to execute. The output of the shell is then placed in the -variable. Any newlines (other than the final one) are replaced by -spaces before the assignment is made. This is typically used to find -the current directory via a line like: -.DS -CWD != pwd -.DE -.LP -.B Note: -this is intended to be used to execute commands that produce small amounts -of output (e.g. ``pwd''). The implementation is less than intelligent and will -likely freeze if you execute something that produces thousands of -bytes of output (8 Kb is the limit on many UNIX systems). -.LP -The value of a variable may be retrieved by enclosing the variable -name in parentheses or curly braces and preceding the whole thing -with a dollar sign. -.LP -For example, to set the variable CFLAGS to the string -.CW "\-I/sprite/src/lib/libc \-O" ,'' `` -you would place a line -.DS -CFLAGS = \-I/sprite/src/lib/libc \-O -.DE -in the makefile and use the word -.CW "$(CFLAGS)" -wherever you would like the string -.CW "\-I/sprite/src/lib/libc \-O" -to appear. This is called variable expansion. -.Ix 0 def variable expansion -.No -.LP -Unlike Make, PMake will not expand a variable unless it knows -the variable exists. E.g. if you have a -.CW "${i}" -in a shell command and you have not assigned a value to the variable -.CW i -(the empty string is considered a value, by the way), where Make would have -substituted the empty string, PMake will leave the -.CW "${i}" -alone. -To keep PMake from substituting for a variable it knows, precede the -dollar sign with another dollar sign. -(e.g. to pass -.CW "${HOME}" -to the shell, use -.CW "$${HOME}" ). -This causes PMake, in effect, to expand the -.CW $ -macro, which expands to a single -.CW $ . -For compatibility, Make's style of variable expansion will be used -if you invoke PMake with any of the compatibility flags (\c -.B \-V , -.B \-B -or -.B \-M . -The -.B \-V -flag alters just the variable expansion). -.Ix 0 ref flags -V -.Ix 0 ref flags -B -.Ix 0 ref flags -M -.Ix 0 ref compatibility -.LP -.Ix 0 ref variable expansion -There are two different times at which variable expansion occurs: -When parsing a dependency line, the expansion occurs immediately -upon reading the line. If any variable used on a dependency line is -undefined, PMake will print a message and exit. -Variables in shell commands are expanded when the command is -executed. -Variables used inside another variable are expanded whenever the outer -variable is expanded (the expansion of an inner variable has no effect -on the outer variable. I.e. if the outer variable is used on a dependency -line and in a shell command, and the inner variable changes value -between when the dependency line is read and the shell command is -executed, two different values will be substituted for the outer -variable). -.Ix 0 def variable types -.LP -Variables come in four flavors, though they are all expanded the same -and all look about the same. They are (in order of expanding scope): -.RS -.IP \(bu 2 -Local variables. -.Ix 0 ref variable local -.IP \(bu 2 -Command-line variables. -.Ix 0 ref variable command-line -.IP \(bu 2 -Global variables. -.Ix 0 ref variable global -.IP \(bu 2 -Environment variables. -.Ix 0 ref variable environment -.RE -.LP -The classification of variables doesn't matter much, except that the -classes are searched from the top (local) to the bottom (environment) -when looking up a variable. The first one found wins. -.xH 3 Local Variables -.LP -.Ix 0 def variable local -Each target can have as many as seven local variables. These are -variables that are only ``visible'' within that target's shell script -and contain such things as the target's name, all of its sources (from -all its dependency lines), those sources that were out-of-date, etc. -Four local variables are defined for all targets. They are: -.RS -.IP ".TARGET" -.Ix 0 def variable local .TARGET -.Ix 0 def .TARGET -The name of the target. -.IP ".OODATE" -.Ix 0 def variable local .OODATE -.Ix 0 def .OODATE -The list of the sources for the target that were considered out-of-date. -The order in the list is not guaranteed to be the same as the order in -which the dependencies were given. -.IP ".ALLSRC" -.Ix 0 def variable local .ALLSRC -.Ix 0 def .ALLSRC -The list of all sources for this target in the order in which they -were given. -.IP ".PREFIX" -.Ix 0 def variable local .PREFIX -.Ix 0 def .PREFIX -The target without its suffix and without any leading path. E.g. for -the target -.CW ../../lib/compat/fsRead.c , -this variable would contain -.CW fsRead . -.RE -.LP -Three other local variables are set only for certain targets under -special circumstances. These are the ``.IMPSRC,'' -.Ix 0 ref variable local .IMPSRC -.Ix 0 ref .IMPSRC -``.ARCHIVE,'' -.Ix 0 ref variable local .ARCHIVE -.Ix 0 ref .ARCHIVE -and ``.MEMBER'' -.Ix 0 ref variable local .MEMBER -.Ix 0 ref .MEMBER -variables. When they are set and how they are used is described later. -.LP -Four of these variables may be used in sources as well as in shell -scripts. -.Ix 0 def "dynamic source" -.Ix 0 def source dynamic -These are ``.TARGET'', ``.PREFIX'', ``.ARCHIVE'' and ``.MEMBER''. The -variables in the sources are expanded once for each target on the -dependency line, providing what is known as a ``dynamic source,'' -.Rd 0 -allowing you to specify several dependency lines at once. For example, -.DS -$(OBJS) : $(.PREFIX).c -.DE -will create a dependency between each object file and its -corresponding C source file. -.xH 3 Command-line Variables -.LP -.Ix 0 def variable command-line -Command-line variables are set when PMake is first invoked by giving a -variable assignment as one of the arguments. For example, -.DS -pmake "CFLAGS = -I/sprite/src/lib/libc -O" -.DE -would make -.CW CFLAGS -be a command-line variable with the given value. Any assignments to -.CW CFLAGS -in the makefile will have no effect, because once it -is set, there is (almost) nothing you can do to change a command-line -variable (the search order, you see). Command-line variables may be -set using any of the four assignment operators, though only -.CW = -and -.CW ?= -behave as you would expect them to, mostly because assignments to -command-line variables are performed before the makefile is read, thus -the values set in the makefile are unavailable at the time. -.CW += -.Ix 0 ref += -.Ix 0 ref variable assignment appended -is the same as -.CW = , -because the old value of the variable is sought only in the scope in -which the assignment is taking place (for reasons of efficiency that I -won't get into here). -.CW := -and -.CW ?= -.Ix 0 ref := -.Ix 0 ref ?= -.Ix 0 ref variable assignment expanded -.Ix 0 ref variable assignment conditional -will work if the only variables used are in the environment. -.CW != -is sort of pointless to use from the command line, since the same -effect can no doubt be accomplished using the shell's own command -substitution mechanisms (backquotes and all that). -.xH 3 Global Variables -.LP -.Ix 0 def variable global -Global variables are those set or appended-to in the makefile. -There are two classes of global variables: those you set and those PMake sets. -As I said before, the ones you set can have any name you want them to have, -except they may not contain a colon or an exclamation point. -The variables PMake sets (almost) always begin with a -period and always contain upper-case letters, only. The variables are -as follows: -.RS -.IP .PMAKE -.Ix 0 def variable global .PMAKE -.Ix 0 def .PMAKE -.Ix 0 def variable global MAKE -.Ix 0 def MAKE -The name by which PMake was invoked is stored in this variable. For -compatibility, the name is also stored in the MAKE variable. -.IP .MAKEFLAGS -.Ix 0 def variable global .MAKEFLAGS -.Ix 0 def .MAKEFLAGS variable -.Ix 0 def variable global MFLAGS -.Ix 0 def MFLAGS -All the relevant flags with which PMake was invoked. This does not -include such things as -.B \-f -or variable assignments. Again for compatibility, this value is stored -in the MFLAGS variable as well. -.RE -.LP -Two other variables, ``.INCLUDES'' and ``.LIBS,'' are covered in the -section on special targets in chapter 3. -.Ix 0 ref variable global .INCLUDES -.Ix 0 ref variable global .LIBS -.LP -Global variables may be deleted using lines of the form: -.Ix 0 def #undef -.Ix 0 def variable deletion -.DS -#undef \fIvariable\fP -.DE -The -.CW # ' ` -must be the first character on the line. Note that this may only be -done on global variables. -.xH 3 Environment Variables -.LP -.Ix 0 def variable environment -Environment variables are passed by the shell that invoked PMake and -are given by PMake to each shell it invokes. They are expanded like -any other variable, but they cannot be altered in any way. -.LP -One special environment variable, -.CW PMAKE , -.Ix 0 def variable environment PMAKE -is examined by PMake for command-line flags, variable assignments, -etc., it should always use. This variable is examined before the -actual arguments to PMake are. In addition, all flags given to PMake, -either through the -.CW PMAKE -variable or on the command line, are placed in this environment -variable and exported to each shell PMake executes. Thus recursive -invocations of PMake automatically receive the same flags as the -top-most one. -.LP -Using all these variables, you can compress the sample makefile even more: -.DS -OBJS = a.o b.o c.o -program : $(OBJS) - cc $(.ALLSRC) \-o $(.TARGET) -$(OBJS) : defs.h -a.o : a.c - cc \-c a.c -b.o : b.c - cc \-c b.c -c.o : c.c - cc \-c c.c -.DE -.Ix 0 ref variable local .ALLSRC -.Ix 0 ref .ALLSRC -.Ix 0 ref variable local .TARGET -.Ix 0 ref .TARGET -.Rd 3 -.xH 2 Comments -.LP -.Ix 0 def comments -Comments in a makefile start with a `#' character and extend to the -end of the line. They may appear -anywhere you want them, except in a shell command (though the shell -will treat it as a comment, too). If, for some reason, you need to use the `#' -in a variable or on a dependency line, put a backslash in front of it. -PMake will compress the two into a single `#' (Note: this isn't true -if PMake is operating in full-compatibility mode). -.Ix 0 ref flags -M -.Ix 0 ref compatibility -.xH 2 Parallelism -.No -.LP -PMake was specifically designed to re-create several targets at once, -when possible. You do not have to do anything special to cause this to -happen (unless PMake was configured to not act in parallel, in which -case you will have to make use of the -.B \-L -and -.B \-J -flags (see below)), -.Ix 0 ref flags -L -.Ix 0 ref flags -J -but you do have to be careful at times. -.LP -There are several problems you are likely to encounter. One is -that some makefiles (and programs) are written in such a way that it is -impossible for two targets to be made at once. The program -.CW xstr , -for example, -always modifies the files -.CW strings -and -.CW x.c . -There is no way to change it. Thus you cannot run two of them at once -without something being trashed. Similarly, if you have commands -in the makefile that always send output to the same file, you will not -be able to make more than one target at once unless you change the -file you use. You can, for instance, add a -.CW $$$$ -to the end of the file name to tack on the process ID of the shell -executing the command (each -.CW $$ -expands to a single -.CW $ , -thus giving you the shell variable -.CW $$ ). -Since only one shell is used for all the -commands, you'll get the same file name for each command in the -script. -.LP -The other problem comes from improperly-specified dependencies that -worked in Make because of its sequential, depth-first way of examining -them. While I don't want to go into depth on how PMake -works (look in chapter 4 if you're interested), I will warn you that -files in two different ``levels'' of the dependency tree may be -examined in a different order in PMake than they were in Make. For -example, given the makefile -.DS -a : b c -b : d -.DE -PMake will examine the targets in the order -.CW c , -.CW d , -.CW b , -.CW a . -If the makefile's author expected PMake to abort before making -.CW c -if an error occurred while making -.CW b , -or if -.CW b -needed to exist before -.CW c -was made, -s/he will be sorely disappointed. The dependencies are -incomplete, since in both these cases, -.CW c -would depend on -.CW b . -So watch out. -.LP -Another problem you may face is that, while PMake is set up to handle the -output from multiple jobs in a graceful fashion, the same is not so for input. -It has no way to regulate input to different jobs, -so if you use the redirection from -.CW /dev/tty -I mentioned earlier, you must be careful not to run two of the jobs at once. -.xH 2 Writing and Debugging a Makefile -.LP -Now you know most of what's in a makefile, what do you do next? There -are two choices: (1) use one of the uncommonly-available makefile -generators or (2) write your own makefile (I leave out the third choice of -ignoring PMake and doing everything by hand as being beyond the bounds -of common sense). -.LP -When faced with the writing of a makefile, it is usually best to start -from first principles: just what -.I are -you trying to do? What do you want the makefile finally to produce? -.LP -To begin with a somewhat traditional example, let's say you need to -write a makefile to create a program, -.CW expr , -that takes standard infix expressions and converts them to prefix form (for -no readily apparent reason). You've got three source files, in C, that -make up the program: -.CW main.c , -.CW parse.c , -and -.CW output.c . -Harking back to my pithy advice about dependency lines, you write the -first line of the file: -.DS -expr : main.o parse.o output.o -.DE -because you remember -.CW expr -is made from -.CW .o -files, not -.CW .c -files. Similarly for the -.CW .o -files you produce the lines: -.DS -main.o : main.c -parse.o : parse.c -output.o : output.c -main.o parse.o output.o : defs.h -.DE -.LP -Great. You've now got the dependencies specified. What you need now is -commands. These commands, remember, must produce the target on the -dependency line, usually by using the sources you've listed. -You remember about local variables? Good, so it should come -to you as no surprise when you write -.DS -expr : main.o parse.o output.o - cc -o $(.TARGET) $(.ALLSRC) -.DE -Why use the variables? If your program grows to produce postfix -expressions too (which, of course, requires a name change or two), it -is one fewer place you have to change the file. You cannot do this for -the object files, however, because they depend on their corresponding -source files -.I and -.CW defs.h , -thus if you said -.DS - cc -c $(.ALLSRC) -.DE -you'd get (for -.CW main.o ): -.DS - cc -c main.c defs.h -.DE -which is wrong. So you round out the makefile with these lines: -.DS -main.o : main.c - cc -c main.c -parse.o : parse.c - cc -c parse.c -output.o : output.c - cc -c output.c -.DE -.LP -The makefile is now complete and will, in fact, create the program you -want it to without unnecessary compilations or excessive typing on -your part. There are two things wrong with it, however (aside from it -being altogether too long, something I'll address in chapter 3): -.IP 1) -The string -.CW "main.o parse.o output.o" '' `` -is repeated twice, necessitating two changes when you add postfix -(you were planning on that, weren't you?). This is in direct violation -of de Boor's First Rule of writing makefiles: -.QP -.I -Anything that needs to be written more than once -should be placed in a variable. -.IP "\&" -I cannot emphasize this enough as being very important to the -maintenance of a makefile and its program. -.IP 2) -There is no way to alter the way compilations are performed short of -editing the makefile and making the change in all places. This is evil -and violates de Boor's Second Rule, which follows directly from the -first: -.QP -.I -Any flags or programs used inside a makefile should be placed in a variable so -they may be changed, temporarily or permanently, with the greatest ease. -.LP -The makefile should more properly read: -.DS -OBJS = main.o parse.o output.o -expr : $(OBJS) - $(CC) $(CFLAGS) -o $(.TARGET) $(.ALLSRC) -main.o : main.c - $(CC) $(CFLAGS) -c main.c -parse.o : parse.c - $(CC) $(CFLAGS) -c parse.c -output.o : output.c - $(CC) $(CFLAGS) -c output.c -$(OBJS) : defs.h -.DE -Alternatively, if you like the idea of dynamic sources mentioned in -section 2.3.1, -.Rm 0 2.3.1 -.Rd 4 -.Ix 0 ref "dynamic source" -.Ix 0 ref source dynamic -you could write it like this: -.DS -OBJS = main.o parse.o output.o -expr : $(OBJS) - $(CC) $(CFLAGS) -o $(.TARGET) $(.ALLSRC) -$(OBJS) : $(.PREFIX).c defs.h - $(CC) $(CFLAGS) -c $(.PREFIX).c -.DE -These two rules and examples lead to de Boor's First Corollary: -.QP -.I -Variables are your friends. -.LP -Once you've written the makefile comes the sometimes-difficult task of -.Ix 0 ref debugging -making sure the darn thing works. Your most helpful tool to make sure -the makefile is at least syntactically correct is the -.B \-n -.Ix 0 ref flags -n -flag, which allows you to see if PMake will choke on the makefile. The -second thing the -.B \-n -flag lets you do is see what PMake would do without it actually doing -it, thus you can make sure the right commands would be executed were -you to give PMake its head. -.LP -When you find your makefile isn't behaving as you hoped, the first -question that comes to mind (after ``What time is it, anyway?'') is -``Why not?'' In answering this, two flags will serve you well: -.CW "-d m" '' `` -.Ix 0 ref flags -d -and -.CW "-p 2" .'' `` -.Ix 0 ref flags -p -The first causes PMake to tell you as it examines each target in the -makefile and indicate why it is deciding whatever it is deciding. You -can then use the information printed for other targets to see where -you went wrong. The -.CW "-p 2" '' `` -flag makes PMake print out its internal state when it is done, -allowing you to see that you forgot to make that one chapter depend on -that file of macros you just got a new version of. The output from -.CW "-p 2" '' `` -is intended to resemble closely a real makefile, but with additional -information provided and with variables expanded in those commands -PMake actually printed or executed. -.LP -Something to be especially careful about is circular dependencies. -.Ix 0 def dependency circular -E.g. -.DS -a : b -b : c d -d : a -.DE -In this case, because of how PMake works, -.CW c -is the only thing PMake will examine, because -.CW d -and -.CW a -will effectively fall off the edge of the universe, making it -impossible to examine -.CW b -(or them, for that matter). -PMake will tell you (if run in its normal mode) all the targets -involved in any cycle it looked at (i.e. if you have two cycles in the -graph (naughty, naughty), but only try to make a target in one of -them, PMake will only tell you about that one. You'll have to try to -make the other to find the second cycle). When run as Make, it will -only print the first target in the cycle. -.xH 2 Invoking PMake -.LP -.Ix 0 ref flags -.Ix 0 ref arguments -.Ix 0 ref usage -PMake comes with a wide variety of flags to choose from. -They may appear in any order, interspersed with command-line variable -assignments and targets to create. -The flags are as follows: -.IP "\fB\-d\fP \fIwhat\fP" -.Ix 0 def flags -d -.Ix 0 ref debugging -This causes PMake to spew out debugging information that -may prove useful to you. If you can't -figure out why PMake is doing what it's doing, you might try using -this flag. The -.I what -parameter is a string of single characters that tell PMake what -aspects you are interested in. Most of what I describe will make -little sense to you, unless you've dealt with Make before. Just -remember where this table is and come back to it as you read on. -The characters and the information they produce are as follows: -.RS -.IP a -Archive searching and caching. -.IP c -Conditional evaluation. -.IP d -The searching and caching of directories. -.IP j -Various snippets of information related to the running of the multiple -shells. Not particularly interesting. -.IP m -The making of each target: what target is being examined; when it was -last modified; whether it is out-of-date; etc. -.IP p -Makefile parsing. -.IP r -Remote execution. -.IP s -The application of suffix-transformation rules. (See chapter 3) -.IP t -The maintenance of the list of targets. -.IP v -Variable assignment. -.RE -.IP "\&" -Of these all, the -.CW m -and -.CW s -letters will be most useful to you. -If the -.B \-d -is the final argument or the argument from which it would get these -key letters (see below for a note about which argument would be used) -begins with a -.B \- , -all of these debugging flags will be set, resulting in massive amounts -of output. -.IP "\fB\-f\fP \fImakefile\fP" -.Ix 0 def flags -f -Specify a makefile to read different from the standard makefiles -.CW Makefile "\&" ( -or -.CW makefile ). -.Ix 0 ref makefile default -.Ix 0 ref makefile other -If -.I makefile -is ``\-'', PMake uses the standard input. This is useful for making -quick and dirty makefiles.\|.\|. -.Ix 0 ref makefile "quick and dirty" -.IP \fB\-h\fP -.Ix 0 def flags -h -Prints out a summary of the various flags PMake accepts. It can also -be used to find out what level of concurrency was compiled into the -version of PMake you are using (look at -.B \-J -and -.B \-L ) -and various other information on how PMake was configured. -.Ix 0 ref configuration -.Ix 0 ref makefile system -.IP \fB\-i\fP -.Ix 0 def flags -i -If you give this flag, PMake will ignore non-zero status returned -by any of its shells. It's like placing a `\-' before all the commands -in the makefile. -.IP \fB\-k\fP -.Ix 0 def flags -k -This is similar to -.B \-i -in that it allows PMake to continue when it sees an error, but unlike -.B \-i , -where PMake continues blithely as if nothing went wrong, -.B \-k -causes it to recognize the error and only continue work on those -things that don't depend on the target, either directly or indirectly (through -depending on something that depends on it), whose creation returned the error. -The `k' is for ``keep going''.\|.\|. -.Ix 0 ref target -.IP \fB\-l\fP -.Ix 0 def flags -l -PMake has the ability to lock a directory against other -people executing it in the same directory (by means of a file called -``LOCK.make'' that it creates and checks for in the directory). This -is a Good Thing because two people doing the same thing in the same place -can be disastrous for the final product (too many cooks and all that). -Whether this locking is the default is up to your system -administrator. If locking is on, -.B \-l -will turn it off, and vice versa. Note that this locking will not -prevent \fIyou\fP from invoking PMake twice in the same place \*- if -you own the lock file, PMake will warn you about it but continue to execute. -.IP "\fB\-m\fP \fIdirectory\fP" -.Ix 0 def flags -m -Tells PMake another place to search for included makefiles via the <...> -style. Several -.B \-m -options can be given to form a search path. If this construct is used the -default system makefile search path is completely overridden. -To be explained in chapter 3, section 3.2. -.Rm 2 3.2 -.IP \fB\-n\fP -.Ix 0 def flags -n -This flag tells PMake not to execute the commands needed to update the -out-of-date targets in the makefile. Rather, PMake will simply print -the commands it would have executed and exit. This is particularly -useful for checking the correctness of a makefile. If PMake doesn't do -what you expect it to, it's a good chance the makefile is wrong. -.IP "\fB\-p\fP \fInumber\fP" -.Ix 0 def flags -p -.Ix 0 ref debugging -This causes PMake to print its input in a reasonable form, though -not necessarily one that would make immediate sense to anyone but me. The -.I number -is a bitwise-or of 1 and 2 where 1 means it should print the input -before doing any processing and 2 says it should print it after -everything has been re-created. Thus -.CW "\-p 3" -would print it twice\*-once before processing and once after (you -might find the difference between the two interesting). This is mostly -useful to me, but you may find it informative in some bizarre circumstances. -.IP \fB\-q\fP -.Ix 0 def flags -q -If you give PMake this flag, it will not try to re-create anything. It -will just see if anything is out-of-date and exit non-zero if so. -.IP \fB\-r\fP -.Ix 0 def flags -r -When PMake starts up, it reads a default makefile that tells it what -sort of system it's on and gives it some idea of what to do if you -don't tell it anything. I'll tell you about it in chapter 3. If you -give this flag, PMake won't read the default makefile. -.IP \fB\-s\fP -.Ix 0 def flags -s -This causes PMake to not print commands before they're executed. It -is the equivalent of putting an `@' before every command in the -makefile. -.IP \fB\-t\fP -.Ix 0 def flags -t -Rather than try to re-create a target, PMake will simply ``touch'' it -so as to make it appear up-to-date. If the target didn't exist before, -it will when PMake finishes, but if the target did exist, it will -appear to have been updated. -.IP \fB\-v\fP -.Ix 0 def flags -v -This is a mixed-compatibility flag intended to mimic the System V -version of Make. It is the same as giving -.B \-B , -and -.B \-V -as well as turning off directory locking. Targets can still be created -in parallel, however. This is the mode PMake will enter if it is -invoked either as -.CW smake '' `` -or -.CW vmake ''. `` -.IP \fB\-x\fP -.Ix 0 def flags -x -This tells PMake it's ok to export jobs to other machines, if they're -available. It is used when running in Make mode, as exporting in this -mode tends to make things run slower than if the commands were just -executed locally. -.IP \fB\-B\fP -.Ix 0 ref compatibility -.Ix 0 def flags -B -Forces PMake to be as backwards-compatible with Make as possible while -still being itself. -This includes: -.RS -.IP \(bu 2 -Executing one shell per shell command -.IP \(bu 2 -Expanding anything that looks even vaguely like a variable, with the -empty string replacing any variable PMake doesn't know. -.IP \(bu 2 -Refusing to allow you to escape a `#' with a backslash. -.IP \(bu 2 -Permitting undefined variables on dependency lines and conditionals -(see below). Normally this causes PMake to abort. -.RE -.IP \fB\-C\fP -.Ix 0 def flags -C -This nullifies any and all compatibility mode flags you may have given -or implied up to the time the -.B \-C -is encountered. It is useful mostly in a makefile that you wrote for PMake -to avoid bad things happening when someone runs PMake as -.CW make '' `` -or has things set in the environment that tell it to be compatible. -.B \-C -is -.I not -placed in the -.CW PMAKE -environment variable or the -.CW .MAKEFLAGS -or -.CW MFLAGS -global variables. -.Ix 0 ref variable environment PMAKE -.Ix 0 ref variable global .MAKEFLAGS -.Ix 0 ref variable global MFLAGS -.Ix 0 ref .MAKEFLAGS variable -.Ix 0 ref MFLAGS -.IP "\fB\-D\fP \fIvariable\fP" -.Ix 0 def flags -D -Allows you to define a variable to have -.CW 1 '' `` -as its value. The variable is a global variable, not a command-line -variable. This is useful mostly for people who are used to the C -compiler arguments and those using conditionals, which I'll get into -in section 4.3 -.Rm 1 4.3 -.IP "\fB\-I\fP \fIdirectory\fP" -.Ix 0 def flags -I -Tells PMake another place to search for included makefiles. Yet -another thing to be explained in chapter 3 (section 3.2, to be -precise). -.Rm 2 3.2 -.IP "\fB\-J\fP \fInumber\fP" -.Ix 0 def flags -J -Gives the absolute maximum number of targets to create at once on both -local and remote machines. -.IP "\fB\-L\fP \fInumber\fP" -.Ix 0 def flags -L -This specifies the maximum number of targets to create on the local -machine at once. This may be 0, though you should be wary of doing -this, as PMake may hang until a remote machine becomes available, if -one is not available when it is started. -.IP \fB\-M\fP -.Ix 0 ref compatibility -.Ix 0 def flags -M -This is the flag that provides absolute, complete, full compatibility -with Make. It still allows you to use all but a few of the features of -PMake, but it is non-parallel. This is the mode PMake enters if you -call it -.CW make .'' `` -.IP \fB\-P\fP -.Ix 0 def flags -P -.Ix 0 ref "output control" -When creating targets in parallel, several shells are executing at -once, each wanting to write its own two cent's-worth to the screen. -This output must be captured by PMake in some way in order to prevent -the screen from being filled with garbage even more indecipherable -than you usually see. PMake has two ways of doing this, one of which -provides for much cleaner output and a clear separation between the -output of different jobs, the other of which provides a more immediate -response so one can tell what is really happpening. The former is done -by notifying you when the creation of a target starts, capturing the -output and transferring it to the screen all at once when the job -finishes. The latter is done by catching the output of the shell (and -its children) and buffering it until an entire line is received, then -printing that line preceded by an indication of which job produced -the output. Since I prefer this second method, it is the one used by -default. The first method will be used if you give the -.B \-P -flag to PMake. -.IP \fB\-V\fP -.Ix 0 def flags -V -As mentioned before, the -.B \-V -flag tells PMake to use Make's style of expanding variables, -substituting the empty string for any variable it doesn't know. -.IP \fB\-W\fP -.Ix 0 def flags -W -There are several times when PMake will print a message at you that is -only a warning, i.e. it can continue to work in spite of your having -done something silly (such as forgotten a leading tab for a shell -command). Sometimes you are well aware of silly things you have done -and would like PMake to stop bothering you. This flag tells it to shut -up about anything non-fatal. -.IP \fB\-X\fP -.Ix 0 def flags -X -This flag causes PMake to not attempt to export any jobs to another -machine. -.LP -Several flags may follow a single `\-'. Those flags that require -arguments take them from successive parameters. E.g. -.DS -pmake -fDnI server.mk DEBUG /chip2/X/server/include -.DE -will cause PMake to read -.CW server.mk -as the input makefile, define the variable -.CW DEBUG -as a global variable and look for included makefiles in the directory -.CW /chip2/X/server/include . -.xH 2 Summary -.LP -A makefile is made of four types of lines: -.RS -.IP \(bu 2 -Dependency lines -.IP \(bu 2 -Creation commands -.IP \(bu 2 -Variable assignments -.IP \(bu 2 -Comments, include statements and conditional directives -.RE -.LP -A dependency line is a list of one or more targets, an operator -.CW : ', (` -.CW :: ', ` -or -.CW ! '), ` -and a list of zero or more sources. Sources may contain wildcards and -certain local variables. -.LP -A creation command is a regular shell command preceded by a tab. In -addition, if the first two characters after the tab (and other -whitespace) are a combination of -.CW @ ' ` -or -.CW - ', ` -PMake will cause the command to not be printed (if the character is -.CW @ ') ` -or errors from it to be ignored (if -.CW - '). ` -A blank line, dependency line or variable assignment terminates a -creation script. There may be only one creation script for each target -with a -.CW : ' ` -or -.CW ! ' ` -operator. -.LP -Variables are places to store text. They may be unconditionally -assigned-to using the -.CW = ' ` -.Ix 0 ref = -.Ix 0 ref variable assignment -operator, appended-to using the -.CW += ' ` -.Ix 0 ref += -.Ix 0 ref variable assignment appended -operator, conditionally (if the variable is undefined) assigned-to -with the -.CW ?= ' ` -.Ix 0 ref ?= -.Ix 0 ref variable assignment conditional -operator, and assigned-to with variable expansion with the -.CW := ' ` -.Ix 0 ref := -.Ix 0 ref variable assignment expanded -operator. The output of a shell command may be assigned to a variable -using the -.CW != ' ` -.Ix 0 ref != -.Ix 0 ref variable assignment shell-output -operator. Variables may be expanded (their value inserted) by enclosing -their name in parentheses or curly braces, preceded by a dollar sign. -A dollar sign may be escaped with another dollar sign. Variables are -not expanded if PMake doesn't know about them. There are seven local -variables: -.CW .TARGET , -.CW .ALLSRC , -.CW .OODATE , -.CW .PREFIX , -.CW .IMPSRC , -.CW .ARCHIVE , -and -.CW .MEMBER . -Four of them -.CW .TARGET , ( -.CW .PREFIX , -.CW .ARCHIVE , -and -.CW .MEMBER ) -may be used to specify ``dynamic sources.'' -.Ix 0 ref "dynamic source" -.Ix 0 ref source dynamic -Variables are good. Know them. Love them. Live them. -.LP -Debugging of makefiles is best accomplished using the -.B \-n , -.B "\-d m" , -and -.B "\-p 2" -flags. -.xH 2 Exercises -.ce -\s+4\fBTBA\fP\s0 -.xH 1 Short-cuts and Other Nice Things -.LP -Based on what I've told you so far, you may have gotten the impression -that PMake is just a way of storing away commands and making sure you -don't forget to compile something. Good. That's just what it is. -However, the ways I've described have been inelegant, at best, and -painful, at worst. -This chapter contains things that make the -writing of makefiles easier and the makefiles themselves shorter and -easier to modify (and, occasionally, simpler). In this chapter, I -assume you are somewhat more -familiar with Sprite (or UNIX, if that's what you're using) than I did -in chapter 2, just so you're on your toes. -So without further ado... -.xH 2 Transformation Rules -.LP -As you know, a file's name consists of two parts: a base name, which -gives some hint as to the contents of the file, and a suffix, which -usually indicates the format of the file. -Over the years, as -.UX -has developed, -naming conventions, with regard to suffixes, have also developed that have -become almost as incontrovertible as Law. E.g. a file ending in -.CW .c -is assumed to contain C source code; one with a -.CW .o -suffix is assumed to be a compiled, relocatable object file that may -be linked into any program; a file with a -.CW .ms -suffix is usually a text file to be processed by Troff with the \-ms -macro package, and so on. -One of the best aspects of both Make and PMake comes from their -understanding of how the suffix of a file pertains to its contents and -their ability to do things with a file based soley on its suffix. This -ability comes from something known as a transformation rule. A -transformation rule specifies how to change a file with one suffix -into a file with another suffix. -.LP -A transformation rule looks much like a dependency line, except the -target is made of two known suffixes stuck together. Suffixes are made -known to PMake by placing them as sources on a dependency line whose -target is the special target -.CW .SUFFIXES . -E.g. -.DS -\&.SUFFIXES : .o .c -\&.c.o : - $(CC) $(CFLAGS) -c $(.IMPSRC) -.DE -The creation script attached to the target is used to transform a file with -the first suffix (in this case, -.CW .c ) -into a file with the second suffix (here, -.CW .o ). -In addition, the target inherits whatever attributes have been applied -to the transformation rule. -The simple rule given above says that to transform a C source file -into an object file, you compile it using -.CW cc -with the -.CW \-c -flag. -This rule is taken straight from the system makefile. Many -transformation rules (and suffixes) are defined there, and I refer you -to it for more examples (type -.CW "pmake -h" '' `` -to find out where it is). -.LP -There are several things to note about the transformation rule given -above: -.RS -.IP 1) -The -.CW .IMPSRC -variable. -.Ix 0 def variable local .IMPSRC -.Ix 0 def .IMPSRC -This variable is set to the ``implied source'' (the file from which -the target is being created; the one with the first suffix), which, in this -case, is the .c file. -.IP 2) -The -.CW CFLAGS -variable. Almost all of the transformation rules in the system -makefile are set up using variables that you can alter in your -makefile to tailor the rule to your needs. In this case, if you want -all your C files to be compiled with the -.B \-g -flag, to provide information for -.CW dbx , -you would set the -.CW CFLAGS -variable to contain -.CW -g -.CW "CFLAGS = -g" '') (`` -and PMake would take care of the rest. -.RE -.LP -To give you a quick example, the makefile in 2.3.4 -.Rm 3 2.3.4 -could be changed to this: -.DS -OBJS = a.o b.o c.o -program : $(OBJS) - $(CC) -o $(.TARGET) $(.ALLSRC) -$(OBJS) : defs.h -.DE -The transformation rule I gave above takes the place of the 6 lines\** -.FS -This is also somewhat cleaner, I think, than the dynamic source -solution presented in 2.6 -.FE -.Rm 4 2.6 -.DS -a.o : a.c - cc -c a.c -b.o : b.c - cc -c b.c -c.o : c.c - cc -c c.c -.DE -.LP -Now you may be wondering about the dependency between the -.CW .o -and -.CW .c -files \*- it's not mentioned anywhere in the new makefile. This is -because it isn't needed: one of the effects of applying a -transformation rule is the target comes to depend on the implied -source. That's why it's called the implied -.I source . -.LP -For a more detailed example. Say you have a makefile like this: -.DS -a.out : a.o b.o - $(CC) $(.ALLSRC) -.DE -and a directory set up like this: -.DS -total 4 --rw-rw-r-- 1 deboor 34 Sep 7 00:43 Makefile --rw-rw-r-- 1 deboor 119 Oct 3 19:39 a.c --rw-rw-r-- 1 deboor 201 Sep 7 00:43 a.o --rw-rw-r-- 1 deboor 69 Sep 7 00:43 b.c -.DE -While just typing -.CW pmake '' `` -will do the right thing, it's much more informative to type -.CW "pmake -d s" ''. `` -This will show you what PMake is up to as it processes the files. In -this case, PMake prints the following: -.DS -Suff_FindDeps (a.out) - using existing source a.o - applying .o -> .out to "a.o" -Suff_FindDeps (a.o) - trying a.c...got it - applying .c -> .o to "a.c" -Suff_FindDeps (b.o) - trying b.c...got it - applying .c -> .o to "b.c" -Suff_FindDeps (a.c) - trying a.y...not there - trying a.l...not there - trying a.c,v...not there - trying a.y,v...not there - trying a.l,v...not there -Suff_FindDeps (b.c) - trying b.y...not there - trying b.l...not there - trying b.c,v...not there - trying b.y,v...not there - trying b.l,v...not there ---- a.o --- -cc -c a.c ---- b.o --- -cc -c b.c ---- a.out --- -cc a.o b.o -.DE -.LP -.CW Suff_FindDeps -is the name of a function in PMake that is called to check for implied -sources for a target using transformation rules. -The transformations it tries are, naturally -enough, limited to the ones that have been defined (a transformation -may be defined multiple times, by the way, but only the most recent -one will be used). You will notice, however, that there is a definite -order to the suffixes that are tried. This order is set by the -relative positions of the suffixes on the -.CW .SUFFIXES -line \*- the earlier a suffix appears, the earlier it is checked as -the source of a transformation. Once a suffix has been defined, the -only way to change its position in the pecking order is to remove all -the suffixes (by having a -.CW .SUFFIXES -dependency line with no sources) and redefine them in the order you -want. (Previously-defined transformation rules will be automatically -redefined as the suffixes they involve are re-entered.) -.LP -Another way to affect the search order is to make the dependency -explicit. In the above example, -.CW a.out -depends on -.CW a.o -and -.CW b.o . -Since a transformation exists from -.CW .o -to -.CW .out , -PMake uses that, as indicated by the -.CW "using existing source a.o" '' `` -message. -.LP -The search for a transformation starts from the suffix of the target -and continues through all the defined transformations, in the order -dictated by the suffix ranking, until an existing file with the same -base (the target name minus the suffix and any leading directories) is -found. At that point, one or more transformation rules will have been -found to change the one existing file into the target. -.LP -For example, ignoring what's in the system makefile for now, say you -have a makefile like this: -.DS -\&.SUFFIXES : .out .o .c .y .l -\&.l.c : - lex $(.IMPSRC) - mv lex.yy.c $(.TARGET) -\&.y.c : - yacc $(.IMPSRC) - mv y.tab.c $(.TARGET) -\&.c.o : - cc -c $(.IMPSRC) -\&.o.out : - cc -o $(.TARGET) $(.IMPSRC) -.DE -and the single file -.CW jive.l . -If you were to type -.CW "pmake -rd ms jive.out" ,'' `` -you would get the following output for -.CW jive.out : -.DS -Suff_FindDeps (jive.out) - trying jive.o...not there - trying jive.c...not there - trying jive.y...not there - trying jive.l...got it - applying .l -> .c to "jive.l" - applying .c -> .o to "jive.c" - applying .o -> .out to "jive.o" -.DE -and this is why: PMake starts with the target -.CW jive.out , -figures out its suffix -.CW .out ) ( -and looks for things it can transform to a -.CW .out -file. In this case, it only finds -.CW .o , -so it looks for the file -.CW jive.o . -It fails to find it, so it looks for transformations into a -.CW .o -file. Again it has only one choice: -.CW .c . -So it looks for -.CW jive.c -and, as you know, fails to find it. At this point it has two choices: -it can create the -.CW .c -file from either a -.CW .y -file or a -.CW .l -file. Since -.CW .y -came first on the -.CW .SUFFIXES -line, it checks for -.CW jive.y -first, but can't find it, so it looks for -.CW jive.l -and, lo and behold, there it is. -At this point, it has defined a transformation path as follows: -.CW .l -\(-> -.CW .c -\(-> -.CW .o -\(-> -.CW .out -and applies the transformation rules accordingly. For completeness, -and to give you a better idea of what PMake actually did with this -three-step transformation, this is what PMake printed for the rest of -the process: -.DS -Suff_FindDeps (jive.o) - using existing source jive.c - applying .c -> .o to "jive.c" -Suff_FindDeps (jive.c) - using existing source jive.l - applying .l -> .c to "jive.l" -Suff_FindDeps (jive.l) -Examining jive.l...modified 17:16:01 Oct 4, 1987...up-to-date -Examining jive.c...non-existent...out-of-date ---- jive.c --- -lex jive.l -\&.\|.\|. meaningless lex output deleted .\|.\|. -mv lex.yy.c jive.c -Examining jive.o...non-existent...out-of-date ---- jive.o --- -cc -c jive.c -Examining jive.out...non-existent...out-of-date ---- jive.out --- -cc -o jive.out jive.o -.DE -.LP -One final question remains: what does PMake do with targets that have -no known suffix? PMake simply pretends it actually has a known suffix -and searches for transformations accordingly. -The suffix it chooses is the source for the -.CW .NULL -.Ix 0 ref .NULL -target mentioned later. In the system makefile, -.CW .out -is chosen as the ``null suffix'' -.Ix 0 def suffix null -.Ix 0 def "null suffix" -because most people use PMake to create programs. You are, however, -free and welcome to change it to a suffix of your own choosing. -The null suffix is ignored, however, when PMake is in compatibility -mode (see chapter 4). -.xH 2 Including Other Makefiles -.Ix 0 def makefile inclusion -.Rd 2 -.LP -Just as for programs, it is often useful to extract certain parts of a -makefile into another file and just include it in other makefiles -somehow. Many compilers allow you say something like -.DS -#include "defs.h" -.DE -to include the contents of -.CW defs.h -in the source file. PMake allows you to do the same thing for -makefiles, with the added ability to use variables in the filenames. -An include directive in a makefile looks either like this: -.DS -#include -.DE -or this -.DS -#include "file" -.DE -The difference between the two is where PMake searches for the file: -the first way, PMake will look for -the file only in the system makefile directory (or directories) -(to find out what that directory is, give PMake the -.B \-h -flag). -.Ix 0 ref flags -h -The system makefile directory search path can be overridden via the -.B \-m -option. -.Ix 0 ref flags -m -For files in double-quotes, the search is more complex: -.RS -.IP 1) -The directory of the makefile that's including the file. -.IP 2) -The current directory (the one in which you invoked PMake). -.IP 3) -The directories given by you using -.B \-I -flags, in the order in which you gave them. -.IP 4) -Directories given by -.CW .PATH -dependency lines (see chapter 4). -.IP 5) -The system makefile directory. -.RE -.LP -in that order. -.LP -You are free to use PMake variables in the filename\*-PMake will -expand them before searching for the file. You must specify the -searching method with either angle brackets or double-quotes -.I outside -of a variable expansion. I.e. the following -.DS -SYSTEM = - -#include $(SYSTEM) -.DE -won't work. -.xH 2 Saving Commands -.LP -.Ix 0 def ... -There may come a time when you will want to save certain commands to -be executed when everything else is done. For instance: you're -making several different libraries at one time and you want to create the -members in parallel. Problem is, -.CW ranlib -is another one of those programs that can't be run more than once in -the same directory at the same time (each one creates a file called -.CW __.SYMDEF -into which it stuffs information for the linker to use. Two of them -running at once will overwrite each other's file and the result will -be garbage for both parties). You might want a way to save the ranlib -commands til the end so they can be run one after the other, thus -keeping them from trashing each other's file. PMake allows you to do -this by inserting an ellipsis (``.\|.\|.'') as a command between -commands to be run at once and those to be run later. -.LP -So for the -.CW ranlib -case above, you might do this: -.Rd 5 -.DS -lib1.a : $(LIB1OBJS) - rm -f $(.TARGET) - ar cr $(.TARGET) $(.ALLSRC) - ... - ranlib $(.TARGET) - -lib2.a : $(LIB2OBJS) - rm -f $(.TARGET) - ar cr $(.TARGET) $(.ALLSRC) - ... - ranlib $(.TARGET) -.DE -.Ix 0 ref variable local .TARGET -.Ix 0 ref variable local .ALLSRC -This would save both -.DS -ranlib $(.TARGET) -.DE -commands until the end, when they would run one after the other -(using the correct value for the -.CW .TARGET -variable, of course). -.LP -Commands saved in this manner are only executed if PMake manages to -re-create everything without an error. -.xH 2 Target Attributes -.LP -PMake allows you to give attributes to targets by means of special -sources. Like everything else PMake uses, these sources begin with a -period and are made up of all upper-case letters. There are various -reasons for using them, and I will try to give examples for most of -them. Others you'll have to find uses for yourself. Think of it as ``an -exercise for the reader.'' By placing one (or more) of these as a source on a -dependency line, you are ``marking the target(s) with that -attribute.'' That's just the way I phrase it, so you know. -.LP -Any attributes given as sources for a transformation rule are applied -to the target of the transformation rule when the rule is applied. -.Ix 0 def attributes -.Ix 0 ref source -.Ix 0 ref target -.nr pw 12 -.IP .DONTCARE \n(pw -.Ix 0 def attributes .DONTCARE -.Ix 0 def .DONTCARE -If a target is marked with this attribute and PMake can't figure out -how to create it, it will ignore this fact and assume the file isn't -really needed or actually exists and PMake just can't find it. This may prove -wrong, but the error will be noted later on, not when PMake tries to create -the target so marked. This attribute also prevents PMake from -attempting to touch the target if it is given the -.B \-t -flag. -.Ix 0 ref flags -t -.IP .EXEC \n(pw -.Ix 0 def attributes .EXEC -.Ix 0 def .EXEC -This attribute causes its shell script to be executed while having no -effect on targets that depend on it. This makes the target into a sort -of subroutine. An example. Say you have some LISP files that need to -be compiled and loaded into a LISP process. To do this, you echo LISP -commands into a file and execute a LISP with this file as its input -when everything's done. Say also that you have to load other files -from another system before you can compile your files and further, -that you don't want to go through the loading and dumping unless one -of -.I your -files has changed. Your makefile might look a little bit -like this (remember, this is an educational example, and don't worry -about the -.CW COMPILE -rule, all will soon become clear, grasshopper): -.DS -system : init a.fasl b.fasl c.fasl - for i in $(.ALLSRC); - do - echo -n '(load "' >> input - echo -n ${i} >> input - echo '")' >> input - done - echo '(dump "$(.TARGET)")' >> input - lisp < input - -a.fasl : a.l init COMPILE -b.fasl : b.l init COMPILE -c.fasl : c.l init COMPILE -COMPILE : .USE - echo '(compile "$(.ALLSRC)")' >> input -init : .EXEC - echo '(load-system)' > input -.DE -.Ix 0 ref .USE -.Ix 0 ref attributes .USE -.Ix 0 ref variable local .ALLSRC -.IP "\&" -.CW .EXEC -sources, don't appear in the local variables of targets that depend on -them (nor are they touched if PMake is given the -.B \-t -flag). -.Ix 0 ref flags -t -Note that all the rules, not just that for -.CW system , -include -.CW init -as a source. This is because none of the other targets can be made -until -.CW init -has been made, thus they depend on it. -.IP .EXPORT \n(pw -.Ix 0 def attributes .EXPORT -.Ix 0 def .EXPORT -This is used to mark those targets whose creation should be sent to -another machine if at all possible. This may be used by some -exportation schemes if the exportation is expensive. You should ask -your system administrator if it is necessary. -.IP .EXPORTSAME \n(pw -.Ix 0 def attributes .EXPORTSAME -.Ix 0 def .EXPORTSAME -Tells the export system that the job should be exported to a machine -of the same architecture as the current one. Certain operations (e.g. -running text through -.CW nroff ) -can be performed the same on any architecture (CPU and -operating system type), while others (e.g. compiling a program with -.CW cc ) -must be performed on a machine with the same architecture. Not all -export systems will support this attribute. -.IP .IGNORE \n(pw -.Ix 0 def attributes .IGNORE -.Ix 0 def .IGNORE attribute -Giving a target the -.CW .IGNORE -attribute causes PMake to ignore errors from any of the target's commands, as -if they all had `\-' before them. -.IP .INVISIBLE \n(pw -.Ix 0 def attributes .INVISIBLE -.Ix 0 def .INVISIBLE -This allows you to specify one target as a source for another without -the one affecting the other's local variables. Useful if, say, you -have a makefile that creates two programs, one of which is used to -create the other, so it must exist before the other is created. You -could say -.DS -prog1 : $(PROG1OBJS) prog2 MAKEINSTALL -prog2 : $(PROG2OBJS) .INVISIBLE MAKEINSTALL -.DE -where -.CW MAKEINSTALL -is some complex .USE rule (see below) that depends on the -.Ix 0 ref .USE -.CW .ALLSRC -variable containing the right things. Without the -.CW .INVISIBLE -attribute for -.CW prog2 , -the -.CW MAKEINSTALL -rule couldn't be applied. This is not as useful as it should be, and -the semantics may change (or the whole thing go away) in the -not-too-distant future. -.IP .JOIN \n(pw -.Ix 0 def attributes .JOIN -.Ix 0 def .JOIN -This is another way to avoid performing some operations in parallel -while permitting everything else to be done so. Specifically it -forces the target's shell script to be executed only if one or more of the -sources was out-of-date. In addition, the target's name, -in both its -.CW .TARGET -variable and all the local variables of any target that depends on it, -is replaced by the value of its -.CW .ALLSRC -variable. -As an example, suppose you have a program that has four libraries that -compile in the same directory along with, and at the same time as, the -program. You again have the problem with -.CW ranlib -that I mentioned earlier, only this time it's more severe: you -can't just put the ranlib off to the end since the program -will need those libraries before it can be re-created. You can do -something like this: -.DS -program : $(OBJS) libraries - cc -o $(.TARGET) $(.ALLSRC) - -libraries : lib1.a lib2.a lib3.a lib4.a .JOIN - ranlib $(.OODATE) -.DE -.Ix 0 ref variable local .TARGET -.Ix 0 ref variable local .ALLSRC -.Ix 0 ref variable local .OODATE -.Ix 0 ref .TARGET -.Ix 0 ref .ALLSRC -.Ix 0 ref .OODATE -In this case, PMake will re-create the -.CW $(OBJS) -as necessary, along with -.CW lib1.a , -.CW lib2.a , -.CW lib3.a -and -.CW lib4.a . -It will then execute -.CW ranlib -on any library that was changed and set -.CW program 's -.CW .ALLSRC -variable to contain what's in -.CW $(OBJS) -followed by -.CW "lib1.a lib2.a lib3.a lib4.a" .'' `` -In case you're wondering, it's called -.CW .JOIN -because it joins together different threads of the ``input graph'' at -the target marked with the attribute. -Another aspect of the .JOIN attribute is it keeps the target from -being created if the -.B \-t -flag was given. -.Ix 0 ref flags -t -.IP .MAKE \n(pw -.Ix 0 def attributes .MAKE -.Ix 0 def .MAKE -The -.CW .MAKE -attribute marks its target as being a recursive invocation of PMake. -This forces PMake to execute the script associated with the target (if -it's out-of-date) even if you gave the -.B \-n -or -.B \-t -flag. By doing this, you can start at the top of a system and type -.DS -pmake -n -.DE -and have it descend the directory tree (if your makefiles are set up -correctly), printing what it would have executed if you hadn't -included the -.B \-n -flag. -.IP .NOEXPORT \n(pw -.Ix 0 def attributes .NOEXPORT -.Ix 0 def .NOEXPORT attribute -If possible, PMake will attempt to export the creation of all targets to -another machine (this depends on how PMake was configured). Sometimes, -the creation is so simple, it is pointless to send it to another -machine. If you give the target the -.CW .NOEXPORT -attribute, it will be run locally, even if you've given PMake the -.B "\-L 0" -flag. -.IP .NOTMAIN \n(pw -.Ix 0 def attributes .NOTMAIN -.Ix 0 def .NOTMAIN -Normally, if you do not specify a target to make in any other way, -PMake will take the first target on the first dependency line of a -makefile as the target to create. That target is known as the ``Main -Target'' and is labeled as such if you print the dependencies out -using the -.B \-p -flag. -.Ix 0 ref flags -p -Giving a target this attribute tells PMake that the target is -definitely -.I not -the Main Target. -This allows you to place targets in an included makefile and -have PMake create something else by default. -.IP .PRECIOUS \n(pw -.Ix 0 def attributes .PRECIOUS -.Ix 0 def .PRECIOUS attribute -When PMake is interrupted (you type control-C at the keyboard), it -will attempt to clean up after itself by removing any half-made -targets. If a target has the -.CW .PRECIOUS -attribute, however, PMake will leave it alone. An additional side -effect of the `::' operator is to mark the targets as -.CW .PRECIOUS . -.Ix 0 ref operator double-colon -.Ix 0 ref :: -.IP .SILENT \n(pw -.Ix 0 def attributes .SILENT -.Ix 0 def .SILENT attribute -Marking a target with this attribute keeps its commands from being -printed when they're executed, just as if they had an `@' in front of them. -.IP .USE \n(pw -.Ix 0 def attributes .USE -.Ix 0 def .USE -By giving a target this attribute, you turn it into PMake's equivalent -of a macro. When the target is used as a source for another target, -the other target acquires the commands, sources and attributes (except -.CW .USE ) -of the source. -If the target already has commands, the -.CW .USE -target's commands are added to the end. If more than one .USE-marked -source is given to a target, the rules are applied sequentially. -.IP "\&" \n(pw -The typical .USE rule (as I call them) will use the sources of the -target to which it is applied (as stored in the -.CW .ALLSRC -variable for the target) as its ``arguments,'' if you will. -For example, you probably noticed that the commands for creating -.CW lib1.a -and -.CW lib2.a -in the example in section 3.3 -.Rm 5 3.3 -were exactly the same. You can use the -.CW .USE -attribute to eliminate the repetition, like so: -.DS -lib1.a : $(LIB1OBJS) MAKELIB -lib2.a : $(LIB2OBJS) MAKELIB - -MAKELIB : .USE - rm -f $(.TARGET) - ar cr $(.TARGET) $(.ALLSRC) - ... - ranlib $(.TARGET) -.DE -.Ix 0 ref variable local .TARGET -.Ix 0 ref variable local .ALLSRC -.IP "\&" \n(pw -Several system makefiles (not to be confused with The System Makefile) -make use of these .USE rules to make your -life easier (they're in the default, system makefile directory...take a look). -Note that the .USE rule source itself -.CW MAKELIB ) ( -does not appear in any of the targets's local variables. -There is no limit to the number of times I could use the -.CW MAKELIB -rule. If there were more libraries, I could continue with -.CW "lib3.a : $(LIB3OBJS) MAKELIB" '' `` -and so on and so forth. -.xH 2 Special Targets -.LP -As there were in Make, so there are certain targets that have special -meaning to PMake. When you use one on a dependency line, it is the -only target that may appear on the left-hand-side of the operator. -.Ix 0 ref target -.Ix 0 ref operator -As for the attributes and variables, all the special targets -begin with a period and consist of upper-case letters only. -I won't describe them all in detail because some of them are rather -complex and I'll describe them in more detail than you'll want in -chapter 4. -The targets are as follows: -.nr pw 10 -.IP .BEGIN \n(pw -.Ix 0 def .BEGIN -Any commands attached to this target are executed before anything else -is done. You can use it for any initialization that needs doing. -.IP .DEFAULT \n(pw -.Ix 0 def .DEFAULT -This is sort of a .USE rule for any target (that was used only as a -source) that PMake can't figure out any other way to create. It's only -``sort of'' a .USE rule because only the shell script attached to the -.CW .DEFAULT -target is used. The -.CW .IMPSRC -variable of a target that inherits -.CW .DEFAULT 's -commands is set to the target's own name. -.Ix 0 ref .IMPSRC -.Ix 0 ref variable local .IMPSRC -.IP .END \n(pw -.Ix 0 def .END -This serves a function similar to -.CW .BEGIN , -in that commands attached to it are executed once everything has been -re-created (so long as no errors occurred). It also serves the extra -function of being a place on which PMake can hang commands you put off -to the end. Thus the script for this target will be executed before -any of the commands you save with the ``.\|.\|.''. -.Ix 0 ref ... -.IP .EXPORT \n(pw -The sources for this target are passed to the exportation system compiled -into PMake. Some systems will use these sources to configure -themselves. You should ask your system administrator about this. -.IP .IGNORE \n(pw -.Ix 0 def .IGNORE target -.Ix 0 ref .IGNORE attribute -.Ix 0 ref attributes .IGNORE -This target marks each of its sources with the -.CW .IGNORE -attribute. If you don't give it any sources, then it is like -giving the -.B \-i -flag when you invoke PMake \*- errors are ignored for all commands. -.Ix 0 ref flags -i -.IP .INCLUDES \n(pw -.Ix 0 def .INCLUDES target -.Ix 0 def variable global .INCLUDES -.Ix 0 def .INCLUDES variable -The sources for this target are taken to be suffixes that indicate a -file that can be included in a program source file. -The suffix must have already been declared with -.CW .SUFFIXES -(see below). -Any suffix so marked will have the directories on its search path -(see -.CW .PATH , -below) placed in the -.CW .INCLUDES -variable, each preceded by a -.B \-I -flag. This variable can then be used as an argument for the compiler -in the normal fashion. The -.CW .h -suffix is already marked in this way in the system makefile. -.Ix 0 ref makefile system -E.g. if you have -.DS -\&.SUFFIXES : .bitmap -\&.PATH.bitmap : /usr/local/X/lib/bitmaps -\&.INCLUDES : .bitmap -.DE -PMake will place -.CW "-I/usr/local/X/lib/bitmaps" '' `` -in the -.CW .INCLUDES -variable and you can then say -.DS -cc $(.INCLUDES) -c xprogram.c -.DE -(Note: the -.CW .INCLUDES -variable is not actually filled in until the entire makefile has been read.) -.IP .INTERRUPT \n(pw -.Ix 0 def .INTERRUPT -When PMake is interrupted, -it will execute the commands in the script for this target, if it -exists. -.IP .LIBS \n(pw -.Ix 0 def .LIBS target -.Ix 0 def .LIBS variable -.Ix 0 def variable global .LIBS -This does for libraries what -.CW .INCLUDES -does for include files, except the flag used is -.B \-L , -as required by those linkers that allow you to tell them where to find -libraries. The variable used is -.CW .LIBS . -Be forewarned that PMake may not have been compiled to do this if the -linker on your system doesn't accept the -.B \-L -flag, though the -.CW .LIBS -variable will always be defined once the makefile has been read. -.IP .MAIN \n(pw -.Ix 0 def .MAIN -If you didn't give a target (or targets) to create when you invoked -PMake, it will take the sources of this target as the targets to -create. -.IP .MAKEFLAGS \n(pw -.Ix 0 def .MAKEFLAGS target -This target provides a way for you to always specify flags for PMake -when the makefile is used. The flags are just as they would be typed -to the shell (except you can't use shell variables unless they're in -the environment), -though the -.B \-f -and -.B \-r -flags have no effect. -.IP .NULL \n(pw -.Ix 0 def .NULL -.Ix 0 ref suffix null -.Ix 0 ref "null suffix" -This allows you to specify what suffix PMake should pretend a file has -if, in fact, it has no known suffix. Only one suffix may be so -designated. The last source on the dependency line is the suffix that -is used (you should, however, only give one suffix.\|.\|.). -.IP .PATH \n(pw -.Ix 0 def .PATH -If you give sources for this target, PMake will take them as -directories in which to search for files it cannot find in the current -directory. If you give no sources, it will clear out any directories -added to the search path before. Since the effects of this all get -very complex, I'll leave it til chapter four to give you a complete -explanation. -.IP .PATH\fIsuffix\fP \n(pw -.Ix 0 ref .PATH -This does a similar thing to -.CW .PATH , -but it does it only for files with the given suffix. The suffix must -have been defined already. Look at -.B "Search Paths" -(section 4.1) -.Rm 6 4.1 -for more information. -.IP .PRECIOUS \n(pw -.Ix 0 def .PRECIOUS target -.Ix 0 ref .PRECIOUS attribute -.Ix 0 ref attributes .PRECIOUS -Similar to -.CW .IGNORE , -this gives the -.CW .PRECIOUS -attribute to each source on the dependency line, unless there are no -sources, in which case the -.CW .PRECIOUS -attribute is given to every target in the file. -.IP .RECURSIVE \n(pw -.Ix 0 def .RECURSIVE -.Ix 0 ref attributes .MAKE -.Ix 0 ref .MAKE -This target applies the -.CW .MAKE -attribute to all its sources. It does nothing if you don't give it any sources. -.IP .SHELL \n(pw -.Ix 0 def .SHELL -PMake is not constrained to only using the Bourne shell to execute -the commands you put in the makefile. You can tell it some other shell -to use with this target. Check out -.B "A Shell is a Shell is a Shell" -(section 4.4) -.Rm 7 4.4 -for more information. -.IP .SILENT \n(pw -.Ix 0 def .SILENT target -.Ix 0 ref .SILENT attribute -.Ix 0 ref attributes .SILENT -When you use -.CW .SILENT -as a target, it applies the -.CW .SILENT -attribute to each of its sources. If there are no sources on the -dependency line, then it is as if you gave PMake the -.B \-s -flag and no commands will be echoed. -.IP .SUFFIXES \n(pw -.Ix 0 def .SUFFIXES -This is used to give new file suffixes for PMake to handle. Each -source is a suffix PMake should recognize. If you give a -.CW .SUFFIXES -dependency line with no sources, PMake will forget about all the -suffixes it knew (this also nukes the null suffix). -For those targets that need to have suffixes defined, this is how you do it. -.LP -In addition to these targets, a line of the form -.DS -\fIattribute\fP : \fIsources\fP -.DE -applies the -.I attribute -to all the targets listed as -.I sources . -.xH 2 Modifying Variable Expansion -.LP -.Ix 0 def variable expansion modified -.Ix 0 ref variable expansion -.Ix 0 def variable modifiers -Variables need not always be expanded verbatim. PMake defines several -modifiers that may be applied to a variable's value before it is -expanded. You apply a modifier by placing it after the variable name -with a colon between the two, like so: -.DS -${\fIVARIABLE\fP:\fImodifier\fP} -.DE -Each modifier is a single character followed by something specific to -the modifier itself. -You may apply as many modifiers as you want \*- each one is applied to -the result of the previous and is separated from the previous by -another colon. -.LP -There are seven ways to modify a variable's expansion, most of which -come from the C shell variable modification characters: -.RS -.IP "M\fIpattern\fP" -.Ix 0 def :M -.Ix 0 def modifier match -This is used to select only those words (a word is a series of -characters that are neither spaces nor tabs) that match the given -.I pattern . -The pattern is a wildcard pattern like that used by the shell, where -.CW * -means 0 or more characters of any sort; -.CW ? -is any single character; -.CW [abcd] -matches any single character that is either `a', `b', `c' or `d' -(there may be any number of characters between the brackets); -.CW [0-9] -matches any single character that is between `0' and `9' (i.e. any -digit. This form may be freely mixed with the other bracket form), and -`\\' is used to escape any of the characters `*', `?', `[' or `:', -leaving them as regular characters to match themselves in a word. -For example, the system makefile -.CW -uses -.CW "$(CFLAGS:M-[ID]*)" '' `` -to extract all the -.CW \-I -and -.CW \-D -flags that would be passed to the C compiler. This allows it to -properly locate include files and generate the correct dependencies. -.IP "N\fIpattern\fP" -.Ix 0 def :N -.Ix 0 def modifier nomatch -This is identical to -.CW :M -except it substitutes all words that don't match the given pattern. -.IP "S/\fIsearch-string\fP/\fIreplacement-string\fP/[g]" -.Ix 0 def :S -.Ix 0 def modifier substitute -Causes the first occurrence of -.I search-string -in the variable to be replaced by -.I replacement-string , -unless the -.CW g -flag is given at the end, in which case all occurrences of the string -are replaced. The substitution is performed on each word in the -variable in turn. If -.I search-string -begins with a -.CW ^ , -the string must match starting at the beginning of the word. If -.I search-string -ends with a -.CW $ , -the string must match to the end of the word (these two may be -combined to force an exact match). If a backslash precedes these two -characters, however, they lose their special meaning. Variable -expansion also occurs in the normal fashion inside both the -.I search-string -and the -.I replacement-string , -.B except -that a backslash is used to prevent the expansion of a -.CW $ , -not another dollar sign, as is usual. -Note that -.I search-string -is just a string, not a pattern, so none of the usual -regular-expression/wildcard characters have any special meaning save -.CW ^ -and -.CW $ . -In the replacement string, -the -.CW & -character is replaced by the -.I search-string -unless it is preceded by a backslash. -You are allowed to use any character except -colon or exclamation point to separate the two strings. This so-called -delimiter character may be placed in either string by preceding it -with a backslash. -.IP T -.Ix 0 def :T -.Ix 0 def modifier tail -Replaces each word in the variable expansion by its last -component (its ``tail''). For example, given -.DS -OBJS = ../lib/a.o b /usr/lib/libm.a -TAILS = $(OBJS:T) -.DE -the variable -.CW TAILS -would expand to -.CW "a.o b libm.a" .'' `` -.IP H -.Ix 0 def :H -.Ix 0 def modifier head -This is similar to -.CW :T , -except that every word is replaced by everything but the tail (the -``head''). Using the same definition of -.CW OBJS , -the string -.CW "$(OBJS:H)" '' `` -would expand to -.CW "../lib /usr/lib" .'' `` -Note that the final slash on the heads is removed and -anything without a head is replaced by the empty string. -.IP E -.Ix 0 def :E -.Ix 0 def modifier extension -.Ix 0 def modifier suffix -.Ix 0 ref suffix "variable modifier" -.CW :E -replaces each word by its suffix (``extension''). So -.CW "$(OBJS:E)" '' `` -would give you -.CW ".o .a" .'' `` -.IP R -.Ix 0 def :R -.Ix 0 def modifier root -.Ix 0 def modifier base -This replaces each word by everything but the suffix (the ``root'' of -the word). -.CW "$(OBJS:R)" '' `` -expands to `` -.CW "../lib/a b /usr/lib/libm" .'' -.RE -.LP -In addition, the System V style of substitution is also supported. -This looks like: -.DS -$(\fIVARIABLE\fP:\fIsearch-string\fP=\fIreplacement\fP) -.DE -It must be the last modifier in the chain. The search is anchored at -the end of each word, so only suffixes or whole words may be replaced. -.xH 2 More on Debugging -.xH 2 More Exercises -.IP (3.1) -You've got a set programs, each of which is created from its own -assembly-language source file (suffix -.CW .asm ). -Each program can be assembled into two versions, one with error-checking -code assembled in and one without. You could assemble them into files -with different suffixes -.CW .eobj \& ( -and -.CW .obj , -for instance), but your linker only understands files that end in -.CW .obj . -To top it all off, the final executables -.I must -have the suffix -.CW .exe . -How can you still use transformation rules to make your life easier -(Hint: assume the error-checking versions have -.CW ec -tacked onto their prefix)? -.IP (3.2) -Assume, for a moment or two, you want to perform a sort of -``indirection'' by placing the name of a variable into another one, -then you want to get the value of the first by expanding the second -somehow. Unfortunately, PMake doesn't allow constructs like -.DS I -$($(FOO)) -.DE -What do you do? Hint: no further variable expansion is performed after -modifiers are applied, thus if you cause a $ to occur in the -expansion, that's what will be in the result. -.xH 1 PMake for Gods -.LP -This chapter is devoted to those facilities in PMake that allow you to -do a great deal in a makefile with very little work, as well as do -some things you couldn't do in Make without a great deal of work (and -perhaps the use of other programs). The problem with these features, -is they must be handled with care, or you will end up with a mess. -.LP -Once more, I assume a greater familiarity with -.UX -or Sprite than I did in the previous two chapters. -.xH 2 Search Paths -.Rd 6 -.LP -PMake supports the dispersal of files into multiple directories by -allowing you to specify places to look for sources with -.CW .PATH -targets in the makefile. The directories you give as sources for these -targets make up a ``search path.'' Only those files used exclusively -as sources are actually sought on a search path, the assumption being -that anything listed as a target in the makefile can be created by the -makefile and thus should be in the current directory. -.LP -There are two types of search paths -in PMake: one is used for all types of files (including included -makefiles) and is specified with a plain -.CW .PATH -target (e.g. -.CW ".PATH : RCS" ''), `` -while the other is specific to a certain type of file, as indicated by -the file's suffix. A specific search path is indicated by immediately following -the -.CW .PATH -with the suffix of the file. For instance -.DS -\&.PATH.h : /sprite/lib/include /sprite/att/lib/include -.DE -would tell PMake to look in the directories -.CW /sprite/lib/include -and -.CW /sprite/att/lib/include -for any files whose suffix is -.CW .h . -.LP -The current directory is always consulted first to see if a file -exists. Only if it cannot be found there are the directories in the -specific search path, followed by those in the general search path, -consulted. -.LP -A search path is also used when expanding wildcard characters. If the -pattern has a recognizable suffix on it, the path for that suffix will -be used for the expansion. Otherwise the default search path is employed. -.LP -When a file is found in some directory other than the current one, all -local variables that would have contained the target's name -.CW .ALLSRC , ( -and -.CW .IMPSRC ) -will instead contain the path to the file, as found by PMake. -Thus if you have a file -.CW ../lib/mumble.c -and a makefile -.DS -\&.PATH.c : ../lib -mumble : mumble.c - $(CC) -o $(.TARGET) $(.ALLSRC) -.DE -the command executed to create -.CW mumble -would be -.CW "cc -o mumble ../lib/mumble.c" .'' `` -(As an aside, the command in this case isn't strictly necessary, since -it will be found using transformation rules if it isn't given. This is because -.CW .out -is the null suffix by default and a transformation exists from -.CW .c -to -.CW .out . -Just thought I'd throw that in.) -.LP -If a file exists in two directories on the same search path, the file -in the first directory on the path will be the one PMake uses. So if -you have a large system spread over many directories, it would behoove -you to follow a naming convention that avoids such conflicts. -.LP -Something you should know about the way search paths are implemented -is that each directory is read, and its contents cached, exactly once -\&\*- when it is first encountered \*- so any changes to the -directories while PMake is running will not be noted when searching -for implicit sources, nor will they be found when PMake attempts to -discover when the file was last modified, unless the file was created in the -current directory. While people have suggested that PMake should read -the directories each time, my experience suggests that the caching seldom -causes problems. In addition, not caching the directories slows things -down enormously because of PMake's attempts to apply transformation -rules through non-existent files \*- the number of extra file-system -searches is truly staggering, especially if many files without -suffixes are used and the null suffix isn't changed from -.CW .out . -.xH 2 Archives and Libraries -.LP -.UX -and Sprite allow you to merge files into an archive using the -.CW ar -command. Further, if the files are relocatable object files, you can -run -.CW ranlib -on the archive and get yourself a library that you can link into any -program you want. The main problem with archives is they double the -space you need to store the archived files, since there's one copy in -the archive and one copy out by itself. The problem with libraries is -you usually think of them as -.CW -lm -rather than -.CW /usr/lib/libm.a -and the linker thinks they're out-of-date if you so much as look at -them. -.LP -PMake solves the problem with archives by allowing you to tell it to -examine the files in the archives (so you can remove the individual -files without having to regenerate them later). To handle the problem -with libraries, PMake adds an additional way of deciding if a library -is out-of-date: -.IP \(bu 2 -If the table of contents is older than the library, or is missing, the -library is out-of-date. -.LP -A library is any target that looks like -.CW \-l name'' `` -or that ends in a suffix that was marked as a library using the -.CW .LIBS -target. -.CW .a -is so marked in the system makefile. -.LP -Members of an archive are specified as -``\fIarchive\fP(\fImember\fP[ \fImember\fP...])''. -Thus -.CW libdix.a(window.o) '' ``' -specifies the file -.CW window.o -in the archive -.CW libdix.a . -You may also use wildcards to specify the members of the archive. Just -remember that most the wildcard characters will only find -.I existing -files. -.LP -A file that is a member of an archive is treated specially. If the -file doesn't exist, but it is in the archive, the modification time -recorded in the archive is used for the file when determining if the -file is out-of-date. When figuring out how to make an archived member target -(not the file itself, but the file in the archive \*- the -\fIarchive\fP(\fImember\fP) target), special care is -taken with the transformation rules, as follows: -.IP \(bu 2 -\&\fIarchive\fP(\fImember\fP) is made to depend on \fImember\fP. -.IP \(bu 2 -The transformation from the \fImember\fP's suffix to the -\fIarchive\fP's suffix is applied to the \fIarchive\fP(\fImember\fP) target. -.IP \(bu 2 -The \fIarchive\fP(\fImember\fP)'s -.CW .TARGET -variable is set to the name of the \fImember\fP if \fImember\fP is -actually a target, or the path to the member file if \fImember\fP is -only a source. -.IP \(bu 2 -The -.CW .ARCHIVE -variable for the \fIarchive\fP(\fImember\fP) target is set to the name -of the \fIarchive\fP. -.Ix 0 def variable local .ARCHIVE -.Ix 0 def .ARCHIVE -.IP \(bu 2 -The -.CW .MEMBER -variable is set to the actual string inside the parentheses. In most -cases, this will be the same as the -.CW .TARGET -variable. -.Ix 0 def variable local .MEMBER -.Ix 0 def .MEMBER -.IP \(bu 2 -The \fIarchive\fP(\fImember\fP)'s place in the local variables of the -targets that depend on it is taken by the value of its -.CW .TARGET -variable. -.LP -Thus, a program library could be created with the following makefile: -.DS -\&.o.a : - ... - rm -f $(.TARGET:T) -OBJS = obj1.o obj2.o obj3.o -libprog.a : libprog.a($(OBJS)) - ar cru $(.TARGET) $(.OODATE) - ranlib $(.TARGET) -.DE -This will cause the three object files to be compiled (if the -corresponding source files were modified after the object file or, if -that doesn't exist, the archived object file), the out-of-date ones -archived in -.CW libprog.a , -a table of contents placed in the archive and the newly-archived -object files to be removed. -.LP -All this is used in the -.CW makelib.mk -system makefile to create a single library with ease. This makefile -looks like this: -.DS -.SM -# -# Rules for making libraries. The object files that make up the library are -# removed once they are archived. -# -# To make several libararies in parallel, you should define the variable -# "many_libraries". This will serialize the invocations of ranlib. -# -# To use, do something like this: -# -# OBJECTS = -# -# fish.a: fish.a($(OBJECTS)) MAKELIB -# -# - -#ifndef _MAKELIB_MK -_MAKELIB_MK = - -#include - -\&.po.a .o.a : - ... - rm -f $(.MEMBER) - -ARFLAGS ?= crl - -# -# Re-archive the out-of-date members and recreate the library's table of -# contents using ranlib. If many_libraries is defined, put the ranlib off -# til the end so many libraries can be made at once. -# -MAKELIB : .USE .PRECIOUS - ar $(ARFLAGS) $(.TARGET) $(.OODATE) -#ifndef no_ranlib -# ifdef many_libraries - ... -# endif many_libraries - ranlib $(.TARGET) -#endif no_ranlib - -#endif _MAKELIB_MK -.DE -.xH 2 On the Condition... -.Rd 1 -.LP -Like the C compiler before it, PMake allows you to configure the makefile, -based on the current environment, using conditional statements. A -conditional looks like this: -.DS -#if \fIboolean expression\fP -\fIlines\fP -#elif \fIanother boolean expression\fP -\fImore lines\fP -#else -\fIstill more lines\fP -#endif -.DE -They may be nested to a maximum depth of 30 and may occur anywhere -(except in a comment, of course). The -.CW # '' `` -must the very first character on the line. -.LP -Each -.I "boolean expression" -is made up of terms that look like function calls, the standard C -boolean operators -.CW && , -.CW || , -and -.CW ! , -and the standard relational operators -.CW == , -.CW != , -.CW > , -.CW >= , -.CW < , -and -.CW <= , -with -.CW == -and -.CW != -being overloaded to allow string comparisons as well. -.CW && -represents logical AND; -.CW || -is logical OR and -.CW ! -is logical NOT. The arithmetic and string operators take precedence -over all three of these operators, while NOT takes precedence over -AND, which takes precedence over OR. This precedence may be -overridden with parentheses, and an expression may be parenthesized to -your heart's content. Each term looks like a call on one of four -functions: -.nr pw 9 -.Ix 0 def make -.Ix 0 def conditional make -.Ix 0 def if make -.IP make \n(pw -The syntax is -.CW make( \fItarget\fP\c -.CW ) -where -.I target -is a target in the makefile. This is true if the given target was -specified on the command line, or as the source for a -.CW .MAIN -target (note that the sources for -.CW .MAIN -are only used if no targets were given on the command line). -.IP defined \n(pw -.Ix 0 def defined -.Ix 0 def conditional defined -.Ix 0 def if defined -The syntax is -.CW defined( \fIvariable\fP\c -.CW ) -and is true if -.I variable -is defined. Certain variables are defined in the system makefile that -identify the system on which PMake is being run. -.IP exists \n(pw -.Ix 0 def exists -.Ix 0 def conditional exists -.Ix 0 def if exists -The syntax is -.CW exists( \fIfile\fP\c -.CW ) -and is true if the file can be found on the global search path (i.e. -that defined by -.CW .PATH -targets, not by -.CW .PATH \fIsuffix\fP -targets). -.IP empty \n(pw -.Ix 0 def empty -.Ix 0 def conditional empty -.Ix 0 def if empty -This syntax is much like the others, except the string inside the -parentheses is of the same form as you would put between parentheses -when expanding a variable, complete with modifiers and everything. The -function returns true if the resulting string is empty (NOTE: an undefined -variable in this context will cause at the very least a warning -message about a malformed conditional, and at the worst will cause the -process to stop once it has read the makefile. If you want to check -for a variable being defined or empty, use the expression -.CW !defined( \fIvar\fP\c `` -.CW ") || empty(" \fIvar\fP\c -.CW ) '' -as the definition of -.CW || -will prevent the -.CW empty() -from being evaluated and causing an error, if the variable is -undefined). This can be used to see if a variable contains a given -word, for example: -.DS -#if !empty(\fIvar\fP:M\fIword\fP) -.DE -.LP -The arithmetic and string operators may only be used to test the value -of a variable. The lefthand side must contain the variable expansion, -while the righthand side contains either a string, enclosed in -double-quotes, or a number. The standard C numeric conventions (except -for specifying an octal number) apply to both sides. E.g. -.DS -#if $(OS) == 4.3 - -#if $(MACHINE) == "sun3" - -#if $(LOAD_ADDR) < 0xc000 -.DE -are all valid conditionals. In addition, the numeric value of a -variable can be tested as a boolean as follows: -.DS -#if $(LOAD) -.DE -would see if -.CW LOAD -contains a non-zero value and -.DS -#if !$(LOAD) -.DE -would test if -.CW LOAD -contains a zero value. -.LP -In addition to the bare -.CW #if ,'' `` -there are other forms that apply one of the first two functions to each -term. They are as follows: -.DS - ifdef \fRdefined\fP - ifndef \fR!defined\fP - ifmake \fRmake\fP - ifnmake \fR!make\fP -.DE -There are also the ``else if'' forms: -.CW elif , -.CW elifdef , -.CW elifndef , -.CW elifmake , -and -.CW elifnmake . -.LP -For instance, if you wish to create two versions of a program, one of which -is optimized (the production version) and the other of which is for debugging -(has symbols for dbx), you have two choices: you can create two -makefiles, one of which uses the -.CW \-g -flag for the compilation, while the other uses the -.CW \-O -flag, or you can use another target (call it -.CW debug ) -to create the debug version. The construct below will take care of -this for you. I have also made it so defining the variable -.CW DEBUG -(say with -.CW "pmake -D DEBUG" ) -will also cause the debug version to be made. -.DS -#if defined(DEBUG) || make(debug) -CFLAGS += -g -#else -CFLAGS += -O -#endif -.DE -There are, of course, problems with this approach. The most glaring -annoyance is that if you want to go from making a debug version to -making a production version, you have to remove all the object files, -or you will get some optimized and some debug versions in the same -program. Another annoyance is you have to be careful not to make two -targets that ``conflict'' because of some conditionals in the -makefile. For instance -.DS -#if make(print) -FORMATTER = ditroff -Plaser_printer -#endif -#if make(draft) -FORMATTER = nroff -Pdot_matrix_printer -#endif -.DE -would wreak havok if you tried -.CW "pmake draft print" '' `` -since you would use the same formatter for each target. As I said, -this all gets somewhat complicated. -.xH 2 A Shell is a Shell is a Shell -.Rd 7 -.LP -In normal operation, the Bourne Shell (better known as -.CW sh '') `` -is used to execute the commands to re-create targets. PMake also allows you -to specify a different shell for it to use when executing these -commands. There are several things PMake must know about the shell you -wish to use. These things are specified as the sources for the -.CW .SHELL -.Ix 0 ref .SHELL -.Ix 0 ref target .SHELL -target by keyword, as follows: -.IP "\fBpath=\fP\fIpath\fP" -PMake needs to know where the shell actually resides, so it can -execute it. If you specify this and nothing else, PMake will use the -last component of the path and look in its table of the shells it -knows and use the specification it finds, if any. Use this if you just -want to use a different version of the Bourne or C Shell (yes, PMake knows -how to use the C Shell too). -.IP "\fBname=\fP\fIname\fP" -This is the name by which the shell is to be known. It is a single -word and, if no other keywords are specified (other than -.B path ), -it is the name by which PMake attempts to find a specification for -it (as mentioned above). You can use this if you would just rather use -the C Shell than the Bourne Shell -.CW ".SHELL: name=csh" '' (`` -will do it). -.IP "\fBquiet=\fP\fIecho-off command\fP" -As mentioned before, PMake actually controls whether commands are -printed by introducing commands into the shell's input stream. This -keyword, and the next two, control what those commands are. The -.B quiet -keyword is the command used to turn echoing off. Once it is turned -off, echoing is expected to remain off until the echo-on command is given. -.IP "\fBecho=\fP\fIecho-on command\fP" -The command PMake should give to turn echoing back on again. -.IP "\fBfilter=\fP\fIprinted echo-off command\fP" -Many shells will echo the echo-off command when it is given. This -keyword tells PMake in what format the shell actually prints the -echo-off command. Wherever PMake sees this string in the shell's -output, it will delete it and any following whitespace, up to and -including the next newline. See the example at the end of this section -for more details. -.IP "\fBechoFlag=\fP\fIflag to turn echoing on\fP" -Unless a target has been marked -.CW .SILENT , -PMake wants to start the shell running with echoing on. To do this, it -passes this flag to the shell as one of its arguments. If either this -or the next flag begins with a `\-', the flags will be passed to the -shell as separate arguments. Otherwise, the two will be concatenated -(if they are used at the same time, of course). -.IP "\fBerrFlag=\fP\fIflag to turn error checking on\fP" -Likewise, unless a target is marked -.CW .IGNORE , -PMake wishes error-checking to be on from the very start. To this end, -it will pass this flag to the shell as an argument. The same rules for -an initial `\-' apply as for the -.B echoFlag . -.IP "\fBcheck=\fP\fIcommand to turn error checking on\fP" -Just as for echo-control, error-control is achieved by inserting -commands into the shell's input stream. This is the command to make -the shell check for errors. It also serves another purpose if the -shell doesn't have error-control as commands, but I'll get into that -in a minute. Again, once error checking has been turned on, it is -expected to remain on until it is turned off again. -.IP "\fBignore=\fP\fIcommand to turn error checking off\fP" -This is the command PMake uses to turn error checking off. It has -another use if the shell doesn't do error-control, but I'll tell you -about that.\|.\|.\|now. -.IP "\fBhasErrCtl=\fP\fIyes or no\fP" -This takes a value that is either -.B yes -or -.B no . -Now you might think that the existence of the -.B check -and -.B ignore -keywords would be enough to tell PMake if the shell can do -error-control, but you'd be wrong. If -.B hasErrCtl -is -.B yes , -PMake uses the check and ignore commands in a straight-forward manner. -If this is -.B no , -however, their use is rather different. In this case, the check -command is used as a template, in which the string -.B %s -is replaced by the command that's about to be executed, to produce a -command for the shell that will echo the command to be executed. The -ignore command is also used as a template, again with -.B %s -replaced by the command to be executed, to produce a command that will -execute the command to be executed and ignore any error it returns. -When these strings are used as templates, you must provide newline(s) -.CW \en '') (`` -in the appropriate place(s). -.LP -The strings that follow these keywords may be enclosed in single or -double quotes (the quotes will be stripped off) and may contain the -usual C backslash-characters (\en is newline, \er is return, \eb is -backspace, \e' escapes a single-quote inside single-quotes, \e" -escapes a double-quote inside double-quotes). Now for an example. -.LP -This is actually the contents of the -.CW -system makefile, and causes PMake to use the Bourne Shell in such a -way that each command is printed as it is executed. That is, if more -than one command is given on a line, each will be printed separately. -Similarly, each time the body of a loop is executed, the commands -within that loop will be printed, etc. The specification runs like -this: -.DS -# -# This is a shell specification to have the bourne shell echo -# the commands just before executing them, rather than when it reads -# them. Useful if you want to see how variables are being expanded, etc. -# -\&.SHELL : path=/bin/sh \e - quiet="set -" \e - echo="set -x" \e - filter="+ set - " \e - echoFlag=x \e - errFlag=e \e - hasErrCtl=yes \e - check="set -e" \e - ignore="set +e" -.DE -.LP -It tells PMake the following: -.Bp -The shell is located in the file -.CW /bin/sh . -It need not tell PMake that the name of the shell is -.CW sh -as PMake can figure that out for itself (it's the last component of -the path). -.Bp -The command to stop echoing is -.CW "set -" . -.Bp -The command to start echoing is -.CW "set -x" . -.Bp -When the echo off command is executed, the shell will print -.CW "+ set - " -(The `+' comes from using the -.CW \-x -flag (rather than the -.CW \-v -flag PMake usually uses)). PMake will remove all occurrences of this -string from the output, so you don't notice extra commands you didn't -put there. -.Bp -The flag the Bourne Shell will take to start echoing in this way is -the -.CW \-x -flag. The Bourne Shell will only take its flag arguments concatenated -as its first argument, so neither this nor the -.B errFlag -specification begins with a \-. -.Bp -The flag to use to turn error-checking on from the start is -.CW \-e . -.Bp -The shell can turn error-checking on and off, and the commands to do -so are -.CW "set +e" -and -.CW "set -e" , -respectively. -.LP -I should note that this specification is for Bourne Shells that are -not part of Berkeley -.UX , -as shells from Berkeley don't do error control. You can get a similar -effect, however, by changing the last three lines to be: -.DS - hasErrCtl=no \e - check="echo \e"+ %s\e"\en" \e - ignore="sh -c '%s || exit 0\en" -.DE -.LP -This will cause PMake to execute the two commands -.DS -echo "+ \fIcmd\fP" -sh -c '\fIcmd\fP || true' -.DE -for each command for which errors are to be ignored. (In case you are -wondering, the thing for -.CW ignore -tells the shell to execute another shell without error checking on and -always exit 0, since the -.B || -causes the -.CW "exit 0" -to be executed only if the first command exited non-zero, and if the -first command exited zero, the shell will also exit zero, since that's -the last command it executed). -.xH 2 Compatibility -.Ix 0 ref compatibility -.LP -There are three (well, 3 \(12) levels of backwards-compatibility built -into PMake. Most makefiles will need none at all. Some may need a -little bit of work to operate correctly when run in parallel. Each -level encompasses the previous levels (e.g. -.B \-B -(one shell per command) implies -.B \-V ) -The three levels are described in the following three sections. -.xH 3 DEFCON 3 \*- Variable Expansion -.Ix 0 ref compatibility -.LP -As noted before, PMake will not expand a variable unless it knows of a -value for it. This can cause problems for makefiles that expect to -leave variables undefined except in special circumstances (e.g. if -more flags need to be passed to the C compiler or the output from a -text processor should be sent to a different printer). If the -variables are enclosed in curly braces -.CW ${PRINTER} ''), (`` -the shell will let them pass. If they are enclosed in parentheses, -however, the shell will declare a syntax error and the make will come -to a grinding halt. -.LP -You have two choices: change the makefile to define the variables -(their values can be overridden on the command line, since that's -where they would have been set if you used Make, anyway) or always give the -.B \-V -flag (this can be done with the -.CW .MAKEFLAGS -target, if you want). -.xH 3 DEFCON 2 \*- The Number of the Beast -.Ix 0 ref compatibility -.LP -Then there are the makefiles that expect certain commands, such as -changing to a different directory, to not affect other commands in a -target's creation script. You can solve this is either by going -back to executing one shell per command (which is what the -.B \-B -flag forces PMake to do), which slows the process down a good bit and -requires you to use semicolons and escaped newlines for shell constructs, or -by changing the makefile to execute the offending command(s) in a subshell -(by placing the line inside parentheses), like so: -.DS -install :: .MAKE - (cd src; $(.PMAKE) install) - (cd lib; $(.PMAKE) install) - (cd man; $(.PMAKE) install) -.DE -.Ix 0 ref operator double-colon -.Ix 0 ref variable global .PMAKE -.Ix 0 ref .PMAKE -.Ix 0 ref .MAKE -.Ix 0 ref attribute .MAKE -This will always execute the three makes (even if the -.B \-n -flag was given) because of the combination of the ``::'' operator and -the -.CW .MAKE -attribute. Each command will change to the proper directory to perform -the install, leaving the main shell in the directory in which it started. -.xH 3 "DEFCON 1 \*- Imitation is the Not the Highest Form of Flattery" -.Ix 0 ref compatibility -.LP -The final category of makefile is the one where every command requires -input, the dependencies are incompletely specified, or you simply -cannot create more than one target at a time, as mentioned earlier. In -addition, you may not have the time or desire to upgrade the makefile -to run smoothly with PMake. If you are the conservative sort, this is -the compatibility mode for you. It is entered either by giving PMake -the -.B \-M -flag (for Make), or by executing PMake as -.CW make .'' `` -In either case, PMake performs things exactly like Make (while still -supporting most of the nice new features PMake provides). This -includes: -.IP \(bu 2 -No parallel execution. -.IP \(bu 2 -Targets are made in the exact order specified by the makefile. The -sources for each target are made in strict left-to-right order, etc. -.IP \(bu 2 -A single Bourne shell is used to execute each command, thus the -shell's -.CW $$ -variable is useless, changing directories doesn't work across command -lines, etc. -.IP \(bu 2 -If no special characters exist in a command line, PMake will break the -command into words itself and execute the command directly, without -executing a shell first. The characters that cause PMake to execute a -shell are: -.CW # , -.CW = , -.CW | , -.CW ^ , -.CW ( , -.CW ) , -.CW { , -.CW } , -.CW ; , -.CW & , -.CW < , -.CW > , -.CW * , -.CW ? , -.CW [ , -.CW ] , -.CW : , -.CW $ , -.CW ` , -and -.CW \e . -You should notice that these are all the characters that are given -special meaning by the shell (except -.CW ' -and -.CW " , -which PMake deals with all by its lonesome). -.IP \(bu 2 -The use of the null suffix is turned off. -.Ix 0 ref "null suffix" -.Ix 0 ref suffix null -.xH 2 The Way Things Work -.LP -When PMake reads the makefile, it parses sources and targets into -nodes in a graph. The graph is directed only in the sense that PMake -knows which way is up. Each node contains not only links to all its -parents and children (the nodes that depend on it and those on which -it depends, respectively), but also a count of the number of its -children that have already been processed. -.LP -The most important thing to know about how PMake uses this graph is -that the traversal is breadth-first and occurs in two passes. -.LP -After PMake has parsed the makefile, it begins with the nodes the user -has told it to make (either on the command line, or via a -.CW .MAIN -target, or by the target being the first in the file not labeled with -the -.CW .NOTMAIN -attribute) placed in a queue. It continues to take the node off the -front of the queue, mark it as something that needs to be made, pass -the node to -.CW Suff_FindDeps -(mentioned earlier) to find any implicit sources for the node, and -place all the node's children that have yet to be marked at the end of -the queue. If any of the children is a -.CW .USE -rule, its attributes are applied to the parent, then its commands are -appended to the parent's list of commands and its children are linked -to its parent. The parent's unmade children counter is then decremented -(since the -.CW .USE -node has been processed). You will note that this allows a -.CW .USE -node to have children that are -.CW .USE -nodes and the rules will be applied in sequence. -If the node has no children, it is placed at the end of -another queue to be examined in the second pass. This process -continues until the first queue is empty. -.LP -At this point, all the leaves of the graph are in the examination -queue. PMake removes the node at the head of the queue and sees if it -is out-of-date. If it is, it is passed to a function that will execute -the commands for the node asynchronously. When the commands have -completed, all the node's parents have their unmade children counter -decremented and, if the counter is then 0, they are placed on the -examination queue. Likewise, if the node is up-to-date. Only those -parents that were marked on the downward pass are processed in this -way. Thus PMake traverses the graph back up to the nodes the user -instructed it to create. When the examination queue is empty and no -shells are running to create a target, PMake is finished. -.LP -Once all targets have been processed, PMake executes the commands -attached to the -.CW .END -target, either explicitly or through the use of an ellipsis in a shell -script. If there were no errors during the entire process but there -are still some targets unmade (PMake keeps a running count of how many -targets are left to be made), there is a cycle in the graph. PMake does -a depth-first traversal of the graph to find all the targets that -weren't made and prints them out one by one. -.xH 1 Answers to Exercises -.IP (3.1) -This is something of a trick question, for which I apologize. The -trick comes from the UNIX definition of a suffix, which PMake doesn't -necessarily share. You will have noticed that all the suffixes used in -this tutorial (and in UNIX in general) begin with a period -.CW .ms , ( -.CW .c , -etc.). Now, PMake's idea of a suffix is more like English's: it's the -characters at the end of a word. With this in mind, one possible -.Ix 0 def suffix -solution to this problem goes as follows: -.DS I -\&.SUFFIXES : ec.exe .exe ec.obj .obj .asm -ec.objec.exe .obj.exe : - link -o $(.TARGET) $(.IMPSRC) -\&.asmec.obj : - asm -o $(.TARGET) -DDO_ERROR_CHECKING $(.IMPSRC) -\&.asm.obj : - asm -o $(.TARGET) $(.IMPSRC) -.DE -.IP (3.2) -The trick to this one lies in the ``:='' variable-assignment operator -and the ``:S'' variable-expansion modifier. -.Ix 0 ref variable assignment expanded -.Ix 0 ref variable expansion modified -.Ix 0 ref modifier substitute -.Ix 0 ref :S -.Ix 0 ref := -Basically what you want is to take the pointer variable, so to speak, -and transform it into an invocation of the variable at which it -points. You might try something like -.DS I -$(PTR:S/^/\e$(/:S/$/)) -.DE -which places -.CW $( '' `` -at the front of the variable name and -.CW ) '' `` -at the end, thus transforming -.CW VAR ,'' `` -for example, into -.CW $(VAR) ,'' `` -which is just what we want. Unfortunately (as you know if you've tried -it), since, as it says in the hint, PMake does no further substitution -on the result of a modified expansion, that's \fIall\fP you get. The -solution is to make use of ``:='' to place that string into yet -another variable, then invoke the other variable directly: -.DS I -*PTR := $(PTR:S/^/\e$(/:S/$/)/) -.DE -You can then use -.CW $(*PTR) '' `` -to your heart's content. -.de Gp -.XP -\&\fB\\$1:\fP -.. -.xH 1 Glossary of Jargon -.Gp "attribute" -A property given to a target that causes PMake to treat it differently. -.Gp "command script" -The lines immediately following a dependency line that specify -commands to execute to create each of the targets on the dependency -line. Each line in the command script must begin with a tab. -.Gp "command-line variable" -A variable defined in an argument when PMake is first executed. -Overrides all assignments to the same variable name in the makefile. -.Gp "conditional" -A construct much like that used in C that allows a makefile to be -configured on the fly based on the local environment, or on what is being -made by that invocation of PMake. -.Gp "creation script" -Commands used to create a target. See ``command script.'' -.Gp "dependency" -The relationship between a source and a target. This comes in three -flavors, as indicated by the operator between the target and the -source. `:' gives a straight time-wise dependency (if the target is -older than the source, the target is out-of-date), while `!' provides -simply an ordering and always considers the target out-of-date. `::' -is much like `:', save it creates multiple instances of a target each -of which depends on its own list of sources. -.Gp "dynamic source" -This refers to a source that has a local variable invocation in it. It -allows a single dependency line to specify a different source for each -target on the line. -.Gp "global variable" -Any variable defined in a makefile. Takes precedence over variables -defined in the environment, but not over command-line or local variables. -.Gp "input graph" -What PMake constructs from a makefile. Consists of nodes made of the -targets in the makefile, and the links between them (the -dependencies). The links are directed (from source to target) and -there may not be any cycles (loops) in the graph. -.Gp "local variable" -A variable defined by PMake visible only in a target's shell script. -There are seven local variables, not all of which are defined for -every target: -.CW .TARGET , -.CW .ALLSRC , -.CW .OODATE , -.CW .PREFIX , -.CW .IMPSRC , -.CW .ARCHIVE , -and -.CW .MEMBER . -.CW .TARGET , -.CW .PREFIX , -.CW .ARCHIVE , -and -.CW .MEMBER -may be used on dependency lines to create ``dynamic sources.'' -.Gp "makefile" -A file that describes how a system is built. If you don't know what it -is after reading this tutorial.\|.\|.\|. -.Gp "modifier" -A letter, following a colon, used to alter how a variable is expanded. -It has no effect on the variable itself. -.Gp "operator" -What separates a source from a target (on a dependency line) and specifies -the relationship between the two. There are three: -.CW : ', ` -.CW :: ', ` -and -.CW ! '. ` -.Gp "search path" -A list of directories in which a file should be sought. PMake's view -of the contents of directories in a search path does not change once -the makefile has been read. A file is sought on a search path only if -it is exclusively a source. -.Gp "shell" -A program to which commands are passed in order to create targets. -.Gp "source" -Anything to the right of an operator on a dependency line. Targets on -the dependency line are usually created from the sources. -.Gp "special target" -A target that causes PMake to do special things when it's encountered. -.Gp "suffix" -The tail end of a file name. Usually begins with a period, -.CW .c -or -.CW .ms , -e.g. -.Gp "target" -A word to the left of the operator on a dependency line. More -generally, any file that PMake might create. A file may be (and often -is) both a target and a source (what it is depends on how PMake is -looking at it at the time \*- sort of like the wave/particle duality -of light, you know). -.Gp "transformation rule" -A special construct in a makefile that specifies how to create a file -of one type from a file of another, as indicated by their suffixes. -.Gp "variable expansion" -The process of substituting the value of a variable for a reference to -it. Expansion may be altered by means of modifiers. -.Gp "variable" -A place in which to store text that may be retrieved later. Also used -to define the local environment. Conditionals exist that test whether -a variable is defined or not. -.bp -.\" Output table of contents last, with an entry for the index, making -.\" sure to save and restore the last real page number for the index... -.nr @n \n(PN+1 -.\" We are not generating an index -.\" .XS \n(@n -.\" Index -.\" .XE -.nr %% \n% -.PX -.nr % \n(%% diff --git a/bootstrap/bmake/README b/bootstrap/bmake/README deleted file mode 100644 index 005c3228e08..00000000000 --- a/bootstrap/bmake/README +++ /dev/null @@ -1,110 +0,0 @@ - bmake v3 - -This directory contains a port of the BSD make tool (from NetBSD) -I have run it on SunOS,Solaris,HP-UX 9 and IRIX. - -Version 3 is has been re-worked from scratch to better facilitate -importing newer make(1) versions from NetBSD. The original code base -was NetBSD-1.0, so version 3 was built by doing a fresh import of the -NetBSD-1.0 usr.bin/make, adding the autoconf and other portability -patches to sync it with bmake v2, and then NetBSD's make -of Feb 20, 2000 was imported and conflicts dealt with. -NetBSD's make was again imported on June 6 and December 15, 2000. - -Note: when cvs importing newer versions -it is important to (in usr.bin/make): - -mv config.h make-conf.h -mv Makefile Makefile.in - -before running cvs import. - -Building is simply a matter of: - -configure -make -f makefile.boot -make -f makefile.boot install -make -f makefile.boot install-man -make -f makefile.boot install-mk - -The install-mk target is only useful if you unpacked [bsd-]mk.tar.gz -under the bmake directory. - -if you have GNU make or a make which supports VPATH, you can build it -in a separate directory: - -here=`pwd` -mkdir /tmp/bmake -cd /tmp/bmake -$here/configure -gmake -f makefile.boot -gmake -f makefile.boot install -gmake -f makefile.boot install-man -gmake -f makefile.boot install-mk - -To make much use of bmake you will need the bsd.*.mk macros or my -portable *.mk macros. See -ftp://ftp.quick.com.au/pub/sjg/bsd-mk.tar.gz -ftp://ftp.quick.com.au/pub/sjg/mk.tar.gz - -If you have an earlier version of bmake installed you can use that -with the generated Makefile. - -Apart from new features such as .PARSEDIR picked up from the recent -NetBSD make, this version has improvments (which are also in NetBSD's -make or soon will be) to facilitate using MAKEOBJDIRPREFIX to support -true read-only src trees. See also ChangeLog. - -MAKEOBJDIRPREFIX: - -When MAKEOBJDIRPREFIX is set in the environment make(1) will attempt -to chdir(${MAKEOBJDIRPREFIX}${.CUDRIR}) and use that as its objdir. -Because the directory tree under ${MAKEOBJDIRPREFIX} is a mirror of -the src tree, make ends up chdir'ing to objdirs that would not exist -otherwise. That is, when using normal ./obj dirs (or symlinks) only -Makefiles which include obj.mk get a separate objdir. When using -MAKEOBJDIRPREFIX any directory which has subdirs that use obj.mk will -have an objdir, thus Makefiles which were written expecting to process -in ${.CURDIR} may break. In particular, Makefiles which do: - -build: - ${.MAKE} something - ${.MAKE} else - -will break as the sub-make will not find a Makefile in -${MAKEOBJDIRPREFIX}${.CUDRIR}. Whereas - -build: - cd ${.CURDIR} && ${.MAKE} something - cd ${.CURDIR} && ${.MAKE} else - -will work fine. To avoid the need to re-work these Makefiles we -check for running ${.MAKE} or ${.MAKE:T} without a preceeding cd and -effectively insert one. This feature only operates if -MAKEOBJDIRPREFIX (or MAKEOBJDIR) is set and can be dissabled by -defining NOCHECKMAKECHDIR. - -Another problem arrises from make(1) overriding the physical location -returned by getcwd() with the logical one from $PWD. We dissable this -feature if MAKEOBJDIRPREFIX is set to avoid the situation where -make(1) behaves differently depending on how it got to a directory. -This avoids lossage like the following example. - -If /usr/local/src is a symlink to /d3/src: - -cd /usr/local/src/project -MAKEOBJDIRPREFIX=/tmp/obj make obj -===> sub1 -/d3/src/project/sub1 -> /tmp/obj/d3/src/project/sub1 -... - -cd /usr/local/src/project/sub1 -MAKEOBJDIRPREFIX=/tmp/obj make obj -/usr/local/src/project/sub1 -> /tmp/obj/usr/local/src/project/sub1 - -the expected objdir changes depending on circumstances - which -means that 9 times out of 10 you'll end up trying to polute -curdir because the objdir you expected does not exist. - - ---sjg diff --git a/bootstrap/bmake/aclocal.m4 b/bootstrap/bmake/aclocal.m4 deleted file mode 100644 index 7350a5501a3..00000000000 --- a/bootstrap/bmake/aclocal.m4 +++ /dev/null @@ -1,77 +0,0 @@ -dnl RCSid: -dnl $Id: aclocal.m4,v 1.1.1.1 2004/03/11 13:04:00 grant Exp $ -dnl - -dnl -dnl AC_CHECK_HEADER_HAS(HEADER, PATTERN, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])) - -AC_DEFUN(AC_CHECK_HEADER_HAS, -[dnl first check if header exists and if so, see if it contains PATTERN -ac_has_hdr=`echo "ac_cv_header_$1" | sed 'y%./+-%__p_%'` -ac_has_it=`echo "ac_cv_header_$1"_$2 | sed 'y%./+-%__p_%'` -if eval "test \"`echo x'$'$ac_has_hdr`\" = x"; then - AC_CHECK_HEADER($1) -fi -if eval "test \"`echo '$'$ac_has_hdr`\" = yes"; then - ac_x=HAVE_`echo "$1" | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - AC_DEFINE_UNQUOTED($ac_x) - AC_MSG_CHECKING([if $1 has $2]) - AC_CACHE_VAL($ac_has_it, - [eval $ac_has_it=no - AC_EGREP_HEADER($2, $1, eval "$ac_has_it=yes")]) - - if eval "test \"`echo '$'$ac_has_it`\" = yes"; then - AC_MSG_RESULT(yes) - ac_x=HAVE_`echo "$1"_$2 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - AC_DEFINE_UNQUOTED($ac_x) - ifelse([$3], , :, [$3]) - else - AC_MSG_RESULT(no) - ifelse([$4], , , [$4 -])dnl - fi -fi -]) - -dnl AC_EGREP(PATTERN, FILE, ACTION-IF-FOUND [, -dnl ACTION-IF-NOT-FOUND]) -AC_DEFUN(AC_EGREP, -[ -dnl Prevent m4 from eating character classes: -changequote(, )dnl -if egrep "$1" $2 >/dev/null 2>&1; then -changequote([, ])dnl - ifelse([$3], , :, [$3]) -ifelse([$4], , , [else - $4 -])dnl -fi -]) - -dnl -dnl Test for __attribute__ -dnl - -AC_DEFUN(AC_C___ATTRIBUTE__, [ -AC_MSG_CHECKING(for __attribute__) -AC_CACHE_VAL(ac_cv___attribute__, [ -AC_TRY_COMPILE([ -#include -], -[ -static void foo(void) __attribute__ ((noreturn)); - -static void -foo(void) -{ - exit(1); -} -], -ac_cv___attribute__=yes, -ac_cv___attribute__=no)]) -if test "$ac_cv___attribute__" = "yes"; then - AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__]) -fi -AC_MSG_RESULT($ac_cv___attribute__) -]) - diff --git a/bootstrap/bmake/arch.c b/bootstrap/bmake/arch.c deleted file mode 100644 index c2f840b2bc1..00000000000 --- a/bootstrap/bmake/arch.c +++ /dev/null @@ -1,1344 +0,0 @@ -/* $NetBSD: arch.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $ */ - -/* - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: arch.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)arch.c 8.2 (Berkeley) 1/2/94"; -#else -__RCSID("$NetBSD: arch.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: arch.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $"); -#endif - -/*- - * arch.c -- - * Functions to manipulate libraries, archives and their members. - * - * Once again, cacheing/hashing comes into play in the manipulation - * of archives. The first time an archive is referenced, all of its members' - * headers are read and hashed and the archive closed again. All hashed - * archives are kept on a list which is searched each time an archive member - * is referenced. - * - * The interface to this module is: - * Arch_ParseArchive Given an archive specification, return a list - * of GNode's, one for each member in the spec. - * FAILURE is returned if the specification is - * invalid for some reason. - * - * Arch_Touch Alter the modification time of the archive - * member described by the given node to be - * the current time. - * - * Arch_TouchLib Update the modification time of the library - * described by the given node. This is special - * because it also updates the modification time - * of the library's table of contents. - * - * Arch_MTime Find the modification time of a member of - * an archive *in the archive*. The time is also - * placed in the member's GNode. Returns the - * modification time. - * - * Arch_MemTime Find the modification time of a member of - * an archive. Called when the member doesn't - * already exist. Looks in the archive for the - * modification time. Returns the modification - * time. - * - * Arch_FindLib Search for a library along a path. The - * library name in the GNode should be in - * -l format. - * - * Arch_LibOODate Special function to decide if a library node - * is out-of-date. - * - * Arch_Init Initialize this module. - * - * Arch_End Cleanup this module. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include -#include -#include -#include -#include -#ifdef HAVE_AR_H -#include -#endif -#ifdef HAVE_RANLIB_H -#include -#endif -#ifdef HAVE_UTIME_H -#include -#endif -#include -#include -#include -#include "make.h" -#include "hash.h" -#include "dir.h" - -#ifdef TARGET_MACHINE -#undef MACHINE -#define MACHINE TARGET_MACHINE -#endif -#ifdef TARGET_MACHINE_ARCH -#undef MACHINE_ARCH -#define MACHINE_ARCH TARGET_MACHINE_ARCH -#endif - -static Lst archives; /* Lst of archives we've already examined */ - -typedef struct Arch { - char *name; /* Name of archive */ - Hash_Table members; /* All the members of the archive described - * by key/value pairs */ - char *fnametab; /* Extended name table strings */ - size_t fnamesize; /* Size of the string table */ -} Arch; - -static int ArchFindArchive __P((ClientData, ClientData)); -#ifdef CLEANUP -static void ArchFree __P((ClientData)); -#endif -static struct ar_hdr *ArchStatMember __P((char *, char *, Boolean)); -static FILE *ArchFindMember __P((char *, char *, struct ar_hdr *, char *)); -#if defined(__svr4__) || defined(__SVR4) || defined(__ELF__) -#define SVR4ARCHIVES -static int ArchSVR4Entry __P((Arch *, char *, size_t, FILE *)); -#endif - - -#if defined(_AIX) -# define AR_NAME _ar_name.ar_name -# define AR_FMAG _ar_name.ar_fmag -# define SARMAG SAIAMAG -# define ARMAG AIAMAG -# define ARFMAG AIAFMAG -#endif -#ifndef AR_NAME -# define AR_NAME ar_name -#endif -#ifndef AR_DATE -# define AR_DATE ar_date -#endif -#ifndef AR_SIZE -# define AR_SIZE ar_size -#endif -#ifndef AR_FMAG -# define AR_FMAG ar_fmag -#endif - -#define AR_MAX_NAME_LEN (sizeof(arh.AR_NAME)-1) - -#ifdef CLEANUP -/*- - *----------------------------------------------------------------------- - * ArchFree -- - * Free memory used by an archive - * - * Results: - * None. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static void -ArchFree(ap) - ClientData ap; -{ - Arch *a = (Arch *) ap; - Hash_Search search; - Hash_Entry *entry; - - /* Free memory from hash entries */ - for (entry = Hash_EnumFirst(&a->members, &search); - entry != (Hash_Entry *)NULL; - entry = Hash_EnumNext(&search)) - free((Address) Hash_GetValue (entry)); - - free(a->name); - if (a->fnametab) - free(a->fnametab); - Hash_DeleteTable(&a->members); - free((Address) a); -} -#endif - - -/*- - *----------------------------------------------------------------------- - * Arch_ParseArchive -- - * Parse the archive specification in the given line and find/create - * the nodes for the specified archive members, placing their nodes - * on the given list. - * - * Results: - * SUCCESS if it was a valid specification. The linePtr is updated - * to point to the first non-space after the archive spec. The - * nodes for the members are placed on the given list. - * - * Side Effects: - * Some nodes may be created. The given list is extended. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Arch_ParseArchive (linePtr, nodeLst, ctxt) - char **linePtr; /* Pointer to start of specification */ - Lst nodeLst; /* Lst on which to place the nodes */ - GNode *ctxt; /* Context in which to expand variables */ -{ - register char *cp; /* Pointer into line */ - GNode *gn; /* New node */ - char *libName; /* Library-part of specification */ - char *memName; /* Member-part of specification */ - char *nameBuf; /* temporary place for node name */ - char saveChar; /* Ending delimiter of member-name */ - Boolean subLibName; /* TRUE if libName should have/had - * variable substitution performed on it */ - - libName = *linePtr; - - subLibName = FALSE; - - for (cp = libName; *cp != '(' && *cp != '\0'; cp++) { - if (*cp == '$') { - /* - * Variable spec, so call the Var module to parse the puppy - * so we can safely advance beyond it... - */ - int length; - Boolean freeIt; - char *result; - - result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt); - if (result == var_Error) { - return(FAILURE); - } else { - subLibName = TRUE; - } - - if (freeIt) { - free(result); - } - cp += length-1; - } - } - - *cp++ = '\0'; - if (subLibName) { - libName = Var_Subst(NULL, libName, ctxt, TRUE); - } - - - for (;;) { - /* - * First skip to the start of the member's name, mark that - * place and skip to the end of it (either white-space or - * a close paren). - */ - Boolean doSubst = FALSE; /* TRUE if need to substitute in memName */ - - while (*cp != '\0' && *cp != ')' && isspace ((unsigned char)*cp)) { - cp++; - } - memName = cp; - while (*cp != '\0' && *cp != ')' && !isspace ((unsigned char)*cp)) { - if (*cp == '$') { - /* - * Variable spec, so call the Var module to parse the puppy - * so we can safely advance beyond it... - */ - int length; - Boolean freeIt; - char *result; - - result=Var_Parse(cp, ctxt, TRUE, &length, &freeIt); - if (result == var_Error) { - return(FAILURE); - } else { - doSubst = TRUE; - } - - if (freeIt) { - free(result); - } - cp += length; - } else { - cp++; - } - } - - /* - * If the specification ends without a closing parenthesis, - * chances are there's something wrong (like a missing backslash), - * so it's better to return failure than allow such things to happen - */ - if (*cp == '\0') { - printf("No closing parenthesis in archive specification\n"); - return (FAILURE); - } - - /* - * If we didn't move anywhere, we must be done - */ - if (cp == memName) { - break; - } - - saveChar = *cp; - *cp = '\0'; - - /* - * XXX: This should be taken care of intelligently by - * SuffExpandChildren, both for the archive and the member portions. - */ - /* - * If member contains variables, try and substitute for them. - * This will slow down archive specs with dynamic sources, of course, - * since we'll be (non-)substituting them three times, but them's - * the breaks -- we need to do this since SuffExpandChildren calls - * us, otherwise we could assume the thing would be taken care of - * later. - */ - if (doSubst) { - char *buf; - char *sacrifice; - char *oldMemName = memName; - size_t sz; - - memName = Var_Subst(NULL, memName, ctxt, TRUE); - - /* - * Now form an archive spec and recurse to deal with nested - * variables and multi-word variable values.... The results - * are just placed at the end of the nodeLst we're returning. - */ - sz = strlen(memName)+strlen(libName)+3; - buf = sacrifice = emalloc(sz); - - snprintf(buf, sz, "%s(%s)", libName, memName); - - if (strchr(memName, '$') && strcmp(memName, oldMemName) == 0) { - /* - * Must contain dynamic sources, so we can't deal with it now. - * Just create an ARCHV node for the thing and let - * SuffExpandChildren handle it... - */ - gn = Targ_FindNode(buf, TARG_CREATE); - - if (gn == NILGNODE) { - free(buf); - return(FAILURE); - } else { - gn->type |= OP_ARCHV; - (void)Lst_AtEnd(nodeLst, (ClientData)gn); - } - } else if (Arch_ParseArchive(&sacrifice, nodeLst, ctxt)!=SUCCESS) { - /* - * Error in nested call -- free buffer and return FAILURE - * ourselves. - */ - free(buf); - return(FAILURE); - } - /* - * Free buffer and continue with our work. - */ - free(buf); - } else if (Dir_HasWildcards(memName)) { - Lst members = Lst_Init(FALSE); - char *member; - size_t sz = MAXPATHLEN, nsz; - nameBuf = emalloc(sz); - - Dir_Expand(memName, dirSearchPath, members); - while (!Lst_IsEmpty(members)) { - member = (char *)Lst_DeQueue(members); - nsz = strlen(libName) + strlen(member) + 3; - if (sz > nsz) - nameBuf = erealloc(nameBuf, sz = nsz * 2); - - snprintf(nameBuf, sz, "%s(%s)", libName, member); - free(member); - gn = Targ_FindNode (nameBuf, TARG_CREATE); - if (gn == NILGNODE) { - free(nameBuf); - return (FAILURE); - } else { - /* - * We've found the node, but have to make sure the rest of - * the world knows it's an archive member, without having - * to constantly check for parentheses, so we type the - * thing with the OP_ARCHV bit before we place it on the - * end of the provided list. - */ - gn->type |= OP_ARCHV; - (void) Lst_AtEnd (nodeLst, (ClientData)gn); - } - } - Lst_Destroy(members, NOFREE); - free(nameBuf); - } else { - size_t sz = strlen(libName) + strlen(memName) + 3; - nameBuf = emalloc(sz); - snprintf(nameBuf, sz, "%s(%s)", libName, memName); - gn = Targ_FindNode (nameBuf, TARG_CREATE); - free(nameBuf); - if (gn == NILGNODE) { - return (FAILURE); - } else { - /* - * We've found the node, but have to make sure the rest of the - * world knows it's an archive member, without having to - * constantly check for parentheses, so we type the thing with - * the OP_ARCHV bit before we place it on the end of the - * provided list. - */ - gn->type |= OP_ARCHV; - (void) Lst_AtEnd (nodeLst, (ClientData)gn); - } - } - if (doSubst) { - free(memName); - } - - *cp = saveChar; - } - - /* - * If substituted libName, free it now, since we need it no longer. - */ - if (subLibName) { - free(libName); - } - - /* - * We promised the pointer would be set up at the next non-space, so - * we must advance cp there before setting *linePtr... (note that on - * entrance to the loop, cp is guaranteed to point at a ')') - */ - do { - cp++; - } while (*cp != '\0' && isspace ((unsigned char)*cp)); - - *linePtr = cp; - return (SUCCESS); -} - -/*- - *----------------------------------------------------------------------- - * ArchFindArchive -- - * See if the given archive is the one we are looking for. Called - * From ArchStatMember and ArchFindMember via Lst_Find. - * - * Results: - * 0 if it is, non-zero if it isn't. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static int -ArchFindArchive (ar, archName) - ClientData ar; /* Current list element */ - ClientData archName; /* Name we want */ -{ - return (strcmp ((char *) archName, ((Arch *) ar)->name)); -} - -/*- - *----------------------------------------------------------------------- - * ArchStatMember -- - * Locate a member of an archive, given the path of the archive and - * the path of the desired member. - * - * Results: - * A pointer to the current struct ar_hdr structure for the member. Note - * That no position is returned, so this is not useful for touching - * archive members. This is mostly because we have no assurances that - * The archive will remain constant after we read all the headers, so - * there's not much point in remembering the position... - * - * Side Effects: - * - *----------------------------------------------------------------------- - */ -static struct ar_hdr * -ArchStatMember (archive, member, hash) - char *archive; /* Path to the archive */ - char *member; /* Name of member. If it is a path, only the - * last component is used. */ - Boolean hash; /* TRUE if archive should be hashed if not - * already so. */ -{ - FILE * arch; /* Stream to archive */ - int size; /* Size of archive member */ - char *cp; /* Useful character pointer */ - char magic[SARMAG]; - LstNode ln; /* Lst member containing archive descriptor */ - Arch *ar; /* Archive descriptor */ - Hash_Entry *he; /* Entry containing member's description */ - struct ar_hdr arh; /* archive-member header for reading archive */ - char memName[MAXPATHLEN+1]; - /* Current member name while hashing. */ - - /* - * Because of space constraints and similar things, files are archived - * using their final path components, not the entire thing, so we need - * to point 'member' to the final component, if there is one, to make - * the comparisons easier... - */ - cp = strrchr (member, '/'); - if (cp != (char *) NULL) { - member = cp + 1; - } - - ln = Lst_Find (archives, (ClientData) archive, ArchFindArchive); - if (ln != NILLNODE) { - ar = (Arch *) Lst_Datum (ln); - - he = Hash_FindEntry (&ar->members, member); - - if (he != (Hash_Entry *) NULL) { - return ((struct ar_hdr *) Hash_GetValue (he)); - } else { - /* Try truncated name */ - char copy[AR_MAX_NAME_LEN+1]; - int len = strlen (member); - - if (len > AR_MAX_NAME_LEN) { - len = AR_MAX_NAME_LEN; - strncpy(copy, member, AR_MAX_NAME_LEN); - copy[AR_MAX_NAME_LEN] = '\0'; - } - if ((he = Hash_FindEntry (&ar->members, copy)) != NULL) - return ((struct ar_hdr *) Hash_GetValue (he)); - return ((struct ar_hdr *) NULL); - } - } - - if (!hash) { - /* - * Caller doesn't want the thing hashed, just use ArchFindMember - * to read the header for the member out and close down the stream - * again. Since the archive is not to be hashed, we assume there's - * no need to allocate extra room for the header we're returning, - * so just declare it static. - */ - static struct ar_hdr sarh; - - arch = ArchFindMember(archive, member, &sarh, "r"); - - if (arch == (FILE *)NULL) { - return ((struct ar_hdr *)NULL); - } else { - fclose(arch); - return (&sarh); - } - } - - /* - * We don't have this archive on the list yet, so we want to find out - * everything that's in it and cache it so we can get at it quickly. - */ - arch = fopen (archive, "r"); - if (arch == (FILE *) NULL) { - return ((struct ar_hdr *) NULL); - } - - /* - * We use the ARMAG string to make sure this is an archive we - * can handle... - */ - if ((fread (magic, SARMAG, 1, arch) != 1) || - (strncmp (magic, ARMAG, SARMAG) != 0)) { - fclose (arch); - return ((struct ar_hdr *) NULL); - } - - ar = (Arch *)emalloc (sizeof (Arch)); - ar->name = estrdup (archive); - ar->fnametab = NULL; - ar->fnamesize = 0; - Hash_InitTable (&ar->members, -1); - memName[AR_MAX_NAME_LEN] = '\0'; - - while (fread ((char *)&arh, sizeof (struct ar_hdr), 1, arch) == 1) { - if (strncmp ( arh.AR_FMAG, ARFMAG, sizeof (arh.AR_FMAG)) != 0) { - /* - * The header is bogus, so the archive is bad - * and there's no way we can recover... - */ - goto badarch; - } else { - /* - * We need to advance the stream's pointer to the start of the - * next header. Files are padded with newlines to an even-byte - * boundary, so we need to extract the size of the file from the - * 'size' field of the header and round it up during the seek. - */ - arh.AR_SIZE[sizeof(arh.AR_SIZE)-1] = '\0'; - size = (int) strtol(arh.AR_SIZE, NULL, 10); - - (void) strncpy (memName, arh.AR_NAME, sizeof(arh.AR_NAME)); - for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) { - continue; - } - cp[1] = '\0'; - -#ifdef SVR4ARCHIVES - /* - * svr4 names are slash terminated. Also svr4 extended AR format. - */ - if (memName[0] == '/') { - /* - * svr4 magic mode; handle it - */ - switch (ArchSVR4Entry(ar, memName, size, arch)) { - case -1: /* Invalid data */ - goto badarch; - case 0: /* List of files entry */ - continue; - default: /* Got the entry */ - break; - } - } - else { - if (cp[0] == '/') - cp[0] = '\0'; - } -#endif - -#ifdef AR_EFMT1 - /* - * BSD 4.4 extended AR format: #1/, with name as the - * first bytes of the file - */ - if (strncmp(memName, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0 && - isdigit(memName[sizeof(AR_EFMT1) - 1])) { - - unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]); - - if (elen > MAXPATHLEN) - goto badarch; - if (fread (memName, elen, 1, arch) != 1) - goto badarch; - memName[elen] = '\0'; - fseek (arch, -elen, SEEK_CUR); - if (DEBUG(ARCH) || DEBUG(MAKE)) { - printf("ArchStat: Extended format entry for %s\n", memName); - } - } -#endif - - he = Hash_CreateEntry (&ar->members, memName, (Boolean *)NULL); - Hash_SetValue (he, (ClientData)emalloc (sizeof (struct ar_hdr))); - memcpy ((Address)Hash_GetValue (he), (Address)&arh, - sizeof (struct ar_hdr)); - } - fseek (arch, (size + 1) & ~1, SEEK_CUR); - } - - fclose (arch); - - (void) Lst_AtEnd (archives, (ClientData) ar); - - /* - * Now that the archive has been read and cached, we can look into - * the hash table to find the desired member's header. - */ - he = Hash_FindEntry (&ar->members, member); - - if (he != (Hash_Entry *) NULL) { - return ((struct ar_hdr *) Hash_GetValue (he)); - } else { - return ((struct ar_hdr *) NULL); - } - -badarch: - fclose (arch); - Hash_DeleteTable (&ar->members); - if (ar->fnametab) - free(ar->fnametab); - free ((Address)ar); - return ((struct ar_hdr *) NULL); -} - -#ifdef SVR4ARCHIVES -/*- - *----------------------------------------------------------------------- - * ArchSVR4Entry -- - * Parse an SVR4 style entry that begins with a slash. - * If it is "//", then load the table of filenames - * If it is "/", then try to substitute the long file name - * from offset of a table previously read. - * - * Results: - * -1: Bad data in archive - * 0: A table was loaded from the file - * 1: Name was successfully substituted from table - * 2: Name was not successfully substituted from table - * - * Side Effects: - * If a table is read, the file pointer is moved to the next archive - * member - * - *----------------------------------------------------------------------- - */ -static int -ArchSVR4Entry(ar, name, size, arch) - Arch *ar; - char *name; - size_t size; - FILE *arch; -{ -#define ARLONGNAMES1 "//" -#define ARLONGNAMES2 "/ARFILENAMES" - size_t entry; - char *ptr, *eptr; - - if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 || - strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) { - - if (ar->fnametab != NULL) { - if (DEBUG(ARCH)) { - printf("Attempted to redefine an SVR4 name table\n"); - } - return -1; - } - - /* - * This is a table of archive names, so we build one for - * ourselves - */ - ar->fnametab = emalloc(size); - ar->fnamesize = size; - - if (fread(ar->fnametab, size, 1, arch) != 1) { - if (DEBUG(ARCH)) { - printf("Reading an SVR4 name table failed\n"); - } - return -1; - } - eptr = ar->fnametab + size; - for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++) - switch (*ptr) { - case '/': - entry++; - *ptr = '\0'; - break; - - case '\n': - break; - - default: - break; - } - if (DEBUG(ARCH)) { - printf("Found svr4 archive name table with %lu entries\n", - (u_long)entry); - } - return 0; - } - - if (name[1] == ' ' || name[1] == '\0') - return 2; - - entry = (size_t) strtol(&name[1], &eptr, 0); - if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) { - if (DEBUG(ARCH)) { - printf("Could not parse SVR4 name %s\n", name); - } - return 2; - } - if (entry >= ar->fnamesize) { - if (DEBUG(ARCH)) { - printf("SVR4 entry offset %s is greater than %lu\n", - name, (u_long)ar->fnamesize); - } - return 2; - } - - if (DEBUG(ARCH)) { - printf("Replaced %s with %s\n", name, &ar->fnametab[entry]); - } - - (void) strncpy(name, &ar->fnametab[entry], MAXPATHLEN); - name[MAXPATHLEN] = '\0'; - return 1; -} -#endif - - -/*- - *----------------------------------------------------------------------- - * ArchFindMember -- - * Locate a member of an archive, given the path of the archive and - * the path of the desired member. If the archive is to be modified, - * the mode should be "r+", if not, it should be "r". - * - * Results: - * An FILE *, opened for reading and writing, positioned at the - * start of the member's struct ar_hdr, or NULL if the member was - * nonexistent. The current struct ar_hdr for member. - * - * Side Effects: - * The passed struct ar_hdr structure is filled in. - * - *----------------------------------------------------------------------- - */ -static FILE * -ArchFindMember (archive, member, arhPtr, mode) - char *archive; /* Path to the archive */ - char *member; /* Name of member. If it is a path, only the - * last component is used. */ - struct ar_hdr *arhPtr; /* Pointer to header structure to be filled in */ - char *mode; /* The mode for opening the stream */ -{ - FILE * arch; /* Stream to archive */ - int size; /* Size of archive member */ - char *cp; /* Useful character pointer */ - char magic[SARMAG]; - int len, tlen; - - arch = fopen (archive, mode); - if (arch == (FILE *) NULL) { - return ((FILE *) NULL); - } - - /* - * We use the ARMAG string to make sure this is an archive we - * can handle... - */ - if ((fread (magic, SARMAG, 1, arch) != 1) || - (strncmp (magic, ARMAG, SARMAG) != 0)) { - fclose (arch); - return ((FILE *) NULL); - } - - /* - * Because of space constraints and similar things, files are archived - * using their final path components, not the entire thing, so we need - * to point 'member' to the final component, if there is one, to make - * the comparisons easier... - */ - cp = strrchr (member, '/'); - if (cp != (char *) NULL) { - member = cp + 1; - } - len = tlen = strlen (member); - if (len > sizeof (arhPtr->AR_NAME)) { - tlen = sizeof (arhPtr->AR_NAME); - } - - while (fread ((char *)arhPtr, sizeof (struct ar_hdr), 1, arch) == 1) { - if (strncmp(arhPtr->AR_FMAG, ARFMAG, sizeof (arhPtr->AR_FMAG) ) != 0) { - /* - * The header is bogus, so the archive is bad - * and there's no way we can recover... - */ - fclose (arch); - return ((FILE *) NULL); - } else if (strncmp (member, arhPtr->AR_NAME, tlen) == 0) { - /* - * If the member's name doesn't take up the entire 'name' field, - * we have to be careful of matching prefixes. Names are space- - * padded to the right, so if the character in 'name' at the end - * of the matched string is anything but a space, this isn't the - * member we sought. - */ - if (tlen != sizeof(arhPtr->AR_NAME) && arhPtr->AR_NAME[tlen] != ' '){ - goto skip; - } else { - /* - * To make life easier, we reposition the file at the start - * of the header we just read before we return the stream. - * In a more general situation, it might be better to leave - * the file at the actual member, rather than its header, but - * not here... - */ - fseek (arch, -sizeof(struct ar_hdr), SEEK_CUR); - return (arch); - } - } else -#ifdef AR_EFMT1 - /* - * BSD 4.4 extended AR format: #1/, with name as the - * first bytes of the file - */ - if (strncmp(arhPtr->AR_NAME, AR_EFMT1, - sizeof(AR_EFMT1) - 1) == 0 && - isdigit(arhPtr->AR_NAME[sizeof(AR_EFMT1) - 1])) { - - unsigned int elen = atoi(&arhPtr->AR_NAME[sizeof(AR_EFMT1)-1]); - char ename[MAXPATHLEN]; - - if (elen > MAXPATHLEN) { - fclose (arch); - return NULL; - } - if (fread (ename, elen, 1, arch) != 1) { - fclose (arch); - return NULL; - } - ename[elen] = '\0'; - if (DEBUG(ARCH) || DEBUG(MAKE)) { - printf("ArchFind: Extended format entry for %s\n", ename); - } - if (strncmp(ename, member, len) == 0) { - /* Found as extended name */ - fseek (arch, -sizeof(struct ar_hdr) - elen, SEEK_CUR); - return (arch); - } - fseek (arch, -elen, SEEK_CUR); - goto skip; - } else -#endif - { -skip: - /* - * This isn't the member we're after, so we need to advance the - * stream's pointer to the start of the next header. Files are - * padded with newlines to an even-byte boundary, so we need to - * extract the size of the file from the 'size' field of the - * header and round it up during the seek. - */ - arhPtr->AR_SIZE[sizeof(arhPtr->AR_SIZE)-1] = '\0'; - size = (int) strtol(arhPtr->AR_SIZE, NULL, 10); - fseek (arch, (size + 1) & ~1, SEEK_CUR); - } - } - - /* - * We've looked everywhere, but the member is not to be found. Close the - * archive and return NULL -- an error. - */ - fclose (arch); - return ((FILE *) NULL); -} - -/*- - *----------------------------------------------------------------------- - * Arch_Touch -- - * Touch a member of an archive. - * - * Results: - * The 'time' field of the member's header is updated. - * - * Side Effects: - * The modification time of the entire archive is also changed. - * For a library, this could necessitate the re-ranlib'ing of the - * whole thing. - * - *----------------------------------------------------------------------- - */ -void -Arch_Touch (gn) - GNode *gn; /* Node of member to touch */ -{ - FILE * arch; /* Stream open to archive, positioned properly */ - struct ar_hdr arh; /* Current header describing member */ - char *p1, *p2; - - arch = ArchFindMember(Var_Value (ARCHIVE, gn, &p1), - Var_Value (MEMBER, gn, &p2), - &arh, "r+"); - if (p1) - free(p1); - if (p2) - free(p2); - snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now); - - if (arch != (FILE *) NULL) { - (void)fwrite ((char *)&arh, sizeof (struct ar_hdr), 1, arch); - fclose (arch); - } -} - -/*- - *----------------------------------------------------------------------- - * Arch_TouchLib -- - * Given a node which represents a library, touch the thing, making - * sure that the table of contents also is touched. - * - * Results: - * None. - * - * Side Effects: - * Both the modification time of the library and of the RANLIBMAG - * member are set to 'now'. - * - *----------------------------------------------------------------------- - */ -void -Arch_TouchLib (gn) - GNode *gn; /* The node of the library to touch */ -{ -#ifdef RANLIBMAG - FILE * arch; /* Stream open to archive */ - struct ar_hdr arh; /* Header describing table of contents */ - struct utimbuf times; /* Times for utime() call */ - - arch = ArchFindMember (gn->path, RANLIBMAG, &arh, "r+"); - snprintf(arh.AR_DATE, sizeof(arh.AR_DATE), "%-12ld", (long) now); - - if (arch != (FILE *) NULL) { - (void)fwrite ((char *)&arh, sizeof (struct ar_hdr), 1, arch); - fclose (arch); - - times.actime = times.modtime = now; - utime(gn->path, ×); - } -#endif -} - -/*- - *----------------------------------------------------------------------- - * Arch_MTime -- - * Return the modification time of a member of an archive. - * - * Results: - * The modification time (seconds). - * - * Side Effects: - * The mtime field of the given node is filled in with the value - * returned by the function. - * - *----------------------------------------------------------------------- - */ -time_t -Arch_MTime (gn) - GNode *gn; /* Node describing archive member */ -{ - struct ar_hdr *arhPtr; /* Header of desired member */ - time_t modTime; /* Modification time as an integer */ - char *p1, *p2; - - arhPtr = ArchStatMember (Var_Value (ARCHIVE, gn, &p1), - Var_Value (MEMBER, gn, &p2), - TRUE); - if (p1) - free(p1); - if (p2) - free(p2); - - if (arhPtr != (struct ar_hdr *) NULL) { - modTime = (time_t) strtol(arhPtr->AR_DATE, NULL, 10); - } else { - modTime = 0; - } - - gn->mtime = modTime; - return (modTime); -} - -/*- - *----------------------------------------------------------------------- - * Arch_MemMTime -- - * Given a non-existent archive member's node, get its modification - * time from its archived form, if it exists. - * - * Results: - * The modification time. - * - * Side Effects: - * The mtime field is filled in. - * - *----------------------------------------------------------------------- - */ -time_t -Arch_MemMTime (gn) - GNode *gn; -{ - LstNode ln; - GNode *pgn; - char *nameStart, - *nameEnd; - - if (Lst_Open (gn->parents) != SUCCESS) { - gn->mtime = 0; - return (0); - } - while ((ln = Lst_Next (gn->parents)) != NILLNODE) { - pgn = (GNode *) Lst_Datum (ln); - - if (pgn->type & OP_ARCHV) { - /* - * If the parent is an archive specification and is being made - * and its member's name matches the name of the node we were - * given, record the modification time of the parent in the - * child. We keep searching its parents in case some other - * parent requires this child to exist... - */ - nameStart = strchr (pgn->name, '(') + 1; - nameEnd = strchr (nameStart, ')'); - - if ((pgn->flags & REMAKE) && - strncmp(nameStart, gn->name, nameEnd - nameStart) == 0) { - gn->mtime = Arch_MTime(pgn); - } - } else if (pgn->flags & REMAKE) { - /* - * Something which isn't a library depends on the existence of - * this target, so it needs to exist. - */ - gn->mtime = 0; - break; - } - } - - Lst_Close (gn->parents); - - return (gn->mtime); -} - -/*- - *----------------------------------------------------------------------- - * Arch_FindLib -- - * Search for a library along the given search path. - * - * Results: - * None. - * - * Side Effects: - * The node's 'path' field is set to the found path (including the - * actual file name, not -l...). If the system can handle the -L - * flag when linking (or we cannot find the library), we assume that - * the user has placed the .LIBRARIES variable in the final linking - * command (or the linker will know where to find it) and set the - * TARGET variable for this node to be the node's name. Otherwise, - * we set the TARGET variable to be the full path of the library, - * as returned by Dir_FindFile. - * - *----------------------------------------------------------------------- - */ -void -Arch_FindLib (gn, path) - GNode *gn; /* Node of library to find */ - Lst path; /* Search path */ -{ - char *libName; /* file name for archive */ - size_t sz = strlen(gn->name) + 6 - 2; - - libName = (char *)emalloc(sz); - snprintf(libName, sz, "lib%s.a", &gn->name[2]); - - gn->path = Dir_FindFile (libName, path); - - free (libName); - -#ifdef LIBRARIES - Var_Set (TARGET, gn->name, gn, 0); -#else - Var_Set (TARGET, gn->path == (char *) NULL ? gn->name : gn->path, gn, 0); -#endif /* LIBRARIES */ -} - -/*- - *----------------------------------------------------------------------- - * Arch_LibOODate -- - * Decide if a node with the OP_LIB attribute is out-of-date. Called - * from Make_OODate to make its life easier. - * - * There are several ways for a library to be out-of-date that are - * not available to ordinary files. In addition, there are ways - * that are open to regular files that are not available to - * libraries. A library that is only used as a source is never - * considered out-of-date by itself. This does not preclude the - * library's modification time from making its parent be out-of-date. - * A library will be considered out-of-date for any of these reasons, - * given that it is a target on a dependency line somewhere: - * Its modification time is less than that of one of its - * sources (gn->mtime < gn->cmtime). - * Its modification time is greater than the time at which the - * make began (i.e. it's been modified in the course - * of the make, probably by archiving). - * The modification time of one of its sources is greater than - * the one of its RANLIBMAG member (i.e. its table of contents - * is out-of-date). We don't compare of the archive time - * vs. TOC time because they can be too close. In my - * opinion we should not bother with the TOC at all since - * this is used by 'ar' rules that affect the data contents - * of the archive, not by ranlib rules, which affect the - * TOC. - * - * Results: - * TRUE if the library is out-of-date. FALSE otherwise. - * - * Side Effects: - * The library will be hashed if it hasn't been already. - * - *----------------------------------------------------------------------- - */ -Boolean -Arch_LibOODate (gn) - GNode *gn; /* The library's graph node */ -{ - Boolean oodate; - - if (gn->type & OP_PHONY) { - oodate = TRUE; - } else if (OP_NOP(gn->type) && Lst_IsEmpty(gn->children)) { - oodate = FALSE; - } else if ((gn->cmtime == 0) || (gn->mtime > now) || - (gn->mtime < gn->cmtime)) { - oodate = TRUE; - } else { -#ifdef RANLIBMAG - struct ar_hdr *arhPtr; /* Header for __.SYMDEF */ - int modTimeTOC; /* The table-of-contents's mod time */ - - arhPtr = ArchStatMember (gn->path, RANLIBMAG, FALSE); - - if (arhPtr != (struct ar_hdr *)NULL) { - modTimeTOC = (int) strtol(arhPtr->AR_DATE, NULL, 10); - - if (DEBUG(ARCH) || DEBUG(MAKE)) { - printf("%s modified %s...", RANLIBMAG, Targ_FmtTime(modTimeTOC)); - } - oodate = (gn->cmtime > modTimeTOC); - } else { - /* - * A library w/o a table of contents is out-of-date - */ - if (DEBUG(ARCH) || DEBUG(MAKE)) { - printf("No t.o.c...."); - } - oodate = TRUE; - } -#else - oodate = FALSE; -#endif - } - return (oodate); -} - -/*- - *----------------------------------------------------------------------- - * Arch_Init -- - * Initialize things for this module. - * - * Results: - * None. - * - * Side Effects: - * The 'archives' list is initialized. - * - *----------------------------------------------------------------------- - */ -void -Arch_Init () -{ - archives = Lst_Init (FALSE); -} - - - -/*- - *----------------------------------------------------------------------- - * Arch_End -- - * Cleanup things for this module. - * - * Results: - * None. - * - * Side Effects: - * The 'archives' list is freed - * - *----------------------------------------------------------------------- - */ -void -Arch_End () -{ -#ifdef CLEANUP - Lst_Destroy(archives, ArchFree); -#endif -} - -/*- - *----------------------------------------------------------------------- - * Arch_IsLib -- - * Check if the node is a library - * - * Results: - * True or False. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -Arch_IsLib(gn) - GNode *gn; -{ - static const char armag[] = "!\n"; - char buf[sizeof(armag)-1]; - int fd; - - if ((fd = open(gn->path, O_RDONLY)) == -1) - return FALSE; - - if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { - (void) close(fd); - return FALSE; - } - - (void) close(fd); - - return memcmp(buf, armag, sizeof(buf)) == 0; -} diff --git a/bootstrap/bmake/bit.h b/bootstrap/bmake/bit.h deleted file mode 100644 index 6753471bf70..00000000000 --- a/bootstrap/bmake/bit.h +++ /dev/null @@ -1,102 +0,0 @@ -/* $NetBSD: bit.h,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)bit.h 5.3 (Berkeley) 6/1/90 - */ - -/* - * bit.h -- - * - * Definition of macros for setting and clearing bits in an array - * of integers. - * - * It is assumed that "int" is 32 bits wide. - */ - -#ifndef _BIT -#define _BIT - -#include "sprite.h" - -#define BIT_NUM_BITS_PER_INT 32 -#define BIT_NUM_BITS_PER_BYTE 8 - -#define Bit_NumInts(numBits) \ - (((numBits)+BIT_NUM_BITS_PER_INT -1)/BIT_NUM_BITS_PER_INT) - -#define Bit_NumBytes(numBits) \ - (Bit_NumInts(numBits) * sizeof(int)) - -#define Bit_Alloc(numBits, bitArrayPtr) \ - bitArrayPtr = (int *) emalloc((unsigned)Bit_NumBytes(numBits)); \ - Bit_Zero((numBits), (bitArrayPtr)) - -#define Bit_Free(bitArrayPtr) \ - free((char *)bitArrayPtr) - -#define Bit_Set(numBits, bitArrayPtr) \ - ((bitArrayPtr)[(numBits)/BIT_NUM_BITS_PER_INT] |= \ - (1 << ((numBits) % BIT_NUM_BITS_PER_INT))) - -#define Bit_IsSet(numBits, bitArrayPtr) \ - ((bitArrayPtr)[(numBits)/BIT_NUM_BITS_PER_INT] & \ - (1 << ((numBits) % BIT_NUM_BITS_PER_INT))) - -#define Bit_Clear(numBits, bitArrayPtr) \ - ((bitArrayPtr)[(numBits)/BIT_NUM_BITS_PER_INT] &= \ - ~(1 << ((numBits) % BIT_NUM_BITS_PER_INT))) - -#define Bit_IsClear(numBits, bitArrayPtr) \ - (!(Bit_IsSet((numBits), (bitArrayPtr)))) - -#define Bit_Copy(numBits, srcArrayPtr, destArrayPtr) \ - memmove((char *)(destArrayPtr), (char *)(srcArrayPtr), \ - Bit_NumBytes(numBits)) - -#define Bit_Zero(numBits, bitArrayPtr) \ - memset((char *)(bitArrayPtr), 0, Bit_NumBytes(numBits)) - -extern int Bit_FindFirstSet(); -extern int Bit_FindFirstClear(); -extern Boolean Bit_Intersect(); -extern Boolean Bit_Union(); -extern Boolean Bit_AnySet(); -extern int *Bit_Expand(); - -#endif /* _BIT */ diff --git a/bootstrap/bmake/buf.c b/bootstrap/bmake/buf.c deleted file mode 100644 index c2eb21db12b..00000000000 --- a/bootstrap/bmake/buf.c +++ /dev/null @@ -1,308 +0,0 @@ -/* $NetBSD: buf.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: buf.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)buf.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: buf.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * buf.c -- - * Functions for automatically-expanded buffers. - */ - -#include "sprite.h" -#include "make.h" -#include "buf.h" - -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif - -/* - * BufExpand -- - * Expand the given buffer to hold the given number of additional - * bytes. - * Makes sure there's room for an extra NULL byte at the end of the - * buffer in case it holds a string. - */ -#define BufExpand(bp,nb) \ - while (bp->left < (nb)+1) {\ - int newSize = (bp)->size * 2; \ - Byte *newBuf = (Byte *) erealloc((bp)->buffer, newSize); \ - \ - (bp)->inPtr = newBuf + ((bp)->inPtr - (bp)->buffer); \ - (bp)->outPtr = newBuf + ((bp)->outPtr - (bp)->buffer);\ - (bp)->buffer = newBuf;\ - (bp)->size = newSize;\ - (bp)->left = newSize - ((bp)->inPtr - (bp)->buffer);\ - } - -#define BUF_DEF_SIZE 256 /* Default buffer size */ - -/*- - *----------------------------------------------------------------------- - * Buf_OvAddByte -- - * Add a single byte to the buffer. left is zero or negative. - * - * Results: - * None. - * - * Side Effects: - * The buffer may be expanded. - * - *----------------------------------------------------------------------- - */ -void -Buf_OvAddByte (bp, byte) - register Buffer bp; - int byte; -{ - int nbytes = 1; - bp->left = 0; - BufExpand (bp, nbytes); - - *bp->inPtr++ = byte; - bp->left--; - - /* - * Null-terminate - */ - *bp->inPtr = 0; -} - -/*- - *----------------------------------------------------------------------- - * Buf_AddBytes -- - * Add a number of bytes to the buffer. - * - * Results: - * None. - * - * Side Effects: - * Guess what? - * - *----------------------------------------------------------------------- - */ -void -Buf_AddBytes (bp, numBytes, bytesPtr) - register Buffer bp; - int numBytes; - const Byte *bytesPtr; -{ - - BufExpand (bp, numBytes); - - memcpy (bp->inPtr, bytesPtr, numBytes); - bp->inPtr += numBytes; - bp->left -= numBytes; - - /* - * Null-terminate - */ - *bp->inPtr = 0; -} - -/*- - *----------------------------------------------------------------------- - * Buf_GetAll -- - * Get all the available data at once. - * - * Results: - * A pointer to the data and the number of bytes available. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -Byte * -Buf_GetAll (bp, numBytesPtr) - register Buffer bp; - int *numBytesPtr; -{ - - if (numBytesPtr != (int *)NULL) { - *numBytesPtr = bp->inPtr - bp->outPtr; - } - - return (bp->outPtr); -} - -/*- - *----------------------------------------------------------------------- - * Buf_Discard -- - * Throw away bytes in a buffer. - * - * Results: - * None. - * - * Side Effects: - * The bytes are discarded. - * - *----------------------------------------------------------------------- - */ -void -Buf_Discard (bp, numBytes) - register Buffer bp; - int numBytes; -{ - - if (bp->inPtr - bp->outPtr <= numBytes) { - bp->inPtr = bp->outPtr = bp->buffer; - bp->left = bp->size; - *bp->inPtr = 0; - } else { - bp->outPtr += numBytes; - } -} - -/*- - *----------------------------------------------------------------------- - * Buf_Size -- - * Returns the number of bytes in the given buffer. Doesn't include - * the null-terminating byte. - * - * Results: - * The number of bytes. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -Buf_Size (buf) - Buffer buf; -{ - return (buf->inPtr - buf->outPtr); -} - -/*- - *----------------------------------------------------------------------- - * Buf_Init -- - * Initialize a buffer. If no initial size is given, a reasonable - * default is used. - * - * Results: - * A buffer to be given to other functions in this library. - * - * Side Effects: - * The buffer is created, the space allocated and pointers - * initialized. - * - *----------------------------------------------------------------------- - */ -Buffer -Buf_Init (size) - int size; /* Initial size for the buffer */ -{ - Buffer bp; /* New Buffer */ - - bp = (Buffer)emalloc(sizeof(*bp)); - - if (size <= 0) { - size = BUF_DEF_SIZE; - } - bp->left = bp->size = size; - bp->buffer = (Byte *)emalloc(size); - bp->inPtr = bp->outPtr = bp->buffer; - *bp->inPtr = 0; - - return (bp); -} - -/*- - *----------------------------------------------------------------------- - * Buf_Destroy -- - * Nuke a buffer and all its resources. - * - * Results: - * None. - * - * Side Effects: - * The buffer is freed. - * - *----------------------------------------------------------------------- - */ -void -Buf_Destroy (buf, freeData) - Buffer buf; /* Buffer to destroy */ - Boolean freeData; /* TRUE if the data should be destroyed as well */ -{ - - if (freeData) { - free ((char *)buf->buffer); - } - free ((char *)buf); -} - -/*- - *----------------------------------------------------------------------- - * Buf_ReplaceLastByte -- - * Replace the last byte in a buffer. - * - * Results: - * None. - * - * Side Effects: - * If the buffer was empty intially, then a new byte will be added. - * Otherwise, the last byte is overwritten. - * - *----------------------------------------------------------------------- - */ -void -Buf_ReplaceLastByte (buf, byte) - Buffer buf; /* buffer to augment */ - int byte; /* byte to be written */ -{ - if (buf->inPtr == buf->outPtr) - Buf_AddByte(buf, byte); - else - *(buf->inPtr - 1) = byte; -} diff --git a/bootstrap/bmake/buf.h b/bootstrap/bmake/buf.h deleted file mode 100644 index b3462a38683..00000000000 --- a/bootstrap/bmake/buf.h +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: buf.h,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)buf.h 8.1 (Berkeley) 6/6/93 - */ - -/*- - * buf.h -- - * Header for users of the buf library. - */ - -#ifndef _BUF_H -#define _BUF_H - -#include "sprite.h" - -typedef char Byte; - -typedef struct Buffer { - int size; /* Current size of the buffer */ - int left; /* Space left (== size - (inPtr - buffer)) */ - Byte *buffer; /* The buffer itself */ - Byte *inPtr; /* Place to write to */ - Byte *outPtr; /* Place to read from */ -} *Buffer; - -/* Buf_AddByte adds a single byte to a buffer. */ -#define Buf_AddByte(bp, byte) \ - (void) (--(bp)->left <= 0 ? Buf_OvAddByte(bp, byte), 1 : \ - (*(bp)->inPtr++ = (byte), *(bp)->inPtr = 0), 1) - -#define BUF_ERROR 256 - -void Buf_OvAddByte __P((Buffer, int)); -void Buf_AddBytes __P((Buffer, int, const Byte *)); -Byte *Buf_GetAll __P((Buffer, int *)); -void Buf_Discard __P((Buffer, int)); -int Buf_Size __P((Buffer)); -Buffer Buf_Init __P((int)); -void Buf_Destroy __P((Buffer, Boolean)); -void Buf_ReplaceLastByte __P((Buffer, int)); - -#endif /* _BUF_H */ diff --git a/bootstrap/bmake/compat.c b/bootstrap/bmake/compat.c deleted file mode 100644 index 5086742c2f4..00000000000 --- a/bootstrap/bmake/compat.c +++ /dev/null @@ -1,636 +0,0 @@ -/* $NetBSD: compat.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: compat.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)compat.c 8.2 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: compat.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: compat.c,v 1.1.1.1 2004/03/11 13:04:01 grant Exp $"); -#endif - -/*- - * compat.c -- - * The routines in this file implement the full-compatibility - * mode of PMake. Most of the special functionality of PMake - * is available in this mode. Things not supported: - * - different shells. - * - friendly variable substitution. - * - * Interface: - * Compat_Run Initialize things for this module and recreate - * thems as need creatin' - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include -#include -#include -#include -#include "wait.h" -#include -#include -#include -#include -#include -#include -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" - -/* - * The following array is used to make a fast determination of which - * characters are interpreted specially by the shell. If a command - * contains any of these characters, it is executed by the shell, not - * directly by us. - */ - -static char meta[256]; - -static GNode *curTarg = NILGNODE; -static GNode *ENDNode; -static void CompatInterrupt __P((int)); -static int CompatRunCommand __P((ClientData, ClientData)); -static int CompatMake __P((ClientData, ClientData)); - -/*- - *----------------------------------------------------------------------- - * CompatInterrupt -- - * Interrupt the creation of the current target and remove it if - * it ain't precious. - * - * Results: - * None. - * - * Side Effects: - * The target is removed and the process exits. If .INTERRUPT exists, - * its commands are run first WITH INTERRUPTS IGNORED.. - * - *----------------------------------------------------------------------- - */ -static void -CompatInterrupt (signo) - int signo; -{ - GNode *gn; - - if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) { - char *p1; - char *file = Var_Value (TARGET, curTarg, &p1); - - if (!noExecute && eunlink(file) != -1) { - Error("*** %s removed\n", file); - } - if (p1) - free(p1); - - /* - * Run .INTERRUPT only if hit with interrupt signal - */ - if (signo == SIGINT) { - gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); - if (gn != NILGNODE) { - Lst_ForEach(gn->commands, CompatRunCommand, (ClientData)gn); - } - } - - } - exit (signo); -} - -/*- - *----------------------------------------------------------------------- - * CompatRunCommand -- - * Execute the next command for a target. If the command returns an - * error, the node's made field is set to ERROR and creation stops. - * - * Results: - * 0 if the command succeeded, 1 if an error occurred. - * - * Side Effects: - * The node's 'made' field may be set to ERROR. - * - *----------------------------------------------------------------------- - */ -static int -CompatRunCommand (cmdp, gnp) - ClientData cmdp; /* Command to execute */ - ClientData gnp; /* Node from which the command came */ -{ - char *cmdStart; /* Start of expanded command */ - char *cp, *bp; - Boolean silent, /* Don't print command */ - errCheck; /* Check errors */ - WAIT_T reason; /* Reason for child's death */ - int status; /* Description of child's death */ - int cpid; /* Child actually found */ - ReturnStatus stat; /* Status of fork */ - LstNode cmdNode; /* Node where current command is located */ - char **av; /* Argument vector for thing to exec */ - int argc; /* Number of arguments in av or 0 if not - * dynamically allocated */ - Boolean local; /* TRUE if command should be executed - * locally */ - char *cmd = (char *) cmdp; - GNode *gn = (GNode *) gnp; - - /* - * Avoid clobbered variable warnings by forcing the compiler - * to ``unregister'' variables - */ -#if __GNUC__ - (void) &av; - (void) &errCheck; -#endif - silent = gn->type & OP_SILENT; - errCheck = !(gn->type & OP_IGNORE); - - cmdNode = Lst_Member (gn->commands, (ClientData)cmd); - cmdStart = Var_Subst (NULL, cmd, gn, FALSE); - - /* - * brk_string will return an argv with a NULL in av[0], thus causing - * execvp to choke and die horribly. Besides, how can we execute a null - * command? In any case, we warn the user that the command expanded to - * nothing (is this the right thing to do?). - */ - - if (*cmdStart == '\0') { - free(cmdStart); - Error("%s expands to empty string", cmd); - return(0); - } else { - cmd = cmdStart; - } - Lst_Replace (cmdNode, (ClientData)cmdStart); - - if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) { - (void)Lst_AtEnd(ENDNode->commands, (ClientData)cmdStart); - return(0); - } else if (strcmp(cmdStart, "...") == 0) { - gn->type |= OP_SAVE_CMDS; - return(0); - } - - while ((*cmd == '@') || (*cmd == '-')) { - if (*cmd == '@') { - silent = TRUE; - } else { - errCheck = FALSE; - } - cmd++; - } - - while (isspace((unsigned char)*cmd)) - cmd++; - - /* - * Search for meta characters in the command. If there are no meta - * characters, there's no need to execute a shell to execute the - * command. - */ - for (cp = cmd; !meta[(unsigned char)*cp]; cp++) { - continue; - } - - /* - * Print the command before echoing if we're not supposed to be quiet for - * this one. We also print the command if -n given. - */ - if (!silent || NoExecute(gn)) { - printf ("%s\n", cmd); - fflush(stdout); - } - - /* - * If we're not supposed to execute any commands, this is as far as - * we go... - */ - if (NoExecute(gn)) { - return (0); - } - - if (*cp != '\0') { - /* - * If *cp isn't the null character, we hit a "meta" character and - * need to pass the command off to the shell. We give the shell the - * -e flag as well as -c if it's supposed to exit when it hits an - * error. - */ - static char *shargv[4] = { "/bin/sh" }; - - if (DEBUG(SHELL)) - shargv[1] = (errCheck ? "-exc" : "-xc"); - else - shargv[1] = (errCheck ? "-ec" : "-c"); - shargv[2] = cmd; - shargv[3] = (char *)NULL; - av = shargv; - argc = 0; - bp = NULL; - } else { - /* - * No meta-characters, so no need to exec a shell. Break the command - * into words to form an argument vector we can execute. - */ - av = brk_string(cmd, &argc, TRUE, &bp); - } - - local = TRUE; - - /* - * Fork and execute the single command. If the fork fails, we abort. - */ - cpid = vfork(); - if (cpid < 0) { - Fatal("Could not fork"); - } - if (cpid == 0) { - Check_Cwd(av); - if (local) - (void)execvp(av[0], av); - else - (void)execv(av[0], av); - execError(av[0]); - _exit(1); - } - if (bp) { - free(av); - free(bp); - } - free(cmdStart); - Lst_Replace (cmdNode, (ClientData) NULL); - - /* - * The child is off and running. Now all we can do is wait... - */ - while (1) { - - while ((stat = wait(&reason)) != cpid) { - if (stat == -1 && errno != EINTR) { - break; - } - } - - if (stat > -1) { - if (WIFSTOPPED(reason)) { - status = WSTOPSIG(reason); /* stopped */ - } else if (WIFEXITED(reason)) { - status = WEXITSTATUS(reason); /* exited */ - if (status != 0) { - printf ("*** Error code %d", status); - } - } else { - status = WTERMSIG(reason); /* signaled */ - printf ("*** Signal %d", status); - } - - - if (!WIFEXITED(reason) || (status != 0)) { - if (errCheck) { - gn->made = ERROR; - if (keepgoing) { - /* - * Abort the current target, but let others - * continue. - */ - printf (" (continuing)\n"); - } - } else { - /* - * Continue executing commands for this target. - * If we return 0, this will happen... - */ - printf (" (ignored)\n"); - status = 0; - } - } - break; - } else { - Fatal ("error in wait: %d: %s", stat, strerror(errno)); - /*NOTREACHED*/ - } - } - - return (status); -} - -/*- - *----------------------------------------------------------------------- - * CompatMake -- - * Make a target. - * - * Results: - * 0 - * - * Side Effects: - * If an error is detected and not being ignored, the process exits. - * - *----------------------------------------------------------------------- - */ -static int -CompatMake (gnp, pgnp) - ClientData gnp; /* The node to make */ - ClientData pgnp; /* Parent to abort if necessary */ -{ - GNode *gn = (GNode *) gnp; - GNode *pgn = (GNode *) pgnp; - - if (pgn->type & OP_MADE) { - (void) Dir_MTime(gn); - gn->made = UPTODATE; - } - - if (gn->made == UNMADE) { - /* - * First mark ourselves to be made, then apply whatever transformations - * the suffix module thinks are necessary. Once that's done, we can - * descend and make all our children. If any of them has an error - * but the -k flag was given, our 'make' field will be set FALSE again. - * This is our signal to not attempt to do anything but abort our - * parent as well. - */ - gn->flags |= REMAKE; - gn->made = BEINGMADE; - Suff_FindDeps (gn); - Lst_ForEach (gn->children, CompatMake, (ClientData)gn); - if ((gn->flags & REMAKE) == 0) { - gn->made = ABORTED; - pgn->flags &= ~REMAKE; - goto cohorts; - } - - if (Lst_Member (gn->iParents, pgn) != NILLNODE) { - char *p1; - Var_Set (IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0); - if (p1) - free(p1); - } - - /* - * All the children were made ok. Now cmtime contains the modification - * time of the newest child, we need to find out if we exist and when - * we were modified last. The criteria for datedness are defined by the - * Make_OODate function. - */ - if (DEBUG(MAKE)) { - printf("Examining %s...", gn->name); - } - if (! Make_OODate(gn)) { - gn->made = UPTODATE; - if (DEBUG(MAKE)) { - printf("up-to-date.\n"); - } - goto cohorts; - } else if (DEBUG(MAKE)) { - printf("out-of-date.\n"); - } - - /* - * If the user is just seeing if something is out-of-date, exit now - * to tell him/her "yes". - */ - if (queryFlag) { - exit (1); - } - - /* - * We need to be re-made. We also have to make sure we've got a $? - * variable. To be nice, we also define the $> variable using - * Make_DoAllVar(). - */ - Make_DoAllVar(gn); - - /* - * Alter our type to tell if errors should be ignored or things - * should not be printed so CompatRunCommand knows what to do. - */ - if (Targ_Ignore (gn)) { - gn->type |= OP_IGNORE; - } - if (Targ_Silent (gn)) { - gn->type |= OP_SILENT; - } - - if (Job_CheckCommands (gn, Fatal)) { - /* - * Our commands are ok, but we still have to worry about the -t - * flag... - */ - if (!touchFlag || (gn->type & OP_MAKE)) { - curTarg = gn; - Lst_ForEach (gn->commands, CompatRunCommand, (ClientData)gn); - curTarg = NILGNODE; - } else { - Job_Touch (gn, gn->type & OP_SILENT); - } - } else { - gn->made = ERROR; - } - - if (gn->made != ERROR) { - /* - * If the node was made successfully, mark it so, update - * its modification time and timestamp all its parents. Note - * that for .ZEROTIME targets, the timestamping isn't done. - * This is to keep its state from affecting that of its parent. - */ - gn->made = MADE; - pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0; - if (!(gn->type & OP_EXEC)) { - pgn->flags |= CHILDMADE; - Make_TimeStamp(pgn, gn); - } - } else if (keepgoing) { - pgn->flags &= ~REMAKE; - } else { - PrintOnError("\n\nStop."); - exit (1); - } - } else if (gn->made == ERROR) { - /* - * Already had an error when making this beastie. Tell the parent - * to abort. - */ - pgn->flags &= ~REMAKE; - } else { - if (Lst_Member (gn->iParents, pgn) != NILLNODE) { - char *p1; - Var_Set (IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0); - if (p1) - free(p1); - } - switch(gn->made) { - case BEINGMADE: - Error("Graph cycles through %s\n", gn->name); - gn->made = ERROR; - pgn->flags &= ~REMAKE; - break; - case MADE: - if ((gn->type & OP_EXEC) == 0) { - pgn->flags |= CHILDMADE; - Make_TimeStamp(pgn, gn); - } - break; - case UPTODATE: - if ((gn->type & OP_EXEC) == 0) { - Make_TimeStamp(pgn, gn); - } - break; - default: - break; - } - } - -cohorts: - Lst_ForEach (gn->cohorts, CompatMake, pgnp); - return (0); -} - -/*- - *----------------------------------------------------------------------- - * Compat_Run -- - * Initialize this mode and start making. - * - * Results: - * None. - * - * Side Effects: - * Guess what? - * - *----------------------------------------------------------------------- - */ -void -Compat_Run(targs) - Lst targs; /* List of target nodes to re-create */ -{ - char *cp; /* Pointer to string of shell meta-characters */ - GNode *gn = NULL;/* Current root target */ - int errors; /* Number of targets not remade due to errors */ - - if (signal(SIGINT, SIG_IGN) != SIG_IGN) { - signal(SIGINT, CompatInterrupt); - } - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { - signal(SIGTERM, CompatInterrupt); - } - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { - signal(SIGHUP, CompatInterrupt); - } - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { - signal(SIGQUIT, CompatInterrupt); - } - - for (cp = "#=|^(){};&<>*?[]:$`\\\n"; *cp != '\0'; cp++) { - meta[(unsigned char) *cp] = 1; - } - /* - * The null character serves as a sentinel in the string. - */ - meta[0] = 1; - - ENDNode = Targ_FindNode(".END", TARG_CREATE); - /* - * If the user has defined a .BEGIN target, execute the commands attached - * to it. - */ - if (!queryFlag) { - gn = Targ_FindNode(".BEGIN", TARG_NOCREATE); - if (gn != NILGNODE) { - Lst_ForEach(gn->commands, CompatRunCommand, (ClientData)gn); - if (gn->made == ERROR) { - PrintOnError("\n\nStop."); - exit(1); - } - } - } - - /* - * Expand .USE nodes right now, because they can modify the structure - * of the tree. - */ - Lst_Destroy(Make_ExpandUse(targs), NOFREE); - - /* - * For each entry in the list of targets to create, call CompatMake on - * it to create the thing. CompatMake will leave the 'made' field of gn - * in one of several states: - * UPTODATE gn was already up-to-date - * MADE gn was recreated successfully - * ERROR An error occurred while gn was being created - * ABORTED gn was not remade because one of its inferiors - * could not be made due to errors. - */ - errors = 0; - while (!Lst_IsEmpty (targs)) { - gn = (GNode *) Lst_DeQueue (targs); - CompatMake (gn, gn); - - if (gn->made == UPTODATE) { - printf ("`%s' is up to date.\n", gn->name); - } else if (gn->made == ABORTED) { - printf ("`%s' not remade because of errors.\n", gn->name); - errors += 1; - } - } - - /* - * If the user has defined a .END target, run its commands. - */ - if (errors == 0) { - Lst_ForEach(ENDNode->commands, CompatRunCommand, (ClientData)gn); - if (gn->made == ERROR) { - PrintOnError("\n\nStop."); - exit(1); - } - } -} diff --git a/bootstrap/bmake/cond.c b/bootstrap/bmake/cond.c deleted file mode 100644 index bb48b195dc0..00000000000 --- a/bootstrap/bmake/cond.c +++ /dev/null @@ -1,1351 +0,0 @@ -/* $NetBSD: cond.c,v 1.2 2004/03/15 14:20:58 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: cond.c,v 1.2 2004/03/15 14:20:58 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94"; -#else -__RCSID("$NetBSD: cond.c,v 1.2 2004/03/15 14:20:58 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * cond.c -- - * Functions to handle conditionals in a makefile. - * - * Interface: - * Cond_Eval Evaluate the conditional in the passed line. - * - */ - -#include -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "buf.h" - -/* - * The parsing of conditional expressions is based on this grammar: - * E -> F || E - * E -> F - * F -> T && F - * F -> T - * T -> defined(variable) - * T -> make(target) - * T -> exists(file) - * T -> empty(varspec) - * T -> target(name) - * T -> commands(name) - * T -> symbol - * T -> $(varspec) op value - * T -> $(varspec) == "string" - * T -> $(varspec) != "string" - * T -> ( E ) - * T -> ! T - * op -> == | != | > | < | >= | <= - * - * 'symbol' is some other symbol to which the default function (condDefProc) - * is applied. - * - * Tokens are scanned from the 'condExpr' string. The scanner (CondToken) - * will return And for '&' and '&&', Or for '|' and '||', Not for '!', - * LParen for '(', RParen for ')' and will evaluate the other terminal - * symbols, using either the default function or the function given in the - * terminal, and return the result as either True or False. - * - * All Non-Terminal functions (CondE, CondF and CondT) return Err on error. - */ -typedef enum { - And, Or, Not, True, False, LParen, RParen, EndOfFile, None, Err -} Token; - -/*- - * Structures to handle elegantly the different forms of #if's. The - * last two fields are stored in condInvert and condDefProc, respectively. - */ -static void CondPushBack __P((Token)); -static int CondGetArg __P((char **, char **, char *, Boolean)); -static Boolean CondDoDefined __P((int, char *)); -static int CondStrMatch __P((ClientData, ClientData)); -static Boolean CondDoMake __P((int, char *)); -static Boolean CondDoExists __P((int, char *)); -static Boolean CondDoTarget __P((int, char *)); -static Boolean CondDoCommands __P((int, char *)); -static Boolean CondCvtArg __P((char *, double *)); -static Token CondToken __P((Boolean)); -static Token CondT __P((Boolean)); -static Token CondF __P((Boolean)); -static Token CondE __P((Boolean)); - -static struct If { - char *form; /* Form of if */ - int formlen; /* Length of form */ - Boolean doNot; /* TRUE if default function should be negated */ - Boolean (*defProc) __P((int, char *)); /* Default function to apply */ -} ifs[] = { - { "ifdef", 5, FALSE, CondDoDefined }, - { "ifndef", 6, TRUE, CondDoDefined }, - { "ifmake", 6, FALSE, CondDoMake }, - { "ifnmake", 7, TRUE, CondDoMake }, - { "if", 2, FALSE, CondDoDefined }, - { NULL, 0, FALSE, NULL } -}; - -static Boolean condInvert; /* Invert the default function */ -static Boolean (*condDefProc) /* Default function to apply */ - __P((int, char *)); -static char *condExpr; /* The expression to parse */ -static Token condPushBack=None; /* Single push-back token used in - * parsing */ - -#define MAXIF 30 /* greatest depth of #if'ing */ - -static Boolean condStack[MAXIF]; /* Stack of conditionals's values */ -static int condTop = MAXIF; /* Top-most conditional */ -static int skipIfLevel=0; /* Depth of skipped conditionals */ -static Boolean skipLine = FALSE; /* Whether the parse module is skipping - * lines */ - -/*- - *----------------------------------------------------------------------- - * CondPushBack -- - * Push back the most recent token read. We only need one level of - * this, so the thing is just stored in 'condPushback'. - * - * Results: - * None. - * - * Side Effects: - * condPushback is overwritten. - * - *----------------------------------------------------------------------- - */ -static void -CondPushBack (t) - Token t; /* Token to push back into the "stream" */ -{ - condPushBack = t; -} - -/*- - *----------------------------------------------------------------------- - * CondGetArg -- - * Find the argument of a built-in function. - * - * Results: - * The length of the argument and the address of the argument. - * - * Side Effects: - * The pointer is set to point to the closing parenthesis of the - * function call. - * - *----------------------------------------------------------------------- - */ -static int -CondGetArg (linePtr, argPtr, func, parens) - char **linePtr; - char **argPtr; - char *func; - Boolean parens; /* TRUE if arg should be bounded by parens */ -{ - register char *cp; - int argLen; - register Buffer buf; - - cp = *linePtr; - if (parens) { - while (*cp != '(' && *cp != '\0') { - cp++; - } - if (*cp == '(') { - cp++; - } - } - - if (*cp == '\0') { - /* - * No arguments whatsoever. Because 'make' and 'defined' aren't really - * "reserved words", we don't print a message. I think this is better - * than hitting the user with a warning message every time s/he uses - * the word 'make' or 'defined' at the beginning of a symbol... - */ - *argPtr = cp; - return (0); - } - - while (*cp == ' ' || *cp == '\t') { - cp++; - } - - /* - * Create a buffer for the argument and start it out at 16 characters - * long. Why 16? Why not? - */ - buf = Buf_Init(16); - - while ((strchr(" \t)&|", *cp) == (char *)NULL) && (*cp != '\0')) { - if (*cp == '$') { - /* - * Parse the variable spec and install it as part of the argument - * if it's valid. We tell Var_Parse to complain on an undefined - * variable, so we don't do it too. Nor do we return an error, - * though perhaps we should... - */ - char *cp2; - int len; - Boolean doFree; - - cp2 = Var_Parse(cp, VAR_CMD, TRUE, &len, &doFree); - - Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2); - if (doFree) { - free(cp2); - } - cp += len; - } else { - Buf_AddByte(buf, (Byte)*cp); - cp++; - } - } - - Buf_AddByte(buf, (Byte)'\0'); - *argPtr = (char *)Buf_GetAll(buf, &argLen); - Buf_Destroy(buf, FALSE); - - while (*cp == ' ' || *cp == '\t') { - cp++; - } - if (parens && *cp != ')') { - Parse_Error (PARSE_WARNING, "Missing closing parenthesis for %s()", - func); - return (0); - } else if (parens) { - /* - * Advance pointer past close parenthesis. - */ - cp++; - } - - *linePtr = cp; - return (argLen); -} - -/*- - *----------------------------------------------------------------------- - * CondDoDefined -- - * Handle the 'defined' function for conditionals. - * - * Results: - * TRUE if the given variable is defined. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoDefined (argLen, arg) - int argLen; - char *arg; -{ - char savec = arg[argLen]; - char *p1; - Boolean result; - - arg[argLen] = '\0'; - if (Var_Value (arg, VAR_CMD, &p1) != (char *)NULL) { - result = TRUE; - } else { - result = FALSE; - } - if (p1) - free(p1); - arg[argLen] = savec; - return (result); -} - -/*- - *----------------------------------------------------------------------- - * CondStrMatch -- - * Front-end for Str_Match so it returns 0 on match and non-zero - * on mismatch. Callback function for CondDoMake via Lst_Find - * - * Results: - * 0 if string matches pattern - * - * Side Effects: - * None - * - *----------------------------------------------------------------------- - */ -static int -CondStrMatch(string, pattern) - ClientData string; - ClientData pattern; -{ - return(!Str_Match((char *) string,(char *) pattern)); -} - -/*- - *----------------------------------------------------------------------- - * CondDoMake -- - * Handle the 'make' function for conditionals. - * - * Results: - * TRUE if the given target is being made. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoMake (argLen, arg) - int argLen; - char *arg; -{ - char savec = arg[argLen]; - Boolean result; - - arg[argLen] = '\0'; - if (Lst_Find (create, (ClientData)arg, CondStrMatch) == NILLNODE) { - result = FALSE; - } else { - result = TRUE; - } - arg[argLen] = savec; - return (result); -} - -/*- - *----------------------------------------------------------------------- - * CondDoExists -- - * See if the given file exists. - * - * Results: - * TRUE if the file exists and FALSE if it does not. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoExists (argLen, arg) - int argLen; - char *arg; -{ - char savec = arg[argLen]; - Boolean result; - char *path; - - arg[argLen] = '\0'; - path = Dir_FindFile(arg, dirSearchPath); - if (path != (char *)NULL) { - result = TRUE; - free(path); - } else { - result = FALSE; - } - arg[argLen] = savec; - return (result); -} - -/*- - *----------------------------------------------------------------------- - * CondDoTarget -- - * See if the given node exists and is an actual target. - * - * Results: - * TRUE if the node exists as a target and FALSE if it does not. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoTarget (argLen, arg) - int argLen; - char *arg; -{ - char savec = arg[argLen]; - Boolean result; - GNode *gn; - - arg[argLen] = '\0'; - gn = Targ_FindNode(arg, TARG_NOCREATE); - if ((gn != NILGNODE) && !OP_NOP(gn->type)) { - result = TRUE; - } else { - result = FALSE; - } - arg[argLen] = savec; - return (result); -} - -/*- - *----------------------------------------------------------------------- - * CondDoCommands -- - * See if the given node exists and is an actual target with commands - * associated with it. - * - * Results: - * TRUE if the node exists as a target and has commands associated with - * it and FALSE if it does not. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -CondDoCommands (argLen, arg) - int argLen; - char *arg; -{ - char savec = arg[argLen]; - Boolean result; - GNode *gn; - - arg[argLen] = '\0'; - gn = Targ_FindNode(arg, TARG_NOCREATE); - if ((gn != NILGNODE) && !OP_NOP(gn->type) && !Lst_IsEmpty(gn->commands)) { - result = TRUE; - } else { - result = FALSE; - } - arg[argLen] = savec; - return (result); -} - -/*- - *----------------------------------------------------------------------- - * CondCvtArg -- - * Convert the given number into a double. If the number begins - * with 0x, it is interpreted as a hexadecimal integer - * and converted to a double from there. All other strings just have - * strtod called on them. - * - * Results: - * Sets 'value' to double value of string. - * Returns true if the string was a valid number, false o.w. - * - * Side Effects: - * Can change 'value' even if string is not a valid number. - * - * - *----------------------------------------------------------------------- - */ -static Boolean -CondCvtArg(str, value) - register char *str; - double *value; -{ - if ((*str == '0') && (str[1] == 'x')) { - register long i; - - for (str += 2, i = 0; *str; str++) { - int x; - if (isdigit((unsigned char) *str)) - x = *str - '0'; - else if (isxdigit((unsigned char) *str)) - x = 10 + *str - isupper((unsigned char) *str) ? 'A' : 'a'; - else - return FALSE; - i = (i << 4) + x; - } - *value = (double) i; - return TRUE; - } - else { - char *eptr; - *value = strtod(str, &eptr); - return *eptr == '\0'; - } -} - -/*- - *----------------------------------------------------------------------- - * CondToken -- - * Return the next token from the input. - * - * Results: - * A Token for the next lexical token in the stream. - * - * Side Effects: - * condPushback will be set back to None if it is used. - * - *----------------------------------------------------------------------- - */ -static Token -CondToken(doEval) - Boolean doEval; -{ - Token t; - - if (condPushBack == None) { - while (*condExpr == ' ' || *condExpr == '\t') { - condExpr++; - } - switch (*condExpr) { - case '(': - t = LParen; - condExpr++; - break; - case ')': - t = RParen; - condExpr++; - break; - case '|': - if (condExpr[1] == '|') { - condExpr++; - } - condExpr++; - t = Or; - break; - case '&': - if (condExpr[1] == '&') { - condExpr++; - } - condExpr++; - t = And; - break; - case '!': - t = Not; - condExpr++; - break; - case '\n': - case '\0': - t = EndOfFile; - break; - case '$': { - char *lhs; - char *rhs; - char *op; - int varSpecLen; - Boolean doFree; - - /* - * Parse the variable spec and skip over it, saving its - * value in lhs. - */ - t = Err; - lhs = Var_Parse(condExpr, VAR_CMD, doEval,&varSpecLen,&doFree); - if (lhs == var_Error) { - /* - * Even if !doEval, we still report syntax errors, which - * is what getting var_Error back with !doEval means. - */ - return(Err); - } - condExpr += varSpecLen; - - if (!isspace((unsigned char) *condExpr) && - strchr("!=><", *condExpr) == NULL) { - Buffer buf; - char *cp; - - buf = Buf_Init(0); - - for (cp = lhs; *cp; cp++) - Buf_AddByte(buf, (Byte)*cp); - - if (doFree) - free(lhs); - - for (;*condExpr && !isspace((unsigned char) *condExpr); - condExpr++) - Buf_AddByte(buf, (Byte)*condExpr); - - Buf_AddByte(buf, (Byte)'\0'); - lhs = (char *)Buf_GetAll(buf, &varSpecLen); - Buf_Destroy(buf, FALSE); - - doFree = TRUE; - } - - /* - * Skip whitespace to get to the operator - */ - while (isspace((unsigned char) *condExpr)) - condExpr++; - - /* - * Make sure the operator is a valid one. If it isn't a - * known relational operator, pretend we got a - * != 0 comparison. - */ - op = condExpr; - switch (*condExpr) { - case '!': - case '=': - case '<': - case '>': - if (condExpr[1] == '=') { - condExpr += 2; - } else { - condExpr += 1; - } - break; - default: - op = "!="; - rhs = "0"; - - goto do_compare; - } - while (isspace((unsigned char) *condExpr)) { - condExpr++; - } - if (*condExpr == '\0') { - Parse_Error(PARSE_WARNING, - "Missing right-hand-side of operator"); - goto error; - } - rhs = condExpr; -do_compare: - if (*rhs == '"') { - /* - * Doing a string comparison. Only allow == and != for - * operators. - */ - char *string; - char *cp, *cp2; - int qt; - Buffer buf; - -do_string_compare: - if (((*op != '!') && (*op != '=')) || (op[1] != '=')) { - Parse_Error(PARSE_WARNING, - "String comparison operator should be either == or !="); - goto error; - } - - buf = Buf_Init(0); - qt = *rhs == '"' ? 1 : 0; - - for (cp = &rhs[qt]; - ((qt && (*cp != '"')) || - (!qt && strchr(" \t)", *cp) == NULL)) && - (*cp != '\0'); cp++) { - if ((*cp == '\\') && (cp[1] != '\0')) { - /* - * Backslash escapes things -- skip over next - * character, if it exists. - */ - cp++; - Buf_AddByte(buf, (Byte)*cp); - } else if (*cp == '$') { - int len; - Boolean freeIt; - - cp2 = Var_Parse(cp, VAR_CMD, doEval,&len, &freeIt); - if (cp2 != var_Error) { - Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2); - if (freeIt) { - free(cp2); - } - cp += len - 1; - } else { - Buf_AddByte(buf, (Byte)*cp); - } - } else { - Buf_AddByte(buf, (Byte)*cp); - } - } - - Buf_AddByte(buf, (Byte)0); - - string = (char *)Buf_GetAll(buf, (int *)0); - Buf_Destroy(buf, FALSE); - - if (DEBUG(COND)) { - printf("lhs = \"%s\", rhs = \"%s\", op = %.2s\n", - lhs, string, op); - } - /* - * Null-terminate rhs and perform the comparison. - * t is set to the result. - */ - if (*op == '=') { - t = strcmp(lhs, string) ? False : True; - } else { - t = strcmp(lhs, string) ? True : False; - } - free(string); - if (rhs == condExpr) { - if (!qt && *cp == ')') - condExpr = cp; - else - condExpr = cp + 1; - } - } else { - /* - * rhs is either a float or an integer. Convert both the - * lhs and the rhs to a double and compare the two. - */ - double left, right; - char *string; - - if (!CondCvtArg(lhs, &left)) - goto do_string_compare; - if (*rhs == '$') { - int len; - Boolean freeIt; - - string = Var_Parse(rhs, VAR_CMD, doEval,&len,&freeIt); - if (string == var_Error) { - right = 0.0; - } else { - if (!CondCvtArg(string, &right)) { - if (freeIt) - free(string); - goto do_string_compare; - } - if (freeIt) - free(string); - if (rhs == condExpr) - condExpr += len; - } - } else { - if (!CondCvtArg(rhs, &right)) - goto do_string_compare; - if (rhs == condExpr) { - /* - * Skip over the right-hand side - */ - while(!isspace((unsigned char) *condExpr) && - (*condExpr != '\0')) { - condExpr++; - } - } - } - - if (DEBUG(COND)) { - printf("left = %f, right = %f, op = %.2s\n", left, - right, op); - } - switch(op[0]) { - case '!': - if (op[1] != '=') { - Parse_Error(PARSE_WARNING, - "Unknown operator"); - goto error; - } - t = (left != right ? True : False); - break; - case '=': - if (op[1] != '=') { - Parse_Error(PARSE_WARNING, - "Unknown operator"); - goto error; - } - t = (left == right ? True : False); - break; - case '<': - if (op[1] == '=') { - t = (left <= right ? True : False); - } else { - t = (left < right ? True : False); - } - break; - case '>': - if (op[1] == '=') { - t = (left >= right ? True : False); - } else { - t = (left > right ? True : False); - } - break; - } - } -error: - if (doFree) - free(lhs); - break; - } - default: { - Boolean (*evalProc) __P((int, char *)); - Boolean invert = FALSE; - char *arg; - int arglen; - - if (strncmp (condExpr, "defined", 7) == 0) { - /* - * Use CondDoDefined to evaluate the argument and - * CondGetArg to extract the argument from the 'function - * call'. - */ - evalProc = CondDoDefined; - condExpr += 7; - arglen = CondGetArg (&condExpr, &arg, "defined", TRUE); - if (arglen == 0) { - condExpr -= 7; - goto use_default; - } - } else if (strncmp (condExpr, "make", 4) == 0) { - /* - * Use CondDoMake to evaluate the argument and - * CondGetArg to extract the argument from the 'function - * call'. - */ - evalProc = CondDoMake; - condExpr += 4; - arglen = CondGetArg (&condExpr, &arg, "make", TRUE); - if (arglen == 0) { - condExpr -= 4; - goto use_default; - } - } else if (strncmp (condExpr, "exists", 6) == 0) { - /* - * Use CondDoExists to evaluate the argument and - * CondGetArg to extract the argument from the - * 'function call'. - */ - evalProc = CondDoExists; - condExpr += 6; - arglen = CondGetArg(&condExpr, &arg, "exists", TRUE); - if (arglen == 0) { - condExpr -= 6; - goto use_default; - } - } else if (strncmp(condExpr, "empty", 5) == 0) { - /* - * Use Var_Parse to parse the spec in parens and return - * True if the resulting string is empty. - */ - int length; - Boolean doFree; - char *val; - - condExpr += 5; - - for (arglen = 0; - condExpr[arglen] != '(' && condExpr[arglen] != '\0'; - arglen += 1) - continue; - - if (condExpr[arglen] != '\0') { - val = Var_Parse(&condExpr[arglen - 1], VAR_CMD, - doEval, &length, &doFree); - if (val == var_Error) { - t = Err; - } else { - /* - * A variable is empty when it just contains - * spaces... 4/15/92, christos - */ - char *p; - for (p = val; *p && isspace((unsigned char)*p); p++) - continue; - t = (*p == '\0') ? True : False; - } - if (doFree) { - free(val); - } - /* - * Advance condExpr to beyond the closing ). Note that - * we subtract one from arglen + length b/c length - * is calculated from condExpr[arglen - 1]. - */ - condExpr += arglen + length - 1; - } else { - condExpr -= 5; - goto use_default; - } - break; - } else if (strncmp (condExpr, "target", 6) == 0) { - /* - * Use CondDoTarget to evaluate the argument and - * CondGetArg to extract the argument from the - * 'function call'. - */ - evalProc = CondDoTarget; - condExpr += 6; - arglen = CondGetArg(&condExpr, &arg, "target", TRUE); - if (arglen == 0) { - condExpr -= 6; - goto use_default; - } - } else if (strncmp (condExpr, "commands", 8) == 0) { - /* - * Use CondDoCommands to evaluate the argument and - * CondGetArg to extract the argument from the - * 'function call'. - */ - evalProc = CondDoCommands; - condExpr += 8; - arglen = CondGetArg(&condExpr, &arg, "commands", TRUE); - if (arglen == 0) { - condExpr -= 8; - goto use_default; - } - } else { - /* - * The symbol is itself the argument to the default - * function. We advance condExpr to the end of the symbol - * by hand (the next whitespace, closing paren or - * binary operator) and set to invert the evaluation - * function if condInvert is TRUE. - */ - use_default: - invert = condInvert; - evalProc = condDefProc; - arglen = CondGetArg(&condExpr, &arg, "", FALSE); - } - - /* - * Evaluate the argument using the set function. If invert - * is TRUE, we invert the sense of the function. - */ - t = (!doEval || (* evalProc) (arglen, arg) ? - (invert ? False : True) : - (invert ? True : False)); - free(arg); - break; - } - } - } else { - t = condPushBack; - condPushBack = None; - } - return (t); -} - -/*- - *----------------------------------------------------------------------- - * CondT -- - * Parse a single term in the expression. This consists of a terminal - * symbol or Not and a terminal symbol (not including the binary - * operators): - * T -> defined(variable) | make(target) | exists(file) | symbol - * T -> ! T | ( E ) - * - * Results: - * True, False or Err. - * - * Side Effects: - * Tokens are consumed. - * - *----------------------------------------------------------------------- - */ -static Token -CondT(doEval) - Boolean doEval; -{ - Token t; - - t = CondToken(doEval); - - if (t == EndOfFile) { - /* - * If we reached the end of the expression, the expression - * is malformed... - */ - t = Err; - } else if (t == LParen) { - /* - * T -> ( E ) - */ - t = CondE(doEval); - if (t != Err) { - if (CondToken(doEval) != RParen) { - t = Err; - } - } - } else if (t == Not) { - t = CondT(doEval); - if (t == True) { - t = False; - } else if (t == False) { - t = True; - } - } - return (t); -} - -/*- - *----------------------------------------------------------------------- - * CondF -- - * Parse a conjunctive factor (nice name, wot?) - * F -> T && F | T - * - * Results: - * True, False or Err - * - * Side Effects: - * Tokens are consumed. - * - *----------------------------------------------------------------------- - */ -static Token -CondF(doEval) - Boolean doEval; -{ - Token l, o; - - l = CondT(doEval); - if (l != Err) { - o = CondToken(doEval); - - if (o == And) { - /* - * F -> T && F - * - * If T is False, the whole thing will be False, but we have to - * parse the r.h.s. anyway (to throw it away). - * If T is True, the result is the r.h.s., be it an Err or no. - */ - if (l == True) { - l = CondF(doEval); - } else { - (void) CondF(FALSE); - } - } else { - /* - * F -> T - */ - CondPushBack (o); - } - } - return (l); -} - -/*- - *----------------------------------------------------------------------- - * CondE -- - * Main expression production. - * E -> F || E | F - * - * Results: - * True, False or Err. - * - * Side Effects: - * Tokens are, of course, consumed. - * - *----------------------------------------------------------------------- - */ -static Token -CondE(doEval) - Boolean doEval; -{ - Token l, o; - - l = CondF(doEval); - if (l != Err) { - o = CondToken(doEval); - - if (o == Or) { - /* - * E -> F || E - * - * A similar thing occurs for ||, except that here we make sure - * the l.h.s. is False before we bother to evaluate the r.h.s. - * Once again, if l is False, the result is the r.h.s. and once - * again if l is True, we parse the r.h.s. to throw it away. - */ - if (l == False) { - l = CondE(doEval); - } else { - (void) CondE(FALSE); - } - } else { - /* - * E -> F - */ - CondPushBack (o); - } - } - return (l); -} - -/*- - *----------------------------------------------------------------------- - * Cond_EvalExpression -- - * Evaluate an expression in the passed line. The expression - * consists of &&, ||, !, make(target), defined(variable) - * and parenthetical groupings thereof. - * - * Results: - * COND_PARSE if the condition was valid grammatically - * COND_INVALID if not a valid conditional. - * - * (*value) is set to the boolean value of the condition - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -Cond_EvalExpression(dosetup, line, value, eprint) - int dosetup; - char *line; - Boolean *value; - int eprint; -{ - if (dosetup) { - condDefProc = CondDoDefined; - condInvert = 0; - } - - while (*line == ' ' || *line == '\t') - line++; - - condExpr = line; - condPushBack = None; - - switch (CondE(TRUE)) { - case True: - if (CondToken(TRUE) == EndOfFile) { - *value = TRUE; - break; - } - goto err; - /*FALLTHRU*/ - case False: - if (CondToken(TRUE) == EndOfFile) { - *value = FALSE; - break; - } - /*FALLTHRU*/ - case Err: -err: - if (eprint) - Parse_Error (PARSE_FATAL, "Malformed conditional (%s)", - line); - return (COND_INVALID); - default: - break; - } - - return COND_PARSE; -} - - -/*- - *----------------------------------------------------------------------- - * Cond_Eval -- - * Evaluate the conditional in the passed line. The line - * looks like this: - * # - * where is any of if, ifmake, ifnmake, ifdef, - * ifndef, elif, elifmake, elifnmake, elifdef, elifndef - * and consists of &&, ||, !, make(target), defined(variable) - * and parenthetical groupings thereof. - * - * Results: - * COND_PARSE if should parse lines after the conditional - * COND_SKIP if should skip lines after the conditional - * COND_INVALID if not a valid conditional. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -Cond_Eval (line) - char *line; /* Line to parse */ -{ - struct If *ifp; - Boolean isElse; - Boolean value = FALSE; - int level; /* Level at which to report errors. */ - - level = PARSE_FATAL; - - for (line++; *line == ' ' || *line == '\t'; line++) { - continue; - } - - /* - * Find what type of if we're dealing with. The result is left - * in ifp and isElse is set TRUE if it's an elif line. - */ - if (line[0] == 'e' && line[1] == 'l') { - line += 2; - isElse = TRUE; - } else if (strncmp (line, "endif", 5) == 0) { - /* - * End of a conditional section. If skipIfLevel is non-zero, that - * conditional was skipped, so lines following it should also be - * skipped. Hence, we return COND_SKIP. Otherwise, the conditional - * was read so succeeding lines should be parsed (think about it...) - * so we return COND_PARSE, unless this endif isn't paired with - * a decent if. - */ - if (skipIfLevel != 0) { - skipIfLevel -= 1; - return (COND_SKIP); - } else { - if (condTop == MAXIF) { - Parse_Error (level, "if-less endif"); - return (COND_INVALID); - } else { - skipLine = FALSE; - condTop += 1; - return (COND_PARSE); - } - } - } else { - isElse = FALSE; - } - - /* - * Figure out what sort of conditional it is -- what its default - * function is, etc. -- by looking in the table of valid "ifs" - */ - for (ifp = ifs; ifp->form != (char *)0; ifp++) { - if (strncmp (ifp->form, line, ifp->formlen) == 0) { - break; - } - } - - if (ifp->form == (char *) 0) { - /* - * Nothing fit. If the first word on the line is actually - * "else", it's a valid conditional whose value is the inverse - * of the previous if we parsed. - */ - if (isElse && (line[0] == 's') && (line[1] == 'e')) { - if (condTop == MAXIF) { - Parse_Error (level, "if-less else"); - return (COND_INVALID); - } else if (skipIfLevel == 0) { - value = !condStack[condTop]; - } else { - return (COND_SKIP); - } - } else { - /* - * Not a valid conditional type. No error... - */ - return (COND_INVALID); - } - } else { - if (isElse) { - if (condTop == MAXIF) { - Parse_Error (level, "if-less elif"); - return (COND_INVALID); - } else if (skipIfLevel != 0) { - /* - * If skipping this conditional, just ignore the whole thing. - * If we don't, the user might be employing a variable that's - * undefined, for which there's an enclosing ifdef that - * we're skipping... - */ - return(COND_SKIP); - } - } else if (skipLine) { - /* - * Don't even try to evaluate a conditional that's not an else if - * we're skipping things... - */ - skipIfLevel += 1; - return(COND_SKIP); - } - - /* - * Initialize file-global variables for parsing - */ - condDefProc = ifp->defProc; - condInvert = ifp->doNot; - - line += ifp->formlen; - if (Cond_EvalExpression(0, line, &value, 1) == COND_INVALID) - return COND_INVALID; - } - if (!isElse) { - condTop -= 1; - } else if ((skipIfLevel != 0) || condStack[condTop]) { - /* - * If this is an else-type conditional, it should only take effect - * if its corresponding if was evaluated and FALSE. If its if was - * TRUE or skipped, we return COND_SKIP (and start skipping in case - * we weren't already), leaving the stack unmolested so later elif's - * don't screw up... - */ - skipLine = TRUE; - return (COND_SKIP); - } - - if (condTop < 0) { - /* - * This is the one case where we can definitely proclaim a fatal - * error. If we don't, we're hosed. - */ - Parse_Error (PARSE_FATAL, "Too many nested if's. %d max.", MAXIF); - return (COND_INVALID); - } else { - condStack[condTop] = value; - skipLine = !value; - return (value ? COND_PARSE : COND_SKIP); - } -} - - - -/*- - *----------------------------------------------------------------------- - * Cond_End -- - * Make sure everything's clean at the end of a makefile. - * - * Results: - * None. - * - * Side Effects: - * Parse_Error will be called if open conditionals are around. - * - *----------------------------------------------------------------------- - */ -void -Cond_End() -{ - if (condTop != MAXIF) { - Parse_Error(PARSE_FATAL, "%d open conditional%s", MAXIF-condTop, - MAXIF-condTop == 1 ? "" : "s"); - } - condTop = MAXIF; -} diff --git a/bootstrap/bmake/config.h.in b/bootstrap/bmake/config.h.in deleted file mode 100644 index cf322768617..00000000000 --- a/bootstrap/bmake/config.h.in +++ /dev/null @@ -1,182 +0,0 @@ -/* config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -#undef _ALL_SOURCE -#endif - -/* Define to empty if the keyword does not work. */ -#undef const - -/* Define if you don't have vprintf but do have _doprnt. */ -#undef HAVE_DOPRNT - -/* Define if your struct stat has st_rdev. */ -#undef HAVE_ST_RDEV - -/* Define if you have that is POSIX.1 compatible. */ -#undef HAVE_SYS_WAIT_H - -/* Define if you have . */ -#undef HAVE_VFORK_H - -/* Define if you have the vprintf function. */ -#undef HAVE_VPRINTF - -/* Define if you have the wait3 system call. */ -#undef HAVE_WAIT3 - -/* Define if on MINIX. */ -#undef _MINIX - -/* Define to `long' if doesn't define. */ -#undef off_t - -/* Define to `int' if doesn't define. */ -#undef pid_t - -/* Define if the system does not provide POSIX.1 features except - with this defined. */ -#undef _POSIX_1_SOURCE - -/* Define if you need to in order for stat and other things to work. */ -#undef _POSIX_SOURCE - -/* Define as the return type of signal handlers (int or void). */ -#undef RETSIGTYPE - -/* Define to `unsigned' if doesn't define. */ -#undef size_t - -/* Define if the `S_IS*' macros in do not work properly. */ -#undef STAT_MACROS_BROKEN - -/* Define if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define if `sys_siglist' is declared by . */ -#undef SYS_SIGLIST_DECLARED - -/* Define if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Define if your declares struct tm. */ -#undef TM_IN_SYS_TIME - -/* Define vfork as fork if vfork does not work. */ -#undef vfork - -/* Define if your processor stores words with the most significant - byte first (like Motorola and SPARC, unlike Intel and VAX). */ -#undef WORDS_BIGENDIAN - -/* Define if you have the getcwd function. */ -#undef HAVE_GETCWD - -/* Define if you have the getenv function. */ -#undef HAVE_GETENV - -/* Define if you have the getopt function. */ -#undef HAVE_GETOPT - -/* Define if you have the getwd function. */ -#undef HAVE_GETWD - -/* Define if you have the putenv function. */ -#undef HAVE_PUTENV - -/* Define if you have the select function. */ -#undef HAVE_SELECT - -/* Define if you have the setenv function. */ -#undef HAVE_SETENV - -/* Define if you have the sigaction function. */ -#undef HAVE_SIGACTION - -/* Define if you have the sigvec function. */ -#undef HAVE_SIGVEC - -/* Define if you have the snprintf function. */ -#undef HAVE_SNPRINTF - -/* Define if you have the strdup function. */ -#undef HAVE_STRDUP - -/* Define if you have the strerror function. */ -#undef HAVE_STRERROR - -/* Define if you have the strftime function. */ -#undef HAVE_STRFTIME - -/* Define if you have the strtod function. */ -#undef HAVE_STRTOD - -/* Define if you have the strtol function. */ -#undef HAVE_STRTOL - -/* Define if you have the vsnprintf function. */ -#undef HAVE_VSNPRINTF - -/* Define if you have the wait3 function. */ -#undef HAVE_WAIT3 - -/* Define if you have the wait4 function. */ -#undef HAVE_WAIT4 - -/* Define if you have the waitpid function. */ -#undef HAVE_WAITPID - -/* Define if you have the header file. */ -#undef HAVE_AR_H - -/* Define if you have the header file. */ -#undef HAVE_DIRENT_H - -/* Define if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define if you have the header file. */ -#undef HAVE_NDIR_H - -/* Define if you have the header file. */ -#undef HAVE_PATHS_H - -/* Define if you have the header file. */ -#undef HAVE_POLL_H - -/* Define if you have the header file. */ -#undef HAVE_RANLIB_H - -/* Define if you have the header file. */ -#undef HAVE_STRING_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_DIR_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_NDIR_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_TIME_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_UIO_H - -/* Define if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define if you have the header file. */ -#undef HAVE_UTIME_H - -/* Define if your compiler has __attribute__ */ -#undef HAVE___ATTRIBUTE__ - -#ifndef HAVE___ATTRIBUTE__ -# define __attribute__(x) -#endif diff --git a/bootstrap/bmake/configure b/bootstrap/bmake/configure deleted file mode 100755 index df76015317f..00000000000 --- a/bootstrap/bmake/configure +++ /dev/null @@ -1,2966 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.13 -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_help="$ac_help - --with-machine=MACHINE explicitly set MACHINE" -ac_help="$ac_help - --with-force-machine=MACHINE set FORCE_MACHINE" -ac_help="$ac_help - --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH" -ac_help="$ac_help - --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH" -ac_help="$ac_help - --with-prefix-sys-path=PATH:DIR:LIST prefix _PATH_PREFIX_SYSPATH" -ac_help="$ac_help - --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX" -ac_help="$ac_help - --disable-pwd-override disable \$PWD overriding getcwd()" -ac_help="$ac_help - --disable-check-make-chdir disable make trying to guess - when it should automatically cd \${.CURDIR}" - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} -# Maximum number of lines to put in a shell here document. -ac_max_here_lines=12 - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.13" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set these to C if already set. These must not be set unconditionally -# because not all systems understand e.g. LANG=C (notably SCO). -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! -# Non-C LC_CTYPE values break the ctype check. -if test "${LANG+set}" = set; then LANG=C; export LANG; fi -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=makefile.boot.in - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -ac_exeext= -ac_objext=o -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - - - -# Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:547: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:577: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_prog_rejected=no - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - if test -z "$CC"; then - case "`uname -s`" in - *win32* | *WIN32*) - # Extract the first word of "cl", so it can be a program name with args. -set dummy cl; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:628: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="cl" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - ;; - esac - fi - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:660: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -cat > conftest.$ac_ext << EOF - -#line 671 "configure" -#include "confdefs.h" - -main(){return(0);} -EOF -if { (eval echo configure:676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cc_cross=no - else - ac_cv_prog_cc_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cc_works=no -fi -rm -fr conftest* -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 -if test $ac_cv_prog_cc_works = no; then - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:702: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 -cross_compiling=$ac_cv_prog_cc_cross - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:707: checking whether we are using GNU C" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 - -if test $ac_cv_prog_gcc = yes; then - GCC=yes -else - GCC= -fi - -ac_test_CFLAGS="${CFLAGS+set}" -ac_save_CFLAGS="$CFLAGS" -CFLAGS= -echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:735: checking whether ${CC-cc} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_cc_g=yes -else - ac_cv_prog_cc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi - -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:767: checking how to run the C preprocessor" >&5 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # This must be in double quotes, not single quotes, because CPP may get - # substituted into the Makefile and "${CC-cc}" will confuse make. - CPP="${CC-cc} -E" - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:788: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:805: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -nologo -E" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:822: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - -if test $ac_cv_prog_gcc = yes; then - echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 -echo "configure:848: checking whether ${CC-cc} needs -traditional" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_pattern="Autoconf.*'x'" - cat > conftest.$ac_ext < -Autoconf TIOCGETP -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "$ac_pattern" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_prog_gcc_traditional=yes -else - rm -rf conftest* - ac_cv_prog_gcc_traditional=no -fi -rm -f conftest* - - - if test $ac_cv_prog_gcc_traditional = no; then - cat > conftest.$ac_ext < -Autoconf TCGETA -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "$ac_pattern" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_prog_gcc_traditional=yes -fi -rm -f conftest* - - fi -fi - -echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6 - if test $ac_cv_prog_gcc_traditional = yes; then - CC="$CC -traditional" - fi -fi - -ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:924: checking for a BSD compatible install" >&5 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_IFS" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -echo $ac_n "checking for AIX""... $ac_c" 1>&6 -echo "configure:977: checking for AIX" >&5 -cat > conftest.$ac_ext <&5 | - egrep "yes" >/dev/null 2>&1; then - rm -rf conftest* - echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF -#define _ALL_SOURCE 1 -EOF - -else - rm -rf conftest* - echo "$ac_t""no" 1>&6 -fi -rm -f conftest* - - -ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6 -echo "configure:1002: checking for minix/config.h" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1012: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - MINIX=yes -else - echo "$ac_t""no" 1>&6 -MINIX= -fi - -if test "$MINIX" = yes; then - cat >> confdefs.h <<\EOF -#define _POSIX_SOURCE 1 -EOF - - cat >> confdefs.h <<\EOF -#define _POSIX_1_SOURCE 2 -EOF - - cat >> confdefs.h <<\EOF -#define _MINIX 1 -EOF - -fi - -echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 -echo "configure:1050: checking for POSIXized ISC" >&5 -if test -d /etc/conf/kconfig.d && - grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 -then - echo "$ac_t""yes" 1>&6 - ISC=yes # If later tests want to check for ISC. - cat >> confdefs.h <<\EOF -#define _POSIX_SOURCE 1 -EOF - - if test "$GCC" = yes; then - CC="$CC -posix" - else - CC="$CC -Xp" - fi -else - echo "$ac_t""no" 1>&6 - ISC= -fi - - - -echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1073: checking for ANSI C header files" >&5 -if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -#include -#include -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1086: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - ac_cv_header_stdc=yes -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. -cat > conftest.$ac_ext < -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "memchr" >/dev/null 2>&1; then - : -else - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. -cat > conftest.$ac_ext < -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "free" >/dev/null 2>&1; then - : -else - rm -rf conftest* - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. -if test "$cross_compiling" = yes; then - : -else - cat > conftest.$ac_ext < -#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int main () { int i; for (i = 0; i < 256; i++) -if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); -exit (0); } - -EOF -if { (eval echo configure:1153: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - : -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_header_stdc=no -fi -rm -fr conftest* -fi - -fi -fi - -echo "$ac_t""$ac_cv_header_stdc" 1>&6 -if test $ac_cv_header_stdc = yes; then - cat >> confdefs.h <<\EOF -#define STDC_HEADERS 1 -EOF - -fi - -echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 -echo "configure:1177: checking for sys/wait.h that is POSIX.1 compatible" >&5 -if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -#ifndef WEXITSTATUS -#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -#endif -#ifndef WIFEXITED -#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif -int main() { -int s; -wait (&s); -s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; -; return 0; } -EOF -if { (eval echo configure:1198: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_header_sys_wait_h=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_header_sys_wait_h=no -fi -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 -if test $ac_cv_header_sys_wait_h = yes; then - cat >> confdefs.h <<\EOF -#define HAVE_SYS_WAIT_H 1 -EOF - -fi - -ac_header_dirent=no -for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:1223: checking for $ac_hdr that defines DIR" >&5 -if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include <$ac_hdr> -int main() { -DIR *dirp = 0; -; return 0; } -EOF -if { (eval echo configure:1236: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - eval "ac_cv_header_dirent_$ac_safe=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_dirent_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <&6 -fi -done -# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. -if test $ac_header_dirent = dirent.h; then -echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:1261: checking for opendir in -ldir" >&5 -ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldir $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - LIBS="$LIBS -ldir" -else - echo "$ac_t""no" 1>&6 -fi - -else -echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:1302: checking for opendir in -lx" >&5 -ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lx $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - LIBS="$LIBS -lx" -else - echo "$ac_t""no" 1>&6 -fi - -fi - -for ac_hdr in ar.h ranlib.h fcntl.h paths.h sys/select.h sys/time.h unistd.h string.h utime.h poll.h sys/uio.h -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1347: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1357: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <&6 -fi -done - - -ac_safe=`echo "sys/cdefs.h" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for sys/cdefs.h""... $ac_c" 1>&6 -echo "configure:1386: checking for sys/cdefs.h" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1396: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - echo $ac_n "checking whether sys/cdefs.h is compatible... $ac_c" 2>&6 -cat > conftest.$ac_ext < -#ifdef __RCSID -yes -#endif - -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "yes" >/dev/null 2>&1; then - rm -rf conftest* - echo yes 2>&6 -else - rm -rf conftest* - echo no 2>&6; CPPFLAGS="${CPPFLAGS} -I\${srcdir}/missing -DNEED_HOST_CDEFS_H" -fi -rm -f conftest* - -else - echo "$ac_t""no" 1>&6 -CPPFLAGS="${CPPFLAGS} -I\${srcdir}/missing" -fi - - - -echo $ac_n "checking for __attribute__""... $ac_c" 1>&6 -echo "configure:1440: checking for __attribute__" >&5 -if eval "test \"`echo '$''{'ac_cv___attribute__'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - -cat > conftest.$ac_ext < - -int main() { - -static void foo(void) __attribute__ ((noreturn)); - -static void -foo(void) -{ - exit(1); -} - -; return 0; } -EOF -if { (eval echo configure:1463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv___attribute__=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv___attribute__=no -fi -rm -f conftest* -fi - -if test "$ac_cv___attribute__" = "yes"; then - cat >> confdefs.h <<\EOF -#define HAVE___ATTRIBUTE__ 1 -EOF - -fi -echo "$ac_t""$ac_cv___attribute__" 1>&6 - -echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 -echo "configure:1484: checking whether byte ordering is bigendian" >&5 -if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_cv_c_bigendian=unknown -# See if sys/param.h defines the BYTE_ORDER macro. -cat > conftest.$ac_ext < -#include -int main() { - -#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN - bogus endian macros -#endif -; return 0; } -EOF -if { (eval echo configure:1502: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - # It does; now see whether it defined to BIG_ENDIAN or not. -cat > conftest.$ac_ext < -#include -int main() { - -#if BYTE_ORDER != BIG_ENDIAN - not big endian -#endif -; return 0; } -EOF -if { (eval echo configure:1517: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_c_bigendian=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_c_bigendian=no -fi -rm -f conftest* -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 -fi -rm -f conftest* -if test $ac_cv_c_bigendian = unknown; then -if test "$cross_compiling" = yes; then - { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } -else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - ac_cv_c_bigendian=no -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_c_bigendian=yes -fi -rm -fr conftest* -fi - -fi -fi - -echo "$ac_t""$ac_cv_c_bigendian" 1>&6 -if test $ac_cv_c_bigendian = yes; then - cat >> confdefs.h <<\EOF -#define WORDS_BIGENDIAN 1 -EOF - -fi - -echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:1574: checking for working const" >&5 -if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <j = 5; -} -{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; -} - -; return 0; } -EOF -if { (eval echo configure:1628: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_c_const=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_c_const=no -fi -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_c_const" 1>&6 -if test $ac_cv_c_const = no; then - cat >> confdefs.h <<\EOF -#define const -EOF - -fi - -echo $ac_n "checking for off_t""... $ac_c" 1>&6 -echo "configure:1649: checking for off_t" >&5 -if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#if STDC_HEADERS -#include -#include -#endif -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_type_off_t=yes -else - rm -rf conftest* - ac_cv_type_off_t=no -fi -rm -f conftest* - -fi -echo "$ac_t""$ac_cv_type_off_t" 1>&6 -if test $ac_cv_type_off_t = no; then - cat >> confdefs.h <<\EOF -#define off_t long -EOF - -fi - -echo $ac_n "checking for pid_t""... $ac_c" 1>&6 -echo "configure:1682: checking for pid_t" >&5 -if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#if STDC_HEADERS -#include -#include -#endif -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_type_pid_t=yes -else - rm -rf conftest* - ac_cv_type_pid_t=no -fi -rm -f conftest* - -fi -echo "$ac_t""$ac_cv_type_pid_t" 1>&6 -if test $ac_cv_type_pid_t = no; then - cat >> confdefs.h <<\EOF -#define pid_t int -EOF - -fi - -echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:1715: checking for size_t" >&5 -if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#if STDC_HEADERS -#include -#include -#endif -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_type_size_t=yes -else - rm -rf conftest* - ac_cv_type_size_t=no -fi -rm -f conftest* - -fi -echo "$ac_t""$ac_cv_type_size_t" 1>&6 -if test $ac_cv_type_size_t = no; then - cat >> confdefs.h <<\EOF -#define size_t unsigned -EOF - -fi - -echo $ac_n "checking for sys_siglist declaration in signal.h or unistd.h""... $ac_c" 1>&6 -echo "configure:1748: checking for sys_siglist declaration in signal.h or unistd.h" >&5 -if eval "test \"`echo '$''{'ac_cv_decl_sys_siglist'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -/* NetBSD declares sys_siglist in unistd.h. */ -#ifdef HAVE_UNISTD_H -#include -#endif -int main() { -char *msg = *(sys_siglist + 1); -; return 0; } -EOF -if { (eval echo configure:1765: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_decl_sys_siglist=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_decl_sys_siglist=no -fi -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_decl_sys_siglist" 1>&6 -if test $ac_cv_decl_sys_siglist = yes; then - cat >> confdefs.h <<\EOF -#define SYS_SIGLIST_DECLARED 1 -EOF - -fi - -echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:1786: checking whether time.h and sys/time.h may both be included" >&5 -if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -#include -int main() { -struct tm *tp; -; return 0; } -EOF -if { (eval echo configure:1800: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_header_time=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_header_time=no -fi -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_header_time" 1>&6 -if test $ac_cv_header_time = yes; then - cat >> confdefs.h <<\EOF -#define TIME_WITH_SYS_TIME 1 -EOF - -fi - -echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 -echo "configure:1821: checking whether struct tm is in sys/time.h or time.h" >&5 -if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -int main() { -struct tm *tp; tp->tm_sec; -; return 0; } -EOF -if { (eval echo configure:1834: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_struct_tm=time.h -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_struct_tm=sys/time.h -fi -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_struct_tm" 1>&6 -if test $ac_cv_struct_tm = sys/time.h; then - cat >> confdefs.h <<\EOF -#define TM_IN_SYS_TIME 1 -EOF - -fi - - -echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:1856: checking return type of signal handlers" >&5 -if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -#ifdef signal -#undef signal -#endif -#ifdef __cplusplus -extern "C" void (*signal (int, void (*)(int)))(int); -#else -void (*signal ()) (); -#endif - -int main() { -int i; -; return 0; } -EOF -if { (eval echo configure:1878: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_type_signal=void -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_type_signal=int -fi -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_type_signal" 1>&6 -cat >> confdefs.h <&6 -echo "configure:1898: checking for vfork.h" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define HAVE_VFORK_H 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi - -echo $ac_n "checking for working vfork""... $ac_c" 1>&6 -echo "configure:1933: checking for working vfork" >&5 -if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - echo $ac_n "checking for vfork""... $ac_c" 1>&6 -echo "configure:1939: checking for vfork" >&5 -if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char vfork(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_vfork) || defined (__stub___vfork) -choke me -#else -vfork(); -#endif - -; return 0; } -EOF -if { (eval echo configure:1967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_vfork=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_vfork=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then - echo "$ac_t""yes" 1>&6 - : -else - echo "$ac_t""no" 1>&6 -fi - -ac_cv_func_vfork_works=$ac_cv_func_vfork -else - cat > conftest.$ac_ext < -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#ifdef HAVE_VFORK_H -#include -#endif -/* On some sparc systems, changes by the child to local and incoming - argument registers are propagated back to the parent. - The compiler is told about this with #include , - but some compilers (e.g. gcc -O) don't grok . - Test for this by using a static variable whose address - is put into a register that is clobbered by the vfork. */ -static -#ifdef __cplusplus -sparc_address_test (int arg) -#else -sparc_address_test (arg) int arg; -#endif -{ - static pid_t child; - if (!child) { - child = vfork (); - if (child < 0) { - perror ("vfork"); - _exit(2); - } - if (!child) { - arg = getpid(); - write(-1, "", 0); - _exit (arg); - } - } -} -main() { - pid_t parent = getpid (); - pid_t child; - - sparc_address_test (); - - child = vfork (); - - if (child == 0) { - /* Here is another test for sparc vfork register problems. - This test uses lots of local variables, at least - as many local variables as main has allocated so far - including compiler temporaries. 4 locals are enough for - gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe. - A buggy compiler should reuse the register of parent - for one of the local variables, since it will think that - parent can't possibly be used any more in this routine. - Assigning to the local variable will thus munge parent - in the parent process. */ - pid_t - p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), - p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); - /* Convince the compiler that p..p7 are live; otherwise, it might - use the same hardware register for all 8 local variables. */ - if (p != p1 || p != p2 || p != p3 || p != p4 - || p != p5 || p != p6 || p != p7) - _exit(1); - - /* On some systems (e.g. IRIX 3.3), - vfork doesn't separate parent from child file descriptors. - If the child closes a descriptor before it execs or exits, - this munges the parent's descriptor as well. - Test for this by closing stdout in the child. */ - _exit(close(fileno(stdout)) != 0); - } else { - int status; - struct stat st; - - while (wait(&status) != child) - ; - exit( - /* Was there some problem with vforking? */ - child < 0 - - /* Did the child fail? (This shouldn't happen.) */ - || status - - /* Did the vfork/compiler bug occur? */ - || parent != getpid() - - /* Did the file descriptor bug occur? */ - || fstat(fileno(stdout), &st) != 0 - ); - } -} -EOF -if { (eval echo configure:2084: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - ac_cv_func_vfork_works=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_func_vfork_works=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$ac_cv_func_vfork_works" 1>&6 -if test $ac_cv_func_vfork_works = no; then - cat >> confdefs.h <<\EOF -#define vfork fork -EOF - -fi - -echo $ac_n "checking for vprintf""... $ac_c" 1>&6 -echo "configure:2107: checking for vprintf" >&5 -if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char vprintf(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_vprintf) || defined (__stub___vprintf) -choke me -#else -vprintf(); -#endif - -; return 0; } -EOF -if { (eval echo configure:2135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_vprintf=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_vprintf=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define HAVE_VPRINTF 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi - -if test "$ac_cv_func_vprintf" != yes; then -echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 -echo "configure:2159: checking for _doprnt" >&5 -if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char _doprnt(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub__doprnt) || defined (__stub____doprnt) -choke me -#else -_doprnt(); -#endif - -; return 0; } -EOF -if { (eval echo configure:2187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func__doprnt=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func__doprnt=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF -#define HAVE_DOPRNT 1 -EOF - -else - echo "$ac_t""no" 1>&6 -fi - -fi - -echo $ac_n "checking for wait3 that fills in rusage""... $ac_c" 1>&6 -echo "configure:2212: checking for wait3 that fills in rusage" >&5 -if eval "test \"`echo '$''{'ac_cv_func_wait3_rusage'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_wait3_rusage=no -else - cat > conftest.$ac_ext < -#include -#include -#include -/* HP-UX has wait3 but does not fill in rusage at all. */ -main() { - struct rusage r; - int i; - /* Use a field that we can force nonzero -- - voluntary context switches. - For systems like NeXT and OSF/1 that don't set it, - also use the system CPU time. And page faults (I/O) for Linux. */ - r.ru_nvcsw = 0; - r.ru_stime.tv_sec = 0; - r.ru_stime.tv_usec = 0; - r.ru_majflt = r.ru_minflt = 0; - switch (fork()) { - case 0: /* Child. */ - sleep(1); /* Give up the CPU. */ - _exit(0); - case -1: _exit(0); /* What can we do? */ - default: /* Parent. */ - wait3(&i, 0, &r); - sleep(2); /* Avoid "text file busy" from rm on fast HP-UX machines. */ - exit(r.ru_nvcsw == 0 && r.ru_majflt == 0 && r.ru_minflt == 0 - && r.ru_stime.tv_sec == 0 && r.ru_stime.tv_usec == 0); - } -} -EOF -if { (eval echo configure:2251: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - ac_cv_func_wait3_rusage=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_func_wait3_rusage=no -fi -rm -fr conftest* -fi - -fi - -echo "$ac_t""$ac_cv_func_wait3_rusage" 1>&6 -if test $ac_cv_func_wait3_rusage = yes; then - cat >> confdefs.h <<\EOF -#define HAVE_WAIT3 1 -EOF - -fi - -for ac_func in getcwd getwd getopt putenv select strdup strerror strtod strtol setenv getenv vsnprintf snprintf strftime sigaction sigvec waitpid wait4 wait3 -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2276: checking for $ac_func" >&5 -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -$ac_func(); -#endif - -; return 0; } -EOF -if { (eval echo configure:2304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_$ac_func=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <&6 -fi -done - -for ac_func in getenv -do -echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2331: checking for $ac_func" >&5 -if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -$ac_func(); -#endif - -; return 0; } -EOF -if { (eval echo configure:2359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_$ac_func=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_$ac_func=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <&6 -LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}" -fi -done - - -echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6 -echo "configure:2386: checking whether stat file-mode macros are broken" >&5 -if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include - -#if defined(S_ISBLK) && defined(S_IFDIR) -# if S_ISBLK (S_IFDIR) -You lose. -# endif -#endif - -#if defined(S_ISBLK) && defined(S_IFCHR) -# if S_ISBLK (S_IFCHR) -You lose. -# endif -#endif - -#if defined(S_ISLNK) && defined(S_IFREG) -# if S_ISLNK (S_IFREG) -You lose. -# endif -#endif - -#if defined(S_ISSOCK) && defined(S_IFREG) -# if S_ISSOCK (S_IFREG) -You lose. -# endif -#endif - -EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "You lose" >/dev/null 2>&1; then - rm -rf conftest* - ac_cv_header_stat_broken=yes -else - rm -rf conftest* - ac_cv_header_stat_broken=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_header_stat_broken" 1>&6 -if test $ac_cv_header_stat_broken = yes; then - cat >> confdefs.h <<\EOF -#define STAT_MACROS_BROKEN 1 -EOF - -fi - -echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6 -echo "configure:2442: checking for st_rdev in struct stat" >&5 -if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -#include -int main() { -struct stat s; s.st_rdev; -; return 0; } -EOF -if { (eval echo configure:2455: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_struct_st_rdev=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_struct_st_rdev=no -fi -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_struct_st_rdev" 1>&6 -if test $ac_cv_struct_st_rdev = yes; then - cat >> confdefs.h <<\EOF -#define HAVE_ST_RDEV 1 -EOF - -fi - - -if egrep "__EXTENSIONS__" /usr/include/signal.h >/dev/null 2>&1; then - CPPFLAGS="$CPPFLAGS -D__EXTENSIONS__" -fi - -echo $ac_n "Checking for MACHINE & MACHINE_ARCH... $ac_c" 2>&6 -cat > conftest.$ac_ext < -#ifdef MACHINE -machine=MACHINE -#endif -#ifdef MACHINE_ARCH -machine_arch=MACHINE_ARCH -#endif -EOF - -default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep machine= | tr -d ' "'` -rm -rf conftest* -if test "$default_machine"; then - eval "$default_machine" -fi -machine=${machine:-`$srcdir/machine.sh`} -machine_arch=${machine_arch:-`$srcdir/machine.sh arch`} -echo "defaults: MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6 -# Check whether --with-machine or --without-machine was given. -if test "${with_machine+set}" = set; then - withval="$with_machine" - case "${withval}" in -yes) { echo "configure: error: bad value ${withval} given for bmake MACHINE" 1>&2; exit 1; } ;; -no) ;; -generic) machine=`$srcdir/machine.sh`;; -*) machine=$with_machine;; -esac -fi - -force_machine= -# Check whether --with-force_machine or --without-force_machine was given. -if test "${with_force_machine+set}" = set; then - withval="$with_force_machine" - case "${withval}" in -yes) force_machine=FORCE_;; -no) ;; -*) force_machine=FORCE_; machine=$with_force_machine;; -esac -fi - -# Check whether --with-machine_arch or --without-machine_arch was given. -if test "${with_machine_arch+set}" = set; then - withval="$with_machine_arch" - case "${withval}" in -yes) { echo "configure: error: bad value ${withval} given for bmake MACHINE_ARCH" 1>&2; exit 1; } ;; -no) ;; -*) machine_arch=$with_machine_arch;; -esac -fi - -echo "Using: ${force_machine}MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6 -# Check whether --with-default-sys-path or --without-default-sys-path was given. -if test "${with_default_sys_path+set}" = set; then - withval="$with_default_sys_path" - case "${withval}" in -yes) { echo "configure: error: bad value ${withval} given for bmake _PATH_DEFSYSPATH" 1>&2; exit 1; } ;; -no) ;; -*) CPPFLAGS="$CPPFLAGS \"-D_PATH_DEFSYSPATH=\\\"$with_default_sys_path\\\"\"" ;; -esac -fi - -# Check whether --with-prefix-sys-path or --without-prefix-sys-path was given. -if test "${with_prefix_sys_path+set}" = set; then - withval="$with_prefix_sys_path" - case "${withval}" in -yes) { echo "configure: error: bad value ${withval} given for bmake _PATH_PREFIX_SYSPATH" 1>&2; exit 1; } ;; -no) ;; -*) CPPFLAGS="$CPPFLAGS \"-D_PATH_PREFIX_SYSPATH=\\\"$with_prefix_sys_path\\\"\"" ;; -esac -fi - -# Check whether --with-path-objdirprefix or --without-path-objdirprefix was given. -if test "${with_path_objdirprefix+set}" = set; then - withval="$with_path_objdirprefix" - case "${withval}" in -yes) { echo "configure: error: bad value ${withval} given for bmake _PATH_OBJDIRPREFIX" 1>&2; exit 1; } ;; -no) CPPFLAGS="$CPPFLAGS -DNO_PATH_OBJDIRPREFIX" ;; -*) CPPFLAGS="$CPPFLAGS \"-D_PATH_OBJDIRPREFIX=\\\"$with_path-objdir\\\"\"" ;; -esac -fi - -# Check whether --enable-pwd-override or --disable-pwd-override was given. -if test "${enable_pwd_override+set}" = set; then - enableval="$enable_pwd_override" - case "${enableval}" in -yes) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_PWD_OVERRIDE" ;; -*) { echo "configure: error: bad value ${enableval} given for pwd-override option" 1>&2; exit 1; } ;; -esac -fi - -# Check whether --enable-check-make-chdir or --disable-check-make-chdir was given. -if test "${enable_check_make_chdir+set}" = set; then - enableval="$enable_check_make_chdir" - case "${enableval}" in -yes) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_CHECK_MAKE_CHDIR" ;; -*) { echo "configure: error: bad value ${enableval} given for check-make-chdir option" 1>&2; exit 1; } ;; -esac -fi - - - - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -DEFS=-DHAVE_CONFIG_H - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.13" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" - -trap 'rm -fr `echo "Makefile makefile.boot lst.lib/makefile.boot config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@SHELL@%$SHELL%g -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@FFLAGS@%$FFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@CC@%$CC%g -s%@CPP@%$CPP%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@ac_exe_suffix@%$ac_exe_suffix%g -s%@LIBOBJS@%$LIBOBJS%g -s%@machine@%$machine%g -s%@force_machine@%$force_machine%g -s%@machine_arch@%$machine_arch%g - -CEOF -EOF - -cat >> $CONFIG_STATUS <<\EOF - -# Split the substitutions into bite-sized pieces for seds with -# small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. -ac_file=1 # Number of current file. -ac_beg=1 # First line for current file. -ac_end=$ac_max_sed_cmds # Line after last line for current file. -ac_more_lines=: -ac_sed_cmds="" -while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file - else - sed "${ac_end}q" conftest.subs > conftest.s$ac_file - fi - if test ! -s conftest.s$ac_file; then - ac_more_lines=false - rm -f conftest.s$ac_file - else - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f conftest.s$ac_file" - else - ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" - fi - ac_file=`expr $ac_file + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_cmds` - fi -done -if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat -fi -EOF - -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; - esac - - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file -fi; done -rm -f conftest.s* - -# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where -# NAME is the cpp macro being defined and VALUE is the value it is being given. -# -# ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' -ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' -ac_dC='\3' -ac_dD='%g' -# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". -ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_uB='\([ ]\)%\1#\2define\3' -ac_uC=' ' -ac_uD='\4%g' -# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_eB='$%\1#\2define\3' -ac_eC=' ' -ac_eD='%g' - -if test "${CONFIG_HEADERS+set}" != set; then -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -fi -for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - echo creating $ac_file - - rm -f conftest.frag conftest.in conftest.out - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - cat $ac_file_inputs > conftest.in - -EOF - -# Transform confdefs.h into a sed script conftest.vals that substitutes -# the proper values into config.h.in to produce config.h. And first: -# Protect against being on the right side of a sed subst in config.status. -# Protect against being in an unquoted here document in config.status. -rm -f conftest.vals -cat > conftest.hdr <<\EOF -s/[\\&%]/\\&/g -s%[\\$`]%\\&%g -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp -s%ac_d%ac_u%gp -s%ac_u%ac_e%gp -EOF -sed -n -f conftest.hdr confdefs.h > conftest.vals -rm -f conftest.hdr - -# This sed command replaces #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -cat >> conftest.vals <<\EOF -s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% -EOF - -# Break up conftest.vals because some shells have a limit on -# the size of here documents, and old seds have small limits too. - -rm -f conftest.tail -while : -do - ac_lines=`grep -c . conftest.vals` - # grep -c gives empty output for an empty file on some AIX systems. - if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi - # Write a limited-size here document to conftest.frag. - echo ' cat > conftest.frag <> $CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS - echo 'CEOF - sed -f conftest.frag conftest.in > conftest.out - rm -f conftest.in - mv conftest.out conftest.in -' >> $CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail - rm -f conftest.vals - mv conftest.tail conftest.vals -done -rm -f conftest.vals - -cat >> $CONFIG_STATUS <<\EOF - rm -f conftest.frag conftest.h - echo "/* $ac_file. Generated automatically by configure. */" > conftest.h - cat conftest.in >> conftest.h - rm -f conftest.in - if cmp -s $ac_file conftest.h 2>/dev/null; then - echo "$ac_file is unchanged" - rm -f conftest.h - else - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - fi - rm -f $ac_file - mv conftest.h $ac_file - fi -fi; done - -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF - -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - - -cat <&6 -AC_EGREP_CPP(yes, -[#include -#ifdef __RCSID -yes -#endif -], -echo yes 2>&6, -echo no 2>&6; CPPFLAGS="${CPPFLAGS} -I\${srcdir}/missing -DNEED_HOST_CDEFS_H"), -CPPFLAGS="${CPPFLAGS} -I\${srcdir}/missing") - -dnl Checks for typedefs, structures, and compiler characteristics. -AC_C___ATTRIBUTE__ -AC_C_BIGENDIAN -AC_C_CONST -AC_TYPE_OFF_T -AC_TYPE_PID_T -AC_TYPE_SIZE_T -AC_DECL_SYS_SIGLIST -AC_HEADER_TIME -AC_STRUCT_TM - -dnl Checks for library functions. -AC_TYPE_SIGNAL -AC_FUNC_VFORK -AC_FUNC_VPRINTF -AC_FUNC_WAIT3 -AC_CHECK_FUNCS(getcwd getwd getopt putenv select strdup strerror strtod strtol setenv getenv vsnprintf snprintf strftime sigaction sigvec waitpid wait4 wait3) -dnl AC_REPLACE_FUNCS(setenv getenv) -AC_REPLACE_FUNCS(getenv) -dnl -dnl Structures -dnl -AC_HEADER_STAT -AC_STRUCT_ST_RDEV -dnl -dnl -dnl -dnl Solaris's signal.h only privides sigset_t etc if one of -dnl _EXTENSIONS_ _POSIX_C_SOURCE or _XOPEN_SOURCE are defined. -dnl The later two seem to cause more problems than they solve so if we -dnl see _EXTENSIONS_ we use it. -dnl Note we _don't_ want AC_EGREP_HEADER as we don't want CPP involved. -dnl -AC_EGREP(__EXTENSIONS__, /usr/include/signal.h, -CPPFLAGS="$CPPFLAGS -D__EXTENSIONS__",) -dnl -dnl AC_* don't quite cut it. -dnl -echo $ac_n "Checking for MACHINE & MACHINE_ARCH... $ac_c" 2>&6 -cat > conftest.$ac_ext < -#ifdef MACHINE -machine=MACHINE -#endif -#ifdef MACHINE_ARCH -machine_arch=MACHINE_ARCH -#endif -EOF - -default_machine=`(eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep machine= | tr -d ' "'` -rm -rf conftest* -if test "$default_machine"; then - eval "$default_machine" -fi -machine=${machine:-`$srcdir/machine.sh`} -machine_arch=${machine_arch:-`$srcdir/machine.sh arch`} -echo "defaults: MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6 -dnl -dnl now allow overrides -dnl -AC_ARG_WITH(machine, -[ --with-machine=MACHINE explicitly set MACHINE], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake MACHINE) ;; -no) ;; -generic) machine=`$srcdir/machine.sh`;; -*) machine=$with_machine;; -esac]) -force_machine= -AC_ARG_WITH(force_machine, -[ --with-force-machine=MACHINE set FORCE_MACHINE], -[case "${withval}" in -yes) force_machine=FORCE_;; -no) ;; -*) force_machine=FORCE_; machine=$with_force_machine;; -esac]) -dnl -AC_ARG_WITH(machine_arch, -[ --with-machine_arch=MACHINE_ARCH explicitly set MACHINE_ARCH], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake MACHINE_ARCH) ;; -no) ;; -*) machine_arch=$with_machine_arch;; -esac]) -dnl -dnl Tell them what we ended up with -dnl -echo "Using: ${force_machine}MACHINE=$machine, MACHINE_ARCH=$machine_arch" 1>&6 -dnl -dnl Allow folk to control _PATH_DEFSYSPATH -dnl -AC_ARG_WITH(default-sys-path, -[ --with-default-sys-path=PATH:DIR:LIST use an explicit _PATH_DEFSYSPATH], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_DEFSYSPATH) ;; -no) ;; -*) CPPFLAGS="$CPPFLAGS \"-D_PATH_DEFSYSPATH=\\\"$with_default_sys_path\\\"\"" ;; -esac]) -dnl -dnl Or just to prefix it -dnl -AC_ARG_WITH(prefix-sys-path, -[ --with-prefix-sys-path=PATH:DIR:LIST prefix _PATH_PREFIX_SYSPATH], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_PREFIX_SYSPATH) ;; -no) ;; -*) CPPFLAGS="$CPPFLAGS \"-D_PATH_PREFIX_SYSPATH=\\\"$with_prefix_sys_path\\\"\"" ;; -esac]) -dnl -dnl Some folk don't like this one -dnl -AC_ARG_WITH(path-objdirprefix, -[ --with-path-objdirprefix=PATH override _PATH_OBJDIRPREFIX], -[case "${withval}" in -yes) AC_MSG_ERROR(bad value ${withval} given for bmake _PATH_OBJDIRPREFIX) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_PATH_OBJDIRPREFIX" ;; -*) CPPFLAGS="$CPPFLAGS \"-D_PATH_OBJDIRPREFIX=\\\"$with_path-objdir\\\"\"" ;; -esac]) -dnl -dnl And this can be handy to do with out. -dnl -AC_ARG_ENABLE(pwd-override, -[ --disable-pwd-override disable \$PWD overriding getcwd()], -[case "${enableval}" in -yes) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_PWD_OVERRIDE" ;; -*) AC_MSG_ERROR(bad value ${enableval} given for pwd-override option) ;; -esac]) -dnl -dnl Just for grins -dnl -AC_ARG_ENABLE(check-make-chdir, -[ --disable-check-make-chdir disable make trying to guess - when it should automatically cd \${.CURDIR}], -[case "${enableval}" in -yes) ;; -no) CPPFLAGS="$CPPFLAGS -DNO_CHECK_MAKE_CHDIR" ;; -*) AC_MSG_ERROR(bad value ${enableval} given for check-make-chdir option) ;; -esac]) -AC_SUBST(machine) -AC_SUBST(force_machine) -AC_SUBST(machine_arch) -AC_OUTPUT(Makefile makefile.boot lst.lib/makefile.boot) - -cat < -#ifndef lint -#if 0 -static char sccsid[] = "@(#)dir.c 8.2 (Berkeley) 1/2/94"; -#else -__RCSID("$NetBSD: dir.c,v 1.2 2004/11/06 15:09:22 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: dir.c,v 1.2 2004/11/06 15:09:22 grant Exp $"); -#endif - -/*- - * dir.c -- - * Directory searching using wildcards and/or normal names... - * Used both for source wildcarding in the Makefile and for finding - * implicit sources. - * - * The interface for this module is: - * Dir_Init Initialize the module. - * - * Dir_End Cleanup the module. - * - * Dir_HasWildcards Returns TRUE if the name given it needs to - * be wildcard-expanded. - * - * Dir_Expand Given a pattern and a path, return a Lst of names - * which match the pattern on the search path. - * - * Dir_FindFile Searches for a file on a given search path. - * If it exists, the entire path is returned. - * Otherwise NULL is returned. - * - * Dir_MTime Return the modification time of a node. The file - * is searched for along the default search path. - * The path and mtime fields of the node are filled - * in. - * - * Dir_AddDir Add a directory to a search path. - * - * Dir_MakeFlags Given a search path and a command flag, create - * a string with each of the directories in the path - * preceded by the command flag and all of them - * separated by a space. - * - * Dir_Destroy Destroy an element of a search path. Frees up all - * things that can be freed for the element as long - * as the element is no longer referenced by any other - * search path. - * Dir_ClearPath Resets a search path to the empty list. - * - * For debugging: - * Dir_PrintDirectories Print stats about the directory cache. - */ - -#include -#include -#include -#include -#include -#include "make.h" -#include "hash.h" -#include "dir.h" - -/* - * A search path consists of a Lst of Path structures. A Path structure - * has in it the name of the directory and a hash table of all the files - * in the directory. This is used to cut down on the number of system - * calls necessary to find implicit dependents and their like. Since - * these searches are made before any actions are taken, we need not - * worry about the directory changing due to creation commands. If this - * hampers the style of some makefiles, they must be changed. - * - * A list of all previously-read directories is kept in the - * openDirectories Lst. This list is checked first before a directory - * is opened. - * - * The need for the caching of whole directories is brought about by - * the multi-level transformation code in suff.c, which tends to search - * for far more files than regular make does. In the initial - * implementation, the amount of time spent performing "stat" calls was - * truly astronomical. The problem with hashing at the start is, - * of course, that pmake doesn't then detect changes to these directories - * during the course of the make. Three possibilities suggest themselves: - * - * 1) just use stat to test for a file's existence. As mentioned - * above, this is very inefficient due to the number of checks - * engendered by the multi-level transformation code. - * 2) use readdir() and company to search the directories, keeping - * them open between checks. I have tried this and while it - * didn't slow down the process too much, it could severely - * affect the amount of parallelism available as each directory - * open would take another file descriptor out of play for - * handling I/O for another job. Given that it is only recently - * that UNIX OS's have taken to allowing more than 20 or 32 - * file descriptors for a process, this doesn't seem acceptable - * to me. - * 3) record the mtime of the directory in the Path structure and - * verify the directory hasn't changed since the contents were - * hashed. This will catch the creation or deletion of files, - * but not the updating of files. However, since it is the - * creation and deletion that is the problem, this could be - * a good thing to do. Unfortunately, if the directory (say ".") - * were fairly large and changed fairly frequently, the constant - * rehashing could seriously degrade performance. It might be - * good in such cases to keep track of the number of rehashes - * and if the number goes over a (small) limit, resort to using - * stat in its place. - * - * An additional thing to consider is that pmake is used primarily - * to create C programs and until recently pcc-based compilers refused - * to allow you to specify where the resulting object file should be - * placed. This forced all objects to be created in the current - * directory. This isn't meant as a full excuse, just an explanation of - * some of the reasons for the caching used here. - * - * One more note: the location of a target's file is only performed - * on the downward traversal of the graph and then only for terminal - * nodes in the graph. This could be construed as wrong in some cases, - * but prevents inadvertent modification of files when the "installed" - * directory for a file is provided in the search path. - * - * Another data structure maintained by this module is an mtime - * cache used when the searching of cached directories fails to find - * a file. In the past, Dir_FindFile would simply perform an access() - * call in such a case to determine if the file could be found using - * just the name given. When this hit, however, all that was gained - * was the knowledge that the file existed. Given that an access() is - * essentially a stat() without the copyout() call, and that the same - * filesystem overhead would have to be incurred in Dir_MTime, it made - * sense to replace the access() with a stat() and record the mtime - * in a cache for when Dir_MTime was actually called. - */ - -Lst dirSearchPath; /* main search path */ - -static Lst openDirectories; /* the list of all open directories */ - -/* - * Variables for gathering statistics on the efficiency of the hashing - * mechanism. - */ -static int hits, /* Found in directory cache */ - misses, /* Sad, but not evil misses */ - nearmisses, /* Found under search path */ - bigmisses; /* Sought by itself */ - -static Path *dot; /* contents of current directory */ -static Path *cur; /* contents of current directory, if not dot */ -static Path *dotLast; /* a fake path entry indicating we need to - * look for . last */ -static Hash_Table mtimes; /* Results of doing a last-resort stat in - * Dir_FindFile -- if we have to go to the - * system to find the file, we might as well - * have its mtime on record. XXX: If this is done - * way early, there's a chance other rules will - * have already updated the file, in which case - * we'll update it again. Generally, there won't - * be two rules to update a single file, so this - * should be ok, but... */ - - -static int DirFindName __P((ClientData, ClientData)); -static int DirMatchFiles __P((char *, Path *, Lst)); -static void DirExpandCurly __P((char *, char *, Lst, Lst)); -static void DirExpandInt __P((char *, Lst, Lst)); -static int DirPrintWord __P((ClientData, ClientData)); -static int DirPrintDir __P((ClientData, ClientData)); -static char *DirLookup __P((Path *, char *, char *, Boolean)); -static char *DirLookupSubdir __P((Path *, char *)); -static char *DirFindDot __P((Boolean, char *, char *)); - -/*- - *----------------------------------------------------------------------- - * Dir_Init -- - * initialize things for this module - * - * Results: - * none - * - * Side Effects: - * some directories may be opened. - *----------------------------------------------------------------------- - */ -void -Dir_Init (cdname) - const char *cdname; -{ - dirSearchPath = Lst_Init (FALSE); - openDirectories = Lst_Init (FALSE); - Hash_InitTable(&mtimes, 0); - - /* - * Since the Path structure is placed on both openDirectories and - * the path we give Dir_AddDir (which in this case is openDirectories), - * we need to remove "." from openDirectories and what better time to - * do it than when we have to fetch the thing anyway? - */ - dot = Dir_AddDir (NULL, "."); - if (dot == NULL) { - Error("Cannot open `.' (%s)", strerror(errno)); - exit(1); - } - - /* - * We always need to have dot around, so we increment its reference count - * to make sure it's not destroyed. - */ - dot->refCount += 1; - - if (cdname != NULL) { - /* - * Our build directory is not the same as our source directory. - * Keep this one around too. - */ - cur = Dir_AddDir (NULL, cdname); - cur->refCount += 1; - } - - dotLast = (Path *) emalloc (sizeof (Path)); - dotLast->refCount = 1; - dotLast->hits = 0; - dotLast->name = estrdup(".DOTLAST"); - Hash_InitTable (&dotLast->files, -1); -} - -/*- - *----------------------------------------------------------------------- - * Dir_End -- - * cleanup things for this module - * - * Results: - * none - * - * Side Effects: - * none - *----------------------------------------------------------------------- - */ -void -Dir_End() -{ -#ifdef CLEANUP - if (cur) { - cur->refCount -= 1; - Dir_Destroy((ClientData) cur); - } - dot->refCount -= 1; - dotLast->refCount -= 1; - Dir_Destroy((ClientData) dotLast); - Dir_Destroy((ClientData) dot); - Dir_ClearPath(dirSearchPath); - Lst_Destroy(dirSearchPath, NOFREE); - Dir_ClearPath(openDirectories); - Lst_Destroy(openDirectories, NOFREE); - Hash_DeleteTable(&mtimes); -#endif -} - -/*- - *----------------------------------------------------------------------- - * DirFindName -- - * See if the Path structure describes the same directory as the - * given one by comparing their names. Called from Dir_AddDir via - * Lst_Find when searching the list of open directories. - * - * Results: - * 0 if it is the same. Non-zero otherwise - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -DirFindName (p, dname) - ClientData p; /* Current name */ - ClientData dname; /* Desired name */ -{ - return (strcmp (((Path *)p)->name, (char *) dname)); -} - -/*- - *----------------------------------------------------------------------- - * Dir_HasWildcards -- - * see if the given name has any wildcard characters in it - * be careful not to expand unmatching brackets or braces. - * XXX: This code is not 100% correct. ([^]] fails etc.) - * I really don't think that make(1) should be expanding - * patterns, because then you have to set a mechanism for - * escaping the expansion! - * - * Results: - * returns TRUE if the word should be expanded, FALSE otherwise - * - * Side Effects: - * none - *----------------------------------------------------------------------- - */ -Boolean -Dir_HasWildcards (name) - char *name; /* name to check */ -{ - register char *cp; - int wild = 0, brace = 0, bracket = 0; - - for (cp = name; *cp; cp++) { - switch(*cp) { - case '{': - brace++; - wild = 1; - break; - case '}': - brace--; - break; - case '[': - bracket++; - wild = 1; - break; - case ']': - bracket--; - break; - case '?': - case '*': - wild = 1; - break; - default: - break; - } - } - return wild && bracket == 0 && brace == 0; -} - -/*- - *----------------------------------------------------------------------- - * DirMatchFiles -- - * Given a pattern and a Path structure, see if any files - * match the pattern and add their names to the 'expansions' list if - * any do. This is incomplete -- it doesn't take care of patterns like - * src / *src / *.c properly (just *.c on any of the directories), but it - * will do for now. - * - * Results: - * Always returns 0 - * - * Side Effects: - * File names are added to the expansions lst. The directory will be - * fully hashed when this is done. - *----------------------------------------------------------------------- - */ -static int -DirMatchFiles (pattern, p, expansions) - char *pattern; /* Pattern to look for */ - Path *p; /* Directory to search */ - Lst expansions; /* Place to store the results */ -{ - Hash_Search search; /* Index into the directory's table */ - Hash_Entry *entry; /* Current entry in the table */ - Boolean isDot; /* TRUE if the directory being searched is . */ - - isDot = (*p->name == '.' && p->name[1] == '\0'); - - for (entry = Hash_EnumFirst(&p->files, &search); - entry != (Hash_Entry *)NULL; - entry = Hash_EnumNext(&search)) - { - /* - * See if the file matches the given pattern. Note we follow the UNIX - * convention that dot files will only be found if the pattern - * begins with a dot (note also that as a side effect of the hashing - * scheme, .* won't match . or .. since they aren't hashed). - */ - if (Str_Match(entry->name, pattern) && - ((entry->name[0] != '.') || - (pattern[0] == '.'))) - { - (void)Lst_AtEnd(expansions, - (isDot ? estrdup(entry->name) : - str_concat(p->name, entry->name, - STR_ADDSLASH))); - } - } - return (0); -} - -/*- - *----------------------------------------------------------------------- - * DirExpandCurly -- - * Expand curly braces like the C shell. Does this recursively. - * Note the special case: if after the piece of the curly brace is - * done there are no wildcard characters in the result, the result is - * placed on the list WITHOUT CHECKING FOR ITS EXISTENCE. - * - * Results: - * None. - * - * Side Effects: - * The given list is filled with the expansions... - * - *----------------------------------------------------------------------- - */ -static void -DirExpandCurly(word, brace, path, expansions) - char *word; /* Entire word to expand */ - char *brace; /* First curly brace in it */ - Lst path; /* Search path to use */ - Lst expansions; /* Place to store the expansions */ -{ - char *end; /* Character after the closing brace */ - char *cp; /* Current position in brace clause */ - char *start; /* Start of current piece of brace clause */ - int bracelevel; /* Number of braces we've seen. If we see a - * right brace when this is 0, we've hit the - * end of the clause. */ - char *file; /* Current expansion */ - int otherLen; /* The length of the other pieces of the - * expansion (chars before and after the - * clause in 'word') */ - char *cp2; /* Pointer for checking for wildcards in - * expansion before calling Dir_Expand */ - - start = brace+1; - - /* - * Find the end of the brace clause first, being wary of nested brace - * clauses. - */ - for (end = start, bracelevel = 0; *end != '\0'; end++) { - if (*end == '{') { - bracelevel++; - } else if ((*end == '}') && (bracelevel-- == 0)) { - break; - } - } - if (*end == '\0') { - Error("Unterminated {} clause \"%s\"", start); - return; - } else { - end++; - } - otherLen = brace - word + strlen(end); - - for (cp = start; cp < end; cp++) { - /* - * Find the end of this piece of the clause. - */ - bracelevel = 0; - while (*cp != ',') { - if (*cp == '{') { - bracelevel++; - } else if ((*cp == '}') && (bracelevel-- <= 0)) { - break; - } - cp++; - } - /* - * Allocate room for the combination and install the three pieces. - */ - file = emalloc(otherLen + cp - start + 1); - if (brace != word) { - strncpy(file, word, brace-word); - } - if (cp != start) { - strncpy(&file[brace-word], start, cp-start); - } - strcpy(&file[(brace-word)+(cp-start)], end); - - /* - * See if the result has any wildcards in it. If we find one, call - * Dir_Expand right away, telling it to place the result on our list - * of expansions. - */ - for (cp2 = file; *cp2 != '\0'; cp2++) { - switch(*cp2) { - case '*': - case '?': - case '{': - case '[': - Dir_Expand(file, path, expansions); - goto next; - } - } - if (*cp2 == '\0') { - /* - * Hit the end w/o finding any wildcards, so stick the expansion - * on the end of the list. - */ - (void)Lst_AtEnd(expansions, file); - } else { - next: - free(file); - } - start = cp+1; - } -} - - -/*- - *----------------------------------------------------------------------- - * DirExpandInt -- - * Internal expand routine. Passes through the directories in the - * path one by one, calling DirMatchFiles for each. NOTE: This still - * doesn't handle patterns in directories... - * - * Results: - * None. - * - * Side Effects: - * Things are added to the expansions list. - * - *----------------------------------------------------------------------- - */ -static void -DirExpandInt(word, path, expansions) - char *word; /* Word to expand */ - Lst path; /* Path on which to look */ - Lst expansions; /* Place to store the result */ -{ - LstNode ln; /* Current node */ - Path *p; /* Directory in the node */ - - if (Lst_Open(path) == SUCCESS) { - while ((ln = Lst_Next(path)) != NILLNODE) { - p = (Path *)Lst_Datum(ln); - DirMatchFiles(word, p, expansions); - } - Lst_Close(path); - } -} - -/*- - *----------------------------------------------------------------------- - * DirPrintWord -- - * Print a word in the list of expansions. Callback for Dir_Expand - * when DEBUG(DIR), via Lst_ForEach. - * - * Results: - * === 0 - * - * Side Effects: - * The passed word is printed, followed by a space. - * - *----------------------------------------------------------------------- - */ -static int -DirPrintWord(word, dummy) - ClientData word; - ClientData dummy; -{ - printf("%s ", (char *) word); - - return(dummy ? 0 : 0); -} - -/*- - *----------------------------------------------------------------------- - * Dir_Expand -- - * Expand the given word into a list of words by globbing it looking - * in the directories on the given search path. - * - * Results: - * A list of words consisting of the files which exist along the search - * path matching the given pattern. - * - * Side Effects: - * Directories may be opened. Who knows? - *----------------------------------------------------------------------- - */ -void -Dir_Expand (word, path, expansions) - char *word; /* the word to expand */ - Lst path; /* the list of directories in which to find - * the resulting files */ - Lst expansions; /* the list on which to place the results */ -{ - char *cp; - - if (DEBUG(DIR)) { - printf("expanding \"%s\"...", word); - } - - cp = strchr(word, '{'); - if (cp) { - DirExpandCurly(word, cp, path, expansions); - } else { - cp = strchr(word, '/'); - if (cp) { - /* - * The thing has a directory component -- find the first wildcard - * in the string. - */ - for (cp = word; *cp; cp++) { - if (*cp == '?' || *cp == '[' || *cp == '*' || *cp == '{') { - break; - } - } - if (*cp == '{') { - /* - * This one will be fun. - */ - DirExpandCurly(word, cp, path, expansions); - return; - } else if (*cp != '\0') { - /* - * Back up to the start of the component - */ - char *dirpath; - - while (cp > word && *cp != '/') { - cp--; - } - if (cp != word) { - char sc; - /* - * If the glob isn't in the first component, try and find - * all the components up to the one with a wildcard. - */ - sc = cp[1]; - cp[1] = '\0'; - dirpath = Dir_FindFile(word, path); - cp[1] = sc; - /* - * dirpath is null if can't find the leading component - * XXX: Dir_FindFile won't find internal components. - * i.e. if the path contains ../Etc/Object and we're - * looking for Etc, it won't be found. Ah well. - * Probably not important. - */ - if (dirpath != (char *)NULL) { - char *dp = &dirpath[strlen(dirpath) - 1]; - if (*dp == '/') - *dp = '\0'; - path = Lst_Init(FALSE); - (void) Dir_AddDir(path, dirpath); - DirExpandInt(cp+1, path, expansions); - Lst_Destroy(path, NOFREE); - } - } else { - /* - * Start the search from the local directory - */ - DirExpandInt(word, path, expansions); - } - } else { - /* - * Return the file -- this should never happen. - */ - DirExpandInt(word, path, expansions); - } - } else { - /* - * First the files in dot - */ - DirMatchFiles(word, dot, expansions); - - /* - * Then the files in every other directory on the path. - */ - DirExpandInt(word, path, expansions); - } - } - if (DEBUG(DIR)) { - Lst_ForEach(expansions, DirPrintWord, (ClientData) 0); - fputc('\n', stdout); - } -} - -/*- - *----------------------------------------------------------------------- - * DirLookup -- - * Find if the file with the given name exists in the given path. - * - * Results: - * The path to the file, the empty string or NULL. If the file is - * the empty string, the search should be terminated. - * This path is guaranteed to be in a - * different part of memory than name and so may be safely free'd. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static char * -DirLookup(p, name, cp, hasSlash) - Path *p; - char *name; - char *cp; - Boolean hasSlash; -{ - char *p1; /* pointer into p->name */ - char *p2; /* pointer into name */ - char *file; /* the current filename to check */ - - if (DEBUG(DIR)) { - printf("%s...", p->name); - } - if (Hash_FindEntry (&p->files, cp) != (Hash_Entry *)NULL) { - if (DEBUG(DIR)) { - printf("here..."); - } - if (hasSlash) { - /* - * If the name had a slash, its initial components and p's - * final components must match. This is false if a mismatch - * is encountered before all of the initial components - * have been checked (p2 > name at the end of the loop), or - * we matched only part of one of the components of p - * along with all the rest of them (*p1 != '/'). - */ - p1 = p->name + strlen (p->name) - 1; - p2 = cp - 2; - while (p2 >= name && p1 >= p->name && *p1 == *p2) { - p1 -= 1; p2 -= 1; - } - if (p2 >= name || (p1 >= p->name && *p1 != '/')) { - if (DEBUG(DIR)) { - printf("component mismatch -- continuing..."); - } - return NULL; - } - } - file = str_concat (p->name, cp, STR_ADDSLASH); - if (DEBUG(DIR)) { - printf("returning %s\n", file); - } - p->hits += 1; - hits += 1; - return file; - } else if (hasSlash) { - /* - * If the file has a leading path component and that component - * exactly matches the entire name of the current search - * directory, we assume the file doesn't exist and return NULL. - */ - for (p1 = p->name, p2 = name; *p1 && *p1 == *p2; p1++, p2++) { - continue; - } - if (*p1 == '\0' && p2 == cp - 1) { - if (DEBUG(DIR)) { - printf("must be here but isn't -- returing\n"); - } - return ""; - } - } - return NULL; -} - - -/*- - *----------------------------------------------------------------------- - * DirLookupSubdir -- - * Find if the file with the given name exists in the given path. - * - * Results: - * The path to the file or NULL. This path is guaranteed to be in a - * different part of memory than name and so may be safely free'd. - * - * Side Effects: - * If the file is found, it is added in the modification times hash - * table. - *----------------------------------------------------------------------- - */ -static char * -DirLookupSubdir(p, name) - Path *p; - char *name; -{ - struct stat stb; /* Buffer for stat, if necessary */ - Hash_Entry *entry; /* Entry for mtimes table */ - char *file; /* the current filename to check */ - - if (p != dot) { - file = str_concat (p->name, name, STR_ADDSLASH); - } else { - /* - * Checking in dot -- DON'T put a leading ./ on the thing. - */ - file = estrdup(name); - } - - if (DEBUG(DIR)) { - printf("checking %s...", file); - } - - if (stat (file, &stb) == 0) { - if (DEBUG(DIR)) { - printf("got it.\n"); - } - - /* - * Save the modification time so if it's needed, we don't have - * to fetch it again. - */ - if (DEBUG(DIR)) { - printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime), - file); - } - entry = Hash_CreateEntry(&mtimes, (char *) file, - (Boolean *)NULL); - Hash_SetValue(entry, (long)stb.st_mtime); - nearmisses += 1; - return (file); - } - free (file); - return NULL; -} - -/*- - *----------------------------------------------------------------------- - * DirFindDot -- - * Find the file given on "." or curdir - * - * Results: - * The path to the file or NULL. This path is guaranteed to be in a - * different part of memory than name and so may be safely free'd. - * - * Side Effects: - * Hit counts change - *----------------------------------------------------------------------- - */ -static char * -DirFindDot(hasSlash, name, cp) - Boolean hasSlash; - char *name; - char *cp; -{ - char *file; - - if ((!hasSlash || (cp - name == 2 && *name == '.'))) { - if (Hash_FindEntry (&dot->files, cp) != (Hash_Entry *)NULL) { - if (DEBUG(DIR)) { - printf("in '.'\n"); - } - hits += 1; - dot->hits += 1; - return (estrdup (name)); - } - if (cur && - Hash_FindEntry (&cur->files, cp) != (Hash_Entry *)NULL) { - if (DEBUG(DIR)) { - printf("in ${.CURDIR} = %s\n", cur->name); - } - hits += 1; - cur->hits += 1; - return str_concat (cur->name, cp, STR_ADDSLASH); - } - } - - - if (cur && (file = DirLookup(cur, name, cp, hasSlash)) != NULL) { - if (*file) - return file; - else - return NULL; - } - return NULL; -} - -/*- - *----------------------------------------------------------------------- - * Dir_FindFile -- - * Find the file with the given name along the given search path. - * - * Results: - * The path to the file or NULL. This path is guaranteed to be in a - * different part of memory than name and so may be safely free'd. - * - * Side Effects: - * If the file is found in a directory which is not on the path - * already (either 'name' is absolute or it is a relative path - * [ dir1/.../dirn/file ] which exists below one of the directories - * already on the search path), its directory is added to the end - * of the path on the assumption that there will be more files in - * that directory later on. Sometimes this is true. Sometimes not. - *----------------------------------------------------------------------- - */ -char * -Dir_FindFile (name, path) - char *name; /* the file to find */ - Lst path; /* the Lst of directories to search */ -{ - LstNode ln; /* a list element */ - register char *file; /* the current filename to check */ - register Path *p; /* current path member */ - register char *cp; /* index of first slash, if any */ - Boolean lastDot = FALSE; /* true we should search dot last */ - Boolean hasSlash; /* true if 'name' contains a / */ - struct stat stb; /* Buffer for stat, if necessary */ - Hash_Entry *entry; /* Entry for mtimes table */ - - /* - * Find the final component of the name and note whether it has a - * slash in it (the name, I mean) - */ - cp = strrchr (name, '/'); - if (cp) { - hasSlash = TRUE; - cp += 1; - } else { - hasSlash = FALSE; - cp = name; - } - - if (DEBUG(DIR)) { - printf("Searching for %s...", name); - } - - if (Lst_Open (path) == FAILURE) { - if (DEBUG(DIR)) { - printf("couldn't open path, file not found\n"); - } - misses += 1; - return ((char *) NULL); - } - - if ((ln = Lst_First (path)) != NILLNODE) { - p = (Path *) Lst_Datum (ln); - if (p == dotLast) - lastDot = TRUE; - if (DEBUG(DIR)) { - printf("[dot last]..."); - } - } - - /* - * No matter what, we always look for the file in the current directory - * before anywhere else and we *do not* add the ./ to it if it exists. - * This is so there are no conflicts between what the user specifies - * (fish.c) and what pmake finds (./fish.c). - * Unless we found the magic DOTLAST path... - */ - if (!lastDot && (file = DirFindDot(hasSlash, name, cp)) != NULL) - return file; - - - /* - * We look through all the directories on the path seeking one which - * contains the final component of the given name and whose final - * component(s) match the name's initial component(s). If such a beast - * is found, we concatenate the directory name and the final component - * and return the resulting string. If we don't find any such thing, - * we go on to phase two... - */ - while ((ln = Lst_Next (path)) != NILLNODE) { - p = (Path *) Lst_Datum (ln); - if (p == dotLast) - continue; - if ((file = DirLookup(p, name, cp, hasSlash)) != NULL) { - Lst_Close (path); - if (*file) - return file; - else - return NULL; - } - } - - if (lastDot && (file = DirFindDot(hasSlash, name, cp)) != NULL) - return file; - - /* - * We didn't find the file on any existing members of the directory. - * If the name doesn't contain a slash, that means it doesn't exist. - * If it *does* contain a slash, however, there is still hope: it - * could be in a subdirectory of one of the members of the search - * path. (eg. /usr/include and sys/types.h. The above search would - * fail to turn up types.h in /usr/include, but it *is* in - * /usr/include/sys/types.h) If we find such a beast, we assume there - * will be more (what else can we assume?) and add all but the last - * component of the resulting name onto the search path (at the - * end). This phase is only performed if the file is *not* absolute. - */ - if (!hasSlash) { - if (DEBUG(DIR)) { - printf("failed.\n"); - } - misses += 1; - return ((char *) NULL); - } - - if (*name != '/') { - Boolean checkedDot = FALSE; - - if (DEBUG(DIR)) { - printf("failed. Trying subdirectories..."); - } - - if (!lastDot && cur && (file = DirLookupSubdir(cur, name)) != NULL) - return file; - - (void) Lst_Open (path); - while ((ln = Lst_Next (path)) != NILLNODE) { - p = (Path *) Lst_Datum (ln); - if (p == dotLast) - continue; - if (p == dot) - checkedDot = TRUE; - if ((file = DirLookupSubdir(p, name)) != NULL) { - Lst_Close (path); - return file; - } - } - - if (lastDot && cur && (file = DirLookupSubdir(cur, name)) != NULL) - return file; - - if (DEBUG(DIR)) { - printf("failed. "); - } - Lst_Close (path); - - if (checkedDot) { - /* - * Already checked by the given name, since . was in the path, - * so no point in proceeding... - */ - if (DEBUG(DIR)) { - printf("Checked . already, returning NULL\n"); - } - return(NULL); - } - } - - /* - * Didn't find it that way, either. Sigh. Phase 3. Add its directory - * onto the search path in any case, just in case, then look for the - * thing in the hash table. If we find it, grand. We return a new - * copy of the name. Otherwise we sadly return a NULL pointer. Sigh. - * Note that if the directory holding the file doesn't exist, this will - * do an extra search of the final directory on the path. Unless something - * weird happens, this search won't succeed and life will be groovy. - * - * Sigh. We cannot add the directory onto the search path because - * of this amusing case: - * $(INSTALLDIR)/$(FILE): $(FILE) - * - * $(FILE) exists in $(INSTALLDIR) but not in the current one. - * When searching for $(FILE), we will find it in $(INSTALLDIR) - * b/c we added it here. This is not good... - */ -#ifdef notdef - cp[-1] = '\0'; - (void) Dir_AddDir (path, name); - cp[-1] = '/'; - - bigmisses += 1; - ln = Lst_Last (path); - if (ln == NILLNODE) { - return ((char *) NULL); - } else { - p = (Path *) Lst_Datum (ln); - } - - if (Hash_FindEntry (&p->files, cp) != (Hash_Entry *)NULL) { - return (estrdup (name)); - } else { - return ((char *) NULL); - } -#else /* !notdef */ - if (DEBUG(DIR)) { - printf("Looking for \"%s\"...", name); - } - - bigmisses += 1; - entry = Hash_FindEntry(&mtimes, name); - if (entry != (Hash_Entry *)NULL) { - if (DEBUG(DIR)) { - printf("got it (in mtime cache)\n"); - } - return(estrdup(name)); - } else if (stat (name, &stb) == 0) { - entry = Hash_CreateEntry(&mtimes, name, (Boolean *)NULL); - if (DEBUG(DIR)) { - printf("Caching %s for %s\n", Targ_FmtTime(stb.st_mtime), - name); - } - Hash_SetValue(entry, (long)stb.st_mtime); - return (estrdup (name)); - } else { - if (DEBUG(DIR)) { - printf("failed. Returning NULL\n"); - } - return ((char *)NULL); - } -#endif /* notdef */ -} - -/*- - *----------------------------------------------------------------------- - * Dir_MTime -- - * Find the modification time of the file described by gn along the - * search path dirSearchPath. - * - * Results: - * The modification time or 0 if it doesn't exist - * - * Side Effects: - * The modification time is placed in the node's mtime slot. - * If the node didn't have a path entry before, and Dir_FindFile - * found one for it, the full name is placed in the path slot. - *----------------------------------------------------------------------- - */ -int -Dir_MTime (gn) - GNode *gn; /* the file whose modification time is - * desired */ -{ - char *fullName; /* the full pathname of name */ - struct stat stb; /* buffer for finding the mod time */ - Hash_Entry *entry; - - if (gn->type & OP_ARCHV) { - return Arch_MTime (gn); - } else if (gn->path == (char *)NULL) { - if (gn->type & (OP_PHONY|OP_NOPATH)) - fullName = NULL; - else - fullName = Dir_FindFile (gn->name, dirSearchPath); - } else { - fullName = gn->path; - } - - if (fullName == (char *)NULL) { - fullName = estrdup(gn->name); - } - - entry = Hash_FindEntry(&mtimes, fullName); - if (entry != (Hash_Entry *)NULL) { - /* - * Only do this once -- the second time folks are checking to - * see if the file was actually updated, so we need to actually go - * to the file system. - */ - if (DEBUG(DIR)) { - printf("Using cached time %s for %s\n", - Targ_FmtTime((time_t)(long)Hash_GetValue(entry)), fullName); - } - stb.st_mtime = (time_t)(long)Hash_GetValue(entry); - Hash_DeleteEntry(&mtimes, entry); - } else if (stat (fullName, &stb) < 0) { - if (gn->type & OP_MEMBER) { - if (fullName != gn->path) - free(fullName); - return Arch_MemMTime (gn); - } else { - stb.st_mtime = 0; - } - } - if (fullName && gn->path == (char *)NULL) { - gn->path = fullName; - } - - gn->mtime = stb.st_mtime; - return (gn->mtime); -} - -/*- - *----------------------------------------------------------------------- - * Dir_AddDir -- - * Add the given name to the end of the given path. The order of - * the arguments is backwards so ParseDoDependency can do a - * Lst_ForEach of its list of paths... - * - * Results: - * none - * - * Side Effects: - * A structure is added to the list and the directory is - * read and hashed. - *----------------------------------------------------------------------- - */ -Path * -Dir_AddDir (path, name) - Lst path; /* the path to which the directory should be - * added */ - const char *name; /* the name of the directory to add */ -{ - LstNode ln; /* node in case Path structure is found */ - register Path *p = NULL; /* pointer to new Path structure */ - DIR *d; /* for reading directory */ - register struct dirent *dp; /* entry in directory */ - - if (strcmp(name, ".DOTLAST") == 0) { - ln = Lst_Find (path, (ClientData)name, DirFindName); - if (ln != NILLNODE) - return (Path *) Lst_Datum(ln); - else { - dotLast->refCount += 1; - (void)Lst_AtFront(path, (ClientData)dotLast); - } - } - - ln = Lst_Find (openDirectories, (ClientData)name, DirFindName); - if (ln != NILLNODE) { - p = (Path *)Lst_Datum (ln); - if (Lst_Member(path, (ClientData)p) == NILLNODE) { - p->refCount += 1; - (void)Lst_AtEnd (path, (ClientData)p); - } - } else { - if (DEBUG(DIR)) { - printf("Caching %s...", name); - fflush(stdout); - } - - if ((d = opendir (name)) != (DIR *) NULL) { - p = (Path *) emalloc (sizeof (Path)); - p->name = estrdup (name); - p->hits = 0; - p->refCount = 1; - Hash_InitTable (&p->files, -1); - - while ((dp = readdir (d)) != (struct dirent *) NULL) { -#if defined(sun) && defined(d_ino) /* d_ino is a sunos4 #define for d_fileno */ - /* - * The sun directory library doesn't check for a 0 inode - * (0-inode slots just take up space), so we have to do - * it ourselves. - */ - if (dp->d_fileno == 0) { - continue; - } -#endif /* sun && d_ino */ - (void)Hash_CreateEntry(&p->files, dp->d_name, (Boolean *)NULL); - } - (void) closedir (d); - (void)Lst_AtEnd (openDirectories, (ClientData)p); - if (path != NULL) - (void)Lst_AtEnd (path, (ClientData)p); - } - if (DEBUG(DIR)) { - printf("done\n"); - } - } - return p; -} - -/*- - *----------------------------------------------------------------------- - * Dir_CopyDir -- - * Callback function for duplicating a search path via Lst_Duplicate. - * Ups the reference count for the directory. - * - * Results: - * Returns the Path it was given. - * - * Side Effects: - * The refCount of the path is incremented. - * - *----------------------------------------------------------------------- - */ -ClientData -Dir_CopyDir(p) - ClientData p; -{ - ((Path *) p)->refCount += 1; - - return ((ClientData)p); -} - -/*- - *----------------------------------------------------------------------- - * Dir_MakeFlags -- - * Make a string by taking all the directories in the given search - * path and preceding them by the given flag. Used by the suffix - * module to create variables for compilers based on suffix search - * paths. - * - * Results: - * The string mentioned above. Note that there is no space between - * the given flag and each directory. The empty string is returned if - * Things don't go well. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -char * -Dir_MakeFlags (flag, path) - char *flag; /* flag which should precede each directory */ - Lst path; /* list of directories */ -{ - char *str; /* the string which will be returned */ - char *tstr; /* the current directory preceded by 'flag' */ - LstNode ln; /* the node of the current directory */ - Path *p; /* the structure describing the current directory */ - - str = estrdup (""); - - if (Lst_Open (path) == SUCCESS) { - while ((ln = Lst_Next (path)) != NILLNODE) { - p = (Path *) Lst_Datum (ln); - tstr = str_concat (flag, p->name, 0); - str = str_concat (str, tstr, STR_ADDSPACE | STR_DOFREE); - } - Lst_Close (path); - } - - return (str); -} - -/*- - *----------------------------------------------------------------------- - * Dir_Destroy -- - * Nuke a directory descriptor, if possible. Callback procedure - * for the suffixes module when destroying a search path. - * - * Results: - * None. - * - * Side Effects: - * If no other path references this directory (refCount == 0), - * the Path and all its data are freed. - * - *----------------------------------------------------------------------- - */ -void -Dir_Destroy (pp) - ClientData pp; /* The directory descriptor to nuke */ -{ - Path *p = (Path *) pp; - p->refCount -= 1; - - if (p->refCount == 0) { - LstNode ln; - - ln = Lst_Member (openDirectories, (ClientData)p); - (void) Lst_Remove (openDirectories, ln); - - Hash_DeleteTable (&p->files); - free((Address)p->name); - free((Address)p); - } -} - -/*- - *----------------------------------------------------------------------- - * Dir_ClearPath -- - * Clear out all elements of the given search path. This is different - * from destroying the list, notice. - * - * Results: - * None. - * - * Side Effects: - * The path is set to the empty list. - * - *----------------------------------------------------------------------- - */ -void -Dir_ClearPath(path) - Lst path; /* Path to clear */ -{ - Path *p; - while (!Lst_IsEmpty(path)) { - p = (Path *)Lst_DeQueue(path); - Dir_Destroy((ClientData) p); - } -} - - -/*- - *----------------------------------------------------------------------- - * Dir_Concat -- - * Concatenate two paths, adding the second to the end of the first. - * Makes sure to avoid duplicates. - * - * Results: - * None - * - * Side Effects: - * Reference counts for added dirs are upped. - * - *----------------------------------------------------------------------- - */ -void -Dir_Concat(path1, path2) - Lst path1; /* Dest */ - Lst path2; /* Source */ -{ - LstNode ln; - Path *p; - - for (ln = Lst_First(path2); ln != NILLNODE; ln = Lst_Succ(ln)) { - p = (Path *)Lst_Datum(ln); - if (Lst_Member(path1, (ClientData)p) == NILLNODE) { - p->refCount += 1; - (void)Lst_AtEnd(path1, (ClientData)p); - } - } -} - -/********** DEBUG INFO **********/ -void -Dir_PrintDirectories() -{ - LstNode ln; - Path *p; - - printf ("#*** Directory Cache:\n"); - printf ("# Stats: %d hits %d misses %d near misses %d losers (%d%%)\n", - hits, misses, nearmisses, bigmisses, - (hits+bigmisses+nearmisses ? - hits * 100 / (hits + bigmisses + nearmisses) : 0)); - printf ("# %-20s referenced\thits\n", "directory"); - if (Lst_Open (openDirectories) == SUCCESS) { - while ((ln = Lst_Next (openDirectories)) != NILLNODE) { - p = (Path *) Lst_Datum (ln); - printf ("# %-20s %10d\t%4d\n", p->name, p->refCount, p->hits); - } - Lst_Close (openDirectories); - } -} - -static int DirPrintDir (p, dummy) - ClientData p; - ClientData dummy; -{ - printf ("%s ", ((Path *) p)->name); - return (dummy ? 0 : 0); -} - -void -Dir_PrintPath (path) - Lst path; -{ - Lst_ForEach (path, DirPrintDir, (ClientData)0); -} diff --git a/bootstrap/bmake/dir.h b/bootstrap/bmake/dir.h deleted file mode 100644 index 000476005fd..00000000000 --- a/bootstrap/bmake/dir.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $NetBSD: dir.h,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)dir.h 8.1 (Berkeley) 6/6/93 - */ - -/* dir.h -- - */ - -#ifndef _DIR -#define _DIR - -typedef struct Path { - char *name; /* Name of directory */ - int refCount; /* Number of paths with this directory */ - int hits; /* the number of times a file in this - * directory has been found */ - Hash_Table files; /* Hash table of files in directory */ -} Path; - -void Dir_Init __P((const char *)); -void Dir_End __P((void)); -Boolean Dir_HasWildcards __P((char *)); -void Dir_Expand __P((char *, Lst, Lst)); -char *Dir_FindFile __P((char *, Lst)); -int Dir_MTime __P((GNode *)); -Path *Dir_AddDir __P((Lst, const char *)); -char *Dir_MakeFlags __P((char *, Lst)); -void Dir_ClearPath __P((Lst)); -void Dir_Concat __P((Lst, Lst)); -void Dir_PrintDirectories __P((void)); -void Dir_PrintPath __P((Lst)); -void Dir_Destroy __P((ClientData)); -ClientData Dir_CopyDir __P((ClientData)); - -#endif /* _DIR */ diff --git a/bootstrap/bmake/find_lib.sh b/bootstrap/bmake/find_lib.sh deleted file mode 100755 index 3c2e4af2f25..00000000000 --- a/bootstrap/bmake/find_lib.sh +++ /dev/null @@ -1,13 +0,0 @@ -: -re=$1; shift - -for lib in $* -do - found=`nm $lib | egrep "$re"` - case "$found" in - "") ;; - *) echo "$lib: $found";; - esac -done - - diff --git a/bootstrap/bmake/for.c b/bootstrap/bmake/for.c deleted file mode 100644 index c31fe7764dd..00000000000 --- a/bootstrap/bmake/for.c +++ /dev/null @@ -1,390 +0,0 @@ -/* $NetBSD: for.c,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $ */ - -/* - * Copyright (c) 1992, The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: for.c,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)for.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: for.c,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * for.c -- - * Functions to handle loops in a makefile. - * - * Interface: - * For_Eval Evaluate the loop in the passed line. - * For_Run Run accumulated loop - * - */ - -#include -#include -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "buf.h" - -/* - * For statements are of the form: - * - * .for in - * ... - * .endfor - * - * The trick is to look for the matching end inside for for loop - * To do that, we count the current nesting level of the for loops. - * and the .endfor statements, accumulating all the statements between - * the initial .for loop and the matching .endfor; - * then we evaluate the for loop for each variable in the varlist. - * - * Note that any nested fors are just passed through; they get handled - * recursively in For_Eval when we're expanding the enclosing for in - * For_Run. - */ - -static int forLevel = 0; /* Nesting level */ - -/* - * State of a for loop. - */ -typedef struct _For { - Buffer buf; /* Body of loop */ - char **vars; /* Iteration variables */ - int nvars; /* # of iteration vars */ - Lst lst; /* List of items */ -} For; - -static For accumFor; /* Loop being accumulated */ - -static void ForAddVar __P((const char *, size_t)); - - - - -/*- - *----------------------------------------------------------------------- - * ForAddVar -- - * Add an iteration variable to the currently accumulating for. - * - * Results: none - * Side effects: no additional side effects. - *----------------------------------------------------------------------- - */ -static void -ForAddVar(data, len) - const char *data; - size_t len; -{ - Buffer buf; - int varlen; - - buf = Buf_Init(0); - Buf_AddBytes(buf, len, (Byte *) data); - - accumFor.nvars++; - accumFor.vars = erealloc(accumFor.vars, accumFor.nvars*sizeof(char *)); - - accumFor.vars[accumFor.nvars-1] = (char *) Buf_GetAll(buf, &varlen); - - Buf_Destroy(buf, FALSE); -} - -/*- - *----------------------------------------------------------------------- - * For_Eval -- - * Evaluate the for loop in the passed line. The line - * looks like this: - * .for in - * - * Results: - * TRUE: We found a for loop, or we are inside a for loop - * FALSE: We did not find a for loop, or we found the end of the for - * for loop. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -int -For_Eval (line) - char *line; /* Line to parse */ -{ - char *ptr = line, *sub, *in, *wrd; - int level; /* Level at which to report errors. */ - - level = PARSE_FATAL; - - - if (forLevel == 0) { - Buffer buf; - int varlen; - - for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) - continue; - /* - * If we are not in a for loop quickly determine if the statement is - * a for. - */ - if (ptr[0] != 'f' || ptr[1] != 'o' || ptr[2] != 'r' || - !isspace((unsigned char) ptr[3])) - return FALSE; - ptr += 3; - - /* - * we found a for loop, and now we are going to parse it. - */ - while (*ptr && isspace((unsigned char) *ptr)) - ptr++; - - /* - * Find the "in". - */ - for (in = ptr; *in; in++) { - if (isspace((unsigned char) in[0]) && in[1]== 'i' && - in[2] == 'n' && - (in[3] == '\0' || isspace((unsigned char) in[3]))) - break; - } - if (*in == '\0') { - Parse_Error(level, "missing `in' in for"); - return 0; - } - - /* - * Grab the variables. - */ - accumFor.vars = NULL; - - while (ptr < in) { - wrd = ptr; - while (*ptr && !isspace((unsigned char) *ptr)) - ptr++; - ForAddVar(wrd, ptr - wrd); - while (*ptr && isspace((unsigned char) *ptr)) - ptr++; - } - - if (accumFor.nvars == 0) { - Parse_Error(level, "no iteration variables in for"); - return 0; - } - - /* At this point we should be pointing right at the "in" */ - assert(!memcmp(ptr, "in", 2)); - ptr += 2; - - while (*ptr && isspace((unsigned char) *ptr)) - ptr++; - - /* - * Make a list with the remaining words - */ - accumFor.lst = Lst_Init(FALSE); - buf = Buf_Init(0); - sub = Var_Subst(NULL, ptr, VAR_GLOBAL, FALSE); - -#define ADDWORD() \ - Buf_AddBytes(buf, ptr - wrd, (Byte *) wrd), \ - Buf_AddByte(buf, (Byte) '\0'), \ - Lst_AtFront(accumFor.lst, (ClientData) Buf_GetAll(buf, &varlen)), \ - Buf_Destroy(buf, FALSE) - - for (ptr = sub; *ptr && isspace((unsigned char) *ptr); ptr++) - continue; - - for (wrd = ptr; *ptr; ptr++) - if (isspace((unsigned char) *ptr)) { - ADDWORD(); - buf = Buf_Init(0); - while (*ptr && isspace((unsigned char) *ptr)) - ptr++; - wrd = ptr--; - } - if (DEBUG(FOR)) { - int i; - for (i = 0; i < accumFor.nvars; i++) { - (void) fprintf(stderr, "For: variable %s\n", accumFor.vars[i]); - } - (void) fprintf(stderr, "For: list %s\n", sub); - } - if (ptr - wrd > 0) - ADDWORD(); - else - Buf_Destroy(buf, TRUE); - free((Address) sub); - - accumFor.buf = Buf_Init(0); - forLevel++; - return 1; - } - else if (*ptr == '.') { - - for (ptr++; *ptr && isspace((unsigned char) *ptr); ptr++) - continue; - - if (strncmp(ptr, "endfor", 6) == 0 && - (isspace((unsigned char) ptr[6]) || !ptr[6])) { - if (DEBUG(FOR)) - (void) fprintf(stderr, "For: end for %d\n", forLevel); - if (--forLevel < 0) { - Parse_Error (level, "for-less endfor"); - return 0; - } - } - else if (strncmp(ptr, "for", 3) == 0 && - isspace((unsigned char) ptr[3])) { - forLevel++; - if (DEBUG(FOR)) - (void) fprintf(stderr, "For: new loop %d\n", forLevel); - } - } - - if (forLevel != 0) { - Buf_AddBytes(accumFor.buf, strlen(line), (Byte *) line); - Buf_AddByte(accumFor.buf, (Byte) '\n'); - return 1; - } - else { - return 0; - } -} - - -/*- - *----------------------------------------------------------------------- - * For_Run -- - * Run the for loop, imitating the actions of an include file - * - * Results: - * None. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -void -For_Run() -{ - For arg; - LstNode ln; - char **values; - int i, done = 0, len; - char *guy, *orig_guy, *old_guy; - - if (accumFor.buf == NULL || accumFor.vars == NULL || accumFor.lst == NULL) - return; - arg = accumFor; - accumFor.buf = NULL; - accumFor.vars = NULL; - accumFor.nvars = 0; - accumFor.lst = NULL; - - if (Lst_Open(arg.lst) != SUCCESS) - return; - - values = emalloc(arg.nvars * sizeof(char *)); - - while (!done) { - /* - * due to the dumb way this is set up, this loop must run - * backwards. - */ - for (i = arg.nvars - 1; i >= 0; i--) { - ln = Lst_Next(arg.lst); - if (ln == NILLNODE) { - if (i != arg.nvars-1) { - Parse_Error(PARSE_FATAL, - "Not enough words in for substitution list"); - } - done = 1; - break; - } else { - values[i] = (char *) Lst_Datum(ln); - } - } - if (done) - break; - - for (i = 0; i < arg.nvars; i++) { - Var_Set(arg.vars[i], values[i], VAR_GLOBAL, 0); - if (DEBUG(FOR)) - (void) fprintf(stderr, "--- %s = %s\n", arg.vars[i], - values[i]); - } - - /* - * Hack, hack, kludge. - * This is really ugly, but to do it any better way would require - * making major changes to var.c, which I don't want to get into - * yet. There is no mechanism for expanding some variables, only - * for expanding a single variable. That should be corrected, but - * not right away. (XXX) - */ - - guy = (char *) Buf_GetAll(arg.buf, &len); - orig_guy = guy; - for (i = 0; i < arg.nvars; i++) { - old_guy = guy; - guy = Var_Subst(arg.vars[i], guy, VAR_GLOBAL, FALSE); - if (old_guy != orig_guy) - free(old_guy); - } - Parse_FromString(guy); - - for (i = 0; i < arg.nvars; i++) - Var_Delete(arg.vars[i], VAR_GLOBAL); - } - - free(values); - - Lst_Close(arg.lst); - - for (i=0; i -#include -#include -#include - -/* - * getenv -- - * Returns ptr to value associated with name, if any, else NULL. - */ -char * -getenv(name) - const char *name; -{ - int offset; - char *__findenv(); - - return(__findenv(name, &offset)); -} - -/* - * __findenv -- - * Returns pointer to value associated with name, if any, else NULL. - * Sets offset to be the offset of the name/value combination in the - * environmental array, for use by setenv(3) and unsetenv(3). - * Explicitly removes '=' in argument name. - * - * This routine *should* be a static; don't use it. - */ -char * -__findenv(name, offset) - register char *name; - int *offset; -{ - extern char **environ; - register int len; - register char **P, *C; - - for (C = name, len = 0; *C && *C != '='; ++C, ++len); - for (P = environ; *P; ++P) - if (!strncmp(*P, name, len)) - if (*(C = *P + len) == '=') { - *offset = P - environ; - return(++C); - } - return(NULL); -} -#endif diff --git a/bootstrap/bmake/getopt.c b/bootstrap/bmake/getopt.c deleted file mode 100644 index 00b8e39ae27..00000000000 --- a/bootstrap/bmake/getopt.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 1987, 1993, 1994 - * 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. 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT) - -#if defined(LIBC_SCCS) && !defined(lint) -/* static char sccsid[] = "from: @(#)getopt.c 8.2 (Berkeley) 4/2/94"; */ -static char *rcsid = "$Id: getopt.c,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt = BADCH, /* character checked for validity */ - optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -getopt(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; -{ - extern char *__progname; - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - -#ifndef BSD4_4 - if (!__progname) { - if (__progname = strrchr(nargv[0], '/')) - ++__progname; - else - __progname = nargv[0]; - } -#endif - - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return (-1); - } - if (place[1] && *++place == '-' /* found "--" */ - && !place[1]) { /* and not "--foo" */ - ++optind; - place = EMSG; - return (-1); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, optopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means -1. - */ - if (optopt == (int)'-') - return (-1); - if (!*place) - ++optind; - if (opterr && *ostr != ':') - (void)fprintf(stderr, - "%s: illegal option -- %c\n", __progname, optopt); - return (BADCH); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } - else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (opterr) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - __progname, optopt); - return (BADCH); - } - else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return (optopt); /* dump back option letter */ -} -#endif -#ifdef MAIN -#ifndef BSD4_4 -char *__progname; -#endif - -int -main(argc, argv) - int argc; - char *argv[]; -{ - int c; - char *opts = argv[1]; - - --argc; - ++argv; - - while ((c = getopt(argc, argv, opts)) != EOF) { - switch (c) { - case '-': - if (optarg) - printf("--%s ", optarg); - break; - case '?': - exit(1); - break; - default: - if (optarg) - printf("-%c %s ", c, optarg); - else - printf("-%c ", c); - break; - } - } - - if (optind < argc) { - printf("-- "); - for (; optind < argc; ++optind) { - printf("%s ", argv[optind]); - } - } - printf("\n"); - exit(0); -} -#endif diff --git a/bootstrap/bmake/hash.c b/bootstrap/bmake/hash.c deleted file mode 100644 index edcfe86abef..00000000000 --- a/bootstrap/bmake/hash.c +++ /dev/null @@ -1,429 +0,0 @@ -/* $NetBSD: hash.c,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: hash.c,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)hash.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: hash.c,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/* hash.c -- - * - * This module contains routines to manipulate a hash table. - * See hash.h for a definition of the structure of the hash - * table. Hash tables grow automatically as the amount of - * information increases. - */ -#include "sprite.h" -#include "make.h" -#include "hash.h" - -/* - * Forward references to local procedures that are used before they're - * defined: - */ - -static void RebuildTable __P((Hash_Table *)); - -/* - * The following defines the ratio of # entries to # buckets - * at which we rebuild the table to make it larger. - */ - -#define rebuildLimit 3 - -/* - *--------------------------------------------------------- - * - * Hash_InitTable -- - * - * This routine just sets up the hash table. - * - * Results: - * None. - * - * Side Effects: - * Memory is allocated for the initial bucket area. - * - *--------------------------------------------------------- - */ - -void -Hash_InitTable(t, numBuckets) - register Hash_Table *t; /* Structure to use to hold table. */ - int numBuckets; /* How many buckets to create for starters. - * This number is rounded up to a power of - * two. If <= 0, a reasonable default is - * chosen. The table will grow in size later - * as needed. */ -{ - register int i; - register 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 = (struct Hash_Entry **)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(t) - Hash_Table *t; -{ - register struct Hash_Entry **hp, *h, *nexth = NULL; - register int i; - - for (hp = t->bucketPtr, i = t->size; --i >= 0;) { - for (h = *hp++; h != NULL; h = nexth) { - nexth = h->next; - free((char *)h); - } - } - free((char *)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(t, key) - Hash_Table *t; /* Hash table to search. */ - char *key; /* A hash key. */ -{ - register Hash_Entry *e; - register unsigned h; - register 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(t, key, newPtr) - register Hash_Table *t; /* Hash table to search. */ - char *key; /* A hash key. */ - Boolean *newPtr; /* Filled in with TRUE if new entry created, - * FALSE otherwise. */ -{ - register Hash_Entry *e; - register unsigned h; - register 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 = (Hash_Entry *) emalloc(sizeof(*e) + keylen); - hp = &t->bucketPtr[h & t->mask]; - e->next = *hp; - *hp = e; - e->clientData = NULL; - e->namehash = h; - (void) strcpy(e->name, p); - t->numEntries++; - - if (newPtr != NULL) - *newPtr = TRUE; - return (e); -} - -/* - *--------------------------------------------------------- - * - * Hash_DeleteEntry -- - * - * Delete the given hash table entry and free memory associated with - * it. - * - * Results: - * None. - * - * Side Effects: - * Hash chain that entry lives in is modified and memory is freed. - * - *--------------------------------------------------------- - */ - -void -Hash_DeleteEntry(t, e) - Hash_Table *t; - Hash_Entry *e; -{ - register 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((char *)p); - t->numEntries--; - return; - } - } - (void) write(2, "bad call to Hash_DeleteEntry\n", 29); - abort(); -} - -/* - *--------------------------------------------------------- - * - * Hash_EnumFirst -- - * This procedure sets things up for a complete search - * of all entries recorded in the hash table. - * - * 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(t, searchPtr) - Hash_Table *t; /* Table to be searched. */ - register Hash_Search *searchPtr;/* Area in which to keep state - * about search.*/ -{ - 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(searchPtr) - register Hash_Search *searchPtr; /* Area used to keep state about - search. */ -{ - register Hash_Entry *e; - Hash_Table *t = searchPtr->tablePtr; - - /* - * The hashEntryPtr field points to the most recently returned - * entry, or is nil if we are starting up. If not nil, we have - * to start at the next one in the chain. - */ - e = searchPtr->hashEntryPtr; - if (e != NULL) - e = e->next; - /* - * If the chain ran out, or if we are starting up, we need to - * find the next nonempty chain. - */ - while (e == NULL) { - if (searchPtr->nextIndex >= t->size) - return (NULL); - e = t->bucketPtr[searchPtr->nextIndex++]; - } - searchPtr->hashEntryPtr = e; - return (e); -} - -/* - *--------------------------------------------------------- - * - * RebuildTable -- - * This local routine makes a new hash table that - * is larger than the old one. - * - * Results: - * None. - * - * Side Effects: - * The entire hash table is moved, so any bucket numbers - * from the old table are invalid. - * - *--------------------------------------------------------- - */ - -static void -RebuildTable(t) - register Hash_Table *t; -{ - register Hash_Entry *e, *next = NULL, **hp, **xp; - register int i, mask; - register 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 = (struct Hash_Entry **) 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((char *)oldhp); -} diff --git a/bootstrap/bmake/hash.h b/bootstrap/bmake/hash.h deleted file mode 100644 index 4a66828b2bb..00000000000 --- a/bootstrap/bmake/hash.h +++ /dev/null @@ -1,118 +0,0 @@ -/* $NetBSD: hash.h,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)hash.h 8.1 (Berkeley) 6/6/93 - */ - -/* hash.h -- - * - * This file contains definitions used by the hash module, - * which maintains hash tables. - */ - -#ifndef _HASH -#define _HASH - -/* - * The following defines one entry in the hash table. - */ - -typedef struct Hash_Entry { - struct Hash_Entry *next; /* Used to link together all the - * entries associated with the same - * bucket. */ - ClientData clientData; /* Arbitrary piece of 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;/* Pointers to Hash_Entry, one - * for each bucket in the table. */ - int size; /* Actual size of array. */ - int numEntries; /* Number of entries in the table. */ - int mask; /* Used to select bits for hashing. */ -} Hash_Table; - -/* - * The following structure is used by the searching routines - * to record where we are in the search. - */ - -typedef struct Hash_Search { - Hash_Table *tablePtr; /* Table being searched. */ - int nextIndex; /* Next bucket to check (after current). */ - Hash_Entry *hashEntryPtr; /* Next entry to check in current bucket. */ -} Hash_Search; - -/* - * Macros. - */ - -/* - * ClientData Hash_GetValue(h) - * Hash_Entry *h; - */ - -#define Hash_GetValue(h) ((h)->clientData) - -/* - * Hash_SetValue(h, val); - * Hash_Entry *h; - * char *val; - */ - -#define Hash_SetValue(h, val) ((h)->clientData = (ClientData) (val)) - -/* - * Hash_Size(n) returns the number of words in an object of n bytes - */ - -#define Hash_Size(n) (((n) + sizeof (int) - 1) / sizeof (int)) - -void Hash_InitTable __P((Hash_Table *, int)); -void Hash_DeleteTable __P((Hash_Table *)); -Hash_Entry *Hash_FindEntry __P((Hash_Table *, char *)); -Hash_Entry *Hash_CreateEntry __P((Hash_Table *, char *, Boolean *)); -void Hash_DeleteEntry __P((Hash_Table *, Hash_Entry *)); -Hash_Entry *Hash_EnumFirst __P((Hash_Table *, Hash_Search *)); -Hash_Entry *Hash_EnumNext __P((Hash_Search *)); - -#endif /* _HASH */ diff --git a/bootstrap/bmake/install-sh b/bootstrap/bmake/install-sh deleted file mode 100755 index 4c57f6b824e..00000000000 --- a/bootstrap/bmake/install-sh +++ /dev/null @@ -1,201 +0,0 @@ -: -# NAME: -# install.sh - portable version of install(1) -# -# SYNOPSIS: -# install [-CNcs] [-f flags] [-i errs] [-o owner] [-g group] [-m mode] file1 file2 ... -# install -d [-i errs] [-o owner] [-g group] [-m mode] directory ... -# -# DESCRIPTION: -# Compatible with BSD install(1). Except that '-c' is always -# true and we always move an already installed target aside as -# this is important on many systems. Recent BSD install(1) -# versions have a '-b' option for this. -# -# -# OPTIONS: -# -b move previous target file aside (always true). -# -# -B "suffix" -# use "suffix" instead of .old for saving existing target. -# -# -c copy rather than move the file into place (always true). -# -# -C compare. Only install if target is missing or -# different. -# -# -N newer. Only install if target is missing or older. -# -# -s strip target -# -# -o "owner" -# make target owned by "owner" -# -# -g "group" -# make target group owned by "group" -# -# -m "mode" -# set permissions to "mode" -# -# -f "flags" -# Pass "flags" onto chflags(1) -# -# -i "errs" -# Ignore errors from steps indicated by "errs" (``s,o,g,m''). -# -# BUGS: -# The '-i' option is to save your sanity when 'bsd.prog.mk' -# insists on haveing a '-o' "owner" option which is doomed to -# fail on many systems. We ignore '-b', '-B' and '-c' options. -# -# AUTHOR: -# Simon J. Gerraty -# - -# RCSid: -# $Id: install-sh,v 1.1.1.1 2004/03/11 13:04:07 grant Exp $ -# -# @(#) Copyright (c) 1993 Simon J. Gerraty -# -# This file is provided in the hope that it will -# be of use. There is absolutely NO WARRANTY. -# Permission to copy, redistribute or otherwise -# use this file is hereby granted provided that -# the above copyright notice and this notice are -# left intact. -# -# Please send copies of changes and bug-fixes to: -# sjg@quick.com.au -# - -set -- `getopt B:bpxCNcsdo:g:m:i:f: $*` - -Mydir=`dirname $0` -[ -s $Mydir/.installrc ] && . $Mydir/.installrc - -owner=: -group=: -mode=: -strip=: -mkdirs= -compare=: -newer=: -chflags=: -LS1= -CP_P= - -while [ $# -gt 1 ] -do - case $1 in - --) shift; break;; - -p) CP_P=-p;; - -x) set -x;; - -B) OLD_EXT=$2; shift;; - -C) compare=Different;; - -N) newer=Newer; - # check if /bin/ls supports -1 - /bin/ls -1 $0 >/dev/null 2>&1 && LS1=1 - ;; - -o) owner="${CHOWN:-chown} $2 "; shift;; - -g) group="${CHGRP:-chgrp} $2 "; shift;; - -m) mode="${CHMOD:-chmod} $2 "; shift;; - -s) strip=${STRIP:-strip};; - -d) mkdirs="mkdir -p";; - -i) ignore_err="$ignore_err$2"; shift;; - -f) chflags="${CHFLAGS:-chflags} $2 "; shift;; - esac - shift -done - -Newer() { - n=`/bin/ls -t$LS1 $* 2>/dev/null | head -1` - [ $1 = $n ] -} - -Different() { - cmp -s $* - [ $? != 0 ] -} - -Err() { - case "$ignore_err" in - *$1*) ;; - *) exit 1;; - esac -} - -Setem() { - # the order is important - if [ ! -d $1 ]; then - $strip $1 || Err s - fi - $group $1 || Err g - $owner $1 || Err o - $mode $1 || Err m - $chflags $1 || Err f - return 0 -} - -# a bug in HP-UX's /bin/sh, means we need to re-set $* -# after any calls to add_path() -args="$*" - -# all this just for chown! -add_path () { [ -d $1 ] && eval ${2:-PATH}="\$${2:-PATH}:$1"; } -add_path /etc -add_path /usr/etc -add_path /sbin -add_path /usr/sbin - -# restore saved $* -set -- $args - -# make directories if needed -# and ensure mode etc are as desired -if [ "$mkdirs" ]; then - for d in $* - do - [ ! -d $d ] && $mkdirs $d - Setem $d - done - exit 0 # that's all we do -fi - -# install files -if [ $# -gt 2 ]; then - dest_dir=yes -elif [ $# -eq 1 ]; then - echo "what should I do with $*?" >&2 - exit 1 -fi - -# get list of files -while [ $# -gt 1 ] -do - files="$files $1" - shift -done -# last one is dest -dest=$1 -shift - - -if [ "$dest_dir" = yes -a ! -d $dest ]; then - echo "no directory $dest" >&2 - exit 1 -fi - -for f in $files -do - b=`basename $f` - if [ -d $dest ]; then - t=$dest/$b - else - t=$dest - fi - $newer $f $t || continue - $compare $f $t || continue - [ -f $t ] && { mv -f $t $t.old || exit 1; } - { cp $CP_P $f $t && Setem $t; } || exit 1 -done -exit 0 diff --git a/bootstrap/bmake/job.c b/bootstrap/bmake/job.c deleted file mode 100644 index fe958fa3ffe..00000000000 --- a/bootstrap/bmake/job.c +++ /dev/null @@ -1,3483 +0,0 @@ -/* $NetBSD: job.c,v 1.1.1.1 2004/03/11 13:04:08 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: job.c,v 1.1.1.1 2004/03/11 13:04:08 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)job.c 8.2 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: job.c,v 1.1.1.1 2004/03/11 13:04:08 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: job.c,v 1.1.1.1 2004/03/11 13:04:08 grant Exp $"); -#endif - -/*- - * job.c -- - * handle the creation etc. of our child processes. - * - * Interface: - * Job_Make Start the creation of the given target. - * - * Job_CatchChildren Check for and handle the termination of any - * children. This must be called reasonably - * frequently to keep the whole make going at - * a decent clip, since job table entries aren't - * removed until their process is caught this way. - * Its single argument is TRUE if the function - * should block waiting for a child to terminate. - * - * Job_CatchOutput Print any output our children have produced. - * Should also be called fairly frequently to - * keep the user informed of what's going on. - * If no output is waiting, it will block for - * a time given by the SEL_* constants, below, - * or until output is ready. - * - * Job_Init Called to intialize this module. in addition, - * any commands attached to the .BEGIN target - * are executed before this function returns. - * Hence, the makefile must have been parsed - * before this function is called. - * - * Job_End Cleanup any memory used. - * - * Job_Empty Return TRUE if the job table is completely - * empty. - * - * Job_ParseShell Given the line following a .SHELL target, parse - * the line as a shell specification. Returns - * FAILURE if the spec was incorrect. - * - * Job_Finish Perform any final processing which needs doing. - * This includes the execution of any commands - * which have been/were attached to the .END - * target. It should only be called when the - * job table is empty. - * - * Job_AbortAll Abort all currently running jobs. It doesn't - * handle output or do anything for the jobs, - * just kills them. It should only be called in - * an emergency, as it were. - * - * Job_CheckCommands Verify that the commands for a target are - * ok. Provide them if necessary and possible. - * - * Job_Touch Update a target without really updating it. - * - * Job_Wait Wait for all currently-running jobs to finish. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include -#include -#include -#include -#include "wait.h" -#include -#include -#include -#include -#include -#include -#ifndef RMT_WILL_WATCH -#if !defined(USE_SELECT) && defined(HAVE_POLL_H) -#include -#else -#ifndef USE_SELECT /* no poll.h */ -# define USE_SELECT -#endif -#if defined(HAVE_SYS_SELECT_H) -# include -#endif -#endif -#endif -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" -#include "pathnames.h" -#include "trace.h" -#ifdef REMOTE -#include "rmt.h" -# define STATIC -#else -# define STATIC static -#endif - -/* - * error handling variables - */ -static int errors = 0; /* number of errors reported */ -static int aborting = 0; /* why is the make aborting? */ -#define ABORT_ERROR 1 /* Because of an error */ -#define ABORT_INTERRUPT 2 /* Because it was interrupted */ -#define ABORT_WAIT 3 /* Waiting for jobs to finish */ - -/* - * XXX: Avoid SunOS bug... FILENO() is fp->_file, and file - * is a char! So when we go above 127 we turn negative! - */ -#define FILENO(a) ((unsigned) fileno(a)) - -/* - * post-make command processing. The node postCommands is really just the - * .END target but we keep it around to avoid having to search for it - * all the time. - */ -static GNode *postCommands; /* node containing commands to execute when - * everything else is done */ -static int numCommands; /* The number of commands actually printed - * for a target. Should this number be - * 0, no shell will be executed. */ - -/* - * Return values from JobStart. - */ -#define JOB_RUNNING 0 /* Job is running */ -#define JOB_ERROR 1 /* Error in starting the job */ -#define JOB_FINISHED 2 /* The job is already finished */ -#define JOB_STOPPED 3 /* The job is stopped */ - - - -/* - * Descriptions for various shells. - */ -static Shell shells[] = { - /* - * 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. - */ -{ - "csh", - TRUE, "unset verbose", "set verbose", "unset verbose", 10, - FALSE, "echo \"%s\"\n", "csh -c \"%s || exit 0\"", - "v", "e", -}, - /* - * SH description. Echo control is also possible and, under - * sun UNIX anyway, one can even control error checking. - */ -{ - "sh", - TRUE, "set -", "set -v", "set -", 5, - TRUE, "set -e", "set +e", -#ifdef OLDBOURNESHELL - FALSE, "echo \"%s\"\n", "sh -c '%s || exit 0'\n", -#endif -#ifdef __NetBSD__ - "vq", -#else - "v", -#endif - "e", -}, - /* - * UNKNOWN. - */ -{ - (char *) 0, - FALSE, (char *) 0, (char *) 0, (char *) 0, 0, - FALSE, (char *) 0, (char *) 0, - (char *) 0, (char *) 0, -} -}; -static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to - * which we pass all - * commands in the Makefile. - * It is set by the - * Job_ParseShell function */ -static char *shellPath = NULL, /* full pathname of - * executable image */ - *shellName = NULL, /* last component of shell */ - *shellArgv = NULL; /* Custom shell args */ - - -static int maxJobs; /* The most children we can run at once */ -static int maxLocal; /* The most local ones we can have */ -STATIC int nJobs; /* The number of children currently running */ -STATIC int nLocal; /* The number of local children */ -STATIC Lst jobs; /* The structures that describe them */ -static Boolean wantToken; /* we want a token */ - -/* - * Set of descriptors of pipes connected to - * the output channels of children - */ -#ifndef RMT_WILL_WATCH -#ifdef USE_SELECT -static fd_set outputs; -#else -static struct pollfd *fds = NULL; -static Job **jobfds = NULL; -static int nfds = 0; -static int maxfds = 0; -static void watchfd __P((Job *)); -static void clearfd __P((Job *)); -static int readyfd __P((Job *)); -#define JBSTART 256 -#define JBFACTOR 2 -#endif -#endif - -STATIC GNode *lastNode; /* The node for which output was most recently - * produced. */ -STATIC char *targFmt; /* Format string to use to head output from a - * job when it's not the most-recent job heard - * from */ -static Job tokenWaitJob; /* token wait pseudo-job */ -int job_pipe[2] = { -1, -1 }; /* job server pipes. */ - -#ifdef REMOTE -# define TARG_FMT "--- %s at %s ---\n" /* Default format */ -# define MESSAGE(fp, gn) \ - (void) fprintf(fp, targFmt, gn->name, gn->rem.hname) -#else -# define TARG_FMT "--- %s ---\n" /* Default format */ -# define MESSAGE(fp, gn) \ - (void) fprintf(fp, targFmt, gn->name) -#endif - -/* - * When JobStart attempts to run a job remotely but can't, and isn't allowed - * to run the job locally, or when Job_CatchChildren detects a job that has - * been migrated home, the job is placed on the stoppedJobs queue to be run - * when the next job finishes. - */ -STATIC Lst stoppedJobs; /* Lst of Job structures describing - * jobs that were stopped due to concurrency - * limits or migration home */ - - -#if defined(USE_PGRP) && defined(SYSV) -# define KILL(pid, sig) kill(-(pid), (sig)) -#else -# if defined(USE_PGRP) -# define KILL(pid, sig) killpg((pid), (sig)) -# else -# define KILL(pid, sig) kill((pid), (sig)) -# endif -#endif - -/* - * Grmpf... There is no way to set bits of the wait structure - * anymore with the stupid W*() macros. I liked the union wait - * stuff much more. So, we devise our own macros... This is - * really ugly, use dramamine sparingly. You have been warned. - */ -#ifndef W_STOPCODE -#define W_STOPCODE(sig) (((sig) << 8) | 0177) -#endif -#ifndef W_EXITCODE -#define W_EXITCODE(ret, sig) ((ret << 8) | (sig)) -#endif - -static int JobCondPassSig __P((ClientData, ClientData)); -static void JobPassSig __P((int)); -static void JobIgnoreSig __P((int)); -#ifdef USE_PGRP -static void JobContinueSig __P((int)); -#endif -static int JobCmpPid __P((ClientData, ClientData)); -static int JobPrintCommand __P((ClientData, ClientData)); -static int JobSaveCommand __P((ClientData, ClientData)); -static void JobClose __P((Job *)); -#ifdef REMOTE -static int JobCmpRmtID __P((Job *, int)); -# ifdef RMT_WILL_WATCH -static void JobLocalInput __P((int, Job *)); -# endif -#else -static void JobFinish __P((Job *, WAIT_T)); -static void JobExec __P((Job *, char **)); -#endif -static void JobMakeArgv __P((Job *, char **)); -static void JobRestart __P((Job *)); -static int JobStart __P((GNode *, int, Job *)); -static char *JobOutput __P((Job *, char *, char *, int)); -static void JobDoOutput __P((Job *, Boolean)); -static Shell *JobMatchShell __P((char *)); -static void JobInterrupt __P((int, int)); -static void JobRestartJobs __P((void)); -static void JobTokenAdd __P((void)); - -/*- - *----------------------------------------------------------------------- - * JobCondPassSig -- - * Pass a signal to a job if the job is remote or if USE_PGRP - * is defined. - * - * Results: - * === 0 - * - * Side Effects: - * None, except the job may bite it. - * - *----------------------------------------------------------------------- - */ -static int -JobCondPassSig(jobp, signop) - ClientData jobp; /* Job to biff */ - ClientData signop; /* Signal to send it */ -{ - Job *job = (Job *) jobp; - int signo = *(int *) signop; -#ifdef RMT_WANTS_SIGNALS - if (job->flags & JOB_REMOTE) { - (void) Rmt_Signal(job, signo); - } else { - KILL(job->pid, signo); - } -#else - /* - * Assume that sending the signal to job->pid will signal any remote - * job as well. - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobCondPassSig passing signal %d to child %d.\n", - signo, job->pid); - (void) fflush(stdout); - } - KILL(job->pid, signo); -#endif - return 0; -} - -/*- - *----------------------------------------------------------------------- - * JobIgnoreSig -- - * No-op signal handler so we wake up from poll. - * - * Results: - * None. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static void -JobIgnoreSig(signo) - int signo; /* The signal number we've received */ -{ - /* - * Do nothing. The mere fact that we've been called will cause - * poll/select in Job_CatchOutput() to return early. - */ -} - - -#ifdef USE_PGRP -/*- - *----------------------------------------------------------------------- - * JobContinueSig -- - * Resume all stopped jobs. - * - * Results: - * None. - * - * Side Effects: - * Jobs start running again. - * - *----------------------------------------------------------------------- - */ -static void -JobContinueSig(signo) - int signo; /* The signal number we've received */ -{ - if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTSTP, JobPassSig); - } - JobRestartJobs(); -} -#endif - -/*- - *----------------------------------------------------------------------- - * JobPassSig -- - * Pass a signal on to all remote jobs and to all local jobs if - * USE_PGRP is defined, then die ourselves. - * - * Results: - * None. - * - * Side Effects: - * We die by the same signal. - * - *----------------------------------------------------------------------- - */ -static void -JobPassSig(signo) - int signo; /* The signal number we've received */ -{ - sigset_t nmask, omask; - struct sigaction act; - int sigcont; - - if (DEBUG(JOB)) { - (void) fprintf(stdout, "JobPassSig(%d) called.\n", signo); - (void) fflush(stdout); - } - Lst_ForEach(jobs, JobCondPassSig, (ClientData) &signo); - - /* - * Deal with proper cleanup based on the signal received. We only run - * the .INTERRUPT target if the signal was in fact an interrupt. The other - * three termination signals are more of a "get out *now*" command. - */ - if (signo == SIGINT) { - JobInterrupt(TRUE, signo); - } else if ((signo == SIGHUP) || (signo == SIGTERM) || (signo == SIGQUIT)) { - JobInterrupt(FALSE, signo); - } - - /* - * Leave gracefully if SIGQUIT, rather than core dumping. - */ - if (signo == SIGQUIT) { - Finish(0); - } - - if (signo == SIGTSTP) { - Job_CatchChildren(FALSE); - } - /* - * Send ourselves the signal now we've given the message to everyone else. - * Note we block everything else possible while we're getting the signal. - * This ensures that all our jobs get continued when we wake up before - * we take any other signal. - */ - sigfillset(&nmask); - sigprocmask(SIG_SETMASK, &nmask, &omask); - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - sigaction(signo, &act, NULL); - - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobPassSig passing signal %d to self.\n", signo); - (void) fflush(stdout); - } - - (void) kill(getpid(), signo); - if (signo != SIGTSTP) { - sigcont = SIGCONT; - Lst_ForEach(jobs, JobCondPassSig, (ClientData) &sigcont); - } - - (void) sigprocmask(SIG_SETMASK, &omask, NULL); - sigprocmask(SIG_SETMASK, &omask, NULL); - if (signo != SIGCONT && signo != SIGTSTP) { - act.sa_handler = JobPassSig; - sigaction(sigcont, &act, NULL); - } -} - -/*- - *----------------------------------------------------------------------- - * JobCmpPid -- - * Compare the pid of the job with the given pid and return 0 if they - * are equal. This function is called from Job_CatchChildren via - * Lst_Find to find the job descriptor of the finished job. - * - * Results: - * 0 if the pid's match - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -JobCmpPid(job, pid) - ClientData job; /* job to examine */ - ClientData pid; /* process id desired */ -{ - return *(int *) pid - ((Job *) job)->pid; -} - -#ifdef REMOTE -/*- - *----------------------------------------------------------------------- - * JobCmpRmtID -- - * Compare the rmtID of the job with the given rmtID and return 0 if they - * are equal. - * - * Results: - * 0 if the rmtID's match - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static int -JobCmpRmtID(job, rmtID) - ClientData job; /* job to examine */ - ClientData rmtID; /* remote id desired */ -{ - return(*(int *) rmtID - *(int *) job->rmtID); -} -#endif - -/*- - *----------------------------------------------------------------------- - * JobPrintCommand -- - * Put out another command for the given job. If the command starts - * with an @ or a - we process it specially. In the former case, - * so long as the -s and -n flags weren't given to make, we stick - * a shell-specific echoOff command in the script. In the latter, - * we ignore errors for the entire job, unless the shell has error - * control. - * If the command is just "..." we take all future commands for this - * job to be commands to be executed once the entire graph has been - * made and return non-zero to signal that the end of the commands - * was reached. These commands are later attached to the postCommands - * node and executed by Job_End when all things are done. - * This function is called from JobStart via Lst_ForEach. - * - * Results: - * Always 0, unless the command was "..." - * - * Side Effects: - * If the command begins with a '-' and the shell has no error control, - * the JOB_IGNERR flag is set in the job descriptor. - * If the command is "..." and we're not ignoring such things, - * tailCmds is set to the successor node of the cmd. - * numCommands is incremented if the command is actually printed. - *----------------------------------------------------------------------- - */ -static int -JobPrintCommand(cmdp, jobp) - ClientData cmdp; /* command string to print */ - ClientData jobp; /* job for which to print it */ -{ - Boolean noSpecials; /* true if we shouldn't worry about - * inserting special commands into - * the input stream. */ - Boolean shutUp = FALSE; /* true if we put a no echo command - * into the command file */ - Boolean errOff = FALSE; /* true if we turned error checking - * off before printing the command - * and need to turn it back on */ - char *cmdTemplate; /* Template to use when printing the - * command */ - char *cmdStart; /* Start of expanded command */ - LstNode cmdNode; /* Node for replacing the command */ - char *cmd = (char *) cmdp; - Job *job = (Job *) jobp; - char *cp; - - noSpecials = NoExecute(job->node); - - if (strcmp(cmd, "...") == 0) { - job->node->type |= OP_SAVE_CMDS; - if ((job->flags & JOB_IGNDOTS) == 0) { - job->tailCmds = Lst_Succ(Lst_Member(job->node->commands, - (ClientData)cmd)); - return 1; - } - return 0; - } - -#define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \ - (void) fprintf(stdout, fmt, arg); \ - (void) fflush(stdout); \ - } \ - (void) fprintf(job->cmdFILE, fmt, arg); \ - (void) fflush(job->cmdFILE); - - numCommands += 1; - - /* - * For debugging, we replace each command with the result of expanding - * the variables in the command. - */ - cmdNode = Lst_Member(job->node->commands, (ClientData)cmd); - cmdStart = cmd = Var_Subst(NULL, cmd, job->node, FALSE); - Lst_Replace(cmdNode, (ClientData)cmdStart); - - cmdTemplate = "%s\n"; - - /* - * Check for leading @' and -'s to control echoing and error checking. - */ - while (*cmd == '@' || *cmd == '-') { - if (*cmd == '@') { - shutUp = TRUE; - } else { - errOff = TRUE; - } - cmd++; - } - - while (isspace((unsigned char) *cmd)) - cmd++; - - if (shutUp) { - if (!(job->flags & JOB_SILENT) && !noSpecials && - commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - } else { - shutUp = FALSE; - } - } - - if (errOff) { - if ( !(job->flags & JOB_IGNERR) && !noSpecials) { - if (commandShell->hasErrCtl) { - /* - * we don't want the error-control commands showing - * up either, so we turn off echoing while executing - * them. We could put another field in the shell - * structure to tell JobDoOutput to look for this - * string too, but why make it any more complex than - * it already is? - */ - if (!(job->flags & JOB_SILENT) && !shutUp && - commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - DBPRINTF("%s\n", commandShell->ignErr); - DBPRINTF("%s\n", commandShell->echoOn); - } else { - DBPRINTF("%s\n", commandShell->ignErr); - } - } else if (commandShell->ignErr && - (*commandShell->ignErr != '\0')) - { - /* - * The shell has no error control, so we need to be - * weird to get it to ignore any errors from the command. - * If echoing is turned on, we turn it off and use the - * errCheck template to echo the command. Leave echoing - * off so the user doesn't see the weirdness we go through - * to ignore errors. Set cmdTemplate to use the weirdness - * instead of the simple "%s\n" template. - */ - if (!(job->flags & JOB_SILENT) && !shutUp && - commandShell->hasEchoCtl) { - DBPRINTF("%s\n", commandShell->echoOff); - DBPRINTF(commandShell->errCheck, cmd); - shutUp = TRUE; - } - cmdTemplate = commandShell->ignErr; - /* - * The error ignoration (hee hee) is already taken care - * of by the ignErr template, so pretend error checking - * is still on. - */ - errOff = FALSE; - } else { - errOff = FALSE; - } - } else { - errOff = FALSE; - } - } - - if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0 && - (job->flags & JOB_TRACED) == 0) { - DBPRINTF("set -%s\n", "x"); - job->flags |= JOB_TRACED; - } - - if ((cp = Check_Cwd_Cmd(cmd)) != NULL) { - DBPRINTF("test -d %s && ", cp); - DBPRINTF("cd %s; ", cp); - } - DBPRINTF(cmdTemplate, cmd); - free(cmdStart); - - if (errOff) { - /* - * If echoing is already off, there's no point in issuing the - * echoOff command. Otherwise we issue it and pretend it was on - * for the whole command... - */ - if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl){ - DBPRINTF("%s\n", commandShell->echoOff); - shutUp = TRUE; - } - DBPRINTF("%s\n", commandShell->errCheck); - } - if (shutUp) { - DBPRINTF("%s\n", commandShell->echoOn); - } - return 0; -} - -/*- - *----------------------------------------------------------------------- - * JobSaveCommand -- - * Save a command to be executed when everything else is done. - * Callback function for JobFinish... - * - * Results: - * Always returns 0 - * - * Side Effects: - * The command is tacked onto the end of postCommands's commands list. - * - *----------------------------------------------------------------------- - */ -static int -JobSaveCommand(cmd, gn) - ClientData cmd; - ClientData gn; -{ - cmd = (ClientData) Var_Subst(NULL, (char *) cmd, (GNode *) gn, FALSE); - (void) Lst_AtEnd(postCommands->commands, cmd); - return(0); -} - - -/*- - *----------------------------------------------------------------------- - * JobClose -- - * Called to close both input and output pipes when a job is finished. - * - * Results: - * Nada - * - * Side Effects: - * The file descriptors associated with the job are closed. - * - *----------------------------------------------------------------------- - */ -static void -JobClose(job) - Job *job; -{ - if (usePipes && (job->flags & JOB_FIRST)) { -#ifdef RMT_WILL_WATCH - Rmt_Ignore(job->inPipe); -#else -#ifdef USE_SELECT - FD_CLR(job->inPipe, &outputs); -#else - clearfd(job); -#endif -#endif - if (job->outPipe != job->inPipe) { - (void) close(job->outPipe); - } - JobDoOutput(job, TRUE); - (void) close(job->inPipe); - } else { - (void) close(job->outFd); - JobDoOutput(job, TRUE); - } -} - -/*- - *----------------------------------------------------------------------- - * JobFinish -- - * Do final processing for the given job including updating - * parents and starting new jobs as available/necessary. Note - * that we pay no attention to the JOB_IGNERR flag here. - * This is because when we're called because of a noexecute flag - * or something, jstat.w_status is 0 and when called from - * Job_CatchChildren, the status is zeroed if it s/b ignored. - * - * Results: - * None - * - * Side Effects: - * Some nodes may be put on the toBeMade queue. - * Final commands for the job are placed on postCommands. - * - * If we got an error and are aborting (aborting == ABORT_ERROR) and - * the job list is now empty, we are done for the day. - * If we recognized an error (errors !=0), we set the aborting flag - * to ABORT_ERROR so no more jobs will be started. - *----------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static void -JobFinish (job, status) - Job *job; /* job to finish */ - WAIT_T status; /* sub-why job went away */ -{ - Boolean done; - - if ((WIFEXITED(status) && - (((WEXITSTATUS(status) != 0) && !(job->flags & JOB_IGNERR)))) || - WIFSIGNALED(status)) - { - /* - * If it exited non-zero and either we're doing things our - * way or we're not ignoring errors, the job is finished. - * Similarly, if the shell died because of a signal - * the job is also finished. In these - * cases, finish out the job's output before printing the exit - * status... - */ -#ifdef REMOTE - KILL(job->pid, SIGCONT); -#endif - JobClose(job); - if (job->cmdFILE != NULL && job->cmdFILE != stdout) { - (void) fclose(job->cmdFILE); - job->cmdFILE = NULL; - } - done = TRUE; -#ifdef REMOTE - if (job->flags & JOB_REMOTE) - Rmt_Done(job->rmtID, job->node); -#endif - } else if (WIFEXITED(status)) { - /* - * Deal with ignored errors in -B mode. We need to print a message - * telling of the ignored error as well as setting status.w_status - * to 0 so the next command gets run. To do this, we set done to be - * TRUE if in -B mode and the job exited non-zero. - */ - done = WEXITSTATUS(status) != 0; - /* - * Old comment said: "Note we don't - * want to close down any of the streams until we know we're at the - * end." - * But we do. Otherwise when are we going to print the rest of the - * stuff? - */ - JobClose(job); -#ifdef REMOTE - if (job->flags & JOB_REMOTE) - Rmt_Done(job->rmtID, job->node); -#endif /* REMOTE */ - } else { - /* - * No need to close things down or anything. - */ - done = FALSE; - } - - if (done || - WIFSTOPPED(status) || - (WIFSIGNALED(status) && (WTERMSIG(status) == SIGCONT))) - { - FILE *out; - - if (compatMake && !usePipes && (job->flags & JOB_IGNERR)) { - /* - * If output is going to a file and this job is ignoring - * errors, arrange to have the exit status sent to the - * output file as well. - */ - out = fdopen(job->outFd, "w"); - if (out == NULL) - Punt("Cannot fdopen"); - } else { - out = stdout; - } - - if (WIFEXITED(status)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Process %d exited.\n", job->pid); - (void) fflush(stdout); - } - if (WEXITSTATUS(status) != 0) { - if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); - lastNode = job->node; - } - fprintf (out, "*** Error code %d%s\n", - WEXITSTATUS(status), - (job->flags & JOB_IGNERR) ? " (ignored)" : ""); - - if (job->flags & JOB_IGNERR) { - WAIT_STATUS(status) = 0; - } - } else if (DEBUG(JOB)) { - if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); - lastNode = job->node; - } - (void) fprintf(out, "*** Completed successfully\n"); - } - } else if (WIFSTOPPED(status) && WSTOPSIG(status) != SIGCONT) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Process %d stopped.\n", job->pid); - (void) fflush(stdout); - } - if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); - lastNode = job->node; - } - if (!(job->flags & JOB_REMIGRATE)) { - switch (WSTOPSIG(status)) { - case SIGTSTP: - (void) fprintf(out, "*** Suspended\n"); - break; - case SIGSTOP: - (void) fprintf(out, "*** Stopped\n"); - break; - default: - (void) fprintf(out, "*** Stopped -- signal %d\n", - WSTOPSIG(status)); - } - } - job->flags |= JOB_RESUME; - (void)Lst_AtEnd(stoppedJobs, (ClientData)job); -#ifdef REMOTE - if (job->flags & JOB_REMIGRATE) - JobRestart(job); -#endif - (void) fflush(out); - return; - } else if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGCONT) { - /* - * If the beastie has continued, shift the Job from the stopped - * list to the running one (or re-stop it if concurrency is - * exceeded) and go and get another child. - */ - if (job->flags & (JOB_RESUME|JOB_REMIGRATE|JOB_RESTART)) { - if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); - lastNode = job->node; - } - (void) fprintf(out, "*** Continued\n"); - } - if (!(job->flags & JOB_CONTINUING)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "Warning: process %d was not continuing.\n", - job->pid); - (void) fflush(stdout); - } -#ifdef notdef - /* - * We don't really want to restart a job from scratch just - * because it continued, especially not without killing the - * continuing process! That's why this is ifdef'ed out. - * FD - 9/17/90 - */ - JobRestart(job); -#endif - } - job->flags &= ~JOB_CONTINUING; - Lst_AtEnd(jobs, (ClientData)job); - nJobs += 1; - if (!(job->flags & JOB_REMOTE)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "Process %d is continuing locally.\n", - job->pid); - (void) fflush(stdout); - } - nLocal += 1; - } - (void) fflush(out); - return; - } else { - if (usePipes && job->node != lastNode) { - MESSAGE(out, job->node); - lastNode = job->node; - } - (void) fprintf(out, "*** Signal %d\n", WTERMSIG(status)); - } - - (void) fflush(out); - } - - /* - * Now handle the -B-mode stuff. If the beast still isn't finished, - * try and restart the job on the next command. If JobStart says it's - * ok, it's ok. If there's an error, this puppy is done. - */ - if (compatMake && (WIFEXITED(status) && - !Lst_IsAtEnd(job->node->commands))) { - switch (JobStart(job->node, job->flags & JOB_IGNDOTS, job)) { - case JOB_RUNNING: - done = FALSE; - break; - case JOB_ERROR: - done = TRUE; - WSET_EXITCODE(status, 1, 0); - break; - case JOB_FINISHED: - /* - * If we got back a JOB_FINISHED code, JobStart has already - * called Make_Update and freed the job descriptor. We set - * done to false here to avoid fake cycles and double frees. - * JobStart needs to do the update so we can proceed up the - * graph when given the -n flag.. - */ - done = FALSE; - break; - } - } else { - done = TRUE; - } - - if (done) { - Trace_Log(JOBEND, job); - if (!compatMake && !(job->flags & JOB_SPECIAL)) { - if ((WAIT_STATUS(status) != 0) || - (aborting == ABORT_ERROR) || - (aborting == ABORT_INTERRUPT)) - Job_TokenReturn(); - } - - } - - if (done && - (aborting != ABORT_ERROR) && - (aborting != ABORT_INTERRUPT) && - (WAIT_STATUS(status) == 0)) - { - /* - * As long as we aren't aborting and the job didn't return a non-zero - * status that we shouldn't ignore, we call Make_Update to update - * the parents. In addition, any saved commands for the node are placed - * on the .END target. - */ - if (job->tailCmds != NILLNODE) { - Lst_ForEachFrom(job->node->commands, job->tailCmds, - JobSaveCommand, - (ClientData)job->node); - } - job->node->made = MADE; - if (!(job->flags & JOB_SPECIAL)) - Job_TokenReturn(); - Make_Update(job->node); - free((Address)job); - } else if (WAIT_STATUS(status)) { - errors += 1; - free((Address)job); - } - JobRestartJobs(); - - /* - * Set aborting if any error. - */ - if (errors && !keepgoing && (aborting != ABORT_INTERRUPT)) { - /* - * If we found any errors in this batch of children and the -k flag - * wasn't given, we set the aborting flag so no more jobs get - * started. - */ - aborting = ABORT_ERROR; - } - - if ((aborting == ABORT_ERROR) && Job_Empty()) { - /* - * If we are aborting and the job table is now empty, we finish. - */ - Finish(errors); - } -} - -/*- - *----------------------------------------------------------------------- - * Job_Touch -- - * Touch the given target. Called by JobStart when the -t flag was - * given - * - * Results: - * None - * - * Side Effects: - * The data modification of the file is changed. In addition, if the - * file did not exist, it is created. - *----------------------------------------------------------------------- - */ -void -Job_Touch(gn, silent) - GNode *gn; /* the node of the file to touch */ - Boolean silent; /* TRUE if should not print messages */ -{ - int streamID; /* ID of stream opened to do the touch */ - struct utimbuf times; /* Times for utime() call */ - - if (gn->type & (OP_JOIN|OP_USE|OP_USEBEFORE|OP_EXEC|OP_OPTIONAL|OP_PHONY)) { - /* - * .JOIN, .USE, .ZEROTIME and .OPTIONAL targets are "virtual" targets - * and, as such, shouldn't really be created. - */ - return; - } - - if (!silent || NoExecute(gn)) { - (void) fprintf(stdout, "touch %s\n", gn->name); - (void) fflush(stdout); - } - - if (NoExecute(gn)) { - return; - } - - if (gn->type & OP_ARCHV) { - Arch_Touch(gn); - } else if (gn->type & OP_LIB) { - Arch_TouchLib(gn); - } else { - char *file = gn->path ? gn->path : gn->name; - - times.actime = times.modtime = now; - if (utime(file, ×) < 0){ - streamID = open(file, O_RDWR | O_CREAT, 0666); - - if (streamID >= 0) { - char c; - - /* - * Read and write a byte to the file to change the - * modification time, then close the file. - */ - if (read(streamID, &c, 1) == 1) { - (void) lseek(streamID, (off_t)0, SEEK_SET); - (void) write(streamID, &c, 1); - } - - (void) close(streamID); - } else { - (void) fprintf(stdout, "*** couldn't touch %s: %s", - file, strerror(errno)); - (void) fflush(stdout); - } - } - } -} - -/*- - *----------------------------------------------------------------------- - * Job_CheckCommands -- - * Make sure the given node has all the commands it needs. - * - * Results: - * TRUE if the commands list is/was ok. - * - * Side Effects: - * The node will have commands from the .DEFAULT rule added to it - * if it needs them. - *----------------------------------------------------------------------- - */ -Boolean -Job_CheckCommands(gn, abortProc) - GNode *gn; /* The target whose commands need - * verifying */ - void (*abortProc) __P((char *, ...)); - /* Function to abort with message */ -{ - if (OP_NOP(gn->type) && Lst_IsEmpty(gn->commands) && - (gn->type & OP_LIB) == 0) { - /* - * No commands. Look for .DEFAULT rule from which we might infer - * commands - */ - if ((DEFAULT != NILGNODE) && !Lst_IsEmpty(DEFAULT->commands)) { - char *p1; - /* - * Make only looks for a .DEFAULT if the node was never the - * target of an operator, so that's what we do too. If - * a .DEFAULT was given, we substitute its commands for gn's - * commands and set the IMPSRC variable to be the target's name - * The DEFAULT node acts like a transformation rule, in that - * gn also inherits any attributes or sources attached to - * .DEFAULT itself. - */ - Make_HandleUse(DEFAULT, gn); - Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), gn, 0); - if (p1) - free(p1); - } else if (Dir_MTime(gn) == 0) { - /* - * The node wasn't the target of an operator we have no .DEFAULT - * rule to go on and the target doesn't already exist. There's - * nothing more we can do for this branch. If the -k flag wasn't - * given, we stop in our tracks, otherwise we just don't update - * this node's parents so they never get examined. - */ - static const char msg[] = ": don't know how to make"; - - if (gn->type & OP_OPTIONAL) { - (void) fprintf(stdout, "%s%s %s(ignored)\n", progname, - msg, gn->name); - (void) fflush(stdout); - } else if (keepgoing) { - (void) fprintf(stdout, "%s%s %s(continuing)\n", progname, - msg, gn->name); - (void) fflush(stdout); - return FALSE; - } else { - (*abortProc)("%s%s %s. Stop", progname, msg, gn->name); - return FALSE; - } - } - } - return TRUE; -} -#ifdef RMT_WILL_WATCH -/*- - *----------------------------------------------------------------------- - * JobLocalInput -- - * Handle a pipe becoming readable. Callback function for Rmt_Watch - * - * Results: - * None - * - * Side Effects: - * JobDoOutput is called. - * - *----------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static void -JobLocalInput(stream, job) - int stream; /* Stream that's ready (ignored) */ - Job *job; /* Job to which the stream belongs */ -{ - JobDoOutput(job, FALSE); -} -#endif /* RMT_WILL_WATCH */ - -/*- - *----------------------------------------------------------------------- - * JobExec -- - * Execute the shell for the given job. Called from JobStart and - * JobRestart. - * - * Results: - * None. - * - * Side Effects: - * A shell is executed, outputs is altered and the Job structure added - * to the job table. - * - *----------------------------------------------------------------------- - */ -static void -JobExec(job, argv) - Job *job; /* Job to execute */ - char **argv; -{ - int cpid; /* ID of new child */ - - job->flags &= ~JOB_TRACED; - - if (DEBUG(JOB)) { - int i; - - (void) fprintf(stdout, "Running %s %sly\n", job->node->name, - job->flags&JOB_REMOTE?"remote":"local"); - (void) fprintf(stdout, "\tCommand: "); - for (i = 0; argv[i] != NULL; i++) { - (void) fprintf(stdout, "%s ", argv[i]); - } - (void) fprintf(stdout, "\n"); - (void) fflush(stdout); - } - - /* - * Some jobs produce no output and it's disconcerting to have - * no feedback of their running (since they produce no output, the - * banner with their name in it never appears). This is an attempt to - * provide that feedback, even if nothing follows it. - */ - if ((lastNode != job->node) && (job->flags & JOB_FIRST) && - !(job->flags & JOB_SILENT)) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } - -#ifdef RMT_NO_EXEC - if (job->flags & JOB_REMOTE) { - goto jobExecFinish; - } -#endif /* RMT_NO_EXEC */ - - if ((cpid = vfork()) == -1) { - Punt("Cannot vfork: %s", strerror(errno)); - } else if (cpid == 0) { - - /* - * Must duplicate the input stream down to the child's input and - * reset it to the beginning (again). Since the stream was marked - * close-on-exec, we must clear that bit in the new input. - */ - if (dup2(FILENO(job->cmdFILE), 0) == -1) - Punt("Cannot dup2: %s", strerror(errno)); - (void) fcntl(0, F_SETFD, 0); - (void) lseek(0, (off_t)0, SEEK_SET); - - if (job->node->type & OP_MAKE) { - /* - * Pass job token pipe to submakes. - */ - fcntl(job_pipe[0], F_SETFD, 0); - fcntl(job_pipe[1], F_SETFD, 0); - } - - if (usePipes) { - /* - * Set up the child's output to be routed through the pipe - * we've created for it. - */ - if (dup2(job->outPipe, 1) == -1) - Punt("Cannot dup2: %s", strerror(errno)); - } else { - /* - * We're capturing output in a file, so we duplicate the - * descriptor to the temporary file into the standard - * output. - */ - if (dup2(job->outFd, 1) == -1) - Punt("Cannot dup2: %s", strerror(errno)); - } - /* - * The output channels are marked close on exec. This bit was - * duplicated by the dup2 (on some systems), so we have to clear - * it before routing the shell's error output to the same place as - * its standard output. - */ - (void) fcntl(1, F_SETFD, 0); - if (dup2(1, 2) == -1) - Punt("Cannot dup2: %s", strerror(errno)); - -#ifdef USE_PGRP - /* - * We want to switch the child into a different process family 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) - (void) setsid(); -# else - (void) setpgid(0, getpid()); -# endif -#endif /* USE_PGRP */ - -#ifdef REMOTE - if (job->flags & JOB_REMOTE) { - Rmt_Exec(shellPath, argv, FALSE); - } else -#endif /* REMOTE */ - { - (void) execv(shellPath, argv); - execError(shellPath); - } - _exit(1); - } else { -#ifdef REMOTE - sigset_t nmask, omask; - sigemptyset(&nmask); - sigaddset(&nmask, SIGCHLD); - sigprocmask(SIG_BLOCK, &nmask, &omask); -#endif - job->pid = cpid; - - Trace_Log(JOBSTART, job); - - if (usePipes && (job->flags & JOB_FIRST)) { - /* - * The first time a job is run for a node, we set the current - * position in the buffer to the beginning and mark another - * stream to watch in the outputs mask - */ - job->curPos = 0; - -#ifdef RMT_WILL_WATCH - Rmt_Watch(job->inPipe, JobLocalInput, job); -#else -#ifdef USE_SELECT - FD_SET(job->inPipe, &outputs); -#else - watchfd(job); -#endif -#endif /* RMT_WILL_WATCH */ - } - - if (job->flags & JOB_REMOTE) { -#ifndef REMOTE - job->rmtID = 0; -#else - job->rmtID = Rmt_LastID(job->pid); -#endif /* REMOTE */ - } else { - nLocal += 1; - /* - * XXX: Used to not happen if REMOTE. Why? - */ - if (job->cmdFILE != NULL && job->cmdFILE != stdout) { - (void) fclose(job->cmdFILE); - job->cmdFILE = NULL; - } - } -#ifdef REMOTE - sigprocmask(SIG_SETMASK, &omask, NULL); -#endif - } - -#ifdef RMT_NO_EXEC -jobExecFinish: -#endif - /* - * Now the job is actually running, add it to the table. - */ - nJobs += 1; - (void) Lst_AtEnd(jobs, (ClientData)job); -} - -/*- - *----------------------------------------------------------------------- - * JobMakeArgv -- - * Create the argv needed to execute the shell for a given job. - * - * - * Results: - * - * Side Effects: - * - *----------------------------------------------------------------------- - */ -static void -JobMakeArgv(job, argv) - Job *job; - char **argv; -{ - int argc; - static char args[10]; /* For merged arguments */ - - argv[0] = shellName; - argc = 1; - - if ((commandShell->exit && (*commandShell->exit != '-')) || - (commandShell->echo && (*commandShell->echo != '-'))) - { - /* - * At least one of the flags doesn't have a minus before it, so - * merge them together. Have to do this because the *(&(@*#*&#$# - * Bourne shell thinks its second argument is a file to source. - * Grrrr. Note the ten-character limitation on the combined arguments. - */ - (void)snprintf(args, sizeof(args), "-%s%s", - ((job->flags & JOB_IGNERR) ? "" : - (commandShell->exit ? commandShell->exit : "")), - ((job->flags & JOB_SILENT) ? "" : - (commandShell->echo ? commandShell->echo : ""))); - - if (args[1]) { - argv[argc] = args; - argc++; - } - } else { - if (!(job->flags & JOB_IGNERR) && commandShell->exit) { - argv[argc] = commandShell->exit; - argc++; - } - if (!(job->flags & JOB_SILENT) && commandShell->echo) { - argv[argc] = commandShell->echo; - argc++; - } - } - argv[argc] = NULL; -} - -/*- - *----------------------------------------------------------------------- - * JobRestart -- - * Restart a job that stopped for some reason. - * - * Results: - * None. - * - *----------------------------------------------------------------------- - */ -static void -JobRestart(job) - Job *job; /* Job to restart */ -{ -#ifdef REMOTE - int host; -#endif - - if (job->flags & JOB_REMIGRATE) { - if ( -#ifdef REMOTE - verboseRemigrates || -#endif - DEBUG(JOB)) { - (void) fprintf(stdout, "*** remigrating %x(%s)\n", - job->pid, job->node->name); - (void) fflush(stdout); - } - -#ifdef REMOTE - if (!Rmt_ReExport(job->pid, job->node, &host)) { - if (verboseRemigrates || DEBUG(JOB)) { - (void) fprintf(stdout, "*** couldn't migrate...\n"); - (void) fflush(stdout); - } -#endif - if (nLocal != maxLocal) { - /* - * Job cannot be remigrated, but there's room on the local - * machine, so resume the job and note that another - * local job has started. - */ - if ( -#ifdef REMOTE - verboseRemigrates || -#endif - DEBUG(JOB)) { - (void) fprintf(stdout, "*** resuming on local machine\n"); - (void) fflush(stdout); - } - KILL(job->pid, SIGCONT); - nLocal +=1; -#ifdef REMOTE - job->flags &= ~(JOB_REMIGRATE|JOB_RESUME|JOB_REMOTE); - job->flags |= JOB_CONTINUING; -#else - job->flags &= ~(JOB_REMIGRATE|JOB_RESUME); -#endif - } else { - /* - * Job cannot be restarted. Mark the table as full and - * place the job back on the list of stopped jobs. - */ - if ( -#ifdef REMOTE - verboseRemigrates || -#endif - DEBUG(JOB)) { - (void) fprintf(stdout, "*** holding\n"); - (void) fflush(stdout); - } - (void)Lst_AtFront(stoppedJobs, (ClientData)job); - return; - } -#ifdef REMOTE - } else { - /* - * Clear out the remigrate and resume flags. Set the continuing - * flag so we know later on that the process isn't exiting just - * because of a signal. - */ - job->flags &= ~(JOB_REMIGRATE|JOB_RESUME); - job->flags |= JOB_CONTINUING; - job->rmtID = host; - } -#endif - - (void)Lst_AtEnd(jobs, (ClientData)job); - nJobs += 1; - } else if (job->flags & JOB_RESTART) { - /* - * Set up the control arguments to the shell. This is based on the - * flags set earlier for this job. If the JOB_IGNERR flag is clear, - * the 'exit' flag of the commandShell is used to cause it to exit - * upon receiving an error. If the JOB_SILENT flag is clear, the - * 'echo' flag of the commandShell is used to get it to start echoing - * as soon as it starts processing commands. - */ - char *argv[10]; - - JobMakeArgv(job, argv); - - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Restarting %s...", job->node->name); - (void) fflush(stdout); - } -#ifdef REMOTE - if ((job->node->type&OP_NOEXPORT) || - (nLocal < maxLocal && runLocalFirst) -# ifdef RMT_NO_EXEC - || !Rmt_Export(shellPath, argv, job) -# else - || !Rmt_Begin(shellPath, argv, job->node) -# endif -#endif - { - if (((nLocal >= maxLocal) && !(job->flags & JOB_SPECIAL))) { - /* - * Can't be exported and not allowed to run locally -- put it - * back on the hold queue and mark the table full - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, "holding\n"); - (void) fflush(stdout); - } - (void)Lst_AtFront(stoppedJobs, (ClientData)job); - return; - } else { - /* - * Job may be run locally. - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, "running locally\n"); - (void) fflush(stdout); - } - job->flags &= ~JOB_REMOTE; - } - } -#ifdef REMOTE - else { - /* - * Can be exported. Hooray! - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, "exporting\n"); - (void) fflush(stdout); - } - job->flags |= JOB_REMOTE; - } -#endif - JobExec(job, argv); - } else { - /* - * The job has stopped and needs to be restarted. Why it stopped, - * we don't know... - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Resuming %s...", job->node->name); - (void) fflush(stdout); - } - if (((job->flags & JOB_REMOTE) || - (nLocal < maxLocal) || -#ifdef REMOTE - (((job->flags & JOB_SPECIAL) && - (job->node->type & OP_NOEXPORT)) && - (maxLocal == 0))) && -#else - ((job->flags & JOB_SPECIAL) && - (maxLocal == 0))) && -#endif - (nJobs != maxJobs)) - { - /* - * If the job is remote, it's ok to resume it as long as the - * maximum concurrency won't be exceeded. If it's local and - * we haven't reached the local concurrency limit already (or the - * job must be run locally and maxLocal is 0), it's also ok to - * resume it. - */ - Boolean error; - WAIT_T status; - -#ifdef RMT_WANTS_SIGNALS - if (job->flags & JOB_REMOTE) { - error = !Rmt_Signal(job, SIGCONT); - } else -#endif /* RMT_WANTS_SIGNALS */ - error = (KILL(job->pid, SIGCONT) != 0); - - if (!error) { - /* - * Make sure the user knows we've continued the beast and - * actually put the thing in the job table. - */ - job->flags |= JOB_CONTINUING; - WSET_STOPCODE(status, SIGCONT); - JobFinish(job, status); - - job->flags &= ~(JOB_RESUME|JOB_CONTINUING); - if (DEBUG(JOB)) { - (void) fprintf(stdout, "done\n"); - (void) fflush(stdout); - } - } else { - Error("couldn't resume %s: %s", - job->node->name, strerror(errno)); - WSET_EXITCODE(status, 1, 0); - JobFinish(job, status); - } - } else { - /* - * Job cannot be restarted. Mark the table as full and - * place the job back on the list of stopped jobs. - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, "table full\n"); - (void) fflush(stdout); - } - (void) Lst_AtFront(stoppedJobs, (ClientData)job); - } - } -} - -/*- - *----------------------------------------------------------------------- - * JobStart -- - * Start a target-creation process going for the target described - * by the graph node gn. - * - * Results: - * JOB_ERROR if there was an error in the commands, JOB_FINISHED - * if there isn't actually anything left to do for the job and - * JOB_RUNNING if the job has been started. - * - * Side Effects: - * A new Job node is created and added to the list of running - * jobs. PMake is forked and a child shell created. - *----------------------------------------------------------------------- - */ -static int -JobStart(gn, flags, previous) - GNode *gn; /* target to create */ - int flags; /* flags for the job to override normal ones. - * e.g. JOB_SPECIAL or JOB_IGNDOTS */ - Job *previous; /* The previous Job structure for this node, - * if any. */ -{ - register Job *job; /* new job descriptor */ - char *argv[10]; /* Argument vector to shell */ - Boolean cmdsOK; /* true if the nodes commands were all right */ - Boolean local; /* Set true if the job was run locally */ - Boolean noExec; /* Set true if we decide not to run the job */ - int tfd; /* File descriptor to the temp file */ - - if (previous != NULL) { - previous->flags &= ~(JOB_FIRST|JOB_IGNERR|JOB_SILENT|JOB_REMOTE); - job = previous; - } else { - job = (Job *) emalloc(sizeof(Job)); - if (job == NULL) { - Punt("JobStart out of memory"); - } - flags |= JOB_FIRST; - } - - job->node = gn; - job->tailCmds = NILLNODE; - - /* - * Set the initial value of the flags for this job based on the global - * ones and the node's attributes... Any flags supplied by the caller - * are also added to the field. - */ - job->flags = 0; - if (Targ_Ignore(gn)) { - job->flags |= JOB_IGNERR; - } - if (Targ_Silent(gn)) { - job->flags |= JOB_SILENT; - } - job->flags |= flags; - - /* - * Check the commands now so any attributes from .DEFAULT have a chance - * to migrate to the node - */ - if (!compatMake && job->flags & JOB_FIRST) { - cmdsOK = Job_CheckCommands(gn, Error); - } else { - cmdsOK = TRUE; - } - -#ifndef RMT_WILL_WATCH -#ifndef USE_SELECT - job->inPollfd = NULL; -#endif -#endif - /* - * If the -n flag wasn't given, we open up OUR (not the child's) - * temporary file to stuff commands in it. The thing is rd/wr so we don't - * need to reopen it to feed it to the shell. If the -n flag *was* given, - * we just set the file to be stdout. Cute, huh? - */ - if (((gn->type & OP_MAKE) && !(noRecursiveExecute)) || - (!noExecute && !touchFlag)) { - /* - * tfile is the name of a file into which all shell commands are - * put. It is used over by removing it before the child shell is - * executed. The XXXXXX in the string are replaced by the pid of - * the make process in a 6-character field with leading zeroes. - */ - char tfile[sizeof(TMPPAT)]; - /* - * We're serious here, but if the commands were bogus, we're - * also dead... - */ - if (!cmdsOK) { - DieHorribly(); - } - - (void)strcpy(tfile, TMPPAT); - if ((tfd = mkstemp(tfile)) == -1) - Punt("Could not create temporary file %s", strerror(errno)); - (void) eunlink(tfile); - - job->cmdFILE = fdopen(tfd, "w+"); - if (job->cmdFILE == NULL) { - Punt("Could not fdopen %s", tfile); - } - (void) fcntl(FILENO(job->cmdFILE), F_SETFD, 1); - /* - * Send the commands to the command file, flush all its buffers then - * rewind and remove the thing. - */ - noExec = FALSE; - - /* - * used to be backwards; replace when start doing multiple commands - * per shell. - */ - if (compatMake) { - /* - * Be compatible: If this is the first time for this node, - * verify its commands are ok and open the commands list for - * sequential access by later invocations of JobStart. - * Once that is done, we take the next command off the list - * and print it to the command file. If the command was an - * ellipsis, note that there's nothing more to execute. - */ - if ((job->flags&JOB_FIRST) && (Lst_Open(gn->commands) != SUCCESS)){ - cmdsOK = FALSE; - } else { - LstNode ln = Lst_Next(gn->commands); - - if ((ln == NILLNODE) || - JobPrintCommand((ClientData) Lst_Datum(ln), - (ClientData) job)) - { - noExec = TRUE; - Lst_Close(gn->commands); - } - if (noExec && !(job->flags & JOB_FIRST)) { - /* - * If we're not going to execute anything, the job - * is done and we need to close down the various - * file descriptors we've opened for output, then - * call JobDoOutput to catch the final characters or - * send the file to the screen... Note that the i/o streams - * are only open if this isn't the first job. - * Note also that this could not be done in - * Job_CatchChildren b/c it wasn't clear if there were - * more commands to execute or not... - */ - JobClose(job); - } - } - } else { - /* - * We can do all the commands at once. hooray for sanity - */ - numCommands = 0; - Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job); - - /* - * If we didn't print out any commands to the shell script, - * there's not much point in executing the shell, is there? - */ - if (numCommands == 0) { - noExec = TRUE; - } - } - } else if (NoExecute(gn)) { - /* - * Not executing anything -- just print all the commands to stdout - * in one fell swoop. This will still set up job->tailCmds correctly. - */ - if (lastNode != gn) { - MESSAGE(stdout, gn); - lastNode = gn; - } - job->cmdFILE = stdout; - /* - * Only print the commands if they're ok, but don't die if they're - * not -- just let the user know they're bad and keep going. It - * doesn't do any harm in this case and may do some good. - */ - if (cmdsOK) { - Lst_ForEach(gn->commands, JobPrintCommand, (ClientData)job); - } - /* - * Don't execute the shell, thank you. - */ - noExec = TRUE; - } else { - /* - * Just touch the target and note that no shell should be executed. - * Set cmdFILE to stdout to make life easier. Check the commands, too, - * but don't die if they're no good -- it does no harm to keep working - * up the graph. - */ - job->cmdFILE = stdout; - Job_Touch(gn, job->flags&JOB_SILENT); - noExec = TRUE; - } - - /* - * If we're not supposed to execute a shell, don't. - */ - if (noExec) { - /* - * Unlink and close the command file if we opened one - */ - if (job->cmdFILE != stdout) { - if (job->cmdFILE != NULL) { - (void) fclose(job->cmdFILE); - job->cmdFILE = NULL; - } - } else { - (void) fflush(stdout); - } - - /* - * We only want to work our way up the graph if we aren't here because - * the commands for the job were no good. - */ - if (cmdsOK) { - if (aborting == 0) { - if (job->tailCmds != NILLNODE) { - Lst_ForEachFrom(job->node->commands, job->tailCmds, - JobSaveCommand, - (ClientData)job->node); - } - if (!(job->flags & JOB_SPECIAL)) - Job_TokenReturn(); - Make_Update(job->node); - } - free((Address)job); - return(JOB_FINISHED); - } else { - free((Address)job); - return(JOB_ERROR); - } - } else { - (void) fflush(job->cmdFILE); - } - - /* - * Set up the control arguments to the shell. This is based on the flags - * set earlier for this job. - */ - JobMakeArgv(job, argv); - - /* - * If we're using pipes to catch output, create the pipe by which we'll - * get the shell's output. If we're using files, print out that we're - * starting a job and then set up its temporary-file name. - */ - if (!compatMake || (job->flags & JOB_FIRST)) { - if (usePipes) { - int fd[2]; - if (pipe(fd) == -1) - Punt("Cannot create pipe: %s", strerror(errno)); - job->inPipe = fd[0]; -#ifdef USE_SELECT - if (job->inPipe >= FD_SETSIZE) - Punt("Ran out of fd_set slots; " - "recompile with a larger FD_SETSIZE."); -#endif - job->outPipe = fd[1]; - (void) fcntl(job->inPipe, F_SETFD, 1); - (void) fcntl(job->outPipe, F_SETFD, 1); - } else { - (void) fprintf(stdout, "Remaking `%s'\n", gn->name); - (void) fflush(stdout); - (void) strcpy(job->outFile, TMPPAT); - job->outFd = mkstemp(job->outFile); - (void) fcntl(job->outFd, F_SETFD, 1); - } - } - -#ifdef REMOTE - if (!(gn->type & OP_NOEXPORT) && !(runLocalFirst && nLocal < maxLocal)) { -#ifdef RMT_NO_EXEC - local = !Rmt_Export(shellPath, argv, job); -#else - local = !Rmt_Begin(shellPath, argv, job->node); -#endif /* RMT_NO_EXEC */ - if (!local) { - job->flags |= JOB_REMOTE; - } - } else -#endif - local = TRUE; - - if (local && (((nLocal >= maxLocal) && - !(job->flags & JOB_SPECIAL) && -#ifdef REMOTE - (!(gn->type & OP_NOEXPORT) || (maxLocal != 0)) -#else - (maxLocal != 0) -#endif - ))) - { - /* - * The job can only be run locally, but we've hit the limit of - * local concurrency, so put the job on hold until some other job - * finishes. Note that the special jobs (.BEGIN, .INTERRUPT and .END) - * may be run locally even when the local limit has been reached - * (e.g. when maxLocal == 0), though they will be exported if at - * all possible. In addition, any target marked with .NOEXPORT will - * be run locally if maxLocal is 0. - */ - job->flags |= JOB_RESTART; - (void) Lst_AtEnd(stoppedJobs, (ClientData)job); - } else { - JobExec(job, argv); - } - return(JOB_RUNNING); -} - -static char * -JobOutput(job, cp, endp, msg) - register Job *job; - register char *cp, *endp; - int msg; -{ - register char *ecp; - - if (commandShell->noPrint) { - ecp = Str_FindSubstring(cp, commandShell->noPrint); - while (ecp != NULL) { - if (cp != ecp) { - *ecp = '\0'; - if (msg && job->node != lastNode) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } - /* - * The only way there wouldn't be a newline after - * this line is if it were the last in the buffer. - * however, since the non-printable comes after it, - * there must be a newline, so we don't print one. - */ - (void) fprintf(stdout, "%s", cp); - (void) fflush(stdout); - } - cp = ecp + commandShell->noPLen; - if (cp != endp) { - /* - * Still more to print, look again after skipping - * the whitespace following the non-printable - * command.... - */ - cp++; - while (*cp == ' ' || *cp == '\t' || *cp == '\n') { - cp++; - } - ecp = Str_FindSubstring(cp, commandShell->noPrint); - } else { - return cp; - } - } - } - return cp; -} - -/*- - *----------------------------------------------------------------------- - * JobDoOutput -- - * This function is called at different times depending on - * whether the user has specified that output is to be collected - * via pipes or temporary files. In the former case, we are called - * whenever there is something to read on the pipe. We collect more - * output from the given job and store it in the job's outBuf. If - * this makes up a line, we print it tagged by the job's identifier, - * as necessary. - * If output has been collected in a temporary file, we open the - * file and read it line by line, transfering it to our own - * output channel until the file is empty. At which point we - * remove the temporary file. - * In both cases, however, we keep our figurative eye out for the - * 'noPrint' line for the shell from which the output came. If - * we recognize a line, we don't print it. If the command is not - * alone on the line (the character after it is not \0 or \n), we - * do print whatever follows it. - * - * Results: - * None - * - * Side Effects: - * curPos may be shifted as may the contents of outBuf. - *----------------------------------------------------------------------- - */ -STATIC void -JobDoOutput(job, finish) - register Job *job; /* the job whose output needs printing */ - Boolean finish; /* TRUE if this is the last time we'll be - * called for this job */ -{ - Boolean gotNL = FALSE; /* true if got a newline */ - Boolean fbuf; /* true if our buffer filled up */ - register int nr; /* number of bytes read */ - register int i; /* auxiliary index into outBuf */ - register int max; /* limit for i (end of current data) */ - int nRead; /* (Temporary) number of bytes read */ - - FILE *oFILE; /* Stream pointer to shell's output file */ - char inLine[132]; - - - if (usePipes) { - /* - * Read as many bytes as will fit in the buffer. - */ -end_loop: - gotNL = FALSE; - fbuf = FALSE; - - nRead = read(job->inPipe, &job->outBuf[job->curPos], - JOB_BUFSIZE - job->curPos); - if (nRead < 0) { - if (DEBUG(JOB)) { - perror("JobDoOutput(piperead)"); - } - nr = 0; - } else { - nr = nRead; - } - - /* - * If we hit the end-of-file (the job is dead), we must flush its - * remaining output, so pretend we read a newline if there's any - * output remaining in the buffer. - * Also clear the 'finish' flag so we stop looping. - */ - if ((nr == 0) && (job->curPos != 0)) { - job->outBuf[job->curPos] = '\n'; - nr = 1; - finish = FALSE; - } else if (nr == 0) { - finish = FALSE; - } - - /* - * Look for the last newline in the bytes we just got. If there is - * one, break out of the loop with 'i' as its index and gotNL set - * TRUE. - */ - max = job->curPos + nr; - for (i = job->curPos + nr - 1; i >= job->curPos; i--) { - if (job->outBuf[i] == '\n') { - gotNL = TRUE; - break; - } else if (job->outBuf[i] == '\0') { - /* - * Why? - */ - job->outBuf[i] = ' '; - } - } - - if (!gotNL) { - job->curPos += nr; - if (job->curPos == JOB_BUFSIZE) { - /* - * If we've run out of buffer space, we have no choice - * but to print the stuff. sigh. - */ - fbuf = TRUE; - i = job->curPos; - } - } - if (gotNL || fbuf) { - /* - * Need to send the output to the screen. Null terminate it - * first, overwriting the newline character if there was one. - * So long as the line isn't one we should filter (according - * to the shell description), we print the line, preceded - * by a target banner if this target isn't the same as the - * one for which we last printed something. - * The rest of the data in the buffer are then shifted down - * to the start of the buffer and curPos is set accordingly. - */ - job->outBuf[i] = '\0'; - if (i >= job->curPos) { - char *cp; - - cp = JobOutput(job, job->outBuf, &job->outBuf[i], FALSE); - - /* - * There's still more in that thar buffer. This time, though, - * we know there's no newline at the end, so we add one of - * our own free will. - */ - if (*cp != '\0') { - if (job->node != lastNode) { - MESSAGE(stdout, job->node); - lastNode = job->node; - } - (void) fprintf(stdout, "%s%s", cp, gotNL ? "\n" : ""); - (void) fflush(stdout); - } - } - if (i < max - 1) { - /* shift the remaining characters down */ - (void) memcpy(job->outBuf, &job->outBuf[i + 1], max - (i + 1)); - job->curPos = max - (i + 1); - - } else { - /* - * We have written everything out, so we just start over - * from the start of the buffer. No copying. No nothing. - */ - job->curPos = 0; - } - } - if (finish) { - /* - * If the finish flag is true, we must loop until we hit - * end-of-file on the pipe. This is guaranteed to happen - * eventually since the other end of the pipe is now closed - * (we closed it explicitly and the child has exited). When - * we do get an EOF, finish will be set FALSE and we'll fall - * through and out. - */ - goto end_loop; - } - } else { - /* - * We've been called to retrieve the output of the job from the - * temporary file where it's been squirreled away. This consists of - * opening the file, reading the output line by line, being sure not - * to print the noPrint line for the shell we used, then close and - * remove the temporary file. Very simple. - * - * Change to read in blocks and do FindSubString type things as for - * pipes? That would allow for "@echo -n..." - */ - oFILE = fopen(job->outFile, "r"); - if (oFILE != NULL) { - (void) fprintf(stdout, "Results of making %s:\n", job->node->name); - (void) fflush(stdout); - while (fgets(inLine, sizeof(inLine), oFILE) != NULL) { - register char *cp, *endp, *oendp; - - cp = inLine; - oendp = endp = inLine + strlen(inLine); - if (endp[-1] == '\n') { - *--endp = '\0'; - } - cp = JobOutput(job, inLine, endp, FALSE); - - /* - * There's still more in that thar buffer. This time, though, - * we know there's no newline at the end, so we add one of - * our own free will. - */ - (void) fprintf(stdout, "%s", cp); - (void) fflush(stdout); - if (endp != oendp) { - (void) fprintf(stdout, "\n"); - (void) fflush(stdout); - } - } - (void) fclose(oFILE); - (void) eunlink(job->outFile); - } else { - Punt("Cannot open `%s'", job->outFile); - } - } -} - -/*- - *----------------------------------------------------------------------- - * Job_CatchChildren -- - * Handle the exit of a child. Called from Make_Make. - * - * Results: - * none. - * - * Side Effects: - * The job descriptor is removed from the list of children. - * - * Notes: - * We do waits, blocking or not, according to the wisdom of our - * caller, until there are no more children to report. For each - * job, call JobFinish to finish things off. This will take care of - * putting jobs on the stoppedJobs queue. - * - *----------------------------------------------------------------------- - */ -void -Job_CatchChildren(block) - Boolean block; /* TRUE if should block on the wait. */ -{ - int pid; /* pid of dead child */ - register Job *job; /* job descriptor for dead child */ - LstNode jnode; /* list element for finding job */ - WAIT_T status; /* Exit/termination status */ - - /* - * Don't even bother if we know there's no one around. - */ - if (nLocal == 0) { - return; - } - - while ((pid = waitpid((pid_t) -1, &status, - (block?0:WNOHANG)|WUNTRACED)) > 0) - { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Process %d exited or stopped %x.\n", pid, - WAIT_STATUS(status)); - (void) fflush(stdout); - } - - - jnode = Lst_Find(jobs, (ClientData)&pid, JobCmpPid); - - if (jnode == NILLNODE) { - if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGCONT)) { - jnode = Lst_Find(stoppedJobs, (ClientData) &pid, JobCmpPid); - if (jnode == NILLNODE) { - Error("Resumed child (%d) not in table", pid); - continue; - } - job = (Job *)Lst_Datum(jnode); - (void) Lst_Remove(stoppedJobs, jnode); - } else { - Error("Child (%d) not in table?", pid); - continue; - } - } else { - job = (Job *) Lst_Datum(jnode); - (void) Lst_Remove(jobs, jnode); - nJobs -= 1; -#ifdef REMOTE - if (!(job->flags & JOB_REMOTE)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "Job queue has one fewer local process.\n"); - (void) fflush(stdout); - } - nLocal -= 1; - } -#else - nLocal -= 1; -#endif - } - - JobFinish(job, status); - } -} - -/*- - *----------------------------------------------------------------------- - * Job_CatchOutput -- - * Catch the output from our children, if we're using - * pipes do so. Otherwise just block time until we get a - * signal (most likely a SIGCHLD) since there's no point in - * just spinning when there's nothing to do and the reaping - * of a child can wait for a while. - * - * Results: - * None - * - * Side Effects: - * Output is read from pipes if we're piping. - * ----------------------------------------------------------------------- - */ -void -Job_CatchOutput() -{ - int nready; - register LstNode ln; - register Job *job; -#ifdef RMT_WILL_WATCH - int pnJobs; /* Previous nJobs */ -#endif - - (void) fflush(stdout); - Job_TokenFlush(); -#ifdef RMT_WILL_WATCH - pnJobs = nJobs; - - /* - * It is possible for us to be called with nJobs equal to 0. This happens - * if all the jobs finish and a job that is stopped cannot be run - * locally (eg if maxLocal is 0) and cannot be exported. The job will - * be placed back on the stoppedJobs queue, Job_Empty() will return false, - * Make_Run will call us again when there's nothing for which to wait. - * nJobs never changes, so we loop forever. Hence the check. It could - * be argued that we should sleep for a bit so as not to swamp the - * exportation system with requests. Perhaps we should. - * - * NOTE: IT IS THE RESPONSIBILITY OF Rmt_Wait TO CALL Job_CatchChildren - * IN A TIMELY FASHION TO CATCH ANY LOCALLY RUNNING JOBS THAT EXIT. - * It may use the variable nLocal to determine if it needs to call - * Job_CatchChildren (if nLocal is 0, there's nothing for which to - * wait...) - */ - while (nJobs != 0 && pnJobs == nJobs) { - Rmt_Wait(); - } -#else - if (usePipes) { -#ifdef USE_SELECT - struct timeval timeout; - fd_set readfds; - - readfds = outputs; - timeout.tv_sec = SEL_SEC; - timeout.tv_usec = SEL_USEC; - - if ((nready = select(FD_SETSIZE, &readfds, (fd_set *) 0, - (fd_set *) 0, &timeout)) <= 0) - return; -#else - if ((nready = poll((wantToken ? fds : (fds + 1)), - (wantToken ? nfds : (nfds - 1)), POLL_MSEC)) <= 0) - return; -#endif - else { - if (Lst_Open(jobs) == FAILURE) { - Punt("Cannot open job table"); - } - while (nready && (ln = Lst_Next(jobs)) != NILLNODE) { - job = (Job *) Lst_Datum(ln); -#ifdef USE_SELECT - if (FD_ISSET(job->inPipe, &readfds)) -#else - if (readyfd(job)) -#endif - { - JobDoOutput(job, FALSE); - nready -= 1; - } - - } - Lst_Close(jobs); - } - } -#endif /* RMT_WILL_WATCH */ -} - -/*- - *----------------------------------------------------------------------- - * Job_Make -- - * Start the creation of a target. Basically a front-end for - * JobStart used by the Make module. - * - * Results: - * None. - * - * Side Effects: - * Another job is started. - * - *----------------------------------------------------------------------- - */ -void -Job_Make(gn) - GNode *gn; -{ - (void) JobStart(gn, 0, NULL); -} - -/*- - *----------------------------------------------------------------------- - * Job_Init -- - * Initialize the process module - * - * Results: - * none - * - * Side Effects: - * lists and counters are initialized - *----------------------------------------------------------------------- - */ -void -Job_Init(maxproc, maxlocal) - int maxproc; /* the greatest number of jobs which may be - * running at one time */ - int maxlocal; /* the greatest number of local jobs which may - * be running at once. */ -{ - GNode *begin; /* node for commands to do at the very start */ - - jobs = Lst_Init(FALSE); - stoppedJobs = Lst_Init(FALSE); - maxJobs = maxproc; - maxLocal = maxlocal; - nJobs = 0; - nLocal = 0; - wantToken = FALSE; - - aborting = 0; - errors = 0; - - lastNode = NILGNODE; - - if (maxJobs == 1 -#ifdef REMOTE - || noMessages -#endif - ) { - /* - * If only one job can run at a time, there's no need for a banner, - * is there? - */ - targFmt = ""; - } else { - targFmt = TARG_FMT; - } - - if (shellPath == NULL) { - /* - * The user didn't specify a shell to use, so we are using the - * default one... Both the absolute path and the last component - * must be set. The last component is taken from the 'name' field - * of the default shell description pointed-to by commandShell. - * All default shells are located in _PATH_DEFSHELLDIR. - */ - shellName = commandShell->name; - shellPath = str_concat(_PATH_DEFSHELLDIR, shellName, STR_ADDSLASH); - } - - if (commandShell->exit == NULL) { - commandShell->exit = ""; - } - if (commandShell->echo == NULL) { - commandShell->echo = ""; - } - - /* - * Catch the four signals that POSIX specifies if they aren't ignored. - * JobPassSig will take care of calling JobInterrupt if appropriate. - */ - if (signal(SIGINT, SIG_IGN) != SIG_IGN) { - (void) signal(SIGINT, JobPassSig); - } - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { - (void) signal(SIGHUP, JobPassSig); - } - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) { - (void) signal(SIGQUIT, JobPassSig); - } - if (signal(SIGTERM, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTERM, JobPassSig); - } - /* - * Install a NOOP SIGCHLD handler so we are woken up if we're blocked. - */ - signal(SIGCHLD, JobIgnoreSig); - - /* - * There are additional signals that need to be caught and passed if - * either the export system wants to be told directly of signals or if - * we're giving each job its own process group (since then it won't get - * signals from the terminal driver as we own the terminal) - */ -#if defined(RMT_WANTS_SIGNALS) || defined(USE_PGRP) - if (signal(SIGTSTP, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTSTP, JobPassSig); - } - if (signal(SIGTTOU, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTTOU, JobPassSig); - } - if (signal(SIGTTIN, SIG_IGN) != SIG_IGN) { - (void) signal(SIGTTIN, JobPassSig); - } - if (signal(SIGWINCH, SIG_IGN) != SIG_IGN) { - (void) signal(SIGWINCH, JobPassSig); - } - if (signal(SIGCONT, SIG_IGN) != SIG_IGN) { - (void) signal(SIGCONT, JobContinueSig); - } -#endif - - begin = Targ_FindNode(".BEGIN", TARG_NOCREATE); - - if (begin != NILGNODE) { - JobStart(begin, JOB_SPECIAL, (Job *)0); - while (nJobs) { - Job_CatchOutput(); -#ifndef RMT_WILL_WATCH - Job_CatchChildren(!usePipes); -#endif /* RMT_WILL_WATCH */ - } - } - postCommands = Targ_FindNode(".END", TARG_CREATE); -} - -/*- - *----------------------------------------------------------------------- - * Job_Empty -- - * See if the job table is empty. Because the local concurrency may - * be set to 0, it is possible for the job table to become empty, - * while the list of stoppedJobs remains non-empty. In such a case, - * we want to restart as many jobs as we can. - * - * Results: - * TRUE if it is. FALSE if it ain't. - * - * Side Effects: - * None. - * - * ----------------------------------------------------------------------- - */ -Boolean -Job_Empty() -{ - if (nJobs == 0) { - if (!Lst_IsEmpty(stoppedJobs) && !aborting) { - /* - * The job table is obviously not full if it has no jobs in - * it...Try and restart the stopped jobs. - */ - JobRestartJobs(); - return(FALSE); - } else { - return(TRUE); - } - } else { - return(FALSE); - } -} - -/*- - *----------------------------------------------------------------------- - * JobMatchShell -- - * Find a matching shell in 'shells' given its final component. - * - * Results: - * A pointer to the Shell structure. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Shell * -JobMatchShell(name) - char *name; /* Final component of shell path */ -{ - register Shell *sh; /* Pointer into shells table */ - Shell *match; /* Longest-matching shell */ - register char *cp1, - *cp2; - char *eoname; - - eoname = name + strlen(name); - - match = NULL; - - for (sh = shells; sh->name != NULL; sh++) { - for (cp1 = eoname - strlen(sh->name), cp2 = sh->name; - *cp1 != '\0' && *cp1 == *cp2; - cp1++, cp2++) { - continue; - } - if (*cp1 != *cp2) { - continue; - } else if (match == NULL || strlen(match->name) < strlen(sh->name)) { - match = sh; - } - } - return(match == NULL ? sh : match); -} - -/*- - *----------------------------------------------------------------------- - * Job_ParseShell -- - * Parse a shell specification and set up commandShell, shellPath - * and shellName appropriately. - * - * Results: - * FAILURE if the specification was incorrect. - * - * Side Effects: - * commandShell points to a Shell structure (either predefined or - * created from the shell spec), shellPath is the full path of the - * shell described by commandShell, while shellName is just the - * final component of shellPath. - * - * 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. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Job_ParseShell(line) - char *line; /* The shell spec */ -{ - char **words; - int wordCount; - register char **argv; - register int argc; - char *path; - Shell newShell; - Boolean fullSpec = FALSE; - - while (isspace((unsigned char)*line)) { - line++; - } - - if (shellArgv) - free(shellArgv); - - words = brk_string(line, &wordCount, TRUE, &shellArgv); - - memset((Address)&newShell, 0, sizeof(newShell)); - - /* - * Parse the specification by keyword - */ - for (path = NULL, argc = wordCount - 1, argv = words; - argc != 0; - argc--, argv++) { - if (strncmp(*argv, "path=", 5) == 0) { - path = &argv[0][5]; - } else if (strncmp(*argv, "name=", 5) == 0) { - newShell.name = &argv[0][5]; - } else { - if (strncmp(*argv, "quiet=", 6) == 0) { - newShell.echoOff = &argv[0][6]; - } else if (strncmp(*argv, "echo=", 5) == 0) { - newShell.echoOn = &argv[0][5]; - } else if (strncmp(*argv, "filter=", 7) == 0) { - newShell.noPrint = &argv[0][7]; - newShell.noPLen = strlen(newShell.noPrint); - } else if (strncmp(*argv, "echoFlag=", 9) == 0) { - newShell.echo = &argv[0][9]; - } else if (strncmp(*argv, "errFlag=", 8) == 0) { - newShell.exit = &argv[0][8]; - } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) { - char c = argv[0][10]; - newShell.hasErrCtl = !((c != 'Y') && (c != 'y') && - (c != 'T') && (c != 't')); - } else if (strncmp(*argv, "check=", 6) == 0) { - newShell.errCheck = &argv[0][6]; - } else if (strncmp(*argv, "ignore=", 7) == 0) { - newShell.ignErr = &argv[0][7]; - } else { - Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"", - *argv); - free(words); - return(FAILURE); - } - fullSpec = TRUE; - } - } - - if (path == NULL) { - /* - * If no path was given, the user wants one of the pre-defined shells, - * yes? So we find the one s/he wants with the help of JobMatchShell - * and set things up the right way. shellPath will be set up by - * Job_Init. - */ - if (newShell.name == NULL) { - Parse_Error(PARSE_FATAL, "Neither path nor name specified"); - return(FAILURE); - } else { - commandShell = JobMatchShell(newShell.name); - shellName = newShell.name; - } - } else { - /* - * 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. - */ - shellPath = path; - path = strrchr(path, '/'); - if (path == NULL) { - path = shellPath; - } else { - path += 1; - } - if (newShell.name != NULL) { - shellName = newShell.name; - } else { - shellName = path; - } - if (!fullSpec) { - commandShell = JobMatchShell(shellName); - } else { - commandShell = (Shell *) emalloc(sizeof(Shell)); - *commandShell = newShell; - } - } - - if (commandShell->echoOn && commandShell->echoOff) { - commandShell->hasEchoCtl = TRUE; - } - - if (!commandShell->hasErrCtl) { - if (commandShell->errCheck == NULL) { - commandShell->errCheck = ""; - } - if (commandShell->ignErr == NULL) { - commandShell->ignErr = "%s\n"; - } - } - - /* - * Do not free up the words themselves, since they might be in use by the - * shell specification. - */ - free(words); - return SUCCESS; -} - -/*- - *----------------------------------------------------------------------- - * JobInterrupt -- - * Handle the receipt of an interrupt. - * - * Results: - * None - * - * Side Effects: - * All children are killed. Another job will be started if the - * .INTERRUPT target was given. - *----------------------------------------------------------------------- - */ -static void -JobInterrupt(runINTERRUPT, signo) - int runINTERRUPT; /* Non-zero if commands for the .INTERRUPT - * target should be executed */ - int signo; /* signal received */ -{ - LstNode ln; /* element in job table */ - Job *job; /* job descriptor in that element */ - GNode *interrupt; /* the node describing the .INTERRUPT target */ - - aborting = ABORT_INTERRUPT; - - (void) Lst_Open(jobs); - while ((ln = Lst_Next(jobs)) != NILLNODE) { - job = (Job *) Lst_Datum(ln); - - if (!Targ_Precious(job->node)) { - char *file = (job->node->path == NULL ? - job->node->name : - job->node->path); - if (!noExecute && eunlink(file) != -1) { - Error("*** %s removed", file); - } - } -#ifdef RMT_WANTS_SIGNALS - if (job->flags & JOB_REMOTE) { - /* - * If job is remote, let the Rmt module do the killing. - */ - if (!Rmt_Signal(job, signo)) { - /* - * If couldn't kill the thing, finish it out now with an - * error code, since no exit report will come in likely. - */ - WAIT_T status; - - WSET_EXITCODE(status, 1, 0); - JobFinish(job, status); - } - } else if (job->pid) { - KILL(job->pid, signo); - } -#else - if (job->pid) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobInterrupt passing signal to child %d.\n", - job->pid); - (void) fflush(stdout); - } - KILL(job->pid, signo); - } -#endif /* RMT_WANTS_SIGNALS */ - } - -#ifdef REMOTE - (void)Lst_Open(stoppedJobs); - while ((ln = Lst_Next(stoppedJobs)) != NILLNODE) { - job = (Job *) Lst_Datum(ln); - - if (job->flags & JOB_RESTART) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "%s%s", - "JobInterrupt skipping job on stopped queue", - "-- it was waiting to be restarted.\n"); - (void) fflush(stdout); - } - continue; - } - if (!Targ_Precious(job->node)) { - char *file = (job->node->path == NULL ? - job->node->name : - job->node->path); - if (eunlink(file) == 0) { - Error("*** %s removed", file); - } - } - /* - * Resume the thing so it will take the signal. - */ - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobInterrupt passing CONT to stopped child %d.\n", - job->pid); - (void) fflush(stdout); - } - KILL(job->pid, SIGCONT); -#ifdef RMT_WANTS_SIGNALS - if (job->flags & JOB_REMOTE) { - /* - * If job is remote, let the Rmt module do the killing. - */ - if (!Rmt_Signal(job, SIGINT)) { - /* - * If couldn't kill the thing, finish it out now with an - * error code, since no exit report will come in likely. - */ - WAIT_T status; - - WSET_EXITCODE(status, 1, 0); - JobFinish(job, status); - } - } else if (job->pid) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobInterrupt passing interrupt to stopped child %d.\n", - job->pid); - (void) fflush(stdout); - } - KILL(job->pid, SIGINT); - } -#endif /* RMT_WANTS_SIGNALS */ - } -#endif - Lst_Close(stoppedJobs); - - if (runINTERRUPT && !touchFlag) { - interrupt = Targ_FindNode(".INTERRUPT", TARG_NOCREATE); - if (interrupt != NILGNODE) { - ignoreErrors = FALSE; - - JobStart(interrupt, JOB_IGNDOTS, (Job *)0); - while (nJobs) { - Job_CatchOutput(); -#ifndef RMT_WILL_WATCH - Job_CatchChildren(!usePipes); -#endif /* RMT_WILL_WATCH */ - } - } - } - Trace_Log(MAKEINTR, 0); - exit(signo); -} - -/* - *----------------------------------------------------------------------- - * Job_Finish -- - * Do final processing such as the running of the commands - * attached to the .END target. - * - * Results: - * Number of errors reported. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -int -Job_Finish() -{ - if (postCommands != NILGNODE && !Lst_IsEmpty(postCommands->commands)) { - if (errors) { - Error("Errors reported so .END ignored"); - } else { - JobStart(postCommands, JOB_SPECIAL | JOB_IGNDOTS, NULL); - - while (nJobs) { - Job_CatchOutput(); -#ifndef RMT_WILL_WATCH - Job_CatchChildren(!usePipes); -#endif /* RMT_WILL_WATCH */ - } - } - } - Job_TokenFlush(); - return(errors); -} - -/*- - *----------------------------------------------------------------------- - * Job_End -- - * Cleanup any memory used by the jobs module - * - * Results: - * None. - * - * Side Effects: - * Memory is freed - *----------------------------------------------------------------------- - */ -void -Job_End() -{ -#ifdef CLEANUP - if (shellArgv) - free(shellArgv); -#endif -} - -/*- - *----------------------------------------------------------------------- - * Job_Wait -- - * Waits for all running jobs to finish and returns. Sets 'aborting' - * to ABORT_WAIT to prevent other jobs from starting. - * - * Results: - * None. - * - * Side Effects: - * Currently running jobs finish. - * - *----------------------------------------------------------------------- - */ -void -Job_Wait() -{ - aborting = ABORT_WAIT; - while (nJobs != 0) { - Job_CatchOutput(); -#ifndef RMT_WILL_WATCH - Job_CatchChildren(!usePipes); -#endif /* RMT_WILL_WATCH */ - } - Job_TokenFlush(); - aborting = 0; -} - -/*- - *----------------------------------------------------------------------- - * Job_AbortAll -- - * Abort all currently running jobs without handling output or anything. - * This function is to be called only in the event of a major - * error. Most definitely NOT to be called from JobInterrupt. - * - * Results: - * None - * - * Side Effects: - * All children are killed, not just the firstborn - *----------------------------------------------------------------------- - */ -void -Job_AbortAll() -{ - LstNode ln; /* element in job table */ - Job *job; /* the job descriptor in that element */ - WAIT_T foo; - - aborting = ABORT_ERROR; - - if (nJobs) { - - (void) Lst_Open(jobs); - while ((ln = Lst_Next(jobs)) != NILLNODE) { - job = (Job *) Lst_Datum(ln); - - /* - * kill the child process with increasingly drastic signals to make - * darn sure it's dead. - */ -#ifdef RMT_WANTS_SIGNALS - if (job->flags & JOB_REMOTE) { - Rmt_Signal(job, SIGINT); - Rmt_Signal(job, SIGKILL); - } else { - KILL(job->pid, SIGINT); - KILL(job->pid, SIGKILL); - } -#else - KILL(job->pid, SIGINT); - KILL(job->pid, SIGKILL); -#endif /* RMT_WANTS_SIGNALS */ - } - } - - /* - * Catch as many children as want to report in at first, then give up - */ - while (waitpid((pid_t) -1, &foo, WNOHANG) > 0) - continue; -} - -#ifdef REMOTE -/*- - *----------------------------------------------------------------------- - * JobFlagForMigration -- - * Handle the eviction of a child. Called from RmtStatusChange. - * Flags the child as remigratable and then suspends it. - * - * Results: - * none. - * - * Side Effects: - * The job descriptor is flagged for remigration. - * - *----------------------------------------------------------------------- - */ -void -JobFlagForMigration(hostID) - int hostID; /* ID of host we used, for matching children. */ -{ - register Job *job; /* job descriptor for dead child */ - LstNode jnode; /* list element for finding job */ - - if (DEBUG(JOB)) { - (void) fprintf(stdout, "JobFlagForMigration(%d) called.\n", hostID); - (void) fflush(stdout); - } - jnode = Lst_Find(jobs, (ClientData)hostID, JobCmpRmtID); - - if (jnode == NILLNODE) { - jnode = Lst_Find(stoppedJobs, (ClientData)hostID, JobCmpRmtID); - if (jnode == NILLNODE) { - if (DEBUG(JOB)) { - Error("Evicting host(%d) not in table", hostID); - } - return; - } - } - job = (Job *) Lst_Datum(jnode); - - if (DEBUG(JOB)) { - (void) fprintf(stdout, - "JobFlagForMigration(%d) found job '%s'.\n", hostID, - job->node->name); - (void) fflush(stdout); - } - - KILL(job->pid, SIGSTOP); - - job->flags |= JOB_REMIGRATE; -} - -#endif - -/*- - *----------------------------------------------------------------------- - * JobRestartJobs -- - * Tries to restart stopped jobs if there are slots available. - * Note that this tries to restart them regardless of pending errors. - * It's not good to leave stopped jobs lying around! - * - * Results: - * None. - * - * Side Effects: - * Resumes(and possibly migrates) jobs. - * - *----------------------------------------------------------------------- - */ -static void -JobRestartJobs() -{ - while (!Lst_IsEmpty(stoppedJobs)) { - if (DEBUG(JOB)) { - (void) fprintf(stdout, "Restarting a stopped job.\n"); - (void) fflush(stdout); - } - JobRestart((Job *)Lst_DeQueue(stoppedJobs)); - } -} - -#ifndef RMT_WILL_WATCH -#ifndef USE_SELECT -static void -watchfd(job) - Job *job; -{ - int i; - if (job->inPollfd != NULL) - Punt("Watching watched job"); - if (fds == NULL) { - maxfds = JBSTART; - fds = emalloc(sizeof(struct pollfd) * maxfds); - jobfds = emalloc(sizeof(Job **) * maxfds); - - fds[0].fd = job_pipe[0]; - fds[0].events = POLLIN; - jobfds[0] = &tokenWaitJob; - tokenWaitJob.inPollfd = &fds[0]; - nfds++; - } else if (nfds == maxfds) { - maxfds *= JBFACTOR; - fds = erealloc(fds, sizeof(struct pollfd) * maxfds); - jobfds = erealloc(jobfds, sizeof(Job **) * maxfds); - for (i = 0; i < nfds; i++) - jobfds[i]->inPollfd = &fds[i]; - } - - fds[nfds].fd = job->inPipe; - fds[nfds].events = POLLIN; - jobfds[nfds] = job; - job->inPollfd = &fds[nfds]; - nfds++; -} - -static void -clearfd(job) - Job *job; -{ - int i; - if (job->inPollfd == NULL) - Punt("Unwatching unwatched job"); - i = job->inPollfd - fds; - nfds--; - /* - * Move last job in table into hole made by dead job. - */ - if (nfds != i) { - fds[i] = fds[nfds]; - jobfds[i] = jobfds[nfds]; - jobfds[i]->inPollfd = &fds[i]; - } - job->inPollfd = NULL; -} - -static int -readyfd(job) - Job *job; -{ - if (job->inPollfd == NULL) - Punt("Polling unwatched job"); - return (job->inPollfd->revents & POLLIN) != 0; -} -#endif -#endif - -/*- - *----------------------------------------------------------------------- - * JobTokenAdd -- - * Put a token into the job pipe so that some make process can start - * another job. - * - * Side Effects: - * Allows more build jobs to be spawned somewhere. - * - *----------------------------------------------------------------------- - */ - -static void -JobTokenAdd() -{ - - if (DEBUG(JOB)) - printf("deposit token\n"); - write(job_pipe[1], "+", 1); -} - -/*- - *----------------------------------------------------------------------- - * Job_ServerStartTokenAdd -- - * Prep the job token pipe in the root make process. - * - *----------------------------------------------------------------------- - */ - -void Job_ServerStart(maxproc) - int maxproc; -{ - int i, flags; - char jobarg[64]; - - if (pipe(job_pipe) < 0) - Fatal ("error in pipe: %s", strerror(errno)); - - /* - * We mark the input side of the pipe non-blocking; we poll(2) the - * pipe when we're waiting for a job token, but we might lose the - * race for the token when a new one becomes available, so the read - * from the pipe should not block. - */ - flags = fcntl(job_pipe[0], F_GETFL, 0); - flags |= O_NONBLOCK; - fcntl(job_pipe[0], F_SETFL, flags); - - /* - * Mark job pipes as close-on-exec. - * Note that we will clear this when executing submakes. - */ - fcntl(job_pipe[0], F_SETFD, 1); - fcntl(job_pipe[1], F_SETFD, 1); - - snprintf(jobarg, sizeof(jobarg), "%d,%d", job_pipe[0], job_pipe[1]); - - Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); - Var_Append(MAKEFLAGS, jobarg, VAR_GLOBAL); - - /* - * Preload job_pipe with one token per job, save the one - * "extra" token for the primary job. - * - * XXX should clip maxJobs against PIPE_BUF -- if maxJobs is - * larger than the write buffer size of the pipe, we will - * deadlock here. - */ - for (i=1; i < maxproc; i++) - JobTokenAdd(); -} - -/* - * this tracks the number of tokens currently "out" to build jobs. - */ -int jobTokensRunning = 0; -int jobTokensFree = 0; -/*- - *----------------------------------------------------------------------- - * Job_TokenReturn -- - * Return a withdrawn token to the pool. - * - *----------------------------------------------------------------------- - */ - -void -Job_TokenReturn() -{ - jobTokensRunning--; - if (jobTokensRunning < 0) - Punt("token botch"); - if (jobTokensRunning) - jobTokensFree++; -} - -/*- - *----------------------------------------------------------------------- - * Job_TokenWithdraw -- - * Attempt to withdraw a token from the pool. - * - * Results: - * Returns TRUE if a token was withdrawn, and FALSE if the pool - * is currently empty. - * - * Side Effects: - * If pool is empty, set wantToken so that we wake up - * when a token is released. - * - *----------------------------------------------------------------------- - */ - - -Boolean -Job_TokenWithdraw() -{ - char tok; - int count; - - if (aborting) - return FALSE; - - if (jobTokensRunning == 0) { - if (DEBUG(JOB)) - printf("first one's free\n"); - jobTokensRunning++; - wantToken = FALSE; - return TRUE; - } - if (jobTokensFree > 0) { - jobTokensFree--; - jobTokensRunning++; - wantToken = FALSE; - return TRUE; - } - count = read(job_pipe[0], &tok, 1); - if (count == 0) - Fatal("eof on job pipe!"); - else if (count < 0) { - if (errno != EAGAIN) { - Fatal("job pipe read: %s", strerror(errno)); - } - if (DEBUG(JOB)) - printf("blocked for token\n"); - wantToken = TRUE; - return FALSE; - } - wantToken = FALSE; - jobTokensRunning++; - if (DEBUG(JOB)) - printf("withdrew token\n"); - return TRUE; -} - -/*- - *----------------------------------------------------------------------- - * Job_TokenFlush -- - * Return free tokens to the pool. - * - *----------------------------------------------------------------------- - */ - -void -Job_TokenFlush() -{ - if (compatMake) return; - - while (jobTokensFree > 0) { - JobTokenAdd(); - jobTokensFree--; - } -} - diff --git a/bootstrap/bmake/job.h b/bootstrap/bmake/job.h deleted file mode 100644 index 87bf8e1d675..00000000000 --- a/bootstrap/bmake/job.h +++ /dev/null @@ -1,265 +0,0 @@ -/* $NetBSD: job.h,v 1.1.1.1 2004/03/11 13:04:08 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)job.h 8.1 (Berkeley) 6/6/93 - */ - -/*- - * job.h -- - * Definitions pertaining to the running of jobs in parallel mode. - * Exported from job.c for the use of remote-execution modules. - */ -#ifndef _JOB_H_ -#define _JOB_H_ - -#define TMPPAT "/tmp/makeXXXXXX" - -#ifdef USE_SELECT -/* - * The SEL_ constants determine the maximum amount of time spent in select - * before coming out to see if a child has finished. SEL_SEC is the number of - * seconds and SEL_USEC is the number of micro-seconds - */ -#define SEL_SEC 5 -#define SEL_USEC 0 -#else -/* - * The POLL_MSEC constant determines the maximum number of milliseconds spent - * in poll before coming out to see if a child has finished. - */ -#define POLL_MSEC 5000 -#endif - - -/*- - * Job Table definitions. - * - * Each job has several things associated with it: - * 1) The process id of the child shell - * 2) The graph node describing the target being made by this job - * 3) A LstNode for the first command to be saved after the job - * completes. This is NILLNODE if there was no "..." in the job's - * commands. - * 4) An FILE* for writing out the commands. This is only - * used before the job is actually started. - * 5) A union of things used for handling the shell's output. Different - * parts of the union are used based on the value of the usePipes - * flag. If it is true, the output is being caught via a pipe and - * the descriptors of our pipe, an array in which output is line - * buffered and the current position in that buffer are all - * maintained for each job. If, on the other hand, usePipes is false, - * the output is routed to a temporary file and all that is kept - * is the name of the file and the descriptor open to the file. - * 6) An identifier provided by and for the exclusive use of the - * Rmt module. - * 7) A word of flags which determine how the module handles errors, - * echoing, etc. for the job - * - * The job "table" is kept as a linked Lst in 'jobs', with the number of - * active jobs maintained in the 'nJobs' variable. At no time will this - * exceed the value of 'maxJobs', initialized by the Job_Init function. - * - * When a job is finished, the Make_Update function is called on each of the - * parents of the node which was just remade. This takes care of the upward - * traversal of the dependency graph. - */ -#ifndef RMT_WILL_WATCH -#ifndef USE_SELECT -struct pollfd; -#endif -#endif - -#define JOB_BUFSIZE 1024 -typedef struct Job { - int pid; /* The child's process ID */ - GNode *node; /* The target the child is making */ - LstNode tailCmds; /* The node of the first command to be - * saved when the job has been run */ - FILE *cmdFILE; /* When creating the shell script, this is - * where the commands go */ - int rmtID; /* ID returned from Rmt module */ - short flags; /* Flags to control treatment of job */ -#define JOB_IGNERR 0x001 /* Ignore non-zero exits */ -#define JOB_SILENT 0x002 /* no output */ -#define JOB_SPECIAL 0x004 /* Target is a special one. i.e. run it locally - * if we can't export it and maxLocal is 0 */ -#define JOB_IGNDOTS 0x008 /* Ignore "..." lines when processing - * commands */ -#define JOB_REMOTE 0x010 /* Job is running remotely */ -#define JOB_FIRST 0x020 /* Job is first job for the node */ -#define JOB_REMIGRATE 0x040 /* Job needs to be remigrated */ -#define JOB_RESTART 0x080 /* Job needs to be completely restarted */ -#define JOB_RESUME 0x100 /* Job needs to be resumed b/c it stopped, - * for some reason */ -#define JOB_CONTINUING 0x200 /* We are in the process of resuming this job. - * Used to avoid infinite recursion between - * JobFinish and JobRestart */ -#define JOB_TRACED 0x400 /* we've sent 'set -x' */ - - union { - struct { - int op_inPipe; /* Input side of pipe associated - * with job's output channel */ -#ifndef RMT_WILL_WATCH -#ifndef USE_SELECT - struct pollfd *op_inPollfd; /* pollfd associated with inPipe */ -#endif -#endif - int op_outPipe; /* Output side of pipe associated with - * job's output channel */ - char op_outBuf[JOB_BUFSIZE + 1]; - /* Buffer for storing the output of the - * job, line by line */ - int op_curPos; /* Current position in op_outBuf */ - } o_pipe; /* data used when catching the output via - * a pipe */ - struct { - char of_outFile[sizeof(TMPPAT)+2]; - /* Name of file to which shell output - * was rerouted */ - int of_outFd; /* Stream open to the output - * file. Used to funnel all - * from a single job to one file - * while still allowing - * multiple shell invocations */ - } o_file; /* Data used when catching the output in - * a temporary file */ - } output; /* Data for tracking a shell's output */ -} Job; - -#define outPipe output.o_pipe.op_outPipe -#define inPipe output.o_pipe.op_inPipe -#define inPollfd output.o_pipe.op_inPollfd -#define outBuf output.o_pipe.op_outBuf -#define curPos output.o_pipe.op_curPos -#define outFile output.o_file.of_outFile -#define outFd output.o_file.of_outFd - - -/*- - * Shell Specifications: - * Each shell type has associated with it the following information: - * 1) The string which must match the last character of the shell name - * for the shell to be considered of this type. The longest match - * wins. - * 2) A command to issue to turn off echoing of command lines - * 3) A command to issue to turn echoing back on again - * 4) What the shell prints, and its length, when given the echo-off - * command. This line will not be printed when received from the shell - * 5) A boolean to tell if the shell has the ability to control - * error checking for individual commands. - * 6) The string to turn this checking on. - * 7) The string to turn it off. - * 8) The command-flag to give to cause the shell to start echoing - * commands right away. - * 9) The command-flag to cause the shell to Lib_Exit when an error is - * detected in one of the commands. - * - * Some special stuff goes on if a shell doesn't have error control. In such - * a case, errCheck becomes a printf template for echoing the command, - * should echoing be on and ignErr becomes another printf template for - * executing the command while ignoring the return status. 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. - */ -typedef struct Shell { - char *name; /* the name of the shell. For Bourne and C - * shells, this is used only to find the - * shell description when used as the single - * source of a .SHELL target. For user-defined - * shells, this is the full path of the shell. - */ - Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */ - char *echoOff; /* command to turn off echo */ - char *echoOn; /* command to turn it back on again */ - char *noPrint; /* command to skip when printing output from - * shell. This is usually the command which - * was executed to turn off echoing */ - int noPLen; /* length of noPrint command */ - Boolean hasErrCtl; /* set if can control error checking for - * individual commands */ - char *errCheck; /* string to turn error checking on */ - char *ignErr; /* string to turn off error checking */ - /* - * command-line flags - */ - char *echo; /* echo commands */ - char *exit; /* exit on error */ -} Shell; - -extern int job_pipe[2]; /* token pipe for jobs. */ -extern int jobTokensRunning; /* tokens currently "out" */ -extern int jobTokensFree; /* tokens free but not yet released to pipe */ - -#ifdef REMOTE -extern char *targFmt; /* Format string for banner that separates - * output from multiple jobs. Contains a - * single %s where the name of the node being - * made should be put. */ -extern GNode *lastNode; /* Last node for which a banner was printed. - * If Rmt module finds it necessary to print - * a banner, it should set this to the node - * for which the banner was printed */ -extern int nJobs; /* Number of jobs running (local and remote) */ -extern int nLocal; /* Number of jobs running locally */ -extern Lst jobs; /* List of active job descriptors */ -extern Lst stoppedJobs; /* List of jobs that are stopped or didn't - * quite get started */ -#endif - -void Job_Touch __P((GNode *, Boolean)); -Boolean Job_CheckCommands __P((GNode *, void (*abortProc )(char *, ...))); -void Job_CatchChildren __P((Boolean)); -void Job_CatchOutput __P((void)); -void Job_Make __P((GNode *)); -void Job_Init __P((int, int)); -Boolean Job_Full __P((void)); -Boolean Job_Empty __P((void)); -ReturnStatus Job_ParseShell __P((char *)); -int Job_Finish __P((void)); -void Job_End __P((void)); -void Job_Wait __P((void)); -void Job_AbortAll __P((void)); -void JobFlagForMigration __P((int)); -void Job_TokenReturn __P((void)); -void Job_TokenFlush __P((void)); -Boolean Job_TokenWithdraw __P((void)); -void Job_ServerStart __P((int)); - -#endif /* _JOB_H_ */ diff --git a/bootstrap/bmake/list.h b/bootstrap/bmake/list.h deleted file mode 100644 index 27e88f91934..00000000000 --- a/bootstrap/bmake/list.h +++ /dev/null @@ -1,300 +0,0 @@ -/* $NetBSD: list.h,v 1.1.1.1 2004/03/11 13:04:08 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)list.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * list.h -- - * - * Structures, macros, and routines exported by the List module. - */ - -#ifndef _LIST -#define _LIST - -#ifndef _SPRITE -#include "sprite.h" -#endif _SPRITE - -/* - * This module defines the list abstraction, which enables one to link - * together arbitrary data structures. Lists are doubly-linked and - * circular. A list contains a header followed by its real members, if - * any. (An empty list therefore consists of a single element, the - * header, whose nextPtr and prevPtr fields point to itself). To refer - * to a list as a whole, the user keeps a pointer to the header; that - * header is initialized by a call to List_Init(), which creates an empty - * list given a pointer to a List_Links structure (described below). - * - * The links are contained in a two-element structure called List_Links. - * A list joins List_Links records (that is, each List_Links structure - * points to other List_Links structures), but if the List_Links is the - * first field within a larger structure, then the larger structures are - * effectively linked together as follows: - * - * header - * (List_Links) first elt. second elt. - * ----------------- ----------------- ----------------- - * ..-> | nextPtr | ----> | List_Links | ----> | List_Links |----.. - * | - - - - - - - | | | | | - * ..-- | prevPtr | <---- | | <---- | |<---.. - * ----------------- - --- --- --- - - --- --- --- - - * | rest of | | rest of | - * | structure | | structure | - * | | | | - * | ... | | ... | - * ----------------- ----------------- - * - * It is possible to link structures through List_Links fields that are - * not at the beginning of the larger structure, but it is then necessary - * to perform pointer arithmetic to find the beginning of the larger - * structure, given a pointer to some point within it. - * - * A typical structure might be something like: - * - * typedef struct { - * List_Links links; - * char ch; - * integer flags; - * } EditChar; - * - * Before an element is inserted in a list for the first time, it must - * be initialized by calling the macro List_InitElement(). - */ - - -/* - * data structure for lists - */ - -typedef struct List_Links { - struct List_Links *prevPtr; - struct List_Links *nextPtr; -} List_Links; - -/* - * procedures - */ - -void List_Init(); /* initialize a header to a list */ -void List_Insert(); /* insert an element into a list */ -void List_Remove(); /* remove an element from a list */ -void List_Move(); /* move an element elsewhere in a list */ - -/* - * ---------------------------------------------------------------------------- - * - * List_InitElement -- - * - * Initialize a list element. Must be called before an element is first - * inserted into a list. - * - * ---------------------------------------------------------------------------- - */ -#define List_InitElement(elementPtr) \ - (elementPtr)->prevPtr = (List_Links *) NIL; \ - (elementPtr)->nextPtr = (List_Links *) NIL; - -/* - * Macros for stepping through or selecting parts of lists - */ - -/* - * ---------------------------------------------------------------------------- - * - * LIST_FORALL -- - * - * Macro to loop through a list and perform an operation on each member. - * - * Usage: LIST_FORALL(headerPtr, itemPtr) { - * / * - * * operation on itemPtr, which points to successive members - * * of the list - * * - * * It may be appropriate to first assign - * * foobarPtr = (Foobar *) itemPtr; - * * to refer to the entire Foobar structure. - * * / - * } - * - * Note: itemPtr must be a List_Links pointer variable, and headerPtr - * must evaluate to a pointer to a List_Links structure. - * - * ---------------------------------------------------------------------------- - */ - -#define LIST_FORALL(headerPtr, itemPtr) \ - for (itemPtr = List_First(headerPtr); \ - !List_IsAtEnd((headerPtr),itemPtr); \ - itemPtr = List_Next(itemPtr)) - -/* - * ---------------------------------------------------------------------------- - * - * List_IsEmpty -- - * - * Macro: Boolean value, TRUE if the given list does not contain any - * members. - * - * Usage: if (List_IsEmpty(headerPtr)) ... - * - * ---------------------------------------------------------------------------- - */ - -#define List_IsEmpty(headerPtr) \ - ((headerPtr) == (headerPtr)->nextPtr) - -/* - * ---------------------------------------------------------------------------- - * - * List_IsAtEnd -- - * - * Macro: Boolean value, TRUE if itemPtr is after the end of headerPtr - * (i.e., itemPtr is the header of the list). - * - * Usage: if (List_IsAtEnd(headerPtr, itemPtr)) ... - * - * ---------------------------------------------------------------------------- - */ - - -#define List_IsAtEnd(headerPtr, itemPtr) \ - ((itemPtr) == (headerPtr)) - - -/* - * ---------------------------------------------------------------------------- - * - * List_First -- - * - * Macro to return the first member in a list, which is the header if - * the list is empty. - * - * Usage: firstPtr = List_First(headerPtr); - * - * ---------------------------------------------------------------------------- - */ - -#define List_First(headerPtr) ((headerPtr)->nextPtr) - -/* - * ---------------------------------------------------------------------------- - * - * List_Last -- - * - * Macro to return the last member in a list, which is the header if - * the list is empty. - * - * Usage: lastPtr = List_Last(headerPtr); - * - * ---------------------------------------------------------------------------- - */ - -#define List_Last(headerPtr) ((headerPtr)->prevPtr) - -/* - * ---------------------------------------------------------------------------- - * - * List_Prev -- - * - * Macro to return the member preceding the given member in its list. - * If the given list member is the first element in the list, List_Prev - * returns the list header. - * - * Usage: prevPtr = List_Prev(itemPtr); - * - * ---------------------------------------------------------------------------- - */ - -#define List_Prev(itemPtr) ((itemPtr)->prevPtr) - -/* - * ---------------------------------------------------------------------------- - * - * List_Next -- - * - * Macro to return the member following the given member in its list. - * If the given list member is the last element in the list, List_Next - * returns the list header. - * - * Usage: nextPtr = List_Next(itemPtr); - * - * ---------------------------------------------------------------------------- - */ - -#define List_Next(itemPtr) ((itemPtr)->nextPtr) - - -/* - * ---------------------------------------------------------------------------- - * The List_Insert procedure takes two arguments. The first argument - * is a pointer to the structure to be inserted into a list, and - * the second argument is a pointer to the list member after which - * the new element is to be inserted. Macros are used to determine - * which existing member will precede the new one. - * - * The List_Move procedure takes a destination argument with the same - * semantics as List_Insert. - * - * The following macros define where to insert the new element - * in the list: - * - * LIST_AFTER(itemPtr) -- insert after itemPtr - * LIST_BEFORE(itemPtr) -- insert before itemPtr - * LIST_ATFRONT(headerPtr) -- insert at front of list - * LIST_ATREAR(headerPtr) -- insert at end of list - * - * For example, - * - * List_Insert(itemPtr, LIST_AFTER(otherPtr)); - * - * will insert itemPtr following otherPtr in the list containing otherPtr. - * ---------------------------------------------------------------------------- - */ - -#define LIST_AFTER(itemPtr) ((List_Links *) itemPtr) - -#define LIST_BEFORE(itemPtr) (((List_Links *) itemPtr)->prevPtr) - -#define LIST_ATFRONT(headerPtr) ((List_Links *) headerPtr) - -#define LIST_ATREAR(headerPtr) (((List_Links *) headerPtr)->prevPtr) - -#endif /* _LIST */ diff --git a/bootstrap/bmake/lst.h b/bootstrap/bmake/lst.h deleted file mode 100644 index 83eaf9cafba..00000000000 --- a/bootstrap/bmake/lst.h +++ /dev/null @@ -1,166 +0,0 @@ -/* $NetBSD: lst.h,v 1.1.1.1 2004/03/11 13:04:08 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)lst.h 8.1 (Berkeley) 6/6/93 - */ - -/*- - * lst.h -- - * Header for using the list library - */ -#ifndef _LST_H_ -#define _LST_H_ - -#include -#if __STDC__ -#include -#endif -#include "sprite.h" - -/* - * basic typedef. This is what the Lst_ functions handle - */ - -typedef struct Lst *Lst; -typedef struct LstNode *LstNode; - -#define NILLST ((Lst) NIL) -#define NILLNODE ((LstNode) NIL) - -/* - * 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 ((void (*) __P((ClientData))) 0) -#define NOCOPY ((ClientData (*) __P((ClientData))) 0) - -#define LST_CONCNEW 0 /* create new LstNode's when using Lst_Concat */ -#define LST_CONCLINK 1 /* relink LstNode's when using Lst_Concat */ - -/* - * Creation/destruction functions - */ -/* Create a new list */ -Lst Lst_Init __P((Boolean)); -/* Duplicate an existing list */ -Lst Lst_Duplicate __P((Lst, ClientData (*)(ClientData))); -/* Destroy an old one */ -void Lst_Destroy __P((Lst, void (*)(ClientData))); -/* True if list is empty */ -Boolean Lst_IsEmpty __P((Lst)); - -/* - * Functions to modify a list - */ -/* Insert an element before another */ -ReturnStatus Lst_Insert __P((Lst, LstNode, ClientData)); -/* Insert an element after another */ -ReturnStatus Lst_Append __P((Lst, LstNode, ClientData)); -/* Place an element at the front of a lst. */ -ReturnStatus Lst_AtFront __P((Lst, ClientData)); -/* Place an element at the end of a lst. */ -ReturnStatus Lst_AtEnd __P((Lst, ClientData)); -/* Remove an element */ -ReturnStatus Lst_Remove __P((Lst, LstNode)); -/* Replace a node with a new value */ -ReturnStatus Lst_Replace __P((LstNode, ClientData)); -/* Concatenate two lists */ -ReturnStatus Lst_Concat __P((Lst, Lst, int)); - -/* - * Node-specific functions - */ -/* Return first element in list */ -LstNode Lst_First __P((Lst)); -/* Return last element in list */ -LstNode Lst_Last __P((Lst)); -/* Return successor to given element */ -LstNode Lst_Succ __P((LstNode)); -/* Get datum from LstNode */ -ClientData Lst_Datum __P((LstNode)); - -/* - * Functions for entire lists - */ -/* Find an element in a list */ -LstNode Lst_Find __P((Lst, ClientData, - int (*)(ClientData, ClientData))); -/* Find an element starting from somewhere */ -LstNode Lst_FindFrom __P((Lst, LstNode, ClientData, - int (*cProc)(ClientData, ClientData))); -/* - * See if the given datum is on the list. Returns the LstNode containing - * the datum - */ -LstNode Lst_Member __P((Lst, ClientData)); -/* Apply a function to all elements of a lst */ -void Lst_ForEach __P((Lst, int (*)(ClientData, ClientData), - ClientData)); -/* - * Apply a function to all elements of a lst starting from a certain point. - * If the list is circular, the application will wrap around to the - * beginning of the list again. - */ -void Lst_ForEachFrom __P((Lst, LstNode, - int (*)(ClientData, ClientData), - ClientData)); -/* - * these functions are for dealing with a list as a table, of sorts. - * An idea of the "current element" is kept and used by all the functions - * between Lst_Open() and Lst_Close(). - */ -/* Open the list */ -ReturnStatus Lst_Open __P((Lst)); -/* Next element please */ -LstNode Lst_Next __P((Lst)); -/* Done yet? */ -Boolean Lst_IsAtEnd __P((Lst)); -/* Finish table access */ -void Lst_Close __P((Lst)); - -/* - * for using the list as a queue - */ -/* Place an element at tail of queue */ -ReturnStatus Lst_EnQueue __P((Lst, ClientData)); -/* Remove an element from head of queue */ -ClientData Lst_DeQueue __P((Lst)); - -#endif /* _LST_H_ */ diff --git a/bootstrap/bmake/lst.lib/Makefile b/bootstrap/bmake/lst.lib/Makefile deleted file mode 100644 index 303b0f57ef2..00000000000 --- a/bootstrap/bmake/lst.lib/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $NetBSD: Makefile,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ - -OBJ=lstAppend.o lstDupl.o lstInit.o lstOpen.o lstAtEnd.o lstEnQueue.o \ - lstInsert.o lstAtFront.o lstIsAtEnd.o lstClose.o lstFind.o lstIsEmpty.o \ - lstRemove.o lstConcat.o lstFindFrom.o lstLast.o lstReplace.o lstFirst.o \ - lstDatum.o lstForEach.o lstMember.o lstSucc.o lstDeQueue.o \ - lstForEachFrom.o lstDestroy.o lstNext.o - -CPPFLAGS=-I${.CURDIR}/.. -all: ${OBJ} diff --git a/bootstrap/bmake/lst.lib/lstAppend.c b/bootstrap/bmake/lst.lib/lstAppend.c deleted file mode 100644 index 48c8984e66b..00000000000 --- a/bootstrap/bmake/lst.lib/lstAppend.c +++ /dev/null @@ -1,124 +0,0 @@ -/* $NetBSD: lstAppend.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstAppend.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstAppend.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstAppend.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstAppend.c -- - * Add a new node with a new datum after an existing node - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Append -- - * Create a new node and add it to the given list after the given node. - * - * Results: - * SUCCESS if all went well. - * - * Side Effects: - * A new ListNode is created and linked in to the List. The lastPtr - * field of the List will be altered if ln is the last node in the - * list. lastPtr and firstPtr will alter if the list was empty and - * ln was NILLNODE. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Append (l, ln, d) - Lst l; /* affected list */ - LstNode ln; /* node after which to append the datum */ - ClientData d; /* said datum */ -{ - register List list; - register ListNode lNode; - register ListNode nLNode; - - if (LstValid (l) && (ln == NILLNODE && LstIsEmpty (l))) { - goto ok; - } - - if (!LstValid (l) || LstIsEmpty (l) || ! LstNodeValid (ln, l)) { - return (FAILURE); - } - ok: - - list = (List)l; - lNode = (ListNode)ln; - - PAlloc (nLNode, ListNode); - nLNode->datum = d; - nLNode->useCount = nLNode->flags = 0; - - if (lNode == NilListNode) { - if (list->isCirc) { - nLNode->nextPtr = nLNode->prevPtr = nLNode; - } else { - nLNode->nextPtr = nLNode->prevPtr = NilListNode; - } - list->firstPtr = list->lastPtr = nLNode; - } else { - nLNode->prevPtr = lNode; - nLNode->nextPtr = lNode->nextPtr; - - lNode->nextPtr = nLNode; - if (nLNode->nextPtr != NilListNode) { - nLNode->nextPtr->prevPtr = nLNode; - } - - if (lNode == list->lastPtr) { - list->lastPtr = nLNode; - } - } - - return (SUCCESS); -} - diff --git a/bootstrap/bmake/lst.lib/lstAtEnd.c b/bootstrap/bmake/lst.lib/lstAtEnd.c deleted file mode 100644 index 129c0a315fd..00000000000 --- a/bootstrap/bmake/lst.lib/lstAtEnd.c +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: lstAtEnd.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstAtEnd.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstAtEnd.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstAtEnd.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstAtEnd.c -- - * Add a node at the end of the list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_AtEnd -- - * Add a node to the end of the given list - * - * Results: - * SUCCESS if life is good. - * - * Side Effects: - * A new ListNode is created and added to the list. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_AtEnd (l, d) - Lst l; /* List to which to add the datum */ - ClientData d; /* Datum to add */ -{ - register LstNode end; - - end = Lst_Last (l); - return (Lst_Append (l, end, d)); -} diff --git a/bootstrap/bmake/lst.lib/lstAtFront.c b/bootstrap/bmake/lst.lib/lstAtFront.c deleted file mode 100644 index 9fb4ee623e0..00000000000 --- a/bootstrap/bmake/lst.lib/lstAtFront.c +++ /dev/null @@ -1,82 +0,0 @@ -/* $NetBSD: lstAtFront.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstAtFront.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstAtFront.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstAtFront.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstAtFront.c -- - * Add a node at the front of the list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_AtFront -- - * Place a piece of data at the front of a list - * - * Results: - * SUCCESS or FAILURE - * - * Side Effects: - * A new ListNode is created and stuck at the front of the list. - * hence, firstPtr (and possible lastPtr) in the list are altered. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_AtFront (l, d) - Lst l; - ClientData d; -{ - register LstNode front; - - front = Lst_First (l); - return (Lst_Insert (l, front, d)); -} diff --git a/bootstrap/bmake/lst.lib/lstClose.c b/bootstrap/bmake/lst.lib/lstClose.c deleted file mode 100644 index 38f1e599f73..00000000000 --- a/bootstrap/bmake/lst.lib/lstClose.c +++ /dev/null @@ -1,88 +0,0 @@ -/* $NetBSD: lstClose.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstClose.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstClose.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstClose.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstClose.c -- - * Close a list for sequential access. - * The sequential functions access the list in a slightly different way. - * CurPtr points to their idea of the current node in the list and they - * access the list based on it. Because the list is circular, Lst_Next - * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be - * used to determine when to stop. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Close -- - * Close a list which was opened for sequential access. - * - * Results: - * None. - * - * Side Effects: - * The list is closed. - * - *----------------------------------------------------------------------- - */ -void -Lst_Close (l) - Lst l; /* The list to close */ -{ - register List list = (List) l; - - if (LstValid(l) == TRUE) { - list->isOpen = FALSE; - list->atEnd = Unknown; - } -} - diff --git a/bootstrap/bmake/lst.lib/lstConcat.c b/bootstrap/bmake/lst.lib/lstConcat.c deleted file mode 100644 index 602bb0a5620..00000000000 --- a/bootstrap/bmake/lst.lib/lstConcat.c +++ /dev/null @@ -1,187 +0,0 @@ -/* $NetBSD: lstConcat.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstConcat.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstConcat.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * listConcat.c -- - * Function to concatentate two lists. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Concat -- - * Concatenate two lists. New elements are created to hold the data - * elements, if specified, but the elements themselves are not copied. - * If the elements should be duplicated to avoid confusion with another - * list, the Lst_Duplicate function should be called first. - * If LST_CONCLINK is specified, the second list is destroyed since - * its pointers have been corrupted and the list is no longer useable. - * - * Results: - * SUCCESS if all went well. FAILURE otherwise. - * - * Side Effects: - * New elements are created and appended the first list. - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Concat (l1, l2, flags) - Lst l1; /* The list to which l2 is to be appended */ - Lst l2; /* The list to append to l1 */ - int flags; /* LST_CONCNEW if LstNode's should be duplicated - * LST_CONCLINK if should just be relinked */ -{ - register ListNode ln; /* original LstNode */ - register ListNode nln; /* new LstNode */ - register ListNode last; /* the last element in the list. Keeps - * bookkeeping until the end */ - register List list1 = (List)l1; - register List list2 = (List)l2; - - if (!LstValid (l1) || !LstValid (l2)) { - return (FAILURE); - } - - if (flags == LST_CONCLINK) { - if (list2->firstPtr != NilListNode) { - /* - * We set the nextPtr of the - * last element of list two to be NIL to make the loop easier and - * so we don't need an extra case should the first list turn - * out to be non-circular -- the final element will already point - * to NIL space and the first element will be untouched if it - * existed before and will also point to NIL space if it didn't. - */ - list2->lastPtr->nextPtr = NilListNode; - /* - * So long as the second list isn't empty, we just link the - * first element of the second list to the last element of the - * first list. If the first list isn't empty, we then link the - * last element of the list to the first element of the second list - * The last element of the second list, if it exists, then becomes - * the last element of the first list. - */ - list2->firstPtr->prevPtr = list1->lastPtr; - if (list1->lastPtr != NilListNode) { - list1->lastPtr->nextPtr = list2->firstPtr; - } else { - list1->firstPtr = list2->firstPtr; - } - list1->lastPtr = list2->lastPtr; - } - if (list1->isCirc && list1->firstPtr != NilListNode) { - /* - * If the first list is supposed to be circular and it is (now) - * non-empty, we must make sure it's circular by linking the - * first element to the last and vice versa - */ - list1->firstPtr->prevPtr = list1->lastPtr; - list1->lastPtr->nextPtr = list1->firstPtr; - } - free ((Address)l2); - } else if (list2->firstPtr != NilListNode) { - /* - * We set the nextPtr of the last element of list 2 to be nil to make - * the loop less difficult. The loop simply goes through the entire - * second list creating new LstNodes and filling in the nextPtr, and - * prevPtr to fit into l1 and its datum field from the - * datum field of the corresponding element in l2. The 'last' node - * follows the last of the new nodes along until the entire l2 has - * been appended. Only then does the bookkeeping catch up with the - * changes. During the first iteration of the loop, if 'last' is nil, - * the first list must have been empty so the newly-created node is - * made the first node of the list. - */ - list2->lastPtr->nextPtr = NilListNode; - for (last = list1->lastPtr, ln = list2->firstPtr; - ln != NilListNode; - ln = ln->nextPtr) - { - PAlloc (nln, ListNode); - nln->datum = ln->datum; - if (last != NilListNode) { - last->nextPtr = nln; - } else { - list1->firstPtr = nln; - } - nln->prevPtr = last; - nln->flags = nln->useCount = 0; - last = nln; - } - - /* - * Finish bookkeeping. The last new element becomes the last element - * of list one. - */ - list1->lastPtr = last; - - /* - * The circularity of both list one and list two must be corrected - * for -- list one because of the new nodes added to it; list two - * because of the alteration of list2->lastPtr's nextPtr to ease the - * above for loop. - */ - if (list1->isCirc) { - list1->lastPtr->nextPtr = list1->firstPtr; - list1->firstPtr->prevPtr = list1->lastPtr; - } else { - last->nextPtr = NilListNode; - } - - if (list2->isCirc) { - list2->lastPtr->nextPtr = list2->firstPtr; - } - } - - return (SUCCESS); -} - diff --git a/bootstrap/bmake/lst.lib/lstDatum.c b/bootstrap/bmake/lst.lib/lstDatum.c deleted file mode 100644 index 35d90c9f57d..00000000000 --- a/bootstrap/bmake/lst.lib/lstDatum.c +++ /dev/null @@ -1,82 +0,0 @@ -/* $NetBSD: lstDatum.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstDatum.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstDatum.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstDatum.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstDatum.c -- - * Return the datum associated with a list node. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Datum -- - * Return the datum stored in the given node. - * - * Results: - * The datum or (ick!) NIL if the node is invalid. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -ClientData -Lst_Datum (ln) - LstNode ln; -{ - if (ln != NILLNODE) { - return (((ListNode)ln)->datum); - } else { - return ((ClientData) NIL); - } -} - diff --git a/bootstrap/bmake/lst.lib/lstDeQueue.c b/bootstrap/bmake/lst.lib/lstDeQueue.c deleted file mode 100644 index 1aa2c7211b2..00000000000 --- a/bootstrap/bmake/lst.lib/lstDeQueue.c +++ /dev/null @@ -1,92 +0,0 @@ -/* $NetBSD: lstDeQueue.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstDeQueue.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstDeQueue.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstDeQueue.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstDeQueue.c -- - * Remove the node and return its datum from the head of the list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_DeQueue -- - * Remove and return the datum at the head of the given list. - * - * Results: - * The datum in the node at the head or (ick) NIL if the list - * is empty. - * - * Side Effects: - * The head node is removed from the list. - * - *----------------------------------------------------------------------- - */ -ClientData -Lst_DeQueue (l) - Lst l; -{ - ClientData rd; - register ListNode tln; - - tln = (ListNode) Lst_First (l); - if (tln == NilListNode) { - return ((ClientData) NIL); - } - - rd = tln->datum; - if (Lst_Remove (l, (LstNode)tln) == FAILURE) { - return ((ClientData) NIL); - } else { - return (rd); - } -} - diff --git a/bootstrap/bmake/lst.lib/lstDestroy.c b/bootstrap/bmake/lst.lib/lstDestroy.c deleted file mode 100644 index 28bcf771065..00000000000 --- a/bootstrap/bmake/lst.lib/lstDestroy.c +++ /dev/null @@ -1,113 +0,0 @@ -/* $NetBSD: lstDestroy.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstDestroy.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstDestroy.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstDestroy.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstDestroy.c -- - * Nuke a list and all its resources - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Destroy -- - * Destroy a list and free all its resources. If the freeProc is - * given, it is called with the datum from each node in turn before - * the node is freed. - * - * Results: - * None. - * - * Side Effects: - * The given list is freed in its entirety. - * - *----------------------------------------------------------------------- - */ -void -Lst_Destroy (l, freeProc) - Lst l; - register void (*freeProc) __P((ClientData)); -{ - register ListNode ln; - register ListNode tln = NilListNode; - register List list = (List)l; - - if (l == NILLST || ! l) { - /* - * Note the check for l == (Lst)0 to catch uninitialized static Lst's. - * Gross, but useful. - */ - return; - } - - /* To ease scanning */ - if (list->lastPtr != NilListNode) - list->lastPtr->nextPtr = NilListNode; - else { - free ((Address)l); - return; - } - - if (freeProc) { - for (ln = list->firstPtr; ln != NilListNode; ln = tln) { - tln = ln->nextPtr; - (*freeProc) (ln->datum); - free ((Address)ln); - } - } else { - for (ln = list->firstPtr; ln != NilListNode; ln = tln) { - tln = ln->nextPtr; - free ((Address)ln); - } - } - - free ((Address)l); -} diff --git a/bootstrap/bmake/lst.lib/lstDupl.c b/bootstrap/bmake/lst.lib/lstDupl.c deleted file mode 100644 index 556e2abc84b..00000000000 --- a/bootstrap/bmake/lst.lib/lstDupl.c +++ /dev/null @@ -1,110 +0,0 @@ -/* $NetBSD: lstDupl.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstDupl.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstDupl.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstDupl.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * listDupl.c -- - * Duplicate a list. This includes duplicating the individual - * elements. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Duplicate -- - * Duplicate an entire list. If a function to copy a ClientData is - * given, the individual client elements will be duplicated as well. - * - * Results: - * The new Lst structure or NILLST if failure. - * - * Side Effects: - * A new list is created. - *----------------------------------------------------------------------- - */ -Lst -Lst_Duplicate (l, copyProc) - Lst l; /* the list to duplicate */ - /* A function to duplicate each ClientData */ - ClientData (*copyProc) __P((ClientData)); -{ - register Lst nl; - register ListNode ln; - register List list = (List)l; - - if (!LstValid (l)) { - return (NILLST); - } - - nl = Lst_Init (list->isCirc); - if (nl == NILLST) { - return (NILLST); - } - - ln = list->firstPtr; - while (ln != NilListNode) { - if (copyProc != NOCOPY) { - if (Lst_AtEnd (nl, (*copyProc) (ln->datum)) == FAILURE) { - return (NILLST); - } - } else if (Lst_AtEnd (nl, ln->datum) == FAILURE) { - return (NILLST); - } - - if (list->isCirc && ln == list->lastPtr) { - ln = NilListNode; - } else { - ln = ln->nextPtr; - } - } - - return (nl); -} diff --git a/bootstrap/bmake/lst.lib/lstEnQueue.c b/bootstrap/bmake/lst.lib/lstEnQueue.c deleted file mode 100644 index c473f72f7a6..00000000000 --- a/bootstrap/bmake/lst.lib/lstEnQueue.c +++ /dev/null @@ -1,84 +0,0 @@ -/* $NetBSD: lstEnQueue.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstEnQueue.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstEnQueue.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstEnQueue.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstEnQueue.c-- - * Treat the list as a queue and place a datum at its end - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_EnQueue -- - * Add the datum to the tail of the given list. - * - * Results: - * SUCCESS or FAILURE as returned by Lst_Append. - * - * Side Effects: - * the lastPtr field is altered all the time and the firstPtr field - * will be altered if the list used to be empty. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_EnQueue (l, d) - Lst l; - ClientData d; -{ - if (LstValid (l) == FALSE) { - return (FAILURE); - } - - return (Lst_Append (l, Lst_Last(l), d)); -} - diff --git a/bootstrap/bmake/lst.lib/lstFind.c b/bootstrap/bmake/lst.lib/lstFind.c deleted file mode 100644 index 24ef0dfccc4..00000000000 --- a/bootstrap/bmake/lst.lib/lstFind.c +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: lstFind.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstFind.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstFind.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstFind.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstFind.c -- - * Find a node on a list. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Find -- - * Find a node on the given list using the given comparison function - * and the given datum. - * - * Results: - * The found node or NILLNODE if none matches. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Find (l, d, cProc) - Lst l; - ClientData d; - int (*cProc) __P((ClientData, ClientData)); -{ - return (Lst_FindFrom (l, Lst_First(l), d, cProc)); -} - diff --git a/bootstrap/bmake/lst.lib/lstFindFrom.c b/bootstrap/bmake/lst.lib/lstFindFrom.c deleted file mode 100644 index a402fec8353..00000000000 --- a/bootstrap/bmake/lst.lib/lstFindFrom.c +++ /dev/null @@ -1,105 +0,0 @@ -/* $NetBSD: lstFindFrom.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstFindFrom.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstFindFrom.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstFindFrom.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstFindFrom.c -- - * Find a node on a list from a given starting point. Used by Lst_Find. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_FindFrom -- - * Search for a node starting and ending with the given one on the - * given list using the passed datum and comparison function to - * determine when it has been found. - * - * Results: - * The found node or NILLNODE - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_FindFrom (l, ln, d, cProc) - Lst l; - register LstNode ln; - register ClientData d; - register int (*cProc) __P((ClientData, ClientData)); -{ - register ListNode tln; - Boolean found = FALSE; - - if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) { - return (NILLNODE); - } - - tln = (ListNode)ln; - - do { - if ((*cProc) (tln->datum, d) == 0) { - found = TRUE; - break; - } else { - tln = tln->nextPtr; - } - } while (tln != (ListNode)ln && tln != NilListNode); - - if (found) { - return ((LstNode)tln); - } else { - return (NILLNODE); - } -} - diff --git a/bootstrap/bmake/lst.lib/lstFirst.c b/bootstrap/bmake/lst.lib/lstFirst.c deleted file mode 100644 index 245f632dc4e..00000000000 --- a/bootstrap/bmake/lst.lib/lstFirst.c +++ /dev/null @@ -1,82 +0,0 @@ -/* $NetBSD: lstFirst.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstFirst.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstFirst.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstFirst.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstFirst.c -- - * Return the first node of a list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_First -- - * Return the first node on the given list. - * - * Results: - * The first node or NILLNODE if the list is empty. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_First (l) - Lst l; -{ - if (!LstValid (l) || LstIsEmpty (l)) { - return (NILLNODE); - } else { - return ((LstNode)((List)l)->firstPtr); - } -} - diff --git a/bootstrap/bmake/lst.lib/lstForEach.c b/bootstrap/bmake/lst.lib/lstForEach.c deleted file mode 100644 index 6f919468ba7..00000000000 --- a/bootstrap/bmake/lst.lib/lstForEach.c +++ /dev/null @@ -1,83 +0,0 @@ -/* $NetBSD: lstForEach.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstForEach.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstForEach.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstForEach.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstForeach.c -- - * Perform a given function on all elements of a list. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_ForEach -- - * Apply the given function to each element of the given list. The - * function should return 0 if Lst_ForEach should continue and non- - * zero if it should abort. - * - * Results: - * None. - * - * Side Effects: - * Only those created by the passed-in function. - * - *----------------------------------------------------------------------- - */ -/*VARARGS2*/ -void -Lst_ForEach (l, proc, d) - Lst l; - register int (*proc) __P((ClientData, ClientData)); - register ClientData d; -{ - Lst_ForEachFrom(l, Lst_First(l), proc, d); -} - diff --git a/bootstrap/bmake/lst.lib/lstForEachFrom.c b/bootstrap/bmake/lst.lib/lstForEachFrom.c deleted file mode 100644 index 66ed9d9b240..00000000000 --- a/bootstrap/bmake/lst.lib/lstForEachFrom.c +++ /dev/null @@ -1,123 +0,0 @@ -/* $NetBSD: lstForEachFrom.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstForEachFrom.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstForEachFrom.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstForEachFrom.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * lstForEachFrom.c -- - * Perform a given function on all elements of a list starting from - * a given point. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_ForEachFrom -- - * Apply the given function to each element of the given list. The - * function should return 0 if traversal should continue and non- - * zero if it should abort. - * - * Results: - * None. - * - * Side Effects: - * Only those created by the passed-in function. - * - *----------------------------------------------------------------------- - */ -/*VARARGS2*/ -void -Lst_ForEachFrom (l, ln, proc, d) - Lst l; - LstNode ln; - register int (*proc) __P((ClientData, ClientData)); - register ClientData d; -{ - register ListNode tln = (ListNode)ln; - register List list = (List)l; - register ListNode next; - Boolean done; - int result; - - if (!LstValid (list) || LstIsEmpty (list)) { - return; - } - - do { - /* - * Take care of having the current element deleted out from under - * us. - */ - - next = tln->nextPtr; - - (void) tln->useCount++; - result = (*proc) (tln->datum, d); - (void) tln->useCount--; - - /* - * We're done with the traversal if - * - nothing's been added after the current node and - * - the next node to examine is the first in the queue or - * doesn't exist. - */ - done = (next == tln->nextPtr && - (next == NilListNode || next == list->firstPtr)); - - next = tln->nextPtr; - - if (tln->flags & LN_DELETED) { - free((char *)tln); - } - tln = next; - } while (!result && !LstIsEmpty(list) && !done); - -} - diff --git a/bootstrap/bmake/lst.lib/lstInit.c b/bootstrap/bmake/lst.lib/lstInit.c deleted file mode 100644 index e8fe69afece..00000000000 --- a/bootstrap/bmake/lst.lib/lstInit.c +++ /dev/null @@ -1,87 +0,0 @@ -/* $NetBSD: lstInit.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstInit.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstInit.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstInit.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * init.c -- - * Initialize a new linked list. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Init -- - * Create and initialize a new list. - * - * Results: - * The created list. - * - * Side Effects: - * A list is created, what else? - * - *----------------------------------------------------------------------- - */ -Lst -Lst_Init(circ) - Boolean circ; /* TRUE if the list should be made circular */ -{ - register List nList; - - PAlloc (nList, List); - - nList->firstPtr = NilListNode; - nList->lastPtr = NilListNode; - nList->isOpen = FALSE; - nList->isCirc = circ; - nList->atEnd = Unknown; - - return ((Lst)nList); -} diff --git a/bootstrap/bmake/lst.lib/lstInsert.c b/bootstrap/bmake/lst.lib/lstInsert.c deleted file mode 100644 index 7656418a1f3..00000000000 --- a/bootstrap/bmake/lst.lib/lstInsert.c +++ /dev/null @@ -1,124 +0,0 @@ -/* $NetBSD: lstInsert.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstInsert.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstInsert.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstInsert.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstInsert.c -- - * Insert a new datum before an old one - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Insert -- - * Insert a new node with the given piece of data before the given - * node in the given list. - * - * Results: - * SUCCESS or FAILURE. - * - * Side Effects: - * the firstPtr field will be changed if ln is the first node in the - * list. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Insert (l, ln, d) - Lst l; /* list to manipulate */ - LstNode ln; /* node before which to insert d */ - ClientData d; /* datum to be inserted */ -{ - register ListNode nLNode; /* new lnode for d */ - register ListNode lNode = (ListNode)ln; - register List list = (List)l; - - - /* - * check validity of arguments - */ - if (LstValid (l) && (LstIsEmpty (l) && ln == NILLNODE)) - goto ok; - - if (!LstValid (l) || LstIsEmpty (l) || !LstNodeValid (ln, l)) { - return (FAILURE); - } - - ok: - PAlloc (nLNode, ListNode); - - nLNode->datum = d; - nLNode->useCount = nLNode->flags = 0; - - if (ln == NILLNODE) { - if (list->isCirc) { - nLNode->prevPtr = nLNode->nextPtr = nLNode; - } else { - nLNode->prevPtr = nLNode->nextPtr = NilListNode; - } - list->firstPtr = list->lastPtr = nLNode; - } else { - nLNode->prevPtr = lNode->prevPtr; - nLNode->nextPtr = lNode; - - if (nLNode->prevPtr != NilListNode) { - nLNode->prevPtr->nextPtr = nLNode; - } - lNode->prevPtr = nLNode; - - if (lNode == list->firstPtr) { - list->firstPtr = nLNode; - } - } - - return (SUCCESS); -} - diff --git a/bootstrap/bmake/lst.lib/lstInt.h b/bootstrap/bmake/lst.lib/lstInt.h deleted file mode 100644 index 718f9faff1a..00000000000 --- a/bootstrap/bmake/lst.lib/lstInt.h +++ /dev/null @@ -1,113 +0,0 @@ -/* $NetBSD: lstInt.h,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)lstInt.h 8.1 (Berkeley) 6/6/93 - */ - -/*- - * lstInt.h -- - * Internals for the list library - */ -#ifndef _LSTINT_H_ -#define _LSTINT_H_ - -#include "make.h" -#include "lst.h" - -typedef struct ListNode { - struct ListNode *prevPtr; /* previous element in list */ - struct ListNode *nextPtr; /* next in list */ - short useCount:8, /* Count of functions using the node. - * node may not be deleted until count - * goes to 0 */ - flags:8; /* Node status flags */ - ClientData datum; /* datum associated with this element */ -} *ListNode; -/* - * Flags required for synchronization - */ -#define LN_DELETED 0x0001 /* List node should be removed when done */ - -#define NilListNode ((ListNode)-1) - -typedef enum { - Head, Middle, Tail, Unknown -} Where; - -typedef struct { - ListNode firstPtr; /* first node in list */ - ListNode lastPtr; /* last node in list */ - Boolean isCirc; /* true if the list should be considered - * circular */ -/* - * fields for sequential access - */ - Where atEnd; /* Where in the list the last access was */ - Boolean isOpen; /* true if list has been Lst_Open'ed */ - ListNode curPtr; /* current node, if open. NilListNode if - * *just* opened */ - ListNode prevPtr; /* Previous node, if open. Used by - * Lst_Remove */ -} *List; - -#define NilList ((List)-1) - -/* - * PAlloc (var, ptype) -- - * Allocate a pointer-typedef structure 'ptype' into the variable 'var' - */ -#define PAlloc(var,ptype) var = (ptype) emalloc (sizeof (*var)) - -/* - * LstValid (l) -- - * Return TRUE if the list l is valid - */ -#define LstValid(l) (((Lst)l == NILLST) ? FALSE : TRUE) - -/* - * LstNodeValid (ln, l) -- - * Return TRUE if the LstNode ln is valid with respect to l - */ -#define LstNodeValid(ln, l) ((((LstNode)ln) == NILLNODE) ? FALSE : TRUE) - -/* - * LstIsEmpty (l) -- - * TRUE if the list l is empty. - */ -#define LstIsEmpty(l) (((List)l)->firstPtr == NilListNode) - -#endif /* _LSTINT_H_ */ diff --git a/bootstrap/bmake/lst.lib/lstIsAtEnd.c b/bootstrap/bmake/lst.lib/lstIsAtEnd.c deleted file mode 100644 index 6fd9714e0c6..00000000000 --- a/bootstrap/bmake/lst.lib/lstIsAtEnd.c +++ /dev/null @@ -1,92 +0,0 @@ -/* $NetBSD: lstIsAtEnd.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstIsAtEnd.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstIsAtEnd.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstIsAtEnd.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstIsAtEnd.c -- - * Tell if the current node is at the end of the list. - * The sequential functions access the list in a slightly different way. - * CurPtr points to their idea of the current node in the list and they - * access the list based on it. Because the list is circular, Lst_Next - * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be - * used to determine when to stop. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_IsAtEnd -- - * Return true if have reached the end of the given list. - * - * Results: - * TRUE if at the end of the list (this includes the list not being - * open or being invalid) or FALSE if not. We return TRUE if the list - * is invalid or unopend so as to cause the caller to exit its loop - * asap, the assumption being that the loop is of the form - * while (!Lst_IsAtEnd (l)) { - * ... - * } - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -Boolean -Lst_IsAtEnd (l) - Lst l; -{ - register List list = (List) l; - - return (!LstValid (l) || !list->isOpen || - (list->atEnd == Head) || (list->atEnd == Tail)); -} - diff --git a/bootstrap/bmake/lst.lib/lstIsEmpty.c b/bootstrap/bmake/lst.lib/lstIsEmpty.c deleted file mode 100644 index dc2a5cf2b27..00000000000 --- a/bootstrap/bmake/lst.lib/lstIsEmpty.c +++ /dev/null @@ -1,80 +0,0 @@ -/* $NetBSD: lstIsEmpty.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstIsEmpty.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstIsEmpty.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstIsEmpty.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstIsEmpty.c -- - * A single function to decide if a list is empty - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_IsEmpty -- - * Return TRUE if the given list is empty. - * - * Results: - * TRUE if the list is empty, FALSE otherwise. - * - * Side Effects: - * None. - * - * A list is considered empty if its firstPtr == NilListNode (or if - * the list itself is NILLIST). - *----------------------------------------------------------------------- - */ -Boolean -Lst_IsEmpty (l) - Lst l; -{ - return ( ! LstValid (l) || LstIsEmpty(l)); -} - diff --git a/bootstrap/bmake/lst.lib/lstLast.c b/bootstrap/bmake/lst.lib/lstLast.c deleted file mode 100644 index e091ebb36fe..00000000000 --- a/bootstrap/bmake/lst.lib/lstLast.c +++ /dev/null @@ -1,82 +0,0 @@ -/* $NetBSD: lstLast.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstLast.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstLast.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstLast.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstLast.c -- - * Return the last element of a list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Last -- - * Return the last node on the list l. - * - * Results: - * The requested node or NILLNODE if the list is empty. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Last (l) - Lst l; -{ - if (!LstValid(l) || LstIsEmpty (l)) { - return (NILLNODE); - } else { - return ((LstNode)((List)l)->lastPtr); - } -} - diff --git a/bootstrap/bmake/lst.lib/lstMember.c b/bootstrap/bmake/lst.lib/lstMember.c deleted file mode 100644 index 4847bb23924..00000000000 --- a/bootstrap/bmake/lst.lib/lstMember.c +++ /dev/null @@ -1,80 +0,0 @@ -/* $NetBSD: lstMember.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstMember.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstMember.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstMember.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * lstMember.c -- - * See if a given datum is on a given list. - */ - -#include "lstInt.h" - -LstNode -Lst_Member (l, d) - Lst l; - ClientData d; -{ - List list = (List) l; - register ListNode lNode; - - lNode = list->firstPtr; - if (lNode == NilListNode) { - return NILLNODE; - } - - do { - if (lNode->datum == d) { - return (LstNode)lNode; - } - lNode = lNode->nextPtr; - } while (lNode != NilListNode && lNode != list->firstPtr); - - return NILLNODE; -} diff --git a/bootstrap/bmake/lst.lib/lstNext.c b/bootstrap/bmake/lst.lib/lstNext.c deleted file mode 100644 index c98bff2c0ab..00000000000 --- a/bootstrap/bmake/lst.lib/lstNext.c +++ /dev/null @@ -1,125 +0,0 @@ -/* $NetBSD: lstNext.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstNext.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstNext.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstNext.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstNext.c -- - * Return the next node for a list. - * The sequential functions access the list in a slightly different way. - * CurPtr points to their idea of the current node in the list and they - * access the list based on it. Because the list is circular, Lst_Next - * and Lst_Prev will go around the list forever. Lst_IsAtEnd must be - * used to determine when to stop. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Next -- - * Return the next node for the given list. - * - * Results: - * The next node or NILLNODE if the list has yet to be opened. Also - * if the list is non-circular and the end has been reached, NILLNODE - * is returned. - * - * Side Effects: - * the curPtr field is updated. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Next (l) - Lst l; -{ - register ListNode tln; - register List list = (List)l; - - if ((LstValid (l) == FALSE) || - (list->isOpen == FALSE)) { - return (NILLNODE); - } - - list->prevPtr = list->curPtr; - - if (list->curPtr == NilListNode) { - if (list->atEnd == Unknown) { - /* - * If we're just starting out, atEnd will be Unknown. - * Then we want to start this thing off in the right - * direction -- at the start with atEnd being Middle. - */ - list->curPtr = tln = list->firstPtr; - list->atEnd = Middle; - } else { - tln = NilListNode; - list->atEnd = Tail; - } - } else { - tln = list->curPtr->nextPtr; - list->curPtr = tln; - - if (tln == list->firstPtr || tln == NilListNode) { - /* - * If back at the front, then we've hit the end... - */ - list->atEnd = Tail; - } else { - /* - * Reset to Middle if gone past first. - */ - list->atEnd = Middle; - } - } - - return ((LstNode)tln); -} - diff --git a/bootstrap/bmake/lst.lib/lstOpen.c b/bootstrap/bmake/lst.lib/lstOpen.c deleted file mode 100644 index 401b9a896ac..00000000000 --- a/bootstrap/bmake/lst.lib/lstOpen.c +++ /dev/null @@ -1,92 +0,0 @@ -/* $NetBSD: lstOpen.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstOpen.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstOpen.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstOpen.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstOpen.c -- - * Open a list for sequential access. The sequential functions access the - * list in a slightly different way. CurPtr points to their idea of the - * current node in the list and they access the list based on it. - * If the list is circular, Lst_Next and Lst_Prev will go around - * the list forever. Lst_IsAtEnd must be used to determine when to stop. - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Open -- - * Open a list for sequential access. A list can still be searched, - * etc., without confusing these functions. - * - * Results: - * SUCCESS or FAILURE. - * - * Side Effects: - * isOpen is set TRUE and curPtr is set to NilListNode so the - * other sequential functions no it was just opened and can choose - * the first element accessed based on this. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Open (l) - register Lst l; -{ - if (LstValid (l) == FALSE) { - return (FAILURE); - } - ((List) l)->isOpen = TRUE; - ((List) l)->atEnd = LstIsEmpty (l) ? Head : Unknown; - ((List) l)->curPtr = NilListNode; - - return (SUCCESS); -} - diff --git a/bootstrap/bmake/lst.lib/lstRemove.c b/bootstrap/bmake/lst.lib/lstRemove.c deleted file mode 100644 index 9790fc8ce96..00000000000 --- a/bootstrap/bmake/lst.lib/lstRemove.c +++ /dev/null @@ -1,142 +0,0 @@ -/* $NetBSD: lstRemove.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstRemove.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstRemove.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstRemove.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstRemove.c -- - * Remove an element from a list - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Remove -- - * Remove the given node from the given list. - * - * Results: - * SUCCESS or FAILURE. - * - * Side Effects: - * The list's firstPtr will be set to NilListNode if ln is the last - * node on the list. firsPtr and lastPtr will be altered if ln is - * either the first or last node, respectively, on the list. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Remove (l, ln) - Lst l; - LstNode ln; -{ - register List list = (List) l; - register ListNode lNode = (ListNode) ln; - - if (!LstValid (l) || - !LstNodeValid (ln, l)) { - return (FAILURE); - } - - /* - * unlink it from the list - */ - if (lNode->nextPtr != NilListNode) { - lNode->nextPtr->prevPtr = lNode->prevPtr; - } - if (lNode->prevPtr != NilListNode) { - lNode->prevPtr->nextPtr = lNode->nextPtr; - } - - /* - * if either the firstPtr or lastPtr of the list point to this node, - * adjust them accordingly - */ - if (list->firstPtr == lNode) { - list->firstPtr = lNode->nextPtr; - } - if (list->lastPtr == lNode) { - list->lastPtr = lNode->prevPtr; - } - - /* - * Sequential access stuff. If the node we're removing is the current - * node in the list, reset the current node to the previous one. If the - * previous one was non-existent (prevPtr == NilListNode), we set the - * end to be Unknown, since it is. - */ - if (list->isOpen && (list->curPtr == lNode)) { - list->curPtr = list->prevPtr; - if (list->curPtr == NilListNode) { - list->atEnd = Unknown; - } - } - - /* - * the only way firstPtr can still point to ln is if ln is the last - * node on the list (the list is circular, so lNode->nextptr == lNode in - * this case). The list is, therefore, empty and is marked as such - */ - if (list->firstPtr == lNode) { - list->firstPtr = NilListNode; - } - - /* - * note that the datum is unmolested. The caller must free it as - * necessary and as expected. - */ - if (lNode->useCount == 0) { - free ((Address)ln); - } else { - lNode->flags |= LN_DELETED; - } - - return (SUCCESS); -} - diff --git a/bootstrap/bmake/lst.lib/lstReplace.c b/bootstrap/bmake/lst.lib/lstReplace.c deleted file mode 100644 index 2b06b25caa1..00000000000 --- a/bootstrap/bmake/lst.lib/lstReplace.c +++ /dev/null @@ -1,84 +0,0 @@ -/* $NetBSD: lstReplace.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstReplace.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstReplace.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstReplace.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstReplace.c -- - * Replace the datum in a node with a new datum - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Replace -- - * Replace the datum in the given node with the new datum - * - * Results: - * SUCCESS or FAILURE. - * - * Side Effects: - * The datum field fo the node is altered. - * - *----------------------------------------------------------------------- - */ -ReturnStatus -Lst_Replace (ln, d) - register LstNode ln; - ClientData d; -{ - if (ln == NILLNODE) { - return (FAILURE); - } else { - ((ListNode) ln)->datum = d; - return (SUCCESS); - } -} - diff --git a/bootstrap/bmake/lst.lib/lstSucc.c b/bootstrap/bmake/lst.lib/lstSucc.c deleted file mode 100644 index 6c3375407d7..00000000000 --- a/bootstrap/bmake/lst.lib/lstSucc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* $NetBSD: lstSucc.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: lstSucc.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)lstSucc.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: lstSucc.c,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * LstSucc.c -- - * return the successor to a given node - */ - -#include "lstInt.h" - -/*- - *----------------------------------------------------------------------- - * Lst_Succ -- - * Return the sucessor to the given node on its list. - * - * Results: - * The successor of the node, if it exists (note that on a circular - * list, if the node is the only one in the list, it is its own - * successor). - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -LstNode -Lst_Succ (ln) - LstNode ln; -{ - if (ln == NILLNODE) { - return (NILLNODE); - } else { - return ((LstNode) ((ListNode) ln)->nextPtr); - } -} - diff --git a/bootstrap/bmake/lst.lib/makefile.boot.in b/bootstrap/bmake/lst.lib/makefile.boot.in deleted file mode 100644 index ebb29195412..00000000000 --- a/bootstrap/bmake/lst.lib/makefile.boot.in +++ /dev/null @@ -1,45 +0,0 @@ -# RCSid: -# $Id: makefile.boot.in,v 1.1.1.1 2004/03/11 13:04:17 grant Exp $ - -srcdir=@srcdir@ -VPATH=.:$(srcdir) - -OBJ=lstAppend.o lstDupl.o lstInit.o lstOpen.o lstAtEnd.o lstEnQueue.o \ - lstInsert.o lstAtFront.o lstIsAtEnd.o lstClose.o lstFind.o lstIsEmpty.o \ - lstRemove.o lstConcat.o lstFindFrom.o lstLast.o lstReplace.o lstFirst.o \ - lstDatum.o lstForEach.o lstMember.o lstSucc.o lstDeQueue.o \ - lstForEachFrom.o lstDestroy.o lstNext.o - -CFLAGS=-I.. -all: ${OBJ} - mv *.o .. - -depend: - VPATH=${VPATH} ${MKDEP} -f makefile.boot ${CFLAGS} ${OBJ:.o=.c} - -#lstAppend.o: $(srcdir)/lstAppend.c -#lstDupl.o: $(srcdir)/lstDupl.c -#lstInit.o: $(srcdir)/lstInit.c -#lstOpen.o: $(srcdir)/lstOpen.c -#lstAtEnd.o: $(srcdir)/lstAtEnd.c -#lstEnQueue.o: $(srcdir)/lstEnQueue.c -#lstInsert.o: $(srcdir)/lstInsert.c -#lstAtFront.o: $(srcdir)/lstAtFront.c -#lstIsAtEnd.o: $(srcdir)/lstIsAtEnd.c -#lstClose.o: $(srcdir)/lstClose.c -#lstFind.o: $(srcdir)/lstFind.c -#lstIsEmpty.o: $(srcdir)/lstIsEmpty.c -#lstRemove.o: $(srcdir)/lstRemove.c -#lstConcat.o: $(srcdir)/lstConcat.c -#lstFindFrom.o: $(srcdir)/lstFindFrom.c -#lstLast.o: $(srcdir)/lstLast.c -#lstReplace.o: $(srcdir)/lstReplace.c -#lstFirst.o: $(srcdir)/lstFirst.c -#lstDatum.o: $(srcdir)/lstDatum.c -#lstForEach.o: $(srcdir)/lstForEach.c -#lstMember.o: $(srcdir)/lstMember.c -#lstSucc.o: $(srcdir)/lstSucc.c -#lstDeQueue.o: $(srcdir)/lstDeQueue.c -#lstForEachFrom.o: $(srcdir)/lstForEachFrom.c -#lstDestroy.o: $(srcdir)/lstDestroy.c -#lstNext.o: $(srcdir)/lstNext.c diff --git a/bootstrap/bmake/machine.sh b/bootstrap/bmake/machine.sh deleted file mode 100755 index 8d70608ebae..00000000000 --- a/bootstrap/bmake/machine.sh +++ /dev/null @@ -1,85 +0,0 @@ -: -# derrived from /etc/rc_d/os.sh - -# RCSid: -# $Id: machine.sh,v 1.2 2004/04/11 03:12:17 heinz Exp $ -# -# @(#) Copyright (c) 1994 Simon J. Gerraty -# -# This file is provided in the hope that it will -# be of use. There is absolutely NO WARRANTY. -# Permission to copy, redistribute or otherwise -# use this file is hereby granted provided that -# the above copyright notice and this notice are -# left intact. -# -# Please send copies of changes and bug-fixes to: -# sjg@quick.com.au -# - -OS=`uname` -OSREL=`uname -r` -OSMAJOR=`IFS=.; set $OSREL; echo $1` -machine=`uname -m` -MACHINE= - -# Great! Solaris keeps moving arch(1) -# we need this here, and it is not always available... -Which() { - pathcomponents=`IFS=:; echo ${2:-$PATH}` - for d in ${pathcomponents} - do - test -x $d/$1 && { echo $d/$1; break; } - done -} - -arch=`Which arch /usr/bin:/usr/ucb:$PATH` -test "$arch" && MACHINE_ARCH=`$arch` - -case $OS in -OpenBSD) - MACHINE=$OS$OSMAJOR.$machine - MACHINE_ARCH=`$arch -s`; - ;; -*BSD) - MACHINE=$OS$OSMAJOR.$machine - ;; -SunOS) - MACHINE=$OS$OSMAJOR - case "$MACHINE_ARCH" in - sparc|sun4*) ;; - sun386*) MACHINE=$MACHINE_ARCH;; - *) MACHINE=$MACHINE.$machine;; - esac - ;; -HP-UX) - MACHINE_ARCH=`IFS="/-."; set $machine; echo $1` - ;; -IRIX) - MACHINE_ARCH=`uname -p 2>/dev/null` - ;; -Interix) - MACHINE=i386 - MACHINE_ARCH=i386 - ;; -UnixWare) - OSREL=`uname -v` - OSMAJOR=`IFS=.; set $OSREL; echo $1` - ;; -esac - -MACHINE=${MACHINE:-$OS$OSMAJOR} -MACHINE_ARCH=${MACHINE_ARCH:-$machine} - - -( -case "$0" in -arch*) echo $MACHINE_ARCH;; -*) - case "$1" in - "") echo $MACHINE;; - *) echo $MACHINE_ARCH;; - esac - ;; -esac -) | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz diff --git a/bootstrap/bmake/main.c b/bootstrap/bmake/main.c deleted file mode 100644 index bd7a765202e..00000000000 --- a/bootstrap/bmake/main.c +++ /dev/null @@ -1,1795 +0,0 @@ -/* $NetBSD: main.c,v 1.3 2005/10/02 11:43:34 joerg Exp $ */ - -/* - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: main.c,v 1.3 2005/10/02 11:43:34 joerg Exp $"; -#else -#include -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993\n\ - The Regents of the University of California. All rights reserved.\n"); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: main.c,v 1.3 2005/10/02 11:43:34 joerg Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: main.c,v 1.3 2005/10/02 11:43:34 joerg Exp $"); -#endif - -/*- - * main.c -- - * The main file for this entire program. Exit routines etc - * reside here. - * - * Utility functions defined in this file: - * Main_ParseArgLine Takes a line of arguments, breaks them and - * treats them as if they were given when first - * invoked. Used by the parse module to implement - * the .MFLAGS target. - * - * Error Print a tagged error message. The global - * MAKE variable must have been defined. This - * takes a format string and two optional - * arguments for it. - * - * Fatal Print an error message and exit. Also takes - * a format string and two arguments. - * - * Punt Aborts all jobs and exits with a message. Also - * takes a format string and two arguments. - * - * Finish Finish things up by printing the number of - * errors which occurred, as passed to it, and - * exiting. - */ - -#include -#include -#include -#include -#include -#include -#ifndef MAKE_BOOTSTRAP -#include -#endif -#include -#include -#include -#include -#include -#ifdef __STDC__ -#include -#include -#else -#include -#endif -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" -#include "pathnames.h" -#include "trace.h" - -#ifdef USE_IOVEC -#include -#endif - -#ifndef DEFMAXLOCAL -#define DEFMAXLOCAL DEFMAXJOBS -#endif /* DEFMAXLOCAL */ - -Lst create; /* Targets to be made */ -time_t now; /* Time at start of make */ -GNode *DEFAULT; /* .DEFAULT node */ -Boolean allPrecious; /* .PRECIOUS given on line by itself */ - -static Boolean noBuiltins; /* -r flag */ -static Lst makefiles; /* ordered list of makefiles to read */ -static Boolean printVars; /* print value of one or more vars */ -static Lst variables; /* list of variables to print */ -int maxJobs; /* -j argument */ -static int maxLocal; /* -L argument */ -Boolean compatMake; /* -B argument */ -Boolean debug; /* -d flag */ -Boolean noExecute; /* -n flag */ -Boolean noRecursiveExecute; /* -N flag */ -Boolean keepgoing; /* -k flag */ -Boolean queryFlag; /* -q flag */ -Boolean touchFlag; /* -t flag */ -Boolean usePipes; /* !-P flag */ -Boolean ignoreErrors; /* -i flag */ -Boolean beSilent; /* -s flag */ -Boolean oldVars; /* variable substitution style */ -Boolean checkEnvFirst; /* -e flag */ -Boolean parseWarnFatal; /* -W flag */ -Boolean jobServer; /* -J flag */ -static Boolean jobsRunning; /* TRUE if the jobs might be running */ -static const char * tracefile; -#ifndef NO_CHECK_MAKE_CHDIR -static char * Check_Cwd_av __P((int, char **, int)); -#endif -static void MainParseArgs __P((int, char **)); -char * chdir_verify_path __P((char *, char *)); -static int ReadMakefile __P((ClientData, ClientData)); -static void usage __P((void)); - -static char *curdir; /* startup directory */ -static char *objdir; /* where we chdir'ed to */ -char *progname; /* the program name */ - -Boolean forceJobs = FALSE; - -/* - * On some systems MACHINE is defined as something other than - * what we want. - */ -#ifdef FORCE_MACHINE -# undef MACHINE -# define MACHINE FORCE_MACHINE -#endif - -extern Lst parseIncPath; - -/*- - * MainParseArgs -- - * Parse a given argument vector. Called from main() and from - * Main_ParseArgLine() when the .MAKEFLAGS target is used. - * - * XXX: Deal with command line overriding .MAKEFLAGS in makefile - * - * Results: - * None - * - * Side Effects: - * Various global and local flags will be set depending on the flags - * given - */ -static void -MainParseArgs(argc, argv) - int argc; - char **argv; -{ - char *p; - int arginc; - char *argvalue; - const char *getopt_def; - char *optscan; - Boolean inOption; - int c; - - if (argv[0] == 0) - argv[0] = progname; /* avoid problems in getopt */ - - optind = 1; /* since we're called more than once */ -#ifdef REMOTE -# define OPTFLAGS "BD:I:J:L:NPST:V:Wd:ef:ij:km:nqrst" -#else -# define OPTFLAGS "BD:I:J:NPST:V:Wd:ef:ij:km:nqrst" -#endif -#undef optarg -#define optarg argvalue -/* Can't actually use getopt(3) because rescanning is not portable */ - - getopt_def = OPTFLAGS; -rearg: - inOption = FALSE; - while(argc > 1) { - char *getopt_spec; - if(!inOption) - optscan = argv[1]; - c = *optscan++; - arginc = 0; - if(inOption) { - if(c == '\0') { - ++argv; - --argc; - inOption = FALSE; - continue; - } - } else { - if (c != '-') - break; - inOption = TRUE; - c = *optscan++; - } - /* '-' found at some earlier point */ - getopt_spec = strchr(getopt_def, c); - if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') { - /* - found, and should have an arg */ - inOption = FALSE; - arginc = 1; - argvalue = optscan; - if(*argvalue == '\0') { - argvalue = argv[2]; - arginc = 2; - } - } - switch(c) { - case '\0': - arginc = 1; - inOption = FALSE; - break; - case 'D': - Var_Set(optarg, "1", VAR_GLOBAL, 0); - Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - break; - case 'I': - Parse_AddIncludeDir(optarg); - Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - break; - case 'J': - if (sscanf(optarg, "%d,%d", &job_pipe[0], &job_pipe[1]) != 2) { - /* backslash to avoid trigraph ??) */ - (void)fprintf(stderr, - "%s: internal error -- J option malformed (%s?\?)\n", - progname, optarg); - usage(); - } - if ((fcntl(job_pipe[0], F_GETFD, 0) < 0) || - (fcntl(job_pipe[1], F_GETFD, 0) < 0)) { -#if 0 - (void)fprintf(stderr, - "%s: warning -- J descriptors were closed!\n", - progname); -#endif - job_pipe[0] = -1; - job_pipe[1] = -1; - compatMake = TRUE; - } else { - Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - jobServer = TRUE; - } - break; - case 'V': - printVars = TRUE; - (void)Lst_AtEnd(variables, (ClientData)optarg); - Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - break; - case 'B': - compatMake = TRUE; - break; -#ifdef REMOTE - case 'L': - maxLocal = strtol(optarg, &p, 0); - if (*p != '\0' || maxLocal < 1) { - (void) fprintf(stderr, "%s: illegal argument to -L -- must be positive integer!\n", - progname); - exit(1); - } - Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - break; -#endif - case 'N': - noExecute = TRUE; - noRecursiveExecute = TRUE; - Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL); - break; - case 'P': - usePipes = FALSE; - Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL); - break; - case 'S': - keepgoing = FALSE; - Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL); - break; - case 'T': - tracefile = estrdup(optarg); - Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - break; - case 'W': - parseWarnFatal = TRUE; - break; - case 'd': { - char *modules = optarg; - - for (; *modules; ++modules) - switch (*modules) { - case 'A': - debug = ~0; - break; - case 'a': - debug |= DEBUG_ARCH; - break; - case 'c': - debug |= DEBUG_COND; - break; - case 'd': - debug |= DEBUG_DIR; - break; - case 'f': - debug |= DEBUG_FOR; - break; - case 'g': - if (modules[1] == '1') { - debug |= DEBUG_GRAPH1; - ++modules; - } - else if (modules[1] == '2') { - debug |= DEBUG_GRAPH2; - ++modules; - } - break; - case 'j': - debug |= DEBUG_JOB; - break; - case 'm': - debug |= DEBUG_MAKE; - break; - case 's': - debug |= DEBUG_SUFF; - break; - case 't': - debug |= DEBUG_TARG; - break; - case 'v': - debug |= DEBUG_VAR; - break; - case 'x': - debug |= DEBUG_SHELL; - break; - default: - (void)fprintf(stderr, - "%s: illegal argument to d option -- %c\n", - progname, *modules); - usage(); - } - Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - break; - } - case 'e': - checkEnvFirst = TRUE; - Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL); - break; - case 'f': - (void)Lst_AtEnd(makefiles, (ClientData)optarg); - break; - case 'i': - ignoreErrors = TRUE; - Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL); - break; - case 'j': - forceJobs = TRUE; - maxJobs = strtol(optarg, &p, 0); - if (*p != '\0' || maxJobs < 1) { - (void) fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n", - progname); - exit(1); - } -#ifndef REMOTE - maxLocal = maxJobs; -#endif - Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - break; - case 'k': - keepgoing = TRUE; - Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL); - break; - case 'm': - (void) Dir_AddDir(sysIncPath, optarg); - Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL); - Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); - break; - case 'n': - noExecute = TRUE; - Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL); - break; - case 'q': - queryFlag = TRUE; - /* Kind of nonsensical, wot? */ - Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL); - break; - case 'r': - noBuiltins = TRUE; - Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL); - break; - case 's': - beSilent = TRUE; - Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL); - break; - case 't': - touchFlag = TRUE; - Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL); - break; - default: - case '?': -#ifdef MAKE_BOOTSTRAP - fprintf(stderr, "getopt(%s) -> %d (%c)\n", - OPTFLAGS, c, c); -#endif - usage(); - } - argv += arginc; - argc -= arginc; - } - - oldVars = TRUE; - - /* - * See if the rest of the arguments are variable assignments and - * perform them if so. Else take them to be targets and stuff them - * on the end of the "create" list. - */ - for (; argc > 1; ++argv, --argc) - if (Parse_IsVar(argv[1])) { - Parse_DoVar(argv[1], VAR_CMD); - } else { - if (!*argv[1]) - Punt("illegal (null) argument."); - if (*argv[1] == '-') - goto rearg; - (void)Lst_AtEnd(create, (ClientData)estrdup(argv[1])); - } -} - -/*- - * Main_ParseArgLine -- - * Used by the parse module when a .MFLAGS or .MAKEFLAGS target - * is encountered and by main() when reading the .MAKEFLAGS envariable. - * Takes a line of arguments and breaks it into its - * component words and passes those words and the number of them to the - * MainParseArgs function. - * The line should have all its leading whitespace removed. - * - * Results: - * None - * - * Side Effects: - * Only those that come from the various arguments. - */ -void -Main_ParseArgLine(line) - char *line; /* Line to fracture */ -{ - char **argv; /* Manufactured argument vector */ - int argc; /* Number of arguments in argv */ - char *args; /* Space used by the args */ - char *buf, *p1; - char *argv0 = Var_Value(".MAKE", VAR_GLOBAL, &p1); - size_t len; - - if (line == NULL) - return; - for (; *line == ' '; ++line) - continue; - if (!*line) - return; - -#ifndef POSIX - { - /* - * $MAKE may simply be naming the make(1) binary - */ - char *cp; - - if (!(cp = strrchr(line, '/'))) - cp = line; - if ((cp = strstr(cp, "make")) && - strcmp(cp, "make") == 0) - return; - } -#endif - buf = emalloc(len = strlen(line) + strlen(argv0) + 2); - (void)snprintf(buf, len, "%s %s", argv0, line); - if (p1) - free(p1); - - argv = brk_string(buf, &argc, TRUE, &args); - free(buf); - MainParseArgs(argc, argv); - - free(args); - free(argv); -} - -char * -chdir_verify_path(path, obpath) - char *path; - char *obpath; -{ - struct stat sb; - - if (strchr(path, '$') != 0) { - path = Var_Subst(NULL, path, VAR_GLOBAL, 0); - } - if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { - if (chdir(path)) { - (void)fprintf(stderr, "make warning: %s: %s.\n", - path, strerror(errno)); - return 0; - } - else { - if (path[0] != '/') { - (void) snprintf(obpath, MAXPATHLEN, "%s/%s", - curdir, path); - return obpath; - } - else - return path; - } - } - - return 0; -} - - -/*- - * main -- - * The main function, for obvious reasons. Initializes variables - * and a few modules, then parses the arguments give it in the - * environment and on the command line. Reads the system makefile - * followed by either Makefile, makefile or the file given by the - * -f argument. Sets the .MAKEFLAGS PMake variable based on all the - * flags it has received by then uses either the Make or the Compat - * module to create the initial list of targets. - * - * Results: - * If -q was given, exits -1 if anything was out-of-date. Else it exits - * 0. - * - * Side Effects: - * The program exits when done. Targets are created. etc. etc. etc. - */ -int -main(argc, argv) - int argc; - char **argv; -{ - Lst targs; /* target nodes to create -- passed to Make_Init */ - Boolean outOfDate = TRUE; /* FALSE if all targets up to date */ - struct stat sb, sa; - char *p1, *path, *pathp, *pwd, *getenv(), *getcwd(); - char mdpath[MAXPATHLEN + 1]; - char obpath[MAXPATHLEN + 1]; - char cdpath[MAXPATHLEN + 1]; -#ifdef FORCE_MACHINE - char *machine = FORCE_MACHINE; -#else - char *machine = getenv("MACHINE"); -#endif - char *machine_arch = getenv("MACHINE_ARCH"); - char *syspath = getenv("MAKESYSPATH"); - Lst sysMkPath; /* Path of sys.mk */ - char *cp = NULL, *start; - /* avoid faults on read-only strings */ - static char defsyspath[] = _PATH_DEFSYSPATH; - - if ((progname = strrchr(argv[0], '/')) != NULL) - progname++; - else - progname = argv[0]; - -#ifdef RLIMIT_NOFILE - /* - * get rid of resource limit on file descriptors - */ - { - struct rlimit rl; - if (getrlimit(RLIMIT_NOFILE, &rl) != -1 && - rl.rlim_cur != rl.rlim_max) { - rl.rlim_cur = rl.rlim_max; - (void) setrlimit(RLIMIT_NOFILE, &rl); - } - } -#endif - /* - * Find where we are and take care of PWD for the automounter... - * All this code is so that we know where we are when we start up - * on a different machine with pmake. - */ - curdir = cdpath; - if (getcwd(curdir, MAXPATHLEN) == NULL) { - (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); - exit(2); - } - - if (stat(curdir, &sa) == -1) { - (void)fprintf(stderr, "%s: %s: %s.\n", - progname, curdir, strerror(errno)); - exit(2); - } - - /* - * Overriding getcwd() with $PWD totally breaks MAKEOBJDIRPREFIX - * since the value of curdir can very depending on how we got - * here. Ie sitting at a shell prompt (shell that provides $PWD) - * or via subdir.mk in which case its likely a shell which does - * not provide it. - * So, to stop it breaking this case only, we ignore PWD if - * MAKEOBJDIRPREFIX is set. - */ -#ifndef NO_PWD_OVERRIDE - if ((pwd = getenv("PWD")) != NULL && - getenv("MAKEOBJDIRPREFIX") == NULL) { - if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && - sa.st_dev == sb.st_dev) - (void) strcpy(curdir, pwd); - } -#endif - /* - * Get the name of this type of MACHINE from utsname - * so we can share an executable for similar machines. - * (i.e. m68k: amiga hp300, mac68k, sun3, ...) - * - * Note that both MACHINE and MACHINE_ARCH are decided at - * run-time. - */ - if (!machine) { -#ifndef MAKE_BOOTSTRAP - struct utsname utsname; - - if (uname(&utsname) == -1) { - (void)fprintf(stderr, "%s: uname failed (%s).\n", progname, - strerror(errno)); - exit(2); - } - machine = utsname.machine; -#else - machine = MACHINE; -#endif - } - - if (!machine_arch) { -#ifndef MACHINE_ARCH -#ifdef __ARCHITECTURE__ - machine_arch = __ARCHITECTURE__; -#else - machine_arch = "unknown"; /* XXX: no uname -p yet */ -#endif -#else - machine_arch = MACHINE_ARCH; -#endif - } - - /* - * Just in case MAKEOBJDIR wants us to do something tricky. - */ - Var_Init(); /* Initialize the lists of variables for - * parsing arguments */ - Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0); - Var_Set("MACHINE", machine, VAR_GLOBAL, 0); - Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL, 0); -#ifdef MAKE_VERSION - Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL, 0); -#endif - Var_Set(".newline", "\n", VAR_GLOBAL, 0); /* handy for :@ loops */ - - /* - * If the MAKEOBJDIR (or by default, the _PATH_OBJDIR) directory - * exists, change into it and build there. (If a .${MACHINE} suffix - * exists, use that directory instead). - * Otherwise check MAKEOBJDIRPREFIX`cwd` (or by default, - * _PATH_OBJDIRPREFIX`cwd`) and build there if it exists. - * If all fails, use the current directory to build. - * - * Once things are initted, - * have to add the original directory to the search path, - * and modify the paths for the Makefiles apropriately. The - * current directory is also placed as a variable for make scripts. - */ - if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) { - if (!(path = getenv("MAKEOBJDIR"))) { - path = _PATH_OBJDIR; -#ifdef _PATH_OBJDIRPREFIX - pathp = _PATH_OBJDIRPREFIX; -#endif - (void) snprintf(mdpath, MAXPATHLEN, "%s.%s", - path, machine); - if (!(objdir = chdir_verify_path(mdpath, obpath))) - if (!(objdir=chdir_verify_path(path, obpath))) { -#ifdef _PATH_OBJDIRPREFIX - (void) snprintf(mdpath, MAXPATHLEN, - "%s%s", pathp, curdir); - if (!(objdir=chdir_verify_path(mdpath, - obpath))) -#endif - objdir = curdir; - } - } - else if (!(objdir = chdir_verify_path(path, obpath))) - objdir = curdir; - } - else { - (void) snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir); - if (!(objdir = chdir_verify_path(mdpath, obpath))) - objdir = curdir; - } - - setenv("PWD", objdir, 1); - - create = Lst_Init(FALSE); - makefiles = Lst_Init(FALSE); - printVars = FALSE; - variables = Lst_Init(FALSE); - beSilent = FALSE; /* Print commands as executed */ - ignoreErrors = FALSE; /* Pay attention to non-zero returns */ - noExecute = FALSE; /* Execute all commands */ - noRecursiveExecute = FALSE; /* Execute all .MAKE targets */ - keepgoing = FALSE; /* Stop on error */ - allPrecious = FALSE; /* Remove targets when interrupted */ - queryFlag = FALSE; /* This is not just a check-run */ - noBuiltins = FALSE; /* Read the built-in rules */ - touchFlag = FALSE; /* Actually update targets */ - usePipes = TRUE; /* Catch child output in pipes */ - debug = 0; /* No debug verbosity, please. */ - jobsRunning = FALSE; - - maxLocal = DEFMAXLOCAL; /* Set default local max concurrency */ -#ifdef REMOTE - maxJobs = DEFMAXJOBS; /* Set default max concurrency */ -#else - maxJobs = maxLocal; -#endif - compatMake = FALSE; /* No compat mode */ - - - /* - * Initialize the parsing, directory and variable modules to prepare - * for the reading of inclusion paths and variable settings on the - * command line - */ - - /* - * Initialize directory structures so -I flags can be processed - * correctly, if we have a different objdir, then let the directory - * know our curdir. - */ - Dir_Init(curdir != objdir ? curdir : NULL); - Parse_Init(); /* Need to initialize the paths of #include - * directories */ - Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0); - - /* - * Initialize various variables. - * MAKE also gets this name, for compatibility - * .MAKEFLAGS gets set to the empty string just in case. - * MFLAGS also gets initialized empty, for compatibility. - */ - Var_Set("MAKE", argv[0], VAR_GLOBAL, 0); - Var_Set(".MAKE", argv[0], VAR_GLOBAL, 0); - Var_Set(MAKEFLAGS, "", VAR_GLOBAL, 0); - Var_Set(MAKEOVERRIDES, "", VAR_GLOBAL, 0); - Var_Set("MFLAGS", "", VAR_GLOBAL, 0); - - /* - * First snag any flags out of the MAKE environment variable. - * (Note this is *not* MAKEFLAGS since /bin/make uses that and it's - * in a different format). - */ -#ifdef POSIX - Main_ParseArgLine(getenv("MAKEFLAGS")); -#else - Main_ParseArgLine(getenv("MAKE")); -#endif - - MainParseArgs(argc, argv); - - /* - * Be compatible if user did not specify -j and did not explicitly - * turned compatibility on - */ - if (!compatMake && !forceJobs) { - compatMake = TRUE; - } - - /* - * Initialize archive, target and suffix modules in preparation for - * parsing the makefile(s) - */ - Arch_Init(); - Targ_Init(); - Suff_Init(); - Trace_Init(tracefile); - - DEFAULT = NILGNODE; - (void)time(&now); - - Trace_Log(MAKESTART, NULL); - - /* - * Set up the .TARGETS variable to contain the list of targets to be - * created. If none specified, make the variable empty -- the parser - * will fill the thing in with the default or .MAIN target. - */ - if (!Lst_IsEmpty(create)) { - LstNode ln; - - for (ln = Lst_First(create); ln != NILLNODE; - ln = Lst_Succ(ln)) { - char *name = (char *)Lst_Datum(ln); - - Var_Append(".TARGETS", name, VAR_GLOBAL); - } - } else - Var_Set(".TARGETS", "", VAR_GLOBAL, 0); - - - /* - * If no user-supplied system path was given (through the -m option) - * add the directories from the DEFSYSPATH (more than one may be given - * as dir1:...:dirn) to the system include path. - */ - if (Lst_IsEmpty(sysIncPath)) { - if (syspath == NULL || *syspath == '\0') - syspath = defsyspath; - else - syspath = strdup(syspath); - - for (start = syspath; *start != '\0'; start = cp) { - for (cp = start; *cp != '\0' && *cp != ':'; cp++) - continue; - if (*cp == '\0') { - (void) Dir_AddDir(sysIncPath, start); - } else { - *cp++ = '\0'; - (void) Dir_AddDir(sysIncPath, start); - } - } - if (syspath != defsyspath) - free(syspath); - } - - /* - * Read in the built-in rules first, followed by the specified - * makefile, if it was (makefile != (char *) NULL), or the default - * Makefile and makefile, in that order, if it wasn't. - */ - if (!noBuiltins) { - LstNode ln; - - sysMkPath = Lst_Init (FALSE); - Dir_Expand (_PATH_DEFSYSMK, sysIncPath, sysMkPath); - if (Lst_IsEmpty(sysMkPath)) - Fatal("%s: no system rules (%s).", progname, - _PATH_DEFSYSMK); - ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile); - if (ln != NILLNODE) - Fatal("%s: cannot open %s.", progname, - (char *)Lst_Datum(ln)); - } - - if (!Lst_IsEmpty(makefiles)) { - LstNode ln; - - ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile); - if (ln != NILLNODE) - Fatal("%s: cannot open %s.", progname, - (char *)Lst_Datum(ln)); - } else if (!ReadMakefile("makefile", NULL)) - (void)ReadMakefile("Makefile", NULL); - - (void)ReadMakefile(".depend", NULL); - - Var_Append("MFLAGS", Var_Value(MAKEFLAGS, VAR_GLOBAL, &p1), VAR_GLOBAL); - if (p1) - free(p1); - - if (!jobServer && !compatMake) - Job_ServerStart(maxJobs); - if (DEBUG(JOB)) - printf("job_pipe %d %d, maxjobs %d maxlocal %d compat %d\n", job_pipe[0], job_pipe[1], maxJobs, - maxLocal, compatMake); - - ExportMAKEFLAGS(1); /* initial export */ - -#ifndef NO_CHECK_MAKE_CHDIR - Check_Cwd_av(0, NULL, 0); /* initialize it */ -#endif - - /* - * For compatibility, look at the directories in the VPATH variable - * and add them to the search path, if the variable is defined. The - * variable's value is in the same format as the PATH envariable, i.e. - * ::... - */ - if (Var_Exists("VPATH", VAR_CMD)) { - char *vpath, *path, *cp, savec; - /* - * GCC stores string constants in read-only memory, but - * Var_Subst will want to write this thing, so store it - * in an array - */ - static char VPATH[] = "${VPATH}"; - - vpath = Var_Subst(NULL, VPATH, VAR_CMD, FALSE); - path = vpath; - do { - /* skip to end of directory */ - for (cp = path; *cp != ':' && *cp != '\0'; cp++) - continue; - /* Save terminator character so know when to stop */ - savec = *cp; - *cp = '\0'; - /* Add directory to search path */ - (void) Dir_AddDir(dirSearchPath, path); - *cp = savec; - path = cp + 1; - } while (savec == ':'); - (void)free((Address)vpath); - } - - /* - * Now that all search paths have been read for suffixes et al, it's - * time to add the default search path to their lists... - */ - Suff_DoPaths(); - - /* - * Propagate attributes through :: dependency lists. - */ - Targ_Propagate(); - - /* print the initial graph, if the user requested it */ - if (DEBUG(GRAPH1)) - Targ_PrintGraph(1); - - /* print the values of any variables requested by the user */ - if (printVars) { - LstNode ln; - - for (ln = Lst_First(variables); ln != NILLNODE; - ln = Lst_Succ(ln)) { - char *value = Var_Value((char *)Lst_Datum(ln), - VAR_GLOBAL, &p1); - - printf("%s\n", value ? value : ""); - if (p1) - free(p1); - } - } - - /* - * Have now read the entire graph and need to make a list of targets - * to create. If none was given on the command line, we consult the - * parsing module to find the main target(s) to create. - */ - if (Lst_IsEmpty(create)) - targs = Parse_MainName(); - else - targs = Targ_FindList(create, TARG_CREATE); - - if (!compatMake && !printVars) { - /* - * Initialize job module before traversing the graph, now that - * any .BEGIN and .END targets have been read. This is done - * only if the -q flag wasn't given (to prevent the .BEGIN from - * being executed should it exist). - */ - if (!queryFlag) { - if (maxLocal == -1) - maxLocal = maxJobs; - Job_Init(maxJobs, maxLocal); - jobsRunning = TRUE; - } - - /* Traverse the graph, checking on all the targets */ - outOfDate = Make_Run(targs); - } else if (!printVars) { - /* - * Compat_Init will take care of creating all the targets as - * well as initializing the module. - */ - Compat_Run(targs); - } - -#ifdef CLEANUP - Lst_Destroy(targs, NOFREE); - Lst_Destroy(variables, NOFREE); - Lst_Destroy(makefiles, NOFREE); - Lst_Destroy(create, (void (*) __P((ClientData))) free); -#endif - - /* print the graph now it's been processed if the user requested it */ - if (DEBUG(GRAPH2)) - Targ_PrintGraph(2); - - Trace_Log(MAKEEND, 0); - - Suff_End(); - Targ_End(); - Arch_End(); - Var_End(); - Parse_End(); - Dir_End(); - Job_End(); - Trace_End(); - - if (queryFlag && outOfDate) - return(1); - else - return(0); -} - -/*- - * ReadMakefile -- - * Open and parse the given makefile. - * - * Results: - * TRUE if ok. FALSE if couldn't open file. - * - * Side Effects: - * lots - */ -static Boolean -ReadMakefile(p, q) - ClientData p, q; -{ - char *fname = p; /* makefile to read */ - FILE *stream; - size_t len = MAXPATHLEN; - char *name, *path = emalloc(len); - int setMAKEFILE; - - if (!strcmp(fname, "-")) { - Parse_File("(stdin)", stdin); - Var_Set("MAKEFILE", "", VAR_GLOBAL, 0); - } else { -#ifdef __INTERIX - /* XXX tv: Hack pending a fix to bsd.pkg.mk to use some other - variable name than this. When using a NFS pkgsrc repository, - bmake thinks "makefile" exists when running under "su" even - though the filesystem is mounted case-sensitive on the - non-su side. This hoses all sorts of fun things. */ - setMAKEFILE = FALSE; -#else - setMAKEFILE = strcmp(fname, ".depend"); -#endif - - /* if we've chdir'd, rebuild the path name */ - if (curdir != objdir && *fname != '/') { - size_t plen = strlen(curdir) + strlen(fname) + 2; - if (len < plen) - path = erealloc(path, len = 2 * plen); - - (void)snprintf(path, len, "%s/%s", curdir, fname); - if ((stream = fopen(path, "r")) != NULL) { - fname = path; - goto found; - } - } else if ((stream = fopen(fname, "r")) != NULL) - goto found; - /* look in -I and system include directories. */ - name = Dir_FindFile(fname, parseIncPath); - if (!name) - name = Dir_FindFile(fname, sysIncPath); - if (!name || !(stream = fopen(name, "r"))) { - free(path); - return(FALSE); - } - fname = name; - /* - * set the MAKEFILE variable desired by System V fans -- the - * placement of the setting here means it gets set to the last - * makefile specified, as it is set by SysV make. - */ -found: - if (setMAKEFILE) - Var_Set("MAKEFILE", fname, VAR_GLOBAL, 0); - Parse_File(fname, stream); - (void)fclose(stream); - } - free(path); - return(TRUE); -} - - -/* - * If MAKEOBJDIRPREFIX is in use, make ends up not in .CURDIR - * in situations that would not arrise with ./obj (links or not). - * This tends to break things like: - * - * build: - * ${MAKE} includes - * - * This function spots when ${.MAKE:T} or ${.MAKE} is a command (as - * opposed to an argument) in a command line and if so returns - * ${.CURDIR} so caller can chdir() so that the assumptions made by - * the Makefile hold true. - * - * If ${.MAKE} does not contain any '/', then ${.MAKE:T} is skipped. - * - * The chdir() only happens in the child process, and does nothing if - * MAKEOBJDIRPREFIX and MAKEOBJDIR are not in the environment so it - * should not break anything. Also if NOCHECKMAKECHDIR is set we - * do nothing - to ensure historic semantics can be retained. - */ -#ifdef NO_CHECK_MAKE_CHDIR -char * -Check_Cwd_Cmd(cmd) - char *cmd; -{ - return 0; -} - -void -Check_Cwd(argv) - char **argv; -{ - return; -} - -#else - -static int Check_Cwd_Off = 0; - -static char * -Check_Cwd_av(ac, av, copy) - int ac; - char **av; - int copy; -{ - static char *make[4]; - static char *curdir = NULL; - char *cp, **mp; - int is_cmd, next_cmd; - int i; - int n; - - if (Check_Cwd_Off) - return NULL; - - if (make[0] == NULL) { - if (Var_Exists("NOCHECKMAKECHDIR", VAR_GLOBAL)) { - Check_Cwd_Off = 1; - return NULL; - } - - make[1] = Var_Value(".MAKE", VAR_GLOBAL, &cp); - if ((make[0] = strrchr(make[1], '/')) == NULL) { - make[0] = make[1]; - make[1] = NULL; - } else - ++make[0]; - make[2] = NULL; - curdir = Var_Value(".CURDIR", VAR_GLOBAL, &cp); - } - if (ac == 0 || av == NULL) - return NULL; /* initialization only */ - - if (getenv("MAKEOBJDIR") == NULL && - getenv("MAKEOBJDIRPREFIX") == NULL) - return NULL; - - - next_cmd = 1; - for (i = 0; i < ac; ++i) { - is_cmd = next_cmd; - - n = strlen(av[i]); - cp = &(av[i])[n - 1]; - if (strspn(av[i], "|&;") == n) { - next_cmd = 1; - continue; - } else if (*cp == ';' || *cp == '&' || *cp == '|' || *cp == ')') { - next_cmd = 1; - if (copy) { - do { - *cp-- = '\0'; - } while (*cp == ';' || *cp == '&' || *cp == '|' || - *cp == ')' || *cp == '}') ; - } else { - /* - * XXX this should not happen. - */ - fprintf(stderr, "WARNING: raw arg ends in shell meta '%s'\n", - av[i]); - } - } else - next_cmd = 0; - - cp = av[i]; - if (*cp == ';' || *cp == '&' || *cp == '|') - is_cmd = 1; - -#ifdef check_cwd_debug - fprintf(stderr, "av[%d] == %s '%s'", - i, (is_cmd) ? "cmd" : "arg", av[i]); -#endif - if (is_cmd != 0) { - if (*cp == '(' || *cp == '{' || - *cp == ';' || *cp == '&' || *cp == '|') { - do { - ++cp; - } while (*cp == '(' || *cp == '{' || - *cp == ';' || *cp == '&' || *cp == '|'); - if (*cp == '\0') { - next_cmd = 1; - continue; - } - } - if (strcmp(cp, "cd") == 0 || strcmp(cp, "chdir") == 0) { -#ifdef check_cwd_debug - fprintf(stderr, " == cd, done.\n"); -#endif - return NULL; - } - for (mp = make; *mp != NULL; ++mp) { - n = strlen(*mp); - if (strcmp(cp, *mp) == 0) { -#ifdef check_cwd_debug - fprintf(stderr, " %s == '%s', chdir(%s)\n", - cp, *mp, curdir); -#endif - return curdir; - } - } - } -#ifdef check_cwd_debug - fprintf(stderr, "\n"); -#endif - } - return NULL; -} - -char * -Check_Cwd_Cmd(cmd) - char *cmd; -{ - char *cp, *bp, **av; - int ac; - - if (Check_Cwd_Off) - return NULL; - - if (cmd) { - av = brk_string(cmd, &ac, TRUE, &bp); -#ifdef check_cwd_debug - fprintf(stderr, "splitting: '%s' -> %d words\n", - cmd, ac); -#endif - } else { - ac = 0; - av = NULL; - bp = NULL; - } - cp = Check_Cwd_av(ac, av, 1); - if (bp) { - free(av); - free(bp); - } - return cp; -} - -void -Check_Cwd(argv) - char **argv; -{ - char *cp; - int ac; - - if (Check_Cwd_Off) - return; - - for (ac = 0; argv[ac] != NULL; ++ac) - /* NOTHING */; - if (ac == 3 && *argv[1] == '-') { - cp = Check_Cwd_Cmd(argv[2]); - } else { - cp = Check_Cwd_av(ac, argv, 0); - } - if (cp) { - chdir(cp); - } -} -#endif /* NO_CHECK_MAKE_CHDIR */ - -/*- - * Cmd_Exec -- - * Execute the command in cmd, and return the output of that command - * in a string. - * - * Results: - * A string containing the output of the command, or the empty string - * If err is not NULL, it contains the reason for the command failure - * - * Side Effects: - * The string must be freed by the caller. - */ -char * -Cmd_Exec(cmd, err) - char *cmd; - char **err; -{ - char *args[4]; /* Args for invoking the shell */ - int fds[2]; /* Pipe streams */ - int cpid; /* Child PID */ - int pid; /* PID from wait() */ - char *res; /* result */ - int status; /* command exit status */ - Buffer buf; /* buffer to store the result */ - char *cp; - int cc; - - - *err = NULL; - - /* - * Set up arguments for shell - */ - args[0] = "sh"; - args[1] = "-c"; - args[2] = cmd; - args[3] = NULL; - - /* - * Open a pipe for fetching its output - */ - if (pipe(fds) == -1) { - *err = "Couldn't create pipe for \"%s\""; - goto bad; - } - - /* - * Fork - */ - switch (cpid = vfork()) { - case 0: - /* - * Close input side of pipe - */ - (void) close(fds[0]); - - /* - * Duplicate the output stream to the shell's output, then - * shut the extra thing down. Note we don't fetch the error - * stream...why not? Why? - */ - (void) dup2(fds[1], 1); - (void) close(fds[1]); - - (void) execv("/bin/sh", args); - _exit(1); - /*NOTREACHED*/ - - case -1: - *err = "Couldn't exec \"%s\""; - goto bad; - - default: - /* - * No need for the writing half - */ - (void) close(fds[1]); - - buf = Buf_Init (MAKE_BSIZE); - - do { - char result[BUFSIZ]; - cc = read(fds[0], result, sizeof(result)); - if (cc > 0) - Buf_AddBytes(buf, cc, (Byte *) result); - } - while (cc > 0 || (cc == -1 && errno == EINTR)); - - /* - * Close the input side of the pipe. - */ - (void) close(fds[0]); - - /* - * Wait for the process to exit. - */ - while(((pid = wait(&status)) != cpid) && (pid >= 0)) - continue; - - res = (char *)Buf_GetAll (buf, &cc); - Buf_Destroy (buf, FALSE); - - if (cc == 0) - *err = "Couldn't read shell's output for \"%s\""; - - if (status) - *err = "\"%s\" returned non-zero status"; - - /* - * Null-terminate the result, convert newlines to spaces and - * install it in the variable. - */ - res[cc] = '\0'; - cp = &res[cc]; - - if (cc > 0 && *--cp == '\n') { - /* - * A final newline is just stripped - */ - *cp-- = '\0'; - } - while (cp >= res) { - if (*cp == '\n') { - *cp = ' '; - } - cp--; - } - break; - } - return res; -bad: - res = emalloc(1); - *res = '\0'; - return res; -} - -/*- - * Error -- - * Print an error message given its format. - * - * Results: - * None. - * - * Side Effects: - * The message is printed. - */ -/* VARARGS */ -void -#ifdef __STDC__ -Error(char *fmt, ...) -#else -Error(va_alist) - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - char *fmt; - - va_start(ap); - fmt = va_arg(ap, char *); -#endif - fprintf(stderr, "%s: ", progname); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - (void)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 -#ifdef __STDC__ -Fatal(char *fmt, ...) -#else -Fatal(va_alist) - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - char *fmt; - - va_start(ap); - fmt = va_arg(ap, char *); -#endif - if (jobsRunning) - Job_Wait(); - Job_TokenFlush(); - - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); - - PrintOnError(NULL); - - if (DEBUG(GRAPH2)) - Targ_PrintGraph(2); - Trace_Log(MAKEERROR, 0); - 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 -#ifdef __STDC__ -Punt(char *fmt, ...) -#else -Punt(va_alist) - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - char *fmt; - - va_start(ap); - fmt = va_arg(ap, char *); -#endif - - (void)fprintf(stderr, "%s: ", progname); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); - - PrintOnError(NULL); - - DieHorribly(); -} - -/*- - * DieHorribly -- - * Exit without giving a message. - * - * Results: - * None - * - * Side Effects: - * A big one... - */ -void -DieHorribly() -{ - if (jobsRunning) - Job_AbortAll(); - if (DEBUG(GRAPH2)) - Targ_PrintGraph(2); - Trace_Log(MAKEERROR, 0); - exit(2); /* Not 1, so -q can distinguish error */ -} - -/* - * Finish -- - * Called when aborting due to errors in child shell to signal - * abnormal exit. - * - * Results: - * None - * - * Side Effects: - * The program exits - */ -void -Finish(errors) - int errors; /* number of errors encountered in Make_Make */ -{ - Fatal("%d error%s", errors, errors == 1 ? "" : "s"); -} - -/* - * emalloc -- - * malloc, but die on error. - */ -void * -emalloc(len) - size_t len; -{ - void *p; - - if ((p = malloc(len)) == NULL) - enomem(); - return(p); -} - -/* - * estrdup -- - * strdup, but die on error. - */ -char * -estrdup(str) - const char *str; -{ - char *p; - - if ((p = strdup(str)) == NULL) - enomem(); - return(p); -} - -/* - * erealloc -- - * realloc, but die on error. - */ -void * -erealloc(ptr, size) - void *ptr; - size_t size; -{ - if ((ptr = realloc(ptr, size)) == NULL) - enomem(); - return(ptr); -} - -/* - * enomem -- - * die when out of memory. - */ -void -enomem() -{ - (void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno)); - exit(2); -} - -/* - * enunlink -- - * Remove a file carefully, avoiding directories. - */ -int -eunlink(file) - const char *file; -{ - struct stat st; - - if (lstat(file, &st) == -1) - return -1; - - if (S_ISDIR(st.st_mode)) { - errno = EISDIR; - return -1; - } - return unlink(file); -} - -/* - * execError -- - * Print why exec failed, avoiding stdio. - */ -void -execError(av) - const char *av; -{ -#ifdef USE_IOVEC - int i = 0; - struct iovec iov[6]; -#define IOADD(s) \ - (void)(iov[i].iov_base = (s), \ - iov[i].iov_len = strlen(iov[i].iov_base), \ - i++) -#else -#define IOADD (void)write(2, s, strlen(s)) -#endif - - IOADD(progname); - IOADD(": Exec of `"); - IOADD((char *)av); - IOADD("' failed ("); - IOADD(strerror(errno)); - IOADD(")\n"); - -#ifdef USE_IOVEC - (void)writev(2, iov, 6); -#endif -} - -/* - * usage -- - * exit with usage message - */ -static void -usage() -{ - (void)fprintf(stderr, -"Usage: %s [-Beiknqrst] [-D variable] [-d flags] [-f makefile ]\n\ - [-I directory] [-j max_jobs] [-m directory] [-V variable]\n\ - [variable=value] [target ...]\n", progname); - exit(2); -} - - -int -PrintAddr(a, b) - ClientData a; - ClientData b; -{ - printf("%lx ", (unsigned long) a); - return b ? 0 : 0; -} - - - -void -PrintOnError(s) - char *s; -{ - char tmp[64]; - - if (s) - printf("%s", s); - - printf("\n%s: stopped in %s\n", progname, curdir); - strncpy(tmp, "${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'\n@}", - sizeof(tmp) - 1); - s = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); - if (s && *s) - printf("%s", s); -} - -void -ExportMAKEFLAGS(first) - int first; -{ - static int once = 1; - char tmp[64]; - char *s; - - if (once != first) - return; - once = 0; - - strncpy(tmp, "${.MAKEFLAGS} ${.MAKEOVERRIDES:O:u:@v@$v=${$v:Q}@}", - sizeof(tmp)); - s = Var_Subst(NULL, tmp, VAR_CMD, 0); - if (s && *s) { -#ifdef POSIX - setenv("MAKEFLAGS", s, 1); -#else - setenv("MAKE", s, 1); -#endif - } -} diff --git a/bootstrap/bmake/make-conf.h b/bootstrap/bmake/make-conf.h deleted file mode 100644 index dcc702788c6..00000000000 --- a/bootstrap/bmake/make-conf.h +++ /dev/null @@ -1,133 +0,0 @@ -/* $NetBSD: make-conf.h,v 1.1.1.1 2004/03/11 13:04:10 grant Exp $ */ - -/* - * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. - * Copyright (c) 1988, 1989 by Adam de Boor - * Copyright (c) 1989 by Berkeley Softworks - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Adam de Boor. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)config.h 8.1 (Berkeley) 6/6/93 - */ - -#define DEFSHELL 1 /* Bourne shell */ - -/* - * DEFMAXJOBS - * DEFMAXLOCAL - * These control the default concurrency. On no occasion will more - * than DEFMAXJOBS targets be created at once (locally or remotely) - * DEFMAXLOCAL is the highest number of targets which will be - * created on the local machine at once. Note that if you set this - * to 0, nothing will ever happen... - */ -#define DEFMAXJOBS 4 -#define DEFMAXLOCAL 1 - -/* - * INCLUDES - * LIBRARIES - * These control the handling of the .INCLUDES and .LIBS variables. - * If INCLUDES is defined, the .INCLUDES variable will be filled - * from the search paths of those suffixes which are marked by - * .INCLUDES dependency lines. Similarly for LIBRARIES and .LIBS - * See suff.c for more details. - */ -#define INCLUDES -#define LIBRARIES - -/* - * LIBSUFF - * Is the suffix used to denote libraries and is used by the Suff module - * to find the search path on which to seek any -l targets. - * - * RECHECK - * If defined, Make_Update will check a target for its current - * modification time after it has been re-made, setting it to the - * starting time of the make only if the target still doesn't exist. - * Unfortunately, under NFS the modification time often doesn't - * get updated in time, so a target will appear to not have been - * re-made, causing later targets to appear up-to-date. On systems - * that don't have this problem, you should defined this. Under - * NFS you probably should not, unless you aren't exporting jobs. - */ -#define LIBSUFF ".a" -#define RECHECK - -/* - * POSIX - * Adhere to the POSIX 1003.2 draft for the make(1) program. - * - Use MAKEFLAGS instead of MAKE to pick arguments from the - * environment. - * - Allow empty command lines if starting with tab. - */ -#define POSIX - -/* - * SYSVINCLUDE - * Recognize system V like include directives [include "filename"] - * SYSVVARSUB - * Recognize system V like ${VAR:x=y} variable substitutions - */ -#define SYSVINCLUDE -#define SYSVVARSUB - -/* - * SUNSHCMD - * Recognize SunOS and Solaris: - * VAR :sh= CMD # Assign VAR to the command substitution of CMD - * ${VAR:sh} # Return the command substitution of the value - * # of ${VAR} - */ -#define SUNSHCMD - -/* - * USE_PGRP - * Kill the process group of the job so that all the progeny of the - * current job dies, instead of just the one forked. - */ -#define USE_PGRP - -/* - * USE_IOVEC - * We have writev(2) - */ -#ifdef HAVE_SYS_UIO_H -# define USE_IOVEC -#endif - -#if !defined(__svr4__) && !defined(__SVR4) && !defined(__ELF__) -# ifndef RANLIBMAG -# define RANLIBMAG "__.SYMDEF" -# endif -#endif diff --git a/bootstrap/bmake/make.1 b/bootstrap/bmake/make.1 deleted file mode 100644 index bfd8caf9e65..00000000000 --- a/bootstrap/bmake/make.1 +++ /dev/null @@ -1,1265 +0,0 @@ -.\" $NetBSD: make.1,v 1.4 2005/05/16 09:18:27 rillig Exp $ -.\" -.\" Copyright (c) 1990, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 -.\" -.Dd March 19, 1994 -.Dt MAKE 1 -.Os -.Sh NAME -.Nm make -.Nd maintain program dependencies -.Sh SYNOPSIS -.Nm "" -.Op Fl BeikNnqrstW -.Bk -words -.Op Fl D Ar variable -.Ek -.Bk -words -.Op Fl d Ar flags -.Ek -.Bk -words -.Op Fl f Ar makefile -.Ek -.Bk -words -.Op Fl I Ar directory -.Ek -.Bk -words -.Op Fl j Ar max_jobs -.Ek -.Bk -words -.Op Fl J Ar private -.Ek -.Bk -words -.Op Fl m Ar directory -.Ek -.Bk -words -.Op Fl T Ar file -.Ek -.Bk -words -.Op Fl V Ar variable -.Ek -.Op Ar variable=value -.Bk -words -.Op Ar target ... -.Ek -.Sh DESCRIPTION -.Nm -is a program designed to simplify the maintenance of other programs. -Its input is a list of specifications as to the files upon which programs -and other files depend. -If the file -.Ql Pa makefile -exists, it is read for this list of specifications. -If it does not exist, the file -.Ql Pa Makefile -is read. -If the file -.Ql Pa .depend -exists, it is read (see -.Xr mkdep 1 ) . -.Pp -This manual page is intended as a reference document only. -For a more thorough description of -.Nm -and makefiles, please refer to -.%T "Make \- A Tutorial" . -.Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl B -Try to be backwards compatible by executing a single shell per command and -by executing the commands to make the sources of a dependency line in sequence. -.It Fl D Ar variable -Define -.Ar variable -to be 1, in the global context. -.It Fl d Ar flags -Turn on debugging, and specify which portions of -.Nm -are to print debugging information. -.Ar Flags -is one or more of the following: -.Bl -tag -width Ds -.It Ar A -Print all possible debugging information; -equivalent to specifying all of the debugging flags. -.It Ar a -Print debugging information about archive searching and caching. -.It Ar c -Print debugging information about conditional evaluation. -.It Ar d -Print debugging information about directory searching and caching. -.It Ar "g1" -Print the input graph before making anything. -.It Ar "g2" -Print the input graph after making everything, or before exiting -on error. -.It Ar j -Print debugging information about running multiple shells. -.It Ar m -Print debugging information about making targets, including modification -dates. -.It Ar s -Print debugging information about suffix-transformation rules. -.It Ar t -Print debugging information about target list maintenance. -.It Ar v -Print debugging information about variable assignment. -.It Ar x -Run shell commands with -.Fl x -so the actual commands are printed as they are executed. -.El -.It Fl e -Specify that environmental variables override macro assignments within -makefiles. -.It Fl f Ar makefile -Specify a makefile to read instead of the default -.Ql Pa makefile -and -If -.Ar makefile -is -.Ql Fl , -standard input is read. -Multiple makefile's may be specified, and are read in the order specified. -.It Fl I Ar directory -Specify a directory in which to search for makefiles and included makefiles. -The system makefile directory (or directories, see the -.Fl m -option) is automatically included as part of this list. -.It Fl i -Ignore non-zero exit of shell commands in the makefile. -Equivalent to specifying -.Ql Fl -before each command line in the makefile. -.It Fl J Ar private -This option should -.Em not -be specified by the user. -.Pp -When the -.Ar j -option is in use in a recursive build, this option is passed by a make -to child makes to allow all the make processes in the build to -cooperate to avoid overloading the system. -.It Fl j Ar max_jobs -Specify the maximum number of jobs that -.Nm -may have running at any one time. Turns compatibility mode off, unless the -.Ar B -flag is also specified. -.It Fl k -Continue processing after errors are encountered, but only on those targets -that do not depend on the target whose creation caused the error. -.It Fl m Ar directory -Specify a directory in which to search for sys.mk and makefiles included -via the <...> style. Multiple directories can be added to form a search path. -This path will override the default system include path: /usr/share/mk. -Furthermore the system include path will be appended to the search path used -for "..."-style inclusions (see the -.Fl I -option). -.It Fl n -Display the commands that would have been executed, but do not -actually execute them unless the target depends on the .MAKE special -source (see below) -.It Fl N -Display the commands which would have been executed, but do not -actually execute any of them; useful for debugging top-level makefiles -without descending into subdirectories. -.It Fl q -Do not execute any commands, but exit 0 if the specified targets are -up-to-date and 1, otherwise. -.It Fl r -Do not use the built-in rules specified in the system makefile. -.It Fl s -Do not echo any commands as they are executed. -Equivalent to specifying -.Ql Ic @ -before each command line in the makefile. -.It Fl T Ar tracefile -When used with the -.Fl j -flag, -append a trace record to -.Ar tracefile -for each job started and completed. -.It Fl t -Rather than re-building a target as specified in the makefile, create it -or update its modification time to make it appear up-to-date. -.It Fl V Ar variable -Print -.Nm "" Ns 's -idea of the value of -.Ar variable , -in the global context. -Do not build any targets. -Multiple instances of this option may be specified; -the variables will be printed one per line, -with a blank line for each null or undefined variable. -.It Fl W -Treat any warnings during makefile parsing as errors. -.It Ar variable=value -Set the value of the variable -.Ar variable -to -.Ar value . -.El -.Pp -There are seven different types of lines in a makefile: file dependency -specifications, shell commands, variable assignments, include statements, -conditional directives, for loops, and comments. -.Pp -In general, lines may be continued from one line to the next by ending -them with a backslash -.Pq Ql \e . -The trailing newline character and initial whitespace on the following -line are compressed into a single space. -.Sh FILE DEPENDENCY SPECIFICATIONS -Dependency lines consist of one or more targets, an operator, and zero -or more sources. -This creates a relationship where the targets ``depend'' on the sources -and are usually created from them. -The exact relationship between the target and the source is determined -by the operator that separates them. -The three operators are as follows: -.Bl -tag -width flag -.It Ic \&: -A target is considered out-of-date if its modification time is less than -those of any of its sources. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&! -Targets are always re-created, but not until all sources have been -examined and re-created as necessary. -Sources for a target accumulate over dependency lines when this operator -is used. -The target is removed if -.Nm -is interrupted. -.It Ic \&:: -If no sources are specified, the target is always re-created. -Otherwise, a target is considered out-of-date if any of its sources has -been modified more recently than the target. -Sources for a target do not accumulate over dependency lines when this -operator is used. -The target will not be removed if -.Nm -is interrupted. -.El -.Pp -Targets and sources may contain the shell wildcard values -.Ql ? , -.Ql * , -.Ql [] -and -.Ql {} . -The values -.Ql ? , -.Ql * -and -.Ql [] -may only be used as part of the final -component of the target or source, and must be used to describe existing -files. -The value -.Ql {} -need not necessarily be used to describe existing files. -Expansion is in directory order, not alphabetically as done in the shell. -.Sh SHELL COMMANDS -Each target may have associated with it a series of shell commands, normally -used to create the target. -Each of the commands in this script -.Em must -be preceded by a tab. -While any target may appear on a dependency line, only one of these -dependencies may be followed by a creation script, unless the -.Ql Ic :: -operator is used. -.Pp -If the first or first two characters of the command line are -.Ql Ic @ -and/or -.Ql Ic \- , -the command is treated specially. -A -.Ql Ic @ -causes the command not to be echoed before it is executed. -A -.Ql Ic \- -causes any non-zero exit status of the command line to be ignored. -.Sh VARIABLE ASSIGNMENTS -Variables in make are much like variables in the shell, and, by tradition, -consist of all upper-case letters. -The five operators that can be used to assign values to variables are as -follows: -.Bl -tag -width Ds -.It Ic \&= -Assign the value to the variable. -Any previous value is overridden. -.It Ic \&+= -Append the value to the current value of the variable. -.It Ic \&?= -Assign the value to the variable if it is not already defined. -.It Ic \&:= -Assign with expansion, i.e. expand the value before assigning it -to the variable. -Normally, expansion is not done until the variable is referenced. -.It Ic \&!= -Expand the value and pass it to the shell for execution and assign -the result to the variable. -Any newlines in the result are replaced with spaces. -.El -.Pp -Any white-space before the assigned -.Ar value -is removed; if the value is being appended, a single space is inserted -between the previous contents of the variable and the appended value. -.Pp -Variables are expanded by surrounding the variable name with either -curly braces -.Pq Ql {} -or parentheses -.Pq Ql () -and preceding it with -a dollar sign -.Pq Ql \&$ . -If the variable name contains only a single letter, the surrounding -braces or parentheses are not required. -This shorter form is not recommended. -.Pp -Variable substitution occurs at two distinct times, depending on where -the variable is being used. -Variables in dependency lines are expanded as the line is read. -Variables in shell commands are expanded when the shell command is -executed. -.Pp -The four different classes of variables (in order of increasing precedence) -are: -.Bl -tag -width Ds -.It Environment variables -Variables defined as part of -.Nm "" Ns 's -environment. -.It Global variables -Variables defined in the makefile or in included makefiles. -.It Command line variables -Variables defined as part of the command line. -.It Local variables -Variables that are defined specific to a certain target. -The seven local variables are as follows: -.Bl -tag -width ".ARCHIVE" -.It Va .ALLSRC -The list of all sources for this target; also known as -.Ql Va \&> . -.It Va .ARCHIVE -The name of the archive file. -.It Va .IMPSRC -The name/path of the source from which the target is to be transformed -(the ``implied'' source); also known as -.Ql Va \&< . -.It Va .MEMBER -The name of the archive member. -.It Va .OODATE -The list of sources for this target that were deemed out-of-date; also -known as -.Ql Va \&? . -.It Va .PREFIX -The file prefix of the file, containing only the file portion, no suffix -or preceding directory components; also known as -.Ql Va * . -.It Va .TARGET -The name of the target; also known as -.Ql Va @ . -.El -.Pp -The shorter forms -.Ql Va @ , -.Ql Va ? , -.Ql Va \&> -and -.Ql Va * -are permitted for backward -compatibility with historical makefiles and are not recommended. -The six variables -.Ql Va "@F" , -.Ql Va "@D" , -.Ql Va " -#ifndef lint -#if 0 -static char sccsid[] = "@(#)make.c 8.1 (Berkeley) 6/6/93"; -#else -__RCSID("$NetBSD: make.c,v 1.1.1.1 2004/03/11 13:04:10 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: make.c,v 1.1.1.1 2004/03/11 13:04:10 grant Exp $"); -#endif - -/*- - * 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. - * - * Make_ExpandUse Expand .USE nodes and return the new list of - * targets. - */ - -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" - -static Lst toBeMade; /* 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 int numNodes; /* 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 MakeAddChild __P((ClientData, ClientData)); -static int MakeFindChild __P((ClientData, ClientData)); -static int MakeUnmark __P((ClientData, ClientData)); -static int MakeAddAllSrc __P((ClientData, ClientData)); -static int MakeTimeStamp __P((ClientData, ClientData)); -static int MakeHandleUse __P((ClientData, ClientData)); -static Boolean MakeStartJobs __P((void)); -static int MakePrintStatus __P((ClientData, ClientData)); -/*- - *----------------------------------------------------------------------- - * Make_TimeStamp -- - * Set the cmtime field of a parent node based on the mtime stamp in its - * child. Called from MakeOODate via Lst_ForEach. - * - * 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 (pgn, cgn) - GNode *pgn; /* the current parent */ - GNode *cgn; /* the child we've just examined */ -{ - if (cgn->mtime > pgn->cmtime) { - pgn->cmtime = cgn->mtime; - } - return (0); -} - -static int -MakeTimeStamp (pgn, cgn) - ClientData pgn; /* the current parent */ - ClientData cgn; /* the child we've just examined */ -{ - return Make_TimeStamp((GNode *) pgn, (GNode *) cgn); -} - -/*- - *----------------------------------------------------------------------- - * 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 (gn) - register GNode *gn; /* the node to check */ -{ - Boolean oodate; - - /* - * 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_USEBEFORE|OP_EXEC)) == 0) { - (void) Dir_MTime (gn); - if (DEBUG(MAKE)) { - if (gn->mtime != 0) { - printf ("modified %s...", Targ_FmtTime(gn->mtime)); - } else { - printf ("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|OP_USEBEFORE)) { - /* - * If the node is a USE node it is *never* out of date - * no matter *what*. - */ - if (DEBUG(MAKE)) { - printf(".USE node..."); - } - oodate = FALSE; - } else if ((gn->type & OP_LIB) && - ((gn->mtime==0) || Arch_IsLib(gn))) { - if (DEBUG(MAKE)) { - printf("library..."); - } - - /* - * always out of date if no children and :: target - * or non-existent. - */ - oodate = (gn->mtime == 0 || 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. - */ - if (DEBUG(MAKE)) { - printf(".JOIN node..."); - } - if (DEBUG(MAKE)) { - printf("source %smade...", gn->flags & CHILDMADE ? "" : "not "); - } - oodate = (gn->flags & CHILDMADE) ? 1 : 0; - } 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 (DEBUG(MAKE)) { - if (gn->type & OP_FORCE) { - printf("! operator..."); - } else if (gn->type & OP_PHONY) { - printf(".PHONY node..."); - } else { - printf(".EXEC node..."); - } - } - 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 (DEBUG(MAKE)) { - if (gn->mtime < gn->cmtime) { - printf("modified before source..."); - } else if (gn->mtime == 0) { - printf("non-existent and no sources..."); - } else { - printf(":: operator and no sources..."); - } - } - oodate = TRUE; - } else { - /* - * When a non-existing child with no sources - * (such as a typically used FORCE source) has been made and - * the target of the child (usually a directory) has the same - * timestamp as the timestamp just given to the non-existing child - * after it was considered made. - */ - if (DEBUG(MAKE)) { - if (gn->flags & FORCE) - printf("non existing child..."); - } - oodate = (gn->flags & FORCE) ? 1 : 0; - } - - /* - * 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 (gn->parents, MakeTimeStamp, (ClientData)gn); - } - - return (oodate); -} - -/*- - *----------------------------------------------------------------------- - * MakeAddChild -- - * Function used by Make_Run to add a child to the list l. - * It will only add the child if its make field is FALSE. - * - * Results: - * Always returns 0 - * - * Side Effects: - * The given list is extended - *----------------------------------------------------------------------- - */ -static int -MakeAddChild (gnp, lp) - ClientData gnp; /* the node to add */ - ClientData lp; /* the list to which to add it */ -{ - GNode *gn = (GNode *) gnp; - Lst l = (Lst) lp; - - if ((gn->flags & REMAKE) == 0 && !(gn->type & (OP_USE|OP_USEBEFORE))) { - (void)Lst_EnQueue (l, (ClientData)gn); - } - return (0); -} - -/*- - *----------------------------------------------------------------------- - * MakeFindChild -- - * Function used by Make_Run to find the pathname of a child - * that was already made. - * - * Results: - * Always returns 0 - * - * Side Effects: - * The path and mtime of the node and the cmtime of the parent are - * updated - *----------------------------------------------------------------------- - */ -static int -MakeFindChild (gnp, pgnp) - ClientData gnp; /* the node to find */ - ClientData pgnp; -{ - GNode *gn = (GNode *) gnp; - GNode *pgn = (GNode *) pgnp; - - (void) Dir_MTime(gn); - Make_TimeStamp(pgn, gn); - gn->made = UPTODATE; - - return (0); -} - -/*- - *----------------------------------------------------------------------- - * 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 by MakeAddChild. - * - * 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 (cgn, pgn) - register GNode *cgn; /* The .USE node */ - register GNode *pgn; /* The target of the .USE node */ -{ - register LstNode ln; /* An element in the children list */ - - if (cgn->type & (OP_USE|OP_USEBEFORE|OP_TRANSFORM)) { - if ((cgn->type & (OP_USE|OP_USEBEFORE)) || Lst_IsEmpty(pgn->commands)) { - if (cgn->type & OP_USEBEFORE) { - /* - * .USEBEFORE -- - * prepend the child's commands to the parent. - */ - Lst cmds = pgn->commands; - pgn->commands = Lst_Duplicate (cgn->commands, NOCOPY); - (void) Lst_Concat (pgn->commands, cmds, LST_CONCNEW); - Lst_Destroy (cmds, NOFREE); - } else { - /* - * .USE or target has no commands -- - * append the child's commands to the parent. - */ - (void) Lst_Concat (pgn->commands, cgn->commands, LST_CONCNEW); - } - } - - if (Lst_Open (cgn->children) == SUCCESS) { - while ((ln = Lst_Next (cgn->children)) != NILLNODE) { - register GNode *tgn, *gn = (GNode *)Lst_Datum (ln); - - /* - * Expand variables in the .USE node's name - * and save the unexpanded form. - * We don't need to do this for commands. - * They get expanded properly when we execute. - */ - if (gn->uname == NULL) { - gn->uname = gn->name; - } else { - if (gn->name) - free(gn->name); - } - gn->name = Var_Subst(NULL, gn->uname, pgn, FALSE); - if (gn->name && gn->uname && strcmp(gn->name, gn->uname) != 0) { - /* See if we have a target for this node. */ - tgn = Targ_FindNode(gn->name, TARG_NOCREATE); - if (tgn != NILGNODE) - gn = tgn; - } - - (void) Lst_AtEnd (pgn->children, gn); - (void) Lst_AtEnd (gn->parents, pgn); - pgn->unmade += 1; - } - Lst_Close (cgn->children); - } - - pgn->type |= cgn->type & ~(OP_OPMASK|OP_USE|OP_USEBEFORE|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|OP_USEBEFORE)) && - (ln = Lst_Member (pgn->children, (ClientData) cgn)) != NILLNODE) { - Lst_Remove(pgn->children, ln); - pgn->unmade--; - } - } - return (0); -} - -static int -MakeHandleUse (cgnp, pgnp) - ClientData cgnp; /* the child we've just examined */ - ClientData pgnp; /* the current parent */ -{ - GNode *cgn = (GNode *) cgnp; - GNode *pgn = (GNode *) pgnp; - - if (cgn->type & OP_MARK) - return (0); - cgn->type |= OP_MARK; - - return Make_HandleUse(cgn, pgn); -} - - -/*- - *----------------------------------------------------------------------- - * Make_Recheck -- - * Check the modification time of a gnode, and update it as described - * in the comments below. - * - * Results: - * returns 0 if the gnode does not exist, or it's filesystem - * time if it does. - * - * Side Effects: - * the gnode's modification time and path name are affected. - * - *----------------------------------------------------------------------- - */ -time_t -Make_Recheck (gn) - GNode *gn; -{ - time_t mtime = Dir_MTime(gn); - -#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 gn->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(gn->commands) || Lst_IsEmpty(gn->children)) { - gn->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(gn) || - (gn->type & OP_SAVE_CMDS) || mtime == 0) { - if (DEBUG(MAKE)) { - printf("update time to now: %s\n", Targ_FmtTime(gn->mtime)); - } - gn->mtime = now; - } - else { - if (DEBUG(MAKE)) { - printf("current update time: %s\n", Targ_FmtTime(gn->mtime)); - } - } -#endif - return mtime; -} - -/*- - *----------------------------------------------------------------------- - * 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 flag CHILDMADE field will be - * set true and its cmtime set to now. - * - * If the child is not up-to-date and still does not exist, - * set the FORCE flag on the parents. - * - * 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 (cgn) - register GNode *cgn; /* the child node */ -{ - register GNode *pgn; /* the parent node */ - register char *cname; /* the child's name */ - register LstNode ln; /* Element in parents and iParents lists */ - time_t mtime = -1; - char *p1; - - cname = Var_Value (TARGET, cgn, &p1); - if (p1) - free(p1); - - /* - * 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) { - mtime = Make_Recheck(cgn); - } - - if (Lst_Open (cgn->parents) == SUCCESS) { - while ((ln = Lst_Next (cgn->parents)) != NILLNODE) { - pgn = (GNode *)Lst_Datum (ln); - if (mtime == 0) - pgn->flags |= FORCE; - if (pgn->flags & REMAKE) { - pgn->unmade -= 1; - - if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) { - if (cgn->made == MADE) - pgn->flags |= CHILDMADE; - (void)Make_TimeStamp (pgn, cgn); - } - if (pgn->unmade == 0) { - /* - * Queue the node up -- any unmade predecessors will - * be dealt with in MakeStartJobs. - */ - (void)Lst_EnQueue (toBeMade, (ClientData)pgn); - } else if (pgn->unmade < 0) { - Error ("Graph cycles through %s", pgn->name); - } - } - } - Lst_Close (cgn->parents); - } - /* - * 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 != NILLNODE; ln = Lst_Succ(ln)) { - GNode *succ = (GNode *)Lst_Datum(ln); - - if ((succ->flags & REMAKE) && succ->unmade == 0 && succ->made == UNMADE && - Lst_Member(toBeMade, (ClientData)succ) == NILLNODE) - { - (void)Lst_EnQueue(toBeMade, (ClientData)succ); - } - } - - /* - * Set the .PREFIX and .IMPSRC variables for all the implied parents - * of this node. - */ - if (Lst_Open (cgn->iParents) == SUCCESS) { - char *p1; - char *cpref = Var_Value(PREFIX, cgn, &p1); - - while ((ln = Lst_Next (cgn->iParents)) != NILLNODE) { - pgn = (GNode *)Lst_Datum (ln); - if (pgn->flags & REMAKE) { - Var_Set (IMPSRC, cname, pgn, 0); - if (cpref != NULL) - Var_Set (PREFIX, cpref, pgn, 0); - } - } - if (p1) - free(p1); - Lst_Close (cgn->iParents); - } -} - -/*- - *----------------------------------------------------------------------- - * MakeAddAllSrc -- - * Add a child's name to the ALLSRC and OODATE variables of the given - * node. Called from Make_DoAllVar via Lst_ForEach. A 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...).. - * - * Results: - * Always returns 0 - * - * Side Effects: - * The ALLSRC variable for the given node is extended. - *----------------------------------------------------------------------- - */ -static int -MakeUnmark (cgnp, pgnp) - ClientData cgnp; - ClientData pgnp; -{ - GNode *cgn = (GNode *) cgnp; - - cgn->type &= ~OP_MARK; - return (0); -} - -static int -MakeAddAllSrc (cgnp, pgnp) - ClientData cgnp; /* The child to add */ - ClientData pgnp; /* The parent to whose ALLSRC variable it should be */ - /* added */ -{ - GNode *cgn = (GNode *) cgnp; - GNode *pgn = (GNode *) pgnp; - - if (cgn->type & OP_MARK) - return (0); - cgn->type |= OP_MARK; - - if ((cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE|OP_INVISIBLE)) == 0) { - char *child; - char *p1 = NULL; - - if (cgn->type & OP_ARCHV) - child = Var_Value (MEMBER, cgn, &p1); - else - child = cgn->path ? cgn->path : cgn->name; - Var_Append (ALLSRC, child, pgn); - if (pgn->type & OP_JOIN) { - if (cgn->made == MADE) { - Var_Append(OODATE, child, pgn); - } - } else if ((pgn->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, pgn); - } - if (p1) - free(p1); - } - return (0); -} - -/*- - *----------------------------------------------------------------------- - * 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. - * - * Results: - * None - * - * 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 (gn) - GNode *gn; -{ - Lst_ForEach (gn->children, MakeUnmark, (ClientData) gn); - Lst_ForEach (gn->children, MakeAddAllSrc, (ClientData) gn); - - if (!Var_Exists (OODATE, gn)) { - Var_Set (OODATE, "", gn, 0); - } - if (!Var_Exists (ALLSRC, gn)) { - Var_Set (ALLSRC, "", gn, 0); - } - - if (gn->type & OP_JOIN) { - char *p1; - Var_Set (TARGET, Var_Value (ALLSRC, gn, &p1), gn, 0); - if (p1) - free(p1); - } -} - -/*- - *----------------------------------------------------------------------- - * 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 () -{ - register GNode *gn; - - while (!Lst_IsEmpty (toBeMade)) { - gn = (GNode *) Lst_DeQueue (toBeMade); - if (DEBUG(MAKE)) { - printf ("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 != NILLNODE; ln = Lst_Succ(ln)){ - GNode *pgn = (GNode *)Lst_Datum(ln); - - if ((pgn->flags & REMAKE) && pgn->made == UNMADE) { - if (DEBUG(MAKE)) { - printf("predecessor %s not made yet.\n", pgn->name); - } - break; - } - } - /* - * If ln isn't nil, 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 != NILLNODE) { - continue; - } - } - - if (!Job_TokenWithdraw()) { - Lst_AtFront(toBeMade, gn); - break; - } - - numNodes--; - if (Make_OODate (gn)) { - if (DEBUG(MAKE)) { - printf ("out-of-date\n"); - } - if (queryFlag) { - return (TRUE); - } - Make_DoAllVar (gn); - Job_Make (gn); - } else { - if (DEBUG(MAKE)) { - printf ("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); - } - Job_TokenReturn(); - 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. - * - * Results: - * Always returns 0. - * - * Side Effects: - * A message may be printed. - * - *----------------------------------------------------------------------- - */ -static int -MakePrintStatus(gnp, cyclep) - ClientData gnp; /* Node to examine */ - ClientData cyclep; /* True if gn->unmade being non-zero implies - * a cycle in the graph, not an error in an - * inferior */ -{ - GNode *gn = (GNode *) gnp; - Boolean cycle = *(Boolean *) cyclep; - if (gn->made == UPTODATE) { - printf ("`%s' is up to date.\n", gn->name); - } else if (gn->unmade != 0) { - if (cycle) { - Boolean t = TRUE; - /* - * 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(gn->children, MakePrintStatus, (ClientData) &t); - gn->made = UNMADE; - } else if (gn->made != ENDCYCLE) { - gn->made = CYCLE; - Lst_ForEach(gn->children, MakePrintStatus, (ClientData) &t); - } - } else { - printf ("`%s' not remade because of errors.\n", gn->name); - } - } - return (0); -} - - -/*- - *----------------------------------------------------------------------- - * Make_ExpandUse -- - * Expand .USE nodes and create a new targets list - * Results: - * The new list of targets. - * - * Side Effects: - * numNodes is set to the number of elements in the list of targets. - *----------------------------------------------------------------------- - */ -Lst -Make_ExpandUse (targs) - Lst targs; /* the initial list of targets */ -{ - register GNode *gn; /* a temporary pointer */ - register Lst examine; /* List of targets to examine */ - register Lst ntargs; /* List of new targets to be made */ - - ntargs = Lst_Init (FALSE); - - examine = Lst_Duplicate(targs, NOCOPY); - numNodes = 0; - - /* - * Make an initial downward pass over the graph, marking nodes to be made - * as we go down. We call Suff_FindDeps to find where a node is and - * to get some children for it if it has none and also has no commands. - * If the node is a leaf, we stick it on the toBeMade queue to - * be looked at in a minute, otherwise we add its children to our queue - * and go on about our business. - */ - while (!Lst_IsEmpty (examine)) { - gn = (GNode *) Lst_DeQueue (examine); - - if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) { - Lst new; - new = Lst_Duplicate (gn->cohorts, NOCOPY); - Lst_Concat (new, examine, LST_CONCLINK); - examine = new; - } - - if ((gn->flags & REMAKE) == 0) { - gn->flags |= REMAKE; - numNodes++; - - /* - * Apply any .USE rules before looking for implicit dependencies - * to make sure everything has commands that should... - * Make sure that the TARGET is set, so that we can make - * expansions. - */ - if (gn->type & OP_ARCHV) { - char *eoa, *eon; - eoa = strchr(gn->name, '('); - eon = strchr(gn->name, ')'); - if (eoa == NULL || eon == NULL) - continue; - *eoa = '\0'; - *eon = '\0'; - Var_Set (MEMBER, eoa + 1, gn, 0); - Var_Set (ARCHIVE, gn->name, gn, 0); - *eoa = '('; - *eon = ')'; - } - - (void)Dir_MTime(gn); - Var_Set (TARGET, gn->path ? gn->path : gn->name, gn, 0); - Lst_ForEach (gn->children, MakeUnmark, (ClientData)gn); - Lst_ForEach (gn->children, MakeHandleUse, (ClientData)gn); - Suff_FindDeps (gn); - - if (gn->unmade != 0 && (gn->type & OP_MADE) == 0) { - Lst_ForEach (gn->children, MakeAddChild, (ClientData)examine); - } else { - (void)Lst_EnQueue (ntargs, (ClientData)gn); - if (gn->type & OP_MADE) - Lst_ForEach (gn->children, MakeFindChild, (ClientData)gn); - } - } - } - - Lst_Destroy (examine, NOFREE); - return ntargs; -} - -/*- - *----------------------------------------------------------------------- - * 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 (targs) - Lst targs; /* the initial list of targets */ -{ - int errors; /* Number of errors the Job module reports */ - - toBeMade = Make_ExpandUse (targs); - - 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. - */ - (void) 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 (!Lst_IsEmpty(toBeMade) || !Job_Empty ()) { - Job_CatchOutput (); - Job_CatchChildren (!usePipes); - (void)MakeStartJobs(); - } - - errors = Job_Finish(); - - /* - * Print the final status of each target. E.g. if it wasn't made - * because some inferior reported an error. - */ - errors = ((errors == 0) && (numNodes != 0)); - Lst_ForEach(targs, MakePrintStatus, (ClientData) &errors); - - return (TRUE); -} diff --git a/bootstrap/bmake/make.h b/bootstrap/bmake/make.h deleted file mode 100644 index fcd79517711..00000000000 --- a/bootstrap/bmake/make.h +++ /dev/null @@ -1,438 +0,0 @@ -/* $NetBSD: make.h,v 1.1.1.1 2004/03/11 13:04:10 grant Exp $ */ - -/* - * 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. - * - * from: @(#)make.h 8.3 (Berkeley) 6/13/95 - */ - -/*- - * make.h -- - * The global definitions for pmake - */ - -#ifndef _MAKE_H_ -#define _MAKE_H_ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#ifdef HAVE_STRING_H -#include -#else -#include -#endif -#include -#ifdef HAVE_SYS_CDEFS_H -#include -#else -# ifndef __P -# if defined(__STDC__) || defined(__cplusplus) -# define __P(protos) protos /* full-blown ANSI C */ -# else -# define __P(protos) () /* traditional C preprocessor */ -# endif -# endif -# ifndef __GNUC__ -# ifndef __inline -# define __inline -# endif -# endif -# ifndef __STDC__ -# ifndef const -# define const -# endif -# ifndef volatile -# define volatile -# endif -# endif -#endif -#ifdef __STDC__ -#include -#include -#endif -#include "sprite.h" -#include "lst.h" -#include "hash.h" -#include "make-conf.h" -#include "buf.h" - -/* - * some vendors don't have this --sjg - */ -#if defined(S_IFDIR) && !defined(S_ISDIR) -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - -#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) -#define POSIX_SIGNALS -#endif - -/*- - * The structure for an individual graph node. Each node has several - * pieces of data associated with it. - * 1) the name of the target it describes - * 2) the location of the target file in the file system. - * 3) the type of operator used to define its sources (qv. parse.c) - * 4) whether it is involved in this invocation of make - * 5) whether the target has been remade - * 6) whether any of its children has been remade - * 7) the number of its children that are, as yet, unmade - * 8) its modification time - * 9) the modification time of its youngest child (qv. make.c) - * 10) a list of nodes for which this is a source - * 11) a list of nodes on which this depends - * 12) a list of nodes that depend on this, as gleaned from the - * transformation rules. - * 13) a list of nodes of the same name created by the :: operator - * 14) a 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. - * 15) a list of nodes that must be made (if they're made) after - * this node is, but that do not depend on this node, in the - * normal sense. - * 16) a Lst of ``local'' variables that are specific to this target - * and this target only (qv. var.c [$@ $< $?, etc.]) - * 17) a Lst of strings that are commands to be given to a shell - * to create this target. - */ -typedef struct GNode { - char *name; /* The target's name */ - char *uname; /* The unexpanded name of a .USE node */ - char *path; /* The full pathname of the file */ - int type; /* Its type (see the OP flags, below) */ - int order; /* Its wait weight */ - - int flags; -#define REMAKE 0x1 /* this target needs to be remade */ -#define CHILDMADE 0x2 /* children of this target were made */ -#define FORCE 0x4 /* children don't exist, and we pretend made */ - enum { - UNMADE, BEINGMADE, MADE, UPTODATE, ERROR, ABORTED, - CYCLE, ENDCYCLE - } made; /* Set to reflect the state of processing - * on this node: - * UNMADE - Not examined yet - * BEINGMADE - Target is already being made. - * Indicates a cycle in the graph. (compat - * mode only) - * MADE - Was out-of-date and has been made - * UPTODATE - Was already up-to-date - * ERROR - An error occurred while it was being - * made (used only in compat mode) - * ABORTED - The target was aborted due to - * an error making an inferior (compat). - * CYCLE - 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. - * ENDCYCLE - the cycle has been completely - * printed. Go back and unmark all its - * members. - */ - int unmade; /* The number of unmade children */ - - time_t mtime; /* Its modification time */ - time_t cmtime; /* The modification time of its youngest - * child */ - - Lst iParents; /* Links to parents for which this is an - * implied source, if any */ - Lst cohorts; /* Other nodes for the :: operator */ - Lst parents; /* Nodes that depend on this one */ - Lst children; /* Nodes on which this one depends */ - Lst successors; /* Nodes that must be made after this one */ - Lst preds; /* Nodes that must be made before this one */ - - Hash_Table context; /* The local variables */ - Lst commands; /* Creation commands */ - - struct _Suff *suffix; /* Suffix for the node (determined by - * Suff_FindDeps and opaque to everyone - * but the Suff module) */ - char *fname; /* filename where the GNode got defined */ - int lineno; /* line number where the GNode got defined */ -} GNode; - -/* - * Manifest constants - */ -#define NILGNODE ((GNode *) NIL) - -/* - * The OP_ constants are used when parsing a dependency line as a way of - * communicating to other parts of the program the way in which a target - * should be made. These constants are bitwise-OR'ed together and - * placed in the 'type' field of each node. Any node that has - * a 'type' field which satisfies the OP_NOP function was never never on - * the lefthand side of an operator, though it may have been on the - * righthand side... - */ -#define OP_DEPENDS 0x00000001 /* Execution of commands depends on - * kids (:) */ -#define OP_FORCE 0x00000002 /* Always execute commands (!) */ -#define OP_DOUBLEDEP 0x00000004 /* Execution of commands depends on kids - * per line (::) */ -#define OP_OPMASK (OP_DEPENDS|OP_FORCE|OP_DOUBLEDEP) - -#define OP_OPTIONAL 0x00000008 /* Don't care if the target doesn't - * exist and can't be created */ -#define OP_USE 0x00000010 /* Use associated commands for parents */ -#define OP_EXEC 0x00000020 /* Target is never out of date, but always - * execute commands anyway. Its time - * doesn't matter, so it has none...sort - * of */ -#define OP_IGNORE 0x00000040 /* Ignore errors when creating the node */ -#define OP_PRECIOUS 0x00000080 /* Don't remove the target when - * interrupted */ -#define OP_SILENT 0x00000100 /* Don't echo commands when executed */ -#define OP_MAKE 0x00000200 /* Target is a 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_MADE 0x00000800 /* Assume the node is already made; even if - * it really is out of date */ -#define OP_USEBEFORE 0x00002000 /* Like .USE, only prepend commands */ -#define OP_INVISIBLE 0x00004000 /* The node is invisible to its parents. - * I.e. it doesn't show up in the parents's - * local variables. */ -#define OP_NOTMAIN 0x00008000 /* The node is exempt from normal 'main - * target' processing in parse.c */ -#define OP_PHONY 0x00010000 /* Not a file target; run always */ -#define OP_NOPATH 0x00020000 /* Don't search for file in the path */ -/* Attributes applied by PMake */ -#define OP_TRANSFORM 0x80000000 /* The node is a transformation rule */ -#define OP_MEMBER 0x40000000 /* Target is a member of an archive */ -#define OP_LIB 0x20000000 /* Target is a library */ -#define OP_ARCHV 0x10000000 /* Target is an archive construct */ -#define OP_HAS_COMMANDS 0x08000000 /* Target has all the commands it should. - * Used when parsing to catch multiple - * commands for a target */ -#define OP_SAVE_CMDS 0x04000000 /* Saving commands on .END (Compat) */ -#define OP_DEPS_FOUND 0x02000000 /* Already processed by Suff_FindDeps */ -#define OP_MARK 0x01000000 /* Node found while expanding .ALLSRC */ - -#define NoExecute(gn) ((gn->type & OP_MAKE) ? noRecursiveExecute : noExecute) -/* - * OP_NOP will return TRUE if the node with the given type was not the - * object of a dependency operator - */ -#define OP_NOP(t) (((t) & OP_OPMASK) == 0x00000000) - -#define OP_NOTARGET (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM) - -/* - * The TARG_ constants are used when calling the Targ_FindNode and - * Targ_FindList functions in targ.c. They simply tell the functions what to - * do if the desired node(s) is (are) not found. If the TARG_CREATE constant - * is given, a new, empty node will be created for the target, placed in the - * table of all targets and its address returned. If TARG_NOCREATE is given, - * a NIL pointer will be returned. - */ -#define TARG_CREATE 0x01 /* create node if not found */ -#define TARG_NOCREATE 0x00 /* don't create it */ - -/* - * 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 */ - -/* - * These constants are all used by the Str_Concat function to decide how the - * final string should look. If STR_ADDSPACE is given, a space will be - * placed between the two strings. If STR_ADDSLASH is given, a '/' will - * be used instead of a space. If neither is given, no intervening characters - * will be placed between the two strings in the final output. If the - * STR_DOFREE bit is set, the two input strings will be freed before - * Str_Concat returns. - */ -#define STR_ADDSPACE 0x01 /* add a space when Str_Concat'ing */ -#define STR_DOFREE 0x02 /* free source strings after concatenation */ -#define STR_ADDSLASH 0x04 /* add a slash when Str_Concat'ing */ - -/* - * Error levels for parsing. PARSE_FATAL means the process cannot continue - * once the makefile has been parsed. PARSE_WARNING means it can. Passed - * as the first argument to Parse_Error. - */ -#define PARSE_WARNING 2 -#define PARSE_FATAL 1 - -/* - * Values returned by Cond_Eval. - */ -#define COND_PARSE 0 /* Parse the next lines */ -#define COND_SKIP 1 /* Skip the next lines */ -#define COND_INVALID 2 /* Not a conditional statement */ - -/* - * Definitions for the "local" variables. Used only for clarity. - */ -#define TARGET "@" /* Target of dependency */ -#define OODATE "?" /* All out-of-date sources */ -#define ALLSRC ">" /* All sources */ -#define IMPSRC "<" /* Source implied by transformation */ -#define PREFIX "*" /* Common prefix */ -#define ARCHIVE "!" /* Archive in "archive(member)" syntax */ -#define MEMBER "%" /* Member in "archive(member)" syntax */ - -#define FTARGET "@F" /* file part of TARGET */ -#define DTARGET "@D" /* directory part of TARGET */ -#define FIMPSRC " -#else -/* - * It sucks that we have to hard code a path like this. - * But systems that have a sys/cdefs.h that don't use gcc - * should be few. - */ -# include "/usr/include/sys/cdefs.h" -#endif -/* - * We are about to [re]define these - */ -#undef __P -#undef _SYS_CDEFS_H_ -#endif - -#define _SYS_CDEFS_H_ - -#ifdef NetBSD -#include -#endif - -#if defined(__cplusplus) -#define __BEGIN_DECLS extern "C" { -#define __END_DECLS }; -#else -#define __BEGIN_DECLS -#define __END_DECLS -#endif - -/* - * The __CONCAT macro is used to concatenate parts of symbol names, e.g. - * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo. - * The __CONCAT macro is a bit tricky -- make sure you don't put spaces - * in between its arguments. __CONCAT can also concatenate double-quoted - * strings produced by the __STRING macro, but this only works with ANSI C. - */ -#if defined(__STDC__) || defined(__cplusplus) -#define __P(protos) protos /* full-blown ANSI C */ -#define __CONCAT(x,y) x ## y -#define __STRING(x) #x - -#define __const const /* define reserved names to standard */ -#define __signed signed -#define __volatile volatile -#if defined(__cplusplus) -#define __inline inline /* convert to C++ keyword */ -#else -#ifndef __GNUC__ -#define __inline /* delete GCC keyword */ -#endif /* !__GNUC__ */ -#endif /* !__cplusplus */ - -#else /* !(__STDC__ || __cplusplus) */ -#define __P(protos) () /* traditional C preprocessor */ -#define __CONCAT(x,y) x/**/y -#define __STRING(x) "x" - -#ifndef __GNUC__ -#define __const /* delete pseudo-ANSI C keywords */ -#define __inline -#define __signed -#define __volatile -#endif /* !__GNUC__ */ - -/* - * In non-ANSI C environments, new programs will want ANSI-only C keywords - * deleted from the program and old programs will want them left alone. - * Programs using the ANSI C keywords const, inline etc. as normal - * identifiers should define -DNO_ANSI_KEYWORDS. - */ -#ifndef NO_ANSI_KEYWORDS -#define const __const /* convert ANSI C keywords */ -#define inline __inline -#define signed __signed -#define volatile __volatile -#endif /* !NO_ANSI_KEYWORDS */ -#endif /* !(__STDC__ || __cplusplus) */ - -/* - * GCC1 and some versions of GCC2 declare dead (non-returning) and - * pure (no side effects) functions using "volatile" and "const"; - * unfortunately, these then cause warnings under "-ansi -pedantic". - * GCC2 uses a new, peculiar __attribute__((attrs)) style. All of - * these work for GNU C++ (modulo a slight glitch in the C++ grammar - * in the distribution version of 2.5.5). - */ -#if !defined(__GNUC__) || __GNUC__ < 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -#define __attribute__(x) /* delete __attribute__ if non-gcc or gcc1 */ -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -#define __dead __volatile -#define __pure __const -#endif -#endif - -#ifdef sun386 -# define __attribute__(x) -#endif - -#ifdef __KPRINTF_ATTRIBUTE__ -#define __kprintf_attribute__(a) __attribute__(a) -#else -#define __kprintf_attribute__(a) -#endif - -/* Delete pseudo-keywords wherever they are not available or needed. */ -#ifndef __dead -#define __dead -#define __pure -#endif - -#define __IDSTRING(name,string) \ - static const char name[] __attribute__((__unused__)) = string - -#ifndef __RCSID -#define __RCSID(s) __IDSTRING(rcsid,s) -#endif - -#ifndef __COPYRIGHT -#define __COPYRIGHT(s) __IDSTRING(copyright,s) -#endif - -#endif /* !_SYS_CDEFS_H_ */ diff --git a/bootstrap/bmake/mkdeps.sh b/bootstrap/bmake/mkdeps.sh deleted file mode 100755 index e5323ffef80..00000000000 --- a/bootstrap/bmake/mkdeps.sh +++ /dev/null @@ -1,322 +0,0 @@ -: -# NAME: -# mkdeps - generate dependencies -# -# SYNOPSIS: -# mkdeps [options] file ... -# -# DESCRIPTION: -# This script updates "makefile" with dependencies for -# "file"(s). It borrows ideas from various makedepend scripts -# and should be compatible with most. -# -# By default we use grep to extract include file names from -# source files. We source an "rc" file '$Mydir/.${Myname}rc' which -# can contain variable assignments such as: -#.nf -# -# cpp_c=/usr/lib/cpp -# cpp_cc=g++ -E -# ... -# -#.fi -# If the variable 'cpp_$suffix' is set, we use it as our cpp in -# place of grep. The program referenced by these variables are -# expected to produce output like: -#.nf -# -# # 10 \"/usr/include/stdio.h\" 1 -# -#.fi -# This allows us to skip most of our processing. For lex,yacc -# and other source files, grep is probably just as quick and -# certainly more portable. -# -# If the "rc" file does not exist, we create it and attempt to -# find cpp or an equivalent cc invocation to assign to 'cpp_c'. -# -# AUTHOR: -# Simon J. Gerraty -# - -# RCSid: -# $Id: mkdeps.sh,v 1.1.1.1 2004/03/11 13:04:10 grant Exp $ -# -# @(#) Copyright (c) 1993 Simon J. Gerraty -# -# This file is provided in the hope that it will -# be of use. There is absolutely NO WARRANTY. -# Permission to copy, redistribute or otherwise -# use this file is hereby granted provided that -# the above copyright notice and this notice are -# left intact. -# -# Please send copies of changes and bug-fixes to: -# sjg@zen.void.oz.au -# - -Myname=`basename $0 .sh` -Mydir=`dirname $0` - -case `echo -n .` in --n*) N=; C="\c";; -*) N=-n; C=;; -esac - -cc_include=-I/usr/include - -TF=/tmp/dep.$$ -EF=/tmp/deperr.$$ -> $EF - -case "$*" in -*-n*) # don't use rc file - rc=/dev/null - norc=yes;; -*) - rc=$Mydir/.${Myname}rc - ;; -esac - -update= -Include=include - -if [ x"$norc" = x -a -f $rc ]; then - . $rc -else - # if /usr/lib/cpp or equivalent is available it is better than - # grepping .c files. - # See what (if anything) works on this system... - echo : > $rc - echo "# pre-processor for .c files" >> $rc - # try a couple of sane places first - for d in /usr/libexec /usr/lib /usr/bin /lib /usr/ccs/bin - do - cpp_c=$d/cpp - [ -x $cpp_c ] && break - done - - if [ -x $cpp_c ]; then - echo cpp_c=$cpp_c >> $rc - else - cpp_c= - # rats see if cc can be used - echo "#include " > /tmp/f$$.c - echo "main() { return 0; }" >> /tmp/f$$.c - # try some sensible args to cc - for arg in -E -P -M - do - ok=`${REALCC:-${CC:-cc}} $arg /tmp/f$$.c 2>/dev/null | grep '^#.*stdio.h' | tail -1` - case "$ok" in - "") ;; - *) - cpp_c="${REALCC:-${CC:-cc}} $arg" - echo cpp_c="'$cpp_c'" >> $rc - break;; - esac - done - rm -f /tmp/f$$.c - fi -fi - -clean_up() { - trap "" 2 3 - trap 0 - if [ -s $EF ]; then - egrep -vi "included from|warning" $EF > ${EF}2 - if [ -s ${EF}2 ]; then - cat $EF >&2 - rm -f .depend - ests=1 - fi - fi - rm -f $TF $EF* - exit ${ests:-0} -} - -# this lot does not work on HPsUX - complain to Hp. -trap clean_up 0 -trap exit 2 3 - -get_incs() { - case "$cpp" in - grep) - # set IGNORE="<" to skip system includes - egrep '^#[ ]*include' $* | egrep -v "$IGNORE" | \ - sed -e 's/^.*include[^"<]*["<]//' -e 's/[">].*//g';; - *) - # $cpp (eg. /usr/lib/cpp or cc -E) should produce output like: - # 1 "/usr/include/stdio.h" 2 - # set IGNORE=/usr/include to skip system includes - $cpp $cpp_opts $cc_include $* 2>> $EF | egrep '^#.*\.h"' | sed 's,^#.*"\(.*\)".*,\1,' | - egrep -v "$IGNORE" | sort -u;; - esac -} - -gen_deps() { - llen=$1 - shift - - for ifile in $* - do - case "$cpp" in - grep) - # this lot is not needed if not using grep. - for dir in $srcdir $dirlist /usr/include - do - [ -f "$dir/$ifile" ] && break - done - - if [ ! -f "$dir/$ifile" ]; then - # produce a useful error message (useful to emacs or error) - iline=`grep -n ".*include.*[\"<]$ifile[\">]" $file | cut -d: -f1` - echo "\"$file\", line $iline: cannot find include file \"$ifile\"" >> $EF - # no point adding to dependency list as the resulting makefile - # would not work anyway... - continue - fi - ifile=$dir/$ifile - - # check whether we have done it yet - case `grep "$ifile" $TF` in - "") echo "$ifile" >> $TF;; - *) continue;; # no repeats... - esac - ;; - esac - - len=`expr "$ifile " : '.*'` - if [ "`expr $llen + $len`" -gt ${width:-76} ]; then - echo "\\" >> .depend - echo $N " $C" >> .depend - llen=8 - fi - echo $N "$ifile $C" >> .depend - llen=`expr $llen + $len` - - case "$cpp" in - grep) - # this lot is not needed unless using grep. - ilist=`get_incs $ifile` # recurse needed? - [ "$ilist" ] && llen=`gen_deps $llen $ilist` - ;; - esac - done - echo $llen -} - -for f in makefile Makefile -do - test -s $f && { MAKEFILE=$f; break; } -done - -MAKEFILE=${MAKEFILE:-makefile} -IGNORE=${IGNORE:-"^-"} # won't happen -obj=o -cpp_opts= # incase cpp != grep -vpath= -append= -progDep= - -set -- `getopt "AanNV:s:w:o:I:D:b:f:i:p" "$@"` -for key in "$@" -do - case $key in - --) shift; break;; - -A) Include=;; # cat .depend >> $MAKEFILE - -a) append=yes; shift;; - -n) shift;; # ignore rc - -N) update=no; shift;; # don't update $MAKEFILE - -I) cpp_opts="$cpp_opts$1$2 "; dirlist="$dirlist $2"; shift 2;; - -o) obj=$2; shift 2;; - -s) shift 2;; # can't handle it anyway... - -w) width=$2; shift 2;; - -f) MAKEFILE=$2; shift 2;; - -b) BASEDIR=$2; shift 2;; - -i) IGNORE="$2"; shift 2;; # ignore headers matching this... - -D) cpp_opts="$cpp_opts$1$2 "; shift 2;; - -V) VPATH="$2"; shift 2;; # where to look for files - -p) progDep=yes; shift;; - esac -done - -[ "$VPATH" ] && vpath=`IFS=:; set -- $VPATH; echo $*` - -[ "$append" ] || > .depend - -for file in $* -do - cpp= - case "$file" in - *.C) suffix=C;; - *.cc) suffix=cc;; - *.c) suffix=c;; - *.y) suffix=y;; - *.l) suffix=l;; - *.pc) suffix=pc;; - *) continue;; - esac - - eval cpp=\"\${cpp_${suffix}:-grep}\" - - if [ ! -f $file -a "$vpath" ]; then - for d in . $vpath - do - [ -f $d/$file ] && { file=$d/$file; break; } - done - fi - srcdir=`dirname $file` - base=`basename $file .$suffix` - - ilist=`get_incs $file` - - if [ "$ilist" ]; then - > $TF - if [ "$progDep" ]; then - echo "$base: $file \\" >> .depend - else - echo "$base.$obj: $file \\" >> .depend - fi - echo $N " $C" >> .depend - llen=8 - llen=`gen_deps $llen $ilist` - echo >> .depend - echo >> .depend - elif [ "$progDep" ]; then - echo "$base: $file" >> .depend - echo >> .depend - fi -done - -if [ -s .depend ]; then - # ./foo.h looks ugly - mv .depend $TF - { test "$BASEDIR" && sed -e "s;$BASEDIR;\$(BASEDIR);g" $TF || cat $TF; } | - sed 's;\([^.]\)\./;\1;g' > .depend - - # - # Save the manually updated section of the makefile - # - if [ x$update != xno ]; then - trap "" 2 # don't die if we got this far - - # if make doesn't support include, then append our deps... - depended=`grep 'include.*\.depend' $MAKEFILE` - test "$depended" && clean_up - - sed '/^# DO NOT DELETE.*depend.*$/,$d' < $MAKEFILE > $TF - mv $TF $MAKEFILE - cat <> $MAKEFILE -# DO NOT DELETE THIS LINE -- make depend depends on it -# Do not edit anything below, it was added automagically by $Myname. - -! - - case "$Include" in - "") cat .depend >> $MAKEFILE;; - .include) echo '.include ".depend"' >> $MAKEFILE;; - include) echo include .depend >> $MAKEFILE;; - esac - fi -fi -clean_up diff --git a/bootstrap/bmake/nonints.h b/bootstrap/bmake/nonints.h deleted file mode 100644 index 324fdb7e976..00000000000 --- a/bootstrap/bmake/nonints.h +++ /dev/null @@ -1,154 +0,0 @@ -/* $NetBSD: nonints.h,v 1.1.1.1 2004/03/11 13:04:10 grant Exp $ */ - -/*- - * 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. - * - * from: @(#)nonints.h 8.3 (Berkeley) 3/19/94 - */ - -/* arch.c */ -ReturnStatus Arch_ParseArchive __P((char **, Lst, GNode *)); -void Arch_Touch __P((GNode *)); -void Arch_TouchLib __P((GNode *)); -time_t Arch_MTime __P((GNode *)); -time_t Arch_MemMTime __P((GNode *)); -void Arch_FindLib __P((GNode *, Lst)); -Boolean Arch_LibOODate __P((GNode *)); -void Arch_Init __P((void)); -void Arch_End __P((void)); -int Arch_IsLib __P((GNode *)); - -/* compat.c */ -void Compat_Run __P((Lst)); - -/* cond.c */ -int Cond_EvalExpression __P((int, char *, Boolean *, int)); -int Cond_Eval __P((char *)); -void Cond_End __P((void)); - -/* for.c */ -int For_Eval __P((char *)); -void For_Run __P((void)); - -/* main.c */ -void Main_ParseArgLine __P((char *)); -int main __P((int, char **)); -char *Cmd_Exec __P((char *, char **)); -void Error __P((char *, ...)) - __attribute__((__format__(__printf__, 1, 2))); -void Fatal __P((char *, ...)) - __attribute__((__format__(__printf__, 1, 2),__noreturn__)); -void Punt __P((char *, ...)) - __attribute__((__format__(__printf__, 1, 2),__noreturn__)); -void DieHorribly __P((void)) - __attribute__((__noreturn__)); -int PrintAddr __P((ClientData, ClientData)); -void Finish __P((int)); -char *estrdup __P((const char *)); -void *emalloc __P((size_t)); -void *erealloc __P((void *, size_t)); -void enomem __P((void)); -int eunlink __P((const char *)); -void execError __P((const char *)); - -/* parse.c */ -void Parse_Error __P((int, char *, ...)) - __attribute__((__format__(__printf__, 2, 3))); -Boolean Parse_AnyExport __P((void)); -Boolean Parse_IsVar __P((char *)); -void Parse_DoVar __P((char *, GNode *)); -void Parse_AddIncludeDir __P((char *)); -void Parse_File __P((char *, FILE *)); -void Parse_Init __P((void)); -void Parse_End __P((void)); -void Parse_FromString __P((char *)); -Lst Parse_MainName __P((void)); - -/* str.c */ -char *str_concat __P((char *, char *, int)); -char **brk_string __P((char *, int *, Boolean, char **)); -char *Str_FindSubstring __P((char *, char *)); -int Str_Match __P((char *, char *)); -char *Str_SYSVMatch __P((char *, char *, int *len)); -void Str_SYSVSubst __P((Buffer, char *, char *, int)); - -/* suff.c */ -void Suff_ClearSuffixes __P((void)); -Boolean Suff_IsTransform __P((char *)); -GNode *Suff_AddTransform __P((char *)); -int Suff_EndTransform __P((ClientData, ClientData)); -void Suff_AddSuffix __P((char *, GNode **)); -Lst Suff_GetPath __P((char *)); -void Suff_DoPaths __P((void)); -void Suff_AddInclude __P((char *)); -void Suff_AddLib __P((char *)); -void Suff_FindDeps __P((GNode *)); -void Suff_SetNull __P((char *)); -void Suff_Init __P((void)); -void Suff_End __P((void)); -void Suff_PrintAll __P((void)); - -/* targ.c */ -void Targ_Init __P((void)); -void Targ_End __P((void)); -Lst Targ_List __P((void)); -GNode *Targ_NewGN __P((char *)); -GNode *Targ_FindNode __P((char *, int)); -Lst Targ_FindList __P((Lst, int)); -Boolean Targ_Ignore __P((GNode *)); -Boolean Targ_Silent __P((GNode *)); -Boolean Targ_Precious __P((GNode *)); -void Targ_SetMain __P((GNode *)); -int Targ_PrintCmd __P((ClientData, ClientData)); -char *Targ_FmtTime __P((time_t)); -void Targ_PrintType __P((int)); -void Targ_PrintGraph __P((int)); -void Targ_Propagate __P((void)); - -/* var.c */ -void Var_Delete __P((char *, GNode *)); -void Var_Set __P((char *, char *, GNode *, int)); -void Var_Append __P((char *, char *, GNode *)); -Boolean Var_Exists __P((char *, GNode *)); -char *Var_Value __P((char *, GNode *, char **)); -char *Var_Parse __P((char *, GNode *, Boolean, int *, Boolean *)); -char *Var_Subst __P((char *, char *, GNode *, Boolean)); -char *Var_GetTail __P((char *)); -char *Var_GetHead __P((char *)); -void Var_Init __P((void)); -void Var_End __P((void)); -void Var_Dump __P((GNode *)); diff --git a/bootstrap/bmake/parse.c b/bootstrap/bmake/parse.c deleted file mode 100644 index 69ae9d21ad8..00000000000 --- a/bootstrap/bmake/parse.c +++ /dev/null @@ -1,2825 +0,0 @@ -/* $NetBSD: parse.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $ */ - -/* - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: parse.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: parse.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: parse.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $"); -#endif - -/*- - * parse.c -- - * Functions to parse a makefile. - * - * One function, Parse_Init, must be called before any functions - * in this module are used. After that, the function Parse_File is the - * main entry point and controls most of the other functions in this - * module. - * - * Most important structures are kept in Lsts. Directories for - * the #include "..." function are kept in the 'parseIncPath' Lst, while - * those for the #include <...> are kept in the 'sysIncPath' Lst. The - * targets currently being defined are kept in the 'targets' Lst. - * - * The variables 'fname' and 'lineno' are used to track the name - * of the current file and the line number in that file so that error - * messages can be more meaningful. - * - * Interface: - * Parse_Init Initialization function which must be - * called before anything else in this module - * is used. - * - * Parse_End Cleanup the module - * - * Parse_File Function used to parse a makefile. It must - * be given the name of the file, which should - * already have been opened, and a function - * to call to read a character from the file. - * - * Parse_IsVar Returns TRUE if the given line is a - * variable assignment. Used by MainParseArgs - * to determine if an argument is a target - * or a variable assignment. Used internally - * for pretty much the same thing... - * - * Parse_Error Function called when an error occurs in - * parsing. Used by the variable and - * conditional modules. - * Parse_MainName Returns a Lst of the main target to create. - */ - -#ifdef __STDC__ -#include -#else -#include -#endif -#include -#include -#include -#include "make.h" -#include "hash.h" -#include "dir.h" -#include "job.h" -#include "buf.h" -#include "pathnames.h" - -/* - * These values are returned by ParseEOF to tell Parse_File whether to - * CONTINUE parsing, i.e. it had only reached the end of an include file, - * or if it's DONE. - */ -#define CONTINUE 1 -#define DONE 0 -static Lst targets; /* targets we're working on */ -#ifdef CLEANUP -static Lst targCmds; /* command lines for targets */ -#endif -static Boolean inLine; /* true if currently in a dependency - * line or its commands */ -typedef struct { - char *str; - char *ptr; -} PTR; - -static char *fname; /* name of current file (for errors) */ -static int lineno; /* line number in current file */ -static FILE *curFILE = NULL; /* current makefile */ - -static PTR *curPTR = NULL; /* current makefile */ - -static int fatals = 0; - -static GNode *mainNode; /* The main target to create. This is the - * first target on the first dependency - * line in the first makefile */ -/* - * Definitions for handling #include specifications - */ -typedef struct IFile { - char *fname; /* name of previous file */ - int lineno; /* saved line number */ - FILE * F; /* the open stream */ - PTR * p; /* the char pointer */ -} IFile; - -static Lst includes; /* stack of IFiles generated by - * #includes */ -Lst parseIncPath; /* list of directories for "..." includes */ -Lst sysIncPath; /* list of directories for <...> includes */ - -/*- - * specType contains the SPECial TYPE of the current target. It is - * Not if the target is unspecial. If it *is* special, however, the children - * are linked as children of the parent but not vice versa. This variable is - * set in ParseDoDependency - */ -typedef enum { - Begin, /* .BEGIN */ - Default, /* .DEFAULT */ - End, /* .END */ - Ignore, /* .IGNORE */ - Includes, /* .INCLUDES */ - Interrupt, /* .INTERRUPT */ - Libs, /* .LIBS */ - MFlags, /* .MFLAGS or .MAKEFLAGS */ - Main, /* .MAIN and we don't have anything user-specified to - * make */ - NoExport, /* .NOEXPORT */ - NoPath, /* .NOPATH */ - Not, /* Not special */ - NotParallel, /* .NOTPARALELL */ - Null, /* .NULL */ - Order, /* .ORDER */ - Parallel, /* .PARALLEL */ - ExPath, /* .PATH */ - Phony, /* .PHONY */ -#ifdef POSIX - Posix, /* .POSIX */ -#endif - Precious, /* .PRECIOUS */ - ExShell, /* .SHELL */ - Silent, /* .SILENT */ - SingleShell, /* .SINGLESHELL */ - Suffixes, /* .SUFFIXES */ - Wait, /* .WAIT */ - Attribute /* Generic attribute */ -} ParseSpecial; - -static ParseSpecial specType; -static int waiting; - -/* - * Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER - * seen, then set to each successive source on the line. - */ -static GNode *predecessor; - -/* - * The parseKeywords table is searched using binary search when deciding - * if a target or source is special. The 'spec' field is the ParseSpecial - * type of the keyword ("Not" if the keyword isn't special as a target) while - * the 'op' field is the operator to apply to the list of targets if the - * keyword is used as a source ("0" if the keyword isn't special as a source) - */ -static struct { - char *name; /* Name of keyword */ - ParseSpecial spec; /* Type when used as a target */ - int op; /* Operator when used as a source */ -} parseKeywords[] = { -{ ".BEGIN", Begin, 0 }, -{ ".DEFAULT", Default, 0 }, -{ ".END", End, 0 }, -{ ".EXEC", Attribute, OP_EXEC }, -{ ".IGNORE", Ignore, OP_IGNORE }, -{ ".INCLUDES", Includes, 0 }, -{ ".INTERRUPT", Interrupt, 0 }, -{ ".INVISIBLE", Attribute, OP_INVISIBLE }, -{ ".JOIN", Attribute, OP_JOIN }, -{ ".LIBS", Libs, 0 }, -{ ".MADE", Attribute, OP_MADE }, -{ ".MAIN", Main, 0 }, -{ ".MAKE", Attribute, OP_MAKE }, -{ ".MAKEFLAGS", MFlags, 0 }, -{ ".MFLAGS", MFlags, 0 }, -{ ".NOPATH", NoPath, OP_NOPATH }, -{ ".NOTMAIN", Attribute, OP_NOTMAIN }, -{ ".NOTPARALLEL", NotParallel, 0 }, -{ ".NO_PARALLEL", NotParallel, 0 }, -{ ".NULL", Null, 0 }, -{ ".OPTIONAL", Attribute, OP_OPTIONAL }, -{ ".ORDER", Order, 0 }, -{ ".PARALLEL", Parallel, 0 }, -{ ".PATH", ExPath, 0 }, -{ ".PHONY", Phony, OP_PHONY }, -#ifdef POSIX -{ ".POSIX", Posix, 0 }, -#endif -{ ".PRECIOUS", Precious, OP_PRECIOUS }, -{ ".RECURSIVE", Attribute, OP_MAKE }, -{ ".SHELL", ExShell, 0 }, -{ ".SILENT", Silent, OP_SILENT }, -{ ".SINGLESHELL", SingleShell, 0 }, -{ ".SUFFIXES", Suffixes, 0 }, -{ ".USE", Attribute, OP_USE }, -{ ".USEBEFORE", Attribute, OP_USEBEFORE }, -{ ".WAIT", Wait, 0 }, -}; - -static void ParseErrorInternal __P((char *, size_t, int, char *, ...)) - __attribute__((__format__(__printf__, 4, 5))); -static void ParseVErrorInternal __P((char *, size_t, int, char *, va_list)) - __attribute__((__format__(__printf__, 4, 0))); -static int ParseFindKeyword __P((char *)); -static int ParseLinkSrc __P((ClientData, ClientData)); -static int ParseDoOp __P((ClientData, ClientData)); -static int ParseAddDep __P((ClientData, ClientData)); -static void ParseDoSrc __P((int, char *, Lst)); -static int ParseFindMain __P((ClientData, ClientData)); -static int ParseAddDir __P((ClientData, ClientData)); -static int ParseClearPath __P((ClientData, ClientData)); -static void ParseDoDependency __P((char *)); -static int ParseAddCmd __P((ClientData, ClientData)); -static __inline int ParseReadc __P((void)); -static void ParseUnreadc __P((int)); -static void ParseHasCommands __P((ClientData)); -static void ParseDoInclude __P((char *)); -static void ParseSetParseFile __P((char *)); -#ifdef SYSVINCLUDE -static void ParseTraditionalInclude __P((char *)); -#endif -static int ParseEOF __P((int)); -static char *ParseReadLine __P((void)); -static char *ParseSkipLine __P((int)); -static void ParseFinishLine __P((void)); -static void ParseMark __P((GNode *)); - -extern int maxJobs; - -/*- - *---------------------------------------------------------------------- - * ParseFindKeyword -- - * Look in the table of keywords for one matching the given string. - * - * Results: - * The index of the keyword, or -1 if it isn't there. - * - * Side Effects: - * None - *---------------------------------------------------------------------- - */ -static int -ParseFindKeyword (str) - char *str; /* String to find */ -{ - register int start, - end, - cur; - register int diff; - - start = 0; - end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1; - - do { - cur = start + ((end - start) / 2); - diff = strcmp (str, parseKeywords[cur].name); - - if (diff == 0) { - return (cur); - } else if (diff < 0) { - end = cur - 1; - } else { - start = cur + 1; - } - } while (start <= end); - return (-1); -} - -/*- - * ParseVErrorInternal -- - * Error message abort function for parsing. Prints out the context - * of the error (line number and file) as well as the message with - * two optional arguments. - * - * Results: - * None - * - * Side Effects: - * "fatals" is incremented if the level is PARSE_FATAL. - */ -/* VARARGS */ -static void -#ifdef __STDC__ -ParseVErrorInternal(char *cfname, size_t clineno, int type, char *fmt, - va_list ap) -#else -ParseVErrorInternal(va_alist) - va_dcl -#endif -{ - static Boolean fatal_warning_error_printed = FALSE; - - (void)fprintf(stderr, "%s: \"", progname); - - if (*cfname != '/') { - char *cp, *dir; - - /* - * Nothing is more anoying than not knowing which Makefile - * is the culprit. - */ - dir = Var_Value(".PARSEDIR", VAR_GLOBAL, &cp); - if (dir == NULL || *dir == '\0' || - (*dir == '.' && dir[1] == '\0')) - dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp); - if (dir == NULL) - dir = "."; - - (void)fprintf(stderr, "%s/%s", dir, cfname); - } else - (void)fprintf(stderr, "%s", cfname); - - (void)fprintf(stderr, "\" line %d: ", (int)clineno); - if (type == PARSE_WARNING) - (void)fprintf(stderr, "warning: "); - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, "\n"); - (void)fflush(stderr); - if (type == PARSE_FATAL || parseWarnFatal) - fatals += 1; - if (parseWarnFatal && !fatal_warning_error_printed) { - Error("parsing warnings being treated as errors"); - fatal_warning_error_printed = TRUE; - } -} - -/*- - * ParseErrorInternal -- - * Error function - * - * Results: - * None - * - * Side Effects: - * None - */ -/* VARARGS */ -static void -#ifdef __STDC__ -ParseErrorInternal(char *cfname, size_t clineno, int type, char *fmt, ...) -#else -ParseErrorInternal(va_alist) - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - int type; /* Error type (PARSE_WARNING, PARSE_FATAL) */ - char *fmt; - char *cfname; - size_t clineno; - - va_start(ap); - cfname = va_arg(ap, char *); - clineno = va_arg(ap, size_t); - type = va_arg(ap, int); - fmt = va_arg(ap, char *); -#endif - - ParseVErrorInternal(cfname, clineno, type, fmt, ap); - va_end(ap); -} - -/*- - * Parse_Error -- - * External interface to ParseErrorInternal; uses the default filename - * Line number. - * - * Results: - * None - * - * Side Effects: - * None - */ -/* VARARGS */ -void -#ifdef __STDC__ -Parse_Error(int type, char *fmt, ...) -#else -Parse_Error(va_alist) - va_dcl -#endif -{ - va_list ap; -#ifdef __STDC__ - va_start(ap, fmt); -#else - int type; /* Error type (PARSE_WARNING, PARSE_FATAL) */ - char *fmt; - - va_start(ap); - type = va_arg(ap, int); - fmt = va_arg(ap, char *); -#endif - ParseVErrorInternal(fname, lineno, type, fmt, ap); - va_end(ap); -} - -/*- - *--------------------------------------------------------------------- - * ParseLinkSrc -- - * Link the parent node to its new child. Used in a Lst_ForEach by - * ParseDoDependency. If the specType isn't 'Not', the parent - * isn't linked as a parent of the child. - * - * Results: - * Always = 0 - * - * Side Effects: - * New elements are added to the parents list of cgn and the - * children list of cgn. the unmade field of pgn is updated - * to reflect the additional child. - *--------------------------------------------------------------------- - */ -static int -ParseLinkSrc (pgnp, cgnp) - ClientData pgnp; /* The parent node */ - ClientData cgnp; /* The child node */ -{ - GNode *pgn = (GNode *) pgnp; - GNode *cgn = (GNode *) cgnp; - - if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts)) - pgn = (GNode *) Lst_Datum (Lst_Last (pgn->cohorts)); - (void)Lst_AtEnd (pgn->children, (ClientData)cgn); - if (specType == Not) - (void)Lst_AtEnd (cgn->parents, (ClientData)pgn); - pgn->unmade += 1; - return (0); -} - -/*- - *--------------------------------------------------------------------- - * ParseDoOp -- - * Apply the parsed operator to the given target node. Used in a - * Lst_ForEach call by ParseDoDependency once all targets have - * been found and their operator parsed. If the previous and new - * operators are incompatible, a major error is taken. - * - * Results: - * Always 0 - * - * Side Effects: - * The type field of the node is altered to reflect any new bits in - * the op. - *--------------------------------------------------------------------- - */ -static int -ParseDoOp (gnp, opp) - ClientData gnp; /* The node to which the operator is to be - * applied */ - ClientData opp; /* The operator to apply */ -{ - GNode *gn = (GNode *) gnp; - int op = *(int *) opp; - /* - * If the dependency mask of the operator and the node don't match and - * the node has actually had an operator applied to it before, and - * the operator actually has some dependency information in it, complain. - */ - if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) && - !OP_NOP(gn->type) && !OP_NOP(op)) - { - Parse_Error (PARSE_FATAL, "Inconsistent operator for %s", gn->name); - return (1); - } - - if ((op == OP_DOUBLEDEP) && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) { - /* - * If the node was the object of a :: operator, we need to create a - * new instance of it for the children and commands on this dependency - * line. The new instance is placed on the 'cohorts' list of the - * initial one (note the initial one is not on its own cohorts list) - * and the new instance is linked to all parents of the initial - * instance. - */ - register GNode *cohort; - - /* - * Propagate copied bits to the initial node. They'll be propagated - * back to the rest of the cohorts later. - */ - gn->type |= op & ~OP_OPMASK; - - cohort = Targ_NewGN(gn->name); - /* - * Make the cohort invisible as well to avoid duplicating it into - * other variables. True, parents of this target won't tend to do - * anything with their local variables, but better safe than - * sorry. (I think this is pointless now, since the relevant list - * traversals will no longer see this node anyway. -mycroft) - */ - cohort->type = op | OP_INVISIBLE; - (void)Lst_AtEnd(gn->cohorts, (ClientData)cohort); - } else { - /* - * We don't want to nuke any previous flags (whatever they were) so we - * just OR the new operator into the old - */ - gn->type |= op; - } - - return (0); -} - -/*- - *--------------------------------------------------------------------- - * ParseAddDep -- - * Check if the pair of GNodes given needs to be synchronized. - * This has to be when two nodes are on different sides of a - * .WAIT directive. - * - * Results: - * Returns 1 if the two targets need to be ordered, 0 otherwise. - * If it returns 1, the search can stop - * - * Side Effects: - * A dependency can be added between the two nodes. - * - *--------------------------------------------------------------------- - */ -static int -ParseAddDep(pp, sp) - ClientData pp; - ClientData sp; -{ - GNode *p = (GNode *) pp; - GNode *s = (GNode *) sp; - - if (p->order < s->order) { - /* - * XXX: This can cause loops, and loops can cause unmade targets, - * but checking is tedious, and the debugging output can show the - * problem - */ - (void)Lst_AtEnd(p->successors, (ClientData)s); - (void)Lst_AtEnd(s->preds, (ClientData)p); - return 0; - } - else - return 1; -} - - -/*- - *--------------------------------------------------------------------- - * ParseDoSrc -- - * Given the name of a source, figure out if it is an attribute - * and apply it to the targets if it is. Else decide if there is - * some attribute which should be applied *to* the source because - * of some special target and apply it if so. Otherwise, make the - * source be a child of the targets in the list 'targets' - * - * Results: - * None - * - * Side Effects: - * Operator bits may be added to the list of targets or to the source. - * The targets may have a new source added to their lists of children. - *--------------------------------------------------------------------- - */ -static void -ParseDoSrc (tOp, src, allsrc) - int tOp; /* operator (if any) from special targets */ - char *src; /* name of the source to handle */ - Lst allsrc; /* List of all sources to wait for */ - -{ - GNode *gn = NULL; - - if (*src == '.' && isupper ((unsigned char)src[1])) { - int keywd = ParseFindKeyword(src); - if (keywd != -1) { - int op = parseKeywords[keywd].op; - if (op != 0) { - Lst_ForEach (targets, ParseDoOp, (ClientData)&op); - return; - } - if (parseKeywords[keywd].spec == Wait) { - waiting++; - return; - } - } - } - - switch (specType) { - case Main: - /* - * If we have noted the existence of a .MAIN, it means we need - * to add the sources of said target to the list of things - * to create. The string 'src' is likely to be free, so we - * must make a new copy of it. Note that this will only be - * invoked if the user didn't specify a target on the command - * line. This is to allow #ifmake's to succeed, or something... - */ - (void) Lst_AtEnd (create, (ClientData)estrdup(src)); - /* - * Add the name to the .TARGETS variable as well, so the user cna - * employ that, if desired. - */ - Var_Append(".TARGETS", src, VAR_GLOBAL); - return; - - case Order: - /* - * Create proper predecessor/successor links between the previous - * source and the current one. - */ - gn = Targ_FindNode(src, TARG_CREATE); - if (predecessor != NILGNODE) { - (void)Lst_AtEnd(predecessor->successors, (ClientData)gn); - (void)Lst_AtEnd(gn->preds, (ClientData)predecessor); - } - /* - * The current source now becomes the predecessor for the next one. - */ - predecessor = gn; - break; - - default: - /* - * If the source is not an attribute, we need to find/create - * a node for it. After that we can apply any operator to it - * from a special target or link it to its parents, as - * appropriate. - * - * In the case of a source that was the object of a :: operator, - * the attribute is applied to all of its instances (as kept in - * the 'cohorts' list of the node) or all the cohorts are linked - * to all the targets. - */ - gn = Targ_FindNode (src, TARG_CREATE); - if (tOp) { - gn->type |= tOp; - } else { - Lst_ForEach (targets, ParseLinkSrc, (ClientData)gn); - } - break; - } - - gn->order = waiting; - (void)Lst_AtEnd(allsrc, (ClientData)gn); - if (waiting) { - Lst_ForEach(allsrc, ParseAddDep, (ClientData)gn); - } -} - -/*- - *----------------------------------------------------------------------- - * ParseFindMain -- - * Find a real target in the list and set it to be the main one. - * Called by ParseDoDependency when a main target hasn't been found - * yet. - * - * Results: - * 0 if main not found yet, 1 if it is. - * - * Side Effects: - * mainNode is changed and Targ_SetMain is called. - * - *----------------------------------------------------------------------- - */ -static int -ParseFindMain(gnp, dummy) - ClientData gnp; /* Node to examine */ - ClientData dummy; -{ - GNode *gn = (GNode *) gnp; - if ((gn->type & OP_NOTARGET) == 0) { - mainNode = gn; - Targ_SetMain(gn); - return (dummy ? 1 : 1); - } else { - return (dummy ? 0 : 0); - } -} - -/*- - *----------------------------------------------------------------------- - * ParseAddDir -- - * Front-end for Dir_AddDir to make sure Lst_ForEach keeps going - * - * Results: - * === 0 - * - * Side Effects: - * See Dir_AddDir. - * - *----------------------------------------------------------------------- - */ -static int -ParseAddDir(path, name) - ClientData path; - ClientData name; -{ - (void) Dir_AddDir((Lst) path, (char *) name); - return(0); -} - -/*- - *----------------------------------------------------------------------- - * ParseClearPath -- - * Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going - * - * Results: - * === 0 - * - * Side Effects: - * See Dir_ClearPath - * - *----------------------------------------------------------------------- - */ -static int -ParseClearPath(path, dummy) - ClientData path; - ClientData dummy; -{ - Dir_ClearPath((Lst) path); - return(dummy ? 0 : 0); -} - -/*- - *--------------------------------------------------------------------- - * ParseDoDependency -- - * Parse the dependency line in line. - * - * Results: - * None - * - * Side Effects: - * The nodes of the sources are linked as children to the nodes of the - * targets. Some nodes may be created. - * - * We parse a dependency line by first extracting words from the line and - * finding nodes in the list of all targets with that name. This is done - * until a character is encountered which is an operator character. Currently - * these are only ! and :. At this point the operator is parsed and the - * pointer into the line advanced until the first source is encountered. - * The parsed operator is applied to each node in the 'targets' list, - * which is where the nodes found for the targets are kept, by means of - * the ParseDoOp function. - * The sources are read in much the same way as the targets were except - * that now they are expanded using the wildcarding scheme of the C-Shell - * and all instances of the resulting words in the list of all targets - * are found. Each of the resulting nodes is then linked to each of the - * targets as one of its children. - * Certain targets are handled specially. These are the ones detailed - * by the specType variable. - * The storing of transformation rules is also taken care of here. - * A target is recognized as a transformation rule by calling - * Suff_IsTransform. If it is a transformation rule, its node is gotten - * from the suffix module via Suff_AddTransform rather than the standard - * Targ_FindNode in the target module. - *--------------------------------------------------------------------- - */ -static void -ParseDoDependency (line) - char *line; /* the line to parse */ -{ - char *cp; /* our current position */ - GNode *gn; /* a general purpose temporary node */ - int op; /* the operator on the line */ - char savec; /* a place to save a character */ - Lst paths; /* List of search paths to alter when parsing - * a list of .PATH targets */ - int tOp; /* operator from special target */ - Lst sources; /* list of archive source names after - * expansion */ - Lst curTargs; /* list of target names to be found and added - * to the targets list */ - Lst curSrcs; /* list of sources in order */ - - tOp = 0; - - specType = Not; - waiting = 0; - paths = (Lst)NULL; - - curTargs = Lst_Init(FALSE); - curSrcs = Lst_Init(FALSE); - - do { - for (cp = line; - *cp && !isspace ((unsigned char)*cp) && - (*cp != '!') && (*cp != ':') && (*cp != '('); - cp++) - { - if (*cp == '$') { - /* - * Must be a dynamic source (would have been expanded - * otherwise), so call the Var module to parse the puppy - * so we can safely advance beyond it...There should be - * no errors in this, as they would have been discovered - * in the initial Var_Subst and we wouldn't be here. - */ - int length; - Boolean freeIt; - char *result; - - result=Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt); - - if (freeIt) { - free(result); - } - cp += length-1; - } - continue; - } - if (*cp == '(') { - /* - * Archives must be handled specially to make sure the OP_ARCHV - * flag is set in their 'type' field, for one thing, and because - * things like "archive(file1.o file2.o file3.o)" are permissible. - * Arch_ParseArchive will set 'line' to be the first non-blank - * after the archive-spec. It creates/finds nodes for the members - * and places them on the given list, returning SUCCESS if all - * went well and FAILURE if there was an error in the - * specification. On error, line should remain untouched. - */ - if (Arch_ParseArchive (&line, targets, VAR_CMD) != SUCCESS) { - Parse_Error (PARSE_FATAL, - "Error in archive specification: \"%s\"", line); - return; - } else { - continue; - } - } - savec = *cp; - - if (!*cp) { - /* - * Ending a dependency line without an operator is a Bozo - * no-no. As a heuristic, this is also often triggered by - * undetected conflicts from cvs/rcs merges. - */ - if ((strncmp(line, "<<<<<<", 6) == 0) || - (strncmp(line, "======", 6) == 0) || - (strncmp(line, ">>>>>>", 6) == 0)) - Parse_Error (PARSE_FATAL, - "Makefile appears to contain unresolved cvs/rcs/??? merge conflicts"); - else - Parse_Error (PARSE_FATAL, "Need an operator"); - return; - } - *cp = '\0'; - /* - * Have a word in line. See if it's a special target and set - * specType to match it. - */ - if (*line == '.' && isupper ((unsigned char)line[1])) { - /* - * See if the target is a special target that must have it - * or its sources handled specially. - */ - int keywd = ParseFindKeyword(line); - if (keywd != -1) { - if (specType == ExPath && parseKeywords[keywd].spec != ExPath) { - Parse_Error(PARSE_FATAL, "Mismatched special targets"); - return; - } - - specType = parseKeywords[keywd].spec; - tOp = parseKeywords[keywd].op; - - /* - * Certain special targets have special semantics: - * .PATH Have to set the dirSearchPath - * variable too - * .MAIN Its sources are only used if - * nothing has been specified to - * create. - * .DEFAULT Need to create a node to hang - * commands on, but we don't want - * it in the graph, nor do we want - * it to be the Main Target, so we - * create it, set OP_NOTMAIN and - * add it to the list, setting - * DEFAULT to the new node for - * later use. We claim the node is - * A transformation rule to make - * life easier later, when we'll - * use Make_HandleUse to actually - * apply the .DEFAULT commands. - * .PHONY The list of targets - * .NOPATH Don't search for file in the path - * .BEGIN - * .END - * .INTERRUPT Are not to be considered the - * main target. - * .NOTPARALLEL Make only one target at a time. - * .SINGLESHELL Create a shell for each command. - * .ORDER Must set initial predecessor to NIL - */ - switch (specType) { - case ExPath: - if (paths == NULL) { - paths = Lst_Init(FALSE); - } - (void)Lst_AtEnd(paths, (ClientData)dirSearchPath); - break; - case Main: - if (!Lst_IsEmpty(create)) { - specType = Not; - } - break; - case Begin: - case End: - case Interrupt: - gn = Targ_FindNode(line, TARG_CREATE); - gn->type |= OP_NOTMAIN; - (void)Lst_AtEnd(targets, (ClientData)gn); - break; - case Default: - gn = Targ_NewGN(".DEFAULT"); - gn->type |= (OP_NOTMAIN|OP_TRANSFORM); - (void)Lst_AtEnd(targets, (ClientData)gn); - DEFAULT = gn; - break; - case NotParallel: - { - maxJobs = 1; - break; - } - case SingleShell: - compatMake = TRUE; - break; - case Order: - predecessor = NILGNODE; - break; - default: - break; - } - } else if (strncmp (line, ".PATH", 5) == 0) { - /* - * .PATH has to be handled specially. - * Call on the suffix module to give us a path to - * modify. - */ - Lst path; - - specType = ExPath; - path = Suff_GetPath (&line[5]); - if (path == NILLST) { - Parse_Error (PARSE_FATAL, - "Suffix '%s' not defined (yet)", - &line[5]); - return; - } else { - if (paths == (Lst)NULL) { - paths = Lst_Init(FALSE); - } - (void)Lst_AtEnd(paths, (ClientData)path); - } - } - } - - /* - * Have word in line. Get or create its node and stick it at - * the end of the targets list - */ - if ((specType == Not) && (*line != '\0')) { - if (Dir_HasWildcards(line)) { - /* - * Targets are to be sought only in the current directory, - * so create an empty path for the thing. Note we need to - * use Dir_Destroy in the destruction of the path as the - * Dir module could have added a directory to the path... - */ - Lst emptyPath = Lst_Init(FALSE); - - Dir_Expand(line, emptyPath, curTargs); - - Lst_Destroy(emptyPath, Dir_Destroy); - } else { - /* - * No wildcards, but we want to avoid code duplication, - * so create a list with the word on it. - */ - (void)Lst_AtEnd(curTargs, (ClientData)line); - } - - while(!Lst_IsEmpty(curTargs)) { - char *targName = (char *)Lst_DeQueue(curTargs); - - if (!Suff_IsTransform (targName)) { - gn = Targ_FindNode (targName, TARG_CREATE); - } else { - gn = Suff_AddTransform (targName); - } - - (void)Lst_AtEnd (targets, (ClientData)gn); - } - } else if (specType == ExPath && *line != '.' && *line != '\0') { - Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line); - } - - *cp = savec; - /* - * If it is a special type and not .PATH, it's the only target we - * allow on this line... - */ - if (specType != Not && specType != ExPath) { - Boolean warn = FALSE; - - while ((*cp != '!') && (*cp != ':') && *cp) { - if (*cp != ' ' && *cp != '\t') { - warn = TRUE; - } - cp++; - } - if (warn) { - Parse_Error(PARSE_WARNING, "Extra target ignored"); - } - } else { - while (*cp && isspace ((unsigned char)*cp)) { - cp++; - } - } - line = cp; - } while ((*line != '!') && (*line != ':') && *line); - - /* - * Don't need the list of target names anymore... - */ - Lst_Destroy(curTargs, NOFREE); - - if (!Lst_IsEmpty(targets)) { - switch(specType) { - default: - Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored"); - break; - case Default: - case Begin: - case End: - case Interrupt: - /* - * These four create nodes on which to hang commands, so - * targets shouldn't be empty... - */ - case Not: - /* - * Nothing special here -- targets can be empty if it wants. - */ - break; - } - } - - /* - * Have now parsed all the target names. Must parse the operator next. The - * result is left in op . - */ - if (*cp == '!') { - op = OP_FORCE; - } else if (*cp == ':') { - if (cp[1] == ':') { - op = OP_DOUBLEDEP; - cp++; - } else { - op = OP_DEPENDS; - } - } else { - Parse_Error (PARSE_FATAL, "Missing dependency operator"); - return; - } - - cp++; /* Advance beyond operator */ - - Lst_ForEach (targets, ParseDoOp, (ClientData)&op); - - /* - * Get to the first source - */ - while (*cp && isspace ((unsigned char)*cp)) { - cp++; - } - line = cp; - - /* - * Several special targets take different actions if present with no - * sources: - * a .SUFFIXES line with no sources clears out all old suffixes - * a .PRECIOUS line makes all targets precious - * a .IGNORE line ignores errors for all targets - * a .SILENT line creates silence when making all targets - * a .PATH removes all directories from the search path(s). - */ - if (!*line) { - switch (specType) { - case Suffixes: - Suff_ClearSuffixes (); - break; - case Precious: - allPrecious = TRUE; - break; - case Ignore: - ignoreErrors = TRUE; - break; - case Silent: - beSilent = TRUE; - break; - case ExPath: - Lst_ForEach(paths, ParseClearPath, (ClientData)NULL); - break; -#ifdef POSIX - case Posix: - Var_Set("%POSIX", "1003.2", VAR_GLOBAL, 0); - break; -#endif - default: - break; - } - } else if (specType == MFlags) { - /* - * Call on functions in main.c to deal with these arguments and - * set the initial character to a null-character so the loop to - * get sources won't get anything - */ - Main_ParseArgLine (line); - *line = '\0'; - } else if (specType == ExShell) { - if (Job_ParseShell (line) != SUCCESS) { - Parse_Error (PARSE_FATAL, "improper shell specification"); - return; - } - *line = '\0'; - } else if ((specType == NotParallel) || (specType == SingleShell)) { - *line = '\0'; - } - - /* - * NOW GO FOR THE SOURCES - */ - if ((specType == Suffixes) || (specType == ExPath) || - (specType == Includes) || (specType == Libs) || - (specType == Null)) - { - while (*line) { - /* - * If the target was one that doesn't take files as its sources - * but takes something like suffixes, we take each - * space-separated word on the line as a something and deal - * with it accordingly. - * - * If the target was .SUFFIXES, we take each source as a - * suffix and add it to the list of suffixes maintained by the - * Suff module. - * - * If the target was a .PATH, we add the source as a directory - * to search on the search path. - * - * If it was .INCLUDES, the source is taken to be the suffix of - * files which will be #included and whose search path should - * be present in the .INCLUDES variable. - * - * If it was .LIBS, the source is taken to be the suffix of - * files which are considered libraries and whose search path - * should be present in the .LIBS variable. - * - * If it was .NULL, the source is the suffix to use when a file - * has no valid suffix. - */ - char savec; - while (*cp && !isspace ((unsigned char)*cp)) { - cp++; - } - savec = *cp; - *cp = '\0'; - switch (specType) { - case Suffixes: - Suff_AddSuffix (line, &mainNode); - break; - case ExPath: - Lst_ForEach(paths, ParseAddDir, (ClientData)line); - break; - case Includes: - Suff_AddInclude (line); - break; - case Libs: - Suff_AddLib (line); - break; - case Null: - Suff_SetNull (line); - break; - default: - break; - } - *cp = savec; - if (savec != '\0') { - cp++; - } - while (*cp && isspace ((unsigned char)*cp)) { - cp++; - } - line = cp; - } - if (paths) { - Lst_Destroy(paths, NOFREE); - } - } else { - while (*line) { - /* - * The targets take real sources, so we must beware of archive - * specifications (i.e. things with left parentheses in them) - * and handle them accordingly. - */ - while (*cp && !isspace ((unsigned char)*cp)) { - if ((*cp == '(') && (cp > line) && (cp[-1] != '$')) { - /* - * Only stop for a left parenthesis if it isn't at the - * start of a word (that'll be for variable changes - * later) and isn't preceded by a dollar sign (a dynamic - * source). - */ - break; - } else { - cp++; - } - } - - if (*cp == '(') { - GNode *gn; - - sources = Lst_Init (FALSE); - if (Arch_ParseArchive (&line, sources, VAR_CMD) != SUCCESS) { - Parse_Error (PARSE_FATAL, - "Error in source archive spec \"%s\"", line); - return; - } - - while (!Lst_IsEmpty (sources)) { - gn = (GNode *) Lst_DeQueue (sources); - ParseDoSrc (tOp, gn->name, curSrcs); - } - Lst_Destroy (sources, NOFREE); - cp = line; - } else { - if (*cp) { - *cp = '\0'; - cp += 1; - } - - ParseDoSrc (tOp, line, curSrcs); - } - while (*cp && isspace ((unsigned char)*cp)) { - cp++; - } - line = cp; - } - } - - if (mainNode == NILGNODE) { - /* - * If we have yet to decide on a main target to make, in the - * absence of any user input, we want the first target on - * the first dependency line that is actually a real target - * (i.e. isn't a .USE or .EXEC rule) to be made. - */ - Lst_ForEach (targets, ParseFindMain, (ClientData)0); - } - - /* - * Finally, destroy the list of sources - */ - Lst_Destroy(curSrcs, NOFREE); -} - -/*- - *--------------------------------------------------------------------- - * Parse_IsVar -- - * Return TRUE if the passed line is a variable assignment. A variable - * assignment consists of a single word followed by optional whitespace - * followed by either a += or an = operator. - * This function is used both by the Parse_File function and main when - * parsing the command-line arguments. - * - * Results: - * TRUE if it is. FALSE if it ain't - * - * Side Effects: - * none - *--------------------------------------------------------------------- - */ -Boolean -Parse_IsVar (line) - register char *line; /* the line to check */ -{ - register Boolean wasSpace = FALSE; /* set TRUE if found a space */ - register Boolean haveName = FALSE; /* Set TRUE if have a variable name */ - int level = 0; -#define ISEQOPERATOR(c) \ - (((c) == '+') || ((c) == ':') || ((c) == '?') || ((c) == '!')) - - /* - * Skip to variable name - */ - for (;(*line == ' ') || (*line == '\t'); line++) - continue; - - for (; *line != '=' || level != 0; line++) - switch (*line) { - case '\0': - /* - * end-of-line -- can't be a variable assignment. - */ - return FALSE; - - case ' ': - case '\t': - /* - * there can be as much white space as desired so long as there is - * only one word before the operator - */ - wasSpace = TRUE; - break; - - case '(': - case '{': - level++; - break; - - case '}': - case ')': - level--; - break; - - default: - if (wasSpace && haveName) { - if (ISEQOPERATOR(*line)) { - /* - * We must have a finished word - */ - if (level != 0) - return FALSE; - - /* - * When an = operator [+?!:] is found, the next - * character must be an = or it ain't a valid - * assignment. - */ - if (line[1] == '=') - return haveName; -#ifdef SUNSHCMD - /* - * This is a shell command - */ - if (strncmp(line, ":sh", 3) == 0) - return haveName; -#endif - } - /* - * This is the start of another word, so not assignment. - */ - return FALSE; - } - else { - haveName = TRUE; - wasSpace = FALSE; - } - break; - } - - return haveName; -} - -/*- - *--------------------------------------------------------------------- - * Parse_DoVar -- - * Take the variable assignment in the passed line and do it in the - * global context. - * - * Note: There is a lexical ambiguity with assignment modifier characters - * in variable names. This routine interprets the character before the = - * as a modifier. Therefore, an assignment like - * C++=/usr/bin/CC - * is interpreted as "C+ +=" instead of "C++ =". - * - * Results: - * none - * - * Side Effects: - * the variable structure of the given variable name is altered in the - * global context. - *--------------------------------------------------------------------- - */ -void -Parse_DoVar (line, ctxt) - char *line; /* a line guaranteed to be a variable - * assignment. This reduces error checks */ - GNode *ctxt; /* Context in which to do the assignment */ -{ - char *cp; /* pointer into line */ - enum { - VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL - } type; /* Type of assignment */ - char *opc; /* ptr to operator character to - * null-terminate the variable name */ - /* - * Avoid clobbered variable warnings by forcing the compiler - * to ``unregister'' variables - */ -#if __GNUC__ - (void) &cp; - (void) &line; -#endif - - /* - * Skip to variable name - */ - while ((*line == ' ') || (*line == '\t')) { - line++; - } - - /* - * Skip to operator character, nulling out whitespace as we go - */ - for (cp = line + 1; *cp != '='; cp++) { - if (isspace ((unsigned char)*cp)) { - *cp = '\0'; - } - } - opc = cp-1; /* operator is the previous character */ - *cp++ = '\0'; /* nuke the = */ - - /* - * Check operator type - */ - switch (*opc) { - case '+': - type = VAR_APPEND; - *opc = '\0'; - break; - - case '?': - /* - * If the variable already has a value, we don't do anything. - */ - *opc = '\0'; - if (Var_Exists(line, ctxt)) { - return; - } else { - type = VAR_NORMAL; - } - break; - - case ':': - type = VAR_SUBST; - *opc = '\0'; - break; - - case '!': - type = VAR_SHELL; - *opc = '\0'; - break; - - default: -#ifdef SUNSHCMD - while (opc > line && *opc != ':') - opc--; - - if (strncmp(opc, ":sh", 3) == 0) { - type = VAR_SHELL; - *opc = '\0'; - break; - } -#endif - type = VAR_NORMAL; - break; - } - - while (isspace ((unsigned char)*cp)) { - cp++; - } - - if (type == VAR_APPEND) { - Var_Append (line, cp, ctxt); - } else if (type == VAR_SUBST) { - /* - * Allow variables in the old value to be undefined, but leave their - * invocation alone -- this is done by forcing oldVars to be false. - * XXX: This can cause recursive variables, but that's not hard to do, - * and this allows someone to do something like - * - * CFLAGS = $(.INCLUDES) - * CFLAGS := -I.. $(CFLAGS) - * - * And not get an error. - */ - Boolean oldOldVars = oldVars; - - oldVars = FALSE; - - /* - * make sure that we set the variable the first time to nothing - * so that it gets substituted! - */ - if (!Var_Exists(line, ctxt)) - Var_Set(line, "", ctxt, 0); - - cp = Var_Subst(NULL, cp, ctxt, FALSE); - oldVars = oldOldVars; - - Var_Set(line, cp, ctxt, 0); - free(cp); - } else if (type == VAR_SHELL) { - Boolean freeCmd = FALSE; /* TRUE if the command needs to be freed, i.e. - * if any variable expansion was performed */ - char *res, *err; - - if (strchr(cp, '$') != NULL) { - /* - * There's a dollar sign in the command, so perform variable - * expansion on the whole thing. The resulting string will need - * freeing when we're done, so set freeCmd to TRUE. - */ - cp = Var_Subst(NULL, cp, VAR_CMD, TRUE); - freeCmd = TRUE; - } - - res = Cmd_Exec(cp, &err); - Var_Set(line, res, ctxt, 0); - free(res); - - if (err) - Parse_Error(PARSE_WARNING, err, cp); - - if (freeCmd) - free(cp); - } else { - /* - * Normal assignment -- just do it. - */ - Var_Set(line, cp, ctxt, 0); - } - if (strcmp(line, MAKEOVERRIDES) == 0) - ExportMAKEFLAGS(0); /* re-export MAKEFLAGS */ -} - - -/*- - * ParseAddCmd -- - * Lst_ForEach function to add a command line to all targets - * - * Results: - * Always 0 - * - * Side Effects: - * A new element is added to the commands list of the node. - */ -static int -ParseAddCmd(gnp, cmd) - ClientData gnp; /* the node to which the command is to be added */ - ClientData cmd; /* the command to add */ -{ - GNode *gn = (GNode *) gnp; - /* if target already supplied, ignore commands */ - if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) - gn = (GNode *) Lst_Datum (Lst_Last (gn->cohorts)); - if (!(gn->type & OP_HAS_COMMANDS)) { - (void)Lst_AtEnd(gn->commands, cmd); - ParseMark(gn); - } else { -#ifdef notyet - /* XXX: We cannot do this until we fix the tree */ - (void)Lst_AtEnd(gn->commands, cmd); - Parse_Error (PARSE_WARNING, - "overriding commands for target \"%s\"; " - "previous commands defined at %s: %d ignored", - gn->name, gn->fname, gn->lineno); -#else - Parse_Error (PARSE_WARNING, - "duplicate script for target \"%s\" ignored", - gn->name); - ParseErrorInternal (gn->fname, gn->lineno, PARSE_WARNING, - "using previous script for \"%s\" defined here", - gn->name); -#endif - } - return(0); -} - -/*- - *----------------------------------------------------------------------- - * ParseHasCommands -- - * Callback procedure for Parse_File when destroying the list of - * targets on the last dependency line. Marks a target as already - * having commands if it does, to keep from having shell commands - * on multiple dependency lines. - * - * Results: - * None - * - * Side Effects: - * OP_HAS_COMMANDS may be set for the target. - * - *----------------------------------------------------------------------- - */ -static void -ParseHasCommands(gnp) - ClientData gnp; /* Node to examine */ -{ - GNode *gn = (GNode *) gnp; - if (!Lst_IsEmpty(gn->commands)) { - gn->type |= OP_HAS_COMMANDS; - } -} - -/*- - *----------------------------------------------------------------------- - * Parse_AddIncludeDir -- - * Add a directory to the path searched for included makefiles - * bracketed by double-quotes. Used by functions in main.c - * - * Results: - * None. - * - * Side Effects: - * The directory is appended to the list. - * - *----------------------------------------------------------------------- - */ -void -Parse_AddIncludeDir (dir) - char *dir; /* The name of the directory to add */ -{ - (void) Dir_AddDir (parseIncPath, dir); -} - -/*- - *--------------------------------------------------------------------- - * ParseDoInclude -- - * Push to another file. - * - * The input is the line minus the `.'. A file spec is a string - * enclosed in <> or "". The former is looked for only in sysIncPath. - * The latter in . and the directories specified by -I command line - * options - * - * Results: - * None - * - * Side Effects: - * A structure is added to the includes Lst and readProc, lineno, - * fname and curFILE are altered for the new file - *--------------------------------------------------------------------- - */ -static void -ParseDoInclude (line) - char *line; -{ - char *fullname; /* full pathname of file */ - IFile *oldFile; /* state associated with current file */ - char endc; /* the character which ends the file spec */ - char *cp; /* current position in file spec */ - Boolean isSystem; /* TRUE if makefile is a system makefile */ - int silent = (*line != 'i') ? 1 : 0; - char *file = &line[7 + silent]; - - /* - * Skip to delimiter character so we know where to look - */ - while ((*file == ' ') || (*file == '\t')) { - file++; - } - - if ((*file != '"') && (*file != '<')) { - Parse_Error (PARSE_FATAL, - ".include filename must be delimited by '\"' or '<'"); - return; - } - - /* - * Set the search path on which to find the include file based on the - * characters which bracket its name. Angle-brackets imply it's - * a system Makefile while double-quotes imply it's a user makefile - */ - if (*file == '<') { - isSystem = TRUE; - endc = '>'; - } else { - isSystem = FALSE; - endc = '"'; - } - - /* - * Skip to matching delimiter - */ - for (cp = ++file; *cp && *cp != endc; cp++) { - continue; - } - - if (*cp != endc) { - Parse_Error (PARSE_FATAL, - "Unclosed %cinclude filename. '%c' expected", - '.', endc); - return; - } - *cp = '\0'; - - /* - * Substitute for any variables in the file name before trying to - * find the thing. - */ - file = Var_Subst (NULL, file, VAR_CMD, FALSE); - - /* - * Now we know the file's name and its search path, we attempt to - * find the durn thing. A return of NULL indicates the file don't - * exist. - */ - if (!isSystem) { - /* - * Include files contained in double-quotes are first searched for - * relative to the including file's location. We don't want to - * cd there, of course, so we just tack on the old file's - * leading path components and call Dir_FindFile to see if - * we can locate the beast. - */ - char *prefEnd, *Fname; - - /* Make a temporary copy of this, to be safe. */ - Fname = estrdup(fname); - - prefEnd = strrchr (Fname, '/'); - if (prefEnd != (char *)NULL) { - char *newName; - - *prefEnd = '\0'; - if (file[0] == '/') - newName = estrdup(file); - else - newName = str_concat (Fname, file, STR_ADDSLASH); - fullname = Dir_FindFile (newName, parseIncPath); - if (fullname == (char *)NULL) { - fullname = Dir_FindFile(newName, dirSearchPath); - } - free (newName); - *prefEnd = '/'; - } else { - fullname = (char *)NULL; - } - free (Fname); - } else { - fullname = (char *)NULL; - } - - if (fullname == (char *)NULL) { - /* - * System makefile or makefile wasn't found in same directory as - * included makefile. Search for it first on the -I search path, - * then on the .PATH search path, if not found in a -I directory. - * XXX: Suffix specific? - */ - fullname = Dir_FindFile (file, parseIncPath); - if (fullname == (char *)NULL) { - fullname = Dir_FindFile(file, dirSearchPath); - } - } - - if (fullname == (char *)NULL) { - /* - * Still haven't found the makefile. Look for it on the system - * path as a last resort. - */ - fullname = Dir_FindFile(file, sysIncPath); - } - - if (fullname == (char *) NULL) { - *cp = endc; - if (!silent) - Parse_Error (PARSE_FATAL, "Could not find %s", file); - return; - } - - free(file); - - /* - * Once we find the absolute path to the file, we get to save all the - * state from the current file before we can start reading this - * include file. The state is stored in an IFile structure which - * is placed on a list with other IFile structures. The list makes - * a very nice stack to track how we got here... - */ - oldFile = (IFile *) emalloc (sizeof (IFile)); - oldFile->fname = fname; - - oldFile->F = curFILE; - oldFile->p = curPTR; - oldFile->lineno = lineno; - - (void) Lst_AtFront (includes, (ClientData)oldFile); - - /* - * Once the previous state has been saved, we can get down to reading - * the new file. We set up the name of the file to be the absolute - * name of the include file so error messages refer to the right - * place. Naturally enough, we start reading at line number 0. - */ - fname = fullname; - lineno = 0; - - ParseSetParseFile(fname); - - curFILE = fopen (fullname, "r"); - curPTR = NULL; - if (curFILE == (FILE * ) NULL) { - if (!silent) - Parse_Error (PARSE_FATAL, "Cannot open %s", fullname); - /* - * Pop to previous file - */ - (void) ParseEOF(0); - } -} - - -/*- - *--------------------------------------------------------------------- - * ParseSetParseFile -- - * Set the .PARSEDIR and .PARSEFILE variables to the dirname and - * basename of the given filename - * - * Results: - * None - * - * Side Effects: - * The .PARSEDIR and .PARSEFILE variables are overwritten by the - * dirname and basename of the given filename. - *--------------------------------------------------------------------- - */ -static void -ParseSetParseFile(fname) - char *fname; -{ - char *slash; - - slash = strrchr(fname, '/'); - if (slash == 0) { - Var_Set(".PARSEDIR", ".", VAR_GLOBAL, 0); - Var_Set(".PARSEFILE", fname, VAR_GLOBAL, 0); - } else { - *slash = '\0'; - Var_Set(".PARSEDIR", fname, VAR_GLOBAL, 0); - Var_Set(".PARSEFILE", slash+1, VAR_GLOBAL, 0); - *slash = '/'; - } -} - - -/*- - *--------------------------------------------------------------------- - * Parse_FromString -- - * Start Parsing from the given string - * - * Results: - * None - * - * Side Effects: - * A structure is added to the includes Lst and readProc, lineno, - * fname and curFILE are altered for the new file - *--------------------------------------------------------------------- - */ -void -Parse_FromString(str) - char *str; -{ - IFile *oldFile; /* state associated with this file */ - - if (DEBUG(FOR)) - (void) fprintf(stderr, "%s\n----\n", str); - - oldFile = (IFile *) emalloc (sizeof (IFile)); - oldFile->lineno = lineno; - oldFile->fname = fname; - oldFile->F = curFILE; - oldFile->p = curPTR; - - (void) Lst_AtFront (includes, (ClientData)oldFile); - - curFILE = NULL; - curPTR = (PTR *) emalloc (sizeof (PTR)); - curPTR->str = curPTR->ptr = str; - lineno = 0; - fname = estrdup(fname); -} - - -#ifdef SYSVINCLUDE -/*- - *--------------------------------------------------------------------- - * ParseTraditionalInclude -- - * Push to another file. - * - * The input is the current line. The file name(s) are - * following the "include". - * - * Results: - * None - * - * Side Effects: - * A structure is added to the includes Lst and readProc, lineno, - * fname and curFILE are altered for the new file - *--------------------------------------------------------------------- - */ -static void -ParseTraditionalInclude (line) - char *line; -{ - char *fullname; /* full pathname of file */ - IFile *oldFile; /* state associated with current file */ - char *cp; /* current position in file spec */ - char *prefEnd; - int done = 0; - int silent = (line[0] != 'i') ? 1 : 0; - char *file = &line[silent + 7]; - char *cfname = fname; - size_t clineno = lineno; - - - /* - * Skip over whitespace - */ - while (isspace((unsigned char)*file)) - file++; - - if (*file == '\0') { - Parse_Error (PARSE_FATAL, - "Filename missing from \"include\""); - return; - } - - for (; !done; file = cp + 1) { - /* - * Skip to end of line or next whitespace - */ - for (cp = file; *cp && !isspace((unsigned char) *cp); cp++) - continue; - - if (*cp) - *cp = '\0'; - else - done = 1; - - /* - * Substitute for any variables in the file name before trying to - * find the thing. - */ - file = Var_Subst(NULL, file, VAR_CMD, FALSE); - - /* - * Now we know the file's name, we attempt to find the durn thing. - * A return of NULL indicates the file don't exist. - * - * Include files are first searched for relative to the including - * file's location. We don't want to cd there, of course, so we - * just tack on the old file's leading path components and call - * Dir_FindFile to see if we can locate the beast. - * XXX - this *does* search in the current directory, right? - */ - - prefEnd = strrchr(cfname, '/'); - if (prefEnd != NULL) { - char *newName; - - *prefEnd = '\0'; - newName = str_concat(cfname, file, STR_ADDSLASH); - fullname = Dir_FindFile(newName, parseIncPath); - if (fullname == NULL) { - fullname = Dir_FindFile(newName, dirSearchPath); - } - free (newName); - *prefEnd = '/'; - } else { - fullname = NULL; - } - - if (fullname == NULL) { - /* - * System makefile or makefile wasn't found in same directory as - * included makefile. Search for it first on the -I search path, - * then on the .PATH search path, if not found in a - * -I directory. XXX: Suffix specific? - */ - fullname = Dir_FindFile(file, parseIncPath); - if (fullname == NULL) { - fullname = Dir_FindFile(file, dirSearchPath); - } - } - - if (fullname == NULL) { - /* - * Still haven't found the makefile. Look for it on the system - * path as a last resort. - */ - fullname = Dir_FindFile(file, sysIncPath); - } - - if (fullname == NULL) { - if (!silent) - ParseErrorInternal(cfname, clineno, PARSE_FATAL, - "Could not find %s", file); - free(file); - continue; - } - - free(file); - - /* - * Once we find the absolute path to the file, we get to save all - * the state from the current file before we can start reading this - * include file. The state is stored in an IFile structure which - * is placed on a list with other IFile structures. The list makes - * a very nice stack to track how we got here... - */ - oldFile = (IFile *) emalloc(sizeof(IFile)); - oldFile->fname = fname; - - oldFile->F = curFILE; - oldFile->p = curPTR; - oldFile->lineno = lineno; - - (void) Lst_AtFront(includes, (ClientData)oldFile); - - /* - * Once the previous state has been saved, we can get down to - * reading the new file. We set up the name of the file to be the - * absolute name of the include file so error messages refer to the - * right place. Naturally enough, we start reading at line number 0. - */ - fname = fullname; - lineno = 0; - - curFILE = fopen(fullname, "r"); - curPTR = NULL; - if (curFILE == NULL) { - if (!silent) - ParseErrorInternal(cfname, clineno, PARSE_FATAL, - "Cannot open %s", fullname); - /* - * Pop to previous file - */ - (void) ParseEOF(1); - } - } -} -#endif - -/*- - *--------------------------------------------------------------------- - * ParseEOF -- - * Called when EOF is reached in the current file. If we were reading - * an include file, the includes stack is popped and things set up - * to go back to reading the previous file at the previous location. - * - * Results: - * CONTINUE if there's more to do. DONE if not. - * - * Side Effects: - * The old curFILE, is closed. The includes list is shortened. - * lineno, curFILE, and fname are changed if CONTINUE is returned. - *--------------------------------------------------------------------- - */ -static int -ParseEOF (opened) - int opened; -{ - IFile *ifile; /* the state on the top of the includes stack */ - - if (Lst_IsEmpty (includes)) { - Var_Delete(".PARSEDIR", VAR_GLOBAL); - Var_Delete(".PARSEFILE", VAR_GLOBAL); - return (DONE); - } - - ifile = (IFile *) Lst_DeQueue (includes); - free ((Address) fname); - fname = ifile->fname; - lineno = ifile->lineno; - if (opened && curFILE) - (void) fclose (curFILE); - if (curPTR) { - free((Address) curPTR->str); - free((Address) curPTR); - } - curFILE = ifile->F; - curPTR = ifile->p; - free ((Address)ifile); - - /* pop the PARSEDIR/PARSEFILE variables */ - ParseSetParseFile(fname); - return (CONTINUE); -} - -/*- - *--------------------------------------------------------------------- - * ParseReadc -- - * Read a character from the current file - * - * Results: - * The character that was read - * - * Side Effects: - *--------------------------------------------------------------------- - */ -static __inline int -ParseReadc() -{ - if (curFILE) - return fgetc(curFILE); - - if (curPTR && *curPTR->ptr) - return *curPTR->ptr++; - return EOF; -} - - -/*- - *--------------------------------------------------------------------- - * ParseUnreadc -- - * Put back a character to the current file - * - * Results: - * None. - * - * Side Effects: - *--------------------------------------------------------------------- - */ -static void -ParseUnreadc(c) - int c; -{ - if (curFILE) { - ungetc(c, curFILE); - return; - } - if (curPTR) { - *--(curPTR->ptr) = c; - return; - } -} - - -/* ParseSkipLine(): - * Grab the next line - */ -static char * -ParseSkipLine(skip) - int skip; /* Skip lines that don't start with . */ -{ - char *line; - int c, lastc, lineLength = 0; - Buffer buf; - - buf = Buf_Init(MAKE_BSIZE); - - do { - Buf_Discard(buf, lineLength); - lastc = '\0'; - - while (((c = ParseReadc()) != '\n' || lastc == '\\') - && c != EOF) { - if (c == '\n') { - Buf_ReplaceLastByte(buf, (Byte)' '); - lineno++; - - while ((c = ParseReadc()) == ' ' || c == '\t'); - - if (c == EOF) - break; - } - - Buf_AddByte(buf, (Byte)c); - lastc = c; - } - - if (c == EOF) { - Parse_Error(PARSE_FATAL, "Unclosed conditional/for loop"); - Buf_Destroy(buf, TRUE); - return((char *)NULL); - } - - lineno++; - Buf_AddByte(buf, (Byte)'\0'); - line = (char *)Buf_GetAll(buf, &lineLength); - } while (skip == 1 && line[0] != '.'); - - Buf_Destroy(buf, FALSE); - return line; -} - - -/*- - *--------------------------------------------------------------------- - * ParseReadLine -- - * Read an entire line from the input file. Called only by Parse_File. - * To facilitate escaped newlines and what have you, a character is - * buffered in 'lastc', which is '\0' when no characters have been - * read. When we break out of the loop, c holds the terminating - * character and lastc holds a character that should be added to - * the line (unless we don't read anything but a terminator). - * - * Results: - * A line w/o its newline - * - * Side Effects: - * Only those associated with reading a character - *--------------------------------------------------------------------- - */ -static char * -ParseReadLine () -{ - Buffer buf; /* Buffer for current line */ - register int c; /* the current character */ - register int lastc; /* The most-recent character */ - Boolean semiNL; /* treat semi-colons as newlines */ - Boolean ignDepOp; /* TRUE if should ignore dependency operators - * for the purposes of setting semiNL */ - Boolean ignComment; /* TRUE if should ignore comments (in a - * shell command */ - char *line; /* Result */ - char *ep; /* to strip trailing blanks */ - int lineLength; /* Length of result */ - - semiNL = FALSE; - ignDepOp = FALSE; - ignComment = FALSE; - - /* - * Handle special-characters at the beginning of the line. Either a - * leading tab (shell command) or pound-sign (possible conditional) - * forces us to ignore comments and dependency operators and treat - * semi-colons as semi-colons (by leaving semiNL FALSE). This also - * discards completely blank lines. - */ - for (;;) { - c = ParseReadc(); - - if (c == '\t') { - ignComment = ignDepOp = TRUE; - break; - } else if (c == '\n') { - lineno++; - } else if (c == '#') { - ParseUnreadc(c); - break; - } else { - /* - * Anything else breaks out without doing anything - */ - break; - } - } - - if (c != EOF) { - lastc = c; - buf = Buf_Init(MAKE_BSIZE); - - while (((c = ParseReadc ()) != '\n' || (lastc == '\\')) && - (c != EOF)) - { -test_char: - switch(c) { - case '\n': - /* - * Escaped newline: read characters until a non-space or an - * unescaped newline and replace them all by a single space. - * This is done by storing the space over the backslash and - * dropping through with the next nonspace. If it is a - * semi-colon and semiNL is TRUE, it will be recognized as a - * newline in the code below this... - */ - lineno++; - lastc = ' '; - while ((c = ParseReadc ()) == ' ' || c == '\t') { - continue; - } - if (c == EOF || c == '\n') { - goto line_read; - } else { - /* - * Check for comments, semiNL's, etc. -- easier than - * ParseUnreadc(c); continue; - */ - goto test_char; - } - /*NOTREACHED*/ - break; - - case ';': - /* - * Semi-colon: Need to see if it should be interpreted as a - * newline - */ - if (semiNL) { - /* - * To make sure the command that may be following this - * semi-colon begins with a tab, we push one back into the - * input stream. This will overwrite the semi-colon in the - * buffer. If there is no command following, this does no - * harm, since the newline remains in the buffer and the - * whole line is ignored. - */ - ParseUnreadc('\t'); - goto line_read; - } - break; - case '=': - if (!semiNL) { - /* - * Haven't seen a dependency operator before this, so this - * must be a variable assignment -- don't pay attention to - * dependency operators after this. - */ - ignDepOp = TRUE; - } else if (lastc == ':' || lastc == '!') { - /* - * Well, we've seen a dependency operator already, but it - * was the previous character, so this is really just an - * expanded variable assignment. Revert semi-colons to - * being just semi-colons again and ignore any more - * dependency operators. - * - * XXX: Note that a line like "foo : a:=b" will blow up, - * but who'd write a line like that anyway? - */ - ignDepOp = TRUE; semiNL = FALSE; - } - break; - case '#': - if (!ignComment) { - if ( -#if 0 - compatMake && -#endif - (lastc != '\\')) { - /* - * If the character is a hash mark and it isn't escaped - * (or we're being compatible), the thing is a comment. - * Skip to the end of the line. - */ - do { - c = ParseReadc(); - } while ((c != '\n') && (c != EOF)); - goto line_read; - } else { - /* - * Don't add the backslash. Just let the # get copied - * over. - */ - lastc = c; - continue; - } - } - break; - case ':': - case '!': - if (!ignDepOp && (c == ':' || c == '!')) { - /* - * A semi-colon is recognized as a newline only on - * dependency lines. Dependency lines are lines with a - * colon or an exclamation point. Ergo... - */ - semiNL = TRUE; - } - break; - } - /* - * Copy in the previous character and save this one in lastc. - */ - Buf_AddByte (buf, (Byte)lastc); - lastc = c; - - } - line_read: - lineno++; - - if (lastc != '\0') { - Buf_AddByte (buf, (Byte)lastc); - } - Buf_AddByte (buf, (Byte)'\0'); - line = (char *)Buf_GetAll (buf, &lineLength); - Buf_Destroy (buf, FALSE); - - /* - * Strip trailing blanks and tabs from the line. - * Do not strip a blank or tab that is preceded by - * a '\' - */ - ep = line; - while (*ep) - ++ep; - while (ep > line + 1 && (ep[-1] == ' ' || ep[-1] == '\t')) { - if (ep > line + 1 && ep[-2] == '\\') - break; - --ep; - } - *ep = 0; - - if (line[0] == '.') { - /* - * The line might be a conditional. Ask the conditional module - * about it and act accordingly - */ - switch (Cond_Eval (line)) { - case COND_SKIP: - /* - * Skip to next conditional that evaluates to COND_PARSE. - */ - do { - free (line); - line = ParseSkipLine(1); - } while (line && Cond_Eval(line) != COND_PARSE); - if (line == NULL) - break; - /*FALLTHRU*/ - case COND_PARSE: - free ((Address) line); - line = ParseReadLine(); - break; - case COND_INVALID: - if (For_Eval(line)) { - int ok; - free(line); - do { - /* - * Skip after the matching end - */ - line = ParseSkipLine(0); - if (line == NULL) { - Parse_Error (PARSE_FATAL, - "Unexpected end of file in for loop.\n"); - break; - } - ok = For_Eval(line); - free(line); - } - while (ok); - if (line != NULL) - For_Run(); - line = ParseReadLine(); - } - break; - } - } - return (line); - - } else { - /* - * Hit end-of-file, so return a NULL line to indicate this. - */ - return((char *)NULL); - } -} - -/*- - *----------------------------------------------------------------------- - * ParseFinishLine -- - * Handle the end of a dependency group. - * - * Results: - * Nothing. - * - * Side Effects: - * inLine set FALSE. 'targets' list destroyed. - * - *----------------------------------------------------------------------- - */ -static void -ParseFinishLine() -{ - if (inLine) { - Lst_ForEach(targets, Suff_EndTransform, (ClientData)NULL); - Lst_Destroy (targets, ParseHasCommands); - targets = NULL; - inLine = FALSE; - } -} - - -/*- - *--------------------------------------------------------------------- - * Parse_File -- - * Parse a file into its component parts, incorporating it into the - * current dependency graph. This is the main function and controls - * almost every other function in this module - * - * Results: - * None - * - * Side Effects: - * Loads. Nodes are added to the list of all targets, nodes and links - * are added to the dependency graph. etc. etc. etc. - *--------------------------------------------------------------------- - */ -void -Parse_File(name, stream) - char *name; /* the name of the file being read */ - FILE * stream; /* Stream open to makefile to parse */ -{ - register char *cp, /* pointer into the line */ - *line; /* the line we're working on */ - - inLine = FALSE; - fname = name; - curFILE = stream; - lineno = 0; - fatals = 0; - - ParseSetParseFile(fname); - - do { - while ((line = ParseReadLine ()) != NULL) { - if (*line == '.') { - /* - * Lines that begin with the special character are either - * include or undef directives. - */ - for (cp = line + 1; isspace ((unsigned char)*cp); cp++) { - continue; - } - if (strncmp(cp, "include", 7) == 0 || - ((cp[0] == 's' || cp[0] == '-') && - strncmp(&cp[1], "include", 7) == 0)) { - ParseDoInclude (cp); - goto nextLine; - } else if (strncmp(cp, "undef", 5) == 0) { - char *cp2; - for (cp += 5; isspace((unsigned char) *cp); cp++) { - continue; - } - - for (cp2 = cp; !isspace((unsigned char) *cp2) && - (*cp2 != '\0'); cp2++) { - continue; - } - - *cp2 = '\0'; - - Var_Delete(cp, VAR_GLOBAL); - goto nextLine; - } - } - if (*line == '#') { - /* If we're this far, the line must be a comment. */ - goto nextLine; - } - - if (*line == '\t') { - /* - * If a line starts with a tab, it can only hope to be - * a creation command. - */ -#ifndef POSIX - shellCommand: -#endif - for (cp = line + 1; isspace ((unsigned char)*cp); cp++) { - continue; - } - if (*cp) { - if (inLine) { - /* - * So long as it's not a blank line and we're actually - * in a dependency spec, add the command to the list of - * commands of all targets in the dependency spec - */ - Lst_ForEach (targets, ParseAddCmd, cp); -#ifdef CLEANUP - Lst_AtEnd(targCmds, (ClientData) line); -#endif - continue; - } else { - Parse_Error (PARSE_FATAL, - "Unassociated shell command \"%s\"", - cp); - } - } -#ifdef SYSVINCLUDE - } else if (((strncmp(line, "include", 7) == 0 && - isspace((unsigned char) line[7])) || - ((line[0] == 's' || line[0] == '-') && - strncmp(&line[1], "include", 7) == 0 && - isspace((unsigned char) line[8]))) && - strchr(line, ':') == NULL) { - /* - * It's an S3/S5-style "include". - */ - ParseTraditionalInclude (line); - goto nextLine; -#endif - } else if (Parse_IsVar (line)) { - ParseFinishLine(); - Parse_DoVar (line, VAR_GLOBAL); - } else { - /* - * We now know it's a dependency line so it needs to have all - * variables expanded before being parsed. Tell the variable - * module to complain if some variable is undefined... - * To make life easier on novices, if the line is indented we - * first make sure the line has a dependency operator in it. - * If it doesn't have an operator and we're in a dependency - * line's script, we assume it's actually a shell command - * and add it to the current list of targets. - */ -#ifndef POSIX - Boolean nonSpace = FALSE; -#endif - - cp = line; - if (isspace((unsigned char) line[0])) { - while ((*cp != '\0') && isspace((unsigned char) *cp)) { - cp++; - } - if (*cp == '\0') { - goto nextLine; - } -#ifndef POSIX - while ((*cp != ':') && (*cp != '!') && (*cp != '\0')) { - nonSpace = TRUE; - cp++; - } -#endif - } - -#ifndef POSIX - if (*cp == '\0') { - if (inLine) { - Parse_Error (PARSE_WARNING, - "Shell command needs a leading tab"); - goto shellCommand; - } else if (nonSpace) { - Parse_Error (PARSE_FATAL, "Missing operator"); - } - } else { -#endif - ParseFinishLine(); - - cp = Var_Subst (NULL, line, VAR_CMD, TRUE); - free (line); - line = cp; - - /* - * Need a non-circular list for the target nodes - */ - if (targets) - Lst_Destroy(targets, NOFREE); - - targets = Lst_Init (FALSE); - inLine = TRUE; - - ParseDoDependency (line); -#ifndef POSIX - } -#endif - } - - nextLine: - - free (line); - } - /* - * Reached EOF, but it may be just EOF of an include file... - */ - } while (ParseEOF(1) == CONTINUE); - - /* - * Make sure conditionals are clean - */ - Cond_End(); - - if (fatals) { - (void)fprintf(stderr, - "%s: Fatal errors encountered -- cannot continue\n", - progname); - PrintOnError(NULL); - exit (1); - } -} - -/*- - *--------------------------------------------------------------------- - * Parse_Init -- - * initialize the parsing module - * - * Results: - * none - * - * Side Effects: - * the parseIncPath list is initialized... - *--------------------------------------------------------------------- - */ -void -Parse_Init () -{ - mainNode = NILGNODE; - parseIncPath = Lst_Init (FALSE); - sysIncPath = Lst_Init (FALSE); - includes = Lst_Init (FALSE); -#ifdef CLEANUP - targCmds = Lst_Init (FALSE); -#endif -} - -void -Parse_End() -{ -#ifdef CLEANUP - Lst_Destroy(targCmds, (void (*) __P((ClientData))) free); - if (targets) - Lst_Destroy(targets, NOFREE); - Lst_Destroy(sysIncPath, Dir_Destroy); - Lst_Destroy(parseIncPath, Dir_Destroy); - Lst_Destroy(includes, NOFREE); /* Should be empty now */ -#endif -} - - -/*- - *----------------------------------------------------------------------- - * Parse_MainName -- - * Return a Lst of the main target to create for main()'s sake. If - * no such target exists, we Punt with an obnoxious error message. - * - * Results: - * A Lst of the single node to create. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -Lst -Parse_MainName() -{ - Lst mainList; /* result list */ - - mainList = Lst_Init (FALSE); - - if (mainNode == NILGNODE) { - Punt ("no target to make."); - /*NOTREACHED*/ - } else if (mainNode->type & OP_DOUBLEDEP) { - (void) Lst_AtEnd (mainList, (ClientData)mainNode); - Lst_Concat(mainList, mainNode->cohorts, LST_CONCNEW); - } - else - (void) Lst_AtEnd (mainList, (ClientData)mainNode); - return (mainList); -} - -/*- - *----------------------------------------------------------------------- - * ParseMark -- - * Add the filename and lineno to the GNode so that we remember - * where it was first defined. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static void -ParseMark(gn) - GNode *gn; -{ - gn->fname = strdup(fname); - gn->lineno = lineno; -} diff --git a/bootstrap/bmake/pathnames.h b/bootstrap/bmake/pathnames.h deleted file mode 100644 index b7fbc7012fb..00000000000 --- a/bootstrap/bmake/pathnames.h +++ /dev/null @@ -1,52 +0,0 @@ -/* $NetBSD: pathnames.h,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $ */ - -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: @(#)pathnames.h 5.2 (Berkeley) 6/1/90 - * $Id: pathnames.h,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $ - */ - -#if !defined(NO_PATH_OBJDIRPREFIX) && !defined(_PATH_OBJDIRPREFIX) -# define _PATH_OBJDIRPREFIX "/usr/obj" -#endif -#define _PATH_OBJDIR "obj" -#define _PATH_DEFSHELLDIR "/bin" -#define _PATH_DEFSYSMK "sys.mk" -#define _path_defsyspath "/usr/share/mk:/usr/local/share/mk:/opt/share/mk" -#ifndef _PATH_DEFSYSPATH -# ifdef _PATH_PREFIX_SYSPATH -# define _PATH_DEFSYSPATH _PATH_PREFIX_SYSPATH ":" _path_defsyspath -# else -# define _PATH_DEFSYSPATH _path_defsyspath -# endif -#endif diff --git a/bootstrap/bmake/ranlib.h b/bootstrap/bmake/ranlib.h deleted file mode 100644 index fdce83402be..00000000000 --- a/bootstrap/bmake/ranlib.h +++ /dev/null @@ -1,30 +0,0 @@ -/* @(#)ranlib.h 1.6 88/08/19 SMI; from UCB 4.1 83/05/03 */ -/* $Id: ranlib.h,v 1.3 2005/10/19 00:33:12 wiz Exp $ */ - -/* - * Structure of the __.SYMDEF table of contents for an archive. - * __.SYMDEF begins with a word giving the number of ranlib structures - * which immediately follow, and then continues with a string - * table consisting of a word giving the number of bytes of strings - * which follow and then the strings themselves. - * The ran_strx fields index the string table whose first byte is numbered 0. - */ - -#if !defined(IRIX) && !defined(__digital__) && !defined(__osf__) -#ifndef _ranlib_h -#define _ranlib_h - -/* #define RANLIBMAG "!\n__.SYMDEF" /* archive file name */ -#define RANLIBMAG "__.SYMDEF" /* archive file name */ -#define RANLIBSKEW 3 /* creation time offset */ - -struct ranlib { - union { - off_t ran_strx; /* string table index of */ - char *ran_name; /* symbol defined by */ - } ran_un; - off_t ran_off; /* library member at this offset */ -}; - -#endif /*!_ranlib_h*/ -#endif diff --git a/bootstrap/bmake/setenv.c b/bootstrap/bmake/setenv.c deleted file mode 100644 index 29e725a7559..00000000000 --- a/bootstrap/bmake/setenv.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 1987 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. 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#ifndef HAVE_SETENV - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)setenv.c 5.6 (Berkeley) 6/4/91";*/ -static char *rcsid = "$Id: setenv.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -/* - * __findenv -- - * Returns pointer to value associated with name, if any, else NULL. - * Sets offset to be the offset of the name/value combination in the - * environmental array, for use by setenv(3) and unsetenv(3). - * Explicitly removes '=' in argument name. - * - * This routine *should* be a static; don't use it. - */ -static char * -__findenv(name, offset) - register char *name; - int *offset; -{ - extern char **environ; - register int len; - register char **P, *C; - - for (C = name, len = 0; *C && *C != '='; ++C, ++len); - for (P = environ; *P; ++P) - if (!strncmp(*P, name, len)) - if (*(C = *P + len) == '=') { - *offset = P - environ; - return(++C); - } - return(NULL); -} - -/* - * setenv -- - * Set the value of the environmental variable "name" to be - * "value". If rewrite is set, replace any current value. - */ -setenv(name, value, rewrite) - register const char *name; - register const char *value; - int rewrite; -{ - extern char **environ; - static int alloced; /* if allocated space before */ - register char *C; - int l_value, offset; - char *__findenv(); - - if (*value == '=') /* no `=' in value */ - ++value; - l_value = strlen(value); - if ((C = __findenv(name, &offset))) { /* find if already exists */ - if (!rewrite) - return (0); - if (strlen(C) >= l_value) { /* old larger; copy over */ - while (*C++ = *value++); - return (0); - } - } else { /* create new slot */ - register int cnt; - register char **P; - - for (P = environ, cnt = 0; *P; ++P, ++cnt); - if (alloced) { /* just increase size */ - environ = (char **)realloc((char *)environ, - (size_t)(sizeof(char *) * (cnt + 2))); - if (!environ) - return (-1); - } - else { /* get new space */ - alloced = 1; /* copy old entries into it */ - P = (char **)malloc((size_t)(sizeof(char *) * - (cnt + 2))); - if (!P) - return (-1); - bcopy(environ, P, cnt * sizeof(char *)); - environ = P; - } - environ[cnt + 1] = NULL; - offset = cnt; - } - for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ - if (!(environ[offset] = /* name + `=' + value */ - malloc((size_t)((int)(C - name) + l_value + 2)))) - return (-1); - for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) - ; - for (*C++ = '='; *C++ = *value++; ) - ; - return (0); -} - -/* - * unsetenv(name) -- - * Delete environmental variable "name". - */ -void -unsetenv(name) - const char *name; -{ - extern char **environ; - register char **P; - int offset; - char *__findenv(); - - while (__findenv(name, &offset)) /* if set multiple times */ - for (P = &environ[offset];; ++P) - if (!(*P = *(P + 1))) - break; -} -#endif diff --git a/bootstrap/bmake/sigcompat.c b/bootstrap/bmake/sigcompat.c deleted file mode 100644 index 674b426e870..00000000000 --- a/bootstrap/bmake/sigcompat.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * NAME: - * sigcompat - BSD compat signals via POSIX - * - * SYNOPSIS: - * void (*signal(int "sig", void (*"handler")(int)))(int); - * int sigsetmask(int "mask"); - * int sigblock(int "mask"); - * int sigpause(int "mask"); - * int sigvec(int "signo", struct sigvec *"sv", struct sigvec *"osv"); - * - * DESCRIPTION: - * These implement the old BSD routines via the POSIX equivalents. - * This module can be used to provide the missing routines, or if - * 'FORCE_POSIX_SIGNALS' is defined, force use of these. - * - * Note that signal() is identical to my Signal() routine except - * for checking for recursion. Within libsig, signal() just - * calls Signal(). - * - * BUGS: - * This package assumes POSIX signal handling is available and - * NOT implemeneted using these routines. To be safe, we check - * for recursion and abort(3) if detected. - * - * Sadly, on some systems, sigset_t is an array, and we cannot - * test for this via #if sizeof(sigset_t) ..., so unless - * 'SIGSET_T_INT' is defined, we have to assume the worst and use - * memcpy(3) to handle args and return values. - * - * HISTORY: - * These routines originate from BSD, and are derrived from the - * NetBSD 1.1 implementation. They have been seriously hacked to - * make them portable to other systems. - * - * AUTHOR: - * Simon J. Gerraty - */ -/* - * @(#)Copyright (c) 1994, Simon J. Gerraty. - * - * This is free software. It comes with NO WARRANTY. - * Permission to use, modify and distribute this source code - * is granted subject to the following conditions. - * 1/ that the above copyright notice and this notice - * are preserved in all copies and that due credit be given - * to the author. - * 2/ that any changes to this code are clearly commented - * as such so that the author does not get blamed for bugs - * other than his own. - * - * Please send copies of changes and bug-fixes to: - * sjg@quick.com.au - */ - -/* - * Copyright (c) 1989 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. 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. - */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include - -#if defined(sun) && !(defined(__svr4__) || defined(__SVR4)) -# define NO_SIGCOMPAT -#endif - -#if !defined(NO_SIGCOMPAT) && (defined(HAVE_SIGACTION) || defined(SA_NOCLDSTOP)) - -#if defined(LIBC_SCCS) && !defined(lint) -/*static char *sccsid = "from: @(#)sigcompat.c 5.3 (Berkeley) 2/24/91";*/ -static char *rcsid = "$Id: sigcompat.c,v 1.2 2005/08/21 12:35:00 grant Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#undef signal -#include -#include -#include -#include -#include "assert.h" - -#ifndef ASSERT -# define ASSERT assert -#endif - -#ifdef NDEBUG -# define _DBUG(x) -#else -# define _DBUG(x) x -#endif - -#ifndef SA_RESTART -# define SA_RESTART 2 -#endif -#ifndef SV_INTERRUPT -# define SV_INTERRUPT SA_RESTART -#endif - -#ifndef MASK_T -# if defined(__hpux__) || defined(_HPUX_SOURCE) -# define MASK_T long -# else -# define MASK_T int -# endif -#endif -/* I just hate HPsUX */ -/* the documentation doesn't match the implementation */ -#if defined(_HPUX_SOURCE) -# define PAUSE_MASK_T int -#else -# define PAUSE_MASK_T MASK_T -#endif - -#ifndef SIG_HDLR -# define SIG_HDLR void -#endif - -#ifdef FORCE_POSIX_SIGNALS -#if !(defined(libsig) || defined(libsjg)) -/* - * This little block is almost identical to Signal(), - * and make this module standalone. - * We don't use it in libsig by default, as some apps might use both - * and expect _SignalFlags to be used by both. - */ - -#ifndef SIGNAL_FLAGS -# define SIGNAL_FLAGS 0 /* no auto-restart */ -#endif -int _signalFlags = SIGNAL_FLAGS; - -SIG_HDLR(*signal(sig, handler)) __P((int)) - int sig; - SIG_HDLR(*handler) __P((int)); -{ - _DBUG(static int depth_signal = 0); - struct sigaction act, oact; - int n; - - _DBUG(++depth_signal); - ASSERT(depth_signal < 2); - act.sa_handler = handler; - sigemptyset(&act.sa_mask); - act.sa_flags = _signalFlags; - n = sigaction(sig, &act, &oact); - _DBUG(--depth_signal); - if (n < 0) - return (SIG_ERR); - return (oact.sa_handler); -} -#else -SIG_HDLR(*signal(sig, handler)) __P((int)) - int sig; - SIG_HDLR(*handler) __P((int)); -{ - extern SIG_HDLR(*Signal __P((int, void (*) __P((int))))) __P((int)); - _DBUG(static int depth_signal = 0); - SIG_HDLR(*old) __P((int)); - - _DBUG(++depth_signal); - ASSERT(depth_signal < 2); - old = Signal(sig, handler); - _DBUG(--depth_signal); - return old; -} -#endif -#endif - -/* - * on some systems, sigset_t is an array... - * it would be nicer if we could do - * #if sizeof(sigset_t) > sizeof(MASK_T) - */ -#ifdef SIGSET_T_INT -# define ss2m(ss) (MASK_T) *(ss) -# define m2ss(ss, m) *ss = (sigset_t) *(m) -#else -static MASK_T -ss2m(ss) - sigset_t *ss; -{ - MASK_T ma[(sizeof(sigset_t) / sizeof(MASK_T)) + 1]; - - memcpy((char *) ma, (char *) ss, sizeof(sigset_t)); - return ma[0]; -} - -static void -m2ss(ss, m) - sigset_t *ss; - MASK_T *m; -{ - if (sizeof(sigset_t) > sizeof(MASK_T)) - memset((char *) ss, 0, sizeof(sigset_t)); - - memcpy((char *) ss, (char *) m, sizeof(MASK_T)); -} -#endif - -#if !defined(HAVE_SIGSETMASK) || defined(FORCE_POSIX_SIGNALS) -MASK_T -sigsetmask(mask) - MASK_T mask; -{ - _DBUG(static int depth_sigsetmask = 0); - sigset_t m, omask; - int n; - - _DBUG(++depth_sigsetmask); - ASSERT(depth_sigsetmask < 2); - m2ss(&m, &mask); - n = sigprocmask(SIG_SETMASK, (sigset_t *) & m, (sigset_t *) & omask); - _DBUG(--depth_sigsetmask); - if (n) - return (n); - - return ss2m(&omask); -} - - -MASK_T -sigblock(mask) - MASK_T mask; -{ - _DBUG(static int depth_sigblock = 0); - sigset_t m, omask; - int n; - - _DBUG(++depth_sigblock); - ASSERT(depth_sigblock < 2); - if (mask) - m2ss(&m, &mask); - n = sigprocmask(SIG_BLOCK, (sigset_t *) ((mask) ? &m : 0), (sigset_t *) & omask); - _DBUG(--depth_sigblock); - if (n) - return (n); - return ss2m(&omask); -} - -#undef sigpause /* Linux at least */ - -PAUSE_MASK_T -sigpause(mask) - PAUSE_MASK_T mask; -{ - _DBUG(static int depth_sigpause = 0); - sigset_t m; - PAUSE_MASK_T n; - - _DBUG(++depth_sigpause); - ASSERT(depth_sigpause < 2); - m2ss(&m, &mask); - n = sigsuspend(&m); - _DBUG(--depth_sigpause); - return n; -} -#endif - -#if defined(HAVE_SIGVEC) && defined(FORCE_POSIX_SIGNALS) -int -sigvec(signo, sv, osv) - int signo; - struct sigvec *sv, *osv; -{ - _DBUG(static int depth_sigvec = 0); - int ret; - struct sigvec nsv; - - _DBUG(++depth_sigvec); - ASSERT(depth_sigvec < 2); - if (sv) { - nsv = *sv; - nsv.sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */ - } - ret = sigaction(signo, sv ? (struct sigaction *) & nsv : NULL, - (struct sigaction *) osv); - _DBUG(--depth_sigvec); - if (ret == 0 && osv) - osv->sv_flags ^= SV_INTERRUPT; /* !SA_INTERRUPT */ - return (ret); -} -#endif - -#ifdef MAIN -# ifndef sigmask -# define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1))) -# endif - -int -main(argc, argv) - int argc; - char **argv; -{ - MASK_T old = 0; - - printf("expect: old=0,old=2\n"); - fflush(stdout); - signal(SIGQUIT, SIG_IGN); - old = sigblock(sigmask(SIGINT)); - printf("old=%d,", old); - old = sigsetmask(sigmask(SIGALRM)); - printf("old=%d\n", old); -} -#endif -#endif diff --git a/bootstrap/bmake/sprite.h b/bootstrap/bmake/sprite.h deleted file mode 100644 index afd06331974..00000000000 --- a/bootstrap/bmake/sprite.h +++ /dev/null @@ -1,113 +0,0 @@ -/* $NetBSD: sprite.h,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $ */ - -/* - * 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. - * - * from: @(#)sprite.h 8.1 (Berkeley) 6/6/93 - */ - -/* - * sprite.h -- - * - * Common constants and type declarations for Sprite. - */ - -#ifndef _SPRITE -#define _SPRITE - - -/* - * A boolean type is defined as an integer, not an enum. This allows a - * boolean argument to be an expression that isn't strictly 0 or 1 valued. - */ - -typedef int Boolean; -#ifndef TRUE -#define TRUE 1 -#endif /* TRUE */ -#ifndef FALSE -#define FALSE 0 -#endif /* FALSE */ - -/* - * Functions that must return a status can return a ReturnStatus to - * indicate success or type of failure. - */ - -typedef int ReturnStatus; - -/* - * The following statuses overlap with the first 2 generic statuses - * defined in status.h: - * - * SUCCESS There was no error. - * FAILURE There was a general error. - */ - -#define SUCCESS 0x00000000 -#define FAILURE 0x00000001 - - -/* - * A nil pointer must be something that will cause an exception if - * referenced. There are two nils: the kernels nil and the nil used - * by user processes. - */ - -#define NIL ~0 -#define USER_NIL 0 -#ifndef NULL -#define NULL 0 -#endif /* NULL */ - -/* - * An address is just a pointer in C. It is defined as a character pointer - * so that address arithmetic will work properly, a byte at a time. - */ - -typedef char *Address; - -/* - * ClientData is an uninterpreted word. It is defined as an int so that - * kdbx will not interpret client data as a string. Unlike an "Address", - * client data will generally not be used in arithmetic. - * But we don't have kdbx anymore so we define it as void (christos) - */ - -typedef void *ClientData; - -#endif /* _SPRITE */ diff --git a/bootstrap/bmake/str.c b/bootstrap/bmake/str.c deleted file mode 100644 index dd053ecee95..00000000000 --- a/bootstrap/bmake/str.c +++ /dev/null @@ -1,472 +0,0 @@ -/* $NetBSD: str.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $ */ - -/*- - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: str.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; -#else -__RCSID("$NetBSD: str.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: str.c,v 1.1.1.1 2004/03/11 13:04:12 grant Exp $"); -#endif - -#include "make.h" - -/*- - * str_concat -- - * concatenate the two strings, inserting a space or slash between them, - * freeing them if requested. - * - * returns -- - * the resulting string in allocated space. - */ -char * -str_concat(s1, s2, flags) - char *s1, *s2; - int flags; -{ - register int len1, len2; - register char *result; - - /* get the length of both strings */ - len1 = strlen(s1); - len2 = strlen(s2); - - /* allocate length plus separator plus EOS */ - result = emalloc((u_int)(len1 + len2 + 2)); - - /* copy first string into place */ - memcpy(result, s1, len1); - - /* add separator character */ - if (flags & STR_ADDSPACE) { - result[len1] = ' '; - ++len1; - } else if (flags & STR_ADDSLASH) { - result[len1] = '/'; - ++len1; - } - - /* copy second string plus EOS into place */ - memcpy(result + len1, s2, len2 + 1); - - /* free original strings */ - if (flags & STR_DOFREE) { - (void)free(s1); - (void)free(s2); - } - return(result); -} - -/*- - * brk_string -- - * Fracture a string into an array of words (as delineated by tabs or - * spaces) taking quotation marks into account. Leading tabs/spaces - * are ignored. - * - * returns -- - * Pointer to the array of pointers to the words. To make life easier, - * the first word is always the value of the .MAKE variable. - */ -char ** -brk_string(str, store_argc, expand, buffer) - register char *str; - int *store_argc; - Boolean expand; - char **buffer; -{ - register int argc, ch; - register char inquote, *p, *start, *t; - int len; - int argmax = 50, curlen = 0; - char **argv = (char **)emalloc((argmax + 1) * sizeof(char *)); - - /* skip leading space chars. */ - for (; *str == ' ' || *str == '\t'; ++str) - continue; - - /* allocate room for a copy of the string */ - if ((len = strlen(str) + 1) > curlen) - *buffer = emalloc(curlen = len); - - /* - * copy the string; at the same time, parse backslashes, - * quotes and build the argument list. - */ - argc = 0; - inquote = '\0'; - for (p = str, start = t = *buffer;; ++p) { - switch(ch = *p) { - case '"': - case '\'': - if (inquote) { - if (inquote == ch) - inquote = '\0'; - else - break; - } - else { - inquote = (char) ch; - /* Don't miss "" or '' */ - if (start == NULL && p[1] == inquote) { - start = t + 1; - break; - } - } - if (!expand) { - if (!start) - start = t; - *t++ = ch; - } - continue; - case ' ': - case '\t': - case '\n': - if (inquote) - break; - if (!start) - continue; - /* FALLTHROUGH */ - case '\0': - /* - * end of a token -- make sure there's enough argv - * space and save off a pointer. - */ - if (!start) - goto done; - - *t++ = '\0'; - if (argc == argmax) { - argmax *= 2; /* ramp up fast */ - argv = (char **)erealloc(argv, - (argmax + 1) * sizeof(char *)); - } - argv[argc++] = start; - start = (char *)NULL; - if (ch == '\n' || ch == '\0') - goto done; - continue; - case '\\': - if (!expand) { - if (!start) - start = t; - *t++ = '\\'; - ch = *++p; - break; - } - - switch (ch = *++p) { - case '\0': - case '\n': - /* hmmm; fix it up as best we can */ - ch = '\\'; - --p; - break; - case 'b': - ch = '\b'; - break; - case 'f': - ch = '\f'; - break; - case 'n': - ch = '\n'; - break; - case 'r': - ch = '\r'; - break; - case 't': - ch = '\t'; - break; - } - break; - } - if (!start) - start = t; - *t++ = (char) ch; - } -done: argv[argc] = (char *)NULL; - *store_argc = argc; - return(argv); -} - -/* - * Str_FindSubstring -- See if a string contains a particular substring. - * - * Results: If string contains substring, the return value is the location of - * the first matching instance of substring in string. If string doesn't - * contain substring, the return value is NULL. Matching is done on an exact - * character-for-character basis with no wildcards or special characters. - * - * Side effects: None. - */ -char * -Str_FindSubstring(string, substring) - register char *string; /* String to search. */ - char *substring; /* Substring to find in string */ -{ - register char *a, *b; - - /* - * First scan quickly through the two strings looking for a single- - * character match. When it's found, then compare the rest of the - * substring. - */ - - for (b = substring; *string != 0; string += 1) { - if (*string != *b) - continue; - a = string; - for (;;) { - if (*b == 0) - return(string); - if (*a++ != *b++) - break; - } - b = substring; - } - return((char *) NULL); -} - -/* - * Str_Match -- - * - * See if a particular string matches a particular pattern. - * - * Results: Non-zero is returned if string matches pattern, 0 otherwise. The - * matching operation permits the following special characters in the - * pattern: *?\[] (see the man page for details on what these mean). - * - * Side effects: None. - */ -int -Str_Match(string, pattern) - register char *string; /* String */ - register char *pattern; /* 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. - * - * Side Effects: - * None - * - *----------------------------------------------------------------------- - */ -char * -Str_SYSVMatch(word, pattern, len) - char *word; /* Word to examine */ - char *pattern; /* Pattern to examine against */ - int *len; /* Number of characters to substitute */ -{ - char *p = pattern; - char *w = word; - char *m; - - 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. - * - * Results: - * None - * - * Side Effects: - * Places result on buf - * - *----------------------------------------------------------------------- - */ -void -Str_SYSVSubst(buf, pat, src, len) - Buffer buf; - char *pat; - char *src; - int len; -{ - char *m; - - if ((m = strchr(pat, '%')) != NULL) { - /* Copy the prefix */ - Buf_AddBytes(buf, m - pat, (Byte *) pat); - /* skip the % */ - pat = m + 1; - } - - /* Copy the pattern */ - Buf_AddBytes(buf, len, (Byte *) src); - - /* append the rest */ - Buf_AddBytes(buf, strlen(pat), (Byte *) pat); -} diff --git a/bootstrap/bmake/suff.c b/bootstrap/bmake/suff.c deleted file mode 100644 index 21f655540e0..00000000000 --- a/bootstrap/bmake/suff.c +++ /dev/null @@ -1,2544 +0,0 @@ -/* $NetBSD: suff.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $ */ - -/* - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: suff.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)suff.c 8.4 (Berkeley) 3/21/94"; -#else -__RCSID("$NetBSD: suff.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * suff.c -- - * Functions to maintain suffix lists and find implicit dependents - * using suffix transformation rules - * - * Interface: - * Suff_Init Initialize all things to do with suffixes. - * - * Suff_End Cleanup the module - * - * Suff_DoPaths This function is used to make life easier - * when searching for a file according to its - * suffix. It takes the global search path, - * as defined using the .PATH: target, and appends - * its directories to the path of each of the - * defined suffixes, as specified using - * .PATH: targets. In addition, all - * directories given for suffixes labeled as - * include files or libraries, using the .INCLUDES - * or .LIBS targets, are played with using - * Dir_MakeFlags to create the .INCLUDES and - * .LIBS global variables. - * - * Suff_ClearSuffixes Clear out all the suffixes and defined - * transformations. - * - * Suff_IsTransform Return TRUE if the passed string is the lhs - * of a transformation rule. - * - * Suff_AddSuffix Add the passed string as another known suffix. - * - * Suff_GetPath Return the search path for the given suffix. - * - * Suff_AddInclude Mark the given suffix as denoting an include - * file. - * - * Suff_AddLib Mark the given suffix as denoting a library. - * - * Suff_AddTransform Add another transformation to the suffix - * graph. Returns GNode suitable for framing, I - * mean, tacking commands, attributes, etc. on. - * - * Suff_SetNull Define the suffix to consider the suffix of - * any file that doesn't have a known one. - * - * Suff_FindDeps Find implicit sources for and the location of - * a target based on its suffix. Returns the - * bottom-most node added to the graph or NILGNODE - * if the target had no implicit sources. - */ - -#include -#include "make.h" -#include "hash.h" -#include "dir.h" - -static Lst sufflist; /* Lst of suffixes */ -#ifdef CLEANUP -static Lst suffClean; /* Lst of suffixes to be cleaned */ -#endif -static Lst srclist; /* Lst of sources */ -static Lst transforms; /* Lst of transformation rules */ - -static int sNum = 0; /* Counter for assigning suffix numbers */ - -/* - * Structure describing an individual suffix. - */ -typedef struct _Suff { - char *name; /* The suffix itself */ - int nameLen; /* Length of the suffix */ - short flags; /* Type of suffix */ -#define SUFF_INCLUDE 0x01 /* One which is #include'd */ -#define SUFF_LIBRARY 0x02 /* One which contains a library */ -#define SUFF_NULL 0x04 /* The empty suffix */ - Lst searchPath; /* The path along which files of this suffix - * may be found */ - int sNum; /* The suffix number */ - int refCount; /* Reference count of list membership */ - Lst parents; /* Suffixes we have a transformation to */ - Lst children; /* Suffixes we have a transformation from */ - Lst ref; /* List of lists this suffix is referenced */ -} Suff; - -/* - * for SuffSuffIsSuffix - */ -typedef struct { - char *ename; /* The end of the name */ - int len; /* Length of the name */ -} SuffixCmpData; - -/* - * Structure used in the search for implied sources. - */ -typedef struct _Src { - char *file; /* The file to look for */ - char *pref; /* Prefix from which file was formed */ - Suff *suff; /* The suffix on the file */ - struct _Src *parent; /* The Src for which this is a source */ - GNode *node; /* The node describing the file */ - int children; /* Count of existing children (so we don't free - * this thing too early or never nuke it) */ -#ifdef DEBUG_SRC - Lst cp; /* Debug; children list */ -#endif -} Src; - -/* - * A structure for passing more than one argument to the Lst-library-invoked - * function... - */ -typedef struct { - Lst l; - Src *s; -} LstSrc; - -typedef struct { - GNode **gn; - Suff *s; - Boolean r; -} GNodeSuff; - -static Suff *suffNull; /* The NULL suffix for this run */ -static Suff *emptySuff; /* The empty suffix required for POSIX - * single-suffix transformation rules */ - - -static char *SuffStrIsPrefix __P((char *, char *)); -static char *SuffSuffIsSuffix __P((Suff *, SuffixCmpData *)); -static int SuffSuffIsSuffixP __P((ClientData, ClientData)); -static int SuffSuffHasNameP __P((ClientData, ClientData)); -static int SuffSuffIsPrefix __P((ClientData, ClientData)); -static int SuffGNHasNameP __P((ClientData, ClientData)); -static void SuffUnRef __P((ClientData, ClientData)); -static void SuffFree __P((ClientData)); -static void SuffInsert __P((Lst, Suff *)); -static void SuffRemove __P((Lst, Suff *)); -static Boolean SuffParseTransform __P((char *, Suff **, Suff **)); -static int SuffRebuildGraph __P((ClientData, ClientData)); -static int SuffScanTargets __P((ClientData, ClientData)); -static int SuffAddSrc __P((ClientData, ClientData)); -static int SuffRemoveSrc __P((Lst)); -static void SuffAddLevel __P((Lst, Src *)); -static Src *SuffFindThem __P((Lst, Lst)); -static Src *SuffFindCmds __P((Src *, Lst)); -static int SuffExpandChildren __P((LstNode, GNode *)); -static Boolean SuffApplyTransform __P((GNode *, GNode *, Suff *, Suff *)); -static void SuffFindDeps __P((GNode *, Lst)); -static void SuffFindArchiveDeps __P((GNode *, Lst)); -static void SuffFindNormalDeps __P((GNode *, Lst)); -static int SuffPrintName __P((ClientData, ClientData)); -static int SuffPrintSuff __P((ClientData, ClientData)); -static int SuffPrintTrans __P((ClientData, ClientData)); - - /*************** Lst Predicates ****************/ -/*- - *----------------------------------------------------------------------- - * SuffStrIsPrefix -- - * See if pref is a prefix of str. - * - * Results: - * NULL if it ain't, pointer to character in str after prefix if so - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static char * -SuffStrIsPrefix (pref, str) - register char *pref; /* possible prefix */ - register char *str; /* string to check */ -{ - while (*str && *pref == *str) { - pref++; - str++; - } - - return (*pref ? NULL : str); -} - -/*- - *----------------------------------------------------------------------- - * SuffSuffIsSuffix -- - * See if suff is a suffix of str. sd->ename should point to THE END - * of the string to check. (THE END == the null byte) - * - * Results: - * NULL if it ain't, pointer to character in str before suffix if - * it is. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static char * -SuffSuffIsSuffix (s, sd) - register Suff *s; /* possible suffix */ - SuffixCmpData *sd; /* string to examine */ -{ - register char *p1; /* Pointer into suffix name */ - register char *p2; /* Pointer into string being examined */ - - if (sd->len < s->nameLen) - return NULL; /* this string is shorter than the suffix */ - - p1 = s->name + s->nameLen; - p2 = sd->ename; - - while (p1 >= s->name && *p1 == *p2) { - p1--; - p2--; - } - - return (p1 == s->name - 1 ? p2 : NULL); -} - -/*- - *----------------------------------------------------------------------- - * SuffSuffIsSuffixP -- - * Predicate form of SuffSuffIsSuffix. Passed as the callback function - * to Lst_Find. - * - * Results: - * 0 if the suffix is the one desired, non-zero if not. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static int -SuffSuffIsSuffixP(s, sd) - ClientData s; - ClientData sd; -{ - return(!SuffSuffIsSuffix((Suff *) s, (SuffixCmpData *) sd)); -} - -/*- - *----------------------------------------------------------------------- - * SuffSuffHasNameP -- - * Callback procedure for finding a suffix based on its name. Used by - * Suff_GetPath. - * - * Results: - * 0 if the suffix is of the given name. non-zero otherwise. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -SuffSuffHasNameP (s, sname) - ClientData s; /* Suffix to check */ - ClientData sname; /* Desired name */ -{ - return (strcmp ((char *) sname, ((Suff *) s)->name)); -} - -/*- - *----------------------------------------------------------------------- - * SuffSuffIsPrefix -- - * See if the suffix described by s is a prefix of the string. Care - * must be taken when using this to search for transformations and - * what-not, since there could well be two suffixes, one of which - * is a prefix of the other... - * - * Results: - * 0 if s is a prefix of str. non-zero otherwise - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -SuffSuffIsPrefix (s, str) - ClientData s; /* suffix to compare */ - ClientData str; /* string to examine */ -{ - return (SuffStrIsPrefix (((Suff *) s)->name, (char *) str) == NULL ? 1 : 0); -} - -/*- - *----------------------------------------------------------------------- - * SuffGNHasNameP -- - * See if the graph node has the desired name - * - * Results: - * 0 if it does. non-zero if it doesn't - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static int -SuffGNHasNameP (gn, name) - ClientData gn; /* current node we're looking at */ - ClientData name; /* name we're looking for */ -{ - return (strcmp ((char *) name, ((GNode *) gn)->name)); -} - - /*********** Maintenance Functions ************/ - -static void -SuffUnRef(lp, sp) - ClientData lp; - ClientData sp; -{ - Lst l = (Lst) lp; - - LstNode ln = Lst_Member(l, sp); - if (ln != NILLNODE) { - Lst_Remove(l, ln); - ((Suff *) sp)->refCount--; - } -} - -/*- - *----------------------------------------------------------------------- - * SuffFree -- - * Free up all memory associated with the given suffix structure. - * - * Results: - * none - * - * Side Effects: - * the suffix entry is detroyed - *----------------------------------------------------------------------- - */ -static void -SuffFree (sp) - ClientData sp; -{ - Suff *s = (Suff *) sp; - - if (s == suffNull) - suffNull = NULL; - - if (s == emptySuff) - emptySuff = NULL; - -#ifdef notdef - /* We don't delete suffixes in order, so we cannot use this */ - if (s->refCount) - Punt("Internal error deleting suffix `%s' with refcount = %d", s->name, - s->refCount); -#endif - - Lst_Destroy (s->ref, NOFREE); - Lst_Destroy (s->children, NOFREE); - Lst_Destroy (s->parents, NOFREE); - Lst_Destroy (s->searchPath, Dir_Destroy); - - free ((Address)s->name); - free ((Address)s); -} - -/*- - *----------------------------------------------------------------------- - * SuffRemove -- - * Remove the suffix into the list - * - * Results: - * None - * - * Side Effects: - * The reference count for the suffix is decremented and the - * suffix is possibly freed - *----------------------------------------------------------------------- - */ -static void -SuffRemove(l, s) - Lst l; - Suff *s; -{ - SuffUnRef((ClientData) l, (ClientData) s); - if (s->refCount == 0) { - SuffUnRef ((ClientData) sufflist, (ClientData) s); - SuffFree((ClientData) s); - } -} - -/*- - *----------------------------------------------------------------------- - * SuffInsert -- - * Insert the suffix into the list keeping the list ordered by suffix - * numbers. - * - * Results: - * None - * - * Side Effects: - * The reference count of the suffix is incremented - *----------------------------------------------------------------------- - */ -static void -SuffInsert (l, s) - Lst l; /* the list where in s should be inserted */ - Suff *s; /* the suffix to insert */ -{ - LstNode ln; /* current element in l we're examining */ - Suff *s2 = NULL; /* the suffix descriptor in this element */ - - if (Lst_Open (l) == FAILURE) { - return; - } - while ((ln = Lst_Next (l)) != NILLNODE) { - s2 = (Suff *) Lst_Datum (ln); - if (s2->sNum >= s->sNum) { - break; - } - } - - Lst_Close (l); - if (DEBUG(SUFF)) { - printf("inserting %s(%d)...", s->name, s->sNum); - } - if (ln == NILLNODE) { - if (DEBUG(SUFF)) { - printf("at end of list\n"); - } - (void)Lst_AtEnd (l, (ClientData)s); - s->refCount++; - (void)Lst_AtEnd(s->ref, (ClientData) l); - } else if (s2->sNum != s->sNum) { - if (DEBUG(SUFF)) { - printf("before %s(%d)\n", s2->name, s2->sNum); - } - (void)Lst_Insert (l, ln, (ClientData)s); - s->refCount++; - (void)Lst_AtEnd(s->ref, (ClientData) l); - } else if (DEBUG(SUFF)) { - printf("already there\n"); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_ClearSuffixes -- - * This is gross. Nuke the list of suffixes but keep all transformation - * rules around. The transformation graph is destroyed in this process, - * but we leave the list of rules so when a new graph is formed the rules - * will remain. - * This function is called from the parse module when a - * .SUFFIXES:\n line is encountered. - * - * Results: - * none - * - * Side Effects: - * the sufflist and its graph nodes are destroyed - *----------------------------------------------------------------------- - */ -void -Suff_ClearSuffixes () -{ -#ifdef CLEANUP - Lst_Concat (suffClean, sufflist, LST_CONCLINK); -#endif - sufflist = Lst_Init(FALSE); - sNum = 0; - suffNull = emptySuff; -} - -/*- - *----------------------------------------------------------------------- - * SuffParseTransform -- - * Parse a transformation string to find its two component suffixes. - * - * Results: - * TRUE if the string is a valid transformation and FALSE otherwise. - * - * Side Effects: - * The passed pointers are overwritten. - * - *----------------------------------------------------------------------- - */ -static Boolean -SuffParseTransform(str, srcPtr, targPtr) - char *str; /* String being parsed */ - Suff **srcPtr; /* Place to store source of trans. */ - Suff **targPtr; /* Place to store target of trans. */ -{ - register LstNode srcLn; /* element in suffix list of trans source*/ - register Suff *src; /* Source of transformation */ - register LstNode targLn; /* element in suffix list of trans target*/ - register char *str2; /* Extra pointer (maybe target suffix) */ - LstNode singleLn; /* element in suffix list of any suffix - * that exactly matches str */ - Suff *single = NULL;/* Source of possible transformation to - * null suffix */ - - srcLn = NILLNODE; - singleLn = NILLNODE; - - /* - * Loop looking first for a suffix that matches the start of the - * string and then for one that exactly matches the rest of it. If - * we can find two that meet these criteria, we've successfully - * parsed the string. - */ - for (;;) { - if (srcLn == NILLNODE) { - srcLn = Lst_Find(sufflist, (ClientData)str, SuffSuffIsPrefix); - } else { - srcLn = Lst_FindFrom (sufflist, Lst_Succ(srcLn), (ClientData)str, - SuffSuffIsPrefix); - } - if (srcLn == NILLNODE) { - /* - * Ran out of source suffixes -- no such rule - */ - if (singleLn != NILLNODE) { - /* - * Not so fast Mr. Smith! There was a suffix that encompassed - * the entire string, so we assume it was a transformation - * to the null suffix (thank you POSIX). We still prefer to - * find a double rule over a singleton, hence we leave this - * check until the end. - * - * XXX: Use emptySuff over suffNull? - */ - *srcPtr = single; - *targPtr = suffNull; - return(TRUE); - } - return (FALSE); - } - src = (Suff *) Lst_Datum (srcLn); - str2 = str + src->nameLen; - if (*str2 == '\0') { - single = src; - singleLn = srcLn; - } else { - targLn = Lst_Find(sufflist, (ClientData)str2, SuffSuffHasNameP); - if (targLn != NILLNODE) { - *srcPtr = src; - *targPtr = (Suff *)Lst_Datum(targLn); - return (TRUE); - } - } - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_IsTransform -- - * Return TRUE if the given string is a transformation rule - * - * - * Results: - * TRUE if the string is a concatenation of two known suffixes. - * FALSE otherwise - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Boolean -Suff_IsTransform (str) - char *str; /* string to check */ -{ - Suff *src, *targ; - - return (SuffParseTransform(str, &src, &targ)); -} - -/*- - *----------------------------------------------------------------------- - * Suff_AddTransform -- - * Add the transformation rule described by the line to the - * list of rules and place the transformation itself in the graph - * - * Results: - * The node created for the transformation in the transforms list - * - * Side Effects: - * The node is placed on the end of the transforms Lst and links are - * made between the two suffixes mentioned in the target name - *----------------------------------------------------------------------- - */ -GNode * -Suff_AddTransform (line) - char *line; /* name of transformation to add */ -{ - GNode *gn; /* GNode of transformation rule */ - Suff *s, /* source suffix */ - *t; /* target suffix */ - LstNode ln; /* Node for existing transformation */ - - ln = Lst_Find (transforms, (ClientData)line, SuffGNHasNameP); - if (ln == NILLNODE) { - /* - * Make a new graph node for the transformation. It will be filled in - * by the Parse module. - */ - gn = Targ_NewGN (line); - (void)Lst_AtEnd (transforms, (ClientData)gn); - } else { - /* - * New specification for transformation rule. Just nuke the old list - * of commands so they can be filled in again... We don't actually - * free the commands themselves, because a given command can be - * attached to several different transformations. - */ - gn = (GNode *) Lst_Datum (ln); - Lst_Destroy (gn->commands, NOFREE); - Lst_Destroy (gn->children, NOFREE); - gn->commands = Lst_Init (FALSE); - gn->children = Lst_Init (FALSE); - } - - gn->type = OP_TRANSFORM; - - (void)SuffParseTransform(line, &s, &t); - - /* - * link the two together in the proper relationship and order - */ - if (DEBUG(SUFF)) { - printf("defining transformation from `%s' to `%s'\n", - s->name, t->name); - } - SuffInsert (t->children, s); - SuffInsert (s->parents, t); - - return (gn); -} - -/*- - *----------------------------------------------------------------------- - * Suff_EndTransform -- - * Handle the finish of a transformation definition, removing the - * transformation from the graph if it has neither commands nor - * sources. This is a callback procedure for the Parse module via - * Lst_ForEach - * - * Results: - * === 0 - * - * Side Effects: - * If the node has no commands or children, the children and parents - * lists of the affected suffices are altered. - * - *----------------------------------------------------------------------- - */ -int -Suff_EndTransform(gnp, dummy) - ClientData gnp; /* Node for transformation */ - ClientData dummy; /* Node for transformation */ -{ - GNode *gn = (GNode *) gnp; - - if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts)) - gn = (GNode *) Lst_Datum (Lst_Last (gn->cohorts)); - if ((gn->type & OP_TRANSFORM) && Lst_IsEmpty(gn->commands) && - Lst_IsEmpty(gn->children)) - { - Suff *s, *t; - - /* - * SuffParseTransform() may fail for special rules which are not - * actual transformation rules. (e.g. .DEFAULT) - */ - if (SuffParseTransform(gn->name, &s, &t)) { - Lst p; - - if (DEBUG(SUFF)) { - printf("deleting transformation from `%s' to `%s'\n", - s->name, t->name); - } - - /* - * Store s->parents because s could be deleted in SuffRemove - */ - p = s->parents; - - /* - * Remove the source from the target's children list. We check for a - * nil return to handle a beanhead saying something like - * .c.o .c.o: - * - * We'll be called twice when the next target is seen, but .c and .o - * are only linked once... - */ - SuffRemove(t->children, s); - - /* - * Remove the target from the source's parents list - */ - SuffRemove(p, t); - } - } else if ((gn->type & OP_TRANSFORM) && DEBUG(SUFF)) { - printf("transformation %s complete\n", gn->name); - } - - return(dummy ? 0 : 0); -} - -/*- - *----------------------------------------------------------------------- - * SuffRebuildGraph -- - * Called from Suff_AddSuffix via Lst_ForEach to search through the - * list of existing transformation rules and rebuild the transformation - * graph when it has been destroyed by Suff_ClearSuffixes. If the - * given rule is a transformation involving this suffix and another, - * existing suffix, the proper relationship is established between - * the two. - * - * Results: - * Always 0. - * - * Side Effects: - * The appropriate links will be made between this suffix and - * others if transformation rules exist for it. - * - *----------------------------------------------------------------------- - */ -static int -SuffRebuildGraph(transformp, sp) - ClientData transformp; /* Transformation to test */ - ClientData sp; /* Suffix to rebuild */ -{ - GNode *transform = (GNode *) transformp; - Suff *s = (Suff *) sp; - char *cp; - LstNode ln; - Suff *s2; - SuffixCmpData sd; - - /* - * First see if it is a transformation from this suffix. - */ - cp = SuffStrIsPrefix(s->name, transform->name); - if (cp != (char *)NULL) { - ln = Lst_Find(sufflist, (ClientData)cp, SuffSuffHasNameP); - if (ln != NILLNODE) { - /* - * Found target. Link in and return, since it can't be anything - * else. - */ - s2 = (Suff *)Lst_Datum(ln); - SuffInsert(s2->children, s); - SuffInsert(s->parents, s2); - return(0); - } - } - - /* - * Not from, maybe to? - */ - sd.len = strlen(transform->name); - sd.ename = transform->name + sd.len; - cp = SuffSuffIsSuffix(s, &sd); - if (cp != (char *)NULL) { - /* - * Null-terminate the source suffix in order to find it. - */ - cp[1] = '\0'; - ln = Lst_Find(sufflist, (ClientData)transform->name, SuffSuffHasNameP); - /* - * Replace the start of the target suffix - */ - cp[1] = s->name[0]; - if (ln != NILLNODE) { - /* - * Found it -- establish the proper relationship - */ - s2 = (Suff *)Lst_Datum(ln); - SuffInsert(s->children, s2); - SuffInsert(s2->parents, s); - } - } - return(0); -} - -/*- - *----------------------------------------------------------------------- - * SuffScanTargets -- - * Called from Suff_AddSuffix via Lst_ForEach to search through the - * list of existing targets and find if any of the existing targets - * can be turned into a transformation rule. - * - * Results: - * 1 if a new main target has been selected, 0 otherwise. - * - * Side Effects: - * If such a target is found and the target is the current main - * target, the main target is set to NULL and the next target - * examined (if that exists) becomes the main target. - * - *----------------------------------------------------------------------- - */ -static int -SuffScanTargets(targetp, gsp) - ClientData targetp; - ClientData gsp; -{ - GNode *target = (GNode *) targetp; - GNodeSuff *gs = (GNodeSuff *) gsp; - Suff *s, *t; - char *ptr; - - if (*gs->gn == NILGNODE && gs->r && (target->type & OP_NOTARGET) == 0) { - *gs->gn = target; - Targ_SetMain(target); - return 1; - } - - if (target->type == OP_TRANSFORM) - return 0; - - if ((ptr = strstr(target->name, gs->s->name)) == NULL || - ptr == target->name) - return 0; - - if (SuffParseTransform(target->name, &s, &t)) { - if (*gs->gn == target) { - gs->r = TRUE; - *gs->gn = NILGNODE; - Targ_SetMain(NILGNODE); - } - Lst_Destroy (target->children, NOFREE); - target->children = Lst_Init (FALSE); - target->type = OP_TRANSFORM; - /* - * link the two together in the proper relationship and order - */ - if (DEBUG(SUFF)) { - printf("defining transformation from `%s' to `%s'\n", - s->name, t->name); - } - SuffInsert (t->children, s); - SuffInsert (s->parents, t); - } - return 0; -} - -/*- - *----------------------------------------------------------------------- - * Suff_AddSuffix -- - * Add the suffix in string to the end of the list of known suffixes. - * Should we restructure the suffix graph? Make doesn't... - * - * Results: - * None - * - * Side Effects: - * A GNode is created for the suffix and a Suff structure is created and - * added to the suffixes list unless the suffix was already known. - * The mainNode passed can be modified if a target mutated into a - * transform and that target happened to be the main target. - *----------------------------------------------------------------------- - */ -void -Suff_AddSuffix (str, gn) - char *str; /* the name of the suffix to add */ - GNode **gn; -{ - Suff *s; /* new suffix descriptor */ - LstNode ln; - GNodeSuff gs; - - ln = Lst_Find (sufflist, (ClientData)str, SuffSuffHasNameP); - if (ln == NILLNODE) { - s = (Suff *) emalloc (sizeof (Suff)); - - s->name = estrdup (str); - s->nameLen = strlen (s->name); - s->searchPath = Lst_Init (FALSE); - s->children = Lst_Init (FALSE); - s->parents = Lst_Init (FALSE); - s->ref = Lst_Init (FALSE); - s->sNum = sNum++; - s->flags = 0; - s->refCount = 0; - - (void)Lst_AtEnd (sufflist, (ClientData)s); - /* - * We also look at our existing targets list to see if adding - * this suffix will make one of our current targets mutate into - * a suffix rule. This is ugly, but other makes treat all targets - * that start with a . as suffix rules. - */ - gs.gn = gn; - gs.s = s; - gs.r = FALSE; - Lst_ForEach (Targ_List(), SuffScanTargets, (ClientData) &gs); - /* - * Look for any existing transformations from or to this suffix. - * XXX: Only do this after a Suff_ClearSuffixes? - */ - Lst_ForEach (transforms, SuffRebuildGraph, (ClientData) s); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_GetPath -- - * Return the search path for the given suffix, if it's defined. - * - * Results: - * The searchPath for the desired suffix or NILLST if the suffix isn't - * defined. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Lst -Suff_GetPath (sname) - char *sname; -{ - LstNode ln; - Suff *s; - - ln = Lst_Find (sufflist, (ClientData)sname, SuffSuffHasNameP); - if (ln == NILLNODE) { - return (NILLST); - } else { - s = (Suff *) Lst_Datum (ln); - return (s->searchPath); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_DoPaths -- - * Extend the search paths for all suffixes to include the default - * search path. - * - * Results: - * None. - * - * Side Effects: - * The searchPath field of all the suffixes is extended by the - * directories in dirSearchPath. If paths were specified for the - * ".h" suffix, the directories are stuffed into a global variable - * called ".INCLUDES" with each directory preceded by a -I. The same - * is done for the ".a" suffix, except the variable is called - * ".LIBS" and the flag is -L. - *----------------------------------------------------------------------- - */ -void -Suff_DoPaths() -{ - register Suff *s; - register LstNode ln; - char *ptr; - Lst inIncludes; /* Cumulative .INCLUDES path */ - Lst inLibs; /* Cumulative .LIBS path */ - - if (Lst_Open (sufflist) == FAILURE) { - return; - } - - inIncludes = Lst_Init(FALSE); - inLibs = Lst_Init(FALSE); - - while ((ln = Lst_Next (sufflist)) != NILLNODE) { - s = (Suff *) Lst_Datum (ln); - if (!Lst_IsEmpty (s->searchPath)) { -#ifdef INCLUDES - if (s->flags & SUFF_INCLUDE) { - Dir_Concat(inIncludes, s->searchPath); - } -#endif /* INCLUDES */ -#ifdef LIBRARIES - if (s->flags & SUFF_LIBRARY) { - Dir_Concat(inLibs, s->searchPath); - } -#endif /* LIBRARIES */ - Dir_Concat(s->searchPath, dirSearchPath); - } else { - Lst_Destroy (s->searchPath, Dir_Destroy); - s->searchPath = Lst_Duplicate(dirSearchPath, Dir_CopyDir); - } - } - - Var_Set(".INCLUDES", ptr = Dir_MakeFlags("-I", inIncludes), VAR_GLOBAL, 0); - free(ptr); - Var_Set(".LIBS", ptr = Dir_MakeFlags("-L", inLibs), VAR_GLOBAL, 0); - free(ptr); - - Lst_Destroy(inIncludes, Dir_Destroy); - Lst_Destroy(inLibs, Dir_Destroy); - - Lst_Close (sufflist); -} - -/*- - *----------------------------------------------------------------------- - * Suff_AddInclude -- - * Add the given suffix as a type of file which gets included. - * Called from the parse module when a .INCLUDES line is parsed. - * The suffix must have already been defined. - * - * Results: - * None. - * - * Side Effects: - * The SUFF_INCLUDE bit is set in the suffix's flags field - * - *----------------------------------------------------------------------- - */ -void -Suff_AddInclude (sname) - char *sname; /* Name of suffix to mark */ -{ - LstNode ln; - Suff *s; - - ln = Lst_Find (sufflist, (ClientData)sname, SuffSuffHasNameP); - if (ln != NILLNODE) { - s = (Suff *) Lst_Datum (ln); - s->flags |= SUFF_INCLUDE; - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_AddLib -- - * Add the given suffix as a type of file which is a library. - * Called from the parse module when parsing a .LIBS line. The - * suffix must have been defined via .SUFFIXES before this is - * called. - * - * Results: - * None. - * - * Side Effects: - * The SUFF_LIBRARY bit is set in the suffix's flags field - * - *----------------------------------------------------------------------- - */ -void -Suff_AddLib (sname) - char *sname; /* Name of suffix to mark */ -{ - LstNode ln; - Suff *s; - - ln = Lst_Find (sufflist, (ClientData)sname, SuffSuffHasNameP); - if (ln != NILLNODE) { - s = (Suff *) Lst_Datum (ln); - s->flags |= SUFF_LIBRARY; - } -} - - /********** Implicit Source Search Functions *********/ - -/*- - *----------------------------------------------------------------------- - * SuffAddSrc -- - * Add a suffix as a Src structure to the given list with its parent - * being the given Src structure. If the suffix is the null suffix, - * the prefix is used unaltered as the file name in the Src structure. - * - * Results: - * always returns 0 - * - * Side Effects: - * A Src structure is created and tacked onto the end of the list - *----------------------------------------------------------------------- - */ -static int -SuffAddSrc (sp, lsp) - ClientData sp; /* suffix for which to create a Src structure */ - ClientData lsp; /* list and parent for the new Src */ -{ - Suff *s = (Suff *) sp; - LstSrc *ls = (LstSrc *) lsp; - Src *s2; /* new Src structure */ - Src *targ; /* Target structure */ - - targ = ls->s; - - if ((s->flags & SUFF_NULL) && (*s->name != '\0')) { - /* - * If the suffix has been marked as the NULL suffix, also create a Src - * structure for a file with no suffix attached. Two birds, and all - * that... - */ - s2 = (Src *) emalloc (sizeof (Src)); - s2->file = estrdup(targ->pref); - s2->pref = targ->pref; - s2->parent = targ; - s2->node = NILGNODE; - s2->suff = s; - s->refCount++; - s2->children = 0; - targ->children += 1; - (void)Lst_AtEnd (ls->l, (ClientData)s2); -#ifdef DEBUG_SRC - s2->cp = Lst_Init(FALSE); - Lst_AtEnd(targ->cp, (ClientData) s2); - printf("1 add %x %x to %x:", targ, s2, ls->l); - Lst_ForEach(ls->l, PrintAddr, (ClientData) 0); - printf("\n"); -#endif - } - s2 = (Src *) emalloc (sizeof (Src)); - s2->file = str_concat (targ->pref, s->name, 0); - s2->pref = targ->pref; - s2->parent = targ; - s2->node = NILGNODE; - s2->suff = s; - s->refCount++; - s2->children = 0; - targ->children += 1; - (void)Lst_AtEnd (ls->l, (ClientData)s2); -#ifdef DEBUG_SRC - s2->cp = Lst_Init(FALSE); - Lst_AtEnd(targ->cp, (ClientData) s2); - printf("2 add %x %x to %x:", targ, s2, ls->l); - Lst_ForEach(ls->l, PrintAddr, (ClientData) 0); - printf("\n"); -#endif - - return(0); -} - -/*- - *----------------------------------------------------------------------- - * SuffAddLevel -- - * Add all the children of targ as Src structures to the given list - * - * Results: - * None - * - * Side Effects: - * Lots of structures are created and added to the list - *----------------------------------------------------------------------- - */ -static void -SuffAddLevel (l, targ) - Lst l; /* list to which to add the new level */ - Src *targ; /* Src structure to use as the parent */ -{ - LstSrc ls; - - ls.s = targ; - ls.l = l; - - Lst_ForEach (targ->suff->children, SuffAddSrc, (ClientData)&ls); -} - -/*- - *---------------------------------------------------------------------- - * SuffRemoveSrc -- - * Free all src structures in list that don't have a reference count - * - * Results: - * Ture if an src was removed - * - * Side Effects: - * The memory is free'd. - *---------------------------------------------------------------------- - */ -static int -SuffRemoveSrc (l) - Lst l; -{ - LstNode ln; - Src *s; - int t = 0; - - if (Lst_Open (l) == FAILURE) { - return 0; - } -#ifdef DEBUG_SRC - printf("cleaning %lx: ", (unsigned long) l); - Lst_ForEach(l, PrintAddr, (ClientData) 0); - printf("\n"); -#endif - - - while ((ln = Lst_Next (l)) != NILLNODE) { - s = (Src *) Lst_Datum (ln); - if (s->children == 0) { - free ((Address)s->file); - if (!s->parent) - free((Address)s->pref); - else { -#ifdef DEBUG_SRC - LstNode ln = Lst_Member(s->parent->cp, (ClientData)s); - if (ln != NILLNODE) - Lst_Remove(s->parent->cp, ln); -#endif - --s->parent->children; - } -#ifdef DEBUG_SRC - printf("free: [l=%x] p=%x %d\n", l, s, s->children); - Lst_Destroy(s->cp, NOFREE); -#endif - Lst_Remove(l, ln); - free ((Address)s); - t |= 1; - Lst_Close(l); - return TRUE; - } -#ifdef DEBUG_SRC - else { - printf("keep: [l=%x] p=%x %d: ", l, s, s->children); - Lst_ForEach(s->cp, PrintAddr, (ClientData) 0); - printf("\n"); - } -#endif - } - - Lst_Close(l); - - return t; -} - -/*- - *----------------------------------------------------------------------- - * SuffFindThem -- - * Find the first existing file/target in the list srcs - * - * Results: - * The lowest structure in the chain of transformations - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static Src * -SuffFindThem (srcs, slst) - Lst srcs; /* list of Src structures to search through */ - Lst slst; -{ - Src *s; /* current Src */ - Src *rs; /* returned Src */ - char *ptr; - - rs = (Src *) NULL; - - while (!Lst_IsEmpty (srcs)) { - s = (Src *) Lst_DeQueue (srcs); - - if (DEBUG(SUFF)) { - printf ("\ttrying %s...", s->file); - } - - /* - * A file is considered to exist if either a node exists in the - * graph for it or the file actually exists. - */ - if (Targ_FindNode(s->file, TARG_NOCREATE) != NILGNODE) { -#ifdef DEBUG_SRC - printf("remove %x from %x\n", s, srcs); -#endif - rs = s; - break; - } - - if ((ptr = Dir_FindFile (s->file, s->suff->searchPath)) != NULL) { - rs = s; -#ifdef DEBUG_SRC - printf("remove %x from %x\n", s, srcs); -#endif - free(ptr); - break; - } - - if (DEBUG(SUFF)) { - printf ("not there\n"); - } - - SuffAddLevel (srcs, s); - Lst_AtEnd(slst, (ClientData) s); - } - - if (DEBUG(SUFF) && rs) { - printf ("got it\n"); - } - return (rs); -} - -/*- - *----------------------------------------------------------------------- - * SuffFindCmds -- - * See if any of the children of the target in the Src structure is - * one from which the target can be transformed. If there is one, - * a Src structure is put together for it and returned. - * - * Results: - * The Src structure of the "winning" child, or NIL if no such beast. - * - * Side Effects: - * A Src structure may be allocated. - * - *----------------------------------------------------------------------- - */ -static Src * -SuffFindCmds (targ, slst) - Src *targ; /* Src structure to play with */ - Lst slst; -{ - LstNode ln; /* General-purpose list node */ - register GNode *t, /* Target GNode */ - *s; /* Source GNode */ - int prefLen;/* The length of the defined prefix */ - Suff *suff; /* Suffix on matching beastie */ - Src *ret; /* Return value */ - char *cp; - - t = targ->node; - (void) Lst_Open (t->children); - prefLen = strlen (targ->pref); - - while ((ln = Lst_Next (t->children)) != NILLNODE) { - s = (GNode *)Lst_Datum (ln); - - cp = strrchr (s->name, '/'); - if (cp == (char *)NULL) { - cp = s->name; - } else { - cp++; - } - if (strncmp (cp, targ->pref, prefLen) == 0) { - /* - * The node matches the prefix ok, see if it has a known - * suffix. - */ - ln = Lst_Find (sufflist, (ClientData)&cp[prefLen], - SuffSuffHasNameP); - if (ln != NILLNODE) { - /* - * It even has a known suffix, see if there's a transformation - * defined between the node's suffix and the target's suffix. - * - * XXX: Handle multi-stage transformations here, too. - */ - suff = (Suff *)Lst_Datum (ln); - - if (Lst_Member (suff->parents, - (ClientData)targ->suff) != NILLNODE) - { - /* - * Hot Damn! Create a new Src structure to describe - * this transformation (making sure to duplicate the - * source node's name so Suff_FindDeps can free it - * again (ick)), and return the new structure. - */ - ret = (Src *)emalloc (sizeof (Src)); - ret->file = estrdup(s->name); - ret->pref = targ->pref; - ret->suff = suff; - suff->refCount++; - ret->parent = targ; - ret->node = s; - ret->children = 0; - targ->children += 1; -#ifdef DEBUG_SRC - ret->cp = Lst_Init(FALSE); - printf("3 add %x %x\n", targ, ret); - Lst_AtEnd(targ->cp, (ClientData) ret); -#endif - Lst_AtEnd(slst, (ClientData) ret); - if (DEBUG(SUFF)) { - printf ("\tusing existing source %s\n", s->name); - } - return (ret); - } - } - } - } - Lst_Close (t->children); - return ((Src *)NULL); -} - -/*- - *----------------------------------------------------------------------- - * SuffExpandChildren -- - * Expand the names of any children of a given node that contain - * variable invocations or file wildcards into actual targets. - * - * Results: - * === 0 (continue) - * - * Side Effects: - * The expanded node is removed from the parent's list of children, - * and the parent's unmade counter is decremented, but other nodes - * may be added. - * - *----------------------------------------------------------------------- - */ -static int -SuffExpandChildren(prevLN, pgn) - LstNode prevLN; /* Child to examine */ - GNode *pgn; /* Parent node being processed */ -{ - GNode *cgn = (GNode *) Lst_Datum(prevLN); - GNode *gn; /* New source 8) */ - LstNode ln; /* List element for old source */ - char *cp; /* Expanded value */ - - /* - * First do variable expansion -- this takes precedence over - * wildcard expansion. If the result contains wildcards, they'll be gotten - * to later since the resulting words are tacked on to the end of - * the children list. - */ - if (strchr(cgn->name, '$') != (char *)NULL) { - if (DEBUG(SUFF)) { - printf("Expanding \"%s\"...", cgn->name); - } - cp = Var_Subst(NULL, cgn->name, pgn, TRUE); - - if (cp != (char *)NULL) { - Lst members = Lst_Init(FALSE); - - if (cgn->type & OP_ARCHV) { - /* - * Node was an archive(member) target, so we want to call - * on the Arch module to find the nodes for us, expanding - * variables in the parent's context. - */ - char *sacrifice = cp; - - (void)Arch_ParseArchive(&sacrifice, members, pgn); - } else { - /* - * Break the result into a vector of strings whose nodes - * we can find, then add those nodes to the members list. - * Unfortunately, we can't use brk_string b/c it - * doesn't understand about variable specifications with - * spaces in them... - */ - char *start; - char *initcp = cp; /* For freeing... */ - - for (start = cp; *start == ' ' || *start == '\t'; start++) - continue; - for (cp = start; *cp != '\0'; cp++) { - if (*cp == ' ' || *cp == '\t') { - /* - * White-space -- terminate element, find the node, - * add it, skip any further spaces. - */ - *cp++ = '\0'; - gn = Targ_FindNode(start, TARG_CREATE); - (void)Lst_AtEnd(members, (ClientData)gn); - while (*cp == ' ' || *cp == '\t') { - cp++; - } - /* - * Adjust cp for increment at start of loop, but - * set start to first non-space. - */ - start = cp--; - } else if (*cp == '$') { - /* - * Start of a variable spec -- contact variable module - * to find the end so we can skip over it. - */ - char *junk; - int len; - Boolean doFree; - - junk = Var_Parse(cp, pgn, TRUE, &len, &doFree); - if (junk != var_Error) { - cp += len - 1; - } - - if (doFree) { - free(junk); - } - } else if (*cp == '\\' && *cp != '\0') { - /* - * Escaped something -- skip over it - */ - cp++; - } - } - - if (cp != start) { - /* - * Stuff left over -- add it to the list too - */ - gn = Targ_FindNode(start, TARG_CREATE); - (void)Lst_AtEnd(members, (ClientData)gn); - } - /* - * Point cp back at the beginning again so the variable value - * can be freed. - */ - cp = initcp; - } - /* - * Add all elements of the members list to the parent node. - */ - while(!Lst_IsEmpty(members)) { - gn = (GNode *)Lst_DeQueue(members); - - if (DEBUG(SUFF)) { - printf("%s...", gn->name); - } - if (Lst_Member(pgn->children, (ClientData)gn) == NILLNODE) { - (void)Lst_Append(pgn->children, prevLN, (ClientData)gn); - prevLN = Lst_Succ(prevLN); - (void)Lst_AtEnd(gn->parents, (ClientData)pgn); - pgn->unmade++; - } - } - Lst_Destroy(members, NOFREE); - /* - * Free the result - */ - free((char *)cp); - } - /* - * Now the source is expanded, remove it from the list of children to - * keep it from being processed. - */ - if (DEBUG(SUFF)) { - printf("\n"); - } - return(1); - } else if (Dir_HasWildcards(cgn->name)) { - Lst exp; /* List of expansions */ - Lst path; /* Search path along which to expand */ - SuffixCmpData sd; /* Search string data */ - - /* - * Find a path along which to expand the word. - * - * If the word has a known suffix, use that path. - * If it has no known suffix and we're allowed to use the null - * suffix, use its path. - * Else use the default system search path. - */ - sd.len = strlen(cgn->name); - sd.ename = cgn->name + sd.len; - ln = Lst_Find(sufflist, (ClientData)&sd, SuffSuffIsSuffixP); - - if (DEBUG(SUFF)) { - printf("Wildcard expanding \"%s\"...", cgn->name); - } - - if (ln != NILLNODE) { - Suff *s = (Suff *)Lst_Datum(ln); - - if (DEBUG(SUFF)) { - printf("suffix is \"%s\"...", s->name); - } - path = s->searchPath; - } else { - /* - * Use default search path - */ - path = dirSearchPath; - } - - /* - * Expand the word along the chosen path - */ - exp = Lst_Init(FALSE); - Dir_Expand(cgn->name, path, exp); - - while (!Lst_IsEmpty(exp)) { - /* - * Fetch next expansion off the list and find its GNode - */ - cp = (char *)Lst_DeQueue(exp); - - if (DEBUG(SUFF)) { - printf("%s...", cp); - } - gn = Targ_FindNode(cp, TARG_CREATE); - - /* - * If gn isn't already a child of the parent, make it so and - * up the parent's count of unmade children. - */ - if (Lst_Member(pgn->children, (ClientData)gn) == NILLNODE) { - (void)Lst_Append(pgn->children, prevLN, (ClientData)gn); - prevLN = Lst_Succ(prevLN); - (void)Lst_AtEnd(gn->parents, (ClientData)pgn); - pgn->unmade++; - } - } - - /* - * Nuke what's left of the list - */ - Lst_Destroy(exp, NOFREE); - - /* - * Now the source is expanded, remove it from the list of children to - * keep it from being processed. - */ - if (DEBUG(SUFF)) { - printf("\n"); - } - return(1); - } - - return(0); -} - -/*- - *----------------------------------------------------------------------- - * SuffApplyTransform -- - * Apply a transformation rule, given the source and target nodes - * and suffixes. - * - * Results: - * TRUE if successful, FALSE if not. - * - * Side Effects: - * The source and target are linked and the commands from the - * transformation are added to the target node's commands list. - * All attributes but OP_DEPMASK and OP_TRANSFORM are applied - * to the target. The target also inherits all the sources for - * the transformation rule. - * - *----------------------------------------------------------------------- - */ -static Boolean -SuffApplyTransform(tGn, sGn, t, s) - GNode *tGn; /* Target node */ - GNode *sGn; /* Source node */ - Suff *t; /* Target suffix */ - Suff *s; /* Source suffix */ -{ - LstNode ln, nln; /* General node */ - char *tname; /* Name of transformation rule */ - GNode *gn; /* Node for same */ - - /* - * Form the proper links between the target and source. - */ - (void)Lst_AtEnd(tGn->children, (ClientData)sGn); - (void)Lst_AtEnd(sGn->parents, (ClientData)tGn); - tGn->unmade += 1; - - /* - * Locate the transformation rule itself - */ - tname = str_concat(s->name, t->name, 0); - ln = Lst_Find(transforms, (ClientData)tname, SuffGNHasNameP); - free(tname); - - if (ln == NILLNODE) { - /* - * Not really such a transformation rule (can happen when we're - * called to link an OP_MEMBER and OP_ARCHV node), so return - * FALSE. - */ - return(FALSE); - } - - gn = (GNode *)Lst_Datum(ln); - - if (DEBUG(SUFF)) { - printf("\tapplying %s -> %s to \"%s\"\n", s->name, t->name, tGn->name); - } - - /* - * Record last child for expansion purposes - */ - ln = Lst_Last(tGn->children); - - /* - * Pass the buck to Make_HandleUse to apply the rule - */ - (void)Make_HandleUse(gn, tGn); - - /* - * Deal with wildcards and variables in any acquired sources - */ - ln = Lst_Succ(ln); - while (ln != NILLNODE) { - if (SuffExpandChildren(ln, tGn)) { - nln = Lst_Succ(ln); - tGn->unmade--; - Lst_Remove(tGn->children, ln); - ln = nln; - } else - ln = Lst_Succ(ln); - } - - /* - * Keep track of another parent to which this beast is transformed so - * the .IMPSRC variable can be set correctly for the parent. - */ - (void)Lst_AtEnd(sGn->iParents, (ClientData)tGn); - - return(TRUE); -} - - -/*- - *----------------------------------------------------------------------- - * SuffFindArchiveDeps -- - * Locate dependencies for an OP_ARCHV node. - * - * Results: - * None - * - * Side Effects: - * Same as Suff_FindDeps - * - *----------------------------------------------------------------------- - */ -static void -SuffFindArchiveDeps(gn, slst) - GNode *gn; /* Node for which to locate dependencies */ - Lst slst; -{ - char *eoarch; /* End of archive portion */ - char *eoname; /* End of member portion */ - GNode *mem; /* Node for member */ - static char *copy[] = { /* Variables to be copied from the member node */ - TARGET, /* Must be first */ - PREFIX, /* Must be second */ - }; - int i; /* Index into copy and vals */ - Suff *ms; /* Suffix descriptor for member */ - char *name; /* Start of member's name */ - - /* - * The node is an archive(member) pair. so we must find a - * suffix for both of them. - */ - eoarch = strchr (gn->name, '('); - eoname = strchr (eoarch, ')'); - - *eoname = '\0'; /* Nuke parentheses during suffix search */ - *eoarch = '\0'; /* So a suffix can be found */ - - name = eoarch + 1; - - /* - * To simplify things, call Suff_FindDeps recursively on the member now, - * so we can simply compare the member's .PREFIX and .TARGET variables - * to locate its suffix. This allows us to figure out the suffix to - * use for the archive without having to do a quadratic search over the - * suffix list, backtracking for each one... - */ - mem = Targ_FindNode(name, TARG_CREATE); - SuffFindDeps(mem, slst); - - /* - * Create the link between the two nodes right off - */ - (void)Lst_AtEnd(gn->children, (ClientData)mem); - (void)Lst_AtEnd(mem->parents, (ClientData)gn); - gn->unmade += 1; - - /* - * Copy in the variables from the member node to this one. - */ - for (i = (sizeof(copy)/sizeof(copy[0]))-1; i >= 0; i--) { - char *p1; - Var_Set(copy[i], Var_Value(copy[i], mem, &p1), gn, 0); - if (p1) - free(p1); - - } - - ms = mem->suffix; - if (ms == NULL) { - /* - * Didn't know what it was -- use .NULL suffix if not in make mode - */ - if (DEBUG(SUFF)) { - printf("using null suffix\n"); - } - ms = suffNull; - } - - - /* - * Set the other two local variables required for this target. - */ - Var_Set (MEMBER, name, gn, 0); - Var_Set (ARCHIVE, gn->name, gn, 0); - - if (ms != NULL) { - /* - * Member has a known suffix, so look for a transformation rule from - * it to a possible suffix of the archive. Rather than searching - * through the entire list, we just look at suffixes to which the - * member's suffix may be transformed... - */ - LstNode ln; - SuffixCmpData sd; /* Search string data */ - - /* - * Use first matching suffix... - */ - sd.len = eoarch - gn->name; - sd.ename = eoarch; - ln = Lst_Find(ms->parents, &sd, SuffSuffIsSuffixP); - - if (ln != NILLNODE) { - /* - * Got one -- apply it - */ - if (!SuffApplyTransform(gn, mem, (Suff *)Lst_Datum(ln), ms) && - DEBUG(SUFF)) - { - printf("\tNo transformation from %s -> %s\n", - ms->name, ((Suff *)Lst_Datum(ln))->name); - } - } - } - - /* - * Replace the opening and closing parens now we've no need of the separate - * pieces. - */ - *eoarch = '('; *eoname = ')'; - - /* - * Pretend gn appeared to the left of a dependency operator so - * the user needn't provide a transformation from the member to the - * archive. - */ - if (OP_NOP(gn->type)) { - gn->type |= OP_DEPENDS; - } - - /* - * Flag the member as such so we remember to look in the archive for - * its modification time. - */ - mem->type |= OP_MEMBER; -} - -/*- - *----------------------------------------------------------------------- - * SuffFindNormalDeps -- - * Locate implicit dependencies for regular targets. - * - * Results: - * None. - * - * Side Effects: - * Same as Suff_FindDeps... - * - *----------------------------------------------------------------------- - */ -static void -SuffFindNormalDeps(gn, slst) - GNode *gn; /* Node for which to find sources */ - Lst slst; -{ - char *eoname; /* End of name */ - char *sopref; /* Start of prefix */ - LstNode ln, nln; /* Next suffix node to check */ - Lst srcs; /* List of sources at which to look */ - Lst targs; /* List of targets to which things can be - * transformed. They all have the same file, - * but different suff and pref fields */ - Src *bottom; /* Start of found transformation path */ - Src *src; /* General Src pointer */ - char *pref; /* Prefix to use */ - Src *targ; /* General Src target pointer */ - SuffixCmpData sd; /* Search string data */ - - - sd.len = strlen(gn->name); - sd.ename = eoname = gn->name + sd.len; - - sopref = gn->name; - - /* - * Begin at the beginning... - */ - ln = Lst_First(sufflist); - srcs = Lst_Init(FALSE); - targs = Lst_Init(FALSE); - - /* - * We're caught in a catch-22 here. On the one hand, we want to use any - * transformation implied by the target's sources, but we can't examine - * the sources until we've expanded any variables/wildcards they may hold, - * and we can't do that until we've set up the target's local variables - * and we can't do that until we know what the proper suffix for the - * target is (in case there are two suffixes one of which is a suffix of - * the other) and we can't know that until we've found its implied - * source, which we may not want to use if there's an existing source - * that implies a different transformation. - * - * In an attempt to get around this, which may not work all the time, - * but should work most of the time, we look for implied sources first, - * checking transformations to all possible suffixes of the target, - * use what we find to set the target's local variables, expand the - * children, then look for any overriding transformations they imply. - * Should we find one, we discard the one we found before. - */ - - while (ln != NILLNODE) { - /* - * Look for next possible suffix... - */ - ln = Lst_FindFrom(sufflist, ln, &sd, SuffSuffIsSuffixP); - - if (ln != NILLNODE) { - int prefLen; /* Length of the prefix */ - Src *targ; - - /* - * Allocate a Src structure to which things can be transformed - */ - targ = (Src *)emalloc(sizeof (Src)); - targ->file = estrdup(gn->name); - targ->suff = (Suff *)Lst_Datum(ln); - targ->suff->refCount++; - targ->node = gn; - targ->parent = (Src *)NULL; - targ->children = 0; -#ifdef DEBUG_SRC - targ->cp = Lst_Init(FALSE); -#endif - - /* - * Allocate room for the prefix, whose end is found by subtracting - * the length of the suffix from the end of the name. - */ - prefLen = (eoname - targ->suff->nameLen) - sopref; - targ->pref = emalloc(prefLen + 1); - memcpy(targ->pref, sopref, prefLen); - targ->pref[prefLen] = '\0'; - - /* - * Add nodes from which the target can be made - */ - SuffAddLevel(srcs, targ); - - /* - * Record the target so we can nuke it - */ - (void)Lst_AtEnd(targs, (ClientData)targ); - - /* - * Search from this suffix's successor... - */ - ln = Lst_Succ(ln); - } - } - - /* - * Handle target of unknown suffix... - */ - if (Lst_IsEmpty(targs) && suffNull != NULL) { - if (DEBUG(SUFF)) { - printf("\tNo known suffix on %s. Using .NULL suffix\n", gn->name); - } - - targ = (Src *)emalloc(sizeof (Src)); - targ->file = estrdup(gn->name); - targ->suff = suffNull; - targ->suff->refCount++; - targ->node = gn; - targ->parent = (Src *)NULL; - targ->children = 0; - targ->pref = estrdup(sopref); -#ifdef DEBUG_SRC - targ->cp = Lst_Init(FALSE); -#endif - - /* - * Only use the default suffix rules if we don't have commands - * defined for this gnode; traditional make programs used to - * not define suffix rules if the gnode had children but we - * don't do this anymore. - */ - if (Lst_IsEmpty(gn->commands)) - SuffAddLevel(srcs, targ); - else { - if (DEBUG(SUFF)) - printf("not "); - } - - if (DEBUG(SUFF)) - printf("adding suffix rules\n"); - - (void)Lst_AtEnd(targs, (ClientData)targ); - } - - /* - * Using the list of possible sources built up from the target suffix(es), - * try and find an existing file/target that matches. - */ - bottom = SuffFindThem(srcs, slst); - - if (bottom == (Src *)NULL) { - /* - * No known transformations -- use the first suffix found for setting - * the local variables. - */ - if (!Lst_IsEmpty(targs)) { - targ = (Src *)Lst_Datum(Lst_First(targs)); - } else { - targ = (Src *)NULL; - } - } else { - /* - * Work up the transformation path to find the suffix of the - * target to which the transformation was made. - */ - for (targ = bottom; targ->parent != NULL; targ = targ->parent) - continue; - } - - Var_Set(TARGET, gn->path ? gn->path : gn->name, gn, 0); - - pref = (targ != NULL) ? targ->pref : gn->name; - Var_Set(PREFIX, pref, gn, 0); - - /* - * Now we've got the important local variables set, expand any sources - * that still contain variables or wildcards in their names. - */ - ln = Lst_First(gn->children); - while (ln != NILLNODE) { - if (SuffExpandChildren(ln, gn)) { - nln = Lst_Succ(ln); - gn->unmade--; - Lst_Remove(gn->children, ln); - ln = nln; - } else - ln = Lst_Succ(ln); - } - - if (targ == NULL) { - if (DEBUG(SUFF)) { - printf("\tNo valid suffix on %s\n", gn->name); - } - -sfnd_abort: - /* - * Deal with finding the thing on the default search path. We - * always do that, not only if the node is only a source (not - * on the lhs of a dependency operator or [XXX] it has neither - * children or commands) as the old pmake did. - */ - if ((gn->type & (OP_PHONY|OP_NOPATH)) == 0) { - free(gn->path); - gn->path = Dir_FindFile(gn->name, - (targ == NULL ? dirSearchPath : - targ->suff->searchPath)); - if (gn->path != NULL) { - char *ptr; - Var_Set(TARGET, gn->path, gn, 0); - - if (targ != NULL) { - /* - * Suffix known for the thing -- trim the suffix off - * the path to form the proper .PREFIX variable. - */ - int savep = strlen(gn->path) - targ->suff->nameLen; - char savec; - - if (gn->suffix) - gn->suffix->refCount--; - gn->suffix = targ->suff; - gn->suffix->refCount++; - - savec = gn->path[savep]; - gn->path[savep] = '\0'; - - if ((ptr = strrchr(gn->path, '/')) != NULL) - ptr++; - else - ptr = gn->path; - - Var_Set(PREFIX, ptr, gn, 0); - - gn->path[savep] = savec; - } else { - /* - * The .PREFIX gets the full path if the target has - * no known suffix. - */ - if (gn->suffix) - gn->suffix->refCount--; - gn->suffix = NULL; - - if ((ptr = strrchr(gn->path, '/')) != NULL) - ptr++; - else - ptr = gn->path; - - Var_Set(PREFIX, ptr, gn, 0); - } - } - } - - goto sfnd_return; - } - - /* - * If the suffix indicates that the target is a library, mark that in - * the node's type field. - */ - if (targ->suff->flags & SUFF_LIBRARY) { - gn->type |= OP_LIB; - } - - /* - * Check for overriding transformation rule implied by sources - */ - if (!Lst_IsEmpty(gn->children)) { - src = SuffFindCmds(targ, slst); - - if (src != (Src *)NULL) { - /* - * Free up all the Src structures in the transformation path - * up to, but not including, the parent node. - */ - while (bottom && bottom->parent != NULL) { - if (Lst_Member(slst, (ClientData) bottom) == NILLNODE) { - Lst_AtEnd(slst, (ClientData) bottom); - } - bottom = bottom->parent; - } - bottom = src; - } - } - - if (bottom == NULL) { - /* - * No idea from where it can come -- return now. - */ - goto sfnd_abort; - } - - /* - * We now have a list of Src structures headed by 'bottom' and linked via - * their 'parent' pointers. What we do next is create links between - * source and target nodes (which may or may not have been created) - * and set the necessary local variables in each target. The - * commands for each target are set from the commands of the - * transformation rule used to get from the src suffix to the targ - * suffix. Note that this causes the commands list of the original - * node, gn, to be replaced by the commands of the final - * transformation rule. Also, the unmade field of gn is incremented. - * Etc. - */ - if (bottom->node == NILGNODE) { - bottom->node = Targ_FindNode(bottom->file, TARG_CREATE); - } - - for (src = bottom; src->parent != (Src *)NULL; src = src->parent) { - targ = src->parent; - - if (src->node->suffix) - src->node->suffix->refCount--; - src->node->suffix = src->suff; - src->node->suffix->refCount++; - - if (targ->node == NILGNODE) { - targ->node = Targ_FindNode(targ->file, TARG_CREATE); - } - - SuffApplyTransform(targ->node, src->node, - targ->suff, src->suff); - - if (targ->node != gn) { - /* - * Finish off the dependency-search process for any nodes - * between bottom and gn (no point in questing around the - * filesystem for their implicit source when it's already - * known). Note that the node can't have any sources that - * need expanding, since SuffFindThem will stop on an existing - * node, so all we need to do is set the standard and System V - * variables. - */ - targ->node->type |= OP_DEPS_FOUND; - - Var_Set(PREFIX, targ->pref, targ->node, 0); - - Var_Set(TARGET, targ->node->name, targ->node, 0); - } - } - - if (gn->suffix) - gn->suffix->refCount--; - gn->suffix = src->suff; - gn->suffix->refCount++; - - /* - * Nuke the transformation path and the Src structures left over in the - * two lists. - */ -sfnd_return: - if (bottom) - if (Lst_Member(slst, (ClientData) bottom) == NILLNODE) - Lst_AtEnd(slst, (ClientData) bottom); - - while (SuffRemoveSrc(srcs) || SuffRemoveSrc(targs)) - continue; - - Lst_Concat(slst, srcs, LST_CONCLINK); - Lst_Concat(slst, targs, LST_CONCLINK); -} - - -/*- - *----------------------------------------------------------------------- - * Suff_FindDeps -- - * Find implicit sources for the target described by the graph node - * gn - * - * Results: - * Nothing. - * - * Side Effects: - * Nodes are added to the graph below the passed-in node. The nodes - * are marked to have their IMPSRC variable filled in. The - * PREFIX variable is set for the given node and all its - * implied children. - * - * Notes: - * The path found by this target is the shortest path in the - * transformation graph, which may pass through non-existent targets, - * to an existing target. The search continues on all paths from the - * root suffix until a file is found. I.e. if there's a path - * .o -> .c -> .l -> .l,v from the root and the .l,v file exists but - * the .c and .l files don't, the search will branch out in - * all directions from .o and again from all the nodes on the - * next level until the .l,v node is encountered. - * - *----------------------------------------------------------------------- - */ - -void -Suff_FindDeps(gn) - GNode *gn; -{ - - SuffFindDeps(gn, srclist); - while (SuffRemoveSrc(srclist)) - continue; -} - - -static void -SuffFindDeps (gn, slst) - GNode *gn; /* node we're dealing with */ - Lst slst; -{ - if (gn->type & (OP_DEPS_FOUND|OP_PHONY)) { - /* - * If dependencies already found, no need to do it again... - * If this is a .PHONY target, we do not apply suffix rules. - */ - return; - } else { - gn->type |= OP_DEPS_FOUND; - } - - if (DEBUG(SUFF)) { - printf ("SuffFindDeps (%s)\n", gn->name); - } - - if (gn->type & OP_ARCHV) { - SuffFindArchiveDeps(gn, slst); - } else if (gn->type & OP_LIB) { - /* - * If the node is a library, it is the arch module's job to find it - * and set the TARGET variable accordingly. We merely provide the - * search path, assuming all libraries end in ".a" (if the suffix - * hasn't been defined, there's nothing we can do for it, so we just - * set the TARGET variable to the node's name in order to give it a - * value). - */ - LstNode ln; - Suff *s; - - ln = Lst_Find (sufflist, (ClientData)LIBSUFF, SuffSuffHasNameP); - if (gn->suffix) - gn->suffix->refCount--; - if (ln != NILLNODE) { - gn->suffix = s = (Suff *) Lst_Datum (ln); - gn->suffix->refCount++; - Arch_FindLib (gn, s->searchPath); - } else { - gn->suffix = NULL; - Var_Set (TARGET, gn->name, gn, 0); - } - /* - * Because a library (-lfoo) target doesn't follow the standard - * filesystem conventions, we don't set the regular variables for - * the thing. .PREFIX is simply made empty... - */ - Var_Set(PREFIX, "", gn, 0); - } else { - SuffFindNormalDeps(gn, slst); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_SetNull -- - * Define which suffix is the null suffix. - * - * Results: - * None. - * - * Side Effects: - * 'suffNull' is altered. - * - * Notes: - * Need to handle the changing of the null suffix gracefully so the - * old transformation rules don't just go away. - * - *----------------------------------------------------------------------- - */ -void -Suff_SetNull(name) - char *name; /* Name of null suffix */ -{ - Suff *s; - LstNode ln; - - ln = Lst_Find(sufflist, (ClientData)name, SuffSuffHasNameP); - if (ln != NILLNODE) { - s = (Suff *)Lst_Datum(ln); - if (suffNull != (Suff *)NULL) { - suffNull->flags &= ~SUFF_NULL; - } - s->flags |= SUFF_NULL; - /* - * XXX: Here's where the transformation mangling would take place - */ - suffNull = s; - } else { - Parse_Error (PARSE_WARNING, "Desired null suffix %s not defined.", - name); - } -} - -/*- - *----------------------------------------------------------------------- - * Suff_Init -- - * Initialize suffixes module - * - * Results: - * None - * - * Side Effects: - * Many - *----------------------------------------------------------------------- - */ -void -Suff_Init () -{ - sufflist = Lst_Init (FALSE); -#ifdef CLEANUP - suffClean = Lst_Init(FALSE); -#endif - srclist = Lst_Init (FALSE); - transforms = Lst_Init (FALSE); - - sNum = 0; - /* - * Create null suffix for single-suffix rules (POSIX). The thing doesn't - * actually go on the suffix list or everyone will think that's its - * suffix. - */ - emptySuff = suffNull = (Suff *) emalloc (sizeof (Suff)); - - suffNull->name = estrdup (""); - suffNull->nameLen = 0; - suffNull->searchPath = Lst_Init (FALSE); - Dir_Concat(suffNull->searchPath, dirSearchPath); - suffNull->children = Lst_Init (FALSE); - suffNull->parents = Lst_Init (FALSE); - suffNull->ref = Lst_Init (FALSE); - suffNull->sNum = sNum++; - suffNull->flags = SUFF_NULL; - suffNull->refCount = 1; - -} - - -/*- - *---------------------------------------------------------------------- - * Suff_End -- - * Cleanup the this module - * - * Results: - * None - * - * Side Effects: - * The memory is free'd. - *---------------------------------------------------------------------- - */ - -void -Suff_End() -{ -#ifdef CLEANUP - Lst_Destroy(sufflist, SuffFree); - Lst_Destroy(suffClean, SuffFree); - if (suffNull) - SuffFree(suffNull); - Lst_Destroy(srclist, NOFREE); - Lst_Destroy(transforms, NOFREE); -#endif -} - - -/********************* DEBUGGING FUNCTIONS **********************/ - -static int SuffPrintName(s, dummy) - ClientData s; - ClientData dummy; -{ - printf ("%s ", ((Suff *) s)->name); - return (dummy ? 0 : 0); -} - -static int -SuffPrintSuff (sp, dummy) - ClientData sp; - ClientData dummy; -{ - Suff *s = (Suff *) sp; - int flags; - int flag; - - printf ("# `%s' [%d] ", s->name, s->refCount); - - flags = s->flags; - if (flags) { - fputs (" (", stdout); - while (flags) { - flag = 1 << (ffs(flags) - 1); - flags &= ~flag; - switch (flag) { - case SUFF_NULL: - printf ("NULL"); - break; - case SUFF_INCLUDE: - printf ("INCLUDE"); - break; - case SUFF_LIBRARY: - printf ("LIBRARY"); - break; - } - fputc(flags ? '|' : ')', stdout); - } - } - fputc ('\n', stdout); - printf ("#\tTo: "); - Lst_ForEach (s->parents, SuffPrintName, (ClientData)0); - fputc ('\n', stdout); - printf ("#\tFrom: "); - Lst_ForEach (s->children, SuffPrintName, (ClientData)0); - fputc ('\n', stdout); - printf ("#\tSearch Path: "); - Dir_PrintPath (s->searchPath); - fputc ('\n', stdout); - return (dummy ? 0 : 0); -} - -static int -SuffPrintTrans (tp, dummy) - ClientData tp; - ClientData dummy; -{ - GNode *t = (GNode *) tp; - - printf ("%-16s: ", t->name); - Targ_PrintType (t->type); - fputc ('\n', stdout); - Lst_ForEach (t->commands, Targ_PrintCmd, (ClientData)0); - fputc ('\n', stdout); - return(dummy ? 0 : 0); -} - -void -Suff_PrintAll() -{ - printf ("#*** Suffixes:\n"); - Lst_ForEach (sufflist, SuffPrintSuff, (ClientData)0); - - printf ("#*** Transformations:\n"); - Lst_ForEach (transforms, SuffPrintTrans, (ClientData)0); -} diff --git a/bootstrap/bmake/targ.c b/bootstrap/bmake/targ.c deleted file mode 100644 index 90465a52d33..00000000000 --- a/bootstrap/bmake/targ.c +++ /dev/null @@ -1,726 +0,0 @@ -/* $NetBSD: targ.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $ */ - -/* - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: targ.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)targ.c 8.2 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: targ.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $"); -#endif -#endif /* not lint */ -#endif - -/*- - * targ.c -- - * Functions for maintaining the Lst allTargets. Target nodes are - * kept in two structures: a Lst, maintained by the list library, and a - * hash table, maintained by the hash library. - * - * Interface: - * Targ_Init Initialization procedure. - * - * Targ_End Cleanup the module - * - * Targ_List Return the list of all targets so far. - * - * Targ_NewGN Create a new GNode for the passed target - * (string). The node is *not* placed in the - * hash table, though all its fields are - * initialized. - * - * Targ_FindNode Find the node for a given target, creating - * and storing it if it doesn't exist and the - * flags are right (TARG_CREATE) - * - * Targ_FindList Given a list of names, find nodes for all - * of them. If a name doesn't exist and the - * TARG_NOCREATE flag was given, an error message - * is printed. Else, if a name doesn't exist, - * its node is created. - * - * Targ_Ignore Return TRUE if errors should be ignored when - * creating the given target. - * - * Targ_Silent Return TRUE if we should be silent when - * creating the given target. - * - * Targ_Precious Return TRUE if the target is precious and - * should not be removed if we are interrupted. - * - * Debugging: - * Targ_PrintGraph Print out the entire graphm all variables - * and statistics for the directory cache. Should - * print something for suffixes, too, but... - */ - -#include -#include -#include "make.h" -#include "hash.h" -#include "dir.h" - -static Lst allTargets; /* the list of all targets found so far */ -#ifdef CLEANUP -static Lst allGNs; /* List of all the GNodes */ -#endif -static Hash_Table targets; /* a hash table of same */ - -#define HTSIZE 191 /* initial size of hash table */ - -static int TargPrintOnlySrc __P((ClientData, ClientData)); -static int TargPrintName __P((ClientData, ClientData)); -static int TargPrintNode __P((ClientData, ClientData)); -#ifdef CLEANUP -static void TargFreeGN __P((ClientData)); -#endif -static int TargPropagateCohort __P((ClientData, ClientData)); -static int TargPropagateNode __P((ClientData, ClientData)); - -/*- - *----------------------------------------------------------------------- - * Targ_Init -- - * Initialize this module - * - * Results: - * None - * - * Side Effects: - * The allTargets list and the targets hash table are initialized - *----------------------------------------------------------------------- - */ -void -Targ_Init () -{ - allTargets = Lst_Init (FALSE); - Hash_InitTable (&targets, HTSIZE); -} - -/*- - *----------------------------------------------------------------------- - * Targ_End -- - * Finalize this module - * - * Results: - * None - * - * Side Effects: - * All lists and gnodes are cleared - *----------------------------------------------------------------------- - */ -void -Targ_End () -{ -#ifdef CLEANUP - Lst_Destroy(allTargets, NOFREE); - if (allGNs) - Lst_Destroy(allGNs, TargFreeGN); - Hash_DeleteTable(&targets); -#endif -} - -/*- - *----------------------------------------------------------------------- - * Targ_List -- - * Return the list of all targets - * - * Results: - * The list of all targets. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Lst -Targ_List () -{ - return allTargets; -} - -/*- - *----------------------------------------------------------------------- - * 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 (name) - char *name; /* the name to stick in the new node */ -{ - register GNode *gn; - - gn = (GNode *) emalloc (sizeof (GNode)); - gn->name = estrdup (name); - gn->uname = NULL; - gn->path = (char *) 0; - if (name[0] == '-' && name[1] == 'l') { - gn->type = OP_LIB; - } else { - gn->type = 0; - } - gn->unmade = 0; - gn->made = UNMADE; - gn->flags = 0; - gn->order = 0; - gn->mtime = gn->cmtime = 0; - gn->iParents = Lst_Init (FALSE); - gn->cohorts = Lst_Init (FALSE); - gn->parents = Lst_Init (FALSE); - gn->children = Lst_Init (FALSE); - gn->successors = Lst_Init (FALSE); - gn->preds = Lst_Init (FALSE); - Hash_InitTable(&gn->context, 0); - gn->commands = Lst_Init (FALSE); - gn->suffix = NULL; - gn->lineno = 0; - gn->fname = NULL; - -#ifdef CLEANUP - if (allGNs == NULL) - allGNs = Lst_Init(FALSE); - Lst_AtEnd(allGNs, (ClientData) gn); -#endif - - return (gn); -} - -#ifdef CLEANUP -/*- - *----------------------------------------------------------------------- - * TargFreeGN -- - * Destroy a GNode - * - * Results: - * None. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static void -TargFreeGN (gnp) - ClientData gnp; -{ - GNode *gn = (GNode *) gnp; - - - free(gn->name); - if (gn->uname) - free(gn->uname); - if (gn->path) - free(gn->path); - if (gn->fname) - free(gn->fname); - - Lst_Destroy(gn->iParents, NOFREE); - Lst_Destroy(gn->cohorts, NOFREE); - Lst_Destroy(gn->parents, NOFREE); - Lst_Destroy(gn->children, NOFREE); - Lst_Destroy(gn->successors, NOFREE); - Lst_Destroy(gn->preds, NOFREE); - Hash_DeleteTable(&gn->context); - Lst_Destroy(gn->commands, NOFREE); - free((Address)gn); -} -#endif - - -/*- - *----------------------------------------------------------------------- - * 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 NILGNODE 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 (name, flags) - char *name; /* the name to find */ - int flags; /* flags governing events when target not - * found */ -{ - 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); - (void) Lst_AtEnd (allTargets, (ClientData)gn); - } - } else { - he = Hash_FindEntry (&targets, name); - } - - if (he == (Hash_Entry *) NULL) { - return (NILGNODE); - } else { - return ((GNode *) 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. - * ----------------------------------------------------------------------- - */ -Lst -Targ_FindList (names, flags) - Lst names; /* list of names to find */ - int flags; /* flags used if no node is found for a given - * name */ -{ - Lst nodes; /* result list */ - register LstNode ln; /* name list element */ - register GNode *gn; /* node in tLn */ - char *name; - - nodes = Lst_Init (FALSE); - - if (Lst_Open (names) == FAILURE) { - return (nodes); - } - while ((ln = Lst_Next (names)) != NILLNODE) { - name = (char *)Lst_Datum(ln); - gn = Targ_FindNode (name, flags); - if (gn != NILGNODE) { - /* - * Note: Lst_AtEnd must come before the Lst_Concat so the nodes - * are added to the list in the order in which they were - * encountered in the makefile. - */ - (void) Lst_AtEnd (nodes, (ClientData)gn); - } else if (flags == TARG_NOCREATE) { - Error ("\"%s\" -- target unknown.", name); - } - } - Lst_Close (names); - return (nodes); -} - -/*- - *----------------------------------------------------------------------- - * Targ_Ignore -- - * Return true if should ignore errors when creating gn - * - * Results: - * TRUE if should ignore errors - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Boolean -Targ_Ignore (gn) - GNode *gn; /* node to check for */ -{ - 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 - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Boolean -Targ_Silent (gn) - GNode *gn; /* node to check for */ -{ - 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 - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -Boolean -Targ_Precious (gn) - GNode *gn; /* the node to check */ -{ - if (allPrecious || (gn->type & (OP_PRECIOUS|OP_DOUBLEDEP))) { - return (TRUE); - } else { - return (FALSE); - } -} - -/******************* DEBUG INFO PRINTING ****************/ - -static GNode *mainTarg; /* the main target, as set by Targ_SetMain */ -/*- - *----------------------------------------------------------------------- - * Targ_SetMain -- - * Set our idea of the main target we'll be creating. Used for - * debugging output. - * - * Results: - * None. - * - * Side Effects: - * "mainTarg" is set to the main target's node. - *----------------------------------------------------------------------- - */ -void -Targ_SetMain (gn) - GNode *gn; /* The main target we'll create */ -{ - mainTarg = gn; -} - -static int -TargPrintName (gnp, ppath) - ClientData gnp; - ClientData ppath; -{ - GNode *gn = (GNode *) gnp; - printf ("%s ", gn->name); -#ifdef notdef - if (ppath) { - if (gn->path) { - printf ("[%s] ", gn->path); - } - if (gn == mainTarg) { - printf ("(MAIN NAME) "); - } - } -#endif /* notdef */ - return (ppath ? 0 : 0); -} - - -int -Targ_PrintCmd (cmd, dummy) - ClientData cmd; - ClientData dummy; -{ - printf ("\t%s\n", (char *) cmd); - return (dummy ? 0 : 0); -} - -/*- - *----------------------------------------------------------------------- - * Targ_FmtTime -- - * Format a modification time in some reasonable way and return it. - * - * Results: - * The time reformatted. - * - * Side Effects: - * The time is placed in a static area, so it is overwritten - * with each call. - * - *----------------------------------------------------------------------- - */ -char * -Targ_FmtTime (time) - time_t time; -{ - struct tm *parts; - static char buf[128]; - - parts = localtime(&time); - (void)strftime(buf, sizeof buf, "%k:%M:%S %b %d, %Y", parts); - return(buf); -} - -/*- - *----------------------------------------------------------------------- - * Targ_PrintType -- - * Print out a type field giving only those attributes the user can - * set. - * - * Results: - * - * Side Effects: - * - *----------------------------------------------------------------------- - */ -void -Targ_PrintType (type) - register int type; -{ - register int tbit; - -#ifdef __STDC__ -#define PRINTBIT(attr) case CONCAT(OP_,attr): printf("." #attr " "); break -#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf("." #attr " "); break -#else -#define PRINTBIT(attr) case CONCAT(OP_,attr): printf(".attr "); break -#define PRINTDBIT(attr) case CONCAT(OP_,attr): if (DEBUG(TARG)) printf(".attr "); break -#endif /* __STDC__ */ - - type &= ~OP_OPMASK; - - while (type) { - tbit = 1 << (ffs(type) - 1); - type &= ~tbit; - - switch(tbit) { - PRINTBIT(OPTIONAL); - PRINTBIT(USE); - PRINTBIT(EXEC); - PRINTBIT(IGNORE); - PRINTBIT(PRECIOUS); - PRINTBIT(SILENT); - PRINTBIT(MAKE); - PRINTBIT(JOIN); - PRINTBIT(INVISIBLE); - PRINTBIT(NOTMAIN); - PRINTDBIT(LIB); - /*XXX: MEMBER is defined, so CONCAT(OP_,MEMBER) gives OP_"%" */ - case OP_MEMBER: if (DEBUG(TARG)) printf(".MEMBER "); break; - PRINTDBIT(ARCHV); - } - } -} - -/*- - *----------------------------------------------------------------------- - * TargPrintNode -- - * print the contents of a node - *----------------------------------------------------------------------- - */ -static int -TargPrintNode (gnp, passp) - ClientData gnp; - ClientData passp; -{ - GNode *gn = (GNode *) gnp; - int pass = *(int *) passp; - 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_USEBEFORE|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 (gn->iParents, TargPrintName, (ClientData)0); - fputc ('\n', stdout); - } - } - if (!Lst_IsEmpty (gn->parents)) { - printf("# parents: "); - Lst_ForEach (gn->parents, TargPrintName, (ClientData)0); - fputc ('\n', stdout); - } - - printf("%-16s", gn->name); - switch (gn->type & OP_OPMASK) { - case OP_DEPENDS: - printf(": "); break; - case OP_FORCE: - printf("! "); break; - case OP_DOUBLEDEP: - printf(":: "); break; - } - Targ_PrintType (gn->type); - Lst_ForEach (gn->children, TargPrintName, (ClientData)0); - fputc ('\n', stdout); - Lst_ForEach (gn->commands, Targ_PrintCmd, (ClientData)0); - printf("\n\n"); - if (gn->type & OP_DOUBLEDEP) { - Lst_ForEach (gn->cohorts, TargPrintNode, (ClientData)&pass); - } - } - return (0); -} - -/*- - *----------------------------------------------------------------------- - * TargPrintOnlySrc -- - * Print only those targets that are just a source. - * - * Results: - * 0. - * - * Side Effects: - * The name of each file is printed preceded by #\t - * - *----------------------------------------------------------------------- - */ -static int -TargPrintOnlySrc(gnp, dummy) - ClientData gnp; - ClientData dummy; -{ - GNode *gn = (GNode *) gnp; - if (OP_NOP(gn->type)) - printf("#\t%s [%s]\n", gn->name, gn->path ? gn->path : gn->name); - - return (dummy ? 0 : 0); -} - -/*- - *----------------------------------------------------------------------- - * Targ_PrintGraph -- - * print the entire graph. heh heh - * - * Results: - * none - * - * Side Effects: - * lots o' output - *----------------------------------------------------------------------- - */ -void -Targ_PrintGraph (pass) - int pass; /* Which pass this is. 1 => no processing - * 2 => processing done */ -{ - printf("#*** Input graph:\n"); - Lst_ForEach (allTargets, TargPrintNode, (ClientData)&pass); - printf("\n\n"); - printf("#\n# Files that are only sources:\n"); - Lst_ForEach (allTargets, TargPrintOnlySrc, (ClientData) 0); - printf("#*** Global Variables:\n"); - Var_Dump (VAR_GLOBAL); - printf("#*** Command-line Variables:\n"); - Var_Dump (VAR_CMD); - printf("\n"); - Dir_PrintDirectories(); - printf("\n"); - Suff_PrintAll(); -} - -static int -TargPropagateCohort (cgnp, pgnp) - ClientData cgnp; - ClientData pgnp; -{ - GNode *cgn = (GNode *) cgnp; - GNode *pgn = (GNode *) pgnp; - - cgn->type |= pgn->type & ~OP_OPMASK; - return (0); -} - -static int -TargPropagateNode (gnp, junk) - ClientData gnp; - ClientData junk; -{ - GNode *gn = (GNode *) gnp; - if (gn->type & OP_DOUBLEDEP) - Lst_ForEach (gn->cohorts, TargPropagateCohort, gnp); - return (0); -} - -void -Targ_Propagate () -{ - Lst_ForEach (allTargets, TargPropagateNode, (ClientData)0); -} diff --git a/bootstrap/bmake/trace.c b/bootstrap/bmake/trace.c deleted file mode 100644 index c02f620f3d7..00000000000 --- a/bootstrap/bmake/trace.c +++ /dev/null @@ -1,125 +0,0 @@ -/* $NetBSD: trace.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: trace.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $"; -#else -#include -#ifndef lint -__RCSID("$NetBSD: trace.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $"); -#endif /* not lint */ -#endif - -/*- - * trace.c -- - * handle logging of trace events generated by various parts of make. - * - * Interface: - * Trace_Init Initialize tracing (called once during - * the lifetime of the process) - * - * Trace_End Finalize tracing (called before make exits) - * - * Trace_Log Log an event about a particular make job. - */ - -#include -#include -#include - -#include "make.h" -#include "job.h" -#include "trace.h" - -static FILE *trfile; -static pid_t trpid; -char *trwd; - -static const char *evname[] = { - "BEG", - "END", - "ERR", - "JOB", - "DON", - "INT", -}; - -void -Trace_Init(pathname) - const char *pathname; -{ - char *p1; - if (pathname != NULL) { - trpid = getpid(); - trwd = Var_Value(".CURDIR", VAR_GLOBAL, &p1); - - trfile = fopen(pathname, "a"); - } -} - -void -Trace_Log(event, job) - TrEvent event; - Job *job; -{ - struct timeval now; - - if (trfile == NULL) - return; - - gettimeofday(&now, NULL); - - fprintf(trfile, "%ld.%06d %d %d %s %d %s", - now.tv_sec, (int)now.tv_usec, - jobTokensRunning, jobTokensFree, - evname[event], trpid, trwd); - if (job != NULL) { - fprintf(trfile, " %s %d %x %x", job->node->name, - job->pid, job->flags, job->node->type); - } - fputc('\n', trfile); - fflush(trfile); -} - -void -Trace_End() -{ - if (trfile != NULL) - fclose(trfile); -} diff --git a/bootstrap/bmake/trace.h b/bootstrap/bmake/trace.h deleted file mode 100644 index 8ca64f8bcda..00000000000 --- a/bootstrap/bmake/trace.h +++ /dev/null @@ -1,56 +0,0 @@ -/* $NetBSD: trace.h,v 1.2 2004/11/20 04:31:35 grant Exp $ */ - -/*- - * Copyright (c) 2000 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Bill Sommerfeld - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/*- - * trace.h -- - * Definitions pertaining to the tracing of jobs in parallel mode. - */ - -typedef enum { - MAKESTART, - MAKEEND, - MAKEERROR, - JOBSTART, - JOBEND, - MAKEINTR -} TrEvent; - -void Trace_Init(const char *); -void Trace_Log(TrEvent, Job *); -void Trace_End(void); - diff --git a/bootstrap/bmake/util.c b/bootstrap/bmake/util.c deleted file mode 100644 index 354e4647b3c..00000000000 --- a/bootstrap/bmake/util.c +++ /dev/null @@ -1,506 +0,0 @@ -/* $NetBSD: util.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $ */ - -/* - * Missing stuff from OS's - * - * $Id: util.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $ - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: util.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $"; -#else -#include -#ifndef lint -__RCSID("$NetBSD: util.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $"); -#endif -#endif - -#include -#include -#include "make.h" -#include -#ifdef HAVE_STRING_H -#include -#endif - -#ifndef __STDC__ -# ifndef const -# define const -# endif -#endif - -#if !defined(HAVE_STRERROR) - -extern int errno, sys_nerr; -extern char *sys_errlist[]; - -char * -strerror(e) - int e; -{ - static char buf[100]; - if (e < 0 || e >= sys_nerr) { - snprintf(buf, sizeof(buf), "Unknown error %d", e); - return buf; - } - else - return sys_errlist[e]; -} -#endif - -#if !defined(HAVE_STRDUP) -/* strdup - * - * Make a duplicate of a string. - * For systems which lack this function. - */ -char * -strdup(str) - const char *str; -{ - size_t len; - char *p; - - if (str == NULL) - return NULL; - len = strlen(str) + 1; - p = emalloc(len); - - return memcpy(p, str, len); -} - -#endif - -#if !defined(HAVE_SETENV) -int -setenv(name, value, dum) - const char *name; - const char *value; - int dum; -{ - register char *p; - int len = strlen(name) + strlen(value) + 2; /* = \0 */ - char *ptr = (char*) emalloc(len); - - (void) dum; - - if (ptr == NULL) - return -1; - - p = ptr; - - while (*name) - *p++ = *name++; - - *p++ = '='; - - while (*value) - *p++ = *value++; - - *p = '\0'; - - len = putenv(ptr); -/* free(ptr); */ - return len; -} -#endif - -#if defined(__hpux) && !defined(_HPUX_SOURCE) -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -int -killpg(pid, sig) - int pid, sig; -{ - return kill(-pid, sig); -} - -void -srandom(seed) - long seed; -{ - srand48(seed); -} - -long -random() -{ - return lrand48(); -} - -int -setpriority(which, who, niceval) - int which, who, niceval; -{ -#ifdef SYS_setpriority - return syscall(SYS_setpriority, which, who, niceval); -#else -#ifndef ENOSYS -# define ENOSYS 90 -#endif - extern int errno; - errno = ENOSYS; - return -1; -#endif -} - -int -setreuid(euid, ruid) - int euid, ruid; -{ - return setresuid(euid, ruid, -1); -} - -int -setregid(egid, rgid) - int egid, rgid; -{ - return setresgid(egid, rgid, -1); -} -#endif /* __hpux && !_HPUX_SOURCE */ - -#if defined(__hpux__) || defined(__hpux) - -/* strrcpy(): - * Like strcpy, going backwards and returning the new pointer - */ -static char * -strrcpy(ptr, str) - register char *ptr, *str; -{ - register int len = strlen(str); - - while (len) - *--ptr = str[--len]; - - return (ptr); -} /* end strrcpy */ - - -char *sys_siglist[] = { - "Signal 0", - "Hangup", /* SIGHUP */ - "Interrupt", /* SIGINT */ - "Quit", /* SIGQUIT */ - "Illegal instruction", /* SIGILL */ - "Trace/BPT trap", /* SIGTRAP */ - "IOT trap", /* SIGIOT */ - "EMT trap", /* SIGEMT */ - "Floating point exception", /* SIGFPE */ - "Killed", /* SIGKILL */ - "Bus error", /* SIGBUS */ - "Segmentation fault", /* SIGSEGV */ - "Bad system call", /* SIGSYS */ - "Broken pipe", /* SIGPIPE */ - "Alarm clock", /* SIGALRM */ - "Terminated", /* SIGTERM */ - "User defined signal 1", /* SIGUSR1 */ - "User defined signal 2", /* SIGUSR2 */ - "Child exited", /* SIGCLD */ - "Power-fail restart", /* SIGPWR */ - "Virtual timer expired", /* SIGVTALRM */ - "Profiling timer expired", /* SIGPROF */ - "I/O possible", /* SIGIO */ - "Window size changes", /* SIGWINDOW */ - "Stopped (signal)", /* SIGSTOP */ - "Stopped", /* SIGTSTP */ - "Continued", /* SIGCONT */ - "Stopped (tty input)", /* SIGTTIN */ - "Stopped (tty output)", /* SIGTTOU */ - "Urgent I/O condition", /* SIGURG */ - "Remote lock lost (NFS)", /* SIGLOST */ - "Signal 31", /* reserved */ - "DIL signal" /* SIGDIL */ -}; -#endif /* __hpux__ || __hpux */ - -#if defined(__hpux) && !defined(_HPUX_SOURCE) - -int -utimes(file, tvp) - char *file; - struct timeval tvp[2]; -{ - struct utimbuf t; - - t.actime = tvp[0].tv_sec; - t.modtime = tvp[1].tv_sec; - return(utime(file, &t)); -} - -#if !defined(BSD) && !defined(d_fileno) -# define d_fileno d_ino -#endif - -#ifndef DEV_DEV_COMPARE -# define DEV_DEV_COMPARE(a, b) ((a) == (b)) -#endif -#define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/'))) -#define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1]))) - -char * -getwd(pathname) - char *pathname; -{ - DIR *dp; - struct dirent *d; - extern int errno; - - struct stat st_root, st_cur, st_next, st_dotdot; - char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; - char *pathptr, *nextpathptr, *cur_name_add; - - /* find the inode of root */ - if (stat("/", &st_root) == -1) { - (void) snprintf(pathname, sizeof(pathname), - "getwd: Cannot stat \"/\" (%s)", strerror(errno)); - return (NULL); - } - pathbuf[MAXPATHLEN - 1] = '\0'; - pathptr = &pathbuf[MAXPATHLEN - 1]; - nextpathbuf[MAXPATHLEN - 1] = '\0'; - cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; - - /* find the inode of the current directory */ - if (lstat(".", &st_cur) == -1) { - (void) snprintf(pathname, sizeof(pathname), - "getwd: Cannot stat \".\" (%s)", strerror(errno)); - return (NULL); - } - nextpathptr = strrcpy(nextpathptr, "../"); - - /* Descend to root */ - for (;;) { - - /* look if we found root yet */ - if (st_cur.st_ino == st_root.st_ino && - DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { - (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr); - return (pathname); - } - - /* open the parent directory */ - if (stat(nextpathptr, &st_dotdot) == -1) { - (void) snprintf(pathname, sizeof(pathname), - "getwd: Cannot stat directory \"%s\" (%s)", - nextpathptr, strerror(errno)); - return (NULL); - } - if ((dp = opendir(nextpathptr)) == NULL) { - (void) snprintf(pathname, sizeof(pathname), - "getwd: Cannot open directory \"%s\" (%s)", - nextpathptr, strerror(errno)); - return (NULL); - } - - /* look in the parent for the entry with the same inode */ - if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { - /* Parent has same device. No need to stat every member */ - for (d = readdir(dp); d != NULL; d = readdir(dp)) - if (d->d_fileno == st_cur.st_ino) - break; - } - else { - /* - * Parent has a different device. This is a mount point so we - * need to stat every member - */ - for (d = readdir(dp); d != NULL; d = readdir(dp)) { - if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) - continue; - (void) strcpy(cur_name_add, d->d_name); - if (lstat(nextpathptr, &st_next) == -1) { - (void) snprintf(pathname, sizeof(pathname), - "getwd: Cannot stat \"%s\" (%s)", - d->d_name, strerror(errno)); - (void) closedir(dp); - return (NULL); - } - /* check if we found it yet */ - if (st_next.st_ino == st_cur.st_ino && - DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) - break; - } - } - if (d == NULL) { - (void) snprintf(pathname, sizeof(pathname), - "getwd: Cannot find \".\" in \"..\""); - (void) closedir(dp); - return (NULL); - } - st_cur = st_dotdot; - pathptr = strrcpy(pathptr, d->d_name); - pathptr = strrcpy(pathptr, "/"); - nextpathptr = strrcpy(nextpathptr, "../"); - (void) closedir(dp); - *cur_name_add = '\0'; - } -} /* end getwd */ - -#endif /* __hpux && !_HPUX_SOURCE */ - -#if !defined(HAVE_GETCWD) -char * -getcwd(path, sz) - char *path; - int sz; -{ - return getwd(path); -} -#endif - - -#if !defined(HAVE_VSNPRINTF) -#if !defined(BSD4_4) && !defined(SUNOS_5_7) && !defined(__linux__) -#ifdef __STDC__ -#include -#else -#include -#endif - -#if !defined(__osf__) -#ifdef _IOSTRG -#define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */ -#else -#if 0 -#define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */ -#endif -#endif /* _IOSTRG */ -#endif /* __osf__ */ - -int -vsnprintf(s, n, fmt, args) - char *s; - size_t n; - const char *fmt; - va_list args; -{ -#ifdef STRFLAG - FILE fakebuf; - - fakebuf._flag = STRFLAG; - /* - * Some os's are char * _ptr, others are unsigned char *_ptr... - * We cast to void * to make everyone happy. - */ - fakebuf._ptr = (void *) s; - fakebuf._cnt = n-1; - fakebuf._file = -1; - _doprnt(fmt, args, &fakebuf); - fakebuf._cnt++; - putc('\0', &fakebuf); - if (fakebuf._cnt<0) - fakebuf._cnt = 0; - return (n-fakebuf._cnt-1); -#else - (void) vsprintf(s, fmt, args); - return strlen(s); -#endif -} -#endif -#endif - -#if !defined(HAVE_SNPRINTF) -int -#ifdef __STDC__ -snprintf(char *s, size_t n, const char *fmt, ...) -#else -snprintf(va_alist) - va_dcl -#endif -{ - va_list ap; - int rv; -#ifdef __STDC__ - va_start(ap, fmt); -#else - char *s; - size_t n; - const char *fmt; - - va_start(ap); - - s = va_arg(ap, char *); - n = va_arg(ap, size_t); - fmt = va_arg(ap, const char *); -#endif - rv = vsnprintf(s, n, fmt, ap); - va_end(ap); - return rv; -} -#endif - -#if !defined(HAVE_STRFTIME) -int -strftime(buf, len, fmt, tm) - char *buf; - size_t len; - const char *fmt; - const struct tm *tm; -{ - static char months[][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; - - size_t s; - char *b = buf; - - while (*fmt) { - if (len == 0) - return buf - b; - if (*fmt != '%') { - *buf++ = *fmt++; - len--; - continue; - } - switch (*fmt++) { - case '%': - *buf++ = '%'; - len--; - if (len == 0) return buf - b; - /*FALLTHROUGH*/ - case '\0': - *buf = '%'; - s = 1; - break; - case 'k': - s = snprintf(buf, len, "%d", tm->tm_hour); - break; - case 'M': - s = snprintf(buf, len, "%02d", tm->tm_min); - break; - case 'S': - s = snprintf(buf, len, "%02d", tm->tm_sec); - break; - case 'b': - if (tm->tm_mon >= 12) - return buf - b; - s = snprintf(buf, len, "%s", months[tm->tm_mon]); - break; - case 'd': - s = snprintf(buf, len, "%s", tm->tm_mday); - break; - case 'Y': - s = snprintf(buf, len, "%s", 1900 + tm->tm_year); - break; - default: - s = snprintf(buf, len, "Unsupported format %c", - fmt[-1]); - break; - } - buf += s; - len -= s; - } -} -#endif diff --git a/bootstrap/bmake/var.c b/bootstrap/bmake/var.c deleted file mode 100644 index 76688887698..00000000000 --- a/bootstrap/bmake/var.c +++ /dev/null @@ -1,2928 +0,0 @@ -/* $NetBSD: var.c,v 1.2 2004/08/23 03:44:34 jlam Exp $ */ - -/* - * 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. - */ - -#ifdef MAKE_BOOTSTRAP -static char rcsid[] = "$NetBSD: var.c,v 1.2 2004/08/23 03:44:34 jlam Exp $"; -#else -#include -#ifndef lint -#if 0 -static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; -#else -__RCSID("$NetBSD: var.c,v 1.2 2004/08/23 03:44:34 jlam Exp $"); -#endif -#endif /* not lint */ -#endif - -#if !defined(MAKE_BOOTSTRAP) && !defined(lint) -__IDSTRING(rcs_id,"$Id: var.c,v 1.2 2004/08/23 03:44:34 jlam Exp $"); -#endif - -/*- - * var.c -- - * Variable-handling functions - * - * Interface: - * Var_Set Set the value of a variable in the given - * context. The variable is created if it doesn't - * yet exist. The value and variable name need not - * be preserved. - * - * Var_Append Append more characters to an existing variable - * in the given context. The variable needn't - * exist already -- it will be created if it doesn't. - * A space is placed between the old value and the - * new one. - * - * Var_Exists See if a variable exists. - * - * Var_Value Return the value of a variable in a context or - * NULL if the variable is undefined. - * - * Var_Subst Substitute named variable, or all variables if - * NULL in a string using - * the given context as the top-most one. If the - * third argument is non-zero, Parse_Error is - * called if any variables are undefined. - * - * Var_Parse Parse a variable expansion from a string and - * return the result and the number of characters - * consumed. - * - * Var_Delete Delete a variable in a context. - * - * Var_Init Initialize this module. - * - * Debugging: - * Var_Dump Print out all variables defined in the given - * context. - * - * XXX: There's a lot of duplication in these functions. - */ - -#include -#ifndef NO_REGEX -#include -#include -/* bmake supplies its own so this header is always present. */ -#ifndef HAVE_SYS_CDEFS_H -#define HAVE_SYS_CDEFS_H 1 -#endif -#if HAVE_REGEX_H -#include -#else -#include -#endif -#endif -#include -#include "make.h" -#include "buf.h" - -/* - * This is a harmless return value for Var_Parse that can be used by Var_Subst - * to determine if there was an error in parsing -- easier than returning - * a flag, as things outside this module don't give a hoot. - */ -char var_Error[] = ""; - -/* - * Similar to var_Error, but returned when the 'err' flag for Var_Parse is - * set false. Why not just use a constant? Well, gcc likes to condense - * identical string instances... - */ -static char varNoError[] = ""; - -/* - * Internally, variables are contained in four different contexts. - * 1) the environment. They may not be changed. If an environment - * variable is appended-to, the result is placed in the global - * context. - * 2) the global context. Variables set in the Makefile are located in - * the global context. It is the penultimate context searched when - * substituting. - * 3) the command-line context. All variables set on the command line - * are placed in this context. They are UNALTERABLE once placed here. - * 4) the local context. Each target has associated with it a context - * list. On this list are located the structures describing such - * local variables as $(@) and $(*) - * The four contexts are searched in the reverse order from which they are - * listed. - */ -GNode *VAR_GLOBAL; /* variables from the makefile */ -GNode *VAR_CMD; /* variables defined on the command-line */ - -#define FIND_CMD 0x1 /* look in VAR_CMD when searching */ -#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */ -#define FIND_ENV 0x4 /* look in the environment also */ - -typedef struct Var { - char *name; /* the variable's name */ - Buffer val; /* its value */ - int flags; /* miscellaneous status flags */ -#define VAR_IN_USE 1 /* Variable's value currently being used. - * Used to avoid recursion */ -#define VAR_FROM_ENV 2 /* Variable comes from the environment */ -#define VAR_JUNK 4 /* Variable is a junk variable that - * should be destroyed when done with - * it. Used by Var_Parse for undefined, - * modified variables */ -#define VAR_KEEP 8 /* Variable is VAR_JUNK, but we found - * a use for it in some modifier and - * the value is therefore valid */ -} Var; - - -/* Var*Pattern flags */ -#define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */ -#define VAR_SUB_ONE 0x02 /* Apply substitution to one word */ -#define VAR_SUB_MATCHED 0x04 /* There was a match */ -#define VAR_MATCH_START 0x08 /* Match at start of word */ -#define VAR_MATCH_END 0x10 /* Match at end of word */ -#define VAR_NOSUBST 0x20 /* don't expand vars in VarGetPattern */ - -/* Var_Set flags */ -#define VAR_NO_EXPORT 0x01 /* do not export */ - -typedef struct { - char *lhs; /* String to match */ - int leftLen; /* Length of string */ - char *rhs; /* Replacement string (w/ &'s removed) */ - int rightLen; /* Length of replacement */ - int flags; -} VarPattern; - -typedef struct { - GNode *ctxt; /* variable context */ - char *tvar; /* name of temp var */ - int tvarLen; - char *str; /* string to expand */ - int strLen; - int err; /* err for not defined */ -} VarLoop_t; - -#ifndef NO_REGEX -typedef struct { - regex_t re; - int nsub; - regmatch_t *matches; - char *replace; - int flags; -} VarREPattern; -#endif - -static Var *VarFind __P((char *, GNode *, int)); -static void VarAdd __P((char *, char *, GNode *)); -static Boolean VarHead __P((GNode *, char *, Boolean, Buffer, ClientData)); -static Boolean VarTail __P((GNode *, char *, Boolean, Buffer, ClientData)); -static Boolean VarSuffix __P((GNode *, char *, Boolean, Buffer, ClientData)); -static Boolean VarRoot __P((GNode *, char *, Boolean, Buffer, ClientData)); -static Boolean VarMatch __P((GNode *, char *, Boolean, Buffer, ClientData)); -#ifdef SYSVVARSUB -static Boolean VarSYSVMatch __P((GNode *, char *, Boolean, Buffer, - ClientData)); -#endif -static Boolean VarNoMatch __P((GNode *, char *, Boolean, Buffer, ClientData)); -#ifndef NO_REGEX -static void VarREError __P((int, regex_t *, const char *)); -static Boolean VarRESubstitute __P((GNode *, char *, Boolean, Buffer, - ClientData)); -#endif -static Boolean VarSubstitute __P((GNode *, char *, Boolean, Buffer, - ClientData)); -static Boolean VarLoopExpand __P((GNode *, char *, Boolean, Buffer, - ClientData)); -static char *VarGetPattern __P((GNode *, int, char **, int, int *, int *, - VarPattern *)); -static char *VarQuote __P((char *)); -static char *VarModify __P((GNode *, char *, Boolean (*)(GNode *, char *, - Boolean, Buffer, - ClientData), - ClientData)); -static char *VarSort __P((char *)); -static char *VarUniq __P((char *)); -static int VarWordCompare __P((const void *, const void *)); -static void VarPrintVar __P((ClientData)); - -/*- - *----------------------------------------------------------------------- - * VarFind -- - * Find the given variable in the given context and any other contexts - * indicated. - * - * Results: - * A pointer to the structure describing the desired variable or - * NIL if the variable does not exist. - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -static Var * -VarFind (name, ctxt, flags) - char *name; /* name to find */ - GNode *ctxt; /* context in which to find it */ - int flags; /* FIND_GLOBAL set means to look in the - * VAR_GLOBAL context as well. - * FIND_CMD set means to look in the VAR_CMD - * context also. - * FIND_ENV set means to look in the - * environment */ -{ - Hash_Entry *var; - Var *v; - - /* - * If the variable name begins with a '.', it could very well be one of - * the local ones. We check the name against all the local variables - * and substitute the short version in for 'name' if it matches one of - * them. - */ - if (*name == '.' && isupper((unsigned char) name[1])) - switch (name[1]) { - case 'A': - if (!strcmp(name, ".ALLSRC")) - name = ALLSRC; - if (!strcmp(name, ".ARCHIVE")) - name = ARCHIVE; - break; - case 'I': - if (!strcmp(name, ".IMPSRC")) - name = IMPSRC; - break; - case 'M': - if (!strcmp(name, ".MEMBER")) - name = MEMBER; - break; - case 'O': - if (!strcmp(name, ".OODATE")) - name = OODATE; - break; - case 'P': - if (!strcmp(name, ".PREFIX")) - name = PREFIX; - break; - case 'T': - if (!strcmp(name, ".TARGET")) - name = TARGET; - break; - } - /* - * First look for the variable in the given context. If it's not there, - * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order, - * depending on the FIND_* flags in 'flags' - */ - var = Hash_FindEntry (&ctxt->context, name); - - if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) { - var = Hash_FindEntry (&VAR_CMD->context, name); - } - if (!checkEnvFirst && (var == NULL) && (flags & FIND_GLOBAL) && - (ctxt != VAR_GLOBAL)) - { - var = Hash_FindEntry (&VAR_GLOBAL->context, name); - } - if ((var == NULL) && (flags & FIND_ENV)) { - char *env; - - if ((env = getenv (name)) != NULL) { - int len; - - v = (Var *) emalloc(sizeof(Var)); - v->name = estrdup(name); - - len = strlen(env); - - v->val = Buf_Init(len); - Buf_AddBytes(v->val, len, (Byte *)env); - - v->flags = VAR_FROM_ENV; - return (v); - } else if (checkEnvFirst && (flags & FIND_GLOBAL) && - (ctxt != VAR_GLOBAL)) - { - var = Hash_FindEntry (&VAR_GLOBAL->context, name); - if (var == NULL) { - return ((Var *) NIL); - } else { - return ((Var *)Hash_GetValue(var)); - } - } else { - return((Var *)NIL); - } - } else if (var == NULL) { - return ((Var *) NIL); - } else { - return ((Var *) Hash_GetValue(var)); - } -} - -/*- - *----------------------------------------------------------------------- - * VarAdd -- - * Add a new variable of name name and value val to the given context - * - * Results: - * None - * - * Side Effects: - * The new variable is placed at the front of the given context - * The name and val arguments are duplicated so they may - * safely be freed. - *----------------------------------------------------------------------- - */ -static void -VarAdd (name, val, ctxt) - char *name; /* name of variable to add */ - char *val; /* value to set it to */ - GNode *ctxt; /* context in which to set it */ -{ - register Var *v; - int len; - Hash_Entry *h; - - v = (Var *) emalloc (sizeof (Var)); - - len = val ? strlen(val) : 0; - v->val = Buf_Init(len+1); - Buf_AddBytes(v->val, len, (Byte *)val); - - v->flags = 0; - - h = Hash_CreateEntry (&ctxt->context, name, NULL); - Hash_SetValue(h, v); - v->name = h->name; - if (DEBUG(VAR)) { - printf("%s:%s = %s\n", ctxt->name, name, val); - } -} - -/*- - *----------------------------------------------------------------------- - * Var_Delete -- - * Remove a variable from a context. - * - * Results: - * None. - * - * Side Effects: - * The Var structure is removed and freed. - * - *----------------------------------------------------------------------- - */ -void -Var_Delete(name, ctxt) - char *name; - GNode *ctxt; -{ - Hash_Entry *ln; - - if (DEBUG(VAR)) { - printf("%s:delete %s\n", ctxt->name, name); - } - ln = Hash_FindEntry(&ctxt->context, name); - if (ln != NULL) { - register Var *v; - - v = (Var *)Hash_GetValue(ln); - if (v->name != ln->name) - free(v->name); - Hash_DeleteEntry(&ctxt->context, ln); - Buf_Destroy(v->val, TRUE); - free((Address) v); - } -} - -/*- - *----------------------------------------------------------------------- - * Var_Set -- - * Set the variable name to the value val in the given context. - * - * Results: - * None. - * - * Side Effects: - * If the variable doesn't yet exist, a new record is created for it. - * Else the old value is freed and the new one stuck in its place - * - * Notes: - * The variable is searched for only in its context before being - * created in that context. I.e. if the context is VAR_GLOBAL, - * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only - * VAR_CMD->context is searched. This is done to avoid the literally - * thousands of unnecessary strcmp's that used to be done to - * set, say, $(@) or $(<). - *----------------------------------------------------------------------- - */ -void -Var_Set (name, val, ctxt, flags) - char *name; /* name of variable to set */ - char *val; /* value to give to the variable */ - GNode *ctxt; /* context in which to set it */ - int flags; -{ - register Var *v; - char *cp = name; - - /* - * We only look for a variable in the given context since anything set - * here will override anything in a lower context, so there's not much - * point in searching them all just to save a bit of memory... - */ - if ((name = strchr(cp, '$'))) { - name = Var_Subst(NULL, cp, ctxt, 0); - } else - name = cp; - v = VarFind (name, ctxt, 0); - if (v == (Var *) NIL) { - VarAdd (name, val, ctxt); - } else { - Buf_Discard(v->val, Buf_Size(v->val)); - Buf_AddBytes(v->val, strlen(val), (Byte *)val); - - if (DEBUG(VAR)) { - printf("%s:%s = %s\n", ctxt->name, name, val); - } - } - /* - * Any variables given on the command line are automatically exported - * to the environment (as per POSIX standard) - */ - if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) { - - setenv(name, val, 1); - - Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL); - } - if (name != cp) - free(name); -} - -/*- - *----------------------------------------------------------------------- - * Var_Append -- - * The variable of the given name has the given value appended to it in - * the given context. - * - * Results: - * None - * - * Side Effects: - * If the variable doesn't exist, it is created. Else the strings - * are concatenated (with a space in between). - * - * Notes: - * Only if the variable is being sought in the global context is the - * environment searched. - * XXX: Knows its calling circumstances in that if called with ctxt - * an actual target, it will only search that context since only - * a local variable could be being appended to. This is actually - * a big win and must be tolerated. - *----------------------------------------------------------------------- - */ -void -Var_Append (name, val, ctxt) - char *name; /* Name of variable to modify */ - char *val; /* String to append to it */ - GNode *ctxt; /* Context in which this should occur */ -{ - register Var *v; - Hash_Entry *h; - char *cp = name; - - if ((name = strchr(cp, '$'))) { - name = Var_Subst(NULL, cp, ctxt, 0); - } else - name = cp; - - v = VarFind (name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0); - - if (v == (Var *) NIL) { - VarAdd (name, val, ctxt); - } else { - Buf_AddByte(v->val, (Byte)' '); - Buf_AddBytes(v->val, strlen(val), (Byte *)val); - - if (DEBUG(VAR)) { - printf("%s:%s = %s\n", ctxt->name, name, - (char *) Buf_GetAll(v->val, (int *)NULL)); - } - - if (v->flags & VAR_FROM_ENV) { - /* - * If the original variable came from the environment, we - * have to install it in the global context (we could place - * it in the environment, but then we should provide a way to - * export other variables...) - */ - v->flags &= ~VAR_FROM_ENV; - h = Hash_CreateEntry (&ctxt->context, name, NULL); - Hash_SetValue(h, v); - } - } - if (name != cp) - free(name); -} - -/*- - *----------------------------------------------------------------------- - * Var_Exists -- - * See if the given variable exists. - * - * Results: - * TRUE if it does, FALSE if it doesn't - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -Boolean -Var_Exists(name, ctxt) - char *name; /* Variable to find */ - GNode *ctxt; /* Context in which to start search */ -{ - Var *v; - - v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV); - - if (v == (Var *)NIL) { - return(FALSE); - } else if (v->flags & VAR_FROM_ENV) { - free(v->name); - Buf_Destroy(v->val, TRUE); - free((char *)v); - } - return(TRUE); -} - -/*- - *----------------------------------------------------------------------- - * Var_Value -- - * Return the value of the named variable in the given context - * - * Results: - * The value if the variable exists, NULL if it doesn't - * - * Side Effects: - * None - *----------------------------------------------------------------------- - */ -char * -Var_Value (name, ctxt, frp) - char *name; /* name to find */ - GNode *ctxt; /* context in which to search for it */ - char **frp; -{ - Var *v; - - v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); - *frp = NULL; - if (v != (Var *) NIL) { - char *p = ((char *)Buf_GetAll(v->val, (int *)NULL)); - if (v->flags & VAR_FROM_ENV) { - free(v->name); - Buf_Destroy(v->val, FALSE); - free((Address) v); - *frp = p; - } - return p; - } else { - return ((char *) NULL); - } -} - -/*- - *----------------------------------------------------------------------- - * VarHead -- - * Remove the tail of the given word and place the result in the given - * buffer. - * - * Results: - * TRUE if characters were added to the buffer (a space needs to be - * added to the buffer before the next word). - * - * Side Effects: - * The trimmed word is added to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarHead (ctx, word, addSpace, buf, dummy) - GNode *ctx; - char *word; /* Word to trim */ - Boolean addSpace; /* True if need to add a space to the buffer - * before sticking in the head */ - Buffer buf; /* Buffer in which to store it */ - ClientData dummy; -{ - register char *slash; - - slash = strrchr (word, '/'); - if (slash != (char *)NULL) { - if (addSpace) { - Buf_AddByte (buf, (Byte)' '); - } - *slash = '\0'; - Buf_AddBytes (buf, strlen (word), (Byte *)word); - *slash = '/'; - return (TRUE); - } else { - /* - * If no directory part, give . (q.v. the POSIX standard) - */ - if (addSpace) { - Buf_AddBytes(buf, 2, (Byte *)" ."); - } else { - Buf_AddByte(buf, (Byte)'.'); - } - } - return(dummy ? TRUE : TRUE); -} - -/*- - *----------------------------------------------------------------------- - * VarTail -- - * Remove the head of the given word and place the result in the given - * buffer. - * - * Results: - * TRUE if characters were added to the buffer (a space needs to be - * added to the buffer before the next word). - * - * Side Effects: - * The trimmed word is added to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarTail (ctx, word, addSpace, buf, dummy) - GNode *ctx; - char *word; /* Word to trim */ - Boolean addSpace; /* TRUE if need to stick a space in the - * buffer before adding the tail */ - Buffer buf; /* Buffer in which to store it */ - ClientData dummy; -{ - register char *slash; - - if (addSpace) { - Buf_AddByte (buf, (Byte)' '); - } - - slash = strrchr (word, '/'); - if (slash != (char *)NULL) { - *slash++ = '\0'; - Buf_AddBytes (buf, strlen(slash), (Byte *)slash); - slash[-1] = '/'; - } else { - Buf_AddBytes (buf, strlen(word), (Byte *)word); - } - return (dummy ? TRUE : TRUE); -} - -/*- - *----------------------------------------------------------------------- - * VarSuffix -- - * Place the suffix of the given word in the given buffer. - * - * Results: - * TRUE if characters were added to the buffer (a space needs to be - * added to the buffer before the next word). - * - * Side Effects: - * The suffix from the word is placed in the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarSuffix (ctx, word, addSpace, buf, dummy) - GNode *ctx; - char *word; /* Word to trim */ - Boolean addSpace; /* TRUE if need to add a space before placing - * the suffix in the buffer */ - Buffer buf; /* Buffer in which to store it */ - ClientData dummy; -{ - register char *dot; - - dot = strrchr (word, '.'); - if (dot != (char *)NULL) { - if (addSpace) { - Buf_AddByte (buf, (Byte)' '); - } - *dot++ = '\0'; - Buf_AddBytes (buf, strlen (dot), (Byte *)dot); - dot[-1] = '.'; - addSpace = TRUE; - } - return (dummy ? addSpace : addSpace); -} - -/*- - *----------------------------------------------------------------------- - * VarRoot -- - * Remove the suffix of the given word and place the result in the - * buffer. - * - * Results: - * TRUE if characters were added to the buffer (a space needs to be - * added to the buffer before the next word). - * - * Side Effects: - * The trimmed word is added to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarRoot (ctx, word, addSpace, buf, dummy) - GNode *ctx; - char *word; /* Word to trim */ - Boolean addSpace; /* TRUE if need to add a space to the buffer - * before placing the root in it */ - Buffer buf; /* Buffer in which to store it */ - ClientData dummy; -{ - register char *dot; - - if (addSpace) { - Buf_AddByte (buf, (Byte)' '); - } - - dot = strrchr (word, '.'); - if (dot != (char *)NULL) { - *dot = '\0'; - Buf_AddBytes (buf, strlen (word), (Byte *)word); - *dot = '.'; - } else { - Buf_AddBytes (buf, strlen(word), (Byte *)word); - } - return (dummy ? TRUE : TRUE); -} - -/*- - *----------------------------------------------------------------------- - * VarMatch -- - * Place the word in the buffer if it matches the given pattern. - * Callback function for VarModify to implement the :M modifier. - * - * Results: - * TRUE if a space should be placed in the buffer before the next - * word. - * - * Side Effects: - * The word may be copied to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarMatch (ctx, word, addSpace, buf, pattern) - GNode *ctx; - char *word; /* Word to examine */ - Boolean addSpace; /* TRUE if need to add a space to the - * buffer before adding the word, if it - * matches */ - Buffer buf; /* Buffer in which to store it */ - ClientData pattern; /* Pattern the word must match */ -{ - if (Str_Match(word, (char *) pattern)) { - if (addSpace) { - Buf_AddByte(buf, (Byte)' '); - } - addSpace = TRUE; - Buf_AddBytes(buf, strlen(word), (Byte *)word); - } - return(addSpace); -} - -#ifdef SYSVVARSUB -/*- - *----------------------------------------------------------------------- - * VarSYSVMatch -- - * Place the word in the buffer if it matches the given pattern. - * Callback function for VarModify to implement the System V % - * modifiers. - * - * Results: - * TRUE if a space should be placed in the buffer before the next - * word. - * - * Side Effects: - * The word may be copied to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarSYSVMatch (ctx, word, addSpace, buf, patp) - GNode *ctx; - char *word; /* Word to examine */ - Boolean addSpace; /* TRUE if need to add a space to the - * buffer before adding the word, if it - * matches */ - Buffer buf; /* Buffer in which to store it */ - ClientData patp; /* Pattern the word must match */ -{ - int len; - char *ptr; - VarPattern *pat = (VarPattern *) patp; - char *varexp; - - if (addSpace) - Buf_AddByte(buf, (Byte)' '); - - addSpace = TRUE; - - if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) { - varexp = Var_Subst(NULL, pat->rhs, ctx, 0); - Str_SYSVSubst(buf, varexp, ptr, len); - free(varexp); - } else { - Buf_AddBytes(buf, strlen(word), (Byte *) word); - } - - return(addSpace); -} -#endif - - -/*- - *----------------------------------------------------------------------- - * VarNoMatch -- - * Place the word in the buffer if it doesn't match the given pattern. - * Callback function for VarModify to implement the :N modifier. - * - * Results: - * TRUE if a space should be placed in the buffer before the next - * word. - * - * Side Effects: - * The word may be copied to the buffer. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarNoMatch (ctx, word, addSpace, buf, pattern) - GNode *ctx; - char *word; /* Word to examine */ - Boolean addSpace; /* TRUE if need to add a space to the - * buffer before adding the word, if it - * matches */ - Buffer buf; /* Buffer in which to store it */ - ClientData pattern; /* Pattern the word must match */ -{ - if (!Str_Match(word, (char *) pattern)) { - if (addSpace) { - Buf_AddByte(buf, (Byte)' '); - } - addSpace = TRUE; - Buf_AddBytes(buf, strlen(word), (Byte *)word); - } - return(addSpace); -} - - -/*- - *----------------------------------------------------------------------- - * VarSubstitute -- - * Perform a string-substitution on the given word, placing the - * result in the passed buffer. - * - * Results: - * TRUE if a space is needed before more characters are added. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarSubstitute (ctx, word, addSpace, buf, patternp) - GNode *ctx; - char *word; /* Word to modify */ - Boolean addSpace; /* True if space should be added before - * other characters */ - Buffer buf; /* Buffer for result */ - ClientData patternp; /* Pattern for substitution */ -{ - register int wordLen; /* Length of word */ - register char *cp; /* General pointer */ - VarPattern *pattern = (VarPattern *) patternp; - - wordLen = strlen(word); - if ((pattern->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) != - (VAR_SUB_ONE|VAR_SUB_MATCHED)) { - /* - * Still substituting -- break it down into simple anchored cases - * and if none of them fits, perform the general substitution case. - */ - if ((pattern->flags & VAR_MATCH_START) && - (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) { - /* - * Anchored at start and beginning of word matches pattern - */ - if ((pattern->flags & VAR_MATCH_END) && - (wordLen == pattern->leftLen)) { - /* - * Also anchored at end and matches to the end (word - * is same length as pattern) add space and rhs only - * if rhs is non-null. - */ - if (pattern->rightLen != 0) { - if (addSpace) { - Buf_AddByte(buf, (Byte)' '); - } - addSpace = TRUE; - Buf_AddBytes(buf, pattern->rightLen, - (Byte *)pattern->rhs); - } - pattern->flags |= VAR_SUB_MATCHED; - } else if (pattern->flags & VAR_MATCH_END) { - /* - * Doesn't match to end -- copy word wholesale - */ - goto nosub; - } else { - /* - * Matches at start but need to copy in trailing characters - */ - if ((pattern->rightLen + wordLen - pattern->leftLen) != 0){ - if (addSpace) { - Buf_AddByte(buf, (Byte)' '); - } - addSpace = TRUE; - } - Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs); - Buf_AddBytes(buf, wordLen - pattern->leftLen, - (Byte *)(word + pattern->leftLen)); - pattern->flags |= VAR_SUB_MATCHED; - } - } else if (pattern->flags & VAR_MATCH_START) { - /* - * Had to match at start of word and didn't -- copy whole word. - */ - goto nosub; - } else if (pattern->flags & VAR_MATCH_END) { - /* - * Anchored at end, Find only place match could occur (leftLen - * characters from the end of the word) and see if it does. Note - * that because the $ will be left at the end of the lhs, we have - * to use strncmp. - */ - cp = word + (wordLen - pattern->leftLen); - if ((cp >= word) && - (strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) { - /* - * Match found. If we will place characters in the buffer, - * add a space before hand as indicated by addSpace, then - * stuff in the initial, unmatched part of the word followed - * by the right-hand-side. - */ - if (((cp - word) + pattern->rightLen) != 0) { - if (addSpace) { - Buf_AddByte(buf, (Byte)' '); - } - addSpace = TRUE; - } - Buf_AddBytes(buf, cp - word, (Byte *)word); - Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs); - pattern->flags |= VAR_SUB_MATCHED; - } else { - /* - * Had to match at end and didn't. Copy entire word. - */ - goto nosub; - } - } else { - /* - * Pattern is unanchored: search for the pattern in the word using - * String_FindSubstring, copying unmatched portions and the - * right-hand-side for each match found, handling non-global - * substitutions correctly, etc. When the loop is done, any - * remaining part of the word (word and wordLen are adjusted - * accordingly through the loop) is copied straight into the - * buffer. - * addSpace is set FALSE as soon as a space is added to the - * buffer. - */ - register Boolean done; - int origSize; - - done = FALSE; - origSize = Buf_Size(buf); - while (!done) { - cp = Str_FindSubstring(word, pattern->lhs); - if (cp != (char *)NULL) { - if (addSpace && (((cp - word) + pattern->rightLen) != 0)){ - Buf_AddByte(buf, (Byte)' '); - addSpace = FALSE; - } - Buf_AddBytes(buf, cp-word, (Byte *)word); - Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs); - wordLen -= (cp - word) + pattern->leftLen; - word = cp + pattern->leftLen; - if (wordLen == 0) { - done = TRUE; - } - if ((pattern->flags & VAR_SUB_GLOBAL) == 0) { - done = TRUE; - } - pattern->flags |= VAR_SUB_MATCHED; - } else { - done = TRUE; - } - } - if (wordLen != 0) { - if (addSpace) { - Buf_AddByte(buf, (Byte)' '); - } - Buf_AddBytes(buf, wordLen, (Byte *)word); - } - /* - * If added characters to the buffer, need to add a space - * before we add any more. If we didn't add any, just return - * the previous value of addSpace. - */ - return ((Buf_Size(buf) != origSize) || addSpace); - } - return (addSpace); - } - nosub: - if (addSpace) { - Buf_AddByte(buf, (Byte)' '); - } - Buf_AddBytes(buf, wordLen, (Byte *)word); - return(TRUE); -} - -#ifndef NO_REGEX -/*- - *----------------------------------------------------------------------- - * VarREError -- - * Print the error caused by a regcomp or regexec call. - * - * Results: - * None. - * - * Side Effects: - * An error gets printed. - * - *----------------------------------------------------------------------- - */ -static void -VarREError(err, pat, str) - int err; - regex_t *pat; - const char *str; -{ - char *errbuf; - int errlen; - - errlen = regerror(err, pat, 0, 0); - errbuf = emalloc(errlen); - regerror(err, pat, errbuf, errlen); - Error("%s: %s", str, errbuf); - free(errbuf); -} - - -/*- - *----------------------------------------------------------------------- - * VarRESubstitute -- - * Perform a regex substitution on the given word, placing the - * result in the passed buffer. - * - * Results: - * TRUE if a space is needed before more characters are added. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarRESubstitute(ctx, word, addSpace, buf, patternp) - GNode *ctx; - char *word; - Boolean addSpace; - Buffer buf; - ClientData patternp; -{ - VarREPattern *pat; - int xrv; - char *wp; - char *rp; - int added; - int flags = 0; - -#define MAYBE_ADD_SPACE() \ - if (addSpace && !added) \ - Buf_AddByte(buf, ' '); \ - added = 1 - - added = 0; - wp = word; - pat = patternp; - - if ((pat->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) == - (VAR_SUB_ONE|VAR_SUB_MATCHED)) - xrv = REG_NOMATCH; - else { - tryagain: - xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags); - } - - switch (xrv) { - case 0: - pat->flags |= VAR_SUB_MATCHED; - if (pat->matches[0].rm_so > 0) { - MAYBE_ADD_SPACE(); - Buf_AddBytes(buf, pat->matches[0].rm_so, wp); - } - - for (rp = pat->replace; *rp; rp++) { - if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) { - MAYBE_ADD_SPACE(); - Buf_AddByte(buf,rp[1]); - rp++; - } - else if ((*rp == '&') || - ((*rp == '\\') && isdigit((unsigned char)rp[1]))) { - int n; - char *subbuf; - int sublen; - char errstr[3]; - - if (*rp == '&') { - n = 0; - errstr[0] = '&'; - errstr[1] = '\0'; - } else { - n = rp[1] - '0'; - errstr[0] = '\\'; - errstr[1] = rp[1]; - errstr[2] = '\0'; - rp++; - } - - if (n > pat->nsub) { - Error("No subexpression %s", &errstr[0]); - subbuf = ""; - sublen = 0; - } else if ((pat->matches[n].rm_so == -1) && - (pat->matches[n].rm_eo == -1)) { - Error("No match for subexpression %s", &errstr[0]); - subbuf = ""; - sublen = 0; - } else { - subbuf = wp + pat->matches[n].rm_so; - sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so; - } - - if (sublen > 0) { - MAYBE_ADD_SPACE(); - Buf_AddBytes(buf, sublen, subbuf); - } - } else { - MAYBE_ADD_SPACE(); - Buf_AddByte(buf, *rp); - } - } - wp += pat->matches[0].rm_eo; - if (pat->flags & VAR_SUB_GLOBAL) { - flags |= REG_NOTBOL; - if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) { - MAYBE_ADD_SPACE(); - Buf_AddByte(buf, *wp); - wp++; - - } - if (*wp) - goto tryagain; - } - if (*wp) { - MAYBE_ADD_SPACE(); - Buf_AddBytes(buf, strlen(wp), wp); - } - break; - default: - VarREError(xrv, &pat->re, "Unexpected regex error"); - /* fall through */ - case REG_NOMATCH: - if (*wp) { - MAYBE_ADD_SPACE(); - Buf_AddBytes(buf,strlen(wp),wp); - } - break; - } - return(addSpace||added); -} -#endif - - - -/*- - *----------------------------------------------------------------------- - * VarLoopExpand -- - * Implements the :@@@ modifier of ODE make. - * We set the temp variable named in pattern.lhs to word and expand - * pattern.rhs storing the result in the passed buffer. - * - * Results: - * TRUE if a space is needed before more characters are added. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static Boolean -VarLoopExpand (ctx, word, addSpace, buf, loopp) - GNode *ctx; - char *word; /* Word to modify */ - Boolean addSpace; /* True if space should be added before - * other characters */ - Buffer buf; /* Buffer for result */ - ClientData loopp; /* Data for substitution */ -{ - VarLoop_t *loop = (VarLoop_t *) loopp; - char *s; - int slen; - - if (word && *word) { - Var_Set(loop->tvar, word, loop->ctxt, VAR_NO_EXPORT); - s = Var_Subst(NULL, loop->str, loop->ctxt, loop->err); - if (s != NULL && *s != '\0') { - if (addSpace && *s != '\n') - Buf_AddByte(buf, ' '); - Buf_AddBytes(buf, (slen = strlen(s)), (Byte *)s); - addSpace = (slen > 0 && s[slen - 1] != '\n'); - free(s); - } - } - return addSpace; -} - -/*- - *----------------------------------------------------------------------- - * VarModify -- - * Modify each of the words of the passed string using the given - * function. Used to implement all modifiers. - * - * Results: - * A string of all the words modified appropriately. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarModify (ctx, str, modProc, datum) - GNode *ctx; - char *str; /* String whose words should be trimmed */ - /* Function to use to modify them */ - Boolean (*modProc) __P((GNode *, char *, Boolean, Buffer, - ClientData)); - ClientData datum; /* Datum to pass it */ -{ - Buffer buf; /* Buffer for the new string */ - Boolean addSpace; /* TRUE if need to add a space to the - * buffer before adding the trimmed - * word */ - char **av; /* word list [first word does not count] */ - char *as; /* word list memory */ - int ac, i; - - buf = Buf_Init (0); - addSpace = FALSE; - - av = brk_string(str, &ac, FALSE, &as); - - for (i = 0; i < ac; i++) - addSpace = (*modProc)(ctx, av[i], addSpace, buf, datum); - - free(as); - free(av); - - Buf_AddByte (buf, '\0'); - str = (char *)Buf_GetAll (buf, (int *)NULL); - Buf_Destroy (buf, FALSE); - return (str); -} - - -static int -VarWordCompare(a, b) - const void *a; - const void *b; -{ - int r = strcmp(*(char **)a, *(char **)b); - return r; -} - -/*- - *----------------------------------------------------------------------- - * VarSort -- - * Sort the words in the string. - * - * Results: - * A string containing the words sorted - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarSort (str) - char *str; /* String whose words should be sorted */ - /* Function to use to modify them */ -{ - Buffer buf; /* Buffer for the new string */ - char **av; /* word list [first word does not count] */ - char *as; /* word list memory */ - int ac, i; - - buf = Buf_Init (0); - - av = brk_string(str, &ac, FALSE, &as); - - if (ac > 0) - qsort(av, ac, sizeof(char *), VarWordCompare); - - for (i = 0; i < ac; i++) { - Buf_AddBytes(buf, strlen(av[i]), (Byte *) av[i]); - if (i != ac - 1) - Buf_AddByte (buf, ' '); - } - - free(as); - free(av); - - Buf_AddByte (buf, '\0'); - str = (char *)Buf_GetAll (buf, (int *)NULL); - Buf_Destroy (buf, FALSE); - return (str); -} - - -/*- - *----------------------------------------------------------------------- - * VarUniq -- - * Remove adjacent duplicate words. - * - * Results: - * A string containing the resulting words. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarUniq(str) - char *str; /* String whose words should be sorted */ - /* Function to use to modify them */ -{ - Buffer buf; /* Buffer for new string */ - char **av; /* List of words to affect */ - char *as; /* Word list memory */ - int ac, i, j; - - buf = Buf_Init(0); - av = brk_string(str, &ac, FALSE, &as); - - if (ac > 1) { - for (j = 0, i = 1; i < ac; i++) - if (strcmp(av[i], av[j]) != 0 && (++j != i)) - av[j] = av[i]; - ac = j + 1; - } - - for (i = 0; i < ac; i++) { - Buf_AddBytes(buf, strlen(av[i]), (Byte *)av[i]); - if (i != ac - 1) - Buf_AddByte(buf, ' '); - } - - free(as); - free(av); - - Buf_AddByte(buf, '\0'); - str = (char *)Buf_GetAll(buf, (int *)NULL); - Buf_Destroy(buf, FALSE); - return str; -} - - -/*- - *----------------------------------------------------------------------- - * VarGetPattern -- - * Pass through the tstr looking for 1) escaped delimiters, - * '$'s and backslashes (place the escaped character in - * uninterpreted) and 2) unescaped $'s that aren't before - * the delimiter (expand the variable substitution unless flags - * has VAR_NOSUBST set). - * Return the expanded string or NULL if the delimiter was missing - * If pattern is specified, handle escaped ampersands, and replace - * unescaped ampersands with the lhs of the pattern. - * - * Results: - * A string of all the words modified appropriately. - * If length is specified, return the string length of the buffer - * If flags is specified and the last character of the pattern is a - * $ set the VAR_MATCH_END bit of flags. - * - * Side Effects: - * None. - *----------------------------------------------------------------------- - */ -static char * -VarGetPattern(ctxt, err, tstr, delim, flags, length, pattern) - GNode *ctxt; - int err; - char **tstr; - int delim; - int *flags; - int *length; - VarPattern *pattern; -{ - char *cp; - Buffer buf = Buf_Init(0); - int junk; - if (length == NULL) - length = &junk; - -#define IS_A_MATCH(cp, delim) \ - ((cp[0] == '\\') && ((cp[1] == delim) || \ - (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&')))) - - /* - * Skim through until the matching delimiter is found; - * pick up variable substitutions on the way. Also allow - * backslashes to quote the delimiter, $, and \, but don't - * touch other backslashes. - */ - for (cp = *tstr; *cp && (*cp != delim); cp++) { - if (IS_A_MATCH(cp, delim)) { - Buf_AddByte(buf, (Byte) cp[1]); - cp++; - } else if (*cp == '$') { - if (cp[1] == delim) { - if (flags == NULL) - Buf_AddByte(buf, (Byte) *cp); - else - /* - * Unescaped $ at end of pattern => anchor - * pattern at end. - */ - *flags |= VAR_MATCH_END; - } else { - if (flags == NULL || (*flags & VAR_NOSUBST) == 0) { - char *cp2; - int len; - Boolean freeIt; - - /* - * If unescaped dollar sign not before the - * delimiter, assume it's a variable - * substitution and recurse. - */ - cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt); - Buf_AddBytes(buf, strlen(cp2), (Byte *) cp2); - if (freeIt) - free(cp2); - cp += len - 1; - } else { - char *cp2 = &cp[1]; - - if (*cp2 == '(' || *cp2 == '{') { - /* - * Find the end of this variable reference - * and suck it in without further ado. - * It will be interperated later. - */ - int have = *cp2; - int want = (*cp2 == '(') ? ')' : '}'; - int depth = 1; - - for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) { - if (cp2[-1] != '\\') { - if (*cp2 == have) - ++depth; - if (*cp2 == want) - --depth; - } - } - Buf_AddBytes(buf, cp2 - cp, (Byte *)cp); - cp = --cp2; - } else - Buf_AddByte(buf, (Byte) *cp); - } - } - } - else if (pattern && *cp == '&') - Buf_AddBytes(buf, pattern->leftLen, (Byte *)pattern->lhs); - else - Buf_AddByte(buf, (Byte) *cp); - } - - Buf_AddByte(buf, (Byte) '\0'); - - if (*cp != delim) { - *tstr = cp; - *length = 0; - return NULL; - } - else { - *tstr = ++cp; - cp = (char *) Buf_GetAll(buf, length); - *length -= 1; /* Don't count the NULL */ - Buf_Destroy(buf, FALSE); - return cp; - } -} - -/*- - *----------------------------------------------------------------------- - * VarQuote -- - * Quote shell meta-characters in the string - * - * Results: - * The quoted string - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -static char * -VarQuote(str) - char *str; -{ - - Buffer buf; - /* This should cover most shells :-( */ - static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~"; - - buf = Buf_Init (MAKE_BSIZE); - for (; *str; str++) { - if (strchr(meta, *str) != NULL) - Buf_AddByte(buf, (Byte)'\\'); - Buf_AddByte(buf, (Byte)*str); - } - Buf_AddByte(buf, (Byte) '\0'); - str = (char *)Buf_GetAll (buf, (int *)NULL); - Buf_Destroy (buf, FALSE); - return str; -} - - -/*- - *----------------------------------------------------------------------- - * Var_Parse -- - * Given the start of a variable invocation, extract the variable - * name and find its value, then modify it according to the - * specification. - * - * Results: - * The (possibly-modified) value of the variable or var_Error if the - * specification is invalid. The length of the specification is - * placed in *lengthPtr (for invalid specifications, this is just - * 2...?). - * A Boolean in *freePtr telling whether the returned string should - * be freed by the caller. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -char * -Var_Parse (str, ctxt, err, lengthPtr, freePtr) - char *str; /* The string to parse */ - GNode *ctxt; /* The context for the variable */ - Boolean err; /* TRUE if undefined variables are an error */ - int *lengthPtr; /* OUT: The length of the specification */ - Boolean *freePtr; /* OUT: TRUE if caller should free result */ -{ - register char *tstr; /* Pointer into str */ - Var *v; /* Variable in invocation */ - char *cp; /* Secondary pointer into str (place marker - * for tstr) */ - Boolean haveModifier;/* TRUE if have modifiers for the variable */ - register char endc; /* Ending character when variable in parens - * or braces */ - register char startc=0; /* Starting character when variable in parens - * or braces */ - int cnt; /* Used to count brace pairs when variable in - * in parens or braces */ - int vlen; /* Length of variable name */ - char *start; - char delim; - Boolean dynamic; /* TRUE if the variable is local and we're - * expanding it in a non-local context. This - * is done to support dynamic sources. The - * result is just the invocation, unaltered */ - - *freePtr = FALSE; - dynamic = FALSE; - start = str; - - if (str[1] != '(' && str[1] != '{') { - /* - * If it's not bounded by braces of some sort, life is much simpler. - * We just need to check for the first character and return the - * value if it exists. - */ - char name[2]; - - name[0] = str[1]; - name[1] = '\0'; - - v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); - if (v == (Var *)NIL) { - *lengthPtr = 2; - - if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { - /* - * If substituting a local variable in a non-local context, - * assume it's for dynamic source stuff. We have to handle - * this specially and return the longhand for the variable - * with the dollar sign escaped so it makes it back to the - * caller. Only four of the local variables are treated - * specially as they are the only four that will be set - * when dynamic sources are expanded. - */ - switch (str[1]) { - case '@': - return("$(.TARGET)"); - case '%': - return("$(.ARCHIVE)"); - case '*': - return("$(.PREFIX)"); - case '!': - return("$(.MEMBER)"); - } - } - /* - * Error - */ - return (err ? var_Error : varNoError); - } else { - haveModifier = FALSE; - tstr = &str[1]; - endc = str[1]; - } - } else { - Buffer buf; /* Holds the variable name */ - - startc = str[1]; - endc = startc == '(' ? ')' : '}'; - buf = Buf_Init (MAKE_BSIZE); - - /* - * Skip to the end character or a colon, whichever comes first. - */ - for (tstr = str + 2; - *tstr != '\0' && *tstr != endc && *tstr != ':'; - tstr++) - { - /* - * A variable inside a variable, expand - */ - if (*tstr == '$') { - int rlen; - Boolean rfree; - char *rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree); - if (rval != NULL) { - Buf_AddBytes(buf, strlen(rval), (Byte *) rval); - if (rfree) - free(rval); - } - tstr += rlen - 1; - } - else - Buf_AddByte(buf, (Byte) *tstr); - } - if (*tstr == ':') { - haveModifier = TRUE; - } else if (*tstr != '\0') { - haveModifier = FALSE; - } else { - /* - * If we never did find the end character, return NULL - * right now, setting the length to be the distance to - * the end of the string, since that's what make does. - */ - *lengthPtr = tstr - str; - return (var_Error); - } - *tstr = '\0'; - Buf_AddByte(buf, (Byte) '\0'); - str = Buf_GetAll(buf, (int *) NULL); - vlen = strlen(str); - - v = VarFind (str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); - if ((v == (Var *)NIL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) && - (vlen == 2) && (str[1] == 'F' || str[1] == 'D')) - { - /* - * Check for bogus D and F forms of local variables since we're - * in a local context and the name is the right length. - */ - switch(*str) { - case '@': - case '%': - case '*': - case '!': - case '>': - case '<': - { - char vname[2]; - char *val; - - /* - * Well, it's local -- go look for it. - */ - vname[0] = *str; - vname[1] = '\0'; - v = VarFind(vname, ctxt, 0); - - if (v != (Var *)NIL) { - /* - * No need for nested expansion or anything, as we're - * the only one who sets these things and we sure don't - * but nested invocations in them... - */ - val = (char *)Buf_GetAll(v->val, (int *)NULL); - - if (str[1] == 'D') { - val = VarModify(ctxt, val, VarHead, (ClientData)0); - } else { - val = VarModify(ctxt, val, VarTail, (ClientData)0); - } - /* - * Resulting string is dynamically allocated, so - * tell caller to free it. - */ - *freePtr = TRUE; - *lengthPtr = tstr-start+1; - *tstr = endc; - Buf_Destroy (buf, TRUE); - return(val); - } - break; - } - } - } - - if (v == (Var *)NIL) { - if (((vlen == 1) || - (((vlen == 2) && (str[1] == 'F' || - str[1] == 'D')))) && - ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) - { - /* - * If substituting a local variable in a non-local context, - * assume it's for dynamic source stuff. We have to handle - * this specially and return the longhand for the variable - * with the dollar sign escaped so it makes it back to the - * caller. Only four of the local variables are treated - * specially as they are the only four that will be set - * when dynamic sources are expanded. - */ - switch (*str) { - case '@': - case '%': - case '*': - case '!': - dynamic = TRUE; - break; - } - } else if ((vlen > 2) && (*str == '.') && - isupper((unsigned char) str[1]) && - ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) - { - int len; - - len = vlen - 1; - if ((strncmp(str, ".TARGET", len) == 0) || - (strncmp(str, ".ARCHIVE", len) == 0) || - (strncmp(str, ".PREFIX", len) == 0) || - (strncmp(str, ".MEMBER", len) == 0)) - { - dynamic = TRUE; - } - } - - if (!haveModifier) { - /* - * No modifiers -- have specification length so we can return - * now. - */ - *lengthPtr = tstr - start + 1; - *tstr = endc; - if (dynamic) { - str = emalloc(*lengthPtr + 1); - strncpy(str, start, *lengthPtr); - str[*lengthPtr] = '\0'; - *freePtr = TRUE; - Buf_Destroy (buf, TRUE); - return(str); - } else { - Buf_Destroy (buf, TRUE); - return (err ? var_Error : varNoError); - } - } else { - /* - * Still need to get to the end of the variable specification, - * so kludge up a Var structure for the modifications - */ - v = (Var *) emalloc(sizeof(Var)); - v->name = str; - v->val = Buf_Init(1); - v->flags = VAR_JUNK; - Buf_Destroy (buf, FALSE); - } - } else - Buf_Destroy (buf, TRUE); - } - - - if (v->flags & VAR_IN_USE) { - Fatal("Variable %s is recursive.", v->name); - /*NOTREACHED*/ - } else { - v->flags |= VAR_IN_USE; - } - /* - * Before doing any modification, we have to make sure the value - * has been fully expanded. If it looks like recursion might be - * necessary (there's a dollar sign somewhere in the variable's value) - * we just call Var_Subst to do any other substitutions that are - * necessary. Note that the value returned by Var_Subst will have - * been dynamically-allocated, so it will need freeing when we - * return. - */ - str = (char *)Buf_GetAll(v->val, (int *)NULL); - if (strchr (str, '$') != (char *)NULL) { - str = Var_Subst(NULL, str, ctxt, err); - *freePtr = TRUE; - } - - v->flags &= ~VAR_IN_USE; - - /* - * Now we need to apply any modifiers the user wants applied. - * These are: - * :M words which match the given . - * is of the standard file - * wildcarding form. - * :N words which do not match the given . - * :S[g] - * Substitute for in the value - * :C[g] - * Substitute for regex in the value - * :H Substitute the head of each word - * :T Substitute the tail of each word - * :E Substitute the extension (minus '.') of - * each word - * :R Substitute the root of each word - * (pathname minus the suffix). - * :O ("Order") Sort words in variable. - * :u ("uniq") Remove adjacent duplicate words. - * :?: - * If the variable evaluates to true, return - * true value, else return the second value. - * :lhs=rhs Like :S, but the rhs goes to the end of - * the invocation. - * :sh Treat the current value as a command - * to be run, new value is its output. - * The following added so we can handle ODE makefiles. - * :@@@ - * Assign a temporary local variable - * to the current value of each word in turn - * and replace each word with the result of - * evaluating - * :D Use as value if variable defined - * :U Use as value if variable undefined - * :L Use the name of the variable as the value. - * :P Use the path of the node that has the same - * name as the variable as the value. This - * basically includes an implied :L so that - * the common method of refering to the path - * of your dependent 'x' in a rule is to use - * the form '${x:P}'. - * :!! Run cmd much the same as :sh run's the - * current value of the variable. - * The ::= modifiers, actually assign a value to the variable. - * Their main purpose is in supporting modifiers of .for loop - * iterators and other obscure uses. They always expand to - * nothing. In a target rule that would otherwise expand to an - * empty line they can be preceded with @: to keep make happy. - * Eg. - * - * foo: .USE - * .for i in ${.TARGET} ${.TARGET:R}.gz - * @: ${t::=$i} - * @echo blah ${t:T} - * .endfor - * - * ::= Assigns as the new value of variable. - * ::?= Assigns as value of variable if - * it was not already set. - * ::+= Appends to variable. - * ::!= Assigns output of as the new value of - * variable. - */ - if ((str != (char *)NULL) && haveModifier) { - /* - * Skip initial colon while putting it back. - */ - *tstr++ = ':'; - while (*tstr != endc) { - char *newStr; /* New value to return */ - char termc; /* Character which terminated scan */ - - if (DEBUG(VAR)) { - printf("Applying :%c to \"%s\"\n", *tstr, str); - } - switch (*tstr) { - case ':': - - if (tstr[1] == '=' || - (tstr[2] == '=' && - (tstr[1] == '!' || tstr[1] == '+' || tstr[1] == '?'))) { - GNode *v_ctxt; /* context where v belongs */ - char *emsg; - VarPattern pattern; - int how; - - ++tstr; - if (v->flags & VAR_JUNK) { - /* - * We need to strdup() it incase - * VarGetPattern() recurses. - */ - v->name = strdup(v->name); - v_ctxt = ctxt; - } else if (ctxt != VAR_GLOBAL) { - if (VarFind(v->name, ctxt, 0) == (Var *)NIL) - v_ctxt = VAR_GLOBAL; - else - v_ctxt = ctxt; - } - - switch ((how = *tstr)) { - case '+': - case '?': - case '!': - cp = &tstr[2]; - break; - default: - cp = ++tstr; - break; - } - delim = '}'; - pattern.flags = 0; - - if ((pattern.rhs = VarGetPattern(ctxt, err, &cp, delim, - NULL, &pattern.rightLen, NULL)) == NULL) { - if (v->flags & VAR_JUNK) { - free(v->name); - v->name = str; - } - goto cleanup; - } - termc = *--cp; - delim = '\0'; - - switch (how) { - case '+': - Var_Append(v->name, pattern.rhs, v_ctxt); - break; - case '!': - newStr = Cmd_Exec (pattern.rhs, &emsg); - if (emsg) - Error (emsg, str); - else - Var_Set(v->name, newStr, v_ctxt, 0); - if (newStr) - free(newStr); - break; - case '?': - if ((v->flags & VAR_JUNK) == 0) - break; - /* FALLTHROUGH */ - default: - Var_Set(v->name, pattern.rhs, v_ctxt, 0); - break; - } - if (v->flags & VAR_JUNK) { - free(v->name); - v->name = str; - } - free(pattern.rhs); - newStr = var_Error; - break; - } - goto default_case; - case '@': - { - VarLoop_t loop; - int flags = VAR_NOSUBST; - - cp = ++tstr; - delim = '@'; - if ((loop.tvar = VarGetPattern(ctxt, err, &cp, delim, - &flags, &loop.tvarLen, - NULL)) == NULL) - goto cleanup; - - if ((loop.str = VarGetPattern(ctxt, err, &cp, delim, - &flags, &loop.strLen, - NULL)) == NULL) - goto cleanup; - - termc = *cp; - delim = '\0'; - - loop.err = err; - loop.ctxt = ctxt; - newStr = VarModify(ctxt, str, VarLoopExpand, - (ClientData)&loop); - free(loop.tvar); - free(loop.str); - break; - } - case 'D': - case 'U': - { - Buffer buf; /* Buffer for patterns */ - int wantit; /* want data in buffer */ - - /* - * Pass through tstr looking for 1) escaped delimiters, - * '$'s and backslashes (place the escaped character in - * uninterpreted) and 2) unescaped $'s that aren't before - * the delimiter (expand the variable substitution). - * The result is left in the Buffer buf. - */ - buf = Buf_Init(0); - for (cp = tstr + 1; - *cp != endc && *cp != ':' && *cp != '\0'; - cp++) { - if ((*cp == '\\') && - ((cp[1] == ':') || - (cp[1] == '$') || - (cp[1] == endc) || - (cp[1] == '\\'))) - { - Buf_AddByte(buf, (Byte) cp[1]); - cp++; - } else if (*cp == '$') { - /* - * If unescaped dollar sign, assume it's a - * variable substitution and recurse. - */ - char *cp2; - int len; - Boolean freeIt; - - cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt); - Buf_AddBytes(buf, strlen(cp2), (Byte *) cp2); - if (freeIt) - free(cp2); - cp += len - 1; - } else { - Buf_AddByte(buf, (Byte) *cp); - } - } - Buf_AddByte(buf, (Byte) '\0'); - - termc = *cp; - - if (*tstr == 'U') - wantit = ((v->flags & VAR_JUNK) != 0); - else - wantit = ((v->flags & VAR_JUNK) == 0); - if ((v->flags & VAR_JUNK) != 0) - v->flags |= VAR_KEEP; - if (wantit) { - newStr = (char *)Buf_GetAll(buf, (int *)NULL); - Buf_Destroy(buf, FALSE); - } else { - newStr = str; - Buf_Destroy(buf, TRUE); - } - break; - } - case 'L': - { - if ((v->flags & VAR_JUNK) != 0) - v->flags |= VAR_KEEP; - newStr = strdup(v->name); - cp = ++tstr; - termc = *tstr; - break; - } - case 'P': - { - GNode *gn; - - if ((v->flags & VAR_JUNK) != 0) - v->flags |= VAR_KEEP; - gn = Targ_FindNode(v->name, TARG_NOCREATE); - if (gn == NILGNODE || gn->path == NULL) - newStr = strdup(v->name); - else - newStr = strdup(gn->path); - cp = ++tstr; - termc = *tstr; - break; - } - case '!': - { - char *emsg; - VarPattern pattern; - pattern.flags = 0; - - delim = '!'; - - cp = ++tstr; - if ((pattern.rhs = VarGetPattern(ctxt, err, &cp, delim, - NULL, &pattern.rightLen, NULL)) == NULL) - goto cleanup; - newStr = Cmd_Exec (pattern.rhs, &emsg); - free(pattern.rhs); - if (emsg) - Error (emsg, str); - termc = *cp; - delim = '\0'; - if (v->flags & VAR_JUNK) { - v->flags |= VAR_KEEP; - } - break; - } - case 'N': - case 'M': - { - char *pattern; - char *cp2; - Boolean copy; - int nest; - - copy = FALSE; - nest = 1; - for (cp = tstr + 1; - *cp != '\0' && *cp != ':'; - cp++) - { - if (*cp == '\\' && - (cp[1] == ':' || - cp[1] == endc || cp[1] == startc)) { - copy = TRUE; - cp++; - continue; - } - if (*cp == startc) - ++nest; - if (*cp == endc) { - --nest; - if (nest == 0) - break; - } - } - termc = *cp; - *cp = '\0'; - if (copy) { - /* - * Need to compress the \:'s out of the pattern, so - * allocate enough room to hold the uncompressed - * pattern (note that cp started at tstr+1, so - * cp - tstr takes the null byte into account) and - * compress the pattern into the space. - */ - pattern = emalloc(cp - tstr); - for (cp2 = pattern, cp = tstr + 1; - *cp != '\0'; - cp++, cp2++) - { - if ((*cp == '\\') && - (cp[1] == ':' || cp[1] == endc)) { - cp++; - } - *cp2 = *cp; - } - *cp2 = '\0'; - } else { - pattern = &tstr[1]; - } - if ((cp2 = strchr(pattern, '$'))) { - cp2 = pattern; - pattern = Var_Subst(NULL, cp2, ctxt, err); - if (copy) - free(cp2); - copy = TRUE; - } - if (*tstr == 'M' || *tstr == 'm') { - newStr = VarModify(ctxt, str, VarMatch, (ClientData)pattern); - } else { - newStr = VarModify(ctxt, str, VarNoMatch, - (ClientData)pattern); - } - if (copy) { - free(pattern); - } - break; - } - case 'S': - { - VarPattern pattern; - - pattern.flags = 0; - delim = tstr[1]; - tstr += 2; - - /* - * If pattern begins with '^', it is anchored to the - * start of the word -- skip over it and flag pattern. - */ - if (*tstr == '^') { - pattern.flags |= VAR_MATCH_START; - tstr += 1; - } - - cp = tstr; - if ((pattern.lhs = VarGetPattern(ctxt, err, &cp, delim, - &pattern.flags, &pattern.leftLen, NULL)) == NULL) - goto cleanup; - - if ((pattern.rhs = VarGetPattern(ctxt, err, &cp, delim, - NULL, &pattern.rightLen, &pattern)) == NULL) - goto cleanup; - - /* - * Check for global substitution. If 'g' after the final - * delimiter, substitution is global and is marked that - * way. - */ - for (;; cp++) { - switch (*cp) { - case 'g': - pattern.flags |= VAR_SUB_GLOBAL; - continue; - case '1': - pattern.flags |= VAR_SUB_ONE; - continue; - } - break; - } - - termc = *cp; - newStr = VarModify(ctxt, str, VarSubstitute, - (ClientData)&pattern); - - /* - * Free the two strings. - */ - free(pattern.lhs); - free(pattern.rhs); - break; - } - case '?': - { - VarPattern pattern; - Boolean value; - - /* find ':', and then substitute accordingly */ - - pattern.flags = 0; - - cp = ++tstr; - delim = ':'; - if ((pattern.lhs = VarGetPattern(ctxt, err, &cp, delim, - NULL, &pattern.leftLen, NULL)) == NULL) - goto cleanup; - - delim = '}'; - if ((pattern.rhs = VarGetPattern(ctxt, err, &cp, delim, - NULL, &pattern.rightLen, NULL)) == NULL) - goto cleanup; - - termc = *--cp; - delim = '\0'; - if (Cond_EvalExpression(1, str, &value, 0) == COND_INVALID){ - Error("Bad conditional expression `%s' in %s?%s:%s", - str, str, pattern.lhs, pattern.rhs); - goto cleanup; - } - - if (value) { - newStr = pattern.lhs; - free(pattern.rhs); - } else { - newStr = pattern.rhs; - free(pattern.lhs); - } - break; - } -#ifndef NO_REGEX - case 'C': - { - VarREPattern pattern; - char *re; - int error; - - pattern.flags = 0; - delim = tstr[1]; - tstr += 2; - - cp = tstr; - - if ((re = VarGetPattern(ctxt, err, &cp, delim, NULL, - NULL, NULL)) == NULL) - goto cleanup; - - if ((pattern.replace = VarGetPattern(ctxt, err, &cp, - delim, NULL, NULL, NULL)) == NULL){ - free(re); - goto cleanup; - } - - for (;; cp++) { - switch (*cp) { - case 'g': - pattern.flags |= VAR_SUB_GLOBAL; - continue; - case '1': - pattern.flags |= VAR_SUB_ONE; - continue; - } - break; - } - - termc = *cp; - - error = regcomp(&pattern.re, re, REG_EXTENDED); - free(re); - if (error) { - *lengthPtr = cp - start + 1; - VarREError(error, &pattern.re, "RE substitution error"); - free(pattern.replace); - return (var_Error); - } - - pattern.nsub = pattern.re.re_nsub + 1; - if (pattern.nsub < 1) - pattern.nsub = 1; - if (pattern.nsub > 10) - pattern.nsub = 10; - pattern.matches = emalloc(pattern.nsub * - sizeof(regmatch_t)); - newStr = VarModify(ctxt, str, VarRESubstitute, - (ClientData) &pattern); - regfree(&pattern.re); - free(pattern.replace); - free(pattern.matches); - break; - } -#endif - case 'Q': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarQuote (str); - cp = tstr + 1; - termc = *cp; - break; - } - /*FALLTHRU*/ - case 'T': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarModify(ctxt, str, VarTail, (ClientData)0); - cp = tstr + 1; - termc = *cp; - break; - } - /*FALLTHRU*/ - case 'H': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarModify(ctxt, str, VarHead, (ClientData)0); - cp = tstr + 1; - termc = *cp; - break; - } - /*FALLTHRU*/ - case 'E': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarModify(ctxt, str, VarSuffix, (ClientData)0); - cp = tstr + 1; - termc = *cp; - break; - } - /*FALLTHRU*/ - case 'R': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarModify(ctxt, str, VarRoot, (ClientData)0); - cp = tstr + 1; - termc = *cp; - break; - } - /*FALLTHRU*/ - case 'O': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarSort (str); - cp = tstr + 1; - termc = *cp; - break; - } - /*FALLTHRU*/ - case 'u': - if (tstr[1] == endc || tstr[1] == ':') { - newStr = VarUniq (str); - cp = tstr + 1; - termc = *cp; - break; - } - /*FALLTHRU*/ -#ifdef SUNSHCMD - case 's': - if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) { - char *err; - newStr = Cmd_Exec (str, &err); - if (err) - Error (err, str); - cp = tstr + 2; - termc = *cp; - break; - } - /*FALLTHRU*/ -#endif - default: - default_case: - { -#ifdef SYSVVARSUB - /* - * This can either be a bogus modifier or a System-V - * substitution command. - */ - VarPattern pattern; - Boolean eqFound; - - pattern.flags = 0; - eqFound = FALSE; - /* - * First we make a pass through the string trying - * to verify it is a SYSV-make-style translation: - * it must be: =) - */ - cp = tstr; - cnt = 1; - while (*cp != '\0' && cnt) { - if (*cp == '=') { - eqFound = TRUE; - /* continue looking for endc */ - } - else if (*cp == endc) - cnt--; - else if (*cp == startc) - cnt++; - if (cnt) - cp++; - } - if (*cp == endc && eqFound) { - - /* - * Now we break this sucker into the lhs and - * rhs. We must null terminate them of course. - */ - for (cp = tstr; *cp != '='; cp++) - continue; - pattern.lhs = tstr; - pattern.leftLen = cp - tstr; - *cp++ = '\0'; - - pattern.rhs = cp; - cnt = 1; - while (cnt) { - if (*cp == endc) - cnt--; - else if (*cp == startc) - cnt++; - if (cnt) - cp++; - } - pattern.rightLen = cp - pattern.rhs; - *cp = '\0'; - - /* - * SYSV modifications happen through the whole - * string. Note the pattern is anchored at the end. - */ - newStr = VarModify(ctxt, str, VarSYSVMatch, - (ClientData)&pattern); - - /* - * Restore the nulled characters - */ - pattern.lhs[pattern.leftLen] = '='; - pattern.rhs[pattern.rightLen] = endc; - termc = endc; - } else -#endif - { - Error ("Unknown modifier '%c'\n", *tstr); - for (cp = tstr+1; - *cp != ':' && *cp != endc && *cp != '\0'; - cp++) - continue; - termc = *cp; - newStr = var_Error; - } - } - } - if (DEBUG(VAR)) { - printf("Result is \"%s\"\n", newStr); - } - - if (newStr != str) { - if (*freePtr) { - free (str); - } - str = newStr; - if (str != var_Error && str != varNoError) { - *freePtr = TRUE; - } else { - *freePtr = FALSE; - } - } - if (termc == '\0') { - Error("Unclosed variable specification for %s", v->name); - } else if (termc == ':') { - *cp++ = termc; - } else { - *cp = termc; - } - tstr = cp; - } - *lengthPtr = tstr - start + 1; - } else { - *lengthPtr = tstr - start + 1; - *tstr = endc; - } - - if (v->flags & VAR_FROM_ENV) { - Boolean destroy = FALSE; - - if (str != (char *)Buf_GetAll(v->val, (int *)NULL)) { - destroy = TRUE; - } else { - /* - * Returning the value unmodified, so tell the caller to free - * the thing. - */ - *freePtr = TRUE; - } - if (str != (char *)Buf_GetAll(v->val, (int *)NULL)) - Buf_Destroy(v->val, destroy); - free((Address)v->name); - free((Address)v); - } else if (v->flags & VAR_JUNK) { - /* - * Perform any free'ing needed and set *freePtr to FALSE so the caller - * doesn't try to free a static pointer. - * If VAR_KEEP is also set then we want to keep str as is. - */ - if (!(v->flags & VAR_KEEP)) { - if (*freePtr) { - free(str); - } - *freePtr = FALSE; - if (dynamic) { - str = emalloc(*lengthPtr + 1); - strncpy(str, start, *lengthPtr); - str[*lengthPtr] = '\0'; - *freePtr = TRUE; - } else { - str = var_Error; - } - } - if (str != (char *)Buf_GetAll(v->val, (int *)NULL)) - Buf_Destroy(v->val, TRUE); - free((Address)v->name); - free((Address)v); - } - return (str); - -cleanup: - *lengthPtr = cp - start + 1; - if (*freePtr) - free(str); - if (delim != '\0') - Error("Unclosed substitution for %s (%c missing)", - v->name, delim); - return (var_Error); -} - -/*- - *----------------------------------------------------------------------- - * Var_Subst -- - * Substitute for all variables in the given string in the given context - * If undefErr is TRUE, Parse_Error will be called when an undefined - * variable is encountered. - * - * Results: - * The resulting string. - * - * Side Effects: - * None. The old string must be freed by the caller - *----------------------------------------------------------------------- - */ -char * -Var_Subst (var, str, ctxt, undefErr) - char *var; /* Named variable || NULL for all */ - char *str; /* the string in which to substitute */ - GNode *ctxt; /* the context wherein to find variables */ - Boolean undefErr; /* TRUE if undefineds are an error */ -{ - Buffer buf; /* Buffer for forming things */ - char *val; /* Value to substitute for a variable */ - int length; /* Length of the variable invocation */ - Boolean doFree; /* Set true if val should be freed */ - static Boolean errorReported; /* Set true if an error has already - * been reported to prevent a plethora - * of messages when recursing */ - - buf = Buf_Init (MAKE_BSIZE); - errorReported = FALSE; - - while (*str) { - if (var == NULL && (*str == '$') && (str[1] == '$')) { - /* - * A dollar sign may be escaped either with another dollar sign. - * In such a case, we skip over the escape character and store the - * dollar sign into the buffer directly. - */ - str++; - Buf_AddByte(buf, (Byte)*str); - str++; - } else if (*str != '$') { - /* - * Skip as many characters as possible -- either to the end of - * the string or to the next dollar sign (variable invocation). - */ - char *cp; - - for (cp = str++; *str != '$' && *str != '\0'; str++) - continue; - Buf_AddBytes(buf, str - cp, (Byte *)cp); - } else { - if (var != NULL) { - int expand; - for (;;) { - if (str[1] != '(' && str[1] != '{') { - if (str[1] != *var || strlen(var) > 1) { - Buf_AddBytes(buf, 2, (Byte *) str); - str += 2; - expand = FALSE; - } - else - expand = TRUE; - break; - } - else { - char *p; - - /* - * Scan up to the end of the variable name. - */ - for (p = &str[2]; *p && - *p != ':' && *p != ')' && *p != '}'; p++) - if (*p == '$') - break; - /* - * A variable inside the variable. We cannot expand - * the external variable yet, so we try again with - * the nested one - */ - if (*p == '$') { - Buf_AddBytes(buf, p - str, (Byte *) str); - str = p; - continue; - } - - if (strncmp(var, str + 2, p - str - 2) != 0 || - var[p - str - 2] != '\0') { - /* - * Not the variable we want to expand, scan - * until the next variable - */ - for (;*p != '$' && *p != '\0'; p++) - continue; - Buf_AddBytes(buf, p - str, (Byte *) str); - str = p; - expand = FALSE; - } - else - expand = TRUE; - break; - } - } - if (!expand) - continue; - } - - val = Var_Parse (str, ctxt, undefErr, &length, &doFree); - - /* - * When we come down here, val should either point to the - * value of this variable, suitably modified, or be NULL. - * Length should be the total length of the potential - * variable invocation (from $ to end character...) - */ - if (val == var_Error || val == varNoError) { - /* - * If performing old-time variable substitution, skip over - * the variable and continue with the substitution. Otherwise, - * store the dollar sign and advance str so we continue with - * the string... - */ - if (oldVars) { - str += length; - } else if (undefErr) { - /* - * If variable is undefined, complain and skip the - * variable. The complaint will stop us from doing anything - * when the file is parsed. - */ - if (!errorReported) { - Parse_Error (PARSE_FATAL, - "Undefined variable \"%.*s\"",length,str); - } - str += length; - errorReported = TRUE; - } else { - Buf_AddByte (buf, (Byte)*str); - str += 1; - } - } else { - /* - * We've now got a variable structure to store in. But first, - * advance the string pointer. - */ - str += length; - - /* - * Copy all the characters from the variable value straight - * into the new string. - */ - Buf_AddBytes (buf, strlen (val), (Byte *)val); - if (doFree) { - free ((Address)val); - } - } - } - } - - Buf_AddByte (buf, '\0'); - str = (char *)Buf_GetAll (buf, (int *)NULL); - Buf_Destroy (buf, FALSE); - return (str); -} - -/*- - *----------------------------------------------------------------------- - * Var_GetTail -- - * Return the tail from each of a list of words. Used to set the - * System V local variables. - * - * Results: - * The resulting string. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -#if 0 -char * -Var_GetTail(file) - char *file; /* Filename to modify */ -{ - return(VarModify(file, VarTail, (ClientData)0)); -} - -/*- - *----------------------------------------------------------------------- - * Var_GetHead -- - * Find the leading components of a (list of) filename(s). - * XXX: VarHead does not replace foo by ., as (sun) System V make - * does. - * - * Results: - * The leading components. - * - * Side Effects: - * None. - * - *----------------------------------------------------------------------- - */ -char * -Var_GetHead(file) - char *file; /* Filename to manipulate */ -{ - return(VarModify(file, VarHead, (ClientData)0)); -} -#endif - -/*- - *----------------------------------------------------------------------- - * Var_Init -- - * Initialize the module - * - * Results: - * None - * - * Side Effects: - * The VAR_CMD and VAR_GLOBAL contexts are created - *----------------------------------------------------------------------- - */ -void -Var_Init () -{ - VAR_GLOBAL = Targ_NewGN ("Global"); - VAR_CMD = Targ_NewGN ("Command"); - -} - - -void -Var_End () -{ -} - - -/****************** PRINT DEBUGGING INFO *****************/ -static void -VarPrintVar (vp) - ClientData vp; -{ - Var *v = (Var *) vp; - printf ("%-16s = %s\n", v->name, (char *) Buf_GetAll(v->val, (int *)NULL)); -} - -/*- - *----------------------------------------------------------------------- - * Var_Dump -- - * print all variables in a context - *----------------------------------------------------------------------- - */ -void -Var_Dump (ctxt) - GNode *ctxt; -{ - Hash_Search search; - Hash_Entry *h; - - for (h = Hash_EnumFirst(&ctxt->context, &search); - h != NULL; - h = Hash_EnumNext(&search)) { - VarPrintVar(Hash_GetValue(h)); - } -} diff --git a/bootstrap/bmake/wait.h b/bootstrap/bmake/wait.h deleted file mode 100644 index 4f082e1d793..00000000000 --- a/bootstrap/bmake/wait.h +++ /dev/null @@ -1,81 +0,0 @@ -/* NAME: - * wait.h - compensate for what vendors leave out - * - * AUTHOR: - * Simon J. Gerraty - */ -/* - * RCSid: - * $Id: wait.h,v 1.1.1.1 2004/03/11 13:04:14 grant Exp $ - * - * @(#)Copyright (c) 1994, Simon J. Gerraty. - * - * This is free software. It comes with NO WARRANTY. - * Permission to use, modify and distribute this source code - * is granted subject to the following conditions. - * 1/ that the above copyright notice and this notice - * are preserved in all copies and that due credit be given - * to the author. - * 2/ that any changes to this code are clearly commented - * as such so that the author does not get blamed for bugs - * other than his own. - * - * Please send copies of changes and bug-fixes to: - * sjg@quick.com.au - */ - -#include - -#ifdef sun386 -# define UNION_WAIT -# define WEXITSTATUS(x) ((&x)->w_retcode) -# define WTERMSIG(x) ((&x)->w_termsig) -# define WSTOPSIG(x) ((&x)->w_stopsig) -# define HAVE_WAIT4 -#endif - -#ifndef WAIT_T -# ifdef UNION_WAIT -# define WAIT_T union wait -# define WAIT_STATUS(x) (x).w_status -# else -# define WAIT_T int -# define WAIT_STATUS(x) x -# endif -#endif - -#ifndef WEXITSTATUS -# define WEXITSTATUS(_X) (((int)(_X)>>8)&0377) -#endif -#ifndef WSTOPPED -# define WSTOPPED 0177 -#endif -#ifndef WSTOPSIG -# define WSTOPSIG(x) WSTOPPED -#endif - -#ifdef UNION_WAIT -#ifndef WSET_STOPCODE -#define WSET_STOPCODE(x, sig) ((&x)->w_stopsig = (sig)) -#endif -#ifndef WSET_EXITCODE -#define WSET_EXITCODE(x, ret, sig) ((&x)->w_termsig = (sig), (&x)->w_retcode = (ret)) -#endif -#else -#ifndef WSET_STOPCODE -#define WSET_STOPCODE(x, sig) ((x) = ((sig) << 8) | 0177) -#endif -#ifndef WSET_EXITCODE -#define WSET_EXITCODE(x, ret, sig) ((x) = (ret << 8) | (sig)) -#endif -#endif - -#ifndef HAVE_WAITPID -# ifdef HAVE_WAIT4 -# define waitpid(pid, statusp, flags) wait4(pid, statusp, flags, (char *)0) -# else -# ifdef HAVE_WAIT3 -# define waitpid(pid, statusp, flags) wait3(statusp, flags, (char *)0) -# endif -# endif -#endif diff --git a/bootstrap/bootstrap b/bootstrap/bootstrap index d25ccd3a4dc..b016dd64ea7 100755 --- a/bootstrap/bootstrap +++ b/bootstrap/bootstrap @@ -1,6 +1,6 @@ #! /bin/sh -# $NetBSD: bootstrap,v 1.41 2005/10/31 23:05:24 reed Exp $ +# $NetBSD: bootstrap,v 1.42 2005/11/01 01:06:02 reed Exp $ # # # Copyright (c) 2001-2002 Alistair G. Crooks. All rights reserved. @@ -606,9 +606,9 @@ mkdir_p $prefix/man/man8 $prefix/man/cat8 # bootstrap make and *.mk files mkdir_p $prefix/share/mk $prefix/lib -copy_src bmake bmake +copy_src bmake/mk files-mk -(cd ${wrkdir}/bmake/mk; +(cd ${wrkdir}/files-mk; if [ -f ${bootstrapdir}/mods/mk/$opsys.sys.mk ]; then run_cmd "$cpprog ${bootstrapdir}/mods/mk/$opsys.sys.mk $prefix/share/mk/sys.mk" else @@ -617,12 +617,12 @@ copy_src bmake bmake run_cmd "$cpprog bsd.*.mk $prefix/share/mk") if [ -f mods/mk/$opsys.bsd.lib.mk ] ; then - run_cmd "$cpprog mods/mk/$opsys.bsd.lib.mk ${wrkdir}/bmake/mk/bsd.lib.mk" + run_cmd "$cpprog mods/mk/$opsys.bsd.lib.mk ${wrkdir}/files-mk/bsd.lib.mk" run_cmd "$cpprog mods/mk/$opsys.bsd.lib.mk $prefix/share/mk/bsd.lib.mk" fi if [ -f mods/mk/$opsys.bsd.man.mk ] ; then - run_cmd "$cpprog mods/mk/$opsys.bsd.man.mk ${wrkdir}/bmake/mk/bsd.man.mk" + run_cmd "$cpprog mods/mk/$opsys.bsd.man.mk ${wrkdir}/files-mk/bsd.man.mk" run_cmd "$cpprog mods/mk/$opsys.bsd.man.mk $prefix/share/mk/bsd.man.mk" fi @@ -663,7 +663,10 @@ if [ "$need_mkdir" = "yes" ]; then fi echo_msg "Installing bmake" -run_cmd "(cd $wrkdir/bmake; env CPPFLAGS='$CPPFLAGS -I../libnbcompat' LDFLAGS='$LDFLAGS -L../libnbcompat' LIBS='-lnbcompat' $shprog ./configure --prefix=$prefix --with-default-sys-path=$prefix/share/mk $configargs && make -f makefile.boot bootstrap && env BINDIR=$prefix/bin MANDIR=$prefix/man $BSTRAP_ENV ./bmake -f Makefile install)" +copy_src ../devel/bmake/files bmake +run_cmd "(cd $wrkdir/bmake && env CPPFLAGS='$CPPFLAGS -I../../libnbcompat' LDFLAGS='$LDFLAGS -L../../libnbcompat' LIBS='-lnbcompat' $shprog ./boot-strap -q -o $opsys --prefix=$prefix --sysconfdir=$sysconfdir --with-default-sys-path="$prefix/share/mk:/usr/share/mk:/usr/local/share/mk:/opt/share/mk")" +run_cmd "$shprog $wrkdir/install-sh -c -o $user -g $group -m 755 $wrkdir/bmake/$opsys/bmake $prefix/bin/bmake" +#run_cmd "$shprog $wrkdir/install-sh -c -o $user -g $group -m 644 $wrkdir/bmake/$opsys/bmake.1 $prefix/man/man1/bmake.1" # bootstrap tnftp case "$DEBIAN" in -- cgit v1.2.3